]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Automatic date update in version.in
[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;
b6ac461a 251static bool extra_sym_info = false;
79bc120c 252static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 253static int sym_base = 0;
252b5132 254
7d9813f1
NA
255static char *dump_ctf_parent_name;
256static char *dump_ctf_symtab_name;
257static char *dump_ctf_strtab_name;
258
e4b17d5c
L
259struct group_list
260{
dda8d76d
NC
261 struct group_list * next;
262 unsigned int section_index;
e4b17d5c
L
263};
264
265struct group
266{
dda8d76d
NC
267 struct group_list * root;
268 unsigned int group_index;
e4b17d5c
L
269};
270
978c4450
AM
271typedef struct filedata
272{
273 const char * file_name;
015dc7e1 274 bool is_separate;
978c4450 275 FILE * handle;
be7d229a 276 uint64_t file_size;
978c4450 277 Elf_Internal_Ehdr file_header;
26c527e6
AM
278 uint64_t archive_file_offset;
279 uint64_t archive_file_size;
066f8fbe 280 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
281 Elf_Internal_Shdr * section_headers;
282 Elf_Internal_Phdr * program_headers;
283 char * string_table;
26c527e6
AM
284 uint64_t string_table_length;
285 uint64_t dynamic_addr;
be7d229a 286 uint64_t dynamic_size;
26c527e6 287 uint64_t dynamic_nent;
978c4450 288 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 289 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 290 char * dynamic_strings;
26c527e6 291 uint64_t dynamic_strings_length;
8ac10c5b 292 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 293 uint64_t num_dynamic_syms;
978c4450 294 Elf_Internal_Sym * dynamic_symbols;
26c527e6 295 uint64_t version_info[16];
978c4450
AM
296 unsigned int dynamic_syminfo_nent;
297 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 298 uint64_t dynamic_syminfo_offset;
be7d229a
AM
299 uint64_t nbuckets;
300 uint64_t nchains;
625d49fc
AM
301 uint64_t * buckets;
302 uint64_t * chains;
be7d229a
AM
303 uint64_t ngnubuckets;
304 uint64_t ngnuchains;
625d49fc
AM
305 uint64_t * gnubuckets;
306 uint64_t * gnuchains;
307 uint64_t * mipsxlat;
308 uint64_t gnusymidx;
13acb58d 309 char * program_interpreter;
bc227f4c 310 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
311 uint64_t dynamic_info_DT_GNU_HASH;
312 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
313 elf_section_list * symtab_shndx_list;
314 size_t group_count;
315 struct group * section_groups;
316 struct group ** section_headers_groups;
317 /* A dynamic array of flags indicating for which sections a dump of
318 some kind has been requested. It is reset on a per-object file
319 basis and then initialised from the cmdline_dump_sects array,
320 the results of interpreting the -w switch, and the
321 dump_sects_byname list. */
322 struct dump_data dump;
323} Filedata;
aef1f6d0 324
c256ffe7 325/* How to print a vma value. */
843dd992
NC
326typedef enum print_mode
327{
328 HEX,
047c3dbf 329 HEX_5,
843dd992
NC
330 DEC,
331 DEC_5,
332 UNSIGNED,
047c3dbf 333 UNSIGNED_5,
843dd992 334 PREFIX_HEX,
047c3dbf 335 PREFIX_HEX_5,
843dd992 336 FULL_HEX,
047c3dbf
NL
337 LONG_HEX,
338 OCTAL,
339 OCTAL_5
843dd992
NC
340}
341print_mode;
342
b3aa80b4
NC
343typedef enum unicode_display_type
344{
345 unicode_default = 0,
346 unicode_locale,
347 unicode_escape,
348 unicode_hex,
349 unicode_highlight,
350 unicode_invalid
351} unicode_display_type;
352
353static unicode_display_type unicode_display = unicode_default;
354
a7fd1186
FS
355typedef enum
356{
357 reltype_unknown,
358 reltype_rel,
359 reltype_rela,
360 reltype_relr
361} relocation_type;
362
bb4d2ac2
L
363/* Versioned symbol info. */
364enum versioned_symbol_info
365{
366 symbol_undefined,
367 symbol_hidden,
368 symbol_public
369};
370
63cf857e
AM
371static int
372fseek64 (FILE *stream, int64_t offset, int whence)
373{
374#if defined (HAVE_FSEEKO64)
375 off64_t o = offset;
376 if (o != offset)
377 {
378 errno = EINVAL;
379 return -1;
380 }
381 return fseeko64 (stream, o, whence);
382#elif defined (HAVE_FSEEKO)
383 off_t o = offset;
384 if (o != offset)
385 {
386 errno = EINVAL;
387 return -1;
388 }
389 return fseeko (stream, o, whence);
390#else
391 long o = offset;
392 if (o != offset)
393 {
394 errno = EINVAL;
395 return -1;
396 }
397 return fseek (stream, o, whence);
398#endif
399}
400
32ec8896 401static const char * get_symbol_version_string
26c527e6 402 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 403 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 404
9c19a809
NC
405#define UNKNOWN -1
406
84714f86
AM
407static inline const char *
408section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
409{
410 return filedata->string_table + hdr->sh_name;
411}
b9e920ec 412
84714f86
AM
413static inline bool
414section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
415{
b6ac461a
NC
416 return (filedata != NULL
417 && hdr != NULL
84714f86
AM
418 && filedata->string_table != NULL
419 && hdr->sh_name < filedata->string_table_length);
420}
b9e920ec 421
b6ac461a
NC
422/* Returns true if the given index is real/valid. Note: "real" here
423 means "references a real section in the section header" and not
424 "is a valid section index as per the ELF standard". */
425
426static inline bool
427section_index_real (const Filedata *filedata, unsigned int ndx)
84714f86 428{
b6ac461a
NC
429 return (filedata != NULL
430 && filedata->section_headers != NULL
431 && ndx < filedata->file_header.e_shnum
432 && ndx > 0);
84714f86 433}
b6ac461a 434
ee42cf8c 435#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 436
84714f86
AM
437static inline bool
438valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
439{
440 return strtab != NULL && offset < strtab_size;
441}
442
443static inline bool
444valid_dynamic_name (const Filedata *filedata, uint64_t offset)
445{
446 return valid_symbol_name (filedata->dynamic_strings,
447 filedata->dynamic_strings_length, offset);
448}
449
d79b3d50
NC
450/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
451 already been called and verified that the string exists. */
84714f86
AM
452static inline const char *
453get_dynamic_name (const Filedata *filedata, size_t offset)
454{
455 return filedata->dynamic_strings + offset;
456}
18bd398b 457
61865e30
NC
458#define REMOVE_ARCH_BITS(ADDR) \
459 do \
460 { \
dda8d76d 461 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
462 (ADDR) &= ~1; \
463 } \
464 while (0)
f16a9783
MS
465
466/* Get the correct GNU hash section name. */
978c4450
AM
467#define GNU_HASH_SECTION_NAME(filedata) \
468 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 469\f
dda8d76d
NC
470/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
471 OFFSET + the offset of the current archive member, if we are examining an
472 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
473 allocate a buffer using malloc and fill that. In either case return the
474 pointer to the start of the retrieved data or NULL if something went wrong.
475 If something does go wrong and REASON is not NULL then emit an error
476 message using REASON as part of the context. */
59245841 477
c256ffe7 478static void *
be7d229a
AM
479get_data (void *var,
480 Filedata *filedata,
26c527e6 481 uint64_t offset,
be7d229a
AM
482 uint64_t size,
483 uint64_t nmemb,
484 const char *reason)
a6e9f9df 485{
2cf0635d 486 void * mvar;
be7d229a 487 uint64_t amt = size * nmemb;
a6e9f9df 488
c256ffe7 489 if (size == 0 || nmemb == 0)
a6e9f9df
AM
490 return NULL;
491
be7d229a
AM
492 /* If size_t is smaller than uint64_t, eg because you are building
493 on a 32-bit host, then make sure that when the sizes are cast to
494 size_t no information is lost. */
7c1c1904
AM
495 if ((size_t) size != size
496 || (size_t) nmemb != nmemb
be7d229a
AM
497 || (size_t) amt != amt
498 || amt / size != nmemb
499 || (size_t) amt + 1 == 0)
57028622
NC
500 {
501 if (reason)
b8281767
AM
502 error (_("Size overflow prevents reading %" PRIu64
503 " elements of size %" PRIu64 " for %s\n"),
be7d229a 504 nmemb, size, reason);
57028622
NC
505 return NULL;
506 }
507
c22b42ce 508 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 509 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
510 if (filedata->archive_file_offset > filedata->file_size
511 || offset > filedata->file_size - filedata->archive_file_offset
512 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 513 {
049b0c3a 514 if (reason)
b8281767 515 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 516 amt, reason);
a6e9f9df
AM
517 return NULL;
518 }
519
63cf857e
AM
520 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
521 SEEK_SET))
071436c6
NC
522 {
523 if (reason)
26c527e6 524 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 525 filedata->archive_file_offset + offset, reason);
071436c6
NC
526 return NULL;
527 }
528
a6e9f9df
AM
529 mvar = var;
530 if (mvar == NULL)
531 {
7c1c1904
AM
532 /* + 1 so that we can '\0' terminate invalid string table sections. */
533 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
534
535 if (mvar == NULL)
536 {
049b0c3a 537 if (reason)
b8281767 538 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 539 amt, reason);
a6e9f9df
AM
540 return NULL;
541 }
c256ffe7 542
c9c1d674 543 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
544 }
545
dda8d76d 546 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 547 {
049b0c3a 548 if (reason)
b8281767 549 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 550 amt, reason);
a6e9f9df
AM
551 if (mvar != var)
552 free (mvar);
553 return NULL;
554 }
555
556 return mvar;
557}
558
32ec8896
NC
559/* Print a VMA value in the MODE specified.
560 Returns the number of characters displayed. */
cb8f3167 561
32ec8896 562static unsigned int
625d49fc 563print_vma (uint64_t vma, print_mode mode)
66543521 564{
32ec8896 565 unsigned int nc = 0;
66543521 566
14a91970 567 switch (mode)
66543521 568 {
14a91970
AM
569 case FULL_HEX:
570 nc = printf ("0x");
1a0670f3 571 /* Fall through. */
14a91970 572 case LONG_HEX:
f493c217 573 if (!is_32bit_elf)
625d49fc
AM
574 return nc + printf ("%16.16" PRIx64, vma);
575 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 576
14a91970
AM
577 case DEC_5:
578 if (vma <= 99999)
625d49fc 579 return printf ("%5" PRId64, vma);
1a0670f3 580 /* Fall through. */
14a91970
AM
581 case PREFIX_HEX:
582 nc = printf ("0x");
1a0670f3 583 /* Fall through. */
14a91970 584 case HEX:
625d49fc 585 return nc + printf ("%" PRIx64, vma);
b19aac67 586
047c3dbf
NL
587 case PREFIX_HEX_5:
588 nc = printf ("0x");
589 /* Fall through. */
590 case HEX_5:
625d49fc 591 return nc + printf ("%05" PRIx64, vma);
047c3dbf 592
14a91970 593 case DEC:
625d49fc 594 return printf ("%" PRId64, vma);
b19aac67 595
14a91970 596 case UNSIGNED:
625d49fc 597 return printf ("%" PRIu64, vma);
32ec8896 598
047c3dbf 599 case UNSIGNED_5:
625d49fc 600 return printf ("%5" PRIu64, vma);
047c3dbf
NL
601
602 case OCTAL:
625d49fc 603 return printf ("%" PRIo64, vma);
047c3dbf
NL
604
605 case OCTAL_5:
625d49fc 606 return printf ("%5" PRIo64, vma);
047c3dbf 607
32ec8896
NC
608 default:
609 /* FIXME: Report unrecognised mode ? */
610 return 0;
f7a99963 611 }
f7a99963
NC
612}
613
047c3dbf 614
7bfd842d 615/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 616 multibye characters (assuming the host environment supports them).
31104126 617
b6ac461a
NC
618 Display at most abs(WIDTH) characters, truncating as necessary,
619 unless do_wide or extra_sym_info is true.
7bfd842d 620
0942c7ab
NC
621 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
622 abs(WIDTH) - 5 characters followed by "[...]".
623
7bfd842d
NC
624 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
625 padding as necessary.
171191ba
NC
626
627 Returns the number of emitted characters. */
628
629static unsigned int
b6ac461a 630print_symbol_name (signed int width, const char * symbol)
31104126 631{
015dc7e1
AM
632 bool extra_padding = false;
633 bool do_dots = false;
32ec8896 634 signed int num_printed = 0;
3bfcb652 635#ifdef HAVE_MBSTATE_T
7bfd842d 636 mbstate_t state;
3bfcb652 637#endif
32ec8896 638 unsigned int width_remaining;
79bc120c 639 const void * alloced_symbol = NULL;
961c521f 640
7bfd842d 641 if (width < 0)
961c521f 642 {
88305e1b 643 /* Keep the width positive. This helps the code below. */
961c521f 644 width = - width;
015dc7e1 645 extra_padding = true;
0b4362b0 646 }
56d8f8a9
NC
647 else if (width == 0)
648 return 0;
961c521f 649
b6ac461a 650 if (do_wide || extra_sym_info)
7bfd842d
NC
651 /* Set the remaining width to a very large value.
652 This simplifies the code below. */
653 width_remaining = INT_MAX;
654 else
0942c7ab
NC
655 {
656 width_remaining = width;
b6ac461a 657
0942c7ab
NC
658 if (! do_not_show_symbol_truncation
659 && (int) strlen (symbol) > width)
660 {
661 width_remaining -= 5;
662 if ((int) width_remaining < 0)
663 width_remaining = 0;
015dc7e1 664 do_dots = true;
0942c7ab
NC
665 }
666 }
cb8f3167 667
3bfcb652 668#ifdef HAVE_MBSTATE_T
7bfd842d
NC
669 /* Initialise the multibyte conversion state. */
670 memset (& state, 0, sizeof (state));
3bfcb652 671#endif
961c521f 672
79bc120c
NC
673 if (do_demangle && *symbol)
674 {
675 const char * res = cplus_demangle (symbol, demangle_flags);
676
677 if (res != NULL)
678 alloced_symbol = symbol = res;
679 }
680
7bfd842d
NC
681 while (width_remaining)
682 {
683 size_t n;
7bfd842d 684 const char c = *symbol++;
961c521f 685
7bfd842d 686 if (c == 0)
961c521f
NC
687 break;
688
b3aa80b4
NC
689 if (ISPRINT (c))
690 {
691 putchar (c);
692 width_remaining --;
693 num_printed ++;
694 }
695 else if (ISCNTRL (c))
961c521f 696 {
b3aa80b4
NC
697 /* Do not print control characters directly as they can affect terminal
698 settings. Such characters usually appear in the names generated
699 by the assembler for local labels. */
700
7bfd842d 701 if (width_remaining < 2)
961c521f
NC
702 break;
703
7bfd842d
NC
704 printf ("^%c", c + 0x40);
705 width_remaining -= 2;
171191ba 706 num_printed += 2;
961c521f 707 }
b3aa80b4 708 else if (c == 0x7f)
7bfd842d 709 {
b3aa80b4
NC
710 if (width_remaining < 5)
711 break;
712 printf ("<DEL>");
713 width_remaining -= 5;
714 num_printed += 5;
715 }
716 else if (unicode_display != unicode_locale
717 && unicode_display != unicode_default)
718 {
719 /* Display unicode characters as something else. */
720 unsigned char bytes[4];
721 bool is_utf8;
795588ae 722 unsigned int nbytes;
b3aa80b4
NC
723
724 bytes[0] = c;
725
726 if (bytes[0] < 0xc0)
727 {
728 nbytes = 1;
729 is_utf8 = false;
730 }
731 else
732 {
733 bytes[1] = *symbol++;
734
735 if ((bytes[1] & 0xc0) != 0x80)
736 {
737 is_utf8 = false;
738 /* Do not consume this character. It may only
739 be the first byte in the sequence that was
740 corrupt. */
741 --symbol;
742 nbytes = 1;
743 }
744 else if ((bytes[0] & 0x20) == 0)
745 {
746 is_utf8 = true;
747 nbytes = 2;
748 }
749 else
750 {
751 bytes[2] = *symbol++;
752
753 if ((bytes[2] & 0xc0) != 0x80)
754 {
755 is_utf8 = false;
756 symbol -= 2;
757 nbytes = 1;
758 }
759 else if ((bytes[0] & 0x10) == 0)
760 {
761 is_utf8 = true;
762 nbytes = 3;
763 }
764 else
765 {
766 bytes[3] = *symbol++;
767
768 nbytes = 4;
769
770 if ((bytes[3] & 0xc0) != 0x80)
771 {
772 is_utf8 = false;
773 symbol -= 3;
774 nbytes = 1;
775 }
776 else
777 is_utf8 = true;
778 }
779 }
780 }
781
782 if (unicode_display == unicode_invalid)
783 is_utf8 = false;
784
785 if (unicode_display == unicode_hex || ! is_utf8)
786 {
795588ae 787 unsigned int i;
b3aa80b4
NC
788
789 if (width_remaining < (nbytes * 2) + 2)
790 break;
791
792 putchar (is_utf8 ? '<' : '{');
793 printf ("0x");
794 for (i = 0; i < nbytes; i++)
795 printf ("%02x", bytes[i]);
796 putchar (is_utf8 ? '>' : '}');
797 }
798 else
799 {
800 if (unicode_display == unicode_highlight && isatty (1))
801 printf ("\x1B[31;47m"); /* Red. */
802
803 switch (nbytes)
804 {
805 case 2:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 (bytes[0] & 0x1c) >> 2,
810 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
811 break;
812 case 3:
813 if (width_remaining < 6)
814 break;
815 printf ("\\u%02x%02x",
816 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
818 break;
819 case 4:
820 if (width_remaining < 8)
821 break;
822 printf ("\\u%02x%02x%02x",
823 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
824 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
825 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
826
827 break;
828 default:
829 /* URG. */
830 break;
831 }
832
833 if (unicode_display == unicode_highlight && isatty (1))
834 printf ("\033[0m"); /* Default colour. */
835 }
836
837 if (bytes[nbytes - 1] == 0)
838 break;
7bfd842d 839 }
961c521f
NC
840 else
841 {
3bfcb652
NC
842#ifdef HAVE_MBSTATE_T
843 wchar_t w;
844#endif
7bfd842d
NC
845 /* Let printf do the hard work of displaying multibyte characters. */
846 printf ("%.1s", symbol - 1);
847 width_remaining --;
848 num_printed ++;
849
3bfcb652 850#ifdef HAVE_MBSTATE_T
7bfd842d
NC
851 /* Try to find out how many bytes made up the character that was
852 just printed. Advance the symbol pointer past the bytes that
853 were displayed. */
854 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
855#else
856 n = 1;
857#endif
7bfd842d
NC
858 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
859 symbol += (n - 1);
961c521f 860 }
961c521f 861 }
171191ba 862
0942c7ab
NC
863 if (do_dots)
864 num_printed += printf ("[...]");
865
7bfd842d 866 if (extra_padding && num_printed < width)
171191ba
NC
867 {
868 /* Fill in the remaining spaces. */
7bfd842d
NC
869 printf ("%-*s", width - num_printed, " ");
870 num_printed = width;
171191ba
NC
871 }
872
79bc120c 873 free ((void *) alloced_symbol);
171191ba 874 return num_printed;
31104126
NC
875}
876
1449284b 877/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
878 the given section's name. Like print_symbol, except that it does not try
879 to print multibyte characters, it just interprets them as hex values. */
880
881static const char *
dda8d76d 882printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 883{
b6ac461a
NC
884#define NUM_SEC_NAME_BUFS 5
885#define MAX_PRINT_SEC_NAME_LEN 256
886
887 static int sec_name_buf_index = 0;
888 /* We use a rotating array of static buffers, so that multiple successive calls
889 to printable_section_name() will still work. eg when used in a printf. */
890 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
891
892 const char * name;
893 char * buf;
894 char * buf_start;
74e1a04b
NC
895 char c;
896 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
897
b6ac461a
NC
898 /* Validate the input parameters. */
899 if (filedata == NULL)
900 return _("<internal error>");
901 if (sec == NULL)
902 return _("<none>");
903 if (filedata->string_table == NULL)
904 return _("<no-strings>");
905 if (sec->sh_name >= filedata->string_table_length)
906 return _("<corrupt>");
907
908 /* Select a buffer to use. */
909 buf_start = buf = sec_name_buf[sec_name_buf_index];
910 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
911 sec_name_buf_index = 0;
912
913 name = section_name (filedata, sec);
914
74e1a04b
NC
915 while ((c = * name ++) != 0)
916 {
917 if (ISCNTRL (c))
918 {
919 if (remaining < 2)
920 break;
948f632f 921
74e1a04b
NC
922 * buf ++ = '^';
923 * buf ++ = c + 0x40;
924 remaining -= 2;
925 }
926 else if (ISPRINT (c))
927 {
928 * buf ++ = c;
929 remaining -= 1;
930 }
931 else
932 {
933 static char hex[17] = "0123456789ABCDEF";
934
935 if (remaining < 4)
936 break;
937 * buf ++ = '<';
938 * buf ++ = hex[(c & 0xf0) >> 4];
939 * buf ++ = hex[c & 0x0f];
940 * buf ++ = '>';
941 remaining -= 4;
942 }
943
944 if (remaining == 0)
945 break;
946 }
947
948 * buf = 0;
b6ac461a
NC
949 return buf_start;
950}
951
952/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
953 This OS has so many departures from the ELF standard that we test it at
954 many places. */
955
956static inline bool
957is_ia64_vms (Filedata * filedata)
958{
959 return filedata->file_header.e_machine == EM_IA_64
960 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
74e1a04b
NC
961}
962
963static const char *
b6ac461a
NC
964printable_section_name_from_index (Filedata * filedata,
965 size_t ndx,
966 bool * is_special)
74e1a04b 967{
b6ac461a
NC
968 if (is_special != NULL)
969 * is_special = true;
970
971 switch (ndx)
972 {
973 case SHN_UNDEF: return "UND";
974 case SHN_ABS: return "ABS";
975 case SHN_COMMON: return "COM";
976 break;
977 }
978
979 if (filedata != NULL)
980 {
981 switch (filedata->file_header.e_machine)
982 {
983 case EM_MIPS:
984 if (ndx == SHN_MIPS_SCOMMON)
985 return "SCOMMON";
986 if (ndx == SHN_MIPS_SUNDEFINED)
987 return "SUNDEF";
988 break;
989
990 case EM_TI_C6000:
991 if (ndx == SHN_TIC6X_SCOMMON)
992 return "SCOM";
993 break;
994
995 case EM_X86_64:
996 case EM_L1OM:
997 case EM_K1OM:
998 if (ndx == SHN_X86_64_LCOMMON)
999 return "LARGE_COM";
1000 break;
1001
1002 case EM_IA_64:
1003 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1004 && ndx == SHN_IA_64_ANSI_COMMON)
1005 return "ANSI_COM";
1006
1007 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1008 return "VMS_SYMVEC";
1009 break;
1010
1011 default:
1012 break;
1013 }
74e1a04b 1014
b6ac461a
NC
1015 if (filedata->section_headers != NULL
1016 && ndx < filedata->file_header.e_shnum)
1017 {
1018 const char * res;
1019
1020 res = printable_section_name (filedata, filedata->section_headers + ndx);
1021 if (is_special != NULL)
1022 * is_special = (res[0] == '<');
1023
1024 return res;
1025 }
1026 }
1027
1028 static char name_buf[40];
1029 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1030
1031 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1032 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1033 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1034 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1035 else if (ndx >= SHN_LORESERVE)
1036 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1037 else if (filedata->file_header.e_shnum != 0
1038 && ndx >= filedata->file_header.e_shnum)
1039 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1040 else
1041 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1042
1043 return name_buf;
74e1a04b
NC
1044}
1045
89fac5e3
RS
1046/* Return a pointer to section NAME, or NULL if no such section exists. */
1047
1048static Elf_Internal_Shdr *
dda8d76d 1049find_section (Filedata * filedata, const char * name)
89fac5e3
RS
1050{
1051 unsigned int i;
1052
68807c3c
NC
1053 if (filedata->section_headers == NULL)
1054 return NULL;
dda8d76d
NC
1055
1056 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
1057 if (section_name_valid (filedata, filedata->section_headers + i)
1058 && streq (section_name (filedata, filedata->section_headers + i),
1059 name))
dda8d76d 1060 return filedata->section_headers + i;
89fac5e3
RS
1061
1062 return NULL;
1063}
1064
0b6ae522
DJ
1065/* Return a pointer to a section containing ADDR, or NULL if no such
1066 section exists. */
1067
1068static Elf_Internal_Shdr *
625d49fc 1069find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
1070{
1071 unsigned int i;
1072
68807c3c
NC
1073 if (filedata->section_headers == NULL)
1074 return NULL;
1075
dda8d76d 1076 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 1077 {
dda8d76d
NC
1078 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1079
0b6ae522
DJ
1080 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1081 return sec;
1082 }
1083
1084 return NULL;
1085}
1086
071436c6 1087static Elf_Internal_Shdr *
dda8d76d 1088find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
1089{
1090 unsigned int i;
1091
68807c3c
NC
1092 if (filedata->section_headers == NULL)
1093 return NULL;
1094
dda8d76d 1095 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 1096 {
dda8d76d
NC
1097 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1098
071436c6
NC
1099 if (sec->sh_type == type)
1100 return sec;
1101 }
1102
1103 return NULL;
1104}
1105
657d0d47
CC
1106/* Return a pointer to section NAME, or NULL if no such section exists,
1107 restricted to the list of sections given in SET. */
1108
1109static Elf_Internal_Shdr *
dda8d76d 1110find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
1111{
1112 unsigned int i;
1113
68807c3c
NC
1114 if (filedata->section_headers == NULL)
1115 return NULL;
1116
657d0d47
CC
1117 if (set != NULL)
1118 {
1119 while ((i = *set++) > 0)
b814a36d
NC
1120 {
1121 /* See PR 21156 for a reproducer. */
dda8d76d 1122 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1123 continue; /* FIXME: Should we issue an error message ? */
1124
84714f86
AM
1125 if (section_name_valid (filedata, filedata->section_headers + i)
1126 && streq (section_name (filedata, filedata->section_headers + i),
1127 name))
dda8d76d 1128 return filedata->section_headers + i;
b814a36d 1129 }
657d0d47
CC
1130 }
1131
dda8d76d 1132 return find_section (filedata, name);
657d0d47
CC
1133}
1134
bcedfee6 1135/* Guess the relocation size commonly used by the specific machines. */
252b5132 1136
015dc7e1 1137static bool
2dc4cec1 1138guess_is_rela (unsigned int e_machine)
252b5132 1139{
9c19a809 1140 switch (e_machine)
252b5132
RH
1141 {
1142 /* Targets that use REL relocations. */
252b5132 1143 case EM_386:
22abe556 1144 case EM_IAMCU:
f954747f 1145 case EM_960:
e9f53129 1146 case EM_ARM:
2b0337b0 1147 case EM_D10V:
252b5132 1148 case EM_CYGNUS_D10V:
e9f53129 1149 case EM_DLX:
252b5132 1150 case EM_MIPS:
4fe85591 1151 case EM_MIPS_RS3_LE:
e9f53129 1152 case EM_CYGNUS_M32R:
1c0d3aa6 1153 case EM_SCORE:
f6c1a2d5 1154 case EM_XGATE:
fe944acf 1155 case EM_NFP:
aca4efc7 1156 case EM_BPF:
015dc7e1 1157 return false;
103f02d3 1158
252b5132
RH
1159 /* Targets that use RELA relocations. */
1160 case EM_68K:
f954747f 1161 case EM_860:
a06ea964 1162 case EM_AARCH64:
cfb8c092 1163 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1164 case EM_ALPHA:
1165 case EM_ALTERA_NIOS2:
886a2506
NC
1166 case EM_ARC:
1167 case EM_ARC_COMPACT:
1168 case EM_ARC_COMPACT2:
b5c37946
SJ
1169 case EM_ARC_COMPACT3:
1170 case EM_ARC_COMPACT3_64:
e9f53129
AM
1171 case EM_AVR:
1172 case EM_AVR_OLD:
1173 case EM_BLACKFIN:
60bca95a 1174 case EM_CR16:
e9f53129
AM
1175 case EM_CRIS:
1176 case EM_CRX:
b8891f8d 1177 case EM_CSKY:
2b0337b0 1178 case EM_D30V:
252b5132 1179 case EM_CYGNUS_D30V:
2b0337b0 1180 case EM_FR30:
3f8107ab 1181 case EM_FT32:
252b5132 1182 case EM_CYGNUS_FR30:
5c70f934 1183 case EM_CYGNUS_FRV:
e9f53129
AM
1184 case EM_H8S:
1185 case EM_H8_300:
1186 case EM_H8_300H:
800eeca4 1187 case EM_IA_64:
1e4cf259
NC
1188 case EM_IP2K:
1189 case EM_IP2K_OLD:
3b36097d 1190 case EM_IQ2000:
6e712424 1191 case EM_KVX:
84e94c90 1192 case EM_LATTICEMICO32:
ff7eeb89 1193 case EM_M32C_OLD:
49f58d10 1194 case EM_M32C:
e9f53129
AM
1195 case EM_M32R:
1196 case EM_MCORE:
15ab5209 1197 case EM_CYGNUS_MEP:
a3c62988 1198 case EM_METAG:
e9f53129
AM
1199 case EM_MMIX:
1200 case EM_MN10200:
1201 case EM_CYGNUS_MN10200:
1202 case EM_MN10300:
1203 case EM_CYGNUS_MN10300:
5506d11a 1204 case EM_MOXIE:
e9f53129
AM
1205 case EM_MSP430:
1206 case EM_MSP430_OLD:
d031aafb 1207 case EM_MT:
35c08157 1208 case EM_NDS32:
64fd6348 1209 case EM_NIOS32:
73589c9d 1210 case EM_OR1K:
e9f53129
AM
1211 case EM_PPC64:
1212 case EM_PPC:
2b100bb5 1213 case EM_TI_PRU:
e23eba97 1214 case EM_RISCV:
99c513f6 1215 case EM_RL78:
c7927a3c 1216 case EM_RX:
e9f53129
AM
1217 case EM_S390:
1218 case EM_S390_OLD:
1219 case EM_SH:
1220 case EM_SPARC:
1221 case EM_SPARC32PLUS:
1222 case EM_SPARCV9:
1223 case EM_SPU:
40b36596 1224 case EM_TI_C6000:
aa137e4d
NC
1225 case EM_TILEGX:
1226 case EM_TILEPRO:
708e2187 1227 case EM_V800:
e9f53129
AM
1228 case EM_V850:
1229 case EM_CYGNUS_V850:
1230 case EM_VAX:
619ed720 1231 case EM_VISIUM:
e9f53129 1232 case EM_X86_64:
8a9036a4 1233 case EM_L1OM:
7a9068fe 1234 case EM_K1OM:
e9f53129
AM
1235 case EM_XSTORMY16:
1236 case EM_XTENSA:
1237 case EM_XTENSA_OLD:
7ba29e2a
NC
1238 case EM_MICROBLAZE:
1239 case EM_MICROBLAZE_OLD:
f96bd6c2 1240 case EM_WEBASSEMBLY:
015dc7e1 1241 return true;
103f02d3 1242
e9f53129
AM
1243 case EM_68HC05:
1244 case EM_68HC08:
1245 case EM_68HC11:
1246 case EM_68HC16:
1247 case EM_FX66:
1248 case EM_ME16:
d1133906 1249 case EM_MMA:
d1133906
NC
1250 case EM_NCPU:
1251 case EM_NDR1:
e9f53129 1252 case EM_PCP:
d1133906 1253 case EM_ST100:
e9f53129 1254 case EM_ST19:
d1133906 1255 case EM_ST7:
e9f53129
AM
1256 case EM_ST9PLUS:
1257 case EM_STARCORE:
d1133906 1258 case EM_SVX:
e9f53129 1259 case EM_TINYJ:
9c19a809
NC
1260 default:
1261 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1262 return false;
9c19a809
NC
1263 }
1264}
252b5132 1265
dda8d76d 1266/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1267 Returns TRUE upon success, FALSE otherwise. If successful then a
1268 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1269 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1270 responsibility to free the allocated buffer. */
1271
015dc7e1 1272static bool
26c527e6
AM
1273slurp_rela_relocs (Filedata *filedata,
1274 uint64_t rel_offset,
1275 uint64_t rel_size,
1276 Elf_Internal_Rela **relasp,
1277 uint64_t *nrelasp)
9c19a809 1278{
2cf0635d 1279 Elf_Internal_Rela * relas;
26c527e6 1280 uint64_t nrelas;
4d6ed7c8 1281 unsigned int i;
252b5132 1282
4d6ed7c8
NC
1283 if (is_32bit_elf)
1284 {
2cf0635d 1285 Elf32_External_Rela * erelas;
103f02d3 1286
dda8d76d 1287 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1288 rel_size, _("32-bit relocation data"));
a6e9f9df 1289 if (!erelas)
015dc7e1 1290 return false;
252b5132 1291
4d6ed7c8 1292 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1293
3f5e193b
NC
1294 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1295 sizeof (Elf_Internal_Rela));
103f02d3 1296
4d6ed7c8
NC
1297 if (relas == NULL)
1298 {
c256ffe7 1299 free (erelas);
591a748a 1300 error (_("out of memory parsing relocs\n"));
015dc7e1 1301 return false;
4d6ed7c8 1302 }
103f02d3 1303
4d6ed7c8
NC
1304 for (i = 0; i < nrelas; i++)
1305 {
1306 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1307 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1308 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1309 }
103f02d3 1310
4d6ed7c8
NC
1311 free (erelas);
1312 }
1313 else
1314 {
2cf0635d 1315 Elf64_External_Rela * erelas;
103f02d3 1316
dda8d76d 1317 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1318 rel_size, _("64-bit relocation data"));
a6e9f9df 1319 if (!erelas)
015dc7e1 1320 return false;
4d6ed7c8
NC
1321
1322 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1323
3f5e193b
NC
1324 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1325 sizeof (Elf_Internal_Rela));
103f02d3 1326
4d6ed7c8
NC
1327 if (relas == NULL)
1328 {
c256ffe7 1329 free (erelas);
591a748a 1330 error (_("out of memory parsing relocs\n"));
015dc7e1 1331 return false;
9c19a809 1332 }
4d6ed7c8
NC
1333
1334 for (i = 0; i < nrelas; i++)
9c19a809 1335 {
66543521
AM
1336 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1337 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1338 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1339
dda8d76d
NC
1340 if (filedata->file_header.e_machine == EM_MIPS
1341 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1342 {
1343 /* In little-endian objects, r_info isn't really a
1344 64-bit little-endian value: it has a 32-bit
1345 little-endian symbol index followed by four
1346 individual byte fields. Reorder INFO
1347 accordingly. */
625d49fc 1348 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1349 inf = (((inf & 0xffffffff) << 32)
1350 | ((inf >> 56) & 0xff)
1351 | ((inf >> 40) & 0xff00)
1352 | ((inf >> 24) & 0xff0000)
1353 | ((inf >> 8) & 0xff000000));
1354 relas[i].r_info = inf;
861fb55a 1355 }
4d6ed7c8 1356 }
103f02d3 1357
4d6ed7c8
NC
1358 free (erelas);
1359 }
32ec8896 1360
4d6ed7c8
NC
1361 *relasp = relas;
1362 *nrelasp = nrelas;
015dc7e1 1363 return true;
4d6ed7c8 1364}
103f02d3 1365
dda8d76d 1366/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1367 Returns TRUE upon success, FALSE otherwise. If successful then a
1368 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1369 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1370 responsibility to free the allocated buffer. */
1371
015dc7e1 1372static bool
26c527e6
AM
1373slurp_rel_relocs (Filedata *filedata,
1374 uint64_t rel_offset,
1375 uint64_t rel_size,
1376 Elf_Internal_Rela **relsp,
1377 uint64_t *nrelsp)
4d6ed7c8 1378{
2cf0635d 1379 Elf_Internal_Rela * rels;
26c527e6 1380 uint64_t nrels;
4d6ed7c8 1381 unsigned int i;
103f02d3 1382
4d6ed7c8
NC
1383 if (is_32bit_elf)
1384 {
2cf0635d 1385 Elf32_External_Rel * erels;
103f02d3 1386
dda8d76d 1387 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1388 rel_size, _("32-bit relocation data"));
a6e9f9df 1389 if (!erels)
015dc7e1 1390 return false;
103f02d3 1391
4d6ed7c8 1392 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1393
3f5e193b 1394 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1395
4d6ed7c8
NC
1396 if (rels == NULL)
1397 {
c256ffe7 1398 free (erels);
591a748a 1399 error (_("out of memory parsing relocs\n"));
015dc7e1 1400 return false;
4d6ed7c8
NC
1401 }
1402
1403 for (i = 0; i < nrels; i++)
1404 {
1405 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1406 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1407 rels[i].r_addend = 0;
9ea033b2 1408 }
4d6ed7c8
NC
1409
1410 free (erels);
9c19a809
NC
1411 }
1412 else
1413 {
2cf0635d 1414 Elf64_External_Rel * erels;
9ea033b2 1415
dda8d76d 1416 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1417 rel_size, _("64-bit relocation data"));
a6e9f9df 1418 if (!erels)
015dc7e1 1419 return false;
103f02d3 1420
4d6ed7c8 1421 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1422
3f5e193b 1423 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1424
4d6ed7c8 1425 if (rels == NULL)
9c19a809 1426 {
c256ffe7 1427 free (erels);
591a748a 1428 error (_("out of memory parsing relocs\n"));
015dc7e1 1429 return false;
4d6ed7c8 1430 }
103f02d3 1431
4d6ed7c8
NC
1432 for (i = 0; i < nrels; i++)
1433 {
66543521
AM
1434 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1435 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1436 rels[i].r_addend = 0;
861fb55a 1437
dda8d76d
NC
1438 if (filedata->file_header.e_machine == EM_MIPS
1439 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1440 {
1441 /* In little-endian objects, r_info isn't really a
1442 64-bit little-endian value: it has a 32-bit
1443 little-endian symbol index followed by four
1444 individual byte fields. Reorder INFO
1445 accordingly. */
625d49fc 1446 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1447 inf = (((inf & 0xffffffff) << 32)
1448 | ((inf >> 56) & 0xff)
1449 | ((inf >> 40) & 0xff00)
1450 | ((inf >> 24) & 0xff0000)
1451 | ((inf >> 8) & 0xff000000));
1452 rels[i].r_info = inf;
861fb55a 1453 }
4d6ed7c8 1454 }
103f02d3 1455
4d6ed7c8
NC
1456 free (erels);
1457 }
32ec8896 1458
4d6ed7c8
NC
1459 *relsp = rels;
1460 *nrelsp = nrels;
015dc7e1 1461 return true;
4d6ed7c8 1462}
103f02d3 1463
a7fd1186 1464static bool
26c527e6
AM
1465slurp_relr_relocs (Filedata *filedata,
1466 uint64_t relr_offset,
1467 uint64_t relr_size,
1468 uint64_t **relrsp,
1469 uint64_t *nrelrsp)
a7fd1186
FS
1470{
1471 void *relrs;
1472 size_t size = 0, nentries, i;
625d49fc 1473 uint64_t base = 0, addr, entry;
a7fd1186
FS
1474
1475 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1476 _("RELR relocation data"));
1477 if (!relrs)
1478 return false;
1479
1480 if (is_32bit_elf)
1481 nentries = relr_size / sizeof (Elf32_External_Relr);
1482 else
1483 nentries = relr_size / sizeof (Elf64_External_Relr);
1484 for (i = 0; i < nentries; i++)
1485 {
1486 if (is_32bit_elf)
1487 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1488 else
1489 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1490 if ((entry & 1) == 0)
1491 size++;
1492 else
1493 while ((entry >>= 1) != 0)
1494 if ((entry & 1) == 1)
1495 size++;
1496 }
1497
625d49fc 1498 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1499 if (*relrsp == NULL)
1500 {
1501 free (relrs);
1502 error (_("out of memory parsing relocs\n"));
1503 return false;
1504 }
1505
1506 size = 0;
1507 for (i = 0; i < nentries; i++)
1508 {
625d49fc 1509 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1510
1511 if (is_32bit_elf)
1512 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1513 else
1514 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1515 if ((entry & 1) == 0)
1516 {
1517 (*relrsp)[size++] = entry;
1518 base = entry + entry_bytes;
1519 }
1520 else
1521 {
1522 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1523 if ((entry & 1) != 0)
1524 (*relrsp)[size++] = addr;
1525 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1526 }
1527 }
1528
1529 *nrelrsp = size;
1530 free (relrs);
1531 return true;
1532}
1533
aca88567
NC
1534/* Returns the reloc type extracted from the reloc info field. */
1535
1536static unsigned int
625d49fc 1537get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1538{
1539 if (is_32bit_elf)
1540 return ELF32_R_TYPE (reloc_info);
1541
dda8d76d 1542 switch (filedata->file_header.e_machine)
aca88567
NC
1543 {
1544 case EM_MIPS:
1545 /* Note: We assume that reloc_info has already been adjusted for us. */
1546 return ELF64_MIPS_R_TYPE (reloc_info);
1547
1548 case EM_SPARCV9:
1549 return ELF64_R_TYPE_ID (reloc_info);
1550
1551 default:
1552 return ELF64_R_TYPE (reloc_info);
1553 }
1554}
1555
1556/* Return the symbol index extracted from the reloc info field. */
1557
625d49fc
AM
1558static uint64_t
1559get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1560{
1561 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1562}
1563
015dc7e1 1564static inline bool
dda8d76d 1565uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1566{
1567 return
dda8d76d 1568 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1569 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1570 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1571 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1572 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1573}
1574
d3ba0551
AM
1575/* Display the contents of the relocation data found at the specified
1576 offset. */
ee42cf8c 1577
015dc7e1 1578static bool
26c527e6
AM
1579dump_relocations (Filedata *filedata,
1580 uint64_t rel_offset,
1581 uint64_t rel_size,
1582 Elf_Internal_Sym *symtab,
1583 uint64_t nsyms,
1584 char *strtab,
1585 uint64_t strtablen,
1586 relocation_type rel_type,
1587 bool is_dynsym)
1588{
1589 size_t i;
2cf0635d 1590 Elf_Internal_Rela * rels;
015dc7e1 1591 bool res = true;
103f02d3 1592
a7fd1186
FS
1593 if (rel_type == reltype_unknown)
1594 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1595
a7fd1186 1596 if (rel_type == reltype_rela)
4d6ed7c8 1597 {
dda8d76d 1598 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1599 return false;
4d6ed7c8 1600 }
a7fd1186 1601 else if (rel_type == reltype_rel)
4d6ed7c8 1602 {
dda8d76d 1603 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1604 return false;
252b5132 1605 }
a7fd1186
FS
1606 else if (rel_type == reltype_relr)
1607 {
625d49fc 1608 uint64_t * relrs;
a7fd1186 1609 const char *format
b8281767 1610 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1611
1612 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1613 &rel_size))
1614 return false;
1615
26c527e6
AM
1616 printf (ngettext (" %" PRIu64 " offset\n",
1617 " %" PRIu64 " offsets\n", rel_size),
b8281767 1618 rel_size);
a7fd1186 1619 for (i = 0; i < rel_size; i++)
625d49fc 1620 printf (format, relrs[i]);
a7fd1186
FS
1621 free (relrs);
1622 return true;
1623 }
252b5132 1624
410f7a12
L
1625 if (is_32bit_elf)
1626 {
a7fd1186 1627 if (rel_type == reltype_rela)
2c71103e
NC
1628 {
1629 if (do_wide)
1630 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1631 else
1632 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1633 }
410f7a12 1634 else
2c71103e
NC
1635 {
1636 if (do_wide)
1637 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1638 else
1639 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1640 }
410f7a12 1641 }
252b5132 1642 else
410f7a12 1643 {
a7fd1186 1644 if (rel_type == reltype_rela)
2c71103e
NC
1645 {
1646 if (do_wide)
8beeaeb7 1647 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1648 else
1649 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1650 }
410f7a12 1651 else
2c71103e
NC
1652 {
1653 if (do_wide)
8beeaeb7 1654 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1655 else
1656 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1657 }
410f7a12 1658 }
252b5132
RH
1659
1660 for (i = 0; i < rel_size; i++)
1661 {
2cf0635d 1662 const char * rtype;
625d49fc
AM
1663 uint64_t offset;
1664 uint64_t inf;
1665 uint64_t symtab_index;
1666 uint64_t type;
103f02d3 1667
b34976b6 1668 offset = rels[i].r_offset;
91d6fa6a 1669 inf = rels[i].r_info;
103f02d3 1670
dda8d76d 1671 type = get_reloc_type (filedata, inf);
91d6fa6a 1672 symtab_index = get_reloc_symindex (inf);
252b5132 1673
410f7a12
L
1674 if (is_32bit_elf)
1675 {
39dbeff8
AM
1676 printf ("%8.8lx %8.8lx ",
1677 (unsigned long) offset & 0xffffffff,
91d6fa6a 1678 (unsigned long) inf & 0xffffffff);
410f7a12
L
1679 }
1680 else
1681 {
39dbeff8 1682 printf (do_wide
b8281767
AM
1683 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1684 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1685 offset, inf);
410f7a12 1686 }
103f02d3 1687
dda8d76d 1688 switch (filedata->file_header.e_machine)
252b5132
RH
1689 {
1690 default:
1691 rtype = NULL;
1692 break;
1693
a06ea964
NC
1694 case EM_AARCH64:
1695 rtype = elf_aarch64_reloc_type (type);
1696 break;
1697
2b0337b0 1698 case EM_M32R:
252b5132 1699 case EM_CYGNUS_M32R:
9ea033b2 1700 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1701 break;
1702
1703 case EM_386:
22abe556 1704 case EM_IAMCU:
9ea033b2 1705 rtype = elf_i386_reloc_type (type);
252b5132
RH
1706 break;
1707
ba2685cc
AM
1708 case EM_68HC11:
1709 case EM_68HC12:
1710 rtype = elf_m68hc11_reloc_type (type);
1711 break;
75751cd9 1712
7b4ae824
JD
1713 case EM_S12Z:
1714 rtype = elf_s12z_reloc_type (type);
1715 break;
1716
252b5132 1717 case EM_68K:
9ea033b2 1718 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1719 break;
1720
f954747f
AM
1721 case EM_960:
1722 rtype = elf_i960_reloc_type (type);
1723 break;
1724
adde6300 1725 case EM_AVR:
2b0337b0 1726 case EM_AVR_OLD:
adde6300
AM
1727 rtype = elf_avr_reloc_type (type);
1728 break;
1729
9ea033b2
NC
1730 case EM_OLD_SPARCV9:
1731 case EM_SPARC32PLUS:
1732 case EM_SPARCV9:
252b5132 1733 case EM_SPARC:
9ea033b2 1734 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1735 break;
1736
e9f53129
AM
1737 case EM_SPU:
1738 rtype = elf_spu_reloc_type (type);
1739 break;
1740
708e2187
NC
1741 case EM_V800:
1742 rtype = v800_reloc_type (type);
1743 break;
2b0337b0 1744 case EM_V850:
252b5132 1745 case EM_CYGNUS_V850:
9ea033b2 1746 rtype = v850_reloc_type (type);
252b5132
RH
1747 break;
1748
2b0337b0 1749 case EM_D10V:
252b5132 1750 case EM_CYGNUS_D10V:
9ea033b2 1751 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1752 break;
1753
2b0337b0 1754 case EM_D30V:
252b5132 1755 case EM_CYGNUS_D30V:
9ea033b2 1756 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1757 break;
1758
d172d4ba
NC
1759 case EM_DLX:
1760 rtype = elf_dlx_reloc_type (type);
1761 break;
1762
252b5132 1763 case EM_SH:
9ea033b2 1764 rtype = elf_sh_reloc_type (type);
252b5132
RH
1765 break;
1766
2b0337b0 1767 case EM_MN10300:
252b5132 1768 case EM_CYGNUS_MN10300:
9ea033b2 1769 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1770 break;
1771
2b0337b0 1772 case EM_MN10200:
252b5132 1773 case EM_CYGNUS_MN10200:
9ea033b2 1774 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1775 break;
1776
2b0337b0 1777 case EM_FR30:
252b5132 1778 case EM_CYGNUS_FR30:
9ea033b2 1779 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1780 break;
1781
ba2685cc
AM
1782 case EM_CYGNUS_FRV:
1783 rtype = elf_frv_reloc_type (type);
1784 break;
5c70f934 1785
b8891f8d
AJ
1786 case EM_CSKY:
1787 rtype = elf_csky_reloc_type (type);
1788 break;
1789
3f8107ab
AM
1790 case EM_FT32:
1791 rtype = elf_ft32_reloc_type (type);
1792 break;
1793
252b5132 1794 case EM_MCORE:
9ea033b2 1795 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1796 break;
1797
3c3bdf30
NC
1798 case EM_MMIX:
1799 rtype = elf_mmix_reloc_type (type);
1800 break;
1801
5506d11a
AM
1802 case EM_MOXIE:
1803 rtype = elf_moxie_reloc_type (type);
1804 break;
1805
2469cfa2 1806 case EM_MSP430:
dda8d76d 1807 if (uses_msp430x_relocs (filedata))
13761a11
NC
1808 {
1809 rtype = elf_msp430x_reloc_type (type);
1810 break;
1811 }
1a0670f3 1812 /* Fall through. */
2469cfa2
NC
1813 case EM_MSP430_OLD:
1814 rtype = elf_msp430_reloc_type (type);
1815 break;
1816
35c08157
KLC
1817 case EM_NDS32:
1818 rtype = elf_nds32_reloc_type (type);
1819 break;
1820
252b5132 1821 case EM_PPC:
9ea033b2 1822 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1823 break;
1824
c833c019
AM
1825 case EM_PPC64:
1826 rtype = elf_ppc64_reloc_type (type);
1827 break;
1828
252b5132 1829 case EM_MIPS:
4fe85591 1830 case EM_MIPS_RS3_LE:
9ea033b2 1831 rtype = elf_mips_reloc_type (type);
252b5132
RH
1832 break;
1833
e23eba97
NC
1834 case EM_RISCV:
1835 rtype = elf_riscv_reloc_type (type);
1836 break;
1837
252b5132 1838 case EM_ALPHA:
9ea033b2 1839 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1840 break;
1841
1842 case EM_ARM:
9ea033b2 1843 rtype = elf_arm_reloc_type (type);
252b5132
RH
1844 break;
1845
584da044 1846 case EM_ARC:
886a2506
NC
1847 case EM_ARC_COMPACT:
1848 case EM_ARC_COMPACT2:
b5c37946
SJ
1849 case EM_ARC_COMPACT3:
1850 case EM_ARC_COMPACT3_64:
9ea033b2 1851 rtype = elf_arc_reloc_type (type);
252b5132
RH
1852 break;
1853
1854 case EM_PARISC:
69e617ca 1855 rtype = elf_hppa_reloc_type (type);
252b5132 1856 break;
7d466069 1857
b8720f9d
JL
1858 case EM_H8_300:
1859 case EM_H8_300H:
1860 case EM_H8S:
1861 rtype = elf_h8_reloc_type (type);
1862 break;
1863
73589c9d
CS
1864 case EM_OR1K:
1865 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1866 break;
1867
7d466069 1868 case EM_PJ:
2b0337b0 1869 case EM_PJ_OLD:
7d466069
ILT
1870 rtype = elf_pj_reloc_type (type);
1871 break;
800eeca4
JW
1872 case EM_IA_64:
1873 rtype = elf_ia64_reloc_type (type);
1874 break;
1b61cf92 1875
6e712424
PI
1876 case EM_KVX:
1877 rtype = elf_kvx_reloc_type (type);
1878 break;
1879
1b61cf92
HPN
1880 case EM_CRIS:
1881 rtype = elf_cris_reloc_type (type);
1882 break;
535c37ff 1883
f954747f
AM
1884 case EM_860:
1885 rtype = elf_i860_reloc_type (type);
1886 break;
1887
bcedfee6 1888 case EM_X86_64:
8a9036a4 1889 case EM_L1OM:
7a9068fe 1890 case EM_K1OM:
bcedfee6
NC
1891 rtype = elf_x86_64_reloc_type (type);
1892 break;
a85d7ed0 1893
f954747f
AM
1894 case EM_S370:
1895 rtype = i370_reloc_type (type);
1896 break;
1897
53c7db4b
KH
1898 case EM_S390_OLD:
1899 case EM_S390:
1900 rtype = elf_s390_reloc_type (type);
1901 break;
93fbbb04 1902
1c0d3aa6
NC
1903 case EM_SCORE:
1904 rtype = elf_score_reloc_type (type);
1905 break;
1906
93fbbb04
GK
1907 case EM_XSTORMY16:
1908 rtype = elf_xstormy16_reloc_type (type);
1909 break;
179d3252 1910
1fe1f39c
NC
1911 case EM_CRX:
1912 rtype = elf_crx_reloc_type (type);
1913 break;
1914
179d3252
JT
1915 case EM_VAX:
1916 rtype = elf_vax_reloc_type (type);
1917 break;
1e4cf259 1918
619ed720
EB
1919 case EM_VISIUM:
1920 rtype = elf_visium_reloc_type (type);
1921 break;
1922
aca4efc7
JM
1923 case EM_BPF:
1924 rtype = elf_bpf_reloc_type (type);
1925 break;
1926
cfb8c092
NC
1927 case EM_ADAPTEVA_EPIPHANY:
1928 rtype = elf_epiphany_reloc_type (type);
1929 break;
1930
1e4cf259
NC
1931 case EM_IP2K:
1932 case EM_IP2K_OLD:
1933 rtype = elf_ip2k_reloc_type (type);
1934 break;
3b36097d
SC
1935
1936 case EM_IQ2000:
1937 rtype = elf_iq2000_reloc_type (type);
1938 break;
88da6820
NC
1939
1940 case EM_XTENSA_OLD:
1941 case EM_XTENSA:
1942 rtype = elf_xtensa_reloc_type (type);
1943 break;
a34e3ecb 1944
84e94c90
NC
1945 case EM_LATTICEMICO32:
1946 rtype = elf_lm32_reloc_type (type);
1947 break;
1948
ff7eeb89 1949 case EM_M32C_OLD:
49f58d10
JB
1950 case EM_M32C:
1951 rtype = elf_m32c_reloc_type (type);
1952 break;
1953
d031aafb
NS
1954 case EM_MT:
1955 rtype = elf_mt_reloc_type (type);
a34e3ecb 1956 break;
1d65ded4
CM
1957
1958 case EM_BLACKFIN:
1959 rtype = elf_bfin_reloc_type (type);
1960 break;
15ab5209
DB
1961
1962 case EM_CYGNUS_MEP:
1963 rtype = elf_mep_reloc_type (type);
1964 break;
60bca95a
NC
1965
1966 case EM_CR16:
1967 rtype = elf_cr16_reloc_type (type);
1968 break;
dd24e3da 1969
7ba29e2a
NC
1970 case EM_MICROBLAZE:
1971 case EM_MICROBLAZE_OLD:
1972 rtype = elf_microblaze_reloc_type (type);
1973 break;
c7927a3c 1974
99c513f6
DD
1975 case EM_RL78:
1976 rtype = elf_rl78_reloc_type (type);
1977 break;
1978
c7927a3c
NC
1979 case EM_RX:
1980 rtype = elf_rx_reloc_type (type);
1981 break;
c29aca4a 1982
a3c62988
NC
1983 case EM_METAG:
1984 rtype = elf_metag_reloc_type (type);
1985 break;
1986
40b36596
JM
1987 case EM_TI_C6000:
1988 rtype = elf_tic6x_reloc_type (type);
1989 break;
aa137e4d
NC
1990
1991 case EM_TILEGX:
1992 rtype = elf_tilegx_reloc_type (type);
1993 break;
1994
1995 case EM_TILEPRO:
1996 rtype = elf_tilepro_reloc_type (type);
1997 break;
f6c1a2d5 1998
f96bd6c2
PC
1999 case EM_WEBASSEMBLY:
2000 rtype = elf_wasm32_reloc_type (type);
2001 break;
2002
f6c1a2d5
NC
2003 case EM_XGATE:
2004 rtype = elf_xgate_reloc_type (type);
2005 break;
36591ba1
SL
2006
2007 case EM_ALTERA_NIOS2:
2008 rtype = elf_nios2_reloc_type (type);
2009 break;
2b100bb5
DD
2010
2011 case EM_TI_PRU:
2012 rtype = elf_pru_reloc_type (type);
2013 break;
fe944acf
FT
2014
2015 case EM_NFP:
2016 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2017 rtype = elf_nfp3200_reloc_type (type);
2018 else
2019 rtype = elf_nfp_reloc_type (type);
2020 break;
6655dba2
SB
2021
2022 case EM_Z80:
2023 rtype = elf_z80_reloc_type (type);
2024 break;
e9a0721f 2025
2026 case EM_LOONGARCH:
2027 rtype = elf_loongarch_reloc_type (type);
2028 break;
2029
0c857ef4
SM
2030 case EM_AMDGPU:
2031 rtype = elf_amdgpu_reloc_type (type);
2032 break;
252b5132
RH
2033 }
2034
2035 if (rtype == NULL)
39dbeff8 2036 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2037 else
5c144731 2038 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2039
dda8d76d 2040 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2041 && rtype != NULL
7ace3541 2042 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2043 && rel_type == reltype_rela)
7ace3541
RH
2044 {
2045 switch (rels[i].r_addend)
2046 {
2047 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2048 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2049 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2050 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2051 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2052 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2053 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2054 default: rtype = NULL;
2055 }
32ec8896 2056
7ace3541
RH
2057 if (rtype)
2058 printf (" (%s)", rtype);
2059 else
2060 {
2061 putchar (' ');
26c527e6
AM
2062 printf (_("<unknown addend: %" PRIx64 ">"),
2063 rels[i].r_addend);
015dc7e1 2064 res = false;
7ace3541
RH
2065 }
2066 }
2067 else if (symtab_index)
252b5132 2068 {
af3fc3bc 2069 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2070 {
27a45f42
AS
2071 error (_(" bad symbol index: %08lx in reloc\n"),
2072 (unsigned long) symtab_index);
015dc7e1 2073 res = false;
32ec8896 2074 }
af3fc3bc 2075 else
19936277 2076 {
2cf0635d 2077 Elf_Internal_Sym * psym;
bb4d2ac2
L
2078 const char * version_string;
2079 enum versioned_symbol_info sym_info;
2080 unsigned short vna_other;
19936277 2081
af3fc3bc 2082 psym = symtab + symtab_index;
103f02d3 2083
bb4d2ac2 2084 version_string
dda8d76d 2085 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2086 strtab, strtablen,
2087 symtab_index,
2088 psym,
2089 &sym_info,
2090 &vna_other);
2091
af3fc3bc 2092 printf (" ");
171191ba 2093
d8045f23
NC
2094 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2095 {
2096 const char * name;
2097 unsigned int len;
2098 unsigned int width = is_32bit_elf ? 8 : 14;
2099
2100 /* Relocations against GNU_IFUNC symbols do not use the value
2101 of the symbol as the address to relocate against. Instead
2102 they invoke the function named by the symbol and use its
2103 result as the address for relocation.
2104
2105 To indicate this to the user, do not display the value of
2106 the symbol in the "Symbols's Value" field. Instead show
2107 its name followed by () as a hint that the symbol is
2108 invoked. */
2109
2110 if (strtab == NULL
2111 || psym->st_name == 0
2112 || psym->st_name >= strtablen)
2113 name = "??";
2114 else
2115 name = strtab + psym->st_name;
2116
b6ac461a 2117 len = print_symbol_name (width, name);
bb4d2ac2
L
2118 if (version_string)
2119 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2120 version_string);
d8045f23
NC
2121 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2122 }
2123 else
2124 {
2125 print_vma (psym->st_value, LONG_HEX);
171191ba 2126
d8045f23
NC
2127 printf (is_32bit_elf ? " " : " ");
2128 }
103f02d3 2129
af3fc3bc 2130 if (psym->st_name == 0)
f1ef08cb 2131 {
2cf0635d 2132 const char * sec_name = "<null>";
f1ef08cb
AM
2133
2134 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2135 sec_name = printable_section_name_from_index
2136 (filedata, psym->st_shndx, NULL);
2137
2138 print_symbol_name (22, sec_name);
f1ef08cb 2139 }
af3fc3bc 2140 else if (strtab == NULL)
d79b3d50 2141 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2142 else if (psym->st_name >= strtablen)
32ec8896 2143 {
27a45f42
AS
2144 error (_("<corrupt string table index: %3ld>\n"),
2145 psym->st_name);
015dc7e1 2146 res = false;
32ec8896 2147 }
af3fc3bc 2148 else
bb4d2ac2 2149 {
b6ac461a 2150 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2151 if (version_string)
2152 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2153 version_string);
2154 }
103f02d3 2155
a7fd1186 2156 if (rel_type == reltype_rela)
171191ba 2157 {
625d49fc 2158 uint64_t off = rels[i].r_addend;
171191ba 2159
625d49fc
AM
2160 if ((int64_t) off < 0)
2161 printf (" - %" PRIx64, -off);
171191ba 2162 else
625d49fc 2163 printf (" + %" PRIx64, off);
171191ba 2164 }
19936277 2165 }
252b5132 2166 }
a7fd1186 2167 else if (rel_type == reltype_rela)
f7a99963 2168 {
625d49fc 2169 uint64_t off = rels[i].r_addend;
e04d7088
L
2170
2171 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2172 if ((int64_t) off < 0)
2173 printf ("-%" PRIx64, -off);
e04d7088 2174 else
625d49fc 2175 printf ("%" PRIx64, off);
f7a99963 2176 }
252b5132 2177
dda8d76d 2178 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2179 && rtype != NULL
2180 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2181 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2182
252b5132 2183 putchar ('\n');
2c71103e 2184
dda8d76d 2185 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2186 {
625d49fc
AM
2187 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2188 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2189 const char * rtype2 = elf_mips_reloc_type (type2);
2190 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2191
2c71103e
NC
2192 printf (" Type2: ");
2193
2194 if (rtype2 == NULL)
39dbeff8
AM
2195 printf (_("unrecognized: %-7lx"),
2196 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2197 else
2198 printf ("%-17.17s", rtype2);
2199
18bd398b 2200 printf ("\n Type3: ");
2c71103e
NC
2201
2202 if (rtype3 == NULL)
39dbeff8
AM
2203 printf (_("unrecognized: %-7lx"),
2204 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2205 else
2206 printf ("%-17.17s", rtype3);
2207
53c7db4b 2208 putchar ('\n');
2c71103e 2209 }
252b5132
RH
2210 }
2211
c8286bd1 2212 free (rels);
32ec8896
NC
2213
2214 return res;
252b5132
RH
2215}
2216
37c18eed
SD
2217static const char *
2218get_aarch64_dynamic_type (unsigned long type)
2219{
2220 switch (type)
2221 {
2222 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2223 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2224 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2225 default:
2226 return NULL;
2227 }
2228}
2229
252b5132 2230static const char *
d3ba0551 2231get_mips_dynamic_type (unsigned long type)
252b5132
RH
2232{
2233 switch (type)
2234 {
2235 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2236 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2237 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2238 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2239 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2240 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2241 case DT_MIPS_MSYM: return "MIPS_MSYM";
2242 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2243 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2244 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2245 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2246 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2247 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2248 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2249 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2250 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2251 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2252 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2253 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2254 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2255 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2256 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2257 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2258 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2259 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2260 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2261 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2262 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2263 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2264 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2265 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2266 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2267 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2268 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2269 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2270 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2271 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2272 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2273 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2274 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2275 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2276 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2277 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2278 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2279 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2280 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2281 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2282 default:
2283 return NULL;
2284 }
2285}
2286
9a097730 2287static const char *
d3ba0551 2288get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2289{
2290 switch (type)
2291 {
2292 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2293 default:
2294 return NULL;
2295 }
103f02d3
UD
2296}
2297
7490d522
AM
2298static const char *
2299get_ppc_dynamic_type (unsigned long type)
2300{
2301 switch (type)
2302 {
a7f2871e 2303 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2304 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2305 default:
2306 return NULL;
2307 }
2308}
2309
f1cb7e17 2310static const char *
d3ba0551 2311get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2312{
2313 switch (type)
2314 {
a7f2871e
AM
2315 case DT_PPC64_GLINK: return "PPC64_GLINK";
2316 case DT_PPC64_OPD: return "PPC64_OPD";
2317 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2318 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2319 default:
2320 return NULL;
2321 }
2322}
2323
103f02d3 2324static const char *
d3ba0551 2325get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2326{
2327 switch (type)
2328 {
2329 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2330 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2331 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2332 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2333 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2334 case DT_HP_PREINIT: return "HP_PREINIT";
2335 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2336 case DT_HP_NEEDED: return "HP_NEEDED";
2337 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2338 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2339 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2340 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2341 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2342 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2343 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2344 case DT_HP_FILTERED: return "HP_FILTERED";
2345 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2346 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2347 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2348 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2349 case DT_PLT: return "PLT";
2350 case DT_PLT_SIZE: return "PLT_SIZE";
2351 case DT_DLT: return "DLT";
2352 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2353 default:
2354 return NULL;
2355 }
2356}
9a097730 2357
ecc51f48 2358static const char *
d3ba0551 2359get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2360{
2361 switch (type)
2362 {
148b93f2
NC
2363 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2364 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2365 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2366 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2367 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2368 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2369 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2370 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2371 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2372 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2373 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2374 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2375 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2376 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2377 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2378 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2379 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2380 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2381 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2382 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2383 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2384 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2385 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2386 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2387 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2388 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2389 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2390 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2391 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2392 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2393 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2394 default:
2395 return NULL;
2396 }
2397}
2398
fd85a6a1
NC
2399static const char *
2400get_solaris_section_type (unsigned long type)
2401{
2402 switch (type)
2403 {
2404 case 0x6fffffee: return "SUNW_ancillary";
2405 case 0x6fffffef: return "SUNW_capchain";
2406 case 0x6ffffff0: return "SUNW_capinfo";
2407 case 0x6ffffff1: return "SUNW_symsort";
2408 case 0x6ffffff2: return "SUNW_tlssort";
2409 case 0x6ffffff3: return "SUNW_LDYNSYM";
2410 case 0x6ffffff4: return "SUNW_dof";
2411 case 0x6ffffff5: return "SUNW_cap";
2412 case 0x6ffffff6: return "SUNW_SIGNATURE";
2413 case 0x6ffffff7: return "SUNW_ANNOTATE";
2414 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2415 case 0x6ffffff9: return "SUNW_DEBUG";
2416 case 0x6ffffffa: return "SUNW_move";
2417 case 0x6ffffffb: return "SUNW_COMDAT";
2418 case 0x6ffffffc: return "SUNW_syminfo";
2419 case 0x6ffffffd: return "SUNW_verdef";
2420 case 0x6ffffffe: return "SUNW_verneed";
2421 case 0x6fffffff: return "SUNW_versym";
2422 case 0x70000000: return "SPARC_GOTDATA";
2423 default: return NULL;
2424 }
2425}
2426
fabcb361
RH
2427static const char *
2428get_alpha_dynamic_type (unsigned long type)
2429{
2430 switch (type)
2431 {
2432 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2433 default: return NULL;
fabcb361
RH
2434 }
2435}
2436
1c0d3aa6
NC
2437static const char *
2438get_score_dynamic_type (unsigned long type)
2439{
2440 switch (type)
2441 {
2442 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2443 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2444 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2445 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2446 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2447 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2448 default: return NULL;
1c0d3aa6
NC
2449 }
2450}
2451
40b36596
JM
2452static const char *
2453get_tic6x_dynamic_type (unsigned long type)
2454{
2455 switch (type)
2456 {
2457 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2458 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2459 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2460 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2461 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2462 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2463 default: return NULL;
40b36596
JM
2464 }
2465}
1c0d3aa6 2466
36591ba1
SL
2467static const char *
2468get_nios2_dynamic_type (unsigned long type)
2469{
2470 switch (type)
2471 {
2472 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2473 default: return NULL;
36591ba1
SL
2474 }
2475}
2476
fd85a6a1
NC
2477static const char *
2478get_solaris_dynamic_type (unsigned long type)
2479{
2480 switch (type)
2481 {
2482 case 0x6000000d: return "SUNW_AUXILIARY";
2483 case 0x6000000e: return "SUNW_RTLDINF";
2484 case 0x6000000f: return "SUNW_FILTER";
2485 case 0x60000010: return "SUNW_CAP";
2486 case 0x60000011: return "SUNW_SYMTAB";
2487 case 0x60000012: return "SUNW_SYMSZ";
2488 case 0x60000013: return "SUNW_SORTENT";
2489 case 0x60000014: return "SUNW_SYMSORT";
2490 case 0x60000015: return "SUNW_SYMSORTSZ";
2491 case 0x60000016: return "SUNW_TLSSORT";
2492 case 0x60000017: return "SUNW_TLSSORTSZ";
2493 case 0x60000018: return "SUNW_CAPINFO";
2494 case 0x60000019: return "SUNW_STRPAD";
2495 case 0x6000001a: return "SUNW_CAPCHAIN";
2496 case 0x6000001b: return "SUNW_LDMACH";
2497 case 0x6000001d: return "SUNW_CAPCHAINENT";
2498 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2499 case 0x60000021: return "SUNW_PARENT";
2500 case 0x60000023: return "SUNW_ASLR";
2501 case 0x60000025: return "SUNW_RELAX";
2502 case 0x60000029: return "SUNW_NXHEAP";
2503 case 0x6000002b: return "SUNW_NXSTACK";
2504
2505 case 0x70000001: return "SPARC_REGISTER";
2506 case 0x7ffffffd: return "AUXILIARY";
2507 case 0x7ffffffe: return "USED";
2508 case 0x7fffffff: return "FILTER";
2509
15f205b1 2510 default: return NULL;
fd85a6a1
NC
2511 }
2512}
2513
8155b853
NC
2514static const char *
2515get_riscv_dynamic_type (unsigned long type)
2516{
2517 switch (type)
2518 {
2519 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2520 default:
2521 return NULL;
2522 }
2523}
2524
832ca732
L
2525static const char *
2526get_x86_64_dynamic_type (unsigned long type)
2527{
2528 switch (type)
2529 {
2530 case DT_X86_64_PLT:
2531 return "DT_X86_64_PLT";
2532 case DT_X86_64_PLTSZ:
2533 return "DT_X86_64_PLTSZ";
2534 case DT_X86_64_PLTENT:
2535 return "DT_X86_64_PLTENT";
2536 default:
2537 return NULL;
2538 }
2539}
2540
252b5132 2541static const char *
dda8d76d 2542get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2543{
e9e44622 2544 static char buff[64];
252b5132
RH
2545
2546 switch (type)
2547 {
2548 case DT_NULL: return "NULL";
2549 case DT_NEEDED: return "NEEDED";
2550 case DT_PLTRELSZ: return "PLTRELSZ";
2551 case DT_PLTGOT: return "PLTGOT";
2552 case DT_HASH: return "HASH";
2553 case DT_STRTAB: return "STRTAB";
2554 case DT_SYMTAB: return "SYMTAB";
2555 case DT_RELA: return "RELA";
2556 case DT_RELASZ: return "RELASZ";
2557 case DT_RELAENT: return "RELAENT";
2558 case DT_STRSZ: return "STRSZ";
2559 case DT_SYMENT: return "SYMENT";
2560 case DT_INIT: return "INIT";
2561 case DT_FINI: return "FINI";
2562 case DT_SONAME: return "SONAME";
2563 case DT_RPATH: return "RPATH";
2564 case DT_SYMBOLIC: return "SYMBOLIC";
2565 case DT_REL: return "REL";
2566 case DT_RELSZ: return "RELSZ";
2567 case DT_RELENT: return "RELENT";
dd207c13
FS
2568 case DT_RELR: return "RELR";
2569 case DT_RELRSZ: return "RELRSZ";
2570 case DT_RELRENT: return "RELRENT";
252b5132
RH
2571 case DT_PLTREL: return "PLTREL";
2572 case DT_DEBUG: return "DEBUG";
2573 case DT_TEXTREL: return "TEXTREL";
2574 case DT_JMPREL: return "JMPREL";
2575 case DT_BIND_NOW: return "BIND_NOW";
2576 case DT_INIT_ARRAY: return "INIT_ARRAY";
2577 case DT_FINI_ARRAY: return "FINI_ARRAY";
2578 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2579 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2580 case DT_RUNPATH: return "RUNPATH";
2581 case DT_FLAGS: return "FLAGS";
2d0e6f43 2582
d1133906
NC
2583 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2584 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2585 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2586
05107a46 2587 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2588 case DT_PLTPADSZ: return "PLTPADSZ";
2589 case DT_MOVEENT: return "MOVEENT";
2590 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2591 case DT_FEATURE: return "FEATURE";
252b5132
RH
2592 case DT_POSFLAG_1: return "POSFLAG_1";
2593 case DT_SYMINSZ: return "SYMINSZ";
2594 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2595
252b5132 2596 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2597 case DT_CONFIG: return "CONFIG";
2598 case DT_DEPAUDIT: return "DEPAUDIT";
2599 case DT_AUDIT: return "AUDIT";
2600 case DT_PLTPAD: return "PLTPAD";
2601 case DT_MOVETAB: return "MOVETAB";
252b5132 2602 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2603
252b5132 2604 case DT_VERSYM: return "VERSYM";
103f02d3 2605
67a4f2b7
AO
2606 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2607 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2608 case DT_RELACOUNT: return "RELACOUNT";
2609 case DT_RELCOUNT: return "RELCOUNT";
2610 case DT_FLAGS_1: return "FLAGS_1";
2611 case DT_VERDEF: return "VERDEF";
2612 case DT_VERDEFNUM: return "VERDEFNUM";
2613 case DT_VERNEED: return "VERNEED";
2614 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2615
019148e4 2616 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2617 case DT_USED: return "USED";
2618 case DT_FILTER: return "FILTER";
103f02d3 2619
047b2264
JJ
2620 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2621 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2622 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2623 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2624 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2625 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2626 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2627
252b5132
RH
2628 default:
2629 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2630 {
2cf0635d 2631 const char * result;
103f02d3 2632
dda8d76d 2633 switch (filedata->file_header.e_machine)
252b5132 2634 {
37c18eed
SD
2635 case EM_AARCH64:
2636 result = get_aarch64_dynamic_type (type);
2637 break;
252b5132 2638 case EM_MIPS:
4fe85591 2639 case EM_MIPS_RS3_LE:
252b5132
RH
2640 result = get_mips_dynamic_type (type);
2641 break;
9a097730
RH
2642 case EM_SPARCV9:
2643 result = get_sparc64_dynamic_type (type);
2644 break;
7490d522
AM
2645 case EM_PPC:
2646 result = get_ppc_dynamic_type (type);
2647 break;
f1cb7e17
AM
2648 case EM_PPC64:
2649 result = get_ppc64_dynamic_type (type);
2650 break;
ecc51f48
NC
2651 case EM_IA_64:
2652 result = get_ia64_dynamic_type (type);
2653 break;
fabcb361
RH
2654 case EM_ALPHA:
2655 result = get_alpha_dynamic_type (type);
2656 break;
1c0d3aa6
NC
2657 case EM_SCORE:
2658 result = get_score_dynamic_type (type);
2659 break;
40b36596
JM
2660 case EM_TI_C6000:
2661 result = get_tic6x_dynamic_type (type);
2662 break;
36591ba1
SL
2663 case EM_ALTERA_NIOS2:
2664 result = get_nios2_dynamic_type (type);
2665 break;
8155b853
NC
2666 case EM_RISCV:
2667 result = get_riscv_dynamic_type (type);
2668 break;
832ca732
L
2669 case EM_X86_64:
2670 result = get_x86_64_dynamic_type (type);
2671 break;
252b5132 2672 default:
dda8d76d 2673 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2674 result = get_solaris_dynamic_type (type);
2675 else
2676 result = NULL;
252b5132
RH
2677 break;
2678 }
2679
2680 if (result != NULL)
2681 return result;
2682
e9e44622 2683 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2684 }
eec8f817 2685 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2686 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2687 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2688 {
2cf0635d 2689 const char * result;
103f02d3 2690
dda8d76d 2691 switch (filedata->file_header.e_machine)
103f02d3
UD
2692 {
2693 case EM_PARISC:
2694 result = get_parisc_dynamic_type (type);
2695 break;
148b93f2
NC
2696 case EM_IA_64:
2697 result = get_ia64_dynamic_type (type);
2698 break;
103f02d3 2699 default:
dda8d76d 2700 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2701 result = get_solaris_dynamic_type (type);
2702 else
2703 result = NULL;
103f02d3
UD
2704 break;
2705 }
2706
2707 if (result != NULL)
2708 return result;
2709
e9e44622
JJ
2710 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2711 type);
103f02d3 2712 }
252b5132 2713 else
e9e44622 2714 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2715
252b5132
RH
2716 return buff;
2717 }
2718}
2719
93df3340
AM
2720static bool get_program_headers (Filedata *);
2721static bool get_dynamic_section (Filedata *);
2722
2723static void
2724locate_dynamic_section (Filedata *filedata)
2725{
26c527e6 2726 uint64_t dynamic_addr = 0;
be7d229a 2727 uint64_t dynamic_size = 0;
93df3340
AM
2728
2729 if (filedata->file_header.e_phnum != 0
2730 && get_program_headers (filedata))
2731 {
2732 Elf_Internal_Phdr *segment;
2733 unsigned int i;
2734
2735 for (i = 0, segment = filedata->program_headers;
2736 i < filedata->file_header.e_phnum;
2737 i++, segment++)
2738 {
2739 if (segment->p_type == PT_DYNAMIC)
2740 {
2741 dynamic_addr = segment->p_offset;
2742 dynamic_size = segment->p_filesz;
2743
2744 if (filedata->section_headers != NULL)
2745 {
2746 Elf_Internal_Shdr *sec;
2747
2748 sec = find_section (filedata, ".dynamic");
2749 if (sec != NULL)
2750 {
2751 if (sec->sh_size == 0
2752 || sec->sh_type == SHT_NOBITS)
2753 {
2754 dynamic_addr = 0;
2755 dynamic_size = 0;
2756 }
2757 else
2758 {
2759 dynamic_addr = sec->sh_offset;
2760 dynamic_size = sec->sh_size;
2761 }
2762 }
2763 }
2764
2765 if (dynamic_addr > filedata->file_size
2766 || (dynamic_size > filedata->file_size - dynamic_addr))
2767 {
2768 dynamic_addr = 0;
2769 dynamic_size = 0;
2770 }
2771 break;
2772 }
2773 }
2774 }
2775 filedata->dynamic_addr = dynamic_addr;
2776 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2777}
2778
2779static bool
2780is_pie (Filedata *filedata)
2781{
2782 Elf_Internal_Dyn *entry;
2783
2784 if (filedata->dynamic_size == 0)
2785 locate_dynamic_section (filedata);
2786 if (filedata->dynamic_size <= 1)
2787 return false;
2788
2789 if (!get_dynamic_section (filedata))
2790 return false;
2791
2792 for (entry = filedata->dynamic_section;
2793 entry < filedata->dynamic_section + filedata->dynamic_nent;
2794 entry++)
2795 {
2796 if (entry->d_tag == DT_FLAGS_1)
2797 {
2798 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2799 return true;
2800 break;
2801 }
2802 }
2803 return false;
2804}
2805
252b5132 2806static char *
93df3340 2807get_file_type (Filedata *filedata)
252b5132 2808{
93df3340 2809 unsigned e_type = filedata->file_header.e_type;
89246a0e 2810 static char buff[64];
252b5132
RH
2811
2812 switch (e_type)
2813 {
32ec8896
NC
2814 case ET_NONE: return _("NONE (None)");
2815 case ET_REL: return _("REL (Relocatable file)");
2816 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2817 case ET_DYN:
2818 if (is_pie (filedata))
2819 return _("DYN (Position-Independent Executable file)");
2820 else
2821 return _("DYN (Shared object file)");
32ec8896 2822 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2823
2824 default:
2825 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2826 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2827 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2828 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2829 else
e9e44622 2830 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2831 return buff;
2832 }
2833}
2834
2835static char *
d3ba0551 2836get_machine_name (unsigned e_machine)
252b5132 2837{
b34976b6 2838 static char buff[64]; /* XXX */
252b5132
RH
2839
2840 switch (e_machine)
2841 {
55e22ca8
NC
2842 /* Please keep this switch table sorted by increasing EM_ value. */
2843 /* 0 */
c45021f2
NC
2844 case EM_NONE: return _("None");
2845 case EM_M32: return "WE32100";
2846 case EM_SPARC: return "Sparc";
2847 case EM_386: return "Intel 80386";
2848 case EM_68K: return "MC68000";
2849 case EM_88K: return "MC88000";
22abe556 2850 case EM_IAMCU: return "Intel MCU";
fb70ec17 2851 case EM_860: return "Intel 80860";
c45021f2
NC
2852 case EM_MIPS: return "MIPS R3000";
2853 case EM_S370: return "IBM System/370";
55e22ca8 2854 /* 10 */
7036c0e1 2855 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2856 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2857 case EM_PARISC: return "HPPA";
55e22ca8 2858 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2859 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2860 case EM_960: return "Intel 80960";
c45021f2 2861 case EM_PPC: return "PowerPC";
55e22ca8 2862 /* 20 */
285d1771 2863 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2864 case EM_S390_OLD:
2865 case EM_S390: return "IBM S/390";
2866 case EM_SPU: return "SPU";
2867 /* 30 */
2868 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2869 case EM_FR20: return "Fujitsu FR20";
2870 case EM_RH32: return "TRW RH32";
b34976b6 2871 case EM_MCORE: return "MCORE";
55e22ca8 2872 /* 40 */
7036c0e1
AJ
2873 case EM_ARM: return "ARM";
2874 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2875 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2876 case EM_SPARCV9: return "Sparc v9";
2877 case EM_TRICORE: return "Siemens Tricore";
584da044 2878 case EM_ARC: return "ARC";
c2dcd04e
NC
2879 case EM_H8_300: return "Renesas H8/300";
2880 case EM_H8_300H: return "Renesas H8/300H";
2881 case EM_H8S: return "Renesas H8S";
2882 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2883 /* 50 */
30800947 2884 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2885 case EM_MIPS_X: return "Stanford MIPS-X";
2886 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2887 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2888 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2889 case EM_PCP: return "Siemens PCP";
2890 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 2891 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
2892 case EM_STARCORE: return "Motorola Star*Core processor";
2893 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2894 /* 60 */
7036c0e1
AJ
2895 case EM_ST100: return "STMicroelectronics ST100 processor";
2896 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2897 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2898 case EM_PDSP: return "Sony DSP processor";
2899 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2900 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2901 case EM_FX66: return "Siemens FX66 microcontroller";
2902 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2903 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2904 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2905 /* 70 */
7036c0e1
AJ
2906 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2907 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2908 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2909 case EM_SVX: return "Silicon Graphics SVx";
2910 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2911 case EM_VAX: return "Digital VAX";
1b61cf92 2912 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2913 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2914 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2915 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2916 /* 80 */
b34976b6 2917 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2918 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2919 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2920 case EM_AVR_OLD:
2921 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2922 case EM_CYGNUS_FR30:
2923 case EM_FR30: return "Fujitsu FR30";
2924 case EM_CYGNUS_D10V:
2925 case EM_D10V: return "d10v";
2926 case EM_CYGNUS_D30V:
2927 case EM_D30V: return "d30v";
2928 case EM_CYGNUS_V850:
2929 case EM_V850: return "Renesas V850";
2930 case EM_CYGNUS_M32R:
2931 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2932 case EM_CYGNUS_MN10300:
2933 case EM_MN10300: return "mn10300";
2934 /* 90 */
2935 case EM_CYGNUS_MN10200:
2936 case EM_MN10200: return "mn10200";
2937 case EM_PJ: return "picoJava";
73589c9d 2938 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2939 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2940 case EM_XTENSA_OLD:
2941 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2942 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2943 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2944 case EM_NS32K: return "National Semiconductor 32000 series";
2945 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2946 case EM_SNP1K: return "Trebia SNP 1000 processor";
2947 /* 100 */
9abca702 2948 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2949 case EM_IP2K_OLD:
2950 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2951 case EM_MAX: return "MAX Processor";
2952 case EM_CR: return "National Semiconductor CompactRISC";
2953 case EM_F2MC16: return "Fujitsu F2MC16";
2954 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2955 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2956 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2957 case EM_SEP: return "Sharp embedded microprocessor";
2958 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2959 /* 110 */
11636f9e
JM
2960 case EM_UNICORE: return "Unicore";
2961 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2962 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2963 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2964 case EM_CRX: return "National Semiconductor CRX microprocessor";
2965 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2966 case EM_C166:
d70c5fc7 2967 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2968 case EM_M16C: return "Renesas M16C series microprocessors";
2969 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2970 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2971 /* 120 */
2972 case EM_M32C: return "Renesas M32c";
2973 /* 130 */
11636f9e
JM
2974 case EM_TSK3000: return "Altium TSK3000 core";
2975 case EM_RS08: return "Freescale RS08 embedded processor";
2976 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2977 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2978 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2979 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2980 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2981 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2982 /* 140 */
11636f9e
JM
2983 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2984 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2985 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2986 case EM_TI_PRU: return "TI PRU I/O processor";
2987 /* 160 */
11636f9e
JM
2988 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2989 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2990 case EM_R32C: return "Renesas R32C series microprocessors";
2991 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2992 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2993 case EM_8051: return "Intel 8051 and variants";
2994 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2995 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2996 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2997 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2998 /* 170 */
11636f9e
JM
2999 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3000 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3001 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3002 case EM_RX: return "Renesas RX";
a3c62988 3003 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3004 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3005 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3006 case EM_CR16:
3007 case EM_MICROBLAZE:
3008 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3009 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3010 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3011 /* 180 */
3012 case EM_L1OM: return "Intel L1OM";
3013 case EM_K1OM: return "Intel K1OM";
3014 case EM_INTEL182: return "Intel (reserved)";
3015 case EM_AARCH64: return "AArch64";
3016 case EM_ARM184: return "ARM (reserved)";
3017 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3018 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3019 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3020 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3021 /* 190 */
11636f9e 3022 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3023 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3024 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3025 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3026 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3027 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3028 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3029 case EM_RL78: return "Renesas RL78";
6d913794 3030 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3031 case EM_78K0R: return "Renesas 78K0R";
3032 /* 200 */
6d913794 3033 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3034 case EM_BA1: return "Beyond BA1 CPU architecture";
3035 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3036 case EM_XCORE: return "XMOS xCORE processor family";
3037 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3038 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3039 /* 210 */
6d913794
NC
3040 case EM_KM32: return "KM211 KM32 32-bit processor";
3041 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3042 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3043 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3044 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3045 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3046 case EM_COGE: return "Cognitive Smart Memory Processor";
3047 case EM_COOL: return "Bluechip Systems CoolEngine";
3048 case EM_NORC: return "Nanoradio Optimized RISC";
3049 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3050 /* 220 */
15f205b1 3051 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3052 case EM_VISIUM: return "CDS VISIUMcore processor";
3053 case EM_FT32: return "FTDI Chip FT32";
3054 case EM_MOXIE: return "Moxie";
3055 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3056 /* 230 (all reserved) */
3057 /* 240 */
55e22ca8
NC
3058 case EM_RISCV: return "RISC-V";
3059 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3060 case EM_CEVA: return "CEVA Processor Architecture Family";
3061 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3062 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3063 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3064 case EM_IMG1: return "Imagination Technologies";
3065 /* 250 */
fe944acf 3066 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3067 case EM_VE: return "NEC Vector Engine";
3068 case EM_CSKY: return "C-SKY";
b5c37946 3069 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3070 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3071 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3072 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3073 case EM_65816: return "WDC 65816/65C816";
01a8c731 3074 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3075 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3076
3077 /* Large numbers... */
3078 case EM_MT: return "Morpho Techologies MT processor";
3079 case EM_ALPHA: return "Alpha";
3080 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3081 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3082 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3083 case EM_IQ2000: return "Vitesse IQ2000";
3084 case EM_M32C_OLD:
3085 case EM_NIOS32: return "Altera Nios";
3086 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3087 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3088 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3089 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3090
252b5132 3091 default:
35d9dd2f 3092 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3093 return buff;
3094 }
3095}
3096
f8c4789c
AM
3097static char *
3098decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3099{
3100 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3101 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3102 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3103 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3104 architectures.
3105
3106 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3107 but also sets a specific architecture type in the e_flags field.
3108
3109 However, when decoding the flags we don't worry if we see an
3110 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3111 ARCEM architecture type. */
3112
3113 switch (e_flags & EF_ARC_MACH_MSK)
3114 {
3115 /* We only expect these to occur for EM_ARC_COMPACT2. */
3116 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3117 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3118 break;
3119 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3120 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3121 break;
3122
3123 /* We only expect these to occur for EM_ARC_COMPACT. */
3124 case E_ARC_MACH_ARC600:
f8c4789c 3125 out = stpcpy (out, ", ARC600");
a9522a21
AB
3126 break;
3127 case E_ARC_MACH_ARC601:
f8c4789c 3128 out = stpcpy (out, ", ARC601");
a9522a21
AB
3129 break;
3130 case E_ARC_MACH_ARC700:
f8c4789c 3131 out = stpcpy (out, ", ARC700");
a9522a21
AB
3132 break;
3133
3134 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3135 new ELF with new architecture being read by an old version of
3136 readelf, or (c) An ELF built with non-GNU compiler that does not
3137 set the architecture in the e_flags. */
3138 default:
3139 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3140 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3141 else
f8c4789c 3142 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3143 break;
3144 }
3145
3146 switch (e_flags & EF_ARC_OSABI_MSK)
3147 {
3148 case E_ARC_OSABI_ORIG:
f8c4789c 3149 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3150 break;
3151 case E_ARC_OSABI_V2:
f8c4789c 3152 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3153 break;
3154 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3155 case E_ARC_OSABI_V3:
f8c4789c 3156 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3157 break;
53a346d8 3158 case E_ARC_OSABI_V4:
f8c4789c 3159 out = stpcpy (out, ", v4 ABI");
53a346d8 3160 break;
a9522a21 3161 default:
f8c4789c 3162 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3163 break;
3164 }
f8c4789c 3165 return out;
a9522a21
AB
3166}
3167
f8c4789c
AM
3168static char *
3169decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3170{
3171 unsigned eabi;
015dc7e1 3172 bool unknown = false;
f3485b74
NC
3173
3174 eabi = EF_ARM_EABI_VERSION (e_flags);
3175 e_flags &= ~ EF_ARM_EABIMASK;
3176
3177 /* Handle "generic" ARM flags. */
3178 if (e_flags & EF_ARM_RELEXEC)
3179 {
f8c4789c 3180 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3181 e_flags &= ~ EF_ARM_RELEXEC;
3182 }
76da6bbe 3183
18a20338
CL
3184 if (e_flags & EF_ARM_PIC)
3185 {
f8c4789c 3186 out = stpcpy (out, ", position independent");
18a20338
CL
3187 e_flags &= ~ EF_ARM_PIC;
3188 }
3189
f3485b74
NC
3190 /* Now handle EABI specific flags. */
3191 switch (eabi)
3192 {
3193 default:
f8c4789c 3194 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3195 if (e_flags)
015dc7e1 3196 unknown = true;
f3485b74
NC
3197 break;
3198
3199 case EF_ARM_EABI_VER1:
f8c4789c 3200 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3201 while (e_flags)
3202 {
3203 unsigned flag;
76da6bbe 3204
f3485b74
NC
3205 /* Process flags one bit at a time. */
3206 flag = e_flags & - e_flags;
3207 e_flags &= ~ flag;
76da6bbe 3208
f3485b74
NC
3209 switch (flag)
3210 {
a5bcd848 3211 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3212 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3213 break;
76da6bbe 3214
f3485b74 3215 default:
015dc7e1 3216 unknown = true;
f3485b74
NC
3217 break;
3218 }
3219 }
3220 break;
76da6bbe 3221
a5bcd848 3222 case EF_ARM_EABI_VER2:
f8c4789c 3223 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3224 while (e_flags)
3225 {
3226 unsigned flag;
3227
3228 /* Process flags one bit at a time. */
3229 flag = e_flags & - e_flags;
3230 e_flags &= ~ flag;
3231
3232 switch (flag)
3233 {
3234 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3235 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3236 break;
3237
3238 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3239 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3240 break;
3241
3242 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3243 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3244 break;
3245
3246 default:
015dc7e1 3247 unknown = true;
a5bcd848
PB
3248 break;
3249 }
3250 }
3251 break;
3252
d507cf36 3253 case EF_ARM_EABI_VER3:
f8c4789c 3254 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3255 break;
3256
3257 case EF_ARM_EABI_VER4:
f8c4789c 3258 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3259 while (e_flags)
3260 {
3261 unsigned flag;
3262
3263 /* Process flags one bit at a time. */
3264 flag = e_flags & - e_flags;
3265 e_flags &= ~ flag;
3266
3267 switch (flag)
3268 {
3269 case EF_ARM_BE8:
f8c4789c 3270 out = stpcpy (out, ", BE8");
3bfcb652
NC
3271 break;
3272
3273 case EF_ARM_LE8:
f8c4789c 3274 out = stpcpy (out, ", LE8");
3bfcb652
NC
3275 break;
3276
3277 default:
015dc7e1 3278 unknown = true;
3bfcb652
NC
3279 break;
3280 }
3bfcb652
NC
3281 }
3282 break;
3a4a14e9
PB
3283
3284 case EF_ARM_EABI_VER5:
f8c4789c 3285 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3286 while (e_flags)
3287 {
3288 unsigned flag;
3289
3290 /* Process flags one bit at a time. */
3291 flag = e_flags & - e_flags;
3292 e_flags &= ~ flag;
3293
3294 switch (flag)
3295 {
3296 case EF_ARM_BE8:
f8c4789c 3297 out = stpcpy (out, ", BE8");
d507cf36
PB
3298 break;
3299
3300 case EF_ARM_LE8:
f8c4789c 3301 out = stpcpy (out, ", LE8");
d507cf36
PB
3302 break;
3303
3bfcb652 3304 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3305 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3306 break;
3307
3308 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3309 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3310 break;
3311
d507cf36 3312 default:
015dc7e1 3313 unknown = true;
d507cf36
PB
3314 break;
3315 }
3316 }
3317 break;
3318
f3485b74 3319 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3320 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3321 while (e_flags)
3322 {
3323 unsigned flag;
76da6bbe 3324
f3485b74
NC
3325 /* Process flags one bit at a time. */
3326 flag = e_flags & - e_flags;
3327 e_flags &= ~ flag;
76da6bbe 3328
f3485b74
NC
3329 switch (flag)
3330 {
a5bcd848 3331 case EF_ARM_INTERWORK:
f8c4789c 3332 out = stpcpy (out, ", interworking enabled");
f3485b74 3333 break;
76da6bbe 3334
a5bcd848 3335 case EF_ARM_APCS_26:
f8c4789c 3336 out = stpcpy (out, ", uses APCS/26");
f3485b74 3337 break;
76da6bbe 3338
a5bcd848 3339 case EF_ARM_APCS_FLOAT:
f8c4789c 3340 out = stpcpy (out, ", uses APCS/float");
f3485b74 3341 break;
76da6bbe 3342
a5bcd848 3343 case EF_ARM_PIC:
f8c4789c 3344 out = stpcpy (out, ", position independent");
f3485b74 3345 break;
76da6bbe 3346
a5bcd848 3347 case EF_ARM_ALIGN8:
f8c4789c 3348 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3349 break;
76da6bbe 3350
a5bcd848 3351 case EF_ARM_NEW_ABI:
f8c4789c 3352 out = stpcpy (out, ", uses new ABI");
f3485b74 3353 break;
76da6bbe 3354
a5bcd848 3355 case EF_ARM_OLD_ABI:
f8c4789c 3356 out = stpcpy (out, ", uses old ABI");
f3485b74 3357 break;
76da6bbe 3358
a5bcd848 3359 case EF_ARM_SOFT_FLOAT:
f8c4789c 3360 out = stpcpy (out, ", software FP");
f3485b74 3361 break;
76da6bbe 3362
90e01f86 3363 case EF_ARM_VFP_FLOAT:
f8c4789c 3364 out = stpcpy (out, ", VFP");
90e01f86
ILT
3365 break;
3366
fde78edd 3367 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3368 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3369 break;
3370
f3485b74 3371 default:
015dc7e1 3372 unknown = true;
f3485b74
NC
3373 break;
3374 }
3375 }
3376 }
f3485b74
NC
3377
3378 if (unknown)
f8c4789c
AM
3379 out = stpcpy (out,_(", <unknown>"));
3380 return out;
f3485b74
NC
3381}
3382
f8c4789c
AM
3383static char *
3384decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3385{
343433df
AB
3386 switch (e_flags & EF_AVR_MACH)
3387 {
3388 case E_AVR_MACH_AVR1:
f8c4789c 3389 out = stpcpy (out, ", avr:1");
343433df
AB
3390 break;
3391 case E_AVR_MACH_AVR2:
f8c4789c 3392 out = stpcpy (out, ", avr:2");
343433df
AB
3393 break;
3394 case E_AVR_MACH_AVR25:
f8c4789c 3395 out = stpcpy (out, ", avr:25");
343433df
AB
3396 break;
3397 case E_AVR_MACH_AVR3:
f8c4789c 3398 out = stpcpy (out, ", avr:3");
343433df
AB
3399 break;
3400 case E_AVR_MACH_AVR31:
f8c4789c 3401 out = stpcpy (out, ", avr:31");
343433df
AB
3402 break;
3403 case E_AVR_MACH_AVR35:
f8c4789c 3404 out = stpcpy (out, ", avr:35");
343433df
AB
3405 break;
3406 case E_AVR_MACH_AVR4:
f8c4789c 3407 out = stpcpy (out, ", avr:4");
343433df
AB
3408 break;
3409 case E_AVR_MACH_AVR5:
f8c4789c 3410 out = stpcpy (out, ", avr:5");
343433df
AB
3411 break;
3412 case E_AVR_MACH_AVR51:
f8c4789c 3413 out = stpcpy (out, ", avr:51");
343433df
AB
3414 break;
3415 case E_AVR_MACH_AVR6:
f8c4789c 3416 out = stpcpy (out, ", avr:6");
343433df
AB
3417 break;
3418 case E_AVR_MACH_AVRTINY:
f8c4789c 3419 out = stpcpy (out, ", avr:100");
343433df
AB
3420 break;
3421 case E_AVR_MACH_XMEGA1:
f8c4789c 3422 out = stpcpy (out, ", avr:101");
343433df
AB
3423 break;
3424 case E_AVR_MACH_XMEGA2:
f8c4789c 3425 out = stpcpy (out, ", avr:102");
343433df
AB
3426 break;
3427 case E_AVR_MACH_XMEGA3:
f8c4789c 3428 out = stpcpy (out, ", avr:103");
343433df
AB
3429 break;
3430 case E_AVR_MACH_XMEGA4:
f8c4789c 3431 out = stpcpy (out, ", avr:104");
343433df
AB
3432 break;
3433 case E_AVR_MACH_XMEGA5:
f8c4789c 3434 out = stpcpy (out, ", avr:105");
343433df
AB
3435 break;
3436 case E_AVR_MACH_XMEGA6:
f8c4789c 3437 out = stpcpy (out, ", avr:106");
343433df
AB
3438 break;
3439 case E_AVR_MACH_XMEGA7:
f8c4789c 3440 out = stpcpy (out, ", avr:107");
343433df
AB
3441 break;
3442 default:
f8c4789c 3443 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3444 break;
3445 }
3446
343433df 3447 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3448 out = stpcpy (out, ", link-relax");
3449 return out;
343433df
AB
3450}
3451
f8c4789c
AM
3452static char *
3453decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3454{
3455 if (e_flags & EF_BFIN_PIC)
3456 out = stpcpy (out, ", PIC");
3457
3458 if (e_flags & EF_BFIN_FDPIC)
3459 out = stpcpy (out, ", FDPIC");
3460
3461 if (e_flags & EF_BFIN_CODE_IN_L1)
3462 out = stpcpy (out, ", code in L1");
3463
3464 if (e_flags & EF_BFIN_DATA_IN_L1)
3465 out = stpcpy (out, ", data in L1");
3466 return out;
3467}
3468
3469static char *
3470decode_FRV_machine_flags (char *out, unsigned e_flags)
3471{
3472 switch (e_flags & EF_FRV_CPU_MASK)
3473 {
3474 case EF_FRV_CPU_GENERIC:
3475 break;
3476
3477 default:
3478 out = stpcpy (out, ", fr???");
3479 break;
3480
3481 case EF_FRV_CPU_FR300:
3482 out = stpcpy (out, ", fr300");
3483 break;
3484
3485 case EF_FRV_CPU_FR400:
3486 out = stpcpy (out, ", fr400");
3487 break;
3488 case EF_FRV_CPU_FR405:
3489 out = stpcpy (out, ", fr405");
3490 break;
3491
3492 case EF_FRV_CPU_FR450:
3493 out = stpcpy (out, ", fr450");
3494 break;
3495
3496 case EF_FRV_CPU_FR500:
3497 out = stpcpy (out, ", fr500");
3498 break;
3499 case EF_FRV_CPU_FR550:
3500 out = stpcpy (out, ", fr550");
3501 break;
3502
3503 case EF_FRV_CPU_SIMPLE:
3504 out = stpcpy (out, ", simple");
3505 break;
3506 case EF_FRV_CPU_TOMCAT:
3507 out = stpcpy (out, ", tomcat");
3508 break;
3509 }
3510 return out;
3511}
3512
3513static char *
3514decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3515{
3516 if ((e_flags & EF_IA_64_ABI64))
3517 out = stpcpy (out, ", 64-bit");
3518 else
3519 out = stpcpy (out, ", 32-bit");
3520 if ((e_flags & EF_IA_64_REDUCEDFP))
3521 out = stpcpy (out, ", reduced fp model");
3522 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3523 out = stpcpy (out, ", no function descriptors, constant gp");
3524 else if ((e_flags & EF_IA_64_CONS_GP))
3525 out = stpcpy (out, ", constant gp");
3526 if ((e_flags & EF_IA_64_ABSOLUTE))
3527 out = stpcpy (out, ", absolute");
3528 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3529 {
3530 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3531 out = stpcpy (out, ", vms_linkages");
3532 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3533 {
3534 case EF_IA_64_VMS_COMCOD_SUCCESS:
3535 break;
3536 case EF_IA_64_VMS_COMCOD_WARNING:
3537 out = stpcpy (out, ", warning");
3538 break;
3539 case EF_IA_64_VMS_COMCOD_ERROR:
3540 out = stpcpy (out, ", error");
3541 break;
3542 case EF_IA_64_VMS_COMCOD_ABORT:
3543 out = stpcpy (out, ", abort");
3544 break;
3545 default:
3546 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3547 e_flags & EF_IA_64_VMS_COMCOD);
3548 out = stpcpy (out, ", <unknown>");
3549 }
3550 }
3551 return out;
3552}
3553
3554static char *
3555decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3556{
3557 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3558 out = stpcpy (out, ", SOFT-FLOAT");
3559 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3560 out = stpcpy (out, ", SINGLE-FLOAT");
3561 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3562 out = stpcpy (out, ", DOUBLE-FLOAT");
3563
3564 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3565 out = stpcpy (out, ", OBJ-v0");
3566 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3567 out = stpcpy (out, ", OBJ-v1");
3568 return out;
3569}
3570
3571static char *
3572decode_M68K_machine_flags (char *out, unsigned int e_flags)
3573{
3574 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3575 out = stpcpy (out, ", m68000");
3576 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3577 out = stpcpy (out, ", cpu32");
3578 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3579 out = stpcpy (out, ", fido_a");
3580 else
3581 {
3582 char const *isa = _("unknown");
3583 char const *mac = _("unknown mac");
3584 char const *additional = NULL;
3585
3586 switch (e_flags & EF_M68K_CF_ISA_MASK)
3587 {
3588 case EF_M68K_CF_ISA_A_NODIV:
3589 isa = "A";
3590 additional = ", nodiv";
3591 break;
3592 case EF_M68K_CF_ISA_A:
3593 isa = "A";
3594 break;
3595 case EF_M68K_CF_ISA_A_PLUS:
3596 isa = "A+";
3597 break;
3598 case EF_M68K_CF_ISA_B_NOUSP:
3599 isa = "B";
3600 additional = ", nousp";
3601 break;
3602 case EF_M68K_CF_ISA_B:
3603 isa = "B";
3604 break;
3605 case EF_M68K_CF_ISA_C:
3606 isa = "C";
3607 break;
3608 case EF_M68K_CF_ISA_C_NODIV:
3609 isa = "C";
3610 additional = ", nodiv";
3611 break;
3612 }
3613 out = stpcpy (out, ", cf, isa ");
3614 out = stpcpy (out, isa);
3615 if (additional)
3616 out = stpcpy (out, additional);
3617 if (e_flags & EF_M68K_CF_FLOAT)
3618 out = stpcpy (out, ", float");
3619 switch (e_flags & EF_M68K_CF_MAC_MASK)
3620 {
3621 case 0:
3622 mac = NULL;
3623 break;
3624 case EF_M68K_CF_MAC:
3625 mac = "mac";
3626 break;
3627 case EF_M68K_CF_EMAC:
3628 mac = "emac";
3629 break;
3630 case EF_M68K_CF_EMAC_B:
3631 mac = "emac_b";
3632 break;
3633 }
3634 if (mac)
3635 {
3636 out = stpcpy (out, ", ");
3637 out = stpcpy (out, mac);
3638 }
3639 }
3640 return out;
3641}
3642
3643static char *
3644decode_MeP_machine_flags (char *out, unsigned int e_flags)
3645{
3646 switch (e_flags & EF_MEP_CPU_MASK)
3647 {
3648 case EF_MEP_CPU_MEP:
3649 out = stpcpy (out, ", generic MeP");
3650 break;
3651 case EF_MEP_CPU_C2:
3652 out = stpcpy (out, ", MeP C2");
3653 break;
3654 case EF_MEP_CPU_C3:
3655 out = stpcpy (out, ", MeP C3");
3656 break;
3657 case EF_MEP_CPU_C4:
3658 out = stpcpy (out, ", MeP C4");
3659 break;
3660 case EF_MEP_CPU_C5:
3661 out = stpcpy (out, ", MeP C5");
3662 break;
3663 case EF_MEP_CPU_H1:
3664 out = stpcpy (out, ", MeP H1");
3665 break;
3666 default:
3667 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3668 break;
3669 }
3670
3671 switch (e_flags & EF_MEP_COP_MASK)
3672 {
3673 case EF_MEP_COP_NONE:
3674 break;
3675 case EF_MEP_COP_AVC:
3676 out = stpcpy (out, ", AVC coprocessor");
3677 break;
3678 case EF_MEP_COP_AVC2:
3679 out = stpcpy (out, ", AVC2 coprocessor");
3680 break;
3681 case EF_MEP_COP_FMAX:
3682 out = stpcpy (out, ", FMAX coprocessor");
3683 break;
3684 case EF_MEP_COP_IVC2:
3685 out = stpcpy (out, ", IVC2 coprocessor");
3686 break;
3687 default:
3688 out = stpcpy (out, _("<unknown MeP copro type>"));
3689 break;
3690 }
3691
3692 if (e_flags & EF_MEP_LIBRARY)
3693 out = stpcpy (out, ", Built for Library");
3694
3695 if (e_flags & EF_MEP_INDEX_MASK)
3696 out += sprintf (out, ", Configuration Index: %#x",
3697 e_flags & EF_MEP_INDEX_MASK);
3698
3699 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3700 out += sprintf (out, _(", unknown flags bits: %#x"),
3701 e_flags & ~ EF_MEP_ALL_FLAGS);
3702 return out;
3703}
3704
3705static char *
3706decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3707{
3708 if (e_flags & EF_MIPS_NOREORDER)
3709 out = stpcpy (out, ", noreorder");
3710
3711 if (e_flags & EF_MIPS_PIC)
3712 out = stpcpy (out, ", pic");
3713
3714 if (e_flags & EF_MIPS_CPIC)
3715 out = stpcpy (out, ", cpic");
3716
3717 if (e_flags & EF_MIPS_UCODE)
3718 out = stpcpy (out, ", ugen_reserved");
3719
3720 if (e_flags & EF_MIPS_ABI2)
3721 out = stpcpy (out, ", abi2");
3722
3723 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3724 out = stpcpy (out, ", odk first");
3725
3726 if (e_flags & EF_MIPS_32BITMODE)
3727 out = stpcpy (out, ", 32bitmode");
3728
3729 if (e_flags & EF_MIPS_NAN2008)
3730 out = stpcpy (out, ", nan2008");
3731
3732 if (e_flags & EF_MIPS_FP64)
3733 out = stpcpy (out, ", fp64");
3734
3735 switch ((e_flags & EF_MIPS_MACH))
3736 {
d173146d 3737 case EF_MIPS_MACH_3900:
f8c4789c
AM
3738 out = stpcpy (out, ", 3900");
3739 break;
d173146d 3740 case EF_MIPS_MACH_4010:
f8c4789c
AM
3741 out = stpcpy (out, ", 4010");
3742 break;
d173146d 3743 case EF_MIPS_MACH_4100:
f8c4789c
AM
3744 out = stpcpy (out, ", 4100");
3745 break;
d173146d 3746 case EF_MIPS_MACH_4111:
f8c4789c
AM
3747 out = stpcpy (out, ", 4111");
3748 break;
d173146d 3749 case EF_MIPS_MACH_4120:
f8c4789c
AM
3750 out = stpcpy (out, ", 4120");
3751 break;
d173146d 3752 case EF_MIPS_MACH_4650:
f8c4789c
AM
3753 out = stpcpy (out, ", 4650");
3754 break;
d173146d 3755 case EF_MIPS_MACH_5400:
f8c4789c
AM
3756 out = stpcpy (out, ", 5400");
3757 break;
d173146d 3758 case EF_MIPS_MACH_5500:
f8c4789c
AM
3759 out = stpcpy (out, ", 5500");
3760 break;
d173146d 3761 case EF_MIPS_MACH_5900:
f8c4789c
AM
3762 out = stpcpy (out, ", 5900");
3763 break;
d173146d 3764 case EF_MIPS_MACH_SB1:
f8c4789c
AM
3765 out = stpcpy (out, ", sb1");
3766 break;
d173146d 3767 case EF_MIPS_MACH_9000:
f8c4789c
AM
3768 out = stpcpy (out, ", 9000");
3769 break;
d173146d 3770 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
3771 out = stpcpy (out, ", loongson-2e");
3772 break;
d173146d 3773 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
3774 out = stpcpy (out, ", loongson-2f");
3775 break;
d173146d 3776 case EF_MIPS_MACH_GS464:
f8c4789c
AM
3777 out = stpcpy (out, ", gs464");
3778 break;
d173146d 3779 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
3780 out = stpcpy (out, ", gs464e");
3781 break;
d173146d 3782 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
3783 out = stpcpy (out, ", gs264e");
3784 break;
d173146d 3785 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
3786 out = stpcpy (out, ", octeon");
3787 break;
d173146d 3788 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
3789 out = stpcpy (out, ", octeon2");
3790 break;
d173146d 3791 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
3792 out = stpcpy (out, ", octeon3");
3793 break;
d173146d 3794 case EF_MIPS_MACH_XLR:
f8c4789c
AM
3795 out = stpcpy (out, ", xlr");
3796 break;
d173146d 3797 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
3798 out = stpcpy (out, ", interaptiv-mr2");
3799 break;
d173146d 3800 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
3801 out = stpcpy (out, ", allegrex");
3802 break;
3803 case 0:
3804 /* We simply ignore the field in this case to avoid confusion:
3805 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3806 extension. */
3807 break;
3808 default:
3809 out = stpcpy (out, _(", unknown CPU"));
3810 break;
3811 }
3812
3813 switch ((e_flags & EF_MIPS_ABI))
3814 {
d173146d 3815 case EF_MIPS_ABI_O32:
f8c4789c
AM
3816 out = stpcpy (out, ", o32");
3817 break;
d173146d 3818 case EF_MIPS_ABI_O64:
f8c4789c
AM
3819 out = stpcpy (out, ", o64");
3820 break;
d173146d 3821 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
3822 out = stpcpy (out, ", eabi32");
3823 break;
d173146d 3824 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
3825 out = stpcpy (out, ", eabi64");
3826 break;
3827 case 0:
3828 /* We simply ignore the field in this case to avoid confusion:
3829 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3830 This means it is likely to be an o32 file, but not for
3831 sure. */
3832 break;
3833 default:
3834 out = stpcpy (out, _(", unknown ABI"));
3835 break;
3836 }
3837
3838 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3839 out = stpcpy (out, ", mdmx");
3840
3841 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3842 out = stpcpy (out, ", mips16");
3843
3844 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3845 out = stpcpy (out, ", micromips");
3846
3847 switch ((e_flags & EF_MIPS_ARCH))
3848 {
d173146d 3849 case EF_MIPS_ARCH_1:
f8c4789c
AM
3850 out = stpcpy (out, ", mips1");
3851 break;
d173146d 3852 case EF_MIPS_ARCH_2:
f8c4789c
AM
3853 out = stpcpy (out, ", mips2");
3854 break;
d173146d 3855 case EF_MIPS_ARCH_3:
f8c4789c
AM
3856 out = stpcpy (out, ", mips3");
3857 break;
d173146d 3858 case EF_MIPS_ARCH_4:
f8c4789c
AM
3859 out = stpcpy (out, ", mips4");
3860 break;
d173146d 3861 case EF_MIPS_ARCH_5:
f8c4789c
AM
3862 out = stpcpy (out, ", mips5");
3863 break;
d173146d 3864 case EF_MIPS_ARCH_32:
f8c4789c
AM
3865 out = stpcpy (out, ", mips32");
3866 break;
d173146d 3867 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
3868 out = stpcpy (out, ", mips32r2");
3869 break;
d173146d 3870 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
3871 out = stpcpy (out, ", mips32r6");
3872 break;
d173146d 3873 case EF_MIPS_ARCH_64:
f8c4789c
AM
3874 out = stpcpy (out, ", mips64");
3875 break;
d173146d 3876 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
3877 out = stpcpy (out, ", mips64r2");
3878 break;
d173146d 3879 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
3880 out = stpcpy (out, ", mips64r6");
3881 break;
3882 default:
3883 out = stpcpy (out, _(", unknown ISA"));
3884 break;
3885 }
3886 return out;
3887}
3888
3889static char *
3890decode_MSP430_machine_flags (char *out, unsigned e_flags)
3891{
3892 out = stpcpy (out, _(": architecture variant: "));
3893 switch (e_flags & EF_MSP430_MACH)
3894 {
3895 case E_MSP430_MACH_MSP430x11:
3896 out = stpcpy (out, "MSP430x11");
3897 break;
3898 case E_MSP430_MACH_MSP430x11x1:
3899 out = stpcpy (out, "MSP430x11x1 ");
3900 break;
3901 case E_MSP430_MACH_MSP430x12:
3902 out = stpcpy (out, "MSP430x12");
3903 break;
3904 case E_MSP430_MACH_MSP430x13:
3905 out = stpcpy (out, "MSP430x13");
3906 break;
3907 case E_MSP430_MACH_MSP430x14:
3908 out = stpcpy (out, "MSP430x14");
3909 break;
3910 case E_MSP430_MACH_MSP430x15:
3911 out = stpcpy (out, "MSP430x15");
3912 break;
3913 case E_MSP430_MACH_MSP430x16:
3914 out = stpcpy (out, "MSP430x16");
3915 break;
3916 case E_MSP430_MACH_MSP430x31:
3917 out = stpcpy (out, "MSP430x31");
3918 break;
3919 case E_MSP430_MACH_MSP430x32:
3920 out = stpcpy (out, "MSP430x32");
3921 break;
3922 case E_MSP430_MACH_MSP430x33:
3923 out = stpcpy (out, "MSP430x33");
3924 break;
3925 case E_MSP430_MACH_MSP430x41:
3926 out = stpcpy (out, "MSP430x41");
3927 break;
3928 case E_MSP430_MACH_MSP430x42:
3929 out = stpcpy (out, "MSP430x42");
3930 break;
3931 case E_MSP430_MACH_MSP430x43:
3932 out = stpcpy (out, "MSP430x43");
3933 break;
3934 case E_MSP430_MACH_MSP430x44:
3935 out = stpcpy (out, "MSP430x44");
3936 break;
3937 case E_MSP430_MACH_MSP430X :
3938 out = stpcpy (out, "MSP430X");
3939 break;
3940 default:
3941 out = stpcpy (out, _(": unknown"));
3942 break;
3943 }
3944
3945 if (e_flags & ~ EF_MSP430_MACH)
3946 out = stpcpy (out, _(": unknown extra flag bits also present"));
3947 return out;
3948}
3949
3950static char *
3951decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
3952{
3953 unsigned abi;
3954 unsigned arch;
3955 unsigned config;
3956 unsigned version;
015dc7e1 3957 bool has_fpu = false;
35c08157
KLC
3958
3959 static const char *ABI_STRINGS[] =
3960 {
3961 "ABI v0", /* use r5 as return register; only used in N1213HC */
3962 "ABI v1", /* use r0 as return register */
3963 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3964 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3965 "AABI",
3966 "ABI2 FP+"
35c08157
KLC
3967 };
3968 static const char *VER_STRINGS[] =
3969 {
3970 "Andes ELF V1.3 or older",
3971 "Andes ELF V1.3.1",
3972 "Andes ELF V1.4"
3973 };
3974 static const char *ARCH_STRINGS[] =
3975 {
3976 "",
3977 "Andes Star v1.0",
3978 "Andes Star v2.0",
3979 "Andes Star v3.0",
3980 "Andes Star v3.0m"
3981 };
3982
3983 abi = EF_NDS_ABI & e_flags;
3984 arch = EF_NDS_ARCH & e_flags;
3985 config = EF_NDS_INST & e_flags;
3986 version = EF_NDS32_ELF_VERSION & e_flags;
3987
35c08157
KLC
3988 switch (abi)
3989 {
3990 case E_NDS_ABI_V0:
3991 case E_NDS_ABI_V1:
3992 case E_NDS_ABI_V2:
3993 case E_NDS_ABI_V2FP:
3994 case E_NDS_ABI_AABI:
40c7a7cb 3995 case E_NDS_ABI_V2FP_PLUS:
35c08157 3996 /* In case there are holes in the array. */
f8c4789c 3997 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
3998 break;
3999
4000 default:
f8c4789c 4001 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4002 break;
4003 }
4004
4005 switch (version)
4006 {
4007 case E_NDS32_ELF_VER_1_2:
4008 case E_NDS32_ELF_VER_1_3:
4009 case E_NDS32_ELF_VER_1_4:
f8c4789c 4010 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4011 break;
4012
4013 default:
f8c4789c 4014 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4015 break;
4016 }
4017
4018 if (E_NDS_ABI_V0 == abi)
4019 {
4020 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4021 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4022 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4023 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4024 return out;
35c08157
KLC
4025 }
4026
4027 switch (arch)
4028 {
4029 case E_NDS_ARCH_STAR_V1_0:
4030 case E_NDS_ARCH_STAR_V2_0:
4031 case E_NDS_ARCH_STAR_V3_0:
4032 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4033 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4034 break;
4035
4036 default:
f8c4789c 4037 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4038 /* ARCH version determines how the e_flags are interpreted.
4039 If it is unknown, we cannot proceed. */
f8c4789c 4040 return out;
35c08157
KLC
4041 }
4042
4043 /* Newer ABI; Now handle architecture specific flags. */
4044 if (arch == E_NDS_ARCH_STAR_V1_0)
4045 {
4046 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4047 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4048
4049 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4050 out = stpcpy (out, ", MAC");
35c08157
KLC
4051
4052 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4053 out = stpcpy (out, ", DIV");
35c08157
KLC
4054
4055 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4056 out = stpcpy (out, ", 16b");
35c08157
KLC
4057 }
4058 else
4059 {
4060 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4061 {
4062 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4063 out = stpcpy (out, ", [B8]");
35c08157 4064 else
f8c4789c 4065 out = stpcpy (out, ", EX9");
35c08157
KLC
4066 }
4067
4068 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4069 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4070
4071 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4072 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4073
4074 if (config & E_NDS32_HAS_16BIT_INST)
4075 {
4076 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4077 out = stpcpy (out, ", 16b");
35c08157 4078 else
f8c4789c 4079 out = stpcpy (out, ", IFC");
35c08157
KLC
4080 }
4081 }
4082
4083 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4084 out = stpcpy (out, ", PERF1");
35c08157
KLC
4085
4086 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4087 out = stpcpy (out, ", PERF2");
35c08157
KLC
4088
4089 if (config & E_NDS32_HAS_FPU_INST)
4090 {
015dc7e1 4091 has_fpu = true;
f8c4789c 4092 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4093 }
4094
4095 if (config & E_NDS32_HAS_FPU_DP_INST)
4096 {
015dc7e1 4097 has_fpu = true;
f8c4789c 4098 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4099 }
4100
4101 if (config & E_NDS32_HAS_FPU_MAC_INST)
4102 {
015dc7e1 4103 has_fpu = true;
f8c4789c 4104 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4105 }
4106
4107 if (has_fpu)
4108 {
4109 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4110 {
4111 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4112 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4113 break;
4114 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4115 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4116 break;
4117 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4118 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4119 break;
4120 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4121 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4122 break;
4123 }
4124 }
4125
4126 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4127 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4128
4129 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4130 out = stpcpy (out, ", STR");
35c08157
KLC
4131
4132 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4133 out = stpcpy (out, ", 16REG");
35c08157
KLC
4134
4135 if (config & E_NDS32_HAS_VIDEO_INST)
4136 {
4137 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4138 out = stpcpy (out, ", VIDEO");
35c08157 4139 else
f8c4789c 4140 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4141 }
4142
4143 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4144 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4145
4146 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4147 out = stpcpy (out, ", L2C");
4148
4149 return out;
35c08157
KLC
4150}
4151
f8c4789c
AM
4152static char *
4153decode_PARISC_machine_flags (char *out, unsigned e_flags)
4154{
4155 switch (e_flags & EF_PARISC_ARCH)
4156 {
4157 case EFA_PARISC_1_0:
4158 out = stpcpy (out, ", PA-RISC 1.0");
4159 break;
4160 case EFA_PARISC_1_1:
4161 out = stpcpy (out, ", PA-RISC 1.1");
4162 break;
4163 case EFA_PARISC_2_0:
4164 out = stpcpy (out, ", PA-RISC 2.0");
4165 break;
4166 default:
4167 break;
4168 }
4169 if (e_flags & EF_PARISC_TRAPNIL)
4170 out = stpcpy (out, ", trapnil");
4171 if (e_flags & EF_PARISC_EXT)
4172 out = stpcpy (out, ", ext");
4173 if (e_flags & EF_PARISC_LSB)
4174 out = stpcpy (out, ", lsb");
4175 if (e_flags & EF_PARISC_WIDE)
4176 out = stpcpy (out, ", wide");
4177 if (e_flags & EF_PARISC_NO_KABP)
4178 out = stpcpy (out, ", no kabp");
4179 if (e_flags & EF_PARISC_LAZYSWAP)
4180 out = stpcpy (out, ", lazyswap");
4181 return out;
4182}
4183
4184static char *
4185decode_RISCV_machine_flags (char *out, unsigned e_flags)
4186{
4187 if (e_flags & EF_RISCV_RVC)
4188 out = stpcpy (out, ", RVC");
4189
4190 if (e_flags & EF_RISCV_RVE)
4191 out = stpcpy (out, ", RVE");
4192
4193 if (e_flags & EF_RISCV_TSO)
4194 out = stpcpy (out, ", TSO");
4195
4196 switch (e_flags & EF_RISCV_FLOAT_ABI)
4197 {
4198 case EF_RISCV_FLOAT_ABI_SOFT:
4199 out = stpcpy (out, ", soft-float ABI");
4200 break;
4201
4202 case EF_RISCV_FLOAT_ABI_SINGLE:
4203 out = stpcpy (out, ", single-float ABI");
4204 break;
4205
4206 case EF_RISCV_FLOAT_ABI_DOUBLE:
4207 out = stpcpy (out, ", double-float ABI");
4208 break;
4209
4210 case EF_RISCV_FLOAT_ABI_QUAD:
4211 out = stpcpy (out, ", quad-float ABI");
4212 break;
4213 }
4214 return out;
4215}
4216
4217static char *
4218decode_RL78_machine_flags (char *out, unsigned e_flags)
4219{
4220 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4221 {
4222 case E_FLAG_RL78_ANY_CPU:
4223 break;
4224 case E_FLAG_RL78_G10:
4225 out = stpcpy (out, ", G10");
4226 break;
4227 case E_FLAG_RL78_G13:
4228 out = stpcpy (out, ", G13");
4229 break;
4230 case E_FLAG_RL78_G14:
4231 out = stpcpy (out, ", G14");
4232 break;
4233 }
4234 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4235 out = stpcpy (out, ", 64-bit doubles");
4236 return out;
4237}
4238
4239static char *
4240decode_RX_machine_flags (char *out, unsigned e_flags)
4241{
4242 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4243 out = stpcpy (out, ", 64-bit doubles");
4244 if (e_flags & E_FLAG_RX_DSP)
4245 out = stpcpy (out, ", dsp");
4246 if (e_flags & E_FLAG_RX_PID)
4247 out = stpcpy (out, ", pid");
4248 if (e_flags & E_FLAG_RX_ABI)
4249 out = stpcpy (out, ", RX ABI");
4250 if (e_flags & E_FLAG_RX_SINSNS_SET)
4251 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4252 ? ", uses String instructions"
4253 : ", bans String instructions"));
4254 if (e_flags & E_FLAG_RX_V2)
4255 out = stpcpy (out, ", V2");
4256 if (e_flags & E_FLAG_RX_V3)
4257 out = stpcpy (out, ", V3");
4258 return out;
4259}
4260
4261static char *
4262decode_SH_machine_flags (char *out, unsigned e_flags)
4263{
4264 switch ((e_flags & EF_SH_MACH_MASK))
4265 {
4266 case EF_SH1:
4267 out = stpcpy (out, ", sh1");
4268 break;
4269 case EF_SH2:
4270 out = stpcpy (out, ", sh2");
4271 break;
4272 case EF_SH3:
4273 out = stpcpy (out, ", sh3");
4274 break;
4275 case EF_SH_DSP:
4276 out = stpcpy (out, ", sh-dsp");
4277 break;
4278 case EF_SH3_DSP:
4279 out = stpcpy (out, ", sh3-dsp");
4280 break;
4281 case EF_SH4AL_DSP:
4282 out = stpcpy (out, ", sh4al-dsp");
4283 break;
4284 case EF_SH3E:
4285 out = stpcpy (out, ", sh3e");
4286 break;
4287 case EF_SH4:
4288 out = stpcpy (out, ", sh4");
4289 break;
4290 case EF_SH5:
4291 out = stpcpy (out, ", sh5");
4292 break;
4293 case EF_SH2E:
4294 out = stpcpy (out, ", sh2e");
4295 break;
4296 case EF_SH4A:
4297 out = stpcpy (out, ", sh4a");
4298 break;
4299 case EF_SH2A:
4300 out = stpcpy (out, ", sh2a");
4301 break;
4302 case EF_SH4_NOFPU:
4303 out = stpcpy (out, ", sh4-nofpu");
4304 break;
4305 case EF_SH4A_NOFPU:
4306 out = stpcpy (out, ", sh4a-nofpu");
4307 break;
4308 case EF_SH2A_NOFPU:
4309 out = stpcpy (out, ", sh2a-nofpu");
4310 break;
4311 case EF_SH3_NOMMU:
4312 out = stpcpy (out, ", sh3-nommu");
4313 break;
4314 case EF_SH4_NOMMU_NOFPU:
4315 out = stpcpy (out, ", sh4-nommu-nofpu");
4316 break;
4317 case EF_SH2A_SH4_NOFPU:
4318 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4319 break;
4320 case EF_SH2A_SH3_NOFPU:
4321 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4322 break;
4323 case EF_SH2A_SH4:
4324 out = stpcpy (out, ", sh2a-or-sh4");
4325 break;
4326 case EF_SH2A_SH3E:
4327 out = stpcpy (out, ", sh2a-or-sh3e");
4328 break;
4329 default:
4330 out = stpcpy (out, _(", unknown ISA"));
4331 break;
4332 }
4333
4334 if (e_flags & EF_SH_PIC)
4335 out = stpcpy (out, ", pic");
4336
4337 if (e_flags & EF_SH_FDPIC)
4338 out = stpcpy (out, ", fdpic");
4339 return out;
4340}
4341
4342static char *
4343decode_SPARC_machine_flags (char *out, unsigned e_flags)
4344{
4345 if (e_flags & EF_SPARC_32PLUS)
4346 out = stpcpy (out, ", v8+");
4347
4348 if (e_flags & EF_SPARC_SUN_US1)
4349 out = stpcpy (out, ", ultrasparcI");
4350
4351 if (e_flags & EF_SPARC_SUN_US3)
4352 out = stpcpy (out, ", ultrasparcIII");
4353
4354 if (e_flags & EF_SPARC_HAL_R1)
4355 out = stpcpy (out, ", halr1");
4356
4357 if (e_flags & EF_SPARC_LEDATA)
4358 out = stpcpy (out, ", ledata");
4359
4360 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4361 out = stpcpy (out, ", tso");
4362
4363 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4364 out = stpcpy (out, ", pso");
4365
4366 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4367 out = stpcpy (out, ", rmo");
4368 return out;
4369}
4370
4371static char *
4372decode_V800_machine_flags (char *out, unsigned int e_flags)
4373{
4374 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4375 out = stpcpy (out, ", RH850 ABI");
4376
4377 if (e_flags & EF_V800_850E3)
4378 out = stpcpy (out, ", V3 architecture");
4379
4380 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4381 out = stpcpy (out, ", FPU not used");
4382
4383 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4384 out = stpcpy (out, ", regmode: COMMON");
4385
4386 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4387 out = stpcpy (out, ", r4 not used");
4388
4389 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4390 out = stpcpy (out, ", r30 not used");
4391
4392 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4393 out = stpcpy (out, ", r5 not used");
4394
4395 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4396 out = stpcpy (out, ", r2 not used");
4397
4398 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4399 {
4400 switch (e_flags & - e_flags)
4401 {
4402 case EF_RH850_FPU_DOUBLE:
4403 out = stpcpy (out, ", double precision FPU");
4404 break;
4405 case EF_RH850_FPU_SINGLE:
4406 out = stpcpy (out, ", single precision FPU");
4407 break;
4408 case EF_RH850_REGMODE22:
4409 out = stpcpy (out, ", regmode:22");
4410 break;
4411 case EF_RH850_REGMODE32:
4412 out = stpcpy (out, ", regmode:23");
4413 break;
4414 case EF_RH850_GP_FIX:
4415 out = stpcpy (out, ", r4 fixed");
4416 break;
4417 case EF_RH850_GP_NOFIX:
4418 out = stpcpy (out, ", r4 free");
4419 break;
4420 case EF_RH850_EP_FIX:
4421 out = stpcpy (out, ", r30 fixed");
4422 break;
4423 case EF_RH850_EP_NOFIX:
4424 out = stpcpy (out, ", r30 free");
4425 break;
4426 case EF_RH850_TP_FIX:
4427 out = stpcpy (out, ", r5 fixed");
4428 break;
4429 case EF_RH850_TP_NOFIX:
4430 out = stpcpy (out, ", r5 free");
4431 break;
4432 case EF_RH850_REG2_RESERVE:
4433 out = stpcpy (out, ", r2 fixed");
4434 break;
4435 case EF_RH850_REG2_NORESERVE:
4436 out = stpcpy (out, ", r2 free");
4437 break;
4438 default:
4439 break;
4440 }
4441 }
4442 return out;
4443}
4444
4445static char *
4446decode_V850_machine_flags (char *out, unsigned int e_flags)
4447{
4448 switch (e_flags & EF_V850_ARCH)
4449 {
4450 case E_V850E3V5_ARCH:
4451 out = stpcpy (out, ", v850e3v5");
4452 break;
4453 case E_V850E2V3_ARCH:
4454 out = stpcpy (out, ", v850e2v3");
4455 break;
4456 case E_V850E2_ARCH:
4457 out = stpcpy (out, ", v850e2");
4458 break;
4459 case E_V850E1_ARCH:
4460 out = stpcpy (out, ", v850e1");
4461 break;
4462 case E_V850E_ARCH:
4463 out = stpcpy (out, ", v850e");
4464 break;
4465 case E_V850_ARCH:
4466 out = stpcpy (out, ", v850");
4467 break;
4468 default:
4469 out = stpcpy (out, _(", unknown v850 architecture variant"));
4470 break;
4471 }
4472 return out;
4473}
4474
4475static char *
4476decode_Z80_machine_flags (char *out, unsigned int e_flags)
4477{
4478 switch (e_flags & EF_Z80_MACH_MSK)
4479 {
4480 case EF_Z80_MACH_Z80:
4481 out = stpcpy (out, ", Z80");
4482 break;
4483 case EF_Z80_MACH_Z180:
4484 out = stpcpy (out, ", Z180");
4485 break;
4486 case EF_Z80_MACH_R800:
4487 out = stpcpy (out, ", R800");
4488 break;
4489 case EF_Z80_MACH_EZ80_Z80:
4490 out = stpcpy (out, ", EZ80");
4491 break;
4492 case EF_Z80_MACH_EZ80_ADL:
4493 out = stpcpy (out, ", EZ80, ADL");
4494 break;
4495 case EF_Z80_MACH_GBZ80:
4496 out = stpcpy (out, ", GBZ80");
4497 break;
4498 case EF_Z80_MACH_Z80N:
4499 out = stpcpy (out, ", Z80N");
4500 break;
4501 default:
4502 out = stpcpy (out, _(", unknown"));
4503 break;
4504 }
4505 return out;
4506}
4507
4508static char *
4509decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4510{
4511 unsigned char *e_ident = filedata->file_header.e_ident;
4512 unsigned char osabi = e_ident[EI_OSABI];
4513 unsigned char abiversion = e_ident[EI_ABIVERSION];
4514 unsigned int mach;
4515
4516 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4517 it has been deprecated for a while.
4518
4519 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4520 of writing, they use the same flags as HSA v3, so the code below uses that
4521 assumption. */
4522 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4523 return out;
c077c580
SM
4524
4525 mach = e_flags & EF_AMDGPU_MACH;
4526 switch (mach)
4527 {
4528#define AMDGPU_CASE(code, string) \
f8c4789c 4529 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4530 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4531 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4532 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4533 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4534 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4535 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4536 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4537 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4538 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4539 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4540 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4541 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4542 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4543 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4544 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4545 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4546 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4547 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4548 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4549 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4550 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4551 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4552 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4553 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4554 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4567 default:
f8c4789c 4568 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4569 break;
4570#undef AMDGPU_CASE
4571 }
4572
c077c580
SM
4573 e_flags &= ~EF_AMDGPU_MACH;
4574
4575 if ((osabi == ELFOSABI_AMDGPU_HSA
4576 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4577 || osabi != ELFOSABI_AMDGPU_HSA)
4578 {
4579 /* For HSA v3 and other OS ABIs. */
4580 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4581 {
f8c4789c 4582 out = stpcpy (out, ", xnack on");
c077c580
SM
4583 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4584 }
4585
4586 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4587 {
f8c4789c 4588 out = stpcpy (out, ", sramecc on");
c077c580
SM
4589 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4590 }
4591 }
4592 else
4593 {
4594 /* For HSA v4+. */
4595 int xnack, sramecc;
4596
4597 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4598 switch (xnack)
4599 {
4600 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4601 break;
4602
4603 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4604 out = stpcpy (out, ", xnack any");
c077c580
SM
4605 break;
4606
4607 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4608 out = stpcpy (out, ", xnack off");
c077c580
SM
4609 break;
4610
4611 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4612 out = stpcpy (out, ", xnack on");
c077c580
SM
4613 break;
4614
4615 default:
f8c4789c 4616 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4617 break;
4618 }
4619
c077c580
SM
4620 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4621
4622 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4623 switch (sramecc)
4624 {
4625 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4626 break;
4627
4628 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4629 out = stpcpy (out, ", sramecc any");
c077c580
SM
4630 break;
4631
4632 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4633 out = stpcpy (out, ", sramecc off");
c077c580
SM
4634 break;
4635
4636 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4637 out = stpcpy (out, ", sramecc on");
c077c580
SM
4638 break;
4639
4640 default:
f8c4789c 4641 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4642 break;
4643 }
4644
c077c580
SM
4645 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4646 }
4647
4648 if (e_flags != 0)
f8c4789c
AM
4649 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4650 return out;
c077c580
SM
4651}
4652
252b5132 4653static char *
dda8d76d 4654get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4655{
b34976b6 4656 static char buf[1024];
f8c4789c 4657 char *out = buf;
252b5132
RH
4658
4659 buf[0] = '\0';
76da6bbe 4660
252b5132
RH
4661 if (e_flags)
4662 {
4663 switch (e_machine)
4664 {
4665 default:
4666 break;
4667
b5c37946 4668 case EM_ARC_COMPACT3:
f8c4789c 4669 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4670 break;
4671
4672 case EM_ARC_COMPACT3_64:
f8c4789c 4673 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4674 break;
4675
886a2506 4676 case EM_ARC_COMPACT2:
886a2506 4677 case EM_ARC_COMPACT:
f8c4789c
AM
4678 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4679 break;
886a2506 4680
f3485b74 4681 case EM_ARM:
f8c4789c 4682 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4683 break;
76da6bbe 4684
f8c4789c
AM
4685 case EM_AVR:
4686 out = decode_AVR_machine_flags (out, e_flags);
4687 break;
343433df 4688
781303ce 4689 case EM_BLACKFIN:
f8c4789c 4690 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4691 break;
4692
ec2dfb42 4693 case EM_CYGNUS_FRV:
f8c4789c 4694 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4695 break;
ec2dfb42 4696
53c7db4b 4697 case EM_68K:
f8c4789c 4698 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4699 break;
33c63f9d 4700
c077c580 4701 case EM_AMDGPU:
f8c4789c 4702 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4703 break;
4704
153a2776 4705 case EM_CYGNUS_MEP:
f8c4789c 4706 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4707 break;
4708
252b5132
RH
4709 case EM_PPC:
4710 if (e_flags & EF_PPC_EMB)
f8c4789c 4711 out = stpcpy (out, ", emb");
252b5132
RH
4712
4713 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4714 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4715
4716 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4717 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4718 break;
4719
ee67d69a
AM
4720 case EM_PPC64:
4721 if (e_flags & EF_PPC64_ABI)
f8c4789c 4722 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4723 break;
4724
708e2187 4725 case EM_V800:
f8c4789c 4726 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4727 break;
4728
2b0337b0 4729 case EM_V850:
252b5132 4730 case EM_CYGNUS_V850:
f8c4789c 4731 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4732 break;
4733
2b0337b0 4734 case EM_M32R:
252b5132
RH
4735 case EM_CYGNUS_M32R:
4736 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4737 out = stpcpy (out, ", m32r");
252b5132
RH
4738 break;
4739
4740 case EM_MIPS:
4fe85591 4741 case EM_MIPS_RS3_LE:
f8c4789c 4742 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4743 break;
351b4b40 4744
35c08157 4745 case EM_NDS32:
f8c4789c 4746 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4747 break;
4748
fe944acf
FT
4749 case EM_NFP:
4750 switch (EF_NFP_MACH (e_flags))
4751 {
4752 case E_NFP_MACH_3200:
f8c4789c 4753 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4754 break;
4755 case E_NFP_MACH_6000:
f8c4789c 4756 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4757 break;
4758 }
4759 break;
4760
e23eba97 4761 case EM_RISCV:
f8c4789c 4762 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4763 break;
4764
ccde1100 4765 case EM_SH:
f8c4789c 4766 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4767 break;
948f632f 4768
f8c4789c
AM
4769 case EM_OR1K:
4770 if (e_flags & EF_OR1K_NODELAY)
4771 out = stpcpy (out, ", no delay");
4772 break;
57346661 4773
f8c4789c
AM
4774 case EM_BPF:
4775 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4776 break;
b5c37946 4777
351b4b40 4778 case EM_SPARCV9:
f8c4789c 4779 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4780 break;
7d466069 4781
103f02d3 4782 case EM_PARISC:
f8c4789c 4783 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4784 break;
76da6bbe 4785
7d466069 4786 case EM_PJ:
2b0337b0 4787 case EM_PJ_OLD:
7d466069 4788 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4789 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4790
4791 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4792 out = stpcpy (out, ", gnu calling convention");
7d466069 4793 break;
4d6ed7c8
NC
4794
4795 case EM_IA_64:
f8c4789c 4796 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4797 break;
179d3252
JT
4798
4799 case EM_VAX:
4800 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4801 out = stpcpy (out, ", non-PIC");
179d3252 4802 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4803 out = stpcpy (out, ", D-Float");
179d3252 4804 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4805 out = stpcpy (out, ", G-Float");
179d3252 4806 break;
c7927a3c 4807
f8c4789c 4808 case EM_VISIUM:
619ed720 4809 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4810 out = stpcpy (out, ", mcm");
619ed720 4811 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4812 out = stpcpy (out, ", mcm24");
619ed720 4813 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4814 out = stpcpy (out, ", gr6");
619ed720
EB
4815 break;
4816
4046d87a 4817 case EM_RL78:
f8c4789c 4818 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4819 break;
0b4362b0 4820
c7927a3c 4821 case EM_RX:
f8c4789c 4822 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4823 break;
55786da2
AK
4824
4825 case EM_S390:
4826 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4827 out = stpcpy (out, ", highgprs");
d4cb0ea0 4828 break;
40b36596
JM
4829
4830 case EM_TI_C6000:
4831 if ((e_flags & EF_C6000_REL))
f8c4789c 4832 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4833 break;
13761a11 4834
6e712424
PI
4835 case EM_KVX:
4836 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4837 strcat (buf, ", Kalray VLIW kv3-1");
4838 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4839 strcat (buf, ", Kalray VLIW kv3-2");
4840 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4841 strcat (buf, ", Kalray VLIW kv4-1");
4842 else
4843 strcat (buf, ", unknown KVX MPPA");
4844 break;
4845
13761a11 4846 case EM_MSP430:
f8c4789c 4847 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4848 break;
4849
4850 case EM_Z80:
f8c4789c 4851 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4852 break;
c4a7e6b5 4853
f8c4789c
AM
4854 case EM_LOONGARCH:
4855 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4856 break;
252b5132
RH
4857 }
4858 }
4859
4860 return buf;
4861}
4862
252b5132 4863static const char *
dda8d76d 4864get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4865{
4866 static char buff[32];
4867
4868 switch (osabi)
4869 {
4870 case ELFOSABI_NONE: return "UNIX - System V";
4871 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4872 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4873 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4874 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4875 case ELFOSABI_AIX: return "UNIX - AIX";
4876 case ELFOSABI_IRIX: return "UNIX - IRIX";
4877 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4878 case ELFOSABI_TRU64: return "UNIX - TRU64";
4879 case ELFOSABI_MODESTO: return "Novell - Modesto";
4880 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4881 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4882 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4883 case ELFOSABI_AROS: return "AROS";
11636f9e 4884 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4885 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4886 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4887 default:
40b36596 4888 if (osabi >= 64)
dda8d76d 4889 switch (filedata->file_header.e_machine)
40b36596 4890 {
37870be8
SM
4891 case EM_AMDGPU:
4892 switch (osabi)
4893 {
4894 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4895 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4896 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4897 default:
4898 break;
4899 }
4900 break;
4901
40b36596
JM
4902 case EM_ARM:
4903 switch (osabi)
4904 {
4905 case ELFOSABI_ARM: return "ARM";
18a20338 4906 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4907 default:
4908 break;
4909 }
4910 break;
4911
4912 case EM_MSP430:
4913 case EM_MSP430_OLD:
619ed720 4914 case EM_VISIUM:
40b36596
JM
4915 switch (osabi)
4916 {
4917 case ELFOSABI_STANDALONE: return _("Standalone App");
4918 default:
4919 break;
4920 }
4921 break;
4922
4923 case EM_TI_C6000:
4924 switch (osabi)
4925 {
4926 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4927 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4928 default:
4929 break;
4930 }
4931 break;
4932
4933 default:
4934 break;
4935 }
e9e44622 4936 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4937 return buff;
4938 }
4939}
4940
a06ea964
NC
4941static const char *
4942get_aarch64_segment_type (unsigned long type)
4943{
4944 switch (type)
4945 {
32ec8896 4946 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4947 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4948 default: return NULL;
a06ea964 4949 }
a06ea964
NC
4950}
4951
b294bdf8
MM
4952static const char *
4953get_arm_segment_type (unsigned long type)
4954{
4955 switch (type)
4956 {
32ec8896
NC
4957 case PT_ARM_EXIDX: return "EXIDX";
4958 default: return NULL;
b294bdf8 4959 }
b294bdf8
MM
4960}
4961
b4cbbe8f
AK
4962static const char *
4963get_s390_segment_type (unsigned long type)
4964{
4965 switch (type)
4966 {
4967 case PT_S390_PGSTE: return "S390_PGSTE";
4968 default: return NULL;
4969 }
4970}
4971
d3ba0551
AM
4972static const char *
4973get_mips_segment_type (unsigned long type)
252b5132
RH
4974{
4975 switch (type)
4976 {
32ec8896
NC
4977 case PT_MIPS_REGINFO: return "REGINFO";
4978 case PT_MIPS_RTPROC: return "RTPROC";
4979 case PT_MIPS_OPTIONS: return "OPTIONS";
4980 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4981 default: return NULL;
252b5132 4982 }
252b5132
RH
4983}
4984
103f02d3 4985static const char *
d3ba0551 4986get_parisc_segment_type (unsigned long type)
103f02d3
UD
4987{
4988 switch (type)
4989 {
103f02d3
UD
4990 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4991 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4992 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4993 default: return NULL;
103f02d3 4994 }
103f02d3
UD
4995}
4996
4d6ed7c8 4997static const char *
d3ba0551 4998get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4999{
5000 switch (type)
5001 {
5002 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5003 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5004 default: return NULL;
4d6ed7c8 5005 }
4d6ed7c8
NC
5006}
5007
40b36596
JM
5008static const char *
5009get_tic6x_segment_type (unsigned long type)
5010{
5011 switch (type)
5012 {
32ec8896
NC
5013 case PT_C6000_PHATTR: return "C6000_PHATTR";
5014 default: return NULL;
40b36596 5015 }
40b36596
JM
5016}
5017
fbc95f1e
KC
5018static const char *
5019get_riscv_segment_type (unsigned long type)
5020{
5021 switch (type)
5022 {
5023 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5024 default: return NULL;
5025 }
5026}
5027
df3a023b
AM
5028static const char *
5029get_hpux_segment_type (unsigned long type, unsigned e_machine)
5030{
5031 if (e_machine == EM_PARISC)
5032 switch (type)
5033 {
5034 case PT_HP_TLS: return "HP_TLS";
5035 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5036 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5037 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5038 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5039 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5040 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5041 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5042 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5043 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5044 case PT_HP_PARALLEL: return "HP_PARALLEL";
5045 case PT_HP_FASTBIND: return "HP_FASTBIND";
5046 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5047 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5048 case PT_HP_STACK: return "HP_STACK";
5049 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5050 default: return NULL;
5051 }
5052
5053 if (e_machine == EM_IA_64)
5054 switch (type)
5055 {
5056 case PT_HP_TLS: return "HP_TLS";
5057 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5058 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5059 case PT_IA_64_HP_STACK: return "HP_STACK";
5060 default: return NULL;
5061 }
5062
5063 return NULL;
5064}
5065
5522f910
NC
5066static const char *
5067get_solaris_segment_type (unsigned long type)
5068{
5069 switch (type)
5070 {
5071 case 0x6464e550: return "PT_SUNW_UNWIND";
5072 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5073 case 0x6ffffff7: return "PT_LOSUNW";
5074 case 0x6ffffffa: return "PT_SUNWBSS";
5075 case 0x6ffffffb: return "PT_SUNWSTACK";
5076 case 0x6ffffffc: return "PT_SUNWDTRACE";
5077 case 0x6ffffffd: return "PT_SUNWCAP";
5078 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5079 default: return NULL;
5522f910
NC
5080 }
5081}
5082
252b5132 5083static const char *
dda8d76d 5084get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5085{
b34976b6 5086 static char buff[32];
252b5132
RH
5087
5088 switch (p_type)
5089 {
b34976b6
AM
5090 case PT_NULL: return "NULL";
5091 case PT_LOAD: return "LOAD";
252b5132 5092 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5093 case PT_INTERP: return "INTERP";
5094 case PT_NOTE: return "NOTE";
5095 case PT_SHLIB: return "SHLIB";
5096 case PT_PHDR: return "PHDR";
13ae64f3 5097 case PT_TLS: return "TLS";
32ec8896 5098 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5099 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5100 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5101 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5102 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5103
80251d41 5104 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5105 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5106 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5107 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
3eba3ef3 5108 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5109
252b5132 5110 default:
df3a023b 5111 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5112 {
2cf0635d 5113 const char * result;
103f02d3 5114
dda8d76d 5115 switch (filedata->file_header.e_machine)
252b5132 5116 {
a06ea964
NC
5117 case EM_AARCH64:
5118 result = get_aarch64_segment_type (p_type);
5119 break;
b294bdf8
MM
5120 case EM_ARM:
5121 result = get_arm_segment_type (p_type);
5122 break;
252b5132 5123 case EM_MIPS:
4fe85591 5124 case EM_MIPS_RS3_LE:
252b5132
RH
5125 result = get_mips_segment_type (p_type);
5126 break;
103f02d3
UD
5127 case EM_PARISC:
5128 result = get_parisc_segment_type (p_type);
5129 break;
4d6ed7c8
NC
5130 case EM_IA_64:
5131 result = get_ia64_segment_type (p_type);
5132 break;
40b36596
JM
5133 case EM_TI_C6000:
5134 result = get_tic6x_segment_type (p_type);
5135 break;
b4cbbe8f
AK
5136 case EM_S390:
5137 case EM_S390_OLD:
5138 result = get_s390_segment_type (p_type);
5139 break;
fbc95f1e
KC
5140 case EM_RISCV:
5141 result = get_riscv_segment_type (p_type);
5142 break;
252b5132
RH
5143 default:
5144 result = NULL;
5145 break;
5146 }
103f02d3 5147
252b5132
RH
5148 if (result != NULL)
5149 return result;
103f02d3 5150
1a9ccd70 5151 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5152 }
5153 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5154 {
df3a023b 5155 const char * result = NULL;
103f02d3 5156
df3a023b 5157 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5158 {
df3a023b
AM
5159 case ELFOSABI_GNU:
5160 case ELFOSABI_FREEBSD:
5161 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5162 {
5163 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5164 result = buff;
5165 }
103f02d3 5166 break;
df3a023b
AM
5167 case ELFOSABI_HPUX:
5168 result = get_hpux_segment_type (p_type,
5169 filedata->file_header.e_machine);
5170 break;
5171 case ELFOSABI_SOLARIS:
5172 result = get_solaris_segment_type (p_type);
00428cca 5173 break;
103f02d3 5174 default:
103f02d3
UD
5175 break;
5176 }
103f02d3
UD
5177 if (result != NULL)
5178 return result;
5179
1a9ccd70 5180 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5181 }
252b5132 5182 else
e9e44622 5183 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5184
5185 return buff;
5186 }
5187}
5188
53a346d8
CZ
5189static const char *
5190get_arc_section_type_name (unsigned int sh_type)
5191{
5192 switch (sh_type)
5193 {
5194 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5195 default:
5196 break;
5197 }
5198 return NULL;
5199}
5200
252b5132 5201static const char *
d3ba0551 5202get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5203{
5204 switch (sh_type)
5205 {
b34976b6
AM
5206 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5207 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5208 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5209 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5210 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5211 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5212 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5213 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5214 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5215 case SHT_MIPS_RELD: return "MIPS_RELD";
5216 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5217 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5218 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5219 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5220 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5221 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5222 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5223 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5224 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5225 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5226 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5227 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5228 case SHT_MIPS_LINE: return "MIPS_LINE";
5229 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5230 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5231 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5232 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5233 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5234 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5235 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5236 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5237 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5238 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5239 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5240 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5241 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5242 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5243 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5244 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5245 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5246 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5247 default:
5248 break;
5249 }
5250 return NULL;
5251}
5252
103f02d3 5253static const char *
d3ba0551 5254get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5255{
5256 switch (sh_type)
5257 {
5258 case SHT_PARISC_EXT: return "PARISC_EXT";
5259 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5260 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5261 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5262 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5263 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5264 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5265 default: return NULL;
103f02d3 5266 }
103f02d3
UD
5267}
5268
4d6ed7c8 5269static const char *
dda8d76d 5270get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5271{
18bd398b 5272 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5273 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5274 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5275
4d6ed7c8
NC
5276 switch (sh_type)
5277 {
148b93f2
NC
5278 case SHT_IA_64_EXT: return "IA_64_EXT";
5279 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5280 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5281 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5282 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5283 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5284 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5285 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5286 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5287 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5288 default:
5289 break;
5290 }
5291 return NULL;
5292}
5293
d2b2c203
DJ
5294static const char *
5295get_x86_64_section_type_name (unsigned int sh_type)
5296{
5297 switch (sh_type)
5298 {
5299 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5300 default: return NULL;
d2b2c203 5301 }
d2b2c203
DJ
5302}
5303
a06ea964
NC
5304static const char *
5305get_aarch64_section_type_name (unsigned int sh_type)
5306{
5307 switch (sh_type)
5308 {
32ec8896
NC
5309 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5310 default: return NULL;
a06ea964 5311 }
a06ea964
NC
5312}
5313
40a18ebd
NC
5314static const char *
5315get_arm_section_type_name (unsigned int sh_type)
5316{
5317 switch (sh_type)
5318 {
7f6fed87
NC
5319 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5320 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5321 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5322 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5323 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5324 default: return NULL;
40a18ebd 5325 }
40a18ebd
NC
5326}
5327
40b36596
JM
5328static const char *
5329get_tic6x_section_type_name (unsigned int sh_type)
5330{
5331 switch (sh_type)
5332 {
32ec8896
NC
5333 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5334 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5335 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5336 case SHT_TI_ICODE: return "TI_ICODE";
5337 case SHT_TI_XREF: return "TI_XREF";
5338 case SHT_TI_HANDLER: return "TI_HANDLER";
5339 case SHT_TI_INITINFO: return "TI_INITINFO";
5340 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5341 default: return NULL;
40b36596 5342 }
40b36596
JM
5343}
5344
13761a11 5345static const char *
b0191216 5346get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5347{
5348 switch (sh_type)
5349 {
32ec8896
NC
5350 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5351 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5352 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5353 default: return NULL;
13761a11
NC
5354 }
5355}
5356
fe944acf
FT
5357static const char *
5358get_nfp_section_type_name (unsigned int sh_type)
5359{
5360 switch (sh_type)
5361 {
5362 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5363 case SHT_NFP_INITREG: return "NFP_INITREG";
5364 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5365 default: return NULL;
5366 }
5367}
5368
685080f2
NC
5369static const char *
5370get_v850_section_type_name (unsigned int sh_type)
5371{
5372 switch (sh_type)
5373 {
32ec8896
NC
5374 case SHT_V850_SCOMMON: return "V850 Small Common";
5375 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5376 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5377 case SHT_RENESAS_IOP: return "RENESAS IOP";
5378 case SHT_RENESAS_INFO: return "RENESAS INFO";
5379 default: return NULL;
685080f2
NC
5380 }
5381}
5382
2dc8dd17
JW
5383static const char *
5384get_riscv_section_type_name (unsigned int sh_type)
5385{
5386 switch (sh_type)
5387 {
5388 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5389 default: return NULL;
5390 }
5391}
5392
0861f561
CQ
5393static const char *
5394get_csky_section_type_name (unsigned int sh_type)
5395{
5396 switch (sh_type)
5397 {
5398 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5399 default: return NULL;
5400 }
5401}
5402
252b5132 5403static const char *
dda8d76d 5404get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5405{
b34976b6 5406 static char buff[32];
9fb71ee4 5407 const char * result;
252b5132
RH
5408
5409 switch (sh_type)
5410 {
5411 case SHT_NULL: return "NULL";
5412 case SHT_PROGBITS: return "PROGBITS";
5413 case SHT_SYMTAB: return "SYMTAB";
5414 case SHT_STRTAB: return "STRTAB";
5415 case SHT_RELA: return "RELA";
dd207c13 5416 case SHT_RELR: return "RELR";
252b5132
RH
5417 case SHT_HASH: return "HASH";
5418 case SHT_DYNAMIC: return "DYNAMIC";
5419 case SHT_NOTE: return "NOTE";
5420 case SHT_NOBITS: return "NOBITS";
5421 case SHT_REL: return "REL";
5422 case SHT_SHLIB: return "SHLIB";
5423 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5424 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5425 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5426 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5427 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5428 case SHT_GROUP: return "GROUP";
67ce483b 5429 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5430 case SHT_GNU_verdef: return "VERDEF";
5431 case SHT_GNU_verneed: return "VERNEED";
5432 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5433 case 0x6ffffff0: return "VERSYM";
5434 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5435 case 0x7ffffffd: return "AUXILIARY";
5436 case 0x7fffffff: return "FILTER";
047b2264 5437 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5438
5439 default:
5440 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5441 {
dda8d76d 5442 switch (filedata->file_header.e_machine)
252b5132 5443 {
53a346d8
CZ
5444 case EM_ARC:
5445 case EM_ARC_COMPACT:
5446 case EM_ARC_COMPACT2:
b5c37946
SJ
5447 case EM_ARC_COMPACT3:
5448 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5449 result = get_arc_section_type_name (sh_type);
5450 break;
252b5132 5451 case EM_MIPS:
4fe85591 5452 case EM_MIPS_RS3_LE:
252b5132
RH
5453 result = get_mips_section_type_name (sh_type);
5454 break;
103f02d3
UD
5455 case EM_PARISC:
5456 result = get_parisc_section_type_name (sh_type);
5457 break;
4d6ed7c8 5458 case EM_IA_64:
dda8d76d 5459 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5460 break;
d2b2c203 5461 case EM_X86_64:
8a9036a4 5462 case EM_L1OM:
7a9068fe 5463 case EM_K1OM:
d2b2c203
DJ
5464 result = get_x86_64_section_type_name (sh_type);
5465 break;
a06ea964
NC
5466 case EM_AARCH64:
5467 result = get_aarch64_section_type_name (sh_type);
5468 break;
40a18ebd
NC
5469 case EM_ARM:
5470 result = get_arm_section_type_name (sh_type);
5471 break;
40b36596
JM
5472 case EM_TI_C6000:
5473 result = get_tic6x_section_type_name (sh_type);
5474 break;
13761a11 5475 case EM_MSP430:
b0191216 5476 result = get_msp430_section_type_name (sh_type);
13761a11 5477 break;
fe944acf
FT
5478 case EM_NFP:
5479 result = get_nfp_section_type_name (sh_type);
5480 break;
685080f2
NC
5481 case EM_V800:
5482 case EM_V850:
5483 case EM_CYGNUS_V850:
5484 result = get_v850_section_type_name (sh_type);
5485 break;
2dc8dd17
JW
5486 case EM_RISCV:
5487 result = get_riscv_section_type_name (sh_type);
5488 break;
0861f561
CQ
5489 case EM_CSKY:
5490 result = get_csky_section_type_name (sh_type);
5491 break;
252b5132
RH
5492 default:
5493 result = NULL;
5494 break;
5495 }
5496
5497 if (result != NULL)
5498 return result;
5499
9fb71ee4 5500 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5501 }
5502 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5503 {
dda8d76d 5504 switch (filedata->file_header.e_machine)
148b93f2
NC
5505 {
5506 case EM_IA_64:
dda8d76d 5507 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5508 break;
5509 default:
dda8d76d 5510 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5511 result = get_solaris_section_type (sh_type);
5512 else
1b4b80bf
NC
5513 {
5514 switch (sh_type)
5515 {
5516 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5517 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5518 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5519 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5520 default:
5521 result = NULL;
5522 break;
5523 }
5524 }
148b93f2
NC
5525 break;
5526 }
5527
5528 if (result != NULL)
5529 return result;
5530
9fb71ee4 5531 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5532 }
252b5132 5533 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5534 {
dda8d76d 5535 switch (filedata->file_header.e_machine)
685080f2
NC
5536 {
5537 case EM_V800:
5538 case EM_V850:
5539 case EM_CYGNUS_V850:
9fb71ee4 5540 result = get_v850_section_type_name (sh_type);
a9fb83be 5541 break;
685080f2 5542 default:
9fb71ee4 5543 result = NULL;
685080f2
NC
5544 break;
5545 }
5546
9fb71ee4
NC
5547 if (result != NULL)
5548 return result;
5549
5550 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5551 }
252b5132 5552 else
a7dbfd1c
NC
5553 /* This message is probably going to be displayed in a 15
5554 character wide field, so put the hex value first. */
5555 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5556
252b5132
RH
5557 return buff;
5558 }
5559}
5560
79bc120c
NC
5561enum long_option_values
5562{
5563 OPTION_DEBUG_DUMP = 512,
5564 OPTION_DYN_SYMS,
0f03783c 5565 OPTION_LTO_SYMS,
79bc120c
NC
5566 OPTION_DWARF_DEPTH,
5567 OPTION_DWARF_START,
5568 OPTION_DWARF_CHECK,
5569 OPTION_CTF_DUMP,
5570 OPTION_CTF_PARENT,
5571 OPTION_CTF_SYMBOLS,
5572 OPTION_CTF_STRINGS,
42b6953b 5573 OPTION_SFRAME_DUMP,
79bc120c
NC
5574 OPTION_WITH_SYMBOL_VERSIONS,
5575 OPTION_RECURSE_LIMIT,
5576 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5577 OPTION_NO_DEMANGLING,
b6ac461a 5578 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5579 OPTION_SYM_BASE
79bc120c 5580};
2979dc34 5581
85b1c36d 5582static struct option options[] =
252b5132 5583{
79bc120c
NC
5584 /* Note - This table is alpha-sorted on the 'val'
5585 field in order to make adding new options easier. */
5586 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5587 {"all", no_argument, 0, 'a'},
79bc120c
NC
5588 {"demangle", optional_argument, 0, 'C'},
5589 {"archive-index", no_argument, 0, 'c'},
5590 {"use-dynamic", no_argument, 0, 'D'},
5591 {"dynamic", no_argument, 0, 'd'},
b34976b6 5592 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5593 {"section-groups", no_argument, 0, 'g'},
5594 {"help", no_argument, 0, 'H'},
5595 {"file-header", no_argument, 0, 'h'},
b34976b6 5596 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5597 {"lint", no_argument, 0, 'L'},
5598 {"enable-checks", no_argument, 0, 'L'},
5599 {"program-headers", no_argument, 0, 'l'},
b34976b6 5600 {"segments", no_argument, 0, 'l'},
595cf52e 5601 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5602 {"notes", no_argument, 0, 'n'},
ca0e11aa 5603 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5604 {"string-dump", required_argument, 0, 'p'},
5605 {"relocated-dump", required_argument, 0, 'R'},
5606 {"relocs", no_argument, 0, 'r'},
5607 {"section-headers", no_argument, 0, 'S'},
5608 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5609 {"symbols", no_argument, 0, 's'},
5610 {"syms", no_argument, 0, 's'},
79bc120c
NC
5611 {"silent-truncation",no_argument, 0, 'T'},
5612 {"section-details", no_argument, 0, 't'},
b3aa80b4 5613 {"unicode", required_argument, NULL, 'U'},
09c11c86 5614 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5615 {"version-info", no_argument, 0, 'V'},
5616 {"version", no_argument, 0, 'v'},
5617 {"wide", no_argument, 0, 'W'},
b6ac461a 5618 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5619 {"hex-dump", required_argument, 0, 'x'},
0e602686 5620 {"decompress", no_argument, 0, 'z'},
252b5132 5621
79bc120c 5622 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5623 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5624 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5625 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5626 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5627 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5628 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5629 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5630 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5631 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5632 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5633#ifdef ENABLE_LIBCTF
d344b407 5634 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5635 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5636 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5637 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5638#endif
42b6953b 5639 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5640 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5641
b34976b6 5642 {0, no_argument, 0, 0}
252b5132
RH
5643};
5644
5645static void
2cf0635d 5646usage (FILE * stream)
252b5132 5647{
92f01d61
JM
5648 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5649 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5650 fprintf (stream, _(" Options are:\n"));
5651 fprintf (stream, _("\
5652 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5653 fprintf (stream, _("\
5654 -h --file-header Display the ELF file header\n"));
5655 fprintf (stream, _("\
5656 -l --program-headers Display the program headers\n"));
5657 fprintf (stream, _("\
5658 --segments An alias for --program-headers\n"));
5659 fprintf (stream, _("\
5660 -S --section-headers Display the sections' header\n"));
5661 fprintf (stream, _("\
5662 --sections An alias for --section-headers\n"));
5663 fprintf (stream, _("\
5664 -g --section-groups Display the section groups\n"));
5665 fprintf (stream, _("\
5666 -t --section-details Display the section details\n"));
5667 fprintf (stream, _("\
5668 -e --headers Equivalent to: -h -l -S\n"));
5669 fprintf (stream, _("\
5670 -s --syms Display the symbol table\n"));
5671 fprintf (stream, _("\
5672 --symbols An alias for --syms\n"));
5673 fprintf (stream, _("\
5674 --dyn-syms Display the dynamic symbol table\n"));
5675 fprintf (stream, _("\
5676 --lto-syms Display LTO symbol tables\n"));
5677 fprintf (stream, _("\
047c3dbf
NL
5678 --sym-base=[0|8|10|16] \n\
5679 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5680 mixed (the default), octal, decimal, hexadecimal.\n"));
5681 fprintf (stream, _("\
0d646226
AM
5682 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5683 display_demangler_styles (stream, _("\
5684 STYLE can be "));
d6249f5f
AM
5685 fprintf (stream, _("\
5686 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5687 fprintf (stream, _("\
5688 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5689 fprintf (stream, _("\
5690 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5691 fprintf (stream, _("\
5692 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5693 Display unicode characters as determined by the current locale\n\
5694 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5695 escape sequences, or treat them as invalid and display as\n\
5696 \"{hex sequences}\"\n"));
d6249f5f 5697 fprintf (stream, _("\
b6ac461a
NC
5698 -X --extra-sym-info Display extra information when showing symbols\n"));
5699 fprintf (stream, _("\
5700 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5701 fprintf (stream, _("\
5702 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5703 fprintf (stream, _("\
5704 -r --relocs Display the relocations (if present)\n"));
5705 fprintf (stream, _("\
5706 -u --unwind Display the unwind info (if present)\n"));
5707 fprintf (stream, _("\
5708 -d --dynamic Display the dynamic section (if present)\n"));
5709 fprintf (stream, _("\
5710 -V --version-info Display the version sections (if present)\n"));
5711 fprintf (stream, _("\
5712 -A --arch-specific Display architecture specific information (if any)\n"));
5713 fprintf (stream, _("\
5714 -c --archive-index Display the symbol/file index in an archive\n"));
5715 fprintf (stream, _("\
5716 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5717 fprintf (stream, _("\
5718 -L --lint|--enable-checks\n\
5719 Display warning messages for possible problems\n"));
5720 fprintf (stream, _("\
09c11c86 5721 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5722 Dump the contents of section <number|name> as bytes\n"));
5723 fprintf (stream, _("\
09c11c86 5724 -p --string-dump=<number|name>\n\
d6249f5f
AM
5725 Dump the contents of section <number|name> as strings\n"));
5726 fprintf (stream, _("\
cf13d699 5727 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5728 Dump the relocated contents of section <number|name>\n"));
5729 fprintf (stream, _("\
5730 -z --decompress Decompress section before dumping it\n"));
5731 fprintf (stream, _("\
5732 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5733 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5734 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5735 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5736 U/=trace_info]\n\
5737 Display the contents of DWARF debug sections\n"));
5738 fprintf (stream, _("\
5739 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5740 debuginfo files\n"));
5741 fprintf (stream, _("\
5742 -P --process-links Display the contents of non-debug sections in separate\n\
5743 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5744#if DEFAULT_FOR_FOLLOW_LINKS
5745 fprintf (stream, _("\
d6249f5f
AM
5746 -wK --debug-dump=follow-links\n\
5747 Follow links to separate debug info files (default)\n"));
5748 fprintf (stream, _("\
5749 -wN --debug-dump=no-follow-links\n\
5750 Do not follow links to separate debug info files\n"));
c46b7066
NC
5751#else
5752 fprintf (stream, _("\
d6249f5f
AM
5753 -wK --debug-dump=follow-links\n\
5754 Follow links to separate debug info files\n"));
5755 fprintf (stream, _("\
5756 -wN --debug-dump=no-follow-links\n\
5757 Do not follow links to separate debug info files\n\
5758 (default)\n"));
bed566bb
NC
5759#endif
5760#if HAVE_LIBDEBUGINFOD
5761 fprintf (stream, _("\
5762 -wD --debug-dump=use-debuginfod\n\
5763 When following links, also query debuginfod servers (default)\n"));
5764 fprintf (stream, _("\
5765 -wE --debug-dump=do-not-use-debuginfod\n\
5766 When following links, do not query debuginfod servers\n"));
c46b7066 5767#endif
fd2f0033 5768 fprintf (stream, _("\
d6249f5f
AM
5769 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5770 fprintf (stream, _("\
5771 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5772#ifdef ENABLE_LIBCTF
7d9813f1 5773 fprintf (stream, _("\
d6249f5f
AM
5774 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5775 fprintf (stream, _("\
80b56fad 5776 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5777 fprintf (stream, _("\
7d9813f1 5778 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5779 Use section <number|name> as the CTF external symtab\n"));
5780 fprintf (stream, _("\
7d9813f1 5781 --ctf-strings=<number|name>\n\
d6249f5f 5782 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5783#endif
42b6953b
IB
5784 fprintf (stream, _("\
5785 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5786
252b5132 5787#ifdef SUPPORT_DISASSEMBLY
92f01d61 5788 fprintf (stream, _("\
09c11c86
NC
5789 -i --instruction-dump=<number|name>\n\
5790 Disassemble the contents of section <number|name>\n"));
252b5132 5791#endif
92f01d61 5792 fprintf (stream, _("\
d6249f5f
AM
5793 -I --histogram Display histogram of bucket list lengths\n"));
5794 fprintf (stream, _("\
5795 -W --wide Allow output width to exceed 80 characters\n"));
5796 fprintf (stream, _("\
5797 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5798 fprintf (stream, _("\
5799 @<file> Read options from <file>\n"));
5800 fprintf (stream, _("\
5801 -H --help Display this information\n"));
5802 fprintf (stream, _("\
8b53311e 5803 -v --version Display the version number of readelf\n"));
1118d252 5804
92f01d61
JM
5805 if (REPORT_BUGS_TO[0] && stream == stdout)
5806 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5807
92f01d61 5808 exit (stream == stdout ? 0 : 1);
252b5132
RH
5809}
5810
18bd398b
NC
5811/* Record the fact that the user wants the contents of section number
5812 SECTION to be displayed using the method(s) encoded as flags bits
5813 in TYPE. Note, TYPE can be zero if we are creating the array for
5814 the first time. */
5815
252b5132 5816static void
6431e409
AM
5817request_dump_bynumber (struct dump_data *dumpdata,
5818 unsigned int section, dump_type type)
252b5132 5819{
6431e409 5820 if (section >= dumpdata->num_dump_sects)
252b5132 5821 {
2cf0635d 5822 dump_type * new_dump_sects;
252b5132 5823
3f5e193b 5824 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5825 sizeof (* new_dump_sects));
252b5132
RH
5826
5827 if (new_dump_sects == NULL)
591a748a 5828 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5829 else
5830 {
6431e409 5831 if (dumpdata->dump_sects)
21b65bac
NC
5832 {
5833 /* Copy current flag settings. */
6431e409
AM
5834 memcpy (new_dump_sects, dumpdata->dump_sects,
5835 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5836
6431e409 5837 free (dumpdata->dump_sects);
21b65bac 5838 }
252b5132 5839
6431e409
AM
5840 dumpdata->dump_sects = new_dump_sects;
5841 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5842 }
5843 }
5844
6431e409
AM
5845 if (dumpdata->dump_sects)
5846 dumpdata->dump_sects[section] |= type;
252b5132
RH
5847}
5848
aef1f6d0
DJ
5849/* Request a dump by section name. */
5850
5851static void
2cf0635d 5852request_dump_byname (const char * section, dump_type type)
aef1f6d0 5853{
2cf0635d 5854 struct dump_list_entry * new_request;
aef1f6d0 5855
3f5e193b
NC
5856 new_request = (struct dump_list_entry *)
5857 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5858 if (!new_request)
591a748a 5859 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5860
5861 new_request->name = strdup (section);
5862 if (!new_request->name)
591a748a 5863 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5864
5865 new_request->type = type;
5866
5867 new_request->next = dump_sects_byname;
5868 dump_sects_byname = new_request;
5869}
5870
cf13d699 5871static inline void
6431e409 5872request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5873{
5874 int section;
5875 char * cp;
5876
015dc7e1 5877 do_dump = true;
cf13d699
NC
5878 section = strtoul (optarg, & cp, 0);
5879
5880 if (! *cp && section >= 0)
6431e409 5881 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5882 else
5883 request_dump_byname (optarg, type);
5884}
5885
252b5132 5886static void
6431e409 5887parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5888{
5889 int c;
5890
5891 if (argc < 2)
92f01d61 5892 usage (stderr);
252b5132
RH
5893
5894 while ((c = getopt_long
b6ac461a 5895 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5896 {
252b5132
RH
5897 switch (c)
5898 {
5899 case 0:
5900 /* Long options. */
5901 break;
5902 case 'H':
92f01d61 5903 usage (stdout);
252b5132
RH
5904 break;
5905
5906 case 'a':
015dc7e1
AM
5907 do_syms = true;
5908 do_reloc = true;
5909 do_unwind = true;
5910 do_dynamic = true;
5911 do_header = true;
5912 do_sections = true;
5913 do_section_groups = true;
5914 do_segments = true;
5915 do_version = true;
5916 do_histogram = true;
5917 do_arch = true;
5918 do_notes = true;
252b5132 5919 break;
79bc120c 5920
f5842774 5921 case 'g':
015dc7e1 5922 do_section_groups = true;
f5842774 5923 break;
5477e8a0 5924 case 't':
595cf52e 5925 case 'N':
015dc7e1
AM
5926 do_sections = true;
5927 do_section_details = true;
595cf52e 5928 break;
252b5132 5929 case 'e':
015dc7e1
AM
5930 do_header = true;
5931 do_sections = true;
5932 do_segments = true;
252b5132 5933 break;
a952a375 5934 case 'A':
015dc7e1 5935 do_arch = true;
a952a375 5936 break;
252b5132 5937 case 'D':
015dc7e1 5938 do_using_dynamic = true;
252b5132
RH
5939 break;
5940 case 'r':
015dc7e1 5941 do_reloc = true;
252b5132 5942 break;
4d6ed7c8 5943 case 'u':
015dc7e1 5944 do_unwind = true;
4d6ed7c8 5945 break;
252b5132 5946 case 'h':
015dc7e1 5947 do_header = true;
252b5132
RH
5948 break;
5949 case 'l':
015dc7e1 5950 do_segments = true;
252b5132
RH
5951 break;
5952 case 's':
015dc7e1 5953 do_syms = true;
252b5132
RH
5954 break;
5955 case 'S':
015dc7e1 5956 do_sections = true;
252b5132
RH
5957 break;
5958 case 'd':
015dc7e1 5959 do_dynamic = true;
252b5132 5960 break;
a952a375 5961 case 'I':
015dc7e1 5962 do_histogram = true;
a952a375 5963 break;
779fe533 5964 case 'n':
015dc7e1 5965 do_notes = true;
779fe533 5966 break;
4145f1d5 5967 case 'c':
015dc7e1 5968 do_archive_index = true;
4145f1d5 5969 break;
1b513401 5970 case 'L':
015dc7e1 5971 do_checks = true;
1b513401 5972 break;
ca0e11aa 5973 case 'P':
015dc7e1
AM
5974 process_links = true;
5975 do_follow_links = true;
e1dbfc17 5976 dump_any_debugging = true;
ca0e11aa 5977 break;
252b5132 5978 case 'x':
6431e409 5979 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5980 break;
09c11c86 5981 case 'p':
6431e409 5982 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5983 break;
5984 case 'R':
6431e409 5985 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5986 break;
0e602686 5987 case 'z':
015dc7e1 5988 decompress_dumps = true;
0e602686 5989 break;
252b5132 5990 case 'w':
0f03783c 5991 if (optarg == NULL)
613ff48b 5992 {
015dc7e1 5993 do_debugging = true;
94585d6d
NC
5994 do_dump = true;
5995 dump_any_debugging = true;
613ff48b
CC
5996 dwarf_select_sections_all ();
5997 }
252b5132
RH
5998 else
5999 {
015dc7e1 6000 do_debugging = false;
94585d6d
NC
6001 if (dwarf_select_sections_by_letters (optarg))
6002 {
6003 do_dump = true;
6004 dump_any_debugging = true;
6005 }
252b5132
RH
6006 }
6007 break;
2979dc34 6008 case OPTION_DEBUG_DUMP:
0f03783c 6009 if (optarg == NULL)
d6249f5f 6010 {
94585d6d 6011 do_dump = true;
d6249f5f 6012 do_debugging = true;
94585d6d 6013 dump_any_debugging = true;
d6249f5f
AM
6014 dwarf_select_sections_all ();
6015 }
2979dc34
JJ
6016 else
6017 {
015dc7e1 6018 do_debugging = false;
94585d6d
NC
6019 if (dwarf_select_sections_by_names (optarg))
6020 {
6021 do_dump = true;
6022 dump_any_debugging = true;
6023 }
2979dc34
JJ
6024 }
6025 break;
fd2f0033
TT
6026 case OPTION_DWARF_DEPTH:
6027 {
6028 char *cp;
6029
6030 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6031 }
6032 break;
6033 case OPTION_DWARF_START:
6034 {
6035 char *cp;
6036
6037 dwarf_start_die = strtoul (optarg, & cp, 0);
6038 }
6039 break;
4723351a 6040 case OPTION_DWARF_CHECK:
015dc7e1 6041 dwarf_check = true;
4723351a 6042 break;
7d9813f1 6043 case OPTION_CTF_DUMP:
015dc7e1 6044 do_ctf = true;
6431e409 6045 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6046 break;
6047 case OPTION_CTF_SYMBOLS:
df16e041 6048 free (dump_ctf_symtab_name);
7d9813f1
NA
6049 dump_ctf_symtab_name = strdup (optarg);
6050 break;
6051 case OPTION_CTF_STRINGS:
df16e041 6052 free (dump_ctf_strtab_name);
7d9813f1
NA
6053 dump_ctf_strtab_name = strdup (optarg);
6054 break;
6055 case OPTION_CTF_PARENT:
df16e041 6056 free (dump_ctf_parent_name);
7d9813f1
NA
6057 dump_ctf_parent_name = strdup (optarg);
6058 break;
42b6953b
IB
6059 case OPTION_SFRAME_DUMP:
6060 do_sframe = true;
6061 /* Providing section name is optional. request_dump (), however,
6062 thrives on non NULL optarg. Handle it explicitly here. */
6063 if (optarg != NULL)
6064 request_dump (dumpdata, SFRAME_DUMP);
6065 else
6066 {
6067 do_dump = true;
6068 const char *sframe_sec_name = strdup (".sframe");
6069 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6070 }
6071 break;
2c610e4b 6072 case OPTION_DYN_SYMS:
015dc7e1 6073 do_dyn_syms = true;
2c610e4b 6074 break;
0f03783c 6075 case OPTION_LTO_SYMS:
015dc7e1 6076 do_lto_syms = true;
0f03783c 6077 break;
b6ac461a
NC
6078 case 'X':
6079 extra_sym_info = true;
6080 break;
6081 case OPTION_NO_EXTRA_SYM_INFO:
6082 extra_sym_info = false;
6083 break;
6084
252b5132
RH
6085#ifdef SUPPORT_DISASSEMBLY
6086 case 'i':
6431e409 6087 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6088 break;
252b5132
RH
6089#endif
6090 case 'v':
6091 print_version (program_name);
6092 break;
6093 case 'V':
015dc7e1 6094 do_version = true;
252b5132 6095 break;
d974e256 6096 case 'W':
015dc7e1 6097 do_wide = true;
d974e256 6098 break;
0942c7ab 6099 case 'T':
015dc7e1 6100 do_not_show_symbol_truncation = true;
0942c7ab 6101 break;
79bc120c 6102 case 'C':
015dc7e1 6103 do_demangle = true;
79bc120c
NC
6104 if (optarg != NULL)
6105 {
6106 enum demangling_styles style;
6107
6108 style = cplus_demangle_name_to_style (optarg);
6109 if (style == unknown_demangling)
6110 error (_("unknown demangling style `%s'"), optarg);
6111
6112 cplus_demangle_set_style (style);
6113 }
6114 break;
6115 case OPTION_NO_DEMANGLING:
015dc7e1 6116 do_demangle = false;
79bc120c
NC
6117 break;
6118 case OPTION_RECURSE_LIMIT:
6119 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6120 break;
6121 case OPTION_NO_RECURSE_LIMIT:
6122 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6123 break;
6124 case OPTION_WITH_SYMBOL_VERSIONS:
6125 /* Ignored for backward compatibility. */
6126 break;
b9e920ec 6127
b3aa80b4
NC
6128 case 'U':
6129 if (optarg == NULL)
6130 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6131 else if (streq (optarg, "default") || streq (optarg, "d"))
6132 unicode_display = unicode_default;
6133 else if (streq (optarg, "locale") || streq (optarg, "l"))
6134 unicode_display = unicode_locale;
6135 else if (streq (optarg, "escape") || streq (optarg, "e"))
6136 unicode_display = unicode_escape;
6137 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6138 unicode_display = unicode_invalid;
6139 else if (streq (optarg, "hex") || streq (optarg, "x"))
6140 unicode_display = unicode_hex;
6141 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6142 unicode_display = unicode_highlight;
6143 else
6144 error (_("invalid argument to -U/--unicode: %s"), optarg);
6145 break;
6146
047c3dbf
NL
6147 case OPTION_SYM_BASE:
6148 sym_base = 0;
6149 if (optarg != NULL)
6150 {
6151 sym_base = strtoul (optarg, NULL, 0);
6152 switch (sym_base)
6153 {
6154 case 0:
6155 case 8:
6156 case 10:
6157 case 16:
6158 break;
6159
6160 default:
6161 sym_base = 0;
6162 break;
6163 }
6164 }
6165 break;
6166
252b5132 6167 default:
252b5132
RH
6168 /* xgettext:c-format */
6169 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6170 /* Fall through. */
252b5132 6171 case '?':
92f01d61 6172 usage (stderr);
252b5132
RH
6173 }
6174 }
6175
4d6ed7c8 6176 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6177 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6178 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6179 && !do_section_groups && !do_archive_index
0f03783c 6180 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6181 {
6182 if (do_checks)
6183 {
015dc7e1
AM
6184 check_all = true;
6185 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6186 do_segments = do_header = do_dump = do_version = true;
6187 do_histogram = do_debugging = do_arch = do_notes = true;
6188 do_section_groups = do_archive_index = do_dyn_syms = true;
6189 do_lto_syms = true;
1b513401
NC
6190 }
6191 else
6192 usage (stderr);
6193 }
252b5132
RH
6194}
6195
6196static const char *
d3ba0551 6197get_elf_class (unsigned int elf_class)
252b5132 6198{
b34976b6 6199 static char buff[32];
103f02d3 6200
252b5132
RH
6201 switch (elf_class)
6202 {
6203 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6204 case ELFCLASS32: return "ELF32";
6205 case ELFCLASS64: return "ELF64";
ab5e7794 6206 default:
e9e44622 6207 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6208 return buff;
252b5132
RH
6209 }
6210}
6211
6212static const char *
d3ba0551 6213get_data_encoding (unsigned int encoding)
252b5132 6214{
b34976b6 6215 static char buff[32];
103f02d3 6216
252b5132
RH
6217 switch (encoding)
6218 {
6219 case ELFDATANONE: return _("none");
33c63f9d
CM
6220 case ELFDATA2LSB: return _("2's complement, little endian");
6221 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6222 default:
e9e44622 6223 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6224 return buff;
252b5132
RH
6225 }
6226}
6227
521f7268
NC
6228static bool
6229check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6230{
6231 if (header->e_ident[EI_MAG0] == ELFMAG0
6232 && header->e_ident[EI_MAG1] == ELFMAG1
6233 && header->e_ident[EI_MAG2] == ELFMAG2
6234 && header->e_ident[EI_MAG3] == ELFMAG3)
6235 return true;
6236
6237 /* Some compilers produce object files that are not in the ELF file format.
6238 As an aid to users of readelf, try to identify these cases and suggest
6239 alternative tools.
6240
6241 FIXME: It is not clear if all four bytes are used as constant magic
6242 valus by all compilers. It may be necessary to recode this function if
6243 different tools use different length sequences. */
6244
6245 static struct
6246 {
6247 unsigned char magic[4];
6248 const char * obj_message;
6249 const char * ar_message;
6250 }
6251 known_magic[] =
6252 {
6253 { { 'B', 'C', 0xc0, 0xde },
6254 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6255 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6256 },
6257 { { 'g', 'o', ' ', 'o' },
6258 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6259 NULL
6260 }
6261 };
6262 int i;
6263
6264 for (i = ARRAY_SIZE (known_magic); i--;)
6265 {
6266 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6267 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6268 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6269 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6270 {
6271 /* Some compiler's analyzer tools do not handle archives,
6272 so we provide two different kinds of error message. */
6273 if (filedata->archive_file_size > 0
6274 && known_magic[i].ar_message != NULL)
b3ea2010 6275 error ("%s", known_magic[i].ar_message);
521f7268 6276 else
b3ea2010 6277 error ("%s", known_magic[i].obj_message);
521f7268
NC
6278 return false;
6279 }
6280 }
6281
6282 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6283 return false;
6284}
6285
dda8d76d 6286/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6287
015dc7e1 6288static bool
dda8d76d 6289process_file_header (Filedata * filedata)
252b5132 6290{
dda8d76d
NC
6291 Elf_Internal_Ehdr * header = & filedata->file_header;
6292
521f7268
NC
6293 if (! check_magic_number (filedata, header))
6294 return false;
252b5132 6295
ca0e11aa
NC
6296 if (! filedata->is_separate)
6297 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6298
252b5132
RH
6299 if (do_header)
6300 {
32ec8896 6301 unsigned i;
252b5132 6302
ca0e11aa
NC
6303 if (filedata->is_separate)
6304 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6305 else
6306 printf (_("ELF Header:\n"));
252b5132 6307 printf (_(" Magic: "));
b34976b6 6308 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6309 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6310 printf ("\n");
6311 printf (_(" Class: %s\n"),
dda8d76d 6312 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6313 printf (_(" Data: %s\n"),
dda8d76d 6314 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6315 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6316 header->e_ident[EI_VERSION],
6317 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6318 ? _(" (current)")
dda8d76d 6319 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6320 ? _(" <unknown>")
789be9f7 6321 : "")));
252b5132 6322 printf (_(" OS/ABI: %s\n"),
dda8d76d 6323 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6324 printf (_(" ABI Version: %d\n"),
dda8d76d 6325 header->e_ident[EI_ABIVERSION]);
252b5132 6326 printf (_(" Type: %s\n"),
93df3340 6327 get_file_type (filedata));
252b5132 6328 printf (_(" Machine: %s\n"),
dda8d76d 6329 get_machine_name (header->e_machine));
252b5132 6330 printf (_(" Version: 0x%lx\n"),
e8a64888 6331 header->e_version);
76da6bbe 6332
f7a99963 6333 printf (_(" Entry point address: "));
e8a64888 6334 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6335 printf (_("\n Start of program headers: "));
e8a64888 6336 print_vma (header->e_phoff, DEC);
f7a99963 6337 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6338 print_vma (header->e_shoff, DEC);
f7a99963 6339 printf (_(" (bytes into file)\n"));
76da6bbe 6340
252b5132 6341 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6342 header->e_flags,
dda8d76d 6343 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6344 printf (_(" Size of this header: %u (bytes)\n"),
6345 header->e_ehsize);
6346 printf (_(" Size of program headers: %u (bytes)\n"),
6347 header->e_phentsize);
6348 printf (_(" Number of program headers: %u"),
6349 header->e_phnum);
dda8d76d
NC
6350 if (filedata->section_headers != NULL
6351 && header->e_phnum == PN_XNUM
6352 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6353 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6354 putc ('\n', stdout);
e8a64888
AM
6355 printf (_(" Size of section headers: %u (bytes)\n"),
6356 header->e_shentsize);
6357 printf (_(" Number of section headers: %u"),
6358 header->e_shnum);
dda8d76d 6359 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6360 {
6361 header->e_shnum = filedata->section_headers[0].sh_size;
6362 printf (" (%u)", header->e_shnum);
6363 }
560f3c1c 6364 putc ('\n', stdout);
e8a64888
AM
6365 printf (_(" Section header string table index: %u"),
6366 header->e_shstrndx);
dda8d76d
NC
6367 if (filedata->section_headers != NULL
6368 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6369 {
6370 header->e_shstrndx = filedata->section_headers[0].sh_link;
6371 printf (" (%u)", header->e_shstrndx);
6372 }
6373 if (header->e_shstrndx != SHN_UNDEF
6374 && header->e_shstrndx >= header->e_shnum)
6375 {
6376 header->e_shstrndx = SHN_UNDEF;
6377 printf (_(" <corrupt: out of range>"));
6378 }
560f3c1c
AM
6379 putc ('\n', stdout);
6380 }
6381
dda8d76d 6382 if (filedata->section_headers != NULL)
560f3c1c 6383 {
dda8d76d
NC
6384 if (header->e_phnum == PN_XNUM
6385 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6386 {
6387 /* Throw away any cached read of PN_XNUM headers. */
6388 free (filedata->program_headers);
6389 filedata->program_headers = NULL;
6390 header->e_phnum = filedata->section_headers[0].sh_info;
6391 }
dda8d76d
NC
6392 if (header->e_shnum == SHN_UNDEF)
6393 header->e_shnum = filedata->section_headers[0].sh_size;
6394 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6395 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6396 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6397 header->e_shstrndx = SHN_UNDEF;
252b5132 6398 }
103f02d3 6399
015dc7e1 6400 return true;
9ea033b2
NC
6401}
6402
dda8d76d
NC
6403/* Read in the program headers from FILEDATA and store them in PHEADERS.
6404 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6405
015dc7e1 6406static bool
dda8d76d 6407get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6408{
2cf0635d
NC
6409 Elf32_External_Phdr * phdrs;
6410 Elf32_External_Phdr * external;
6411 Elf_Internal_Phdr * internal;
b34976b6 6412 unsigned int i;
dda8d76d
NC
6413 unsigned int size = filedata->file_header.e_phentsize;
6414 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6415
6416 /* PR binutils/17531: Cope with unexpected section header sizes. */
6417 if (size == 0 || num == 0)
015dc7e1 6418 return false;
e0a31db1
NC
6419 if (size < sizeof * phdrs)
6420 {
6421 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6422 return false;
e0a31db1
NC
6423 }
6424 if (size > sizeof * phdrs)
6425 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6426
dda8d76d 6427 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6428 size, num, _("program headers"));
6429 if (phdrs == NULL)
015dc7e1 6430 return false;
9ea033b2 6431
91d6fa6a 6432 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6433 i < filedata->file_header.e_phnum;
b34976b6 6434 i++, internal++, external++)
252b5132 6435 {
9ea033b2
NC
6436 internal->p_type = BYTE_GET (external->p_type);
6437 internal->p_offset = BYTE_GET (external->p_offset);
6438 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6439 internal->p_paddr = BYTE_GET (external->p_paddr);
6440 internal->p_filesz = BYTE_GET (external->p_filesz);
6441 internal->p_memsz = BYTE_GET (external->p_memsz);
6442 internal->p_flags = BYTE_GET (external->p_flags);
6443 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6444 }
6445
9ea033b2 6446 free (phdrs);
015dc7e1 6447 return true;
252b5132
RH
6448}
6449
dda8d76d
NC
6450/* Read in the program headers from FILEDATA and store them in PHEADERS.
6451 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6452
015dc7e1 6453static bool
dda8d76d 6454get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6455{
2cf0635d
NC
6456 Elf64_External_Phdr * phdrs;
6457 Elf64_External_Phdr * external;
6458 Elf_Internal_Phdr * internal;
b34976b6 6459 unsigned int i;
dda8d76d
NC
6460 unsigned int size = filedata->file_header.e_phentsize;
6461 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6462
6463 /* PR binutils/17531: Cope with unexpected section header sizes. */
6464 if (size == 0 || num == 0)
015dc7e1 6465 return false;
e0a31db1
NC
6466 if (size < sizeof * phdrs)
6467 {
6468 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6469 return false;
e0a31db1
NC
6470 }
6471 if (size > sizeof * phdrs)
6472 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6473
dda8d76d 6474 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6475 size, num, _("program headers"));
a6e9f9df 6476 if (!phdrs)
015dc7e1 6477 return false;
9ea033b2 6478
91d6fa6a 6479 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6480 i < filedata->file_header.e_phnum;
b34976b6 6481 i++, internal++, external++)
9ea033b2
NC
6482 {
6483 internal->p_type = BYTE_GET (external->p_type);
6484 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6485 internal->p_offset = BYTE_GET (external->p_offset);
6486 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6487 internal->p_paddr = BYTE_GET (external->p_paddr);
6488 internal->p_filesz = BYTE_GET (external->p_filesz);
6489 internal->p_memsz = BYTE_GET (external->p_memsz);
6490 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6491 }
6492
6493 free (phdrs);
015dc7e1 6494 return true;
9ea033b2 6495}
252b5132 6496
32ec8896 6497/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6498
015dc7e1 6499static bool
dda8d76d 6500get_program_headers (Filedata * filedata)
d93f0186 6501{
2cf0635d 6502 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6503
6504 /* Check cache of prior read. */
dda8d76d 6505 if (filedata->program_headers != NULL)
015dc7e1 6506 return true;
d93f0186 6507
82156ab7
NC
6508 /* Be kind to memory checkers by looking for
6509 e_phnum values which we know must be invalid. */
dda8d76d 6510 if (filedata->file_header.e_phnum
82156ab7 6511 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6512 >= filedata->file_size)
82156ab7
NC
6513 {
6514 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6515 filedata->file_header.e_phnum);
015dc7e1 6516 return false;
82156ab7 6517 }
d93f0186 6518
dda8d76d 6519 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6520 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6521 if (phdrs == NULL)
6522 {
8b73c356 6523 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6524 filedata->file_header.e_phnum);
015dc7e1 6525 return false;
d93f0186
NC
6526 }
6527
6528 if (is_32bit_elf
dda8d76d
NC
6529 ? get_32bit_program_headers (filedata, phdrs)
6530 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6531 {
dda8d76d 6532 filedata->program_headers = phdrs;
015dc7e1 6533 return true;
d93f0186
NC
6534 }
6535
6536 free (phdrs);
015dc7e1 6537 return false;
d93f0186
NC
6538}
6539
93df3340 6540/* Print program header info and locate dynamic section. */
2f62977e 6541
93df3340 6542static void
dda8d76d 6543process_program_headers (Filedata * filedata)
252b5132 6544{
2cf0635d 6545 Elf_Internal_Phdr * segment;
b34976b6 6546 unsigned int i;
1a9ccd70 6547 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6548
dda8d76d 6549 if (filedata->file_header.e_phnum == 0)
252b5132 6550 {
82f2dbf7 6551 /* PR binutils/12467. */
dda8d76d 6552 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6553 warn (_("possibly corrupt ELF header - it has a non-zero program"
6554 " header offset, but no program headers\n"));
82f2dbf7 6555 else if (do_segments)
ca0e11aa
NC
6556 {
6557 if (filedata->is_separate)
6558 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6559 filedata->file_name);
6560 else
6561 printf (_("\nThere are no program headers in this file.\n"));
6562 }
93df3340 6563 goto no_headers;
252b5132
RH
6564 }
6565
6566 if (do_segments && !do_header)
6567 {
ca0e11aa
NC
6568 if (filedata->is_separate)
6569 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6570 filedata->file_name, get_file_type (filedata));
ca0e11aa 6571 else
93df3340 6572 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6573 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6574 filedata->file_header.e_entry);
b8281767
AM
6575 printf (ngettext ("There is %d program header,"
6576 " starting at offset %" PRIu64 "\n",
6577 "There are %d program headers,"
6578 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6579 filedata->file_header.e_phnum),
6580 filedata->file_header.e_phnum,
625d49fc 6581 filedata->file_header.e_phoff);
252b5132
RH
6582 }
6583
dda8d76d 6584 if (! get_program_headers (filedata))
93df3340 6585 goto no_headers;
103f02d3 6586
252b5132
RH
6587 if (do_segments)
6588 {
dda8d76d 6589 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6590 printf (_("\nProgram Headers:\n"));
6591 else
6592 printf (_("\nProgram Headers:\n"));
76da6bbe 6593
f7a99963
NC
6594 if (is_32bit_elf)
6595 printf
6596 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6597 else if (do_wide)
6598 printf
6599 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6600 else
6601 {
6602 printf
6603 (_(" Type Offset VirtAddr PhysAddr\n"));
6604 printf
6605 (_(" FileSiz MemSiz Flags Align\n"));
6606 }
252b5132
RH
6607 }
6608
26c527e6 6609 uint64_t dynamic_addr = 0;
be7d229a 6610 uint64_t dynamic_size = 0;
dda8d76d
NC
6611 for (i = 0, segment = filedata->program_headers;
6612 i < filedata->file_header.e_phnum;
b34976b6 6613 i++, segment++)
252b5132
RH
6614 {
6615 if (do_segments)
6616 {
dda8d76d 6617 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6618
6619 if (is_32bit_elf)
6620 {
6621 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6622 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6623 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6624 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6625 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6626 printf ("%c%c%c ",
6627 (segment->p_flags & PF_R ? 'R' : ' '),
6628 (segment->p_flags & PF_W ? 'W' : ' '),
6629 (segment->p_flags & PF_X ? 'E' : ' '));
6630 printf ("%#lx", (unsigned long) segment->p_align);
6631 }
d974e256
JJ
6632 else if (do_wide)
6633 {
6634 if ((unsigned long) segment->p_offset == segment->p_offset)
6635 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6636 else
6637 {
6638 print_vma (segment->p_offset, FULL_HEX);
6639 putchar (' ');
6640 }
6641
6642 print_vma (segment->p_vaddr, FULL_HEX);
6643 putchar (' ');
6644 print_vma (segment->p_paddr, FULL_HEX);
6645 putchar (' ');
6646
6647 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6648 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6649 else
6650 {
6651 print_vma (segment->p_filesz, FULL_HEX);
6652 putchar (' ');
6653 }
6654
6655 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6656 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6657 else
6658 {
f48e6c45 6659 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6660 }
6661
6662 printf (" %c%c%c ",
6663 (segment->p_flags & PF_R ? 'R' : ' '),
6664 (segment->p_flags & PF_W ? 'W' : ' '),
6665 (segment->p_flags & PF_X ? 'E' : ' '));
6666
6667 if ((unsigned long) segment->p_align == segment->p_align)
6668 printf ("%#lx", (unsigned long) segment->p_align);
6669 else
6670 {
6671 print_vma (segment->p_align, PREFIX_HEX);
6672 }
6673 }
f7a99963
NC
6674 else
6675 {
6676 print_vma (segment->p_offset, FULL_HEX);
6677 putchar (' ');
6678 print_vma (segment->p_vaddr, FULL_HEX);
6679 putchar (' ');
6680 print_vma (segment->p_paddr, FULL_HEX);
6681 printf ("\n ");
6682 print_vma (segment->p_filesz, FULL_HEX);
6683 putchar (' ');
6684 print_vma (segment->p_memsz, FULL_HEX);
6685 printf (" %c%c%c ",
6686 (segment->p_flags & PF_R ? 'R' : ' '),
6687 (segment->p_flags & PF_W ? 'W' : ' '),
6688 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6689 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6690 }
252b5132 6691
1a9ccd70
NC
6692 putc ('\n', stdout);
6693 }
f54498b4 6694
252b5132
RH
6695 switch (segment->p_type)
6696 {
1a9ccd70 6697 case PT_LOAD:
502d895c
NC
6698#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6699 required by the ELF standard, several programs, including the Linux
6700 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6701 if (previous_load
6702 && previous_load->p_vaddr > segment->p_vaddr)
6703 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6704#endif
1a9ccd70
NC
6705 if (segment->p_memsz < segment->p_filesz)
6706 error (_("the segment's file size is larger than its memory size\n"));
6707 previous_load = segment;
6708 break;
6709
6710 case PT_PHDR:
6711 /* PR 20815 - Verify that the program header is loaded into memory. */
6712 if (i > 0 && previous_load != NULL)
6713 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6714 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6715 {
6716 unsigned int j;
6717
dda8d76d 6718 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6719 {
6720 Elf_Internal_Phdr *load = filedata->program_headers + j;
6721 if (load->p_type == PT_LOAD
6722 && load->p_offset <= segment->p_offset
6723 && (load->p_offset + load->p_filesz
6724 >= segment->p_offset + segment->p_filesz)
6725 && load->p_vaddr <= segment->p_vaddr
6726 && (load->p_vaddr + load->p_filesz
6727 >= segment->p_vaddr + segment->p_filesz))
6728 break;
6729 }
dda8d76d 6730 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6731 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6732 }
6733 break;
6734
252b5132 6735 case PT_DYNAMIC:
93df3340 6736 if (dynamic_addr)
252b5132
RH
6737 error (_("more than one dynamic segment\n"));
6738
20737c13
AM
6739 /* By default, assume that the .dynamic section is the first
6740 section in the DYNAMIC segment. */
93df3340
AM
6741 dynamic_addr = segment->p_offset;
6742 dynamic_size = segment->p_filesz;
20737c13 6743
b2d38a17
NC
6744 /* Try to locate the .dynamic section. If there is
6745 a section header table, we can easily locate it. */
dda8d76d 6746 if (filedata->section_headers != NULL)
b2d38a17 6747 {
2cf0635d 6748 Elf_Internal_Shdr * sec;
b2d38a17 6749
dda8d76d 6750 sec = find_section (filedata, ".dynamic");
89fac5e3 6751 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6752 {
93df3340
AM
6753 /* A corresponding .dynamic section is expected, but on
6754 IA-64/OpenVMS it is OK for it to be missing. */
6755 if (!is_ia64_vms (filedata))
6756 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6757 break;
6758 }
6759
42bb2e33 6760 if (sec->sh_type == SHT_NOBITS)
20737c13 6761 {
93df3340
AM
6762 dynamic_addr = 0;
6763 dynamic_size = 0;
20737c13
AM
6764 break;
6765 }
42bb2e33 6766
93df3340
AM
6767 dynamic_addr = sec->sh_offset;
6768 dynamic_size = sec->sh_size;
b2d38a17 6769
8ac10c5b
L
6770 /* The PT_DYNAMIC segment, which is used by the run-time
6771 loader, should exactly match the .dynamic section. */
6772 if (do_checks
93df3340
AM
6773 && (dynamic_addr != segment->p_offset
6774 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6775 warn (_("\
6776the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6777 }
39e224f6
MW
6778
6779 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6780 segment. Check this after matching against the section headers
6781 so we don't warn on debuginfo file (which have NOBITS .dynamic
6782 sections). */
93df3340
AM
6783 if (dynamic_addr > filedata->file_size
6784 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6785 {
6786 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6787 dynamic_addr = 0;
6788 dynamic_size = 0;
39e224f6 6789 }
252b5132
RH
6790 break;
6791
6792 case PT_INTERP:
13acb58d
AM
6793 if (segment->p_offset >= filedata->file_size
6794 || segment->p_filesz > filedata->file_size - segment->p_offset
6795 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6796 || fseek64 (filedata->handle,
6797 filedata->archive_file_offset + segment->p_offset,
6798 SEEK_SET))
252b5132
RH
6799 error (_("Unable to find program interpreter name\n"));
6800 else
6801 {
13acb58d
AM
6802 size_t len = segment->p_filesz;
6803 free (filedata->program_interpreter);
6804 filedata->program_interpreter = xmalloc (len + 1);
6805 len = fread (filedata->program_interpreter, 1, len,
6806 filedata->handle);
6807 filedata->program_interpreter[len] = 0;
252b5132
RH
6808
6809 if (do_segments)
f54498b4 6810 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6811 filedata->program_interpreter);
252b5132
RH
6812 }
6813 break;
6814 }
252b5132
RH
6815 }
6816
dda8d76d
NC
6817 if (do_segments
6818 && filedata->section_headers != NULL
6819 && filedata->string_table != NULL)
252b5132
RH
6820 {
6821 printf (_("\n Section to Segment mapping:\n"));
6822 printf (_(" Segment Sections...\n"));
6823
dda8d76d 6824 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6825 {
9ad5cbcf 6826 unsigned int j;
2cf0635d 6827 Elf_Internal_Shdr * section;
252b5132 6828
dda8d76d
NC
6829 segment = filedata->program_headers + i;
6830 section = filedata->section_headers + 1;
252b5132
RH
6831
6832 printf (" %2.2d ", i);
6833
dda8d76d 6834 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6835 {
f4638467
AM
6836 if (!ELF_TBSS_SPECIAL (section, segment)
6837 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6838 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6839 }
6840
6841 putc ('\n',stdout);
6842 }
6843 }
6844
93df3340
AM
6845 filedata->dynamic_addr = dynamic_addr;
6846 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6847 return;
6848
6849 no_headers:
6850 filedata->dynamic_addr = 0;
6851 filedata->dynamic_size = 1;
252b5132
RH
6852}
6853
6854
d93f0186
NC
6855/* Find the file offset corresponding to VMA by using the program headers. */
6856
26c527e6 6857static int64_t
625d49fc 6858offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6859{
2cf0635d 6860 Elf_Internal_Phdr * seg;
d93f0186 6861
dda8d76d 6862 if (! get_program_headers (filedata))
d93f0186
NC
6863 {
6864 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6865 return (long) vma;
6866 }
6867
dda8d76d
NC
6868 for (seg = filedata->program_headers;
6869 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6870 ++seg)
6871 {
6872 if (seg->p_type != PT_LOAD)
6873 continue;
6874
6875 if (vma >= (seg->p_vaddr & -seg->p_align)
6876 && vma + size <= seg->p_vaddr + seg->p_filesz)
6877 return vma - seg->p_vaddr + seg->p_offset;
6878 }
6879
26c527e6
AM
6880 warn (_("Virtual address %#" PRIx64
6881 " not located in any PT_LOAD segment.\n"), vma);
6882 return vma;
d93f0186
NC
6883}
6884
6885
dda8d76d
NC
6886/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6887 If PROBE is true, this is just a probe and we do not generate any error
6888 messages if the load fails. */
049b0c3a 6889
015dc7e1
AM
6890static bool
6891get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6892{
2cf0635d
NC
6893 Elf32_External_Shdr * shdrs;
6894 Elf_Internal_Shdr * internal;
dda8d76d
NC
6895 unsigned int i;
6896 unsigned int size = filedata->file_header.e_shentsize;
6897 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6898
6899 /* PR binutils/17531: Cope with unexpected section header sizes. */
6900 if (size == 0 || num == 0)
015dc7e1 6901 return false;
907b52f4
NC
6902
6903 /* The section header cannot be at the start of the file - that is
6904 where the ELF file header is located. A file with absolutely no
6905 sections in it will use a shoff of 0. */
6906 if (filedata->file_header.e_shoff == 0)
6907 return false;
6908
049b0c3a
NC
6909 if (size < sizeof * shdrs)
6910 {
6911 if (! probe)
6912 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6913 return false;
049b0c3a
NC
6914 }
6915 if (!probe && size > sizeof * shdrs)
6916 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6917
dda8d76d 6918 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6919 size, num,
6920 probe ? NULL : _("section headers"));
6921 if (shdrs == NULL)
015dc7e1 6922 return false;
252b5132 6923
dda8d76d
NC
6924 filedata->section_headers = (Elf_Internal_Shdr *)
6925 cmalloc (num, sizeof (Elf_Internal_Shdr));
6926 if (filedata->section_headers == NULL)
252b5132 6927 {
049b0c3a 6928 if (!probe)
8b73c356 6929 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6930 free (shdrs);
015dc7e1 6931 return false;
252b5132
RH
6932 }
6933
dda8d76d 6934 for (i = 0, internal = filedata->section_headers;
560f3c1c 6935 i < num;
b34976b6 6936 i++, internal++)
252b5132
RH
6937 {
6938 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6939 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6940 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6941 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6942 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6943 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6944 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6945 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6946 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6947 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6948 if (!probe && internal->sh_link > num)
6949 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6950 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6951 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6952 }
6953
6954 free (shdrs);
015dc7e1 6955 return true;
252b5132
RH
6956}
6957
dda8d76d
NC
6958/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6959
015dc7e1
AM
6960static bool
6961get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6962{
dda8d76d
NC
6963 Elf64_External_Shdr * shdrs;
6964 Elf_Internal_Shdr * internal;
6965 unsigned int i;
6966 unsigned int size = filedata->file_header.e_shentsize;
6967 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6968
6969 /* PR binutils/17531: Cope with unexpected section header sizes. */
6970 if (size == 0 || num == 0)
015dc7e1 6971 return false;
dda8d76d 6972
907b52f4
NC
6973 /* The section header cannot be at the start of the file - that is
6974 where the ELF file header is located. A file with absolutely no
6975 sections in it will use a shoff of 0. */
6976 if (filedata->file_header.e_shoff == 0)
6977 return false;
6978
049b0c3a
NC
6979 if (size < sizeof * shdrs)
6980 {
6981 if (! probe)
6982 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6983 return false;
049b0c3a 6984 }
dda8d76d 6985
049b0c3a
NC
6986 if (! probe && size > sizeof * shdrs)
6987 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6988
dda8d76d
NC
6989 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6990 filedata->file_header.e_shoff,
049b0c3a
NC
6991 size, num,
6992 probe ? NULL : _("section headers"));
6993 if (shdrs == NULL)
015dc7e1 6994 return false;
9ea033b2 6995
dda8d76d
NC
6996 filedata->section_headers = (Elf_Internal_Shdr *)
6997 cmalloc (num, sizeof (Elf_Internal_Shdr));
6998 if (filedata->section_headers == NULL)
9ea033b2 6999 {
049b0c3a 7000 if (! probe)
8b73c356 7001 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7002 free (shdrs);
015dc7e1 7003 return false;
9ea033b2
NC
7004 }
7005
dda8d76d 7006 for (i = 0, internal = filedata->section_headers;
560f3c1c 7007 i < num;
b34976b6 7008 i++, internal++)
9ea033b2
NC
7009 {
7010 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7011 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7012 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7013 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7014 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7015 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7016 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7017 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7018 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7019 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7020 if (!probe && internal->sh_link > num)
7021 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7022 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7023 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7024 }
7025
7026 free (shdrs);
015dc7e1 7027 return true;
9ea033b2
NC
7028}
7029
4de91c10
AM
7030static bool
7031get_section_headers (Filedata *filedata, bool probe)
7032{
7033 if (filedata->section_headers != NULL)
7034 return true;
7035
4de91c10
AM
7036 if (is_32bit_elf)
7037 return get_32bit_section_headers (filedata, probe);
7038 else
7039 return get_64bit_section_headers (filedata, probe);
7040}
7041
252b5132 7042static Elf_Internal_Sym *
26c527e6
AM
7043get_32bit_elf_symbols (Filedata *filedata,
7044 Elf_Internal_Shdr *section,
7045 uint64_t *num_syms_return)
252b5132 7046{
26c527e6 7047 uint64_t number = 0;
dd24e3da 7048 Elf32_External_Sym * esyms = NULL;
ba5cdace 7049 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7050 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7051 Elf_Internal_Sym * psym;
b34976b6 7052 unsigned int j;
e3d39609 7053 elf_section_list * entry;
252b5132 7054
c9c1d674
EG
7055 if (section->sh_size == 0)
7056 {
7057 if (num_syms_return != NULL)
7058 * num_syms_return = 0;
7059 return NULL;
7060 }
7061
dd24e3da 7062 /* Run some sanity checks first. */
c9c1d674 7063 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7064 {
26c527e6 7065 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7066 printable_section_name (filedata, section),
26c527e6 7067 section->sh_entsize);
ba5cdace 7068 goto exit_point;
dd24e3da
NC
7069 }
7070
dda8d76d 7071 if (section->sh_size > filedata->file_size)
f54498b4 7072 {
26c527e6 7073 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7074 printable_section_name (filedata, section),
26c527e6 7075 section->sh_size);
f54498b4
NC
7076 goto exit_point;
7077 }
7078
dd24e3da
NC
7079 number = section->sh_size / section->sh_entsize;
7080
7081 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7082 {
26c527e6
AM
7083 error (_("Size (%#" PRIx64 ") of section %s "
7084 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7085 section->sh_size,
dda8d76d 7086 printable_section_name (filedata, section),
26c527e6 7087 section->sh_entsize);
ba5cdace 7088 goto exit_point;
dd24e3da
NC
7089 }
7090
dda8d76d 7091 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7092 section->sh_size, _("symbols"));
dd24e3da 7093 if (esyms == NULL)
ba5cdace 7094 goto exit_point;
252b5132 7095
e3d39609 7096 shndx = NULL;
978c4450 7097 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7098 {
26c527e6 7099 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7100 continue;
7101
7102 if (shndx != NULL)
7103 {
7104 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7105 free (shndx);
7106 }
7107
7108 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7109 entry->hdr->sh_offset,
7110 1, entry->hdr->sh_size,
7111 _("symbol table section indices"));
7112 if (shndx == NULL)
7113 goto exit_point;
7114
7115 /* PR17531: file: heap-buffer-overflow */
7116 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7117 {
26c527e6 7118 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7119 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7120 entry->hdr->sh_size,
7121 section->sh_size);
e3d39609 7122 goto exit_point;
c9c1d674 7123 }
e3d39609 7124 }
9ad5cbcf 7125
3f5e193b 7126 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7127
7128 if (isyms == NULL)
7129 {
26c527e6 7130 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7131 goto exit_point;
252b5132
RH
7132 }
7133
dd24e3da 7134 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7135 {
7136 psym->st_name = BYTE_GET (esyms[j].st_name);
7137 psym->st_value = BYTE_GET (esyms[j].st_value);
7138 psym->st_size = BYTE_GET (esyms[j].st_size);
7139 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7140 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7141 psym->st_shndx
7142 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7143 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7144 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7145 psym->st_info = BYTE_GET (esyms[j].st_info);
7146 psym->st_other = BYTE_GET (esyms[j].st_other);
7147 }
7148
dd24e3da 7149 exit_point:
e3d39609
NC
7150 free (shndx);
7151 free (esyms);
252b5132 7152
ba5cdace
NC
7153 if (num_syms_return != NULL)
7154 * num_syms_return = isyms == NULL ? 0 : number;
7155
252b5132
RH
7156 return isyms;
7157}
7158
9ea033b2 7159static Elf_Internal_Sym *
26c527e6
AM
7160get_64bit_elf_symbols (Filedata *filedata,
7161 Elf_Internal_Shdr *section,
7162 uint64_t *num_syms_return)
9ea033b2 7163{
26c527e6 7164 uint64_t number = 0;
ba5cdace
NC
7165 Elf64_External_Sym * esyms = NULL;
7166 Elf_External_Sym_Shndx * shndx = NULL;
7167 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7168 Elf_Internal_Sym * psym;
b34976b6 7169 unsigned int j;
e3d39609 7170 elf_section_list * entry;
9ea033b2 7171
c9c1d674
EG
7172 if (section->sh_size == 0)
7173 {
7174 if (num_syms_return != NULL)
7175 * num_syms_return = 0;
7176 return NULL;
7177 }
7178
dd24e3da 7179 /* Run some sanity checks first. */
c9c1d674 7180 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7181 {
26c527e6 7182 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7183 printable_section_name (filedata, section),
26c527e6 7184 section->sh_entsize);
ba5cdace 7185 goto exit_point;
dd24e3da
NC
7186 }
7187
dda8d76d 7188 if (section->sh_size > filedata->file_size)
f54498b4 7189 {
26c527e6 7190 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7191 printable_section_name (filedata, section),
26c527e6 7192 section->sh_size);
f54498b4
NC
7193 goto exit_point;
7194 }
7195
dd24e3da
NC
7196 number = section->sh_size / section->sh_entsize;
7197
7198 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7199 {
26c527e6
AM
7200 error (_("Size (%#" PRIx64 ") of section %s "
7201 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7202 section->sh_size,
dda8d76d 7203 printable_section_name (filedata, section),
26c527e6 7204 section->sh_entsize);
ba5cdace 7205 goto exit_point;
dd24e3da
NC
7206 }
7207
dda8d76d 7208 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7209 section->sh_size, _("symbols"));
a6e9f9df 7210 if (!esyms)
ba5cdace 7211 goto exit_point;
9ea033b2 7212
e3d39609 7213 shndx = NULL;
978c4450 7214 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7215 {
26c527e6 7216 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7217 continue;
7218
7219 if (shndx != NULL)
7220 {
7221 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7222 free (shndx);
c9c1d674 7223 }
e3d39609
NC
7224
7225 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7226 entry->hdr->sh_offset,
7227 1, entry->hdr->sh_size,
7228 _("symbol table section indices"));
7229 if (shndx == NULL)
7230 goto exit_point;
7231
7232 /* PR17531: file: heap-buffer-overflow */
7233 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7234 {
26c527e6 7235 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7236 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7237 entry->hdr->sh_size,
7238 section->sh_size);
e3d39609
NC
7239 goto exit_point;
7240 }
7241 }
9ad5cbcf 7242
3f5e193b 7243 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7244
7245 if (isyms == NULL)
7246 {
26c527e6 7247 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7248 goto exit_point;
9ea033b2
NC
7249 }
7250
ba5cdace 7251 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7252 {
7253 psym->st_name = BYTE_GET (esyms[j].st_name);
7254 psym->st_info = BYTE_GET (esyms[j].st_info);
7255 psym->st_other = BYTE_GET (esyms[j].st_other);
7256 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7257
4fbb74a6 7258 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7259 psym->st_shndx
7260 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7261 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7262 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7263
66543521
AM
7264 psym->st_value = BYTE_GET (esyms[j].st_value);
7265 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7266 }
7267
ba5cdace 7268 exit_point:
e3d39609
NC
7269 free (shndx);
7270 free (esyms);
ba5cdace
NC
7271
7272 if (num_syms_return != NULL)
7273 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7274
7275 return isyms;
7276}
7277
4de91c10
AM
7278static Elf_Internal_Sym *
7279get_elf_symbols (Filedata *filedata,
7280 Elf_Internal_Shdr *section,
26c527e6 7281 uint64_t *num_syms_return)
4de91c10
AM
7282{
7283 if (is_32bit_elf)
7284 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7285 else
7286 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7287}
7288
d1133906 7289static const char *
625d49fc 7290get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7291{
5477e8a0 7292 static char buff[1024];
2cf0635d 7293 char * p = buff;
32ec8896
NC
7294 unsigned int field_size = is_32bit_elf ? 8 : 16;
7295 signed int sindex;
7296 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7297 uint64_t os_flags = 0;
7298 uint64_t proc_flags = 0;
7299 uint64_t unknown_flags = 0;
148b93f2 7300 static const struct
5477e8a0 7301 {
2cf0635d 7302 const char * str;
32ec8896 7303 unsigned int len;
5477e8a0
L
7304 }
7305 flags [] =
7306 {
cfcac11d
NC
7307 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7308 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7309 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7310 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7311 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7312 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7313 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7314 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7315 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7316 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7317 /* IA-64 specific. */
7318 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7319 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7320 /* IA-64 OpenVMS specific. */
7321 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7322 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7323 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7324 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7325 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7326 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7327 /* Generic. */
cfcac11d 7328 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7329 /* SPARC specific. */
77115a4a 7330 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7331 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7332 /* ARM specific. */
7333 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7334 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7335 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7336 /* GNU specific. */
7337 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7338 /* VLE specific. */
7339 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7340 /* GNU specific. */
7341 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7342 };
7343
7344 if (do_section_details)
f8c4789c
AM
7345 p += sprintf (p, "[%*.*lx]: ",
7346 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7347
d1133906
NC
7348 while (sh_flags)
7349 {
625d49fc 7350 uint64_t flag;
d1133906
NC
7351
7352 flag = sh_flags & - sh_flags;
7353 sh_flags &= ~ flag;
76da6bbe 7354
5477e8a0 7355 if (do_section_details)
d1133906 7356 {
5477e8a0
L
7357 switch (flag)
7358 {
91d6fa6a
NC
7359 case SHF_WRITE: sindex = 0; break;
7360 case SHF_ALLOC: sindex = 1; break;
7361 case SHF_EXECINSTR: sindex = 2; break;
7362 case SHF_MERGE: sindex = 3; break;
7363 case SHF_STRINGS: sindex = 4; break;
7364 case SHF_INFO_LINK: sindex = 5; break;
7365 case SHF_LINK_ORDER: sindex = 6; break;
7366 case SHF_OS_NONCONFORMING: sindex = 7; break;
7367 case SHF_GROUP: sindex = 8; break;
7368 case SHF_TLS: sindex = 9; break;
18ae9cc1 7369 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7370 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7371
5477e8a0 7372 default:
91d6fa6a 7373 sindex = -1;
dda8d76d 7374 switch (filedata->file_header.e_machine)
148b93f2 7375 {
cfcac11d 7376 case EM_IA_64:
148b93f2 7377 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7378 sindex = 10;
148b93f2 7379 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7380 sindex = 11;
dda8d76d 7381 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7382 switch (flag)
7383 {
91d6fa6a
NC
7384 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7385 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7386 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7387 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7388 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7389 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7390 default: break;
7391 }
cfcac11d
NC
7392 break;
7393
caa83f8b 7394 case EM_386:
22abe556 7395 case EM_IAMCU:
caa83f8b 7396 case EM_X86_64:
7f502d6c 7397 case EM_L1OM:
7a9068fe 7398 case EM_K1OM:
cfcac11d
NC
7399 case EM_OLD_SPARCV9:
7400 case EM_SPARC32PLUS:
7401 case EM_SPARCV9:
7402 case EM_SPARC:
18ae9cc1 7403 if (flag == SHF_ORDERED)
91d6fa6a 7404 sindex = 19;
cfcac11d 7405 break;
ac4c9b04
MG
7406
7407 case EM_ARM:
7408 switch (flag)
7409 {
7410 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7411 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7412 case SHF_COMDEF: sindex = 23; break;
7413 default: break;
7414 }
7415 break;
83eef883
AFB
7416 case EM_PPC:
7417 if (flag == SHF_PPC_VLE)
7418 sindex = 25;
7419 break;
99fabbc9
JL
7420 default:
7421 break;
7422 }
ac4c9b04 7423
99fabbc9
JL
7424 switch (filedata->file_header.e_ident[EI_OSABI])
7425 {
7426 case ELFOSABI_GNU:
7427 case ELFOSABI_FREEBSD:
7428 if (flag == SHF_GNU_RETAIN)
7429 sindex = 26;
7430 /* Fall through */
7431 case ELFOSABI_NONE:
7432 if (flag == SHF_GNU_MBIND)
7433 /* We should not recognize SHF_GNU_MBIND for
7434 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7435 not set the EI_OSABI header byte. */
7436 sindex = 24;
7437 break;
cfcac11d
NC
7438 default:
7439 break;
148b93f2 7440 }
99fabbc9 7441 break;
5477e8a0
L
7442 }
7443
91d6fa6a 7444 if (sindex != -1)
5477e8a0 7445 {
8d5ff12c
L
7446 if (p != buff + field_size + 4)
7447 {
7448 if (size < (10 + 2))
bee0ee85
NC
7449 {
7450 warn (_("Internal error: not enough buffer room for section flag info"));
7451 return _("<unknown>");
7452 }
8d5ff12c
L
7453 size -= 2;
7454 *p++ = ',';
7455 *p++ = ' ';
7456 }
7457
91d6fa6a
NC
7458 size -= flags [sindex].len;
7459 p = stpcpy (p, flags [sindex].str);
5477e8a0 7460 }
3b22753a 7461 else if (flag & SHF_MASKOS)
8d5ff12c 7462 os_flags |= flag;
d1133906 7463 else if (flag & SHF_MASKPROC)
8d5ff12c 7464 proc_flags |= flag;
d1133906 7465 else
8d5ff12c 7466 unknown_flags |= flag;
5477e8a0
L
7467 }
7468 else
7469 {
7470 switch (flag)
7471 {
7472 case SHF_WRITE: *p = 'W'; break;
7473 case SHF_ALLOC: *p = 'A'; break;
7474 case SHF_EXECINSTR: *p = 'X'; break;
7475 case SHF_MERGE: *p = 'M'; break;
7476 case SHF_STRINGS: *p = 'S'; break;
7477 case SHF_INFO_LINK: *p = 'I'; break;
7478 case SHF_LINK_ORDER: *p = 'L'; break;
7479 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7480 case SHF_GROUP: *p = 'G'; break;
7481 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7482 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7483 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7484
7485 default:
dda8d76d
NC
7486 if ((filedata->file_header.e_machine == EM_X86_64
7487 || filedata->file_header.e_machine == EM_L1OM
7488 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7489 && flag == SHF_X86_64_LARGE)
7490 *p = 'l';
dda8d76d 7491 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7492 && flag == SHF_ARM_PURECODE)
99fabbc9 7493 *p = 'y';
dda8d76d 7494 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7495 && flag == SHF_PPC_VLE)
99fabbc9 7496 *p = 'v';
5477e8a0
L
7497 else if (flag & SHF_MASKOS)
7498 {
99fabbc9
JL
7499 switch (filedata->file_header.e_ident[EI_OSABI])
7500 {
7501 case ELFOSABI_GNU:
7502 case ELFOSABI_FREEBSD:
7503 if (flag == SHF_GNU_RETAIN)
7504 {
7505 *p = 'R';
7506 break;
7507 }
7508 /* Fall through */
7509 case ELFOSABI_NONE:
7510 if (flag == SHF_GNU_MBIND)
7511 {
7512 /* We should not recognize SHF_GNU_MBIND for
7513 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7514 not set the EI_OSABI header byte. */
7515 *p = 'D';
7516 break;
7517 }
7518 /* Fall through */
7519 default:
7520 *p = 'o';
7521 sh_flags &= ~SHF_MASKOS;
7522 break;
7523 }
5477e8a0
L
7524 }
7525 else if (flag & SHF_MASKPROC)
7526 {
7527 *p = 'p';
7528 sh_flags &= ~ SHF_MASKPROC;
7529 }
7530 else
7531 *p = 'x';
7532 break;
7533 }
7534 p++;
d1133906
NC
7535 }
7536 }
76da6bbe 7537
8d5ff12c
L
7538 if (do_section_details)
7539 {
7540 if (os_flags)
7541 {
8d5ff12c
L
7542 if (p != buff + field_size + 4)
7543 {
f8c4789c 7544 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7545 {
7546 warn (_("Internal error: not enough buffer room for section flag info"));
7547 return _("<unknown>");
7548 }
8d5ff12c
L
7549 size -= 2;
7550 *p++ = ',';
7551 *p++ = ' ';
7552 }
f8c4789c
AM
7553 size -= 5 + field_size;
7554 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7555 (unsigned long) os_flags);
8d5ff12c
L
7556 }
7557 if (proc_flags)
7558 {
8d5ff12c
L
7559 if (p != buff + field_size + 4)
7560 {
f8c4789c 7561 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7562 {
7563 warn (_("Internal error: not enough buffer room for section flag info"));
7564 return _("<unknown>");
7565 }
8d5ff12c
L
7566 size -= 2;
7567 *p++ = ',';
7568 *p++ = ' ';
7569 }
f8c4789c
AM
7570 size -= 7 + field_size;
7571 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7572 (unsigned long) proc_flags);
8d5ff12c
L
7573 }
7574 if (unknown_flags)
7575 {
8d5ff12c
L
7576 if (p != buff + field_size + 4)
7577 {
f8c4789c 7578 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7579 {
7580 warn (_("Internal error: not enough buffer room for section flag info"));
7581 return _("<unknown>");
7582 }
8d5ff12c
L
7583 size -= 2;
7584 *p++ = ',';
7585 *p++ = ' ';
7586 }
f8c4789c
AM
7587 size -= 10 + field_size;
7588 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7589 (unsigned long) unknown_flags);
8d5ff12c
L
7590 }
7591 }
7592
e9e44622 7593 *p = '\0';
d1133906
NC
7594 return buff;
7595}
7596
5844b465 7597static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7598get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7599 uint64_t size)
77115a4a
L
7600{
7601 if (is_32bit_elf)
7602 {
7603 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7604
ebdf1ebf
NC
7605 if (size < sizeof (* echdr))
7606 {
7607 error (_("Compressed section is too small even for a compression header\n"));
7608 return 0;
7609 }
7610
77115a4a
L
7611 chdr->ch_type = BYTE_GET (echdr->ch_type);
7612 chdr->ch_size = BYTE_GET (echdr->ch_size);
7613 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7614 return sizeof (*echdr);
7615 }
7616 else
7617 {
7618 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7619
ebdf1ebf
NC
7620 if (size < sizeof (* echdr))
7621 {
7622 error (_("Compressed section is too small even for a compression header\n"));
7623 return 0;
7624 }
7625
77115a4a
L
7626 chdr->ch_type = BYTE_GET (echdr->ch_type);
7627 chdr->ch_size = BYTE_GET (echdr->ch_size);
7628 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7629 return sizeof (*echdr);
7630 }
7631}
7632
015dc7e1 7633static bool
dda8d76d 7634process_section_headers (Filedata * filedata)
252b5132 7635{
2cf0635d 7636 Elf_Internal_Shdr * section;
b34976b6 7637 unsigned int i;
252b5132 7638
dda8d76d 7639 if (filedata->file_header.e_shnum == 0)
252b5132 7640 {
82f2dbf7 7641 /* PR binutils/12467. */
dda8d76d 7642 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7643 {
7644 warn (_("possibly corrupt ELF file header - it has a non-zero"
7645 " section header offset, but no section headers\n"));
015dc7e1 7646 return false;
32ec8896 7647 }
82f2dbf7 7648 else if (do_sections)
252b5132
RH
7649 printf (_("\nThere are no sections in this file.\n"));
7650
015dc7e1 7651 return true;
252b5132
RH
7652 }
7653
7654 if (do_sections && !do_header)
ca0e11aa
NC
7655 {
7656 if (filedata->is_separate && process_links)
7657 printf (_("In linked file '%s': "), filedata->file_name);
7658 if (! filedata->is_separate || process_links)
7659 printf (ngettext ("There is %d section header, "
26c527e6 7660 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7661 "There are %d section headers, "
26c527e6 7662 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7663 filedata->file_header.e_shnum),
7664 filedata->file_header.e_shnum,
26c527e6 7665 filedata->file_header.e_shoff);
ca0e11aa 7666 }
252b5132 7667
4de91c10
AM
7668 if (!get_section_headers (filedata, false))
7669 return false;
252b5132
RH
7670
7671 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7672 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7673 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7674 {
dda8d76d 7675 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7676
c256ffe7
JJ
7677 if (section->sh_size != 0)
7678 {
dda8d76d
NC
7679 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7680 1, section->sh_size,
7681 _("string table"));
0de14b54 7682
dda8d76d 7683 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7684 }
252b5132
RH
7685 }
7686
7687 /* Scan the sections for the dynamic symbol table
e3c8793a 7688 and dynamic string table and debug sections. */
89fac5e3 7689 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7690 switch (filedata->file_header.e_machine)
89fac5e3
RS
7691 {
7692 case EM_MIPS:
7693 case EM_MIPS_RS3_LE:
7694 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7695 FDE addresses. However, the ABI also has a semi-official ILP32
7696 variant for which the normal FDE address size rules apply.
7697
7698 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7699 section, where XX is the size of longs in bits. Unfortunately,
7700 earlier compilers provided no way of distinguishing ILP32 objects
7701 from LP64 objects, so if there's any doubt, we should assume that
7702 the official LP64 form is being used. */
d173146d 7703 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 7704 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7705 eh_addr_size = 8;
7706 break;
0f56a26a
DD
7707
7708 case EM_H8_300:
7709 case EM_H8_300H:
dda8d76d 7710 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7711 {
7712 case E_H8_MACH_H8300:
7713 case E_H8_MACH_H8300HN:
7714 case E_H8_MACH_H8300SN:
7715 case E_H8_MACH_H8300SXN:
7716 eh_addr_size = 2;
7717 break;
7718 case E_H8_MACH_H8300H:
7719 case E_H8_MACH_H8300S:
7720 case E_H8_MACH_H8300SX:
7721 eh_addr_size = 4;
7722 break;
7723 }
f4236fe4
DD
7724 break;
7725
ff7eeb89 7726 case EM_M32C_OLD:
f4236fe4 7727 case EM_M32C:
dda8d76d 7728 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7729 {
7730 case EF_M32C_CPU_M16C:
7731 eh_addr_size = 2;
7732 break;
7733 }
7734 break;
89fac5e3
RS
7735 }
7736
76ca31c0
NC
7737#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7738 do \
7739 { \
be7d229a 7740 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7741 if (section->sh_entsize != expected_entsize) \
9dd3a467 7742 { \
f493c217 7743 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7744 i, section->sh_entsize); \
f493c217 7745 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7746 expected_entsize); \
9dd3a467 7747 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7748 } \
7749 } \
08d8fa11 7750 while (0)
9dd3a467
NC
7751
7752#define CHECK_ENTSIZE(section, i, type) \
1b513401 7753 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7754 sizeof (Elf64_External_##type))
7755
dda8d76d
NC
7756 for (i = 0, section = filedata->section_headers;
7757 i < filedata->file_header.e_shnum;
b34976b6 7758 i++, section++)
252b5132 7759 {
b6ac461a 7760 const char *name = printable_section_name (filedata, section);
252b5132 7761
1b513401
NC
7762 /* Run some sanity checks on the headers and
7763 possibly fill in some file data as well. */
7764 switch (section->sh_type)
252b5132 7765 {
1b513401 7766 case SHT_DYNSYM:
978c4450 7767 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7768 {
7769 error (_("File contains multiple dynamic symbol tables\n"));
7770 continue;
7771 }
7772
08d8fa11 7773 CHECK_ENTSIZE (section, i, Sym);
978c4450 7774 filedata->dynamic_symbols
4de91c10 7775 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7776 filedata->dynamic_symtab_section = section;
1b513401
NC
7777 break;
7778
7779 case SHT_STRTAB:
7780 if (streq (name, ".dynstr"))
252b5132 7781 {
1b513401
NC
7782 if (filedata->dynamic_strings != NULL)
7783 {
7784 error (_("File contains multiple dynamic string tables\n"));
7785 continue;
7786 }
7787
7788 filedata->dynamic_strings
7789 = (char *) get_data (NULL, filedata, section->sh_offset,
7790 1, section->sh_size, _("dynamic strings"));
7791 filedata->dynamic_strings_length
7792 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7793 filedata->dynamic_strtab_section = section;
252b5132 7794 }
1b513401
NC
7795 break;
7796
7797 case SHT_SYMTAB_SHNDX:
7798 {
7799 elf_section_list * entry = xmalloc (sizeof * entry);
7800
7801 entry->hdr = section;
7802 entry->next = filedata->symtab_shndx_list;
7803 filedata->symtab_shndx_list = entry;
7804 }
7805 break;
7806
7807 case SHT_SYMTAB:
7808 CHECK_ENTSIZE (section, i, Sym);
7809 break;
7810
7811 case SHT_GROUP:
7812 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7813 break;
252b5132 7814
1b513401
NC
7815 case SHT_REL:
7816 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7817 if (do_checks && section->sh_size == 0)
1b513401
NC
7818 warn (_("Section '%s': zero-sized relocation section\n"), name);
7819 break;
7820
7821 case SHT_RELA:
7822 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7823 if (do_checks && section->sh_size == 0)
1b513401
NC
7824 warn (_("Section '%s': zero-sized relocation section\n"), name);
7825 break;
7826
682351b9
AM
7827 case SHT_RELR:
7828 CHECK_ENTSIZE (section, i, Relr);
7829 break;
7830
1b513401
NC
7831 case SHT_NOTE:
7832 case SHT_PROGBITS:
546cb2d8
NC
7833 /* Having a zero sized section is not illegal according to the
7834 ELF standard, but it might be an indication that something
7835 is wrong. So issue a warning if we are running in lint mode. */
7836 if (do_checks && section->sh_size == 0)
1b513401
NC
7837 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7838 break;
7839
7840 default:
7841 break;
7842 }
7843
7844 if ((do_debugging || do_debug_info || do_debug_abbrevs
7845 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7846 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7847 || do_debug_str || do_debug_str_offsets || do_debug_loc
7848 || do_debug_ranges
1b513401 7849 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7850 && (startswith (name, ".debug_")
7851 || startswith (name, ".zdebug_")))
252b5132 7852 {
1b315056
CS
7853 if (name[1] == 'z')
7854 name += sizeof (".zdebug_") - 1;
7855 else
7856 name += sizeof (".debug_") - 1;
252b5132
RH
7857
7858 if (do_debugging
24d127aa
ML
7859 || (do_debug_info && startswith (name, "info"))
7860 || (do_debug_info && startswith (name, "types"))
7861 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7862 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7863 || (do_debug_lines && startswith (name, "line."))
7864 || (do_debug_pubnames && startswith (name, "pubnames"))
7865 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7866 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7867 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7868 || (do_debug_aranges && startswith (name, "aranges"))
7869 || (do_debug_ranges && startswith (name, "ranges"))
7870 || (do_debug_ranges && startswith (name, "rnglists"))
7871 || (do_debug_frames && startswith (name, "frame"))
7872 || (do_debug_macinfo && startswith (name, "macinfo"))
7873 || (do_debug_macinfo && startswith (name, "macro"))
7874 || (do_debug_str && startswith (name, "str"))
7875 || (do_debug_links && startswith (name, "sup"))
7876 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7877 || (do_debug_loc && startswith (name, "loc"))
7878 || (do_debug_loc && startswith (name, "loclists"))
7879 || (do_debug_addr && startswith (name, "addr"))
7880 || (do_debug_cu_index && startswith (name, "cu_index"))
7881 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7882 )
6431e409 7883 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7884 }
a262ae96 7885 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7886 else if ((do_debugging || do_debug_info)
24d127aa 7887 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7888 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7889 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7890 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7891 else if (do_gdb_index && (streq (name, ".gdb_index")
7892 || streq (name, ".debug_names")))
6431e409 7893 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7894 /* Trace sections for Itanium VMS. */
7895 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7896 || do_trace_aranges)
24d127aa 7897 && startswith (name, ".trace_"))
6f875884
TG
7898 {
7899 name += sizeof (".trace_") - 1;
7900
7901 if (do_debugging
7902 || (do_trace_info && streq (name, "info"))
7903 || (do_trace_abbrevs && streq (name, "abbrev"))
7904 || (do_trace_aranges && streq (name, "aranges"))
7905 )
6431e409 7906 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7907 }
dda8d76d 7908 else if ((do_debugging || do_debug_links)
24d127aa
ML
7909 && (startswith (name, ".gnu_debuglink")
7910 || startswith (name, ".gnu_debugaltlink")))
6431e409 7911 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7912 }
7913
7914 if (! do_sections)
015dc7e1 7915 return true;
252b5132 7916
ca0e11aa 7917 if (filedata->is_separate && ! process_links)
015dc7e1 7918 return true;
ca0e11aa
NC
7919
7920 if (filedata->is_separate)
7921 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7922 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7923 printf (_("\nSection Headers:\n"));
7924 else
7925 printf (_("\nSection Header:\n"));
76da6bbe 7926
f7a99963 7927 if (is_32bit_elf)
595cf52e 7928 {
5477e8a0 7929 if (do_section_details)
595cf52e
L
7930 {
7931 printf (_(" [Nr] Name\n"));
5477e8a0 7932 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7933 }
7934 else
7935 printf
7936 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7937 }
d974e256 7938 else if (do_wide)
595cf52e 7939 {
5477e8a0 7940 if (do_section_details)
595cf52e
L
7941 {
7942 printf (_(" [Nr] Name\n"));
5477e8a0 7943 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7944 }
7945 else
7946 printf
7947 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7948 }
f7a99963
NC
7949 else
7950 {
5477e8a0 7951 if (do_section_details)
595cf52e
L
7952 {
7953 printf (_(" [Nr] Name\n"));
5477e8a0
L
7954 printf (_(" Type Address Offset Link\n"));
7955 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7956 }
7957 else
7958 {
7959 printf (_(" [Nr] Name Type Address Offset\n"));
7960 printf (_(" Size EntSize Flags Link Info Align\n"));
7961 }
f7a99963 7962 }
252b5132 7963
5477e8a0
L
7964 if (do_section_details)
7965 printf (_(" Flags\n"));
7966
dda8d76d
NC
7967 for (i = 0, section = filedata->section_headers;
7968 i < filedata->file_header.e_shnum;
b34976b6 7969 i++, section++)
252b5132 7970 {
dd905818
NC
7971 /* Run some sanity checks on the section header. */
7972
7973 /* Check the sh_link field. */
7974 switch (section->sh_type)
7975 {
285e3f99
AM
7976 case SHT_REL:
7977 case SHT_RELA:
7978 if (section->sh_link == 0
7979 && (filedata->file_header.e_type == ET_EXEC
7980 || filedata->file_header.e_type == ET_DYN))
7981 /* A dynamic relocation section where all entries use a
7982 zero symbol index need not specify a symtab section. */
7983 break;
7984 /* Fall through. */
dd905818
NC
7985 case SHT_SYMTAB_SHNDX:
7986 case SHT_GROUP:
7987 case SHT_HASH:
7988 case SHT_GNU_HASH:
7989 case SHT_GNU_versym:
285e3f99 7990 if (section->sh_link == 0
dda8d76d
NC
7991 || section->sh_link >= filedata->file_header.e_shnum
7992 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7993 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7994 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7995 i, section->sh_link);
7996 break;
7997
7998 case SHT_DYNAMIC:
7999 case SHT_SYMTAB:
8000 case SHT_DYNSYM:
8001 case SHT_GNU_verneed:
8002 case SHT_GNU_verdef:
8003 case SHT_GNU_LIBLIST:
285e3f99 8004 if (section->sh_link == 0
dda8d76d
NC
8005 || section->sh_link >= filedata->file_header.e_shnum
8006 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8007 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8008 i, section->sh_link);
8009 break;
8010
8011 case SHT_INIT_ARRAY:
8012 case SHT_FINI_ARRAY:
8013 case SHT_PREINIT_ARRAY:
8014 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8015 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8016 i, section->sh_link);
8017 break;
8018
8019 default:
8020 /* FIXME: Add support for target specific section types. */
8021#if 0 /* Currently we do not check other section types as there are too
8022 many special cases. Stab sections for example have a type
8023 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8024 section. */
8025 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8026 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8027 i, section->sh_link);
8028#endif
8029 break;
8030 }
8031
8032 /* Check the sh_info field. */
8033 switch (section->sh_type)
8034 {
8035 case SHT_REL:
8036 case SHT_RELA:
285e3f99
AM
8037 if (section->sh_info == 0
8038 && (filedata->file_header.e_type == ET_EXEC
8039 || filedata->file_header.e_type == ET_DYN))
8040 /* Dynamic relocations apply to segments, so they do not
8041 need to specify the section they relocate. */
8042 break;
8043 if (section->sh_info == 0
dda8d76d
NC
8044 || section->sh_info >= filedata->file_header.e_shnum
8045 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8046 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8047 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8048 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8049 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8050 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8051 /* FIXME: Are other section types valid ? */
dda8d76d 8052 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8053 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8054 i, section->sh_info);
dd905818
NC
8055 break;
8056
8057 case SHT_DYNAMIC:
8058 case SHT_HASH:
8059 case SHT_SYMTAB_SHNDX:
8060 case SHT_INIT_ARRAY:
8061 case SHT_FINI_ARRAY:
8062 case SHT_PREINIT_ARRAY:
8063 if (section->sh_info != 0)
8064 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8065 i, section->sh_info);
8066 break;
8067
8068 case SHT_GROUP:
8069 case SHT_SYMTAB:
8070 case SHT_DYNSYM:
8071 /* A symbol index - we assume that it is valid. */
8072 break;
8073
8074 default:
8075 /* FIXME: Add support for target specific section types. */
8076 if (section->sh_type == SHT_NOBITS)
8077 /* NOBITS section headers with non-zero sh_info fields can be
8078 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8079 information. The stripped sections have their headers
8080 preserved but their types set to SHT_NOBITS. So do not check
8081 this type of section. */
dd905818
NC
8082 ;
8083 else if (section->sh_flags & SHF_INFO_LINK)
8084 {
dda8d76d 8085 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8086 warn (_("[%2u]: Expected link to another section in info field"), i);
8087 }
a91e1603
L
8088 else if (section->sh_type < SHT_LOOS
8089 && (section->sh_flags & SHF_GNU_MBIND) == 0
8090 && section->sh_info != 0)
dd905818
NC
8091 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8092 i, section->sh_info);
8093 break;
8094 }
8095
3e6b6445 8096 /* Check the sh_size field. */
dda8d76d 8097 if (section->sh_size > filedata->file_size
3e6b6445
NC
8098 && section->sh_type != SHT_NOBITS
8099 && section->sh_type != SHT_NULL
8100 && section->sh_type < SHT_LOOS)
8101 warn (_("Size of section %u is larger than the entire file!\n"), i);
8102
7bfd842d 8103 printf (" [%2u] ", i);
5477e8a0 8104 if (do_section_details)
dda8d76d 8105 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8106 else
b6ac461a 8107 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8108
ea52a088 8109 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8110 get_section_type_name (filedata, section->sh_type));
0b4362b0 8111
f7a99963
NC
8112 if (is_32bit_elf)
8113 {
cfcac11d
NC
8114 const char * link_too_big = NULL;
8115
f7a99963 8116 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8117
f7a99963
NC
8118 printf ( " %6.6lx %6.6lx %2.2lx",
8119 (unsigned long) section->sh_offset,
8120 (unsigned long) section->sh_size,
8121 (unsigned long) section->sh_entsize);
d1133906 8122
5477e8a0
L
8123 if (do_section_details)
8124 fputs (" ", stdout);
8125 else
dda8d76d 8126 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8127
dda8d76d 8128 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8129 {
8130 link_too_big = "";
8131 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8132 an error but it can have special values in Solaris binaries. */
dda8d76d 8133 switch (filedata->file_header.e_machine)
cfcac11d 8134 {
caa83f8b 8135 case EM_386:
22abe556 8136 case EM_IAMCU:
caa83f8b 8137 case EM_X86_64:
7f502d6c 8138 case EM_L1OM:
7a9068fe 8139 case EM_K1OM:
cfcac11d
NC
8140 case EM_OLD_SPARCV9:
8141 case EM_SPARC32PLUS:
8142 case EM_SPARCV9:
8143 case EM_SPARC:
8144 if (section->sh_link == (SHN_BEFORE & 0xffff))
8145 link_too_big = "BEFORE";
8146 else if (section->sh_link == (SHN_AFTER & 0xffff))
8147 link_too_big = "AFTER";
8148 break;
8149 default:
8150 break;
8151 }
8152 }
8153
8154 if (do_section_details)
8155 {
8156 if (link_too_big != NULL && * link_too_big)
8157 printf ("<%s> ", link_too_big);
8158 else
8159 printf ("%2u ", section->sh_link);
8160 printf ("%3u %2lu\n", section->sh_info,
8161 (unsigned long) section->sh_addralign);
8162 }
8163 else
8164 printf ("%2u %3u %2lu\n",
8165 section->sh_link,
8166 section->sh_info,
8167 (unsigned long) section->sh_addralign);
8168
8169 if (link_too_big && ! * link_too_big)
8170 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8171 i, section->sh_link);
f7a99963 8172 }
d974e256
JJ
8173 else if (do_wide)
8174 {
8175 print_vma (section->sh_addr, LONG_HEX);
8176
8177 if ((long) section->sh_offset == section->sh_offset)
8178 printf (" %6.6lx", (unsigned long) section->sh_offset);
8179 else
8180 {
8181 putchar (' ');
8182 print_vma (section->sh_offset, LONG_HEX);
8183 }
8184
8185 if ((unsigned long) section->sh_size == section->sh_size)
8186 printf (" %6.6lx", (unsigned long) section->sh_size);
8187 else
8188 {
8189 putchar (' ');
8190 print_vma (section->sh_size, LONG_HEX);
8191 }
8192
8193 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8194 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8195 else
8196 {
8197 putchar (' ');
8198 print_vma (section->sh_entsize, LONG_HEX);
8199 }
8200
5477e8a0
L
8201 if (do_section_details)
8202 fputs (" ", stdout);
8203 else
dda8d76d 8204 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8205
72de5009 8206 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8207
8208 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8209 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8210 else
8211 {
8212 print_vma (section->sh_addralign, DEC);
8213 putchar ('\n');
8214 }
8215 }
5477e8a0 8216 else if (do_section_details)
595cf52e 8217 {
55cc53e9 8218 putchar (' ');
595cf52e
L
8219 print_vma (section->sh_addr, LONG_HEX);
8220 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8221 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8222 else
8223 {
8224 printf (" ");
8225 print_vma (section->sh_offset, LONG_HEX);
8226 }
72de5009 8227 printf (" %u\n ", section->sh_link);
595cf52e 8228 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8229 putchar (' ');
595cf52e
L
8230 print_vma (section->sh_entsize, LONG_HEX);
8231
72de5009
AM
8232 printf (" %-16u %lu\n",
8233 section->sh_info,
595cf52e
L
8234 (unsigned long) section->sh_addralign);
8235 }
f7a99963
NC
8236 else
8237 {
8238 putchar (' ');
8239 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8240 if ((long) section->sh_offset == section->sh_offset)
8241 printf (" %8.8lx", (unsigned long) section->sh_offset);
8242 else
8243 {
8244 printf (" ");
8245 print_vma (section->sh_offset, LONG_HEX);
8246 }
f7a99963
NC
8247 printf ("\n ");
8248 print_vma (section->sh_size, LONG_HEX);
8249 printf (" ");
8250 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8251
dda8d76d 8252 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8253
72de5009
AM
8254 printf (" %2u %3u %lu\n",
8255 section->sh_link,
8256 section->sh_info,
f7a99963
NC
8257 (unsigned long) section->sh_addralign);
8258 }
5477e8a0
L
8259
8260 if (do_section_details)
77115a4a 8261 {
dda8d76d 8262 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8263 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8264 {
8265 /* Minimum section size is 12 bytes for 32-bit compression
8266 header + 12 bytes for compressed data header. */
8267 unsigned char buf[24];
d8024a91 8268
77115a4a 8269 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8270 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8271 sizeof (buf), _("compression header")))
8272 {
8273 Elf_Internal_Chdr chdr;
d8024a91 8274
5844b465
NC
8275 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8276 printf (_(" [<corrupt>]\n"));
77115a4a 8277 else
5844b465 8278 {
89dbeac7 8279 if (chdr.ch_type == ch_compress_zlib)
5844b465 8280 printf (" ZLIB, ");
89dbeac7 8281 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8282 printf (" ZSTD, ");
5844b465
NC
8283 else
8284 printf (_(" [<unknown>: 0x%x], "),
8285 chdr.ch_type);
8286 print_vma (chdr.ch_size, LONG_HEX);
8287 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8288 }
77115a4a
L
8289 }
8290 }
8291 }
252b5132
RH
8292 }
8293
5477e8a0 8294 if (!do_section_details)
3dbcc61d 8295 {
9fb71ee4
NC
8296 /* The ordering of the letters shown here matches the ordering of the
8297 corresponding SHF_xxx values, and hence the order in which these
8298 letters will be displayed to the user. */
8299 printf (_("Key to Flags:\n\
8300 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8301 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8302 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8303 switch (filedata->file_header.e_ident[EI_OSABI])
8304 {
8305 case ELFOSABI_GNU:
8306 case ELFOSABI_FREEBSD:
8307 printf (_("R (retain), "));
8308 /* Fall through */
8309 case ELFOSABI_NONE:
8310 printf (_("D (mbind), "));
8311 break;
8312 default:
8313 break;
8314 }
dda8d76d
NC
8315 if (filedata->file_header.e_machine == EM_X86_64
8316 || filedata->file_header.e_machine == EM_L1OM
8317 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8318 printf (_("l (large), "));
dda8d76d 8319 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8320 printf (_("y (purecode), "));
dda8d76d 8321 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8322 printf (_("v (VLE), "));
9fb71ee4 8323 printf ("p (processor specific)\n");
0b4362b0 8324 }
d1133906 8325
015dc7e1 8326 return true;
252b5132
RH
8327}
8328
015dc7e1 8329static bool
28d13567 8330get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8331 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8332 char **strtab, uint64_t *strtablen)
28d13567
AM
8333{
8334 *strtab = NULL;
8335 *strtablen = 0;
4de91c10 8336 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8337
8338 if (*symtab == NULL)
015dc7e1 8339 return false;
28d13567
AM
8340
8341 if (symsec->sh_link != 0)
8342 {
8343 Elf_Internal_Shdr *strsec;
8344
8345 if (symsec->sh_link >= filedata->file_header.e_shnum)
8346 {
8347 error (_("Bad sh_link in symbol table section\n"));
8348 free (*symtab);
8349 *symtab = NULL;
8350 *nsyms = 0;
015dc7e1 8351 return false;
28d13567
AM
8352 }
8353
8354 strsec = filedata->section_headers + symsec->sh_link;
8355
8356 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8357 1, strsec->sh_size, _("string table"));
8358 if (*strtab == NULL)
8359 {
8360 free (*symtab);
8361 *symtab = NULL;
8362 *nsyms = 0;
015dc7e1 8363 return false;
28d13567
AM
8364 }
8365 *strtablen = strsec->sh_size;
8366 }
015dc7e1 8367 return true;
28d13567
AM
8368}
8369
f5842774
L
8370static const char *
8371get_group_flags (unsigned int flags)
8372{
1449284b 8373 static char buff[128];
220453ec 8374
6d913794
NC
8375 if (flags == 0)
8376 return "";
8377 else if (flags == GRP_COMDAT)
8378 return "COMDAT ";
f5842774 8379
89246a0e
AM
8380 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8381 flags,
8382 flags & GRP_MASKOS ? _("<OS specific>") : "",
8383 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8384 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8385 ? _("<unknown>") : ""));
6d913794 8386
f5842774
L
8387 return buff;
8388}
8389
015dc7e1 8390static bool
dda8d76d 8391process_section_groups (Filedata * filedata)
f5842774 8392{
2cf0635d 8393 Elf_Internal_Shdr * section;
f5842774 8394 unsigned int i;
2cf0635d
NC
8395 struct group * group;
8396 Elf_Internal_Shdr * symtab_sec;
8397 Elf_Internal_Shdr * strtab_sec;
8398 Elf_Internal_Sym * symtab;
26c527e6 8399 uint64_t num_syms;
2cf0635d 8400 char * strtab;
c256ffe7 8401 size_t strtab_size;
d1f5c6e3
L
8402
8403 /* Don't process section groups unless needed. */
8404 if (!do_unwind && !do_section_groups)
015dc7e1 8405 return true;
f5842774 8406
dda8d76d 8407 if (filedata->file_header.e_shnum == 0)
f5842774
L
8408 {
8409 if (do_section_groups)
ca0e11aa
NC
8410 {
8411 if (filedata->is_separate)
8412 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8413 filedata->file_name);
8414 else
8415 printf (_("\nThere are no section groups in this file.\n"));
8416 }
015dc7e1 8417 return true;
f5842774
L
8418 }
8419
dda8d76d 8420 if (filedata->section_headers == NULL)
f5842774
L
8421 {
8422 error (_("Section headers are not available!\n"));
fa1908fd 8423 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8424 return false;
f5842774
L
8425 }
8426
978c4450
AM
8427 filedata->section_headers_groups
8428 = (struct group **) calloc (filedata->file_header.e_shnum,
8429 sizeof (struct group *));
e4b17d5c 8430
978c4450 8431 if (filedata->section_headers_groups == NULL)
e4b17d5c 8432 {
8b73c356 8433 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8434 filedata->file_header.e_shnum);
015dc7e1 8435 return false;
e4b17d5c
L
8436 }
8437
f5842774 8438 /* Scan the sections for the group section. */
978c4450 8439 filedata->group_count = 0;
dda8d76d
NC
8440 for (i = 0, section = filedata->section_headers;
8441 i < filedata->file_header.e_shnum;
f5842774 8442 i++, section++)
e4b17d5c 8443 if (section->sh_type == SHT_GROUP)
978c4450 8444 filedata->group_count++;
e4b17d5c 8445
978c4450 8446 if (filedata->group_count == 0)
d1f5c6e3
L
8447 {
8448 if (do_section_groups)
ca0e11aa
NC
8449 {
8450 if (filedata->is_separate)
8451 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8452 filedata->file_name);
8453 else
8454 printf (_("\nThere are no section groups in this file.\n"));
8455 }
d1f5c6e3 8456
015dc7e1 8457 return true;
d1f5c6e3
L
8458 }
8459
978c4450
AM
8460 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8461 sizeof (struct group));
e4b17d5c 8462
978c4450 8463 if (filedata->section_groups == NULL)
e4b17d5c 8464 {
26c527e6 8465 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8466 return false;
e4b17d5c
L
8467 }
8468
d1f5c6e3
L
8469 symtab_sec = NULL;
8470 strtab_sec = NULL;
8471 symtab = NULL;
ba5cdace 8472 num_syms = 0;
d1f5c6e3 8473 strtab = NULL;
c256ffe7 8474 strtab_size = 0;
ca0e11aa
NC
8475
8476 if (filedata->is_separate)
8477 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8478
978c4450 8479 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8480 i < filedata->file_header.e_shnum;
e4b17d5c 8481 i++, section++)
f5842774
L
8482 {
8483 if (section->sh_type == SHT_GROUP)
8484 {
dda8d76d 8485 const char * name = printable_section_name (filedata, section);
74e1a04b 8486 const char * group_name;
2cf0635d
NC
8487 unsigned char * start;
8488 unsigned char * indices;
f5842774 8489 unsigned int entry, j, size;
2cf0635d
NC
8490 Elf_Internal_Shdr * sec;
8491 Elf_Internal_Sym * sym;
f5842774
L
8492
8493 /* Get the symbol table. */
dda8d76d
NC
8494 if (section->sh_link >= filedata->file_header.e_shnum
8495 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8496 != SHT_SYMTAB))
f5842774
L
8497 {
8498 error (_("Bad sh_link in group section `%s'\n"), name);
8499 continue;
8500 }
d1f5c6e3
L
8501
8502 if (symtab_sec != sec)
8503 {
8504 symtab_sec = sec;
9db70fc3 8505 free (symtab);
4de91c10 8506 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8507 }
f5842774 8508
dd24e3da
NC
8509 if (symtab == NULL)
8510 {
8511 error (_("Corrupt header in group section `%s'\n"), name);
8512 continue;
8513 }
8514
ba5cdace
NC
8515 if (section->sh_info >= num_syms)
8516 {
8517 error (_("Bad sh_info in group section `%s'\n"), name);
8518 continue;
8519 }
8520
f5842774
L
8521 sym = symtab + section->sh_info;
8522
8523 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8524 {
4fbb74a6 8525 if (sym->st_shndx == 0
dda8d76d 8526 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8527 {
8528 error (_("Bad sh_info in group section `%s'\n"), name);
8529 continue;
8530 }
ba2685cc 8531
b6ac461a
NC
8532 group_name = printable_section_name (filedata,
8533 filedata->section_headers
8534 + sym->st_shndx);
c256ffe7 8535 strtab_sec = NULL;
9db70fc3 8536 free (strtab);
f5842774 8537 strtab = NULL;
c256ffe7 8538 strtab_size = 0;
f5842774
L
8539 }
8540 else
8541 {
8542 /* Get the string table. */
dda8d76d 8543 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8544 {
8545 strtab_sec = NULL;
9db70fc3 8546 free (strtab);
c256ffe7
JJ
8547 strtab = NULL;
8548 strtab_size = 0;
8549 }
8550 else if (strtab_sec
dda8d76d 8551 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8552 {
8553 strtab_sec = sec;
9db70fc3 8554 free (strtab);
071436c6 8555
dda8d76d 8556 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8557 1, strtab_sec->sh_size,
8558 _("string table"));
c256ffe7 8559 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8560 }
c256ffe7 8561 group_name = sym->st_name < strtab_size
2b692964 8562 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8563 }
8564
c9c1d674
EG
8565 /* PR 17531: file: loop. */
8566 if (section->sh_entsize > section->sh_size)
8567 {
26c527e6
AM
8568 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8569 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8570 printable_section_name (filedata, section),
26c527e6
AM
8571 section->sh_entsize,
8572 section->sh_size);
61dd8e19 8573 continue;
c9c1d674
EG
8574 }
8575
dda8d76d 8576 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8577 1, section->sh_size,
8578 _("section data"));
59245841
NC
8579 if (start == NULL)
8580 continue;
f5842774
L
8581
8582 indices = start;
8583 size = (section->sh_size / section->sh_entsize) - 1;
8584 entry = byte_get (indices, 4);
8585 indices += 4;
e4b17d5c
L
8586
8587 if (do_section_groups)
8588 {
2b692964 8589 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8590 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8591
e4b17d5c
L
8592 printf (_(" [Index] Name\n"));
8593 }
8594
8595 group->group_index = i;
8596
f5842774
L
8597 for (j = 0; j < size; j++)
8598 {
2cf0635d 8599 struct group_list * g;
e4b17d5c 8600
f5842774
L
8601 entry = byte_get (indices, 4);
8602 indices += 4;
8603
dda8d76d 8604 if (entry >= filedata->file_header.e_shnum)
391cb864 8605 {
57028622
NC
8606 static unsigned num_group_errors = 0;
8607
8608 if (num_group_errors ++ < 10)
8609 {
8610 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8611 entry, i, filedata->file_header.e_shnum - 1);
57028622 8612 if (num_group_errors == 10)
67ce483b 8613 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8614 }
391cb864
L
8615 continue;
8616 }
391cb864 8617
978c4450 8618 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8619 {
d1f5c6e3
L
8620 if (entry)
8621 {
57028622
NC
8622 static unsigned num_errs = 0;
8623
8624 if (num_errs ++ < 10)
8625 {
8626 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8627 entry, i,
978c4450 8628 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8629 if (num_errs == 10)
8630 warn (_("Further error messages about already contained group sections suppressed\n"));
8631 }
d1f5c6e3
L
8632 continue;
8633 }
8634 else
8635 {
8636 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8637 section group. We just warn it the first time
d1f5c6e3 8638 and ignore it afterwards. */
015dc7e1 8639 static bool warned = false;
d1f5c6e3
L
8640 if (!warned)
8641 {
8642 error (_("section 0 in group section [%5u]\n"),
978c4450 8643 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8644 warned = true;
d1f5c6e3
L
8645 }
8646 }
e4b17d5c
L
8647 }
8648
978c4450 8649 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8650
8651 if (do_section_groups)
8652 {
dda8d76d
NC
8653 sec = filedata->section_headers + entry;
8654 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8655 }
8656
3f5e193b 8657 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8658 g->section_index = entry;
8659 g->next = group->root;
8660 group->root = g;
f5842774
L
8661 }
8662
9db70fc3 8663 free (start);
e4b17d5c
L
8664
8665 group++;
f5842774
L
8666 }
8667 }
8668
9db70fc3
AM
8669 free (symtab);
8670 free (strtab);
015dc7e1 8671 return true;
f5842774
L
8672}
8673
28f997cf
TG
8674/* Data used to display dynamic fixups. */
8675
8676struct ia64_vms_dynfixup
8677{
625d49fc
AM
8678 uint64_t needed_ident; /* Library ident number. */
8679 uint64_t needed; /* Index in the dstrtab of the library name. */
8680 uint64_t fixup_needed; /* Index of the library. */
8681 uint64_t fixup_rela_cnt; /* Number of fixups. */
8682 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8683};
8684
8685/* Data used to display dynamic relocations. */
8686
8687struct ia64_vms_dynimgrela
8688{
625d49fc
AM
8689 uint64_t img_rela_cnt; /* Number of relocations. */
8690 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8691};
8692
8693/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8694 library). */
8695
015dc7e1 8696static bool
dda8d76d
NC
8697dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8698 struct ia64_vms_dynfixup * fixup,
8699 const char * strtab,
8700 unsigned int strtab_sz)
28f997cf 8701{
32ec8896 8702 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8703 size_t i;
32ec8896 8704 const char * lib_name;
28f997cf 8705
978c4450
AM
8706 imfs = get_data (NULL, filedata,
8707 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8708 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8709 _("dynamic section image fixups"));
8710 if (!imfs)
015dc7e1 8711 return false;
28f997cf
TG
8712
8713 if (fixup->needed < strtab_sz)
8714 lib_name = strtab + fixup->needed;
8715 else
8716 {
26c527e6
AM
8717 warn (_("corrupt library name index of %#" PRIx64
8718 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8719 lib_name = "???";
8720 }
736990c4 8721
26c527e6
AM
8722 printf (_("\nImage fixups for needed library #%" PRId64
8723 ": %s - ident: %" PRIx64 "\n"),
8724 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8725 printf
8726 (_("Seg Offset Type SymVec DataType\n"));
8727
26c527e6 8728 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8729 {
8730 unsigned int type;
8731 const char *rtype;
8732
8733 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8734 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8735 type = BYTE_GET (imfs [i].type);
8736 rtype = elf_ia64_reloc_type (type);
8737 if (rtype == NULL)
f493c217 8738 printf ("0x%08x ", type);
28f997cf 8739 else
f493c217 8740 printf ("%-32s ", rtype);
28f997cf
TG
8741 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8742 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8743 }
8744
8745 free (imfs);
015dc7e1 8746 return true;
28f997cf
TG
8747}
8748
8749/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8750
015dc7e1 8751static bool
dda8d76d 8752dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8753{
8754 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8755 size_t i;
28f997cf 8756
978c4450
AM
8757 imrs = get_data (NULL, filedata,
8758 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8759 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8760 _("dynamic section image relocations"));
28f997cf 8761 if (!imrs)
015dc7e1 8762 return false;
28f997cf
TG
8763
8764 printf (_("\nImage relocs\n"));
8765 printf
8766 (_("Seg Offset Type Addend Seg Sym Off\n"));
8767
26c527e6 8768 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8769 {
8770 unsigned int type;
8771 const char *rtype;
8772
8773 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8774 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8775 type = BYTE_GET (imrs [i].type);
8776 rtype = elf_ia64_reloc_type (type);
8777 if (rtype == NULL)
8778 printf ("0x%08x ", type);
8779 else
8780 printf ("%-31s ", rtype);
8781 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8782 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8783 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8784 }
8785
8786 free (imrs);
015dc7e1 8787 return true;
28f997cf
TG
8788}
8789
8790/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8791
015dc7e1 8792static bool
dda8d76d 8793process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8794{
8795 struct ia64_vms_dynfixup fixup;
8796 struct ia64_vms_dynimgrela imgrela;
8797 Elf_Internal_Dyn *entry;
625d49fc
AM
8798 uint64_t strtab_off = 0;
8799 uint64_t strtab_sz = 0;
28f997cf 8800 char *strtab = NULL;
015dc7e1 8801 bool res = true;
28f997cf
TG
8802
8803 memset (&fixup, 0, sizeof (fixup));
8804 memset (&imgrela, 0, sizeof (imgrela));
8805
8806 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8807 for (entry = filedata->dynamic_section;
8808 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8809 entry++)
8810 {
8811 switch (entry->d_tag)
8812 {
8813 case DT_IA_64_VMS_STRTAB_OFFSET:
8814 strtab_off = entry->d_un.d_val;
8815 break;
8816 case DT_STRSZ:
8817 strtab_sz = entry->d_un.d_val;
8818 if (strtab == NULL)
978c4450
AM
8819 strtab = get_data (NULL, filedata,
8820 filedata->dynamic_addr + strtab_off,
28f997cf 8821 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8822 if (strtab == NULL)
8823 strtab_sz = 0;
28f997cf
TG
8824 break;
8825
8826 case DT_IA_64_VMS_NEEDED_IDENT:
8827 fixup.needed_ident = entry->d_un.d_val;
8828 break;
8829 case DT_NEEDED:
8830 fixup.needed = entry->d_un.d_val;
8831 break;
8832 case DT_IA_64_VMS_FIXUP_NEEDED:
8833 fixup.fixup_needed = entry->d_un.d_val;
8834 break;
8835 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8836 fixup.fixup_rela_cnt = entry->d_un.d_val;
8837 break;
8838 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8839 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8840 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8841 res = false;
28f997cf 8842 break;
28f997cf
TG
8843 case DT_IA_64_VMS_IMG_RELA_CNT:
8844 imgrela.img_rela_cnt = entry->d_un.d_val;
8845 break;
8846 case DT_IA_64_VMS_IMG_RELA_OFF:
8847 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8848 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8849 res = false;
28f997cf
TG
8850 break;
8851
8852 default:
8853 break;
8854 }
8855 }
8856
9db70fc3 8857 free (strtab);
28f997cf
TG
8858
8859 return res;
8860}
8861
85b1c36d 8862static struct
566b0d53 8863{
2cf0635d 8864 const char * name;
566b0d53
L
8865 int reloc;
8866 int size;
a7fd1186 8867 relocation_type rel_type;
32ec8896
NC
8868}
8869 dynamic_relocations [] =
566b0d53 8870{
a7fd1186
FS
8871 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8872 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8873 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8874 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8875};
8876
252b5132 8877/* Process the reloc section. */
18bd398b 8878
015dc7e1 8879static bool
dda8d76d 8880process_relocs (Filedata * filedata)
252b5132 8881{
26c527e6
AM
8882 uint64_t rel_size;
8883 uint64_t rel_offset;
252b5132 8884
252b5132 8885 if (!do_reloc)
015dc7e1 8886 return true;
252b5132
RH
8887
8888 if (do_using_dynamic)
8889 {
a7fd1186 8890 relocation_type rel_type;
2cf0635d 8891 const char * name;
015dc7e1 8892 bool has_dynamic_reloc;
566b0d53 8893 unsigned int i;
0de14b54 8894
015dc7e1 8895 has_dynamic_reloc = false;
252b5132 8896
566b0d53 8897 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8898 {
a7fd1186 8899 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8900 name = dynamic_relocations [i].name;
978c4450
AM
8901 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8902 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8903
32ec8896 8904 if (rel_size)
015dc7e1 8905 has_dynamic_reloc = true;
566b0d53 8906
a7fd1186 8907 if (rel_type == reltype_unknown)
aa903cfb 8908 {
566b0d53 8909 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8910 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8911 {
8912 case DT_REL:
a7fd1186 8913 rel_type = reltype_rel;
566b0d53
L
8914 break;
8915 case DT_RELA:
a7fd1186 8916 rel_type = reltype_rela;
566b0d53
L
8917 break;
8918 }
aa903cfb 8919 }
252b5132 8920
566b0d53
L
8921 if (rel_size)
8922 {
ca0e11aa
NC
8923 if (filedata->is_separate)
8924 printf
26c527e6
AM
8925 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8926 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8927 filedata->file_name, name, rel_offset, rel_size);
8928 else
8929 printf
26c527e6
AM
8930 (_("\n'%s' relocation section at offset %#" PRIx64
8931 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8932 name, rel_offset, rel_size);
252b5132 8933
dda8d76d
NC
8934 dump_relocations (filedata,
8935 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8936 rel_size,
978c4450
AM
8937 filedata->dynamic_symbols,
8938 filedata->num_dynamic_syms,
8939 filedata->dynamic_strings,
8940 filedata->dynamic_strings_length,
a7fd1186 8941 rel_type, true /* is_dynamic */);
566b0d53 8942 }
252b5132 8943 }
566b0d53 8944
dda8d76d
NC
8945 if (is_ia64_vms (filedata))
8946 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8947 has_dynamic_reloc = true;
28f997cf 8948
566b0d53 8949 if (! has_dynamic_reloc)
ca0e11aa
NC
8950 {
8951 if (filedata->is_separate)
8952 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8953 filedata->file_name);
8954 else
8955 printf (_("\nThere are no dynamic relocations in this file.\n"));
8956 }
252b5132
RH
8957 }
8958 else
8959 {
2cf0635d 8960 Elf_Internal_Shdr * section;
26c527e6 8961 size_t i;
015dc7e1 8962 bool found = false;
252b5132 8963
dda8d76d
NC
8964 for (i = 0, section = filedata->section_headers;
8965 i < filedata->file_header.e_shnum;
b34976b6 8966 i++, section++)
252b5132
RH
8967 {
8968 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8969 && section->sh_type != SHT_REL
8970 && section->sh_type != SHT_RELR)
252b5132
RH
8971 continue;
8972
8973 rel_offset = section->sh_offset;
8974 rel_size = section->sh_size;
8975
8976 if (rel_size)
8977 {
a7fd1186 8978 relocation_type rel_type;
26c527e6 8979 uint64_t num_rela;
103f02d3 8980
ca0e11aa
NC
8981 if (filedata->is_separate)
8982 printf (_("\nIn linked file '%s' relocation section "),
8983 filedata->file_name);
8984 else
8985 printf (_("\nRelocation section "));
252b5132 8986
dda8d76d 8987 if (filedata->string_table == NULL)
19936277 8988 printf ("%d", section->sh_name);
252b5132 8989 else
dda8d76d 8990 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8991
d3a49aa8 8992 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8993 printf (ngettext (" at offset %#" PRIx64
8994 " contains %" PRIu64 " entry:\n",
8995 " at offset %#" PRIx64
8996 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8997 num_rela),
8998 rel_offset, num_rela);
252b5132 8999
a7fd1186
FS
9000 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
9001 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 9002
4fbb74a6 9003 if (section->sh_link != 0
dda8d76d 9004 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 9005 {
26c527e6
AM
9006 Elf_Internal_Shdr *symsec;
9007 Elf_Internal_Sym *symtab;
9008 uint64_t nsyms;
9009 uint64_t strtablen = 0;
9010 char *strtab = NULL;
57346661 9011
dda8d76d 9012 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
9013 if (symsec->sh_type != SHT_SYMTAB
9014 && symsec->sh_type != SHT_DYNSYM)
9015 continue;
9016
28d13567
AM
9017 if (!get_symtab (filedata, symsec,
9018 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 9019 continue;
252b5132 9020
dda8d76d 9021 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 9022 symtab, nsyms, strtab, strtablen,
a7fd1186 9023 rel_type,
bb4d2ac2 9024 symsec->sh_type == SHT_DYNSYM);
9db70fc3 9025 free (strtab);
d79b3d50
NC
9026 free (symtab);
9027 }
9028 else
dda8d76d 9029 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 9030 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 9031
015dc7e1 9032 found = true;
252b5132
RH
9033 }
9034 }
9035
9036 if (! found)
45ac8f4f
NC
9037 {
9038 /* Users sometimes forget the -D option, so try to be helpful. */
9039 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9040 {
978c4450 9041 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9042 {
ca0e11aa
NC
9043 if (filedata->is_separate)
9044 printf (_("\nThere are no static relocations in linked file '%s'."),
9045 filedata->file_name);
9046 else
9047 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9048 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9049
9050 break;
9051 }
9052 }
9053 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9054 {
9055 if (filedata->is_separate)
9056 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9057 filedata->file_name);
9058 else
9059 printf (_("\nThere are no relocations in this file.\n"));
9060 }
45ac8f4f 9061 }
252b5132
RH
9062 }
9063
015dc7e1 9064 return true;
252b5132
RH
9065}
9066
4d6ed7c8
NC
9067/* An absolute address consists of a section and an offset. If the
9068 section is NULL, the offset itself is the address, otherwise, the
9069 address equals to LOAD_ADDRESS(section) + offset. */
9070
9071struct absaddr
948f632f
DA
9072{
9073 unsigned short section;
625d49fc 9074 uint64_t offset;
948f632f 9075};
4d6ed7c8 9076
948f632f
DA
9077/* Find the nearest symbol at or below ADDR. Returns the symbol
9078 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9079
4d6ed7c8 9080static void
26c527e6
AM
9081find_symbol_for_address (Filedata *filedata,
9082 Elf_Internal_Sym *symtab,
9083 uint64_t nsyms,
9084 const char *strtab,
9085 uint64_t strtab_size,
9086 struct absaddr addr,
9087 const char **symname,
9088 uint64_t *offset)
4d6ed7c8 9089{
625d49fc 9090 uint64_t dist = 0x100000;
2cf0635d 9091 Elf_Internal_Sym * sym;
948f632f
DA
9092 Elf_Internal_Sym * beg;
9093 Elf_Internal_Sym * end;
2cf0635d 9094 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9095
0b6ae522 9096 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9097 beg = symtab;
9098 end = symtab + nsyms;
0b6ae522 9099
948f632f 9100 while (beg < end)
4d6ed7c8 9101 {
625d49fc 9102 uint64_t value;
948f632f
DA
9103
9104 sym = beg + (end - beg) / 2;
0b6ae522 9105
948f632f 9106 value = sym->st_value;
0b6ae522
DJ
9107 REMOVE_ARCH_BITS (value);
9108
948f632f 9109 if (sym->st_name != 0
4d6ed7c8 9110 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9111 && addr.offset >= value
9112 && addr.offset - value < dist)
4d6ed7c8
NC
9113 {
9114 best = sym;
0b6ae522 9115 dist = addr.offset - value;
4d6ed7c8
NC
9116 if (!dist)
9117 break;
9118 }
948f632f
DA
9119
9120 if (addr.offset < value)
9121 end = sym;
9122 else
9123 beg = sym + 1;
4d6ed7c8 9124 }
1b31d05e 9125
4d6ed7c8
NC
9126 if (best)
9127 {
57346661 9128 *symname = (best->st_name >= strtab_size
2b692964 9129 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9130 *offset = dist;
9131 return;
9132 }
1b31d05e 9133
4d6ed7c8
NC
9134 *symname = NULL;
9135 *offset = addr.offset;
9136}
9137
32ec8896 9138static /* signed */ int
948f632f
DA
9139symcmp (const void *p, const void *q)
9140{
9141 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9142 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9143
9144 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9145}
9146
9147/* Process the unwind section. */
9148
9149#include "unwind-ia64.h"
9150
9151struct ia64_unw_table_entry
9152{
9153 struct absaddr start;
9154 struct absaddr end;
9155 struct absaddr info;
9156};
9157
9158struct ia64_unw_aux_info
9159{
32ec8896 9160 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9161 uint64_t table_len; /* Length of unwind table. */
32ec8896 9162 unsigned char * info; /* Unwind info. */
26c527e6 9163 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9164 uint64_t info_addr; /* Starting address of unwind info. */
9165 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9166 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9167 uint64_t nsyms; /* Number of symbols. */
32ec8896 9168 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9169 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9170 char * strtab; /* The string table. */
26c527e6 9171 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9172};
9173
015dc7e1 9174static bool
dda8d76d 9175dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9176{
2cf0635d 9177 struct ia64_unw_table_entry * tp;
26c527e6 9178 size_t j, nfuns;
4d6ed7c8 9179 int in_body;
015dc7e1 9180 bool res = true;
7036c0e1 9181
948f632f
DA
9182 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9183 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9184 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9185 aux->funtab[nfuns++] = aux->symtab[j];
9186 aux->nfuns = nfuns;
9187 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9188
4d6ed7c8
NC
9189 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9190 {
625d49fc
AM
9191 uint64_t stamp;
9192 uint64_t offset;
2cf0635d
NC
9193 const unsigned char * dp;
9194 const unsigned char * head;
53774b7e 9195 const unsigned char * end;
2cf0635d 9196 const char * procname;
4d6ed7c8 9197
dda8d76d 9198 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9199 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9200
9201 fputs ("\n<", stdout);
9202
9203 if (procname)
9204 {
9205 fputs (procname, stdout);
9206
9207 if (offset)
26c527e6 9208 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9209 }
9210
9211 fputs (">: [", stdout);
9212 print_vma (tp->start.offset, PREFIX_HEX);
9213 fputc ('-', stdout);
9214 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9215 printf ("], info at +0x%" PRIx64 "\n",
9216 tp->info.offset - aux->seg_base);
4d6ed7c8 9217
53774b7e
NC
9218 /* PR 17531: file: 86232b32. */
9219 if (aux->info == NULL)
9220 continue;
9221
97c0a079
AM
9222 offset = tp->info.offset;
9223 if (tp->info.section)
9224 {
9225 if (tp->info.section >= filedata->file_header.e_shnum)
9226 {
26c527e6
AM
9227 warn (_("Invalid section %u in table entry %td\n"),
9228 tp->info.section, tp - aux->table);
015dc7e1 9229 res = false;
97c0a079
AM
9230 continue;
9231 }
9232 offset += filedata->section_headers[tp->info.section].sh_addr;
9233 }
9234 offset -= aux->info_addr;
53774b7e 9235 /* PR 17531: file: 0997b4d1. */
90679903
AM
9236 if (offset >= aux->info_size
9237 || aux->info_size - offset < 8)
53774b7e 9238 {
26c527e6
AM
9239 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9240 tp->info.offset, tp - aux->table);
015dc7e1 9241 res = false;
53774b7e
NC
9242 continue;
9243 }
9244
97c0a079 9245 head = aux->info + offset;
a4a00738 9246 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9247
86f55779 9248 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9249 (unsigned) UNW_VER (stamp),
9250 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9251 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9252 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9253 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9254
9255 if (UNW_VER (stamp) != 1)
9256 {
2b692964 9257 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9258 continue;
9259 }
9260
9261 in_body = 0;
53774b7e
NC
9262 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9263 /* PR 17531: file: 16ceda89. */
9264 if (end > aux->info + aux->info_size)
9265 end = aux->info + aux->info_size;
9266 for (dp = head + 8; dp < end;)
b4477bc8 9267 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9268 }
948f632f
DA
9269
9270 free (aux->funtab);
32ec8896
NC
9271
9272 return res;
4d6ed7c8
NC
9273}
9274
015dc7e1 9275static bool
dda8d76d
NC
9276slurp_ia64_unwind_table (Filedata * filedata,
9277 struct ia64_unw_aux_info * aux,
9278 Elf_Internal_Shdr * sec)
4d6ed7c8 9279{
26c527e6 9280 uint64_t size, nrelas, i;
2cf0635d
NC
9281 Elf_Internal_Phdr * seg;
9282 struct ia64_unw_table_entry * tep;
9283 Elf_Internal_Shdr * relsec;
9284 Elf_Internal_Rela * rela;
9285 Elf_Internal_Rela * rp;
9286 unsigned char * table;
9287 unsigned char * tp;
9288 Elf_Internal_Sym * sym;
9289 const char * relname;
4d6ed7c8 9290
53774b7e
NC
9291 aux->table_len = 0;
9292
4d6ed7c8
NC
9293 /* First, find the starting address of the segment that includes
9294 this section: */
9295
dda8d76d 9296 if (filedata->file_header.e_phnum)
4d6ed7c8 9297 {
dda8d76d 9298 if (! get_program_headers (filedata))
015dc7e1 9299 return false;
4d6ed7c8 9300
dda8d76d
NC
9301 for (seg = filedata->program_headers;
9302 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9303 ++seg)
4d6ed7c8
NC
9304 {
9305 if (seg->p_type != PT_LOAD)
9306 continue;
9307
9308 if (sec->sh_addr >= seg->p_vaddr
9309 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9310 {
9311 aux->seg_base = seg->p_vaddr;
9312 break;
9313 }
9314 }
4d6ed7c8
NC
9315 }
9316
9317 /* Second, build the unwind table from the contents of the unwind section: */
9318 size = sec->sh_size;
dda8d76d 9319 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9320 _("unwind table"));
a6e9f9df 9321 if (!table)
015dc7e1 9322 return false;
4d6ed7c8 9323
53774b7e 9324 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9325 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9326 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9327 tep = aux->table;
53774b7e
NC
9328
9329 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9330 {
9331 tep->start.section = SHN_UNDEF;
9332 tep->end.section = SHN_UNDEF;
9333 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9334 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9335 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9336 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9337 tep->start.offset += aux->seg_base;
9338 tep->end.offset += aux->seg_base;
9339 tep->info.offset += aux->seg_base;
9340 }
9341 free (table);
9342
41e92641 9343 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9344 for (relsec = filedata->section_headers;
9345 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9346 ++relsec)
9347 {
9348 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9349 || relsec->sh_info >= filedata->file_header.e_shnum
9350 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9351 continue;
9352
dda8d76d 9353 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9354 & rela, & nrelas))
53774b7e
NC
9355 {
9356 free (aux->table);
9357 aux->table = NULL;
9358 aux->table_len = 0;
015dc7e1 9359 return false;
53774b7e 9360 }
4d6ed7c8
NC
9361
9362 for (rp = rela; rp < rela + nrelas; ++rp)
9363 {
4770fb94 9364 unsigned int sym_ndx;
726bd37d
AM
9365 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9366 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9367
82b1b41b
NC
9368 /* PR 17531: file: 9fa67536. */
9369 if (relname == NULL)
9370 {
726bd37d 9371 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9372 continue;
9373 }
948f632f 9374
24d127aa 9375 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9376 {
82b1b41b 9377 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9378 continue;
9379 }
9380
89fac5e3 9381 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9382
53774b7e
NC
9383 /* PR 17531: file: 5bc8d9bf. */
9384 if (i >= aux->table_len)
9385 {
26c527e6
AM
9386 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9387 i);
53774b7e
NC
9388 continue;
9389 }
9390
4770fb94
AM
9391 sym_ndx = get_reloc_symindex (rp->r_info);
9392 if (sym_ndx >= aux->nsyms)
9393 {
9394 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9395 sym_ndx);
9396 continue;
9397 }
9398 sym = aux->symtab + sym_ndx;
9399
53774b7e 9400 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9401 {
9402 case 0:
9403 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9404 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9405 break;
9406 case 1:
9407 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9408 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9409 break;
9410 case 2:
9411 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9412 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9413 break;
9414 default:
9415 break;
9416 }
9417 }
9418
9419 free (rela);
9420 }
9421
015dc7e1 9422 return true;
4d6ed7c8
NC
9423}
9424
015dc7e1 9425static bool
dda8d76d 9426ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9427{
2cf0635d
NC
9428 Elf_Internal_Shdr * sec;
9429 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9430 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9431 struct ia64_unw_aux_info aux;
015dc7e1 9432 bool res = true;
f1467e33 9433
4d6ed7c8
NC
9434 memset (& aux, 0, sizeof (aux));
9435
dda8d76d 9436 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9437 {
28d13567 9438 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9439 {
28d13567 9440 if (aux.symtab)
4082ef84 9441 {
28d13567
AM
9442 error (_("Multiple symbol tables encountered\n"));
9443 free (aux.symtab);
9444 aux.symtab = NULL;
4082ef84 9445 free (aux.strtab);
28d13567 9446 aux.strtab = NULL;
4082ef84 9447 }
28d13567
AM
9448 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9449 &aux.strtab, &aux.strtab_size))
015dc7e1 9450 return false;
4d6ed7c8
NC
9451 }
9452 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9453 unwcount++;
9454 }
9455
9456 if (!unwcount)
9457 printf (_("\nThere are no unwind sections in this file.\n"));
9458
9459 while (unwcount-- > 0)
9460 {
84714f86 9461 const char *suffix;
579f31ac
JJ
9462 size_t len, len2;
9463
dda8d76d
NC
9464 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9465 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9466 if (sec->sh_type == SHT_IA_64_UNWIND)
9467 {
9468 unwsec = sec;
9469 break;
9470 }
4082ef84
NC
9471 /* We have already counted the number of SHT_IA64_UNWIND
9472 sections so the loop above should never fail. */
9473 assert (unwsec != NULL);
579f31ac
JJ
9474
9475 unwstart = i + 1;
9476 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9477
e4b17d5c
L
9478 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9479 {
9480 /* We need to find which section group it is in. */
4082ef84 9481 struct group_list * g;
e4b17d5c 9482
978c4450
AM
9483 if (filedata->section_headers_groups == NULL
9484 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9485 i = filedata->file_header.e_shnum;
4082ef84 9486 else
e4b17d5c 9487 {
978c4450 9488 g = filedata->section_headers_groups[i]->root;
18bd398b 9489
4082ef84
NC
9490 for (; g != NULL; g = g->next)
9491 {
dda8d76d 9492 sec = filedata->section_headers + g->section_index;
e4b17d5c 9493
84714f86
AM
9494 if (section_name_valid (filedata, sec)
9495 && streq (section_name (filedata, sec),
9496 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9497 break;
9498 }
9499
9500 if (g == NULL)
dda8d76d 9501 i = filedata->file_header.e_shnum;
4082ef84 9502 }
e4b17d5c 9503 }
84714f86
AM
9504 else if (section_name_valid (filedata, unwsec)
9505 && startswith (section_name (filedata, unwsec),
e9b095a5 9506 ELF_STRING_ia64_unwind_once))
579f31ac 9507 {
18bd398b 9508 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9509 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9510 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9511 for (i = 0, sec = filedata->section_headers;
9512 i < filedata->file_header.e_shnum;
579f31ac 9513 ++i, ++sec)
84714f86
AM
9514 if (section_name_valid (filedata, sec)
9515 && startswith (section_name (filedata, sec),
e9b095a5 9516 ELF_STRING_ia64_unwind_info_once)
84714f86 9517 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9518 break;
9519 }
9520 else
9521 {
9522 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9523 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9524 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9525 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9526 suffix = "";
84714f86
AM
9527 if (section_name_valid (filedata, unwsec)
9528 && startswith (section_name (filedata, unwsec),
9529 ELF_STRING_ia64_unwind))
9530 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9531 for (i = 0, sec = filedata->section_headers;
9532 i < filedata->file_header.e_shnum;
579f31ac 9533 ++i, ++sec)
84714f86
AM
9534 if (section_name_valid (filedata, sec)
9535 && startswith (section_name (filedata, sec),
9536 ELF_STRING_ia64_unwind_info)
9537 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9538 break;
9539 }
9540
dda8d76d 9541 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9542 {
9543 printf (_("\nCould not find unwind info section for "));
9544
dda8d76d 9545 if (filedata->string_table == NULL)
579f31ac
JJ
9546 printf ("%d", unwsec->sh_name);
9547 else
dda8d76d 9548 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9549 }
9550 else
4d6ed7c8 9551 {
4d6ed7c8 9552 aux.info_addr = sec->sh_addr;
dda8d76d 9553 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9554 sec->sh_size,
9555 _("unwind info"));
59245841 9556 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9557
579f31ac 9558 printf (_("\nUnwind section "));
4d6ed7c8 9559
dda8d76d 9560 if (filedata->string_table == NULL)
579f31ac
JJ
9561 printf ("%d", unwsec->sh_name);
9562 else
dda8d76d 9563 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9564
26c527e6
AM
9565 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9566 unwsec->sh_offset,
9567 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9568
dda8d76d 9569 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9570 && aux.table_len > 0)
dda8d76d 9571 dump_ia64_unwind (filedata, & aux);
579f31ac 9572
9db70fc3
AM
9573 free ((char *) aux.table);
9574 free ((char *) aux.info);
579f31ac
JJ
9575 aux.table = NULL;
9576 aux.info = NULL;
9577 }
4d6ed7c8 9578 }
4d6ed7c8 9579
9db70fc3
AM
9580 free (aux.symtab);
9581 free ((char *) aux.strtab);
32ec8896
NC
9582
9583 return res;
4d6ed7c8
NC
9584}
9585
3f5e193b 9586struct hppa_unw_table_entry
32ec8896
NC
9587{
9588 struct absaddr start;
9589 struct absaddr end;
9590 unsigned int Cannot_unwind:1; /* 0 */
9591 unsigned int Millicode:1; /* 1 */
9592 unsigned int Millicode_save_sr0:1; /* 2 */
9593 unsigned int Region_description:2; /* 3..4 */
9594 unsigned int reserved1:1; /* 5 */
9595 unsigned int Entry_SR:1; /* 6 */
9596 unsigned int Entry_FR:4; /* Number saved 7..10 */
9597 unsigned int Entry_GR:5; /* Number saved 11..15 */
9598 unsigned int Args_stored:1; /* 16 */
9599 unsigned int Variable_Frame:1; /* 17 */
9600 unsigned int Separate_Package_Body:1; /* 18 */
9601 unsigned int Frame_Extension_Millicode:1; /* 19 */
9602 unsigned int Stack_Overflow_Check:1; /* 20 */
9603 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9604 unsigned int Ada_Region:1; /* 22 */
9605 unsigned int cxx_info:1; /* 23 */
9606 unsigned int cxx_try_catch:1; /* 24 */
9607 unsigned int sched_entry_seq:1; /* 25 */
9608 unsigned int reserved2:1; /* 26 */
9609 unsigned int Save_SP:1; /* 27 */
9610 unsigned int Save_RP:1; /* 28 */
9611 unsigned int Save_MRP_in_frame:1; /* 29 */
9612 unsigned int extn_ptr_defined:1; /* 30 */
9613 unsigned int Cleanup_defined:1; /* 31 */
9614
9615 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9616 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9617 unsigned int Large_frame:1; /* 2 */
9618 unsigned int Pseudo_SP_Set:1; /* 3 */
9619 unsigned int reserved4:1; /* 4 */
9620 unsigned int Total_frame_size:27; /* 5..31 */
9621};
3f5e193b 9622
57346661 9623struct hppa_unw_aux_info
948f632f 9624{
32ec8896 9625 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9626 uint64_t table_len; /* Length of unwind table. */
625d49fc 9627 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9628 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9629 uint64_t nsyms; /* Number of symbols. */
32ec8896 9630 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9631 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9632 char * strtab; /* The string table. */
26c527e6 9633 uint64_t strtab_size; /* Size of string table. */
948f632f 9634};
57346661 9635
015dc7e1 9636static bool
dda8d76d 9637dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9638{
2cf0635d 9639 struct hppa_unw_table_entry * tp;
26c527e6 9640 uint64_t j, nfuns;
015dc7e1 9641 bool res = true;
948f632f
DA
9642
9643 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9644 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9645 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9646 aux->funtab[nfuns++] = aux->symtab[j];
9647 aux->nfuns = nfuns;
9648 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9649
57346661
AM
9650 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9651 {
625d49fc 9652 uint64_t offset;
2cf0635d 9653 const char * procname;
57346661 9654
dda8d76d 9655 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9656 aux->strtab_size, tp->start, &procname,
9657 &offset);
9658
9659 fputs ("\n<", stdout);
9660
9661 if (procname)
9662 {
9663 fputs (procname, stdout);
9664
9665 if (offset)
26c527e6 9666 printf ("+%" PRIx64, offset);
57346661
AM
9667 }
9668
9669 fputs (">: [", stdout);
9670 print_vma (tp->start.offset, PREFIX_HEX);
9671 fputc ('-', stdout);
9672 print_vma (tp->end.offset, PREFIX_HEX);
9673 printf ("]\n\t");
9674
18bd398b
NC
9675#define PF(_m) if (tp->_m) printf (#_m " ");
9676#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9677 PF(Cannot_unwind);
9678 PF(Millicode);
9679 PF(Millicode_save_sr0);
18bd398b 9680 /* PV(Region_description); */
57346661
AM
9681 PF(Entry_SR);
9682 PV(Entry_FR);
9683 PV(Entry_GR);
9684 PF(Args_stored);
9685 PF(Variable_Frame);
9686 PF(Separate_Package_Body);
9687 PF(Frame_Extension_Millicode);
9688 PF(Stack_Overflow_Check);
9689 PF(Two_Instruction_SP_Increment);
9690 PF(Ada_Region);
9691 PF(cxx_info);
9692 PF(cxx_try_catch);
9693 PF(sched_entry_seq);
9694 PF(Save_SP);
9695 PF(Save_RP);
9696 PF(Save_MRP_in_frame);
9697 PF(extn_ptr_defined);
9698 PF(Cleanup_defined);
9699 PF(MPE_XL_interrupt_marker);
9700 PF(HP_UX_interrupt_marker);
9701 PF(Large_frame);
9702 PF(Pseudo_SP_Set);
9703 PV(Total_frame_size);
9704#undef PF
9705#undef PV
9706 }
9707
18bd398b 9708 printf ("\n");
948f632f
DA
9709
9710 free (aux->funtab);
32ec8896
NC
9711
9712 return res;
57346661
AM
9713}
9714
015dc7e1 9715static bool
dda8d76d
NC
9716slurp_hppa_unwind_table (Filedata * filedata,
9717 struct hppa_unw_aux_info * aux,
9718 Elf_Internal_Shdr * sec)
57346661 9719{
26c527e6 9720 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9721 Elf_Internal_Phdr * seg;
9722 struct hppa_unw_table_entry * tep;
9723 Elf_Internal_Shdr * relsec;
9724 Elf_Internal_Rela * rela;
9725 Elf_Internal_Rela * rp;
9726 unsigned char * table;
9727 unsigned char * tp;
9728 Elf_Internal_Sym * sym;
9729 const char * relname;
57346661 9730
57346661
AM
9731 /* First, find the starting address of the segment that includes
9732 this section. */
dda8d76d 9733 if (filedata->file_header.e_phnum)
57346661 9734 {
dda8d76d 9735 if (! get_program_headers (filedata))
015dc7e1 9736 return false;
57346661 9737
dda8d76d
NC
9738 for (seg = filedata->program_headers;
9739 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9740 ++seg)
9741 {
9742 if (seg->p_type != PT_LOAD)
9743 continue;
9744
9745 if (sec->sh_addr >= seg->p_vaddr
9746 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9747 {
9748 aux->seg_base = seg->p_vaddr;
9749 break;
9750 }
9751 }
9752 }
9753
9754 /* Second, build the unwind table from the contents of the unwind
9755 section. */
9756 size = sec->sh_size;
dda8d76d 9757 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9758 _("unwind table"));
57346661 9759 if (!table)
015dc7e1 9760 return false;
57346661 9761
1c0751b2
DA
9762 unw_ent_size = 16;
9763 nentries = size / unw_ent_size;
9764 size = unw_ent_size * nentries;
57346661 9765
e3fdc001 9766 aux->table_len = nentries;
3f5e193b
NC
9767 tep = aux->table = (struct hppa_unw_table_entry *)
9768 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9769
1c0751b2 9770 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9771 {
9772 unsigned int tmp1, tmp2;
9773
9774 tep->start.section = SHN_UNDEF;
9775 tep->end.section = SHN_UNDEF;
9776
1c0751b2
DA
9777 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9778 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9779 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9780 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9781
9782 tep->start.offset += aux->seg_base;
9783 tep->end.offset += aux->seg_base;
57346661
AM
9784
9785 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9786 tep->Millicode = (tmp1 >> 30) & 0x1;
9787 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9788 tep->Region_description = (tmp1 >> 27) & 0x3;
9789 tep->reserved1 = (tmp1 >> 26) & 0x1;
9790 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9791 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9792 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9793 tep->Args_stored = (tmp1 >> 15) & 0x1;
9794 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9795 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9796 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9797 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9798 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9799 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9800 tep->cxx_info = (tmp1 >> 8) & 0x1;
9801 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9802 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9803 tep->reserved2 = (tmp1 >> 5) & 0x1;
9804 tep->Save_SP = (tmp1 >> 4) & 0x1;
9805 tep->Save_RP = (tmp1 >> 3) & 0x1;
9806 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9807 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9808 tep->Cleanup_defined = tmp1 & 0x1;
9809
9810 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9811 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9812 tep->Large_frame = (tmp2 >> 29) & 0x1;
9813 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9814 tep->reserved4 = (tmp2 >> 27) & 0x1;
9815 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9816 }
9817 free (table);
9818
9819 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9820 for (relsec = filedata->section_headers;
9821 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9822 ++relsec)
9823 {
9824 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9825 || relsec->sh_info >= filedata->file_header.e_shnum
9826 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9827 continue;
9828
dda8d76d 9829 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9830 & rela, & nrelas))
015dc7e1 9831 return false;
57346661
AM
9832
9833 for (rp = rela; rp < rela + nrelas; ++rp)
9834 {
4770fb94 9835 unsigned int sym_ndx;
726bd37d
AM
9836 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9837 relname = elf_hppa_reloc_type (r_type);
57346661 9838
726bd37d
AM
9839 if (relname == NULL)
9840 {
9841 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9842 continue;
9843 }
9844
57346661 9845 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9846 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9847 {
726bd37d 9848 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9849 continue;
9850 }
9851
9852 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9853 if (i >= aux->table_len)
9854 {
26c527e6
AM
9855 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9856 i);
726bd37d
AM
9857 continue;
9858 }
57346661 9859
4770fb94
AM
9860 sym_ndx = get_reloc_symindex (rp->r_info);
9861 if (sym_ndx >= aux->nsyms)
9862 {
9863 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9864 sym_ndx);
9865 continue;
9866 }
9867 sym = aux->symtab + sym_ndx;
9868
43f6cd05 9869 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9870 {
9871 case 0:
9872 aux->table[i].start.section = sym->st_shndx;
1e456d54 9873 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9874 break;
9875 case 1:
9876 aux->table[i].end.section = sym->st_shndx;
1e456d54 9877 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9878 break;
9879 default:
9880 break;
9881 }
9882 }
9883
9884 free (rela);
9885 }
9886
015dc7e1 9887 return true;
57346661
AM
9888}
9889
015dc7e1 9890static bool
dda8d76d 9891hppa_process_unwind (Filedata * filedata)
57346661 9892{
57346661 9893 struct hppa_unw_aux_info aux;
2cf0635d 9894 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9895 Elf_Internal_Shdr * sec;
26c527e6 9896 size_t i;
015dc7e1 9897 bool res = true;
57346661 9898
dda8d76d 9899 if (filedata->string_table == NULL)
015dc7e1 9900 return false;
1b31d05e
NC
9901
9902 memset (& aux, 0, sizeof (aux));
57346661 9903
dda8d76d 9904 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9905 {
28d13567 9906 if (sec->sh_type == SHT_SYMTAB)
57346661 9907 {
28d13567 9908 if (aux.symtab)
4082ef84 9909 {
28d13567
AM
9910 error (_("Multiple symbol tables encountered\n"));
9911 free (aux.symtab);
9912 aux.symtab = NULL;
4082ef84 9913 free (aux.strtab);
28d13567 9914 aux.strtab = NULL;
4082ef84 9915 }
28d13567
AM
9916 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9917 &aux.strtab, &aux.strtab_size))
015dc7e1 9918 return false;
57346661 9919 }
84714f86
AM
9920 else if (section_name_valid (filedata, sec)
9921 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9922 unwsec = sec;
9923 }
9924
9925 if (!unwsec)
9926 printf (_("\nThere are no unwind sections in this file.\n"));
9927
dda8d76d 9928 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9929 {
84714f86
AM
9930 if (section_name_valid (filedata, sec)
9931 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9932 {
26c527e6 9933 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9934
26c527e6
AM
9935 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9936 "contains %" PRIu64 " entry:\n",
9937 "\nUnwind section '%s' at offset %#" PRIx64 " "
9938 "contains %" PRIu64 " entries:\n",
d3a49aa8 9939 num_unwind),
dda8d76d 9940 printable_section_name (filedata, sec),
26c527e6 9941 sec->sh_offset,
d3a49aa8 9942 num_unwind);
57346661 9943
dda8d76d 9944 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9945 res = false;
66b09c7e
S
9946
9947 if (res && aux.table_len > 0)
32ec8896 9948 {
dda8d76d 9949 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9950 res = false;
32ec8896 9951 }
57346661 9952
9db70fc3 9953 free ((char *) aux.table);
57346661
AM
9954 aux.table = NULL;
9955 }
9956 }
9957
9db70fc3
AM
9958 free (aux.symtab);
9959 free ((char *) aux.strtab);
32ec8896
NC
9960
9961 return res;
57346661
AM
9962}
9963
0b6ae522
DJ
9964struct arm_section
9965{
a734115a
NC
9966 unsigned char * data; /* The unwind data. */
9967 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9968 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9969 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9970 unsigned int rel_type; /* REL or RELA ? */
9971 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9972};
9973
9974struct arm_unw_aux_info
9975{
dda8d76d 9976 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9977 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9978 uint64_t nsyms; /* Number of symbols. */
948f632f 9979 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9980 uint64_t nfuns; /* Number of these symbols. */
a734115a 9981 char * strtab; /* The file's string table. */
26c527e6 9982 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9983};
9984
9985static const char *
dda8d76d
NC
9986arm_print_vma_and_name (Filedata * filedata,
9987 struct arm_unw_aux_info * aux,
625d49fc 9988 uint64_t fn,
dda8d76d 9989 struct absaddr addr)
0b6ae522
DJ
9990{
9991 const char *procname;
625d49fc 9992 uint64_t sym_offset;
0b6ae522
DJ
9993
9994 if (addr.section == SHN_UNDEF)
9995 addr.offset = fn;
9996
dda8d76d 9997 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9998 aux->strtab_size, addr, &procname,
9999 &sym_offset);
10000
10001 print_vma (fn, PREFIX_HEX);
10002
10003 if (procname)
10004 {
10005 fputs (" <", stdout);
10006 fputs (procname, stdout);
10007
10008 if (sym_offset)
26c527e6 10009 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10010 fputc ('>', stdout);
10011 }
10012
10013 return procname;
10014}
10015
10016static void
10017arm_free_section (struct arm_section *arm_sec)
10018{
9db70fc3
AM
10019 free (arm_sec->data);
10020 free (arm_sec->rela);
0b6ae522
DJ
10021}
10022
a734115a
NC
10023/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10024 cached section and install SEC instead.
10025 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10026 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10027 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10028 relocation's offset in ADDR.
1b31d05e
NC
10029 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10030 into the string table of the symbol associated with the reloc. If no
10031 reloc was applied store -1 there.
10032 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10033
015dc7e1 10034static bool
dda8d76d
NC
10035get_unwind_section_word (Filedata * filedata,
10036 struct arm_unw_aux_info * aux,
1b31d05e
NC
10037 struct arm_section * arm_sec,
10038 Elf_Internal_Shdr * sec,
625d49fc 10039 uint64_t word_offset,
1b31d05e
NC
10040 unsigned int * wordp,
10041 struct absaddr * addr,
625d49fc 10042 uint64_t * sym_name)
0b6ae522
DJ
10043{
10044 Elf_Internal_Rela *rp;
10045 Elf_Internal_Sym *sym;
10046 const char * relname;
10047 unsigned int word;
015dc7e1 10048 bool wrapped;
0b6ae522 10049
e0a31db1 10050 if (sec == NULL || arm_sec == NULL)
015dc7e1 10051 return false;
e0a31db1 10052
0b6ae522
DJ
10053 addr->section = SHN_UNDEF;
10054 addr->offset = 0;
10055
1b31d05e 10056 if (sym_name != NULL)
625d49fc 10057 *sym_name = (uint64_t) -1;
1b31d05e 10058
a734115a 10059 /* If necessary, update the section cache. */
0b6ae522
DJ
10060 if (sec != arm_sec->sec)
10061 {
10062 Elf_Internal_Shdr *relsec;
10063
10064 arm_free_section (arm_sec);
10065
10066 arm_sec->sec = sec;
dda8d76d 10067 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10068 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10069 arm_sec->rela = NULL;
10070 arm_sec->nrelas = 0;
10071
dda8d76d
NC
10072 for (relsec = filedata->section_headers;
10073 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10074 ++relsec)
10075 {
dda8d76d
NC
10076 if (relsec->sh_info >= filedata->file_header.e_shnum
10077 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10078 /* PR 15745: Check the section type as well. */
10079 || (relsec->sh_type != SHT_REL
10080 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10081 continue;
10082
a734115a 10083 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10084 if (relsec->sh_type == SHT_REL)
10085 {
dda8d76d 10086 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10087 relsec->sh_size,
10088 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10089 return false;
0b6ae522 10090 }
1ae40aa4 10091 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10092 {
dda8d76d 10093 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10094 relsec->sh_size,
10095 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10096 return false;
0b6ae522 10097 }
1ae40aa4 10098 break;
0b6ae522
DJ
10099 }
10100
10101 arm_sec->next_rela = arm_sec->rela;
10102 }
10103
a734115a 10104 /* If there is no unwind data we can do nothing. */
0b6ae522 10105 if (arm_sec->data == NULL)
015dc7e1 10106 return false;
0b6ae522 10107
e0a31db1 10108 /* If the offset is invalid then fail. */
f32ba729
NC
10109 if (/* PR 21343 *//* PR 18879 */
10110 sec->sh_size < 4
625d49fc 10111 || word_offset > sec->sh_size - 4)
015dc7e1 10112 return false;
e0a31db1 10113
a734115a 10114 /* Get the word at the required offset. */
0b6ae522
DJ
10115 word = byte_get (arm_sec->data + word_offset, 4);
10116
0eff7165
NC
10117 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10118 if (arm_sec->rela == NULL)
10119 {
10120 * wordp = word;
015dc7e1 10121 return true;
0eff7165
NC
10122 }
10123
a734115a 10124 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10125 wrapped = false;
0b6ae522
DJ
10126 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10127 {
625d49fc 10128 uint64_t prelval, offset;
0b6ae522
DJ
10129
10130 if (rp->r_offset > word_offset && !wrapped)
10131 {
10132 rp = arm_sec->rela;
015dc7e1 10133 wrapped = true;
0b6ae522
DJ
10134 }
10135 if (rp->r_offset > word_offset)
10136 break;
10137
10138 if (rp->r_offset & 3)
10139 {
26c527e6
AM
10140 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10141 rp->r_offset);
0b6ae522
DJ
10142 continue;
10143 }
10144
10145 if (rp->r_offset < word_offset)
10146 continue;
10147
74e1a04b
NC
10148 /* PR 17531: file: 027-161405-0.004 */
10149 if (aux->symtab == NULL)
10150 continue;
10151
0b6ae522
DJ
10152 if (arm_sec->rel_type == SHT_REL)
10153 {
10154 offset = word & 0x7fffffff;
10155 if (offset & 0x40000000)
625d49fc 10156 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10157 }
a734115a 10158 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10159 offset = rp->r_addend;
a734115a 10160 else
74e1a04b
NC
10161 {
10162 error (_("Unknown section relocation type %d encountered\n"),
10163 arm_sec->rel_type);
10164 break;
10165 }
0b6ae522 10166
071436c6
NC
10167 /* PR 17531 file: 027-1241568-0.004. */
10168 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10169 {
26c527e6
AM
10170 error (_("Bad symbol index in unwind relocation "
10171 "(%" PRIu64 " > %" PRIu64 ")\n"),
10172 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10173 break;
10174 }
10175
10176 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10177 offset += sym->st_value;
10178 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10179
a734115a 10180 /* Check that we are processing the expected reloc type. */
dda8d76d 10181 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10182 {
10183 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10184 if (relname == NULL)
10185 {
10186 warn (_("Skipping unknown ARM relocation type: %d\n"),
10187 (int) ELF32_R_TYPE (rp->r_info));
10188 continue;
10189 }
a734115a
NC
10190
10191 if (streq (relname, "R_ARM_NONE"))
10192 continue;
0b4362b0 10193
a734115a
NC
10194 if (! streq (relname, "R_ARM_PREL31"))
10195 {
071436c6 10196 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10197 continue;
10198 }
10199 }
dda8d76d 10200 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10201 {
10202 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10203 if (relname == NULL)
10204 {
10205 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10206 (int) ELF32_R_TYPE (rp->r_info));
10207 continue;
10208 }
0b4362b0 10209
a734115a
NC
10210 if (streq (relname, "R_C6000_NONE"))
10211 continue;
10212
10213 if (! streq (relname, "R_C6000_PREL31"))
10214 {
071436c6 10215 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10216 continue;
10217 }
10218
10219 prelval >>= 1;
10220 }
10221 else
74e1a04b
NC
10222 {
10223 /* This function currently only supports ARM and TI unwinders. */
10224 warn (_("Only TI and ARM unwinders are currently supported\n"));
10225 break;
10226 }
fa197c1c 10227
625d49fc 10228 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10229 addr->section = sym->st_shndx;
10230 addr->offset = offset;
74e1a04b 10231
1b31d05e
NC
10232 if (sym_name)
10233 * sym_name = sym->st_name;
0b6ae522
DJ
10234 break;
10235 }
10236
10237 *wordp = word;
10238 arm_sec->next_rela = rp;
10239
015dc7e1 10240 return true;
0b6ae522
DJ
10241}
10242
a734115a
NC
10243static const char *tic6x_unwind_regnames[16] =
10244{
0b4362b0
RM
10245 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10246 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10247 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10248};
fa197c1c 10249
0b6ae522 10250static void
fa197c1c 10251decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10252{
fa197c1c
PB
10253 int i;
10254
10255 for (i = 12; mask; mask >>= 1, i--)
10256 {
10257 if (mask & 1)
10258 {
10259 fputs (tic6x_unwind_regnames[i], stdout);
10260 if (mask > 1)
10261 fputs (", ", stdout);
10262 }
10263 }
10264}
0b6ae522
DJ
10265
10266#define ADVANCE \
10267 if (remaining == 0 && more_words) \
10268 { \
10269 data_offset += 4; \
dda8d76d 10270 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10271 data_offset, & word, & addr, NULL)) \
015dc7e1 10272 return false; \
0b6ae522
DJ
10273 remaining = 4; \
10274 more_words--; \
10275 } \
10276
10277#define GET_OP(OP) \
10278 ADVANCE; \
10279 if (remaining) \
10280 { \
10281 remaining--; \
10282 (OP) = word >> 24; \
10283 word <<= 8; \
10284 } \
10285 else \
10286 { \
2b692964 10287 printf (_("[Truncated opcode]\n")); \
015dc7e1 10288 return false; \
0b6ae522 10289 } \
cc5914eb 10290 printf ("0x%02x ", OP)
0b6ae522 10291
015dc7e1 10292static bool
dda8d76d
NC
10293decode_arm_unwind_bytecode (Filedata * filedata,
10294 struct arm_unw_aux_info * aux,
948f632f
DA
10295 unsigned int word,
10296 unsigned int remaining,
10297 unsigned int more_words,
625d49fc 10298 uint64_t data_offset,
948f632f
DA
10299 Elf_Internal_Shdr * data_sec,
10300 struct arm_section * data_arm_sec)
fa197c1c
PB
10301{
10302 struct absaddr addr;
015dc7e1 10303 bool res = true;
0b6ae522
DJ
10304
10305 /* Decode the unwinding instructions. */
10306 while (1)
10307 {
10308 unsigned int op, op2;
10309
10310 ADVANCE;
10311 if (remaining == 0)
10312 break;
10313 remaining--;
10314 op = word >> 24;
10315 word <<= 8;
10316
cc5914eb 10317 printf (" 0x%02x ", op);
0b6ae522
DJ
10318
10319 if ((op & 0xc0) == 0x00)
10320 {
10321 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10322
cc5914eb 10323 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10324 }
10325 else if ((op & 0xc0) == 0x40)
10326 {
10327 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10328
cc5914eb 10329 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10330 }
10331 else if ((op & 0xf0) == 0x80)
10332 {
10333 GET_OP (op2);
10334 if (op == 0x80 && op2 == 0)
10335 printf (_("Refuse to unwind"));
10336 else
10337 {
10338 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10339 bool first = true;
0b6ae522 10340 int i;
2b692964 10341
0b6ae522
DJ
10342 printf ("pop {");
10343 for (i = 0; i < 12; i++)
10344 if (mask & (1 << i))
10345 {
10346 if (first)
015dc7e1 10347 first = false;
0b6ae522
DJ
10348 else
10349 printf (", ");
10350 printf ("r%d", 4 + i);
10351 }
10352 printf ("}");
10353 }
10354 }
10355 else if ((op & 0xf0) == 0x90)
10356 {
10357 if (op == 0x9d || op == 0x9f)
10358 printf (_(" [Reserved]"));
10359 else
cc5914eb 10360 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10361 }
10362 else if ((op & 0xf0) == 0xa0)
10363 {
10364 int end = 4 + (op & 0x07);
015dc7e1 10365 bool first = true;
0b6ae522 10366 int i;
61865e30 10367
0b6ae522
DJ
10368 printf (" pop {");
10369 for (i = 4; i <= end; i++)
10370 {
10371 if (first)
015dc7e1 10372 first = false;
0b6ae522
DJ
10373 else
10374 printf (", ");
10375 printf ("r%d", i);
10376 }
10377 if (op & 0x08)
10378 {
1b31d05e 10379 if (!first)
0b6ae522
DJ
10380 printf (", ");
10381 printf ("r14");
10382 }
10383 printf ("}");
10384 }
10385 else if (op == 0xb0)
10386 printf (_(" finish"));
10387 else if (op == 0xb1)
10388 {
10389 GET_OP (op2);
10390 if (op2 == 0 || (op2 & 0xf0) != 0)
10391 printf (_("[Spare]"));
10392 else
10393 {
10394 unsigned int mask = op2 & 0x0f;
015dc7e1 10395 bool first = true;
0b6ae522 10396 int i;
61865e30 10397
0b6ae522
DJ
10398 printf ("pop {");
10399 for (i = 0; i < 12; i++)
10400 if (mask & (1 << i))
10401 {
10402 if (first)
015dc7e1 10403 first = false;
0b6ae522
DJ
10404 else
10405 printf (", ");
10406 printf ("r%d", i);
10407 }
10408 printf ("}");
10409 }
10410 }
10411 else if (op == 0xb2)
10412 {
b115cf96 10413 unsigned char buf[9];
0b6ae522 10414 unsigned int i, len;
26c527e6 10415 uint64_t offset;
61865e30 10416
b115cf96 10417 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10418 {
10419 GET_OP (buf[i]);
10420 if ((buf[i] & 0x80) == 0)
10421 break;
10422 }
4082ef84 10423 if (i == sizeof (buf))
32ec8896 10424 {
27a45f42 10425 error (_("corrupt change to vsp\n"));
015dc7e1 10426 res = false;
32ec8896 10427 }
4082ef84
NC
10428 else
10429 {
015dc7e1 10430 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10431 assert (len == i + 1);
10432 offset = offset * 4 + 0x204;
26c527e6 10433 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10434 }
0b6ae522 10435 }
61865e30 10436 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10437 {
61865e30
NC
10438 unsigned int first, last;
10439
10440 GET_OP (op2);
10441 first = op2 >> 4;
10442 last = op2 & 0x0f;
10443 if (op == 0xc8)
10444 first = first + 16;
10445 printf ("pop {D%d", first);
10446 if (last)
10447 printf ("-D%d", first + last);
10448 printf ("}");
10449 }
09854a88
TB
10450 else if (op == 0xb4)
10451 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10452 else if (op == 0xb5)
10453 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10454 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10455 {
10456 unsigned int count = op & 0x07;
10457
10458 printf ("pop {D8");
10459 if (count)
10460 printf ("-D%d", 8 + count);
10461 printf ("}");
10462 }
10463 else if (op >= 0xc0 && op <= 0xc5)
10464 {
10465 unsigned int count = op & 0x07;
10466
10467 printf (" pop {wR10");
10468 if (count)
10469 printf ("-wR%d", 10 + count);
10470 printf ("}");
10471 }
10472 else if (op == 0xc6)
10473 {
10474 unsigned int first, last;
10475
10476 GET_OP (op2);
10477 first = op2 >> 4;
10478 last = op2 & 0x0f;
10479 printf ("pop {wR%d", first);
10480 if (last)
10481 printf ("-wR%d", first + last);
10482 printf ("}");
10483 }
10484 else if (op == 0xc7)
10485 {
10486 GET_OP (op2);
10487 if (op2 == 0 || (op2 & 0xf0) != 0)
10488 printf (_("[Spare]"));
0b6ae522
DJ
10489 else
10490 {
61865e30 10491 unsigned int mask = op2 & 0x0f;
015dc7e1 10492 bool first = true;
61865e30
NC
10493 int i;
10494
10495 printf ("pop {");
10496 for (i = 0; i < 4; i++)
10497 if (mask & (1 << i))
10498 {
10499 if (first)
015dc7e1 10500 first = false;
61865e30
NC
10501 else
10502 printf (", ");
10503 printf ("wCGR%d", i);
10504 }
10505 printf ("}");
0b6ae522
DJ
10506 }
10507 }
61865e30 10508 else
32ec8896
NC
10509 {
10510 printf (_(" [unsupported opcode]"));
015dc7e1 10511 res = false;
32ec8896
NC
10512 }
10513
0b6ae522
DJ
10514 printf ("\n");
10515 }
32ec8896
NC
10516
10517 return res;
fa197c1c
PB
10518}
10519
015dc7e1 10520static bool
dda8d76d
NC
10521decode_tic6x_unwind_bytecode (Filedata * filedata,
10522 struct arm_unw_aux_info * aux,
948f632f
DA
10523 unsigned int word,
10524 unsigned int remaining,
10525 unsigned int more_words,
625d49fc 10526 uint64_t data_offset,
948f632f
DA
10527 Elf_Internal_Shdr * data_sec,
10528 struct arm_section * data_arm_sec)
fa197c1c
PB
10529{
10530 struct absaddr addr;
10531
10532 /* Decode the unwinding instructions. */
10533 while (1)
10534 {
10535 unsigned int op, op2;
10536
10537 ADVANCE;
10538 if (remaining == 0)
10539 break;
10540 remaining--;
10541 op = word >> 24;
10542 word <<= 8;
10543
9cf03b7e 10544 printf (" 0x%02x ", op);
fa197c1c
PB
10545
10546 if ((op & 0xc0) == 0x00)
10547 {
10548 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10549 printf (" sp = sp + %d", offset);
fa197c1c
PB
10550 }
10551 else if ((op & 0xc0) == 0x80)
10552 {
10553 GET_OP (op2);
10554 if (op == 0x80 && op2 == 0)
10555 printf (_("Refuse to unwind"));
10556 else
10557 {
10558 unsigned int mask = ((op & 0x1f) << 8) | op2;
10559 if (op & 0x20)
10560 printf ("pop compact {");
10561 else
10562 printf ("pop {");
10563
10564 decode_tic6x_unwind_regmask (mask);
10565 printf("}");
10566 }
10567 }
10568 else if ((op & 0xf0) == 0xc0)
10569 {
10570 unsigned int reg;
10571 unsigned int nregs;
10572 unsigned int i;
10573 const char *name;
a734115a
NC
10574 struct
10575 {
32ec8896
NC
10576 unsigned int offset;
10577 unsigned int reg;
fa197c1c
PB
10578 } regpos[16];
10579
10580 /* Scan entire instruction first so that GET_OP output is not
10581 interleaved with disassembly. */
10582 nregs = 0;
10583 for (i = 0; nregs < (op & 0xf); i++)
10584 {
10585 GET_OP (op2);
10586 reg = op2 >> 4;
10587 if (reg != 0xf)
10588 {
10589 regpos[nregs].offset = i * 2;
10590 regpos[nregs].reg = reg;
10591 nregs++;
10592 }
10593
10594 reg = op2 & 0xf;
10595 if (reg != 0xf)
10596 {
10597 regpos[nregs].offset = i * 2 + 1;
10598 regpos[nregs].reg = reg;
10599 nregs++;
10600 }
10601 }
10602
10603 printf (_("pop frame {"));
18344509 10604 if (nregs == 0)
fa197c1c 10605 {
18344509
NC
10606 printf (_("*corrupt* - no registers specified"));
10607 }
10608 else
10609 {
10610 reg = nregs - 1;
10611 for (i = i * 2; i > 0; i--)
fa197c1c 10612 {
18344509
NC
10613 if (regpos[reg].offset == i - 1)
10614 {
10615 name = tic6x_unwind_regnames[regpos[reg].reg];
10616 if (reg > 0)
10617 reg--;
10618 }
10619 else
10620 name = _("[pad]");
fa197c1c 10621
18344509
NC
10622 fputs (name, stdout);
10623 if (i > 1)
10624 printf (", ");
10625 }
fa197c1c
PB
10626 }
10627
10628 printf ("}");
10629 }
10630 else if (op == 0xd0)
10631 printf (" MOV FP, SP");
10632 else if (op == 0xd1)
10633 printf (" __c6xabi_pop_rts");
10634 else if (op == 0xd2)
10635 {
10636 unsigned char buf[9];
10637 unsigned int i, len;
26c527e6 10638 uint64_t offset;
a734115a 10639
fa197c1c
PB
10640 for (i = 0; i < sizeof (buf); i++)
10641 {
10642 GET_OP (buf[i]);
10643 if ((buf[i] & 0x80) == 0)
10644 break;
10645 }
0eff7165
NC
10646 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10647 if (i == sizeof (buf))
10648 {
0eff7165 10649 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10650 return false;
0eff7165 10651 }
948f632f 10652
015dc7e1 10653 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10654 assert (len == i + 1);
10655 offset = offset * 8 + 0x408;
26c527e6 10656 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10657 }
10658 else if ((op & 0xf0) == 0xe0)
10659 {
10660 if ((op & 0x0f) == 7)
10661 printf (" RETURN");
10662 else
10663 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10664 }
10665 else
10666 {
10667 printf (_(" [unsupported opcode]"));
10668 }
10669 putchar ('\n');
10670 }
32ec8896 10671
015dc7e1 10672 return true;
fa197c1c
PB
10673}
10674
625d49fc
AM
10675static uint64_t
10676arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10677{
625d49fc 10678 uint64_t offset;
fa197c1c
PB
10679
10680 offset = word & 0x7fffffff;
10681 if (offset & 0x40000000)
625d49fc 10682 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10683
dda8d76d 10684 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10685 offset <<= 1;
10686
10687 return offset + where;
10688}
10689
015dc7e1 10690static bool
dda8d76d
NC
10691decode_arm_unwind (Filedata * filedata,
10692 struct arm_unw_aux_info * aux,
1b31d05e
NC
10693 unsigned int word,
10694 unsigned int remaining,
625d49fc 10695 uint64_t data_offset,
1b31d05e
NC
10696 Elf_Internal_Shdr * data_sec,
10697 struct arm_section * data_arm_sec)
fa197c1c
PB
10698{
10699 int per_index;
10700 unsigned int more_words = 0;
37e14bc3 10701 struct absaddr addr;
625d49fc 10702 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10703 bool res = true;
fa197c1c
PB
10704
10705 if (remaining == 0)
10706 {
1b31d05e
NC
10707 /* Fetch the first word.
10708 Note - when decoding an object file the address extracted
10709 here will always be 0. So we also pass in the sym_name
10710 parameter so that we can find the symbol associated with
10711 the personality routine. */
dda8d76d 10712 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10713 & word, & addr, & sym_name))
015dc7e1 10714 return false;
1b31d05e 10715
fa197c1c
PB
10716 remaining = 4;
10717 }
c93dbb25
CZ
10718 else
10719 {
10720 addr.section = SHN_UNDEF;
10721 addr.offset = 0;
10722 }
fa197c1c
PB
10723
10724 if ((word & 0x80000000) == 0)
10725 {
10726 /* Expand prel31 for personality routine. */
625d49fc 10727 uint64_t fn;
fa197c1c
PB
10728 const char *procname;
10729
dda8d76d 10730 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10731 printf (_(" Personality routine: "));
1b31d05e
NC
10732 if (fn == 0
10733 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10734 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10735 {
10736 procname = aux->strtab + sym_name;
10737 print_vma (fn, PREFIX_HEX);
10738 if (procname)
10739 {
10740 fputs (" <", stdout);
10741 fputs (procname, stdout);
10742 fputc ('>', stdout);
10743 }
10744 }
10745 else
dda8d76d 10746 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10747 fputc ('\n', stdout);
10748
10749 /* The GCC personality routines use the standard compact
10750 encoding, starting with one byte giving the number of
10751 words. */
10752 if (procname != NULL
24d127aa
ML
10753 && (startswith (procname, "__gcc_personality_v0")
10754 || startswith (procname, "__gxx_personality_v0")
10755 || startswith (procname, "__gcj_personality_v0")
10756 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10757 {
10758 remaining = 0;
10759 more_words = 1;
10760 ADVANCE;
10761 if (!remaining)
10762 {
10763 printf (_(" [Truncated data]\n"));
015dc7e1 10764 return false;
fa197c1c
PB
10765 }
10766 more_words = word >> 24;
10767 word <<= 8;
10768 remaining--;
10769 per_index = -1;
10770 }
10771 else
015dc7e1 10772 return true;
fa197c1c
PB
10773 }
10774 else
10775 {
1b31d05e 10776 /* ARM EHABI Section 6.3:
0b4362b0 10777
1b31d05e 10778 An exception-handling table entry for the compact model looks like:
0b4362b0 10779
1b31d05e
NC
10780 31 30-28 27-24 23-0
10781 -- ----- ----- ----
10782 1 0 index Data for personalityRoutine[index] */
10783
dda8d76d 10784 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10785 && (word & 0x70000000))
32ec8896
NC
10786 {
10787 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10788 res = false;
32ec8896 10789 }
1b31d05e 10790
fa197c1c 10791 per_index = (word >> 24) & 0x7f;
1b31d05e 10792 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10793 if (per_index == 0)
10794 {
10795 more_words = 0;
10796 word <<= 8;
10797 remaining--;
10798 }
10799 else if (per_index < 3)
10800 {
10801 more_words = (word >> 16) & 0xff;
10802 word <<= 16;
10803 remaining -= 2;
10804 }
10805 }
10806
dda8d76d 10807 switch (filedata->file_header.e_machine)
fa197c1c
PB
10808 {
10809 case EM_ARM:
10810 if (per_index < 3)
10811 {
dda8d76d 10812 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10813 data_offset, data_sec, data_arm_sec))
015dc7e1 10814 res = false;
fa197c1c
PB
10815 }
10816 else
1b31d05e
NC
10817 {
10818 warn (_("Unknown ARM compact model index encountered\n"));
10819 printf (_(" [reserved]\n"));
015dc7e1 10820 res = false;
1b31d05e 10821 }
fa197c1c
PB
10822 break;
10823
10824 case EM_TI_C6000:
10825 if (per_index < 3)
10826 {
dda8d76d 10827 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10828 data_offset, data_sec, data_arm_sec))
015dc7e1 10829 res = false;
fa197c1c
PB
10830 }
10831 else if (per_index < 5)
10832 {
10833 if (((word >> 17) & 0x7f) == 0x7f)
10834 printf (_(" Restore stack from frame pointer\n"));
10835 else
10836 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10837 printf (_(" Registers restored: "));
10838 if (per_index == 4)
10839 printf (" (compact) ");
10840 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10841 putchar ('\n');
10842 printf (_(" Return register: %s\n"),
10843 tic6x_unwind_regnames[word & 0xf]);
10844 }
10845 else
1b31d05e 10846 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10847 break;
10848
10849 default:
74e1a04b 10850 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10851 filedata->file_header.e_machine);
015dc7e1 10852 res = false;
fa197c1c 10853 }
0b6ae522
DJ
10854
10855 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10856
10857 return res;
0b6ae522
DJ
10858}
10859
015dc7e1 10860static bool
dda8d76d
NC
10861dump_arm_unwind (Filedata * filedata,
10862 struct arm_unw_aux_info * aux,
10863 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10864{
10865 struct arm_section exidx_arm_sec, extab_arm_sec;
10866 unsigned int i, exidx_len;
26c527e6 10867 uint64_t j, nfuns;
015dc7e1 10868 bool res = true;
0b6ae522
DJ
10869
10870 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10871 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10872 exidx_len = exidx_sec->sh_size / 8;
10873
948f632f
DA
10874 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10875 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10876 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10877 aux->funtab[nfuns++] = aux->symtab[j];
10878 aux->nfuns = nfuns;
10879 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10880
0b6ae522
DJ
10881 for (i = 0; i < exidx_len; i++)
10882 {
10883 unsigned int exidx_fn, exidx_entry;
10884 struct absaddr fn_addr, entry_addr;
625d49fc 10885 uint64_t fn;
0b6ae522
DJ
10886
10887 fputc ('\n', stdout);
10888
dda8d76d 10889 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10890 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10891 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10892 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10893 {
948f632f 10894 free (aux->funtab);
1b31d05e
NC
10895 arm_free_section (& exidx_arm_sec);
10896 arm_free_section (& extab_arm_sec);
015dc7e1 10897 return false;
0b6ae522
DJ
10898 }
10899
83c257ca
NC
10900 /* ARM EHABI, Section 5:
10901 An index table entry consists of 2 words.
10902 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10903 if (exidx_fn & 0x80000000)
32ec8896
NC
10904 {
10905 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10906 res = false;
32ec8896 10907 }
83c257ca 10908
dda8d76d 10909 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10910
dda8d76d 10911 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10912 fputs (": ", stdout);
10913
10914 if (exidx_entry == 1)
10915 {
10916 print_vma (exidx_entry, PREFIX_HEX);
10917 fputs (" [cantunwind]\n", stdout);
10918 }
10919 else if (exidx_entry & 0x80000000)
10920 {
10921 print_vma (exidx_entry, PREFIX_HEX);
10922 fputc ('\n', stdout);
dda8d76d 10923 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10924 }
10925 else
10926 {
625d49fc 10927 uint64_t table, table_offset = 0;
0b6ae522
DJ
10928 Elf_Internal_Shdr *table_sec;
10929
10930 fputs ("@", stdout);
dda8d76d 10931 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10932 print_vma (table, PREFIX_HEX);
10933 printf ("\n");
10934
10935 /* Locate the matching .ARM.extab. */
10936 if (entry_addr.section != SHN_UNDEF
dda8d76d 10937 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10938 {
dda8d76d 10939 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10940 table_offset = entry_addr.offset;
1a915552 10941 /* PR 18879 */
625d49fc 10942 if (table_offset > table_sec->sh_size)
1a915552 10943 {
26c527e6
AM
10944 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10945 table_offset,
dda8d76d 10946 printable_section_name (filedata, table_sec));
015dc7e1 10947 res = false;
1a915552
NC
10948 continue;
10949 }
0b6ae522
DJ
10950 }
10951 else
10952 {
dda8d76d 10953 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10954 if (table_sec != NULL)
10955 table_offset = table - table_sec->sh_addr;
10956 }
32ec8896 10957
0b6ae522
DJ
10958 if (table_sec == NULL)
10959 {
26c527e6
AM
10960 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10961 table);
015dc7e1 10962 res = false;
0b6ae522
DJ
10963 continue;
10964 }
32ec8896 10965
dda8d76d 10966 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10967 &extab_arm_sec))
015dc7e1 10968 res = false;
0b6ae522
DJ
10969 }
10970 }
10971
10972 printf ("\n");
10973
948f632f 10974 free (aux->funtab);
0b6ae522
DJ
10975 arm_free_section (&exidx_arm_sec);
10976 arm_free_section (&extab_arm_sec);
32ec8896
NC
10977
10978 return res;
0b6ae522
DJ
10979}
10980
fa197c1c 10981/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10982
015dc7e1 10983static bool
dda8d76d 10984arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10985{
10986 struct arm_unw_aux_info aux;
10987 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10988 Elf_Internal_Shdr *sec;
26c527e6 10989 size_t i;
fa197c1c 10990 unsigned int sec_type;
015dc7e1 10991 bool res = true;
0b6ae522 10992
dda8d76d 10993 switch (filedata->file_header.e_machine)
fa197c1c
PB
10994 {
10995 case EM_ARM:
10996 sec_type = SHT_ARM_EXIDX;
10997 break;
10998
10999 case EM_TI_C6000:
11000 sec_type = SHT_C6000_UNWIND;
11001 break;
11002
0b4362b0 11003 default:
74e1a04b 11004 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11005 filedata->file_header.e_machine);
015dc7e1 11006 return false;
fa197c1c
PB
11007 }
11008
dda8d76d 11009 if (filedata->string_table == NULL)
015dc7e1 11010 return false;
1b31d05e
NC
11011
11012 memset (& aux, 0, sizeof (aux));
dda8d76d 11013 aux.filedata = filedata;
0b6ae522 11014
dda8d76d 11015 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11016 {
28d13567 11017 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11018 {
28d13567 11019 if (aux.symtab)
74e1a04b 11020 {
28d13567
AM
11021 error (_("Multiple symbol tables encountered\n"));
11022 free (aux.symtab);
11023 aux.symtab = NULL;
74e1a04b 11024 free (aux.strtab);
28d13567 11025 aux.strtab = NULL;
74e1a04b 11026 }
28d13567
AM
11027 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11028 &aux.strtab, &aux.strtab_size))
015dc7e1 11029 return false;
0b6ae522 11030 }
fa197c1c 11031 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11032 unwsec = sec;
11033 }
11034
1b31d05e 11035 if (unwsec == NULL)
0b6ae522 11036 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11037 else
dda8d76d 11038 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11039 {
11040 if (sec->sh_type == sec_type)
11041 {
26c527e6
AM
11042 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11043 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11044 "contains %" PRIu64 " entry:\n",
11045 "\nUnwind section '%s' at offset %#" PRIx64 " "
11046 "contains %" PRIu64 " entries:\n",
d3a49aa8 11047 num_unwind),
dda8d76d 11048 printable_section_name (filedata, sec),
26c527e6 11049 sec->sh_offset,
d3a49aa8 11050 num_unwind);
0b6ae522 11051
dda8d76d 11052 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11053 res = false;
1b31d05e
NC
11054 }
11055 }
0b6ae522 11056
9db70fc3
AM
11057 free (aux.symtab);
11058 free ((char *) aux.strtab);
32ec8896
NC
11059
11060 return res;
0b6ae522
DJ
11061}
11062
3ecc00ec
NC
11063static bool
11064no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11065{
11066 printf (_("No processor specific unwind information to decode\n"));
11067 return true;
11068}
11069
015dc7e1 11070static bool
dda8d76d 11071process_unwind (Filedata * filedata)
57346661 11072{
2cf0635d
NC
11073 struct unwind_handler
11074 {
32ec8896 11075 unsigned int machtype;
015dc7e1 11076 bool (* handler)(Filedata *);
2cf0635d
NC
11077 } handlers[] =
11078 {
0b6ae522 11079 { EM_ARM, arm_process_unwind },
57346661
AM
11080 { EM_IA_64, ia64_process_unwind },
11081 { EM_PARISC, hppa_process_unwind },
fa197c1c 11082 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11083 { EM_386, no_processor_specific_unwind },
11084 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11085 { 0, NULL }
57346661
AM
11086 };
11087 int i;
11088
11089 if (!do_unwind)
015dc7e1 11090 return true;
57346661
AM
11091
11092 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11093 if (filedata->file_header.e_machine == handlers[i].machtype)
11094 return handlers[i].handler (filedata);
57346661 11095
1b31d05e 11096 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11097 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11098 return true;
57346661
AM
11099}
11100
37c18eed
SD
11101static void
11102dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11103{
11104 switch (entry->d_tag)
11105 {
11106 case DT_AARCH64_BTI_PLT:
1dbade74 11107 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11108 break;
11109 default:
11110 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11111 break;
11112 }
11113 putchar ('\n');
11114}
11115
252b5132 11116static void
978c4450 11117dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11118{
11119 switch (entry->d_tag)
11120 {
11121 case DT_MIPS_FLAGS:
11122 if (entry->d_un.d_val == 0)
4b68bca3 11123 printf (_("NONE"));
252b5132
RH
11124 else
11125 {
11126 static const char * opts[] =
11127 {
11128 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11129 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11130 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11131 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11132 "RLD_ORDER_SAFE"
11133 };
11134 unsigned int cnt;
015dc7e1 11135 bool first = true;
2b692964 11136
60bca95a 11137 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11138 if (entry->d_un.d_val & (1 << cnt))
11139 {
11140 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11141 first = false;
252b5132 11142 }
252b5132
RH
11143 }
11144 break;
103f02d3 11145
252b5132 11146 case DT_MIPS_IVERSION:
84714f86 11147 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11148 printf (_("Interface Version: %s"),
84714f86 11149 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11150 else
f493c217 11151 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11152 entry->d_un.d_ptr);
252b5132 11153 break;
103f02d3 11154
252b5132
RH
11155 case DT_MIPS_TIME_STAMP:
11156 {
d5b07ef4 11157 char timebuf[128];
2cf0635d 11158 struct tm * tmp;
91d6fa6a 11159 time_t atime = entry->d_un.d_val;
82b1b41b 11160
91d6fa6a 11161 tmp = gmtime (&atime);
82b1b41b
NC
11162 /* PR 17531: file: 6accc532. */
11163 if (tmp == NULL)
11164 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11165 else
11166 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11167 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11168 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11169 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11170 }
11171 break;
103f02d3 11172
252b5132
RH
11173 case DT_MIPS_RLD_VERSION:
11174 case DT_MIPS_LOCAL_GOTNO:
11175 case DT_MIPS_CONFLICTNO:
11176 case DT_MIPS_LIBLISTNO:
11177 case DT_MIPS_SYMTABNO:
11178 case DT_MIPS_UNREFEXTNO:
11179 case DT_MIPS_HIPAGENO:
11180 case DT_MIPS_DELTA_CLASS_NO:
11181 case DT_MIPS_DELTA_INSTANCE_NO:
11182 case DT_MIPS_DELTA_RELOC_NO:
11183 case DT_MIPS_DELTA_SYM_NO:
11184 case DT_MIPS_DELTA_CLASSSYM_NO:
11185 case DT_MIPS_COMPACT_SIZE:
c69075ac 11186 print_vma (entry->d_un.d_val, DEC);
252b5132 11187 break;
103f02d3 11188
f16a9783 11189 case DT_MIPS_XHASH:
978c4450
AM
11190 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11191 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11192 /* Falls through. */
11193
103f02d3 11194 default:
4b68bca3 11195 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11196 }
4b68bca3 11197 putchar ('\n');
103f02d3
UD
11198}
11199
103f02d3 11200static void
2cf0635d 11201dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11202{
11203 switch (entry->d_tag)
11204 {
11205 case DT_HP_DLD_FLAGS:
11206 {
11207 static struct
11208 {
26c527e6 11209 unsigned int bit;
2cf0635d 11210 const char * str;
5e220199
NC
11211 }
11212 flags[] =
11213 {
11214 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11215 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11216 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11217 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11218 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11219 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11220 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11221 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11222 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11223 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11224 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11225 { DT_HP_GST, "HP_GST" },
11226 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11227 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11228 { DT_HP_NODELETE, "HP_NODELETE" },
11229 { DT_HP_GROUP, "HP_GROUP" },
11230 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11231 };
015dc7e1 11232 bool first = true;
5e220199 11233 size_t cnt;
625d49fc 11234 uint64_t val = entry->d_un.d_val;
103f02d3 11235
60bca95a 11236 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11237 if (val & flags[cnt].bit)
30800947
NC
11238 {
11239 if (! first)
11240 putchar (' ');
11241 fputs (flags[cnt].str, stdout);
015dc7e1 11242 first = false;
30800947
NC
11243 val ^= flags[cnt].bit;
11244 }
76da6bbe 11245
103f02d3 11246 if (val != 0 || first)
f7a99963
NC
11247 {
11248 if (! first)
11249 putchar (' ');
11250 print_vma (val, HEX);
11251 }
103f02d3
UD
11252 }
11253 break;
76da6bbe 11254
252b5132 11255 default:
f7a99963
NC
11256 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11257 break;
252b5132 11258 }
35b1837e 11259 putchar ('\n');
252b5132
RH
11260}
11261
28f997cf
TG
11262/* VMS vs Unix time offset and factor. */
11263
11264#define VMS_EPOCH_OFFSET 35067168000000000LL
11265#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11266#ifndef INT64_MIN
11267#define INT64_MIN (-9223372036854775807LL - 1)
11268#endif
28f997cf
TG
11269
11270/* Display a VMS time in a human readable format. */
11271
11272static void
0e3c1eeb 11273print_vms_time (int64_t vmstime)
28f997cf 11274{
dccc31de 11275 struct tm *tm = NULL;
28f997cf
TG
11276 time_t unxtime;
11277
dccc31de
AM
11278 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11279 {
11280 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11281 unxtime = vmstime;
11282 if (unxtime == vmstime)
11283 tm = gmtime (&unxtime);
11284 }
11285 if (tm != NULL)
11286 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11287 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11288 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11289}
28f997cf 11290
ecc51f48 11291static void
2cf0635d 11292dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11293{
11294 switch (entry->d_tag)
11295 {
0de14b54 11296 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11297 /* First 3 slots reserved. */
ecc51f48
NC
11298 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11299 printf (" -- ");
11300 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11301 break;
11302
28f997cf 11303 case DT_IA_64_VMS_LINKTIME:
28f997cf 11304 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11305 break;
11306
11307 case DT_IA_64_VMS_LNKFLAGS:
11308 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11309 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11310 printf (" CALL_DEBUG");
11311 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11312 printf (" NOP0BUFS");
11313 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11314 printf (" P0IMAGE");
11315 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11316 printf (" MKTHREADS");
11317 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11318 printf (" UPCALLS");
11319 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11320 printf (" IMGSTA");
11321 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11322 printf (" INITIALIZE");
11323 if (entry->d_un.d_val & VMS_LF_MAIN)
11324 printf (" MAIN");
11325 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11326 printf (" EXE_INIT");
11327 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11328 printf (" TBK_IN_IMG");
11329 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11330 printf (" DBG_IN_IMG");
11331 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11332 printf (" TBK_IN_DSF");
11333 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11334 printf (" DBG_IN_DSF");
11335 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11336 printf (" SIGNATURES");
11337 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11338 printf (" REL_SEG_OFF");
11339 break;
11340
bdf4d63a
JJ
11341 default:
11342 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11343 break;
ecc51f48 11344 }
bdf4d63a 11345 putchar ('\n');
ecc51f48
NC
11346}
11347
015dc7e1 11348static bool
dda8d76d 11349get_32bit_dynamic_section (Filedata * filedata)
252b5132 11350{
2cf0635d
NC
11351 Elf32_External_Dyn * edyn;
11352 Elf32_External_Dyn * ext;
11353 Elf_Internal_Dyn * entry;
103f02d3 11354
978c4450
AM
11355 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11356 filedata->dynamic_addr, 1,
11357 filedata->dynamic_size,
11358 _("dynamic section"));
a6e9f9df 11359 if (!edyn)
015dc7e1 11360 return false;
103f02d3 11361
071436c6
NC
11362 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11363 might not have the luxury of section headers. Look for the DT_NULL
11364 terminator to determine the number of entries. */
978c4450
AM
11365 for (ext = edyn, filedata->dynamic_nent = 0;
11366 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11367 ext++)
11368 {
978c4450 11369 filedata->dynamic_nent++;
ba2685cc
AM
11370 if (BYTE_GET (ext->d_tag) == DT_NULL)
11371 break;
11372 }
252b5132 11373
978c4450
AM
11374 filedata->dynamic_section
11375 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11376 if (filedata->dynamic_section == NULL)
252b5132 11377 {
26c527e6
AM
11378 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11379 filedata->dynamic_nent);
9ea033b2 11380 free (edyn);
015dc7e1 11381 return false;
9ea033b2 11382 }
252b5132 11383
978c4450
AM
11384 for (ext = edyn, entry = filedata->dynamic_section;
11385 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11386 ext++, entry++)
9ea033b2 11387 {
fb514b26
AM
11388 entry->d_tag = BYTE_GET (ext->d_tag);
11389 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11390 }
11391
9ea033b2
NC
11392 free (edyn);
11393
015dc7e1 11394 return true;
9ea033b2
NC
11395}
11396
015dc7e1 11397static bool
dda8d76d 11398get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11399{
2cf0635d
NC
11400 Elf64_External_Dyn * edyn;
11401 Elf64_External_Dyn * ext;
11402 Elf_Internal_Dyn * entry;
103f02d3 11403
071436c6 11404 /* Read in the data. */
978c4450
AM
11405 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11406 filedata->dynamic_addr, 1,
11407 filedata->dynamic_size,
11408 _("dynamic section"));
a6e9f9df 11409 if (!edyn)
015dc7e1 11410 return false;
103f02d3 11411
071436c6
NC
11412 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11413 might not have the luxury of section headers. Look for the DT_NULL
11414 terminator to determine the number of entries. */
978c4450 11415 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11416 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11417 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11418 ext++)
11419 {
978c4450 11420 filedata->dynamic_nent++;
66543521 11421 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11422 break;
11423 }
252b5132 11424
978c4450
AM
11425 filedata->dynamic_section
11426 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11427 if (filedata->dynamic_section == NULL)
252b5132 11428 {
26c527e6
AM
11429 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11430 filedata->dynamic_nent);
252b5132 11431 free (edyn);
015dc7e1 11432 return false;
252b5132
RH
11433 }
11434
071436c6 11435 /* Convert from external to internal formats. */
978c4450
AM
11436 for (ext = edyn, entry = filedata->dynamic_section;
11437 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11438 ext++, entry++)
252b5132 11439 {
66543521
AM
11440 entry->d_tag = BYTE_GET (ext->d_tag);
11441 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11442 }
11443
11444 free (edyn);
11445
015dc7e1 11446 return true;
9ea033b2
NC
11447}
11448
4de91c10
AM
11449static bool
11450get_dynamic_section (Filedata *filedata)
11451{
11452 if (filedata->dynamic_section)
11453 return true;
11454
11455 if (is_32bit_elf)
11456 return get_32bit_dynamic_section (filedata);
11457 else
11458 return get_64bit_dynamic_section (filedata);
11459}
11460
e9e44622 11461static void
625d49fc 11462print_dynamic_flags (uint64_t flags)
d1133906 11463{
015dc7e1 11464 bool first = true;
13ae64f3 11465
d1133906
NC
11466 while (flags)
11467 {
625d49fc 11468 uint64_t flag;
d1133906
NC
11469
11470 flag = flags & - flags;
11471 flags &= ~ flag;
11472
e9e44622 11473 if (first)
015dc7e1 11474 first = false;
e9e44622
JJ
11475 else
11476 putc (' ', stdout);
13ae64f3 11477
d1133906
NC
11478 switch (flag)
11479 {
e9e44622
JJ
11480 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11481 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11482 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11483 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11484 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11485 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11486 }
11487 }
e9e44622 11488 puts ("");
d1133906
NC
11489}
11490
625d49fc 11491static uint64_t *
be7d229a 11492get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11493{
11494 unsigned char * e_data;
625d49fc 11495 uint64_t * i_data;
10ca4b04 11496
be7d229a
AM
11497 /* If size_t is smaller than uint64_t, eg because you are building
11498 on a 32-bit host, then make sure that when number is cast to
11499 size_t no information is lost. */
11500 if ((size_t) number != number
11501 || ent_size * number / ent_size != number)
10ca4b04 11502 {
be7d229a 11503 error (_("Size overflow prevents reading %" PRIu64
b8281767 11504 " elements of size %u\n"),
be7d229a 11505 number, ent_size);
10ca4b04
L
11506 return NULL;
11507 }
11508
11509 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11510 attempting to allocate memory when the read is bound to fail. */
11511 if (ent_size * number > filedata->file_size)
11512 {
b8281767 11513 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11514 number);
10ca4b04
L
11515 return NULL;
11516 }
11517
11518 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11519 if (e_data == NULL)
11520 {
b8281767 11521 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11522 number);
10ca4b04
L
11523 return NULL;
11524 }
11525
11526 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11527 {
b8281767 11528 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11529 number * ent_size);
10ca4b04
L
11530 free (e_data);
11531 return NULL;
11532 }
11533
625d49fc 11534 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11535 if (i_data == NULL)
11536 {
b8281767 11537 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11538 number);
10ca4b04
L
11539 free (e_data);
11540 return NULL;
11541 }
11542
11543 while (number--)
11544 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11545
11546 free (e_data);
11547
11548 return i_data;
11549}
11550
26c527e6 11551static uint64_t
10ca4b04
L
11552get_num_dynamic_syms (Filedata * filedata)
11553{
26c527e6 11554 uint64_t num_of_syms = 0;
10ca4b04
L
11555
11556 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11557 return num_of_syms;
11558
978c4450 11559 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11560 {
11561 unsigned char nb[8];
11562 unsigned char nc[8];
11563 unsigned int hash_ent_size = 4;
11564
11565 if ((filedata->file_header.e_machine == EM_ALPHA
11566 || filedata->file_header.e_machine == EM_S390
11567 || filedata->file_header.e_machine == EM_S390_OLD)
11568 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11569 hash_ent_size = 8;
11570
63cf857e
AM
11571 if (fseek64 (filedata->handle,
11572 (filedata->archive_file_offset
11573 + offset_from_vma (filedata,
11574 filedata->dynamic_info[DT_HASH],
11575 sizeof nb + sizeof nc)),
11576 SEEK_SET))
10ca4b04
L
11577 {
11578 error (_("Unable to seek to start of dynamic information\n"));
11579 goto no_hash;
11580 }
11581
11582 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11583 {
11584 error (_("Failed to read in number of buckets\n"));
11585 goto no_hash;
11586 }
11587
11588 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11589 {
11590 error (_("Failed to read in number of chains\n"));
11591 goto no_hash;
11592 }
11593
978c4450
AM
11594 filedata->nbuckets = byte_get (nb, hash_ent_size);
11595 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11596
2482f306
AM
11597 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11598 {
11599 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11600 hash_ent_size);
11601 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11602 hash_ent_size);
001890e1 11603
2482f306
AM
11604 if (filedata->buckets != NULL && filedata->chains != NULL)
11605 num_of_syms = filedata->nchains;
11606 }
ceb9bf11 11607 no_hash:
10ca4b04
L
11608 if (num_of_syms == 0)
11609 {
9db70fc3
AM
11610 free (filedata->buckets);
11611 filedata->buckets = NULL;
11612 free (filedata->chains);
11613 filedata->chains = NULL;
978c4450 11614 filedata->nbuckets = 0;
10ca4b04
L
11615 }
11616 }
11617
978c4450 11618 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11619 {
11620 unsigned char nb[16];
625d49fc
AM
11621 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11622 uint64_t buckets_vma;
26c527e6 11623 uint64_t hn;
10ca4b04 11624
63cf857e
AM
11625 if (fseek64 (filedata->handle,
11626 (filedata->archive_file_offset
11627 + offset_from_vma (filedata,
11628 filedata->dynamic_info_DT_GNU_HASH,
11629 sizeof nb)),
11630 SEEK_SET))
10ca4b04
L
11631 {
11632 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11633 goto no_gnu_hash;
11634 }
11635
11636 if (fread (nb, 16, 1, filedata->handle) != 1)
11637 {
11638 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11639 goto no_gnu_hash;
11640 }
11641
978c4450
AM
11642 filedata->ngnubuckets = byte_get (nb, 4);
11643 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11644 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11645 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11646 if (is_32bit_elf)
11647 buckets_vma += bitmaskwords * 4;
11648 else
11649 buckets_vma += bitmaskwords * 8;
11650
63cf857e
AM
11651 if (fseek64 (filedata->handle,
11652 (filedata->archive_file_offset
11653 + offset_from_vma (filedata, buckets_vma, 4)),
11654 SEEK_SET))
10ca4b04
L
11655 {
11656 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11657 goto no_gnu_hash;
11658 }
11659
978c4450
AM
11660 filedata->gnubuckets
11661 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11662
978c4450 11663 if (filedata->gnubuckets == NULL)
90837ea7 11664 goto no_gnu_hash;
10ca4b04 11665
978c4450
AM
11666 for (i = 0; i < filedata->ngnubuckets; i++)
11667 if (filedata->gnubuckets[i] != 0)
10ca4b04 11668 {
978c4450 11669 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11670 goto no_gnu_hash;
10ca4b04 11671
978c4450
AM
11672 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11673 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11674 }
11675
11676 if (maxchain == 0xffffffff)
90837ea7 11677 goto no_gnu_hash;
10ca4b04 11678
978c4450 11679 maxchain -= filedata->gnusymidx;
10ca4b04 11680
63cf857e
AM
11681 if (fseek64 (filedata->handle,
11682 (filedata->archive_file_offset
11683 + offset_from_vma (filedata,
11684 buckets_vma + 4 * (filedata->ngnubuckets
11685 + maxchain),
11686 4)),
11687 SEEK_SET))
10ca4b04
L
11688 {
11689 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11690 goto no_gnu_hash;
11691 }
11692
11693 do
11694 {
11695 if (fread (nb, 4, 1, filedata->handle) != 1)
11696 {
11697 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11698 goto no_gnu_hash;
11699 }
11700
11701 if (maxchain + 1 == 0)
90837ea7 11702 goto no_gnu_hash;
10ca4b04
L
11703
11704 ++maxchain;
11705 }
11706 while ((byte_get (nb, 4) & 1) == 0);
11707
63cf857e
AM
11708 if (fseek64 (filedata->handle,
11709 (filedata->archive_file_offset
11710 + offset_from_vma (filedata, (buckets_vma
11711 + 4 * filedata->ngnubuckets),
11712 4)),
11713 SEEK_SET))
10ca4b04
L
11714 {
11715 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11716 goto no_gnu_hash;
11717 }
11718
978c4450
AM
11719 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11720 filedata->ngnuchains = maxchain;
10ca4b04 11721
978c4450 11722 if (filedata->gnuchains == NULL)
90837ea7 11723 goto no_gnu_hash;
10ca4b04 11724
978c4450 11725 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11726 {
63cf857e
AM
11727 if (fseek64 (filedata->handle,
11728 (filedata->archive_file_offset
11729 + offset_from_vma (filedata, (buckets_vma
11730 + 4 * (filedata->ngnubuckets
11731 + maxchain)), 4)),
11732 SEEK_SET))
10ca4b04
L
11733 {
11734 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11735 goto no_gnu_hash;
11736 }
11737
978c4450 11738 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11739 if (filedata->mipsxlat == NULL)
11740 goto no_gnu_hash;
10ca4b04
L
11741 }
11742
978c4450
AM
11743 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11744 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11745 {
625d49fc
AM
11746 uint64_t si = filedata->gnubuckets[hn];
11747 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11748
11749 do
11750 {
978c4450 11751 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11752 {
c31ab5a0
AM
11753 if (off < filedata->ngnuchains
11754 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11755 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11756 }
11757 else
11758 {
11759 if (si >= num_of_syms)
11760 num_of_syms = si + 1;
11761 }
11762 si++;
11763 }
978c4450
AM
11764 while (off < filedata->ngnuchains
11765 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11766 }
11767
90837ea7 11768 if (num_of_syms == 0)
10ca4b04 11769 {
90837ea7 11770 no_gnu_hash:
9db70fc3
AM
11771 free (filedata->mipsxlat);
11772 filedata->mipsxlat = NULL;
11773 free (filedata->gnuchains);
11774 filedata->gnuchains = NULL;
11775 free (filedata->gnubuckets);
11776 filedata->gnubuckets = NULL;
978c4450
AM
11777 filedata->ngnubuckets = 0;
11778 filedata->ngnuchains = 0;
10ca4b04
L
11779 }
11780 }
11781
11782 return num_of_syms;
11783}
11784
b2d38a17
NC
11785/* Parse and display the contents of the dynamic section. */
11786
015dc7e1 11787static bool
dda8d76d 11788process_dynamic_section (Filedata * filedata)
9ea033b2 11789{
2cf0635d 11790 Elf_Internal_Dyn * entry;
9ea033b2 11791
93df3340 11792 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11793 {
11794 if (do_dynamic)
ca0e11aa
NC
11795 {
11796 if (filedata->is_separate)
11797 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11798 filedata->file_name);
11799 else
11800 printf (_("\nThere is no dynamic section in this file.\n"));
11801 }
9ea033b2 11802
015dc7e1 11803 return true;
9ea033b2
NC
11804 }
11805
4de91c10
AM
11806 if (!get_dynamic_section (filedata))
11807 return false;
9ea033b2 11808
252b5132 11809 /* Find the appropriate symbol table. */
978c4450 11810 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11811 {
26c527e6 11812 uint64_t num_of_syms;
2482f306 11813
978c4450
AM
11814 for (entry = filedata->dynamic_section;
11815 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11816 ++entry)
10ca4b04 11817 if (entry->d_tag == DT_SYMTAB)
978c4450 11818 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11819 else if (entry->d_tag == DT_SYMENT)
978c4450 11820 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11821 else if (entry->d_tag == DT_HASH)
978c4450 11822 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11823 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11824 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11825 else if ((filedata->file_header.e_machine == EM_MIPS
11826 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11827 && entry->d_tag == DT_MIPS_XHASH)
11828 {
978c4450
AM
11829 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11830 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11831 }
252b5132 11832
2482f306
AM
11833 num_of_syms = get_num_dynamic_syms (filedata);
11834
11835 if (num_of_syms != 0
11836 && filedata->dynamic_symbols == NULL
11837 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11838 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11839 {
11840 Elf_Internal_Phdr *seg;
625d49fc 11841 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11842
2482f306
AM
11843 if (! get_program_headers (filedata))
11844 {
11845 error (_("Cannot interpret virtual addresses "
11846 "without program headers.\n"));
015dc7e1 11847 return false;
2482f306 11848 }
252b5132 11849
2482f306
AM
11850 for (seg = filedata->program_headers;
11851 seg < filedata->program_headers + filedata->file_header.e_phnum;
11852 ++seg)
11853 {
11854 if (seg->p_type != PT_LOAD)
11855 continue;
252b5132 11856
2482f306
AM
11857 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11858 {
11859 /* See PR 21379 for a reproducer. */
11860 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11861 return false;
2482f306 11862 }
252b5132 11863
2482f306
AM
11864 if (vma >= (seg->p_vaddr & -seg->p_align)
11865 && vma < seg->p_vaddr + seg->p_filesz)
11866 {
11867 /* Since we do not know how big the symbol table is,
11868 we default to reading in up to the end of PT_LOAD
11869 segment and processing that. This is overkill, I
11870 know, but it should work. */
11871 Elf_Internal_Shdr section;
11872 section.sh_offset = (vma - seg->p_vaddr
11873 + seg->p_offset);
11874 section.sh_size = (num_of_syms
11875 * filedata->dynamic_info[DT_SYMENT]);
11876 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11877
11878 if (do_checks
11879 && filedata->dynamic_symtab_section != NULL
11880 && ((filedata->dynamic_symtab_section->sh_offset
11881 != section.sh_offset)
11882 || (filedata->dynamic_symtab_section->sh_size
11883 != section.sh_size)
11884 || (filedata->dynamic_symtab_section->sh_entsize
11885 != section.sh_entsize)))
11886 warn (_("\
11887the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11888
2482f306
AM
11889 section.sh_name = filedata->string_table_length;
11890 filedata->dynamic_symbols
4de91c10 11891 = get_elf_symbols (filedata, &section,
2482f306
AM
11892 &filedata->num_dynamic_syms);
11893 if (filedata->dynamic_symbols == NULL
11894 || filedata->num_dynamic_syms != num_of_syms)
11895 {
11896 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11897 return false;
2482f306
AM
11898 }
11899 break;
11900 }
11901 }
11902 }
11903 }
252b5132
RH
11904
11905 /* Similarly find a string table. */
978c4450
AM
11906 if (filedata->dynamic_strings == NULL)
11907 for (entry = filedata->dynamic_section;
11908 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11909 ++entry)
11910 {
11911 if (entry->d_tag == DT_STRTAB)
978c4450 11912 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11913
10ca4b04 11914 if (entry->d_tag == DT_STRSZ)
978c4450 11915 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11916
978c4450
AM
11917 if (filedata->dynamic_info[DT_STRTAB]
11918 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11919 {
26c527e6 11920 uint64_t offset;
be7d229a 11921 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11922
11923 offset = offset_from_vma (filedata,
978c4450 11924 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11925 str_tab_len);
8ac10c5b
L
11926 if (do_checks
11927 && filedata->dynamic_strtab_section
11928 && ((filedata->dynamic_strtab_section->sh_offset
11929 != (file_ptr) offset)
11930 || (filedata->dynamic_strtab_section->sh_size
11931 != str_tab_len)))
11932 warn (_("\
11933the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11934
978c4450
AM
11935 filedata->dynamic_strings
11936 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11937 _("dynamic string table"));
11938 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11939 {
11940 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11941 break;
11942 }
e3d39609 11943
978c4450 11944 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11945 break;
11946 }
11947 }
252b5132
RH
11948
11949 /* And find the syminfo section if available. */
978c4450 11950 if (filedata->dynamic_syminfo == NULL)
252b5132 11951 {
26c527e6 11952 uint64_t syminsz = 0;
252b5132 11953
978c4450
AM
11954 for (entry = filedata->dynamic_section;
11955 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11956 ++entry)
252b5132
RH
11957 {
11958 if (entry->d_tag == DT_SYMINENT)
11959 {
11960 /* Note: these braces are necessary to avoid a syntax
11961 error from the SunOS4 C compiler. */
049b0c3a
NC
11962 /* PR binutils/17531: A corrupt file can trigger this test.
11963 So do not use an assert, instead generate an error message. */
11964 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11965 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11966 (int) entry->d_un.d_val);
252b5132
RH
11967 }
11968 else if (entry->d_tag == DT_SYMINSZ)
11969 syminsz = entry->d_un.d_val;
11970 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11971 filedata->dynamic_syminfo_offset
11972 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11973 }
11974
978c4450 11975 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11976 {
2cf0635d
NC
11977 Elf_External_Syminfo * extsyminfo;
11978 Elf_External_Syminfo * extsym;
11979 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11980
11981 /* There is a syminfo section. Read the data. */
3f5e193b 11982 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11983 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11984 1, syminsz, _("symbol information"));
a6e9f9df 11985 if (!extsyminfo)
015dc7e1 11986 return false;
252b5132 11987
978c4450 11988 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11989 {
11990 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11991 free (filedata->dynamic_syminfo);
e3d39609 11992 }
978c4450
AM
11993 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11994 if (filedata->dynamic_syminfo == NULL)
252b5132 11995 {
26c527e6
AM
11996 error (_("Out of memory allocating %" PRIu64
11997 " bytes for dynamic symbol info\n"),
11998 syminsz);
015dc7e1 11999 return false;
252b5132
RH
12000 }
12001
2482f306
AM
12002 filedata->dynamic_syminfo_nent
12003 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12004 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12005 syminfo < (filedata->dynamic_syminfo
12006 + filedata->dynamic_syminfo_nent);
86dba8ee 12007 ++syminfo, ++extsym)
252b5132 12008 {
86dba8ee
AM
12009 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12010 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12011 }
12012
12013 free (extsyminfo);
12014 }
12015 }
12016
978c4450 12017 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12018 {
f253158f 12019 if (filedata->is_separate)
26c527e6
AM
12020 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12021 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12022 filedata->dynamic_nent),
f253158f
NC
12023 filedata->file_name,
12024 filedata->dynamic_addr,
26c527e6 12025 filedata->dynamic_nent);
84a9f195 12026 else
02da71ee 12027 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12028 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12029 filedata->dynamic_nent),
84a9f195 12030 filedata->dynamic_addr,
26c527e6 12031 filedata->dynamic_nent);
ca0e11aa 12032 }
252b5132
RH
12033 if (do_dynamic)
12034 printf (_(" Tag Type Name/Value\n"));
12035
978c4450
AM
12036 for (entry = filedata->dynamic_section;
12037 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12038 entry++)
252b5132
RH
12039 {
12040 if (do_dynamic)
f7a99963 12041 {
2cf0635d 12042 const char * dtype;
e699b9ff 12043
f7a99963
NC
12044 putchar (' ');
12045 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12046 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12047 printf (" (%s)%*s", dtype,
32ec8896 12048 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12049 }
252b5132
RH
12050
12051 switch (entry->d_tag)
12052 {
d1133906
NC
12053 case DT_FLAGS:
12054 if (do_dynamic)
e9e44622 12055 print_dynamic_flags (entry->d_un.d_val);
d1133906 12056 break;
76da6bbe 12057
252b5132
RH
12058 case DT_AUXILIARY:
12059 case DT_FILTER:
019148e4
L
12060 case DT_CONFIG:
12061 case DT_DEPAUDIT:
12062 case DT_AUDIT:
252b5132
RH
12063 if (do_dynamic)
12064 {
019148e4 12065 switch (entry->d_tag)
b34976b6 12066 {
019148e4
L
12067 case DT_AUXILIARY:
12068 printf (_("Auxiliary library"));
12069 break;
12070
12071 case DT_FILTER:
12072 printf (_("Filter library"));
12073 break;
12074
b34976b6 12075 case DT_CONFIG:
019148e4
L
12076 printf (_("Configuration file"));
12077 break;
12078
12079 case DT_DEPAUDIT:
12080 printf (_("Dependency audit library"));
12081 break;
12082
12083 case DT_AUDIT:
12084 printf (_("Audit library"));
12085 break;
12086 }
252b5132 12087
84714f86 12088 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12089 printf (": [%s]\n",
84714f86 12090 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12091 else
f7a99963
NC
12092 {
12093 printf (": ");
12094 print_vma (entry->d_un.d_val, PREFIX_HEX);
12095 putchar ('\n');
12096 }
252b5132
RH
12097 }
12098 break;
12099
dcefbbbd 12100 case DT_FEATURE:
252b5132
RH
12101 if (do_dynamic)
12102 {
12103 printf (_("Flags:"));
86f55779 12104
252b5132
RH
12105 if (entry->d_un.d_val == 0)
12106 printf (_(" None\n"));
12107 else
12108 {
26c527e6 12109 uint64_t val = entry->d_un.d_val;
86f55779 12110
252b5132
RH
12111 if (val & DTF_1_PARINIT)
12112 {
12113 printf (" PARINIT");
12114 val ^= DTF_1_PARINIT;
12115 }
dcefbbbd
L
12116 if (val & DTF_1_CONFEXP)
12117 {
12118 printf (" CONFEXP");
12119 val ^= DTF_1_CONFEXP;
12120 }
252b5132 12121 if (val != 0)
26c527e6 12122 printf (" %" PRIx64, val);
252b5132
RH
12123 puts ("");
12124 }
12125 }
12126 break;
12127
12128 case DT_POSFLAG_1:
12129 if (do_dynamic)
12130 {
12131 printf (_("Flags:"));
86f55779 12132
252b5132
RH
12133 if (entry->d_un.d_val == 0)
12134 printf (_(" None\n"));
12135 else
12136 {
26c527e6 12137 uint64_t val = entry->d_un.d_val;
86f55779 12138
252b5132
RH
12139 if (val & DF_P1_LAZYLOAD)
12140 {
12141 printf (" LAZYLOAD");
12142 val ^= DF_P1_LAZYLOAD;
12143 }
12144 if (val & DF_P1_GROUPPERM)
12145 {
12146 printf (" GROUPPERM");
12147 val ^= DF_P1_GROUPPERM;
12148 }
12149 if (val != 0)
26c527e6 12150 printf (" %" PRIx64, val);
252b5132
RH
12151 puts ("");
12152 }
12153 }
12154 break;
12155
12156 case DT_FLAGS_1:
12157 if (do_dynamic)
12158 {
12159 printf (_("Flags:"));
12160 if (entry->d_un.d_val == 0)
12161 printf (_(" None\n"));
12162 else
12163 {
26c527e6 12164 uint64_t val = entry->d_un.d_val;
86f55779 12165
252b5132
RH
12166 if (val & DF_1_NOW)
12167 {
12168 printf (" NOW");
12169 val ^= DF_1_NOW;
12170 }
12171 if (val & DF_1_GLOBAL)
12172 {
12173 printf (" GLOBAL");
12174 val ^= DF_1_GLOBAL;
12175 }
12176 if (val & DF_1_GROUP)
12177 {
12178 printf (" GROUP");
12179 val ^= DF_1_GROUP;
12180 }
12181 if (val & DF_1_NODELETE)
12182 {
12183 printf (" NODELETE");
12184 val ^= DF_1_NODELETE;
12185 }
12186 if (val & DF_1_LOADFLTR)
12187 {
12188 printf (" LOADFLTR");
12189 val ^= DF_1_LOADFLTR;
12190 }
12191 if (val & DF_1_INITFIRST)
12192 {
12193 printf (" INITFIRST");
12194 val ^= DF_1_INITFIRST;
12195 }
12196 if (val & DF_1_NOOPEN)
12197 {
12198 printf (" NOOPEN");
12199 val ^= DF_1_NOOPEN;
12200 }
12201 if (val & DF_1_ORIGIN)
12202 {
12203 printf (" ORIGIN");
12204 val ^= DF_1_ORIGIN;
12205 }
12206 if (val & DF_1_DIRECT)
12207 {
12208 printf (" DIRECT");
12209 val ^= DF_1_DIRECT;
12210 }
12211 if (val & DF_1_TRANS)
12212 {
12213 printf (" TRANS");
12214 val ^= DF_1_TRANS;
12215 }
12216 if (val & DF_1_INTERPOSE)
12217 {
12218 printf (" INTERPOSE");
12219 val ^= DF_1_INTERPOSE;
12220 }
f7db6139 12221 if (val & DF_1_NODEFLIB)
dcefbbbd 12222 {
f7db6139
L
12223 printf (" NODEFLIB");
12224 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12225 }
12226 if (val & DF_1_NODUMP)
12227 {
12228 printf (" NODUMP");
12229 val ^= DF_1_NODUMP;
12230 }
34b60028 12231 if (val & DF_1_CONFALT)
dcefbbbd 12232 {
34b60028
L
12233 printf (" CONFALT");
12234 val ^= DF_1_CONFALT;
12235 }
12236 if (val & DF_1_ENDFILTEE)
12237 {
12238 printf (" ENDFILTEE");
12239 val ^= DF_1_ENDFILTEE;
12240 }
12241 if (val & DF_1_DISPRELDNE)
12242 {
12243 printf (" DISPRELDNE");
12244 val ^= DF_1_DISPRELDNE;
12245 }
12246 if (val & DF_1_DISPRELPND)
12247 {
12248 printf (" DISPRELPND");
12249 val ^= DF_1_DISPRELPND;
12250 }
12251 if (val & DF_1_NODIRECT)
12252 {
12253 printf (" NODIRECT");
12254 val ^= DF_1_NODIRECT;
12255 }
12256 if (val & DF_1_IGNMULDEF)
12257 {
12258 printf (" IGNMULDEF");
12259 val ^= DF_1_IGNMULDEF;
12260 }
12261 if (val & DF_1_NOKSYMS)
12262 {
12263 printf (" NOKSYMS");
12264 val ^= DF_1_NOKSYMS;
12265 }
12266 if (val & DF_1_NOHDR)
12267 {
12268 printf (" NOHDR");
12269 val ^= DF_1_NOHDR;
12270 }
12271 if (val & DF_1_EDITED)
12272 {
12273 printf (" EDITED");
12274 val ^= DF_1_EDITED;
12275 }
12276 if (val & DF_1_NORELOC)
12277 {
12278 printf (" NORELOC");
12279 val ^= DF_1_NORELOC;
12280 }
12281 if (val & DF_1_SYMINTPOSE)
12282 {
12283 printf (" SYMINTPOSE");
12284 val ^= DF_1_SYMINTPOSE;
12285 }
12286 if (val & DF_1_GLOBAUDIT)
12287 {
12288 printf (" GLOBAUDIT");
12289 val ^= DF_1_GLOBAUDIT;
12290 }
12291 if (val & DF_1_SINGLETON)
12292 {
12293 printf (" SINGLETON");
12294 val ^= DF_1_SINGLETON;
dcefbbbd 12295 }
5c383f02
RO
12296 if (val & DF_1_STUB)
12297 {
12298 printf (" STUB");
12299 val ^= DF_1_STUB;
12300 }
12301 if (val & DF_1_PIE)
12302 {
12303 printf (" PIE");
12304 val ^= DF_1_PIE;
12305 }
b1202ffa
L
12306 if (val & DF_1_KMOD)
12307 {
12308 printf (" KMOD");
12309 val ^= DF_1_KMOD;
12310 }
12311 if (val & DF_1_WEAKFILTER)
12312 {
12313 printf (" WEAKFILTER");
12314 val ^= DF_1_WEAKFILTER;
12315 }
12316 if (val & DF_1_NOCOMMON)
12317 {
12318 printf (" NOCOMMON");
12319 val ^= DF_1_NOCOMMON;
12320 }
252b5132 12321 if (val != 0)
26c527e6 12322 printf (" %" PRIx64, val);
252b5132
RH
12323 puts ("");
12324 }
12325 }
12326 break;
12327
12328 case DT_PLTREL:
978c4450 12329 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12330 if (do_dynamic)
dda8d76d 12331 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12332 break;
12333
12334 case DT_NULL :
12335 case DT_NEEDED :
12336 case DT_PLTGOT :
12337 case DT_HASH :
12338 case DT_STRTAB :
12339 case DT_SYMTAB :
12340 case DT_RELA :
12341 case DT_INIT :
12342 case DT_FINI :
12343 case DT_SONAME :
12344 case DT_RPATH :
12345 case DT_SYMBOLIC:
12346 case DT_REL :
a7fd1186 12347 case DT_RELR :
252b5132
RH
12348 case DT_DEBUG :
12349 case DT_TEXTREL :
12350 case DT_JMPREL :
019148e4 12351 case DT_RUNPATH :
978c4450 12352 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12353
12354 if (do_dynamic)
12355 {
84714f86 12356 const char *name;
252b5132 12357
84714f86
AM
12358 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12359 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12360 else
d79b3d50 12361 name = NULL;
252b5132
RH
12362
12363 if (name)
12364 {
12365 switch (entry->d_tag)
12366 {
12367 case DT_NEEDED:
12368 printf (_("Shared library: [%s]"), name);
12369
13acb58d
AM
12370 if (filedata->program_interpreter
12371 && streq (name, filedata->program_interpreter))
f7a99963 12372 printf (_(" program interpreter"));
252b5132
RH
12373 break;
12374
12375 case DT_SONAME:
f7a99963 12376 printf (_("Library soname: [%s]"), name);
252b5132
RH
12377 break;
12378
12379 case DT_RPATH:
f7a99963 12380 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12381 break;
12382
019148e4
L
12383 case DT_RUNPATH:
12384 printf (_("Library runpath: [%s]"), name);
12385 break;
12386
252b5132 12387 default:
f7a99963
NC
12388 print_vma (entry->d_un.d_val, PREFIX_HEX);
12389 break;
252b5132
RH
12390 }
12391 }
12392 else
f7a99963
NC
12393 print_vma (entry->d_un.d_val, PREFIX_HEX);
12394
12395 putchar ('\n');
252b5132
RH
12396 }
12397 break;
12398
12399 case DT_PLTRELSZ:
12400 case DT_RELASZ :
12401 case DT_STRSZ :
12402 case DT_RELSZ :
12403 case DT_RELAENT :
a7fd1186
FS
12404 case DT_RELRENT :
12405 case DT_RELRSZ :
252b5132
RH
12406 case DT_SYMENT :
12407 case DT_RELENT :
978c4450 12408 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12409 /* Fall through. */
252b5132
RH
12410 case DT_PLTPADSZ:
12411 case DT_MOVEENT :
12412 case DT_MOVESZ :
04d8355a 12413 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12414 case DT_INIT_ARRAYSZ:
12415 case DT_FINI_ARRAYSZ:
047b2264
JJ
12416 case DT_GNU_CONFLICTSZ:
12417 case DT_GNU_LIBLISTSZ:
252b5132 12418 if (do_dynamic)
f7a99963
NC
12419 {
12420 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12421 printf (_(" (bytes)\n"));
f7a99963 12422 }
252b5132
RH
12423 break;
12424
12425 case DT_VERDEFNUM:
12426 case DT_VERNEEDNUM:
12427 case DT_RELACOUNT:
12428 case DT_RELCOUNT:
12429 if (do_dynamic)
f7a99963
NC
12430 {
12431 print_vma (entry->d_un.d_val, UNSIGNED);
12432 putchar ('\n');
12433 }
252b5132
RH
12434 break;
12435
12436 case DT_SYMINSZ:
12437 case DT_SYMINENT:
12438 case DT_SYMINFO:
12439 case DT_USED:
12440 case DT_INIT_ARRAY:
12441 case DT_FINI_ARRAY:
12442 if (do_dynamic)
12443 {
d79b3d50 12444 if (entry->d_tag == DT_USED
84714f86 12445 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12446 {
84714f86
AM
12447 const char *name
12448 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12449
b34976b6 12450 if (*name)
252b5132
RH
12451 {
12452 printf (_("Not needed object: [%s]\n"), name);
12453 break;
12454 }
12455 }
103f02d3 12456
f7a99963
NC
12457 print_vma (entry->d_un.d_val, PREFIX_HEX);
12458 putchar ('\n');
252b5132
RH
12459 }
12460 break;
12461
12462 case DT_BIND_NOW:
12463 /* The value of this entry is ignored. */
35b1837e
AM
12464 if (do_dynamic)
12465 putchar ('\n');
252b5132 12466 break;
103f02d3 12467
047b2264
JJ
12468 case DT_GNU_PRELINKED:
12469 if (do_dynamic)
12470 {
2cf0635d 12471 struct tm * tmp;
91d6fa6a 12472 time_t atime = entry->d_un.d_val;
047b2264 12473
91d6fa6a 12474 tmp = gmtime (&atime);
071436c6
NC
12475 /* PR 17533 file: 041-1244816-0.004. */
12476 if (tmp == NULL)
26c527e6
AM
12477 printf (_("<corrupt time val: %" PRIx64),
12478 (uint64_t) atime);
071436c6
NC
12479 else
12480 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12481 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12482 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12483
12484 }
12485 break;
12486
fdc90cb4 12487 case DT_GNU_HASH:
978c4450 12488 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12489 if (do_dynamic)
12490 {
12491 print_vma (entry->d_un.d_val, PREFIX_HEX);
12492 putchar ('\n');
12493 }
12494 break;
12495
a5da3dee
VDM
12496 case DT_GNU_FLAGS_1:
12497 if (do_dynamic)
12498 {
12499 printf (_("Flags:"));
12500 if (entry->d_un.d_val == 0)
12501 printf (_(" None\n"));
12502 else
12503 {
26c527e6 12504 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12505
12506 if (val & DF_GNU_1_UNIQUE)
12507 {
12508 printf (" UNIQUE");
12509 val ^= DF_GNU_1_UNIQUE;
12510 }
12511 if (val != 0)
26c527e6 12512 printf (" %" PRIx64, val);
a5da3dee
VDM
12513 puts ("");
12514 }
12515 }
12516 break;
12517
252b5132
RH
12518 default:
12519 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12520 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12521 = entry->d_un.d_val;
252b5132
RH
12522
12523 if (do_dynamic)
12524 {
dda8d76d 12525 switch (filedata->file_header.e_machine)
252b5132 12526 {
37c18eed
SD
12527 case EM_AARCH64:
12528 dynamic_section_aarch64_val (entry);
12529 break;
252b5132 12530 case EM_MIPS:
4fe85591 12531 case EM_MIPS_RS3_LE:
978c4450 12532 dynamic_section_mips_val (filedata, entry);
252b5132 12533 break;
103f02d3 12534 case EM_PARISC:
b2d38a17 12535 dynamic_section_parisc_val (entry);
103f02d3 12536 break;
ecc51f48 12537 case EM_IA_64:
b2d38a17 12538 dynamic_section_ia64_val (entry);
ecc51f48 12539 break;
252b5132 12540 default:
f7a99963
NC
12541 print_vma (entry->d_un.d_val, PREFIX_HEX);
12542 putchar ('\n');
252b5132
RH
12543 }
12544 }
12545 break;
12546 }
12547 }
12548
015dc7e1 12549 return true;
252b5132
RH
12550}
12551
12552static char *
d3ba0551 12553get_ver_flags (unsigned int flags)
252b5132 12554{
6d4f21f6 12555 static char buff[128];
252b5132
RH
12556
12557 buff[0] = 0;
12558
12559 if (flags == 0)
12560 return _("none");
12561
12562 if (flags & VER_FLG_BASE)
7bb1ad17 12563 strcat (buff, "BASE");
252b5132
RH
12564
12565 if (flags & VER_FLG_WEAK)
12566 {
12567 if (flags & VER_FLG_BASE)
7bb1ad17 12568 strcat (buff, " | ");
252b5132 12569
7bb1ad17 12570 strcat (buff, "WEAK");
252b5132
RH
12571 }
12572
44ec90b9
RO
12573 if (flags & VER_FLG_INFO)
12574 {
12575 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12576 strcat (buff, " | ");
44ec90b9 12577
7bb1ad17 12578 strcat (buff, "INFO");
44ec90b9
RO
12579 }
12580
12581 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12582 {
12583 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12584 strcat (buff, " | ");
12585
12586 strcat (buff, _("<unknown>"));
12587 }
252b5132
RH
12588
12589 return buff;
12590}
12591
12592/* Display the contents of the version sections. */
98fb390a 12593
015dc7e1 12594static bool
dda8d76d 12595process_version_sections (Filedata * filedata)
252b5132 12596{
2cf0635d 12597 Elf_Internal_Shdr * section;
b34976b6 12598 unsigned i;
015dc7e1 12599 bool found = false;
252b5132
RH
12600
12601 if (! do_version)
015dc7e1 12602 return true;
252b5132 12603
dda8d76d
NC
12604 for (i = 0, section = filedata->section_headers;
12605 i < filedata->file_header.e_shnum;
b34976b6 12606 i++, section++)
252b5132
RH
12607 {
12608 switch (section->sh_type)
12609 {
12610 case SHT_GNU_verdef:
12611 {
2cf0635d 12612 Elf_External_Verdef * edefs;
26c527e6
AM
12613 size_t idx;
12614 size_t cnt;
2cf0635d 12615 char * endbuf;
252b5132 12616
015dc7e1 12617 found = true;
252b5132 12618
ca0e11aa
NC
12619 if (filedata->is_separate)
12620 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12621 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12622 section->sh_info),
12623 filedata->file_name,
12624 printable_section_name (filedata, section),
12625 section->sh_info);
12626 else
12627 printf (ngettext ("\nVersion definition section '%s' "
12628 "contains %u entry:\n",
12629 "\nVersion definition section '%s' "
12630 "contains %u entries:\n",
12631 section->sh_info),
12632 printable_section_name (filedata, section),
12633 section->sh_info);
047c3dbf 12634
625d49fc 12635 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12636 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12637 section->sh_offset, section->sh_link,
b6ac461a 12638 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12639
3f5e193b 12640 edefs = (Elf_External_Verdef *)
dda8d76d 12641 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12642 _("version definition section"));
a6e9f9df
AM
12643 if (!edefs)
12644 break;
59245841 12645 endbuf = (char *) edefs + section->sh_size;
252b5132 12646
1445030f 12647 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12648 {
2cf0635d
NC
12649 char * vstart;
12650 Elf_External_Verdef * edef;
b34976b6 12651 Elf_Internal_Verdef ent;
2cf0635d 12652 Elf_External_Verdaux * eaux;
b34976b6 12653 Elf_Internal_Verdaux aux;
26c527e6 12654 size_t isum;
b34976b6 12655 int j;
103f02d3 12656
252b5132 12657 vstart = ((char *) edefs) + idx;
54806181
AM
12658 if (vstart + sizeof (*edef) > endbuf)
12659 break;
252b5132
RH
12660
12661 edef = (Elf_External_Verdef *) vstart;
12662
12663 ent.vd_version = BYTE_GET (edef->vd_version);
12664 ent.vd_flags = BYTE_GET (edef->vd_flags);
12665 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12666 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12667 ent.vd_hash = BYTE_GET (edef->vd_hash);
12668 ent.vd_aux = BYTE_GET (edef->vd_aux);
12669 ent.vd_next = BYTE_GET (edef->vd_next);
12670
26c527e6 12671 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12672 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12673
12674 printf (_(" Index: %d Cnt: %d "),
12675 ent.vd_ndx, ent.vd_cnt);
12676
452bf675 12677 /* Check for overflow. */
1445030f 12678 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12679 break;
12680
252b5132
RH
12681 vstart += ent.vd_aux;
12682
1445030f
AM
12683 if (vstart + sizeof (*eaux) > endbuf)
12684 break;
252b5132
RH
12685 eaux = (Elf_External_Verdaux *) vstart;
12686
12687 aux.vda_name = BYTE_GET (eaux->vda_name);
12688 aux.vda_next = BYTE_GET (eaux->vda_next);
12689
84714f86 12690 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12691 printf (_("Name: %s\n"),
84714f86 12692 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12693 else
12694 printf (_("Name index: %ld\n"), aux.vda_name);
12695
12696 isum = idx + ent.vd_aux;
12697
b34976b6 12698 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12699 {
1445030f
AM
12700 if (aux.vda_next < sizeof (*eaux)
12701 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12702 {
12703 warn (_("Invalid vda_next field of %lx\n"),
12704 aux.vda_next);
12705 j = ent.vd_cnt;
12706 break;
12707 }
dd24e3da 12708 /* Check for overflow. */
7e26601c 12709 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12710 break;
12711
252b5132
RH
12712 isum += aux.vda_next;
12713 vstart += aux.vda_next;
12714
54806181
AM
12715 if (vstart + sizeof (*eaux) > endbuf)
12716 break;
1445030f 12717 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12718
12719 aux.vda_name = BYTE_GET (eaux->vda_name);
12720 aux.vda_next = BYTE_GET (eaux->vda_next);
12721
84714f86 12722 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12723 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12724 isum, j,
84714f86 12725 get_dynamic_name (filedata, aux.vda_name));
252b5132 12726 else
26c527e6 12727 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12728 isum, j, aux.vda_name);
12729 }
dd24e3da 12730
54806181
AM
12731 if (j < ent.vd_cnt)
12732 printf (_(" Version def aux past end of section\n"));
252b5132 12733
c9f02c3e
MR
12734 /* PR 17531:
12735 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12736 if (ent.vd_next < sizeof (*edef)
12737 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12738 {
12739 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12740 cnt = section->sh_info;
12741 break;
12742 }
452bf675 12743 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12744 break;
12745
252b5132
RH
12746 idx += ent.vd_next;
12747 }
dd24e3da 12748
54806181
AM
12749 if (cnt < section->sh_info)
12750 printf (_(" Version definition past end of section\n"));
252b5132
RH
12751
12752 free (edefs);
12753 }
12754 break;
103f02d3 12755
252b5132
RH
12756 case SHT_GNU_verneed:
12757 {
2cf0635d 12758 Elf_External_Verneed * eneed;
26c527e6
AM
12759 size_t idx;
12760 size_t cnt;
2cf0635d 12761 char * endbuf;
252b5132 12762
015dc7e1 12763 found = true;
252b5132 12764
ca0e11aa
NC
12765 if (filedata->is_separate)
12766 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12767 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12768 section->sh_info),
12769 filedata->file_name,
12770 printable_section_name (filedata, section),
12771 section->sh_info);
12772 else
12773 printf (ngettext ("\nVersion needs section '%s' "
12774 "contains %u entry:\n",
12775 "\nVersion needs section '%s' "
12776 "contains %u entries:\n",
12777 section->sh_info),
12778 printable_section_name (filedata, section),
12779 section->sh_info);
047c3dbf 12780
625d49fc 12781 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12782 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12783 section->sh_offset, section->sh_link,
b6ac461a 12784 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12785
dda8d76d 12786 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12787 section->sh_offset, 1,
12788 section->sh_size,
9cf03b7e 12789 _("Version Needs section"));
a6e9f9df
AM
12790 if (!eneed)
12791 break;
59245841 12792 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12793
12794 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12795 {
2cf0635d 12796 Elf_External_Verneed * entry;
b34976b6 12797 Elf_Internal_Verneed ent;
26c527e6 12798 size_t isum;
b34976b6 12799 int j;
2cf0635d 12800 char * vstart;
252b5132
RH
12801
12802 vstart = ((char *) eneed) + idx;
54806181
AM
12803 if (vstart + sizeof (*entry) > endbuf)
12804 break;
252b5132
RH
12805
12806 entry = (Elf_External_Verneed *) vstart;
12807
12808 ent.vn_version = BYTE_GET (entry->vn_version);
12809 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12810 ent.vn_file = BYTE_GET (entry->vn_file);
12811 ent.vn_aux = BYTE_GET (entry->vn_aux);
12812 ent.vn_next = BYTE_GET (entry->vn_next);
12813
26c527e6 12814 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12815
84714f86 12816 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12817 printf (_(" File: %s"),
84714f86 12818 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12819 else
12820 printf (_(" File: %lx"), ent.vn_file);
12821
12822 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12823
dd24e3da 12824 /* Check for overflow. */
7e26601c 12825 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12826 break;
252b5132
RH
12827 vstart += ent.vn_aux;
12828
12829 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12830 {
2cf0635d 12831 Elf_External_Vernaux * eaux;
b34976b6 12832 Elf_Internal_Vernaux aux;
252b5132 12833
54806181
AM
12834 if (vstart + sizeof (*eaux) > endbuf)
12835 break;
252b5132
RH
12836 eaux = (Elf_External_Vernaux *) vstart;
12837
12838 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12839 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12840 aux.vna_other = BYTE_GET (eaux->vna_other);
12841 aux.vna_name = BYTE_GET (eaux->vna_name);
12842 aux.vna_next = BYTE_GET (eaux->vna_next);
12843
84714f86 12844 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12845 printf (_(" %#06zx: Name: %s"),
84714f86 12846 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12847 else
26c527e6 12848 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12849 isum, aux.vna_name);
12850
12851 printf (_(" Flags: %s Version: %d\n"),
12852 get_ver_flags (aux.vna_flags), aux.vna_other);
12853
1445030f
AM
12854 if (aux.vna_next < sizeof (*eaux)
12855 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12856 {
12857 warn (_("Invalid vna_next field of %lx\n"),
12858 aux.vna_next);
12859 j = ent.vn_cnt;
12860 break;
12861 }
1445030f
AM
12862 /* Check for overflow. */
12863 if (aux.vna_next > (size_t) (endbuf - vstart))
12864 break;
252b5132
RH
12865 isum += aux.vna_next;
12866 vstart += aux.vna_next;
12867 }
9cf03b7e 12868
54806181 12869 if (j < ent.vn_cnt)
f9a6a8f0 12870 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12871
1445030f
AM
12872 if (ent.vn_next < sizeof (*entry)
12873 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12874 {
452bf675 12875 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12876 cnt = section->sh_info;
12877 break;
12878 }
1445030f
AM
12879 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12880 break;
252b5132
RH
12881 idx += ent.vn_next;
12882 }
9cf03b7e 12883
54806181 12884 if (cnt < section->sh_info)
9cf03b7e 12885 warn (_("Missing Version Needs information\n"));
103f02d3 12886
252b5132
RH
12887 free (eneed);
12888 }
12889 break;
12890
12891 case SHT_GNU_versym:
12892 {
2cf0635d 12893 Elf_Internal_Shdr * link_section;
26c527e6 12894 uint64_t total;
8b73c356 12895 unsigned int cnt;
2cf0635d
NC
12896 unsigned char * edata;
12897 unsigned short * data;
12898 char * strtab;
12899 Elf_Internal_Sym * symbols;
12900 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12901 uint64_t num_syms;
12902 uint64_t off;
252b5132 12903
dda8d76d 12904 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12905 break;
12906
dda8d76d 12907 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12908 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12909
dda8d76d 12910 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12911 break;
12912
015dc7e1 12913 found = true;
252b5132 12914
4de91c10 12915 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12916 if (symbols == NULL)
12917 break;
252b5132 12918
dda8d76d 12919 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12920
dda8d76d 12921 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12922 string_sec->sh_size,
12923 _("version string table"));
a6e9f9df 12924 if (!strtab)
0429c154
MS
12925 {
12926 free (symbols);
12927 break;
12928 }
252b5132 12929
ca0e11aa 12930 if (filedata->is_separate)
26c527e6
AM
12931 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12932 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12933 total),
12934 filedata->file_name,
12935 printable_section_name (filedata, section),
26c527e6 12936 total);
ca0e11aa
NC
12937 else
12938 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12939 "contains %" PRIu64 " entry:\n",
ca0e11aa 12940 "\nVersion symbols section '%s' "
26c527e6 12941 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12942 total),
12943 printable_section_name (filedata, section),
26c527e6 12944 total);
252b5132 12945
625d49fc 12946 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12947 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12948 section->sh_offset, section->sh_link,
dda8d76d 12949 printable_section_name (filedata, link_section));
252b5132 12950
dda8d76d 12951 off = offset_from_vma (filedata,
978c4450 12952 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12953 total * sizeof (short));
95099889
AM
12954 edata = (unsigned char *) get_data (NULL, filedata, off,
12955 sizeof (short), total,
12956 _("version symbol data"));
a6e9f9df
AM
12957 if (!edata)
12958 {
12959 free (strtab);
0429c154 12960 free (symbols);
a6e9f9df
AM
12961 break;
12962 }
252b5132 12963
3f5e193b 12964 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12965
12966 for (cnt = total; cnt --;)
b34976b6
AM
12967 data[cnt] = byte_get (edata + cnt * sizeof (short),
12968 sizeof (short));
252b5132
RH
12969
12970 free (edata);
12971
12972 for (cnt = 0; cnt < total; cnt += 4)
12973 {
12974 int j, nn;
ab273396
AM
12975 char *name;
12976 char *invalid = _("*invalid*");
252b5132
RH
12977
12978 printf (" %03x:", cnt);
12979
12980 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12981 switch (data[cnt + j])
252b5132
RH
12982 {
12983 case 0:
12984 fputs (_(" 0 (*local*) "), stdout);
12985 break;
12986
12987 case 1:
12988 fputs (_(" 1 (*global*) "), stdout);
12989 break;
12990
12991 default:
c244d050
NC
12992 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12993 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12994
dd24e3da 12995 /* If this index value is greater than the size of the symbols
ba5cdace 12996 array, break to avoid an out-of-bounds read. */
26c527e6 12997 if (cnt + j >= num_syms)
dd24e3da
NC
12998 {
12999 warn (_("invalid index into symbol array\n"));
13000 break;
13001 }
13002
ab273396 13003 name = NULL;
978c4450 13004 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13005 {
b34976b6 13006 Elf_Internal_Verneed ivn;
26c527e6 13007 uint64_t offset;
252b5132 13008
d93f0186 13009 offset = offset_from_vma
978c4450
AM
13010 (filedata,
13011 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13012 sizeof (Elf_External_Verneed));
252b5132 13013
b34976b6 13014 do
252b5132 13015 {
b34976b6
AM
13016 Elf_Internal_Vernaux ivna;
13017 Elf_External_Verneed evn;
13018 Elf_External_Vernaux evna;
26c527e6 13019 uint64_t a_off;
252b5132 13020
dda8d76d 13021 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13022 _("version need")) == NULL)
13023 break;
0b4362b0 13024
252b5132
RH
13025 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13026 ivn.vn_next = BYTE_GET (evn.vn_next);
13027
13028 a_off = offset + ivn.vn_aux;
13029
13030 do
13031 {
dda8d76d 13032 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13033 1, _("version need aux (2)")) == NULL)
13034 {
13035 ivna.vna_next = 0;
13036 ivna.vna_other = 0;
13037 }
13038 else
13039 {
13040 ivna.vna_next = BYTE_GET (evna.vna_next);
13041 ivna.vna_other = BYTE_GET (evna.vna_other);
13042 }
252b5132
RH
13043
13044 a_off += ivna.vna_next;
13045 }
b34976b6 13046 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13047 && ivna.vna_next != 0);
13048
b34976b6 13049 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13050 {
13051 ivna.vna_name = BYTE_GET (evna.vna_name);
13052
54806181 13053 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13054 name = invalid;
54806181
AM
13055 else
13056 name = strtab + ivna.vna_name;
252b5132
RH
13057 break;
13058 }
13059
13060 offset += ivn.vn_next;
13061 }
13062 while (ivn.vn_next);
13063 }
00d93f34 13064
ab273396 13065 if (data[cnt + j] != 0x8001
978c4450 13066 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13067 {
b34976b6
AM
13068 Elf_Internal_Verdef ivd;
13069 Elf_External_Verdef evd;
26c527e6 13070 uint64_t offset;
252b5132 13071
d93f0186 13072 offset = offset_from_vma
978c4450
AM
13073 (filedata,
13074 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13075 sizeof evd);
252b5132
RH
13076
13077 do
13078 {
dda8d76d 13079 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13080 _("version def")) == NULL)
13081 {
13082 ivd.vd_next = 0;
948f632f 13083 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13084 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13085 break;
59245841
NC
13086 }
13087 else
13088 {
13089 ivd.vd_next = BYTE_GET (evd.vd_next);
13090 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13091 }
252b5132
RH
13092
13093 offset += ivd.vd_next;
13094 }
c244d050 13095 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13096 && ivd.vd_next != 0);
13097
c244d050 13098 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13099 {
b34976b6
AM
13100 Elf_External_Verdaux evda;
13101 Elf_Internal_Verdaux ivda;
252b5132
RH
13102
13103 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13104
dda8d76d 13105 if (get_data (&evda, filedata,
59245841
NC
13106 offset - ivd.vd_next + ivd.vd_aux,
13107 sizeof (evda), 1,
13108 _("version def aux")) == NULL)
13109 break;
252b5132
RH
13110
13111 ivda.vda_name = BYTE_GET (evda.vda_name);
13112
54806181 13113 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13114 name = invalid;
13115 else if (name != NULL && name != invalid)
13116 name = _("*both*");
54806181
AM
13117 else
13118 name = strtab + ivda.vda_name;
252b5132
RH
13119 }
13120 }
ab273396
AM
13121 if (name != NULL)
13122 nn += printf ("(%s%-*s",
13123 name,
13124 12 - (int) strlen (name),
13125 ")");
252b5132
RH
13126
13127 if (nn < 18)
13128 printf ("%*c", 18 - nn, ' ');
13129 }
13130
13131 putchar ('\n');
13132 }
13133
13134 free (data);
13135 free (strtab);
13136 free (symbols);
13137 }
13138 break;
103f02d3 13139
252b5132
RH
13140 default:
13141 break;
13142 }
13143 }
13144
13145 if (! found)
ca0e11aa
NC
13146 {
13147 if (filedata->is_separate)
13148 printf (_("\nNo version information found in linked file '%s'.\n"),
13149 filedata->file_name);
13150 else
13151 printf (_("\nNo version information found in this file.\n"));
13152 }
252b5132 13153
015dc7e1 13154 return true;
252b5132
RH
13155}
13156
d1133906 13157static const char *
dda8d76d 13158get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13159{
89246a0e 13160 static char buff[64];
252b5132
RH
13161
13162 switch (binding)
13163 {
b34976b6
AM
13164 case STB_LOCAL: return "LOCAL";
13165 case STB_GLOBAL: return "GLOBAL";
13166 case STB_WEAK: return "WEAK";
252b5132
RH
13167 default:
13168 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13169 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13170 binding);
252b5132 13171 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13172 {
13173 if (binding == STB_GNU_UNIQUE
df3a023b 13174 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13175 return "UNIQUE";
13176 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13177 }
252b5132 13178 else
e9e44622 13179 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13180 return buff;
13181 }
13182}
13183
d1133906 13184static const char *
dda8d76d 13185get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13186{
89246a0e 13187 static char buff[64];
252b5132
RH
13188
13189 switch (type)
13190 {
b34976b6
AM
13191 case STT_NOTYPE: return "NOTYPE";
13192 case STT_OBJECT: return "OBJECT";
13193 case STT_FUNC: return "FUNC";
13194 case STT_SECTION: return "SECTION";
13195 case STT_FILE: return "FILE";
13196 case STT_COMMON: return "COMMON";
13197 case STT_TLS: return "TLS";
15ab5209
DB
13198 case STT_RELC: return "RELC";
13199 case STT_SRELC: return "SRELC";
252b5132
RH
13200 default:
13201 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13202 {
dda8d76d 13203 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13204 return "THUMB_FUNC";
103f02d3 13205
dda8d76d 13206 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13207 return "REGISTER";
13208
dda8d76d 13209 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13210 return "PARISC_MILLI";
13211
e9e44622 13212 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13213 }
252b5132 13214 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13215 {
dda8d76d 13216 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13217 {
13218 if (type == STT_HP_OPAQUE)
13219 return "HP_OPAQUE";
13220 if (type == STT_HP_STUB)
13221 return "HP_STUB";
13222 }
13223
8654c01f
ML
13224 if (type == STT_GNU_IFUNC
13225 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13226 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13227 return "IFUNC";
13228
e9e44622 13229 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13230 }
252b5132 13231 else
e9e44622 13232 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13233 return buff;
13234 }
13235}
13236
d1133906 13237static const char *
d3ba0551 13238get_symbol_visibility (unsigned int visibility)
d1133906
NC
13239{
13240 switch (visibility)
13241 {
b34976b6
AM
13242 case STV_DEFAULT: return "DEFAULT";
13243 case STV_INTERNAL: return "INTERNAL";
13244 case STV_HIDDEN: return "HIDDEN";
d1133906 13245 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13246 default:
27a45f42 13247 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13248 return _("<unknown>");
d1133906
NC
13249 }
13250}
13251
2057d69d
CZ
13252static const char *
13253get_alpha_symbol_other (unsigned int other)
9abca702 13254{
2057d69d
CZ
13255 switch (other)
13256 {
13257 case STO_ALPHA_NOPV: return "NOPV";
13258 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13259 default:
27a45f42 13260 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13261 return _("<unknown>");
9abca702 13262 }
2057d69d
CZ
13263}
13264
fd85a6a1
NC
13265static const char *
13266get_solaris_symbol_visibility (unsigned int visibility)
13267{
13268 switch (visibility)
13269 {
13270 case 4: return "EXPORTED";
13271 case 5: return "SINGLETON";
13272 case 6: return "ELIMINATE";
13273 default: return get_symbol_visibility (visibility);
13274 }
13275}
13276
2301ed1c
SN
13277static const char *
13278get_aarch64_symbol_other (unsigned int other)
13279{
13280 static char buf[32];
13281
13282 if (other & STO_AARCH64_VARIANT_PCS)
13283 {
13284 other &= ~STO_AARCH64_VARIANT_PCS;
13285 if (other == 0)
13286 return "VARIANT_PCS";
13287 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13288 return buf;
13289 }
13290 return NULL;
13291}
13292
5e2b0d47
NC
13293static const char *
13294get_mips_symbol_other (unsigned int other)
13295{
13296 switch (other)
13297 {
32ec8896
NC
13298 case STO_OPTIONAL: return "OPTIONAL";
13299 case STO_MIPS_PLT: return "MIPS PLT";
13300 case STO_MIPS_PIC: return "MIPS PIC";
13301 case STO_MICROMIPS: return "MICROMIPS";
13302 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13303 case STO_MIPS16: return "MIPS16";
13304 default: return NULL;
5e2b0d47
NC
13305 }
13306}
13307
28f997cf 13308static const char *
dda8d76d 13309get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13310{
dda8d76d 13311 if (is_ia64_vms (filedata))
28f997cf
TG
13312 {
13313 static char res[32];
13314
13315 res[0] = 0;
13316
13317 /* Function types is for images and .STB files only. */
dda8d76d 13318 switch (filedata->file_header.e_type)
28f997cf
TG
13319 {
13320 case ET_DYN:
13321 case ET_EXEC:
13322 switch (VMS_ST_FUNC_TYPE (other))
13323 {
13324 case VMS_SFT_CODE_ADDR:
13325 strcat (res, " CA");
13326 break;
13327 case VMS_SFT_SYMV_IDX:
13328 strcat (res, " VEC");
13329 break;
13330 case VMS_SFT_FD:
13331 strcat (res, " FD");
13332 break;
13333 case VMS_SFT_RESERVE:
13334 strcat (res, " RSV");
13335 break;
13336 default:
bee0ee85
NC
13337 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13338 VMS_ST_FUNC_TYPE (other));
13339 strcat (res, " <unknown>");
13340 break;
28f997cf
TG
13341 }
13342 break;
13343 default:
13344 break;
13345 }
13346 switch (VMS_ST_LINKAGE (other))
13347 {
13348 case VMS_STL_IGNORE:
13349 strcat (res, " IGN");
13350 break;
13351 case VMS_STL_RESERVE:
13352 strcat (res, " RSV");
13353 break;
13354 case VMS_STL_STD:
13355 strcat (res, " STD");
13356 break;
13357 case VMS_STL_LNK:
13358 strcat (res, " LNK");
13359 break;
13360 default:
bee0ee85
NC
13361 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13362 VMS_ST_LINKAGE (other));
13363 strcat (res, " <unknown>");
13364 break;
28f997cf
TG
13365 }
13366
13367 if (res[0] != 0)
13368 return res + 1;
13369 else
13370 return res;
13371 }
13372 return NULL;
13373}
13374
6911b7dc
AM
13375static const char *
13376get_ppc64_symbol_other (unsigned int other)
13377{
14732552
AM
13378 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13379 return NULL;
13380
13381 other >>= STO_PPC64_LOCAL_BIT;
13382 if (other <= 6)
6911b7dc 13383 {
89246a0e 13384 static char buf[64];
14732552
AM
13385 if (other >= 2)
13386 other = ppc64_decode_local_entry (other);
13387 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13388 return buf;
13389 }
13390 return NULL;
13391}
13392
8155b853
NC
13393static const char *
13394get_riscv_symbol_other (unsigned int other)
13395{
13396 static char buf[32];
13397 buf[0] = 0;
13398
13399 if (other & STO_RISCV_VARIANT_CC)
13400 {
13401 strcat (buf, _(" VARIANT_CC"));
13402 other &= ~STO_RISCV_VARIANT_CC;
13403 }
13404
13405 if (other != 0)
13406 snprintf (buf, sizeof buf, " %x", other);
13407
13408
13409 if (buf[0] != 0)
13410 return buf + 1;
13411 else
13412 return buf;
13413}
13414
5e2b0d47 13415static const char *
dda8d76d 13416get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13417{
13418 const char * result = NULL;
89246a0e 13419 static char buff [64];
5e2b0d47
NC
13420
13421 if (other == 0)
13422 return "";
13423
dda8d76d 13424 switch (filedata->file_header.e_machine)
5e2b0d47 13425 {
2057d69d
CZ
13426 case EM_ALPHA:
13427 result = get_alpha_symbol_other (other);
13428 break;
2301ed1c
SN
13429 case EM_AARCH64:
13430 result = get_aarch64_symbol_other (other);
13431 break;
5e2b0d47
NC
13432 case EM_MIPS:
13433 result = get_mips_symbol_other (other);
28f997cf
TG
13434 break;
13435 case EM_IA_64:
dda8d76d 13436 result = get_ia64_symbol_other (filedata, other);
28f997cf 13437 break;
6911b7dc
AM
13438 case EM_PPC64:
13439 result = get_ppc64_symbol_other (other);
13440 break;
8155b853
NC
13441 case EM_RISCV:
13442 result = get_riscv_symbol_other (other);
13443 break;
5e2b0d47 13444 default:
fd85a6a1 13445 result = NULL;
5e2b0d47
NC
13446 break;
13447 }
13448
13449 if (result)
13450 return result;
13451
13452 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13453 return buff;
13454}
13455
bb4d2ac2 13456static const char *
26c527e6
AM
13457get_symbol_version_string (Filedata *filedata,
13458 bool is_dynsym,
13459 const char *strtab,
13460 size_t strtab_size,
13461 unsigned int si,
13462 Elf_Internal_Sym *psym,
13463 enum versioned_symbol_info *sym_info,
13464 unsigned short *vna_other)
bb4d2ac2 13465{
ab273396
AM
13466 unsigned char data[2];
13467 unsigned short vers_data;
26c527e6 13468 uint64_t offset;
7a815dd5 13469 unsigned short max_vd_ndx;
bb4d2ac2 13470
ab273396 13471 if (!is_dynsym
978c4450 13472 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13473 return NULL;
bb4d2ac2 13474
978c4450
AM
13475 offset = offset_from_vma (filedata,
13476 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13477 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13478
dda8d76d 13479 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13480 sizeof (data), 1, _("version data")) == NULL)
13481 return NULL;
13482
13483 vers_data = byte_get (data, 2);
bb4d2ac2 13484
1f6f5dba 13485 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13486 return NULL;
bb4d2ac2 13487
0b8b7609 13488 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13489 max_vd_ndx = 0;
13490
ab273396
AM
13491 /* Usually we'd only see verdef for defined symbols, and verneed for
13492 undefined symbols. However, symbols defined by the linker in
13493 .dynbss for variables copied from a shared library in order to
13494 avoid text relocations are defined yet have verneed. We could
13495 use a heuristic to detect the special case, for example, check
13496 for verneed first on symbols defined in SHT_NOBITS sections, but
13497 it is simpler and more reliable to just look for both verdef and
13498 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13499
ab273396
AM
13500 if (psym->st_shndx != SHN_UNDEF
13501 && vers_data != 0x8001
978c4450 13502 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13503 {
13504 Elf_Internal_Verdef ivd;
13505 Elf_Internal_Verdaux ivda;
13506 Elf_External_Verdaux evda;
26c527e6 13507 uint64_t off;
bb4d2ac2 13508
dda8d76d 13509 off = offset_from_vma (filedata,
978c4450 13510 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13511 sizeof (Elf_External_Verdef));
13512
13513 do
bb4d2ac2 13514 {
ab273396
AM
13515 Elf_External_Verdef evd;
13516
dda8d76d 13517 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13518 _("version def")) == NULL)
13519 {
13520 ivd.vd_ndx = 0;
13521 ivd.vd_aux = 0;
13522 ivd.vd_next = 0;
1f6f5dba 13523 ivd.vd_flags = 0;
ab273396
AM
13524 }
13525 else
bb4d2ac2 13526 {
ab273396
AM
13527 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13528 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13529 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13530 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13531 }
bb4d2ac2 13532
7a815dd5
L
13533 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13534 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13535
ab273396
AM
13536 off += ivd.vd_next;
13537 }
13538 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13539
ab273396
AM
13540 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13541 {
9abca702 13542 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13543 return NULL;
13544
ab273396
AM
13545 off -= ivd.vd_next;
13546 off += ivd.vd_aux;
bb4d2ac2 13547
dda8d76d 13548 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13549 _("version def aux")) != NULL)
13550 {
13551 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13552
ab273396 13553 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13554 return (ivda.vda_name < strtab_size
13555 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13556 }
13557 }
13558 }
bb4d2ac2 13559
978c4450 13560 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13561 {
13562 Elf_External_Verneed evn;
13563 Elf_Internal_Verneed ivn;
13564 Elf_Internal_Vernaux ivna;
bb4d2ac2 13565
dda8d76d 13566 offset = offset_from_vma (filedata,
978c4450 13567 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13568 sizeof evn);
13569 do
13570 {
26c527e6 13571 uint64_t vna_off;
bb4d2ac2 13572
dda8d76d 13573 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13574 _("version need")) == NULL)
13575 {
13576 ivna.vna_next = 0;
13577 ivna.vna_other = 0;
13578 ivna.vna_name = 0;
13579 break;
13580 }
bb4d2ac2 13581
ab273396
AM
13582 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13583 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13584
ab273396 13585 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13586
ab273396
AM
13587 do
13588 {
13589 Elf_External_Vernaux evna;
bb4d2ac2 13590
dda8d76d 13591 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13592 _("version need aux (3)")) == NULL)
bb4d2ac2 13593 {
ab273396
AM
13594 ivna.vna_next = 0;
13595 ivna.vna_other = 0;
13596 ivna.vna_name = 0;
bb4d2ac2 13597 }
bb4d2ac2 13598 else
bb4d2ac2 13599 {
ab273396
AM
13600 ivna.vna_other = BYTE_GET (evna.vna_other);
13601 ivna.vna_next = BYTE_GET (evna.vna_next);
13602 ivna.vna_name = BYTE_GET (evna.vna_name);
13603 }
bb4d2ac2 13604
ab273396
AM
13605 vna_off += ivna.vna_next;
13606 }
13607 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13608
ab273396
AM
13609 if (ivna.vna_other == vers_data)
13610 break;
bb4d2ac2 13611
ab273396
AM
13612 offset += ivn.vn_next;
13613 }
13614 while (ivn.vn_next != 0);
bb4d2ac2 13615
ab273396
AM
13616 if (ivna.vna_other == vers_data)
13617 {
13618 *sym_info = symbol_undefined;
13619 *vna_other = ivna.vna_other;
13620 return (ivna.vna_name < strtab_size
13621 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13622 }
7a815dd5
L
13623 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13624 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13625 return _("<corrupt>");
bb4d2ac2 13626 }
ab273396 13627 return NULL;
bb4d2ac2
L
13628}
13629
047c3dbf
NL
13630/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13631
13632static unsigned int
b6ac461a 13633print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13634{
13635 switch (base)
13636 {
13637 case 8:
13638 return print_vma (vma, OCTAL_5);
13639
13640 case 10:
13641 return print_vma (vma, UNSIGNED_5);
13642
13643 case 16:
13644 return print_vma (vma, PREFIX_HEX_5);
13645
13646 case 0:
13647 default:
13648 return print_vma (vma, DEC_5);
13649 }
13650}
13651
b6ac461a
NC
13652/* Print information on a single symbol. */
13653
10ca4b04 13654static void
b6ac461a
NC
13655print_symbol (Filedata * filedata,
13656 uint64_t symbol_index,
13657 Elf_Internal_Sym * symtab,
13658 Elf_Internal_Shdr * section,
13659 char * strtab,
13660 size_t strtab_size)
252b5132 13661{
10ca4b04
L
13662 const char *version_string;
13663 enum versioned_symbol_info sym_info;
13664 unsigned short vna_other;
23356397 13665 const char * sstr;
b6ac461a 13666 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13667
b6ac461a
NC
13668 /* FIXME: We should have a table of field widths,
13669 rather than using hard coded constants. */
13670 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13671 print_vma (psym->st_value, LONG_HEX);
13672 putchar (' ');
b6ac461a 13673 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13674 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13675 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13676 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13677 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13678 else
252b5132 13679 {
10ca4b04 13680 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13681
10ca4b04 13682 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13683
10ca4b04 13684 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13685 FIXME: Displaying this information here disrupts the layout
13686 of the table being generated. */
10ca4b04
L
13687 if (psym->st_other ^ vis)
13688 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13689 }
0942c7ab 13690
b6ac461a
NC
13691 bool is_special;
13692
13693 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13694
13695 /* Print the symbol's section index. If the index is special
13696 then print the index's name rather than its number. */
13697 if (is_special)
13698 {
13699 int printed;
13700
13701 /* Special case: If there are no section headers, and the printable
13702 name is "<section 0x...." then just display the section number
13703 as a decimal. This happens when objcopy --strip -section-headers
13704 is used. */
13705 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13706 printed = printf (" %4d ", psym->st_shndx);
13707 else
13708 printed = printf (" %4s ", sstr);
13709
13710 if (extra_sym_info && printed < 16)
13711 printf ("%*s", 16 - printed, "");
13712 }
13713 else
13714 {
13715 printf (" %4u ", psym->st_shndx);
13716
13717 if (extra_sym_info)
13718 {
13719 /* Display the section name referenced by the section index. */
13720 int printed = printf ("(%s) ", sstr);
13721 if (printed < 10)
13722 printf ("%*s", 10 - printed, "");
13723 }
13724 }
13725
13726 /* Get the symbol's name. For section symbols without a
13727 specific name use the (already computed) section name. */
23356397 13728 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 13729 && section_index_real (filedata, psym->st_shndx)
23356397
NC
13730 && psym->st_name == 0)
13731 {
b6ac461a 13732 ;
23356397
NC
13733 }
13734 else
13735 {
b6ac461a
NC
13736 bool is_valid;
13737
84714f86 13738 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13739 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13740 }
10ca4b04
L
13741
13742 version_string
13743 = get_symbol_version_string (filedata,
13744 (section == NULL
13745 || section->sh_type == SHT_DYNSYM),
b6ac461a 13746 strtab, strtab_size, symbol_index,
10ca4b04 13747 psym, &sym_info, &vna_other);
b9e920ec 13748
0942c7ab
NC
13749 int len_avail = 21;
13750 if (! do_wide && version_string != NULL)
13751 {
ddb43bab 13752 char buffer[16];
0942c7ab 13753
ddb43bab 13754 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13755
13756 if (sym_info == symbol_undefined)
13757 len_avail -= sprintf (buffer," (%d)", vna_other);
13758 else if (sym_info != symbol_hidden)
13759 len_avail -= 1;
13760 }
13761
b6ac461a 13762 print_symbol_name (len_avail, sstr);
b9e920ec 13763
10ca4b04
L
13764 if (version_string)
13765 {
13766 if (sym_info == symbol_undefined)
13767 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13768 else
10ca4b04
L
13769 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13770 version_string);
13771 }
6bd1a22c 13772
10ca4b04 13773 putchar ('\n');
6bd1a22c 13774
10ca4b04
L
13775 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13776 && section != NULL
b6ac461a 13777 && symbol_index >= section->sh_info
10ca4b04
L
13778 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13779 && filedata->file_header.e_machine != EM_MIPS
13780 /* Solaris binaries have been found to violate this requirement as
13781 well. Not sure if this is a bug or an ABI requirement. */
13782 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13783 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 13784 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 13785}
f16a9783 13786
0f03783c
NC
13787static const char *
13788get_lto_kind (unsigned int kind)
13789{
13790 switch (kind)
13791 {
13792 case 0: return "DEF";
13793 case 1: return "WEAKDEF";
13794 case 2: return "UNDEF";
13795 case 3: return "WEAKUNDEF";
13796 case 4: return "COMMON";
13797 default:
13798 break;
13799 }
13800
13801 static char buffer[30];
13802 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13803 sprintf (buffer, "<unknown: %u>", kind);
13804 return buffer;
13805}
13806
13807static const char *
13808get_lto_visibility (unsigned int visibility)
13809{
13810 switch (visibility)
13811 {
13812 case 0: return "DEFAULT";
13813 case 1: return "PROTECTED";
13814 case 2: return "INTERNAL";
13815 case 3: return "HIDDEN";
13816 default:
13817 break;
13818 }
13819
13820 static char buffer[30];
13821 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13822 sprintf (buffer, "<unknown: %u>", visibility);
13823 return buffer;
13824}
13825
13826static const char *
13827get_lto_sym_type (unsigned int sym_type)
13828{
13829 switch (sym_type)
13830 {
13831 case 0: return "UNKNOWN";
13832 case 1: return "FUNCTION";
13833 case 2: return "VARIABLE";
13834 default:
13835 break;
13836 }
13837
13838 static char buffer[30];
13839 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13840 sprintf (buffer, "<unknown: %u>", sym_type);
13841 return buffer;
13842}
13843
13844/* Display an LTO format symbol table.
13845 FIXME: The format of LTO symbol tables is not formalized.
13846 So this code could need changing in the future. */
13847
015dc7e1 13848static bool
0f03783c
NC
13849display_lto_symtab (Filedata * filedata,
13850 Elf_Internal_Shdr * section)
13851{
13852 if (section->sh_size == 0)
13853 {
ca0e11aa
NC
13854 if (filedata->is_separate)
13855 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13856 printable_section_name (filedata, section),
13857 filedata->file_name);
13858 else
13859 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13860 printable_section_name (filedata, section));
047c3dbf 13861
015dc7e1 13862 return true;
0f03783c
NC
13863 }
13864
13865 if (section->sh_size > filedata->file_size)
13866 {
26c527e6 13867 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13868 printable_section_name (filedata, section),
26c527e6 13869 section->sh_size);
015dc7e1 13870 return false;
0f03783c
NC
13871 }
13872
13873 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13874 section->sh_size, 1, _("LTO symbols"));
13875 if (alloced_data == NULL)
015dc7e1 13876 return false;
0f03783c
NC
13877
13878 /* Look for extended data for the symbol table. */
765a0c0a 13879 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
13880 void * ext_data_orig = NULL;
13881 char * ext_data = NULL;
13882 char * ext_data_end = NULL;
13883 char * ext_name = NULL;
13884
13885 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13886 (section_name (filedata, section)
13887 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13888 && ext_name != NULL /* Paranoia. */
13889 && (ext = find_section (filedata, ext_name)) != NULL)
13890 {
13891 if (ext->sh_size < 3)
13892 error (_("LTO Symbol extension table '%s' is empty!\n"),
13893 printable_section_name (filedata, ext));
13894 else
13895 {
13896 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13897 ext->sh_size, 1,
13898 _("LTO ext symbol data"));
13899 if (ext_data != NULL)
13900 {
13901 ext_data_end = ext_data + ext->sh_size;
13902 if (* ext_data++ != 1)
13903 error (_("Unexpected version number in symbol extension table\n"));
13904 }
13905 }
13906 }
b9e920ec 13907
0f03783c
NC
13908 const unsigned char * data = (const unsigned char *) alloced_data;
13909 const unsigned char * end = data + section->sh_size;
13910
ca0e11aa
NC
13911 if (filedata->is_separate)
13912 printf (_("\nIn linked file '%s': "), filedata->file_name);
13913 else
13914 printf ("\n");
13915
0f03783c
NC
13916 if (ext_data_orig != NULL)
13917 {
13918 if (do_wide)
ca0e11aa 13919 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13920 printable_section_name (filedata, section),
13921 printable_section_name (filedata, ext));
13922 else
13923 {
ca0e11aa 13924 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13925 printable_section_name (filedata, section));
13926 printf (_(" and extension table '%s' contain:\n"),
13927 printable_section_name (filedata, ext));
13928 }
13929 }
13930 else
ca0e11aa 13931 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13932 printable_section_name (filedata, section));
b9e920ec 13933
0f03783c 13934 /* FIXME: Add a wide version. */
b9e920ec 13935 if (ext_data_orig != NULL)
0f03783c
NC
13936 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13937 else
13938 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13939
13940 /* FIXME: We do not handle style prefixes. */
13941
13942 while (data < end)
13943 {
13944 const unsigned char * sym_name = data;
13945 data += strnlen ((const char *) sym_name, end - data) + 1;
13946 if (data >= end)
13947 goto fail;
13948
13949 const unsigned char * comdat_key = data;
13950 data += strnlen ((const char *) comdat_key, end - data) + 1;
13951 if (data >= end)
13952 goto fail;
13953
13954 if (data + 2 + 8 + 4 > end)
13955 goto fail;
13956
13957 unsigned int kind = *data++;
13958 unsigned int visibility = *data++;
13959
928c411d 13960 uint64_t size = byte_get (data, 8);
0f03783c
NC
13961 data += 8;
13962
928c411d 13963 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13964 data += 4;
13965
13966 if (ext_data != NULL)
13967 {
13968 if (ext_data < (ext_data_end - 1))
13969 {
13970 unsigned int sym_type = * ext_data ++;
13971 unsigned int sec_kind = * ext_data ++;
13972
31e5a3a3 13973 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13974 * comdat_key == 0 ? "-" : (char *) comdat_key,
13975 get_lto_kind (kind),
13976 get_lto_visibility (visibility),
31e5a3a3
AM
13977 size,
13978 slot,
0f03783c 13979 get_lto_sym_type (sym_type),
31e5a3a3 13980 sec_kind);
b6ac461a 13981 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
13982 }
13983 else
13984 {
13985 error (_("Ran out of LTO symbol extension data\n"));
13986 ext_data = NULL;
13987 /* FIXME: return FAIL result ? */
13988 }
13989 }
13990 else
13991 {
31e5a3a3 13992 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13993 * comdat_key == 0 ? "-" : (char *) comdat_key,
13994 get_lto_kind (kind),
13995 get_lto_visibility (visibility),
31e5a3a3
AM
13996 size,
13997 slot);
b6ac461a 13998 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
13999 }
14000 putchar ('\n');
14001 }
14002
14003 if (ext_data != NULL && ext_data < ext_data_end)
14004 {
14005 error (_("Data remains in the LTO symbol extension table\n"));
14006 goto fail;
14007 }
14008
14009 free (alloced_data);
14010 free (ext_data_orig);
14011 free (ext_name);
015dc7e1 14012 return true;
b9e920ec 14013
0f03783c
NC
14014 fail:
14015 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14016 free (alloced_data);
14017 free (ext_data_orig);
14018 free (ext_name);
015dc7e1 14019 return false;
0f03783c
NC
14020}
14021
14022/* Display LTO symbol tables. */
14023
015dc7e1 14024static bool
0f03783c
NC
14025process_lto_symbol_tables (Filedata * filedata)
14026{
14027 Elf_Internal_Shdr * section;
14028 unsigned int i;
015dc7e1 14029 bool res = true;
0f03783c
NC
14030
14031 if (!do_lto_syms)
015dc7e1 14032 return true;
0f03783c
NC
14033
14034 if (filedata->section_headers == NULL)
015dc7e1 14035 return true;
0f03783c
NC
14036
14037 for (i = 0, section = filedata->section_headers;
14038 i < filedata->file_header.e_shnum;
14039 i++, section++)
84714f86
AM
14040 if (section_name_valid (filedata, section)
14041 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14042 res &= display_lto_symtab (filedata, section);
14043
b9e920ec 14044 return res;
0f03783c
NC
14045}
14046
b6ac461a
NC
14047static void
14048print_symbol_table_heading (void)
14049{
14050 /* FIXME: We should store the size of each field in the display in a table and
14051 then use the values inside print_symbol(), instead of that function using
14052 hard coded constants. */
14053 if (is_32bit_elf)
14054 {
14055 if (extra_sym_info)
14056 {
14057 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14058 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14059 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14060 }
14061 else if (do_wide)
14062 {
14063 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14064 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14065 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14066 }
14067 else
14068 {
14069 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14070 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14071 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14072 }
14073 }
14074 else
14075 {
14076 if (extra_sym_info)
14077 {
14078 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14079 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14080 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14081
14082 }
14083 else if (do_wide)
14084 {
14085 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14086 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14087 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14088 }
14089 else
14090 {
14091 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14092 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14093 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14094 }
14095 }
14096}
14097
10ca4b04 14098/* Dump the symbol table. */
0f03783c 14099
015dc7e1 14100static bool
10ca4b04
L
14101process_symbol_table (Filedata * filedata)
14102{
14103 Elf_Internal_Shdr * section;
f16a9783 14104
10ca4b04 14105 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14106 return true;
6bd1a22c 14107
978c4450 14108 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14109 && do_syms
14110 && do_using_dynamic
978c4450
AM
14111 && filedata->dynamic_strings != NULL
14112 && filedata->dynamic_symbols != NULL)
6bd1a22c 14113 {
26c527e6 14114 uint64_t si;
6bd1a22c 14115
ca0e11aa
NC
14116 if (filedata->is_separate)
14117 {
26c527e6
AM
14118 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14119 " contains %" PRIu64 " entry:\n",
14120 "\nIn linked file '%s' the dynamic symbol table"
14121 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14122 filedata->num_dynamic_syms),
14123 filedata->file_name,
14124 filedata->num_dynamic_syms);
14125 }
14126 else
14127 {
26c527e6
AM
14128 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14129 " entry:\n",
14130 "\nSymbol table for image contains %" PRIu64
14131 " entries:\n",
ca0e11aa
NC
14132 filedata->num_dynamic_syms),
14133 filedata->num_dynamic_syms);
14134 }
b6ac461a
NC
14135
14136 print_symbol_table_heading ();
6bd1a22c 14137
978c4450 14138 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14139 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14140 filedata->dynamic_strings,
14141 filedata->dynamic_strings_length);
252b5132 14142 }
8b73c356 14143 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14144 && filedata->section_headers != NULL)
252b5132 14145 {
b34976b6 14146 unsigned int i;
252b5132 14147
dda8d76d
NC
14148 for (i = 0, section = filedata->section_headers;
14149 i < filedata->file_header.e_shnum;
252b5132
RH
14150 i++, section++)
14151 {
2cf0635d 14152 char * strtab = NULL;
26c527e6 14153 uint64_t strtab_size = 0;
2cf0635d 14154 Elf_Internal_Sym * symtab;
26c527e6 14155 uint64_t si, num_syms;
252b5132 14156
2c610e4b
L
14157 if ((section->sh_type != SHT_SYMTAB
14158 && section->sh_type != SHT_DYNSYM)
14159 || (!do_syms
14160 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14161 continue;
14162
dd24e3da
NC
14163 if (section->sh_entsize == 0)
14164 {
14165 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14166 printable_section_name (filedata, section));
dd24e3da
NC
14167 continue;
14168 }
14169
d3a49aa8 14170 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14171
14172 if (filedata->is_separate)
26c527e6
AM
14173 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14174 " contains %" PRIu64 " entry:\n",
14175 "\nIn linked file '%s' symbol section '%s'"
14176 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14177 num_syms),
14178 filedata->file_name,
14179 printable_section_name (filedata, section),
14180 num_syms);
14181 else
26c527e6
AM
14182 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14183 " entry:\n",
14184 "\nSymbol table '%s' contains %" PRIu64
14185 " entries:\n",
ca0e11aa
NC
14186 num_syms),
14187 printable_section_name (filedata, section),
14188 num_syms);
dd24e3da 14189
b6ac461a 14190 print_symbol_table_heading ();
252b5132 14191
4de91c10 14192 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14193 if (symtab == NULL)
14194 continue;
14195
dda8d76d 14196 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14197 {
dda8d76d
NC
14198 strtab = filedata->string_table;
14199 strtab_size = filedata->string_table_length;
c256ffe7 14200 }
dda8d76d 14201 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14202 {
2cf0635d 14203 Elf_Internal_Shdr * string_sec;
252b5132 14204
dda8d76d 14205 string_sec = filedata->section_headers + section->sh_link;
252b5132 14206
dda8d76d 14207 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14208 1, string_sec->sh_size,
14209 _("string table"));
c256ffe7 14210 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14211 }
14212
10ca4b04 14213 for (si = 0; si < num_syms; si++)
b6ac461a
NC
14214 print_symbol (filedata, si, symtab, section,
14215 strtab, strtab_size);
252b5132
RH
14216
14217 free (symtab);
dda8d76d 14218 if (strtab != filedata->string_table)
252b5132
RH
14219 free (strtab);
14220 }
14221 }
14222 else if (do_syms)
14223 printf
14224 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14225
978c4450 14226 if (do_histogram && filedata->buckets != NULL)
252b5132 14227 {
26c527e6
AM
14228 uint64_t *lengths;
14229 uint64_t *counts;
14230 uint64_t hn;
625d49fc 14231 uint64_t si;
26c527e6
AM
14232 uint64_t maxlength = 0;
14233 uint64_t nzero_counts = 0;
14234 uint64_t nsyms = 0;
6bd6a03d 14235 char *visited;
252b5132 14236
d3a49aa8 14237 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14238 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14239 "\nHistogram for bucket list length "
26c527e6
AM
14240 "(total of %" PRIu64 " buckets):\n",
14241 filedata->nbuckets),
14242 filedata->nbuckets);
252b5132 14243
26c527e6 14244 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14245 if (lengths == NULL)
14246 {
8b73c356 14247 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14248 goto err_out;
252b5132 14249 }
978c4450
AM
14250 visited = xcmalloc (filedata->nchains, 1);
14251 memset (visited, 0, filedata->nchains);
8b73c356
NC
14252
14253 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14254 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14255 {
978c4450 14256 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14257 {
b34976b6 14258 ++nsyms;
252b5132 14259 if (maxlength < ++lengths[hn])
b34976b6 14260 ++maxlength;
978c4450 14261 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14262 {
14263 error (_("histogram chain is corrupt\n"));
14264 break;
14265 }
14266 visited[si] = 1;
252b5132
RH
14267 }
14268 }
6bd6a03d 14269 free (visited);
252b5132 14270
26c527e6 14271 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14272 if (counts == NULL)
14273 {
b2e951ec 14274 free (lengths);
8b73c356 14275 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14276 goto err_out;
252b5132
RH
14277 }
14278
978c4450 14279 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14280 ++counts[lengths[hn]];
252b5132 14281
978c4450 14282 if (filedata->nbuckets > 0)
252b5132 14283 {
26c527e6
AM
14284 uint64_t i;
14285 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14286 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14287 for (i = 1; i <= maxlength; ++i)
103f02d3 14288 {
66543521 14289 nzero_counts += counts[i] * i;
26c527e6 14290 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14291 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14292 (nzero_counts * 100.0) / nsyms);
14293 }
252b5132
RH
14294 }
14295
14296 free (counts);
14297 free (lengths);
14298 }
14299
978c4450
AM
14300 free (filedata->buckets);
14301 filedata->buckets = NULL;
14302 filedata->nbuckets = 0;
14303 free (filedata->chains);
14304 filedata->chains = NULL;
252b5132 14305
978c4450 14306 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14307 {
26c527e6
AM
14308 uint64_t *lengths;
14309 uint64_t *counts;
14310 uint64_t hn;
14311 uint64_t maxlength = 0;
14312 uint64_t nzero_counts = 0;
14313 uint64_t nsyms = 0;
fdc90cb4 14314
f16a9783 14315 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14316 "(total of %" PRIu64 " bucket):\n",
f16a9783 14317 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14318 "(total of %" PRIu64 " buckets):\n",
14319 filedata->ngnubuckets),
978c4450 14320 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14321 filedata->ngnubuckets);
8b73c356 14322
26c527e6 14323 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14324 if (lengths == NULL)
14325 {
8b73c356 14326 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14327 goto err_out;
fdc90cb4
JJ
14328 }
14329
fdc90cb4
JJ
14330 printf (_(" Length Number %% of total Coverage\n"));
14331
978c4450
AM
14332 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14333 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14334 {
625d49fc 14335 uint64_t off, length = 1;
fdc90cb4 14336
978c4450 14337 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14338 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14339 off < filedata->ngnuchains
14340 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14341 ++off)
fdc90cb4
JJ
14342 ++length;
14343 lengths[hn] = length;
14344 if (length > maxlength)
14345 maxlength = length;
14346 nsyms += length;
14347 }
14348
26c527e6 14349 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14350 if (counts == NULL)
14351 {
b2e951ec 14352 free (lengths);
8b73c356 14353 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14354 goto err_out;
fdc90cb4
JJ
14355 }
14356
978c4450 14357 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14358 ++counts[lengths[hn]];
14359
978c4450 14360 if (filedata->ngnubuckets > 0)
fdc90cb4 14361 {
26c527e6
AM
14362 uint64_t j;
14363 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14364 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14365 for (j = 1; j <= maxlength; ++j)
14366 {
14367 nzero_counts += counts[j] * j;
26c527e6 14368 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14369 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14370 (nzero_counts * 100.0) / nsyms);
14371 }
14372 }
14373
14374 free (counts);
14375 free (lengths);
fdc90cb4 14376 }
978c4450
AM
14377 free (filedata->gnubuckets);
14378 filedata->gnubuckets = NULL;
14379 filedata->ngnubuckets = 0;
14380 free (filedata->gnuchains);
14381 filedata->gnuchains = NULL;
14382 filedata->ngnuchains = 0;
14383 free (filedata->mipsxlat);
14384 filedata->mipsxlat = NULL;
015dc7e1 14385 return true;
fd486f32
AM
14386
14387 err_out:
978c4450
AM
14388 free (filedata->gnubuckets);
14389 filedata->gnubuckets = NULL;
14390 filedata->ngnubuckets = 0;
14391 free (filedata->gnuchains);
14392 filedata->gnuchains = NULL;
14393 filedata->ngnuchains = 0;
14394 free (filedata->mipsxlat);
14395 filedata->mipsxlat = NULL;
14396 free (filedata->buckets);
14397 filedata->buckets = NULL;
14398 filedata->nbuckets = 0;
14399 free (filedata->chains);
14400 filedata->chains = NULL;
015dc7e1 14401 return false;
252b5132
RH
14402}
14403
015dc7e1 14404static bool
ca0e11aa 14405process_syminfo (Filedata * filedata)
252b5132 14406{
b4c96d0d 14407 unsigned int i;
252b5132 14408
978c4450 14409 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14410 || !do_dynamic)
14411 /* No syminfo, this is ok. */
015dc7e1 14412 return true;
252b5132
RH
14413
14414 /* There better should be a dynamic symbol section. */
978c4450 14415 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14416 return false;
252b5132 14417
ca0e11aa 14418 if (filedata->is_separate)
26c527e6
AM
14419 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14420 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14421 filedata->dynamic_syminfo_nent),
14422 filedata->file_name,
14423 filedata->dynamic_syminfo_offset,
14424 filedata->dynamic_syminfo_nent);
14425 else
26c527e6
AM
14426 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14427 " contains %d entry:\n",
14428 "\nDynamic info segment at offset %#" PRIx64
14429 " contains %d entries:\n",
978c4450 14430 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14431 filedata->dynamic_syminfo_offset,
14432 filedata->dynamic_syminfo_nent);
252b5132
RH
14433
14434 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14435 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14436 {
978c4450 14437 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14438
31104126 14439 printf ("%4d: ", i);
978c4450 14440 if (i >= filedata->num_dynamic_syms)
4082ef84 14441 printf (_("<corrupt index>"));
84714f86 14442 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14443 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14444 filedata->dynamic_symbols[i].st_name));
d79b3d50 14445 else
978c4450 14446 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14447 putchar (' ');
252b5132 14448
978c4450 14449 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14450 {
14451 case SYMINFO_BT_SELF:
14452 fputs ("SELF ", stdout);
14453 break;
14454 case SYMINFO_BT_PARENT:
14455 fputs ("PARENT ", stdout);
14456 break;
14457 default:
978c4450
AM
14458 if (filedata->dynamic_syminfo[i].si_boundto > 0
14459 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14460 && valid_dynamic_name (filedata,
978c4450 14461 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14462 {
b6ac461a 14463 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14464 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14465 putchar (' ' );
14466 }
252b5132 14467 else
978c4450 14468 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14469 break;
14470 }
14471
14472 if (flags & SYMINFO_FLG_DIRECT)
14473 printf (" DIRECT");
14474 if (flags & SYMINFO_FLG_PASSTHRU)
14475 printf (" PASSTHRU");
14476 if (flags & SYMINFO_FLG_COPY)
14477 printf (" COPY");
14478 if (flags & SYMINFO_FLG_LAZYLOAD)
14479 printf (" LAZYLOAD");
14480
14481 puts ("");
14482 }
14483
015dc7e1 14484 return true;
252b5132
RH
14485}
14486
75802ccb
CE
14487/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14488 is contained by the region START .. END. The types of ADDR, START
14489 and END should all be the same. Note both ADDR + NELEM and END
14490 point to just beyond the end of the regions that are being tested. */
14491#define IN_RANGE(START,END,ADDR,NELEM) \
14492 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14493
cf13d699
NC
14494/* Check to see if the given reloc needs to be handled in a target specific
14495 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14496 FALSE.
14497
14498 If called with reloc == NULL, then this is a signal that reloc processing
14499 for the current section has finished, and any saved state should be
14500 discarded. */
09c11c86 14501
015dc7e1 14502static bool
26c527e6
AM
14503target_specific_reloc_handling (Filedata *filedata,
14504 Elf_Internal_Rela *reloc,
14505 unsigned char *start,
14506 unsigned char *end,
14507 Elf_Internal_Sym *symtab,
14508 uint64_t num_syms)
252b5132 14509{
f84ce13b 14510 unsigned int reloc_type = 0;
26c527e6 14511 uint64_t sym_index = 0;
f84ce13b
NC
14512
14513 if (reloc)
14514 {
dda8d76d 14515 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14516 sym_index = get_reloc_symindex (reloc->r_info);
14517 }
252b5132 14518
dda8d76d 14519 switch (filedata->file_header.e_machine)
252b5132 14520 {
76244462 14521 case EM_LOONGARCH:
14522 {
14523 switch (reloc_type)
14524 {
14525 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14526 at assembly time. */
14527 case 107: /* R_LARCH_ADD_ULEB128. */
14528 case 108: /* R_LARCH_SUB_ULEB128. */
14529 {
d3f34076 14530 uint64_t value = 0;
76244462 14531 unsigned int reloc_size = 0;
14532 int leb_ret = 0;
14533
89c70cd3
AM
14534 if (reloc->r_offset < (size_t) (end - start))
14535 value = read_leb128 (start + reloc->r_offset, end, false,
14536 &reloc_size, &leb_ret);
76244462 14537 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14538 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14539 "ULEB128 value\n"),
14540 (long) reloc->r_offset);
14541
74a965d8
AM
14542 else if (sym_index >= num_syms)
14543 error (_("%s reloc contains invalid symbol index "
14544 "%" PRIu64 "\n"),
14545 (reloc_type == 107
14546 ? "R_LARCH_ADD_ULEB128"
14547 : "R_LARCH_SUB_ULEB128"),
14548 sym_index);
14549 else
76244462 14550 {
74a965d8
AM
14551 if (reloc_type == 107)
14552 value += reloc->r_addend + symtab[sym_index].st_value;
14553 else
14554 value -= reloc->r_addend + symtab[sym_index].st_value;
14555
14556 /* Write uleb128 value to p. */
14557 bfd_byte *p = start + reloc->r_offset;
14558 do
14559 {
14560 bfd_byte c = value & 0x7f;
14561 value >>= 7;
14562 if (--reloc_size != 0)
14563 c |= 0x80;
14564 *p++ = c;
14565 }
14566 while (reloc_size);
76244462 14567 }
76244462 14568
14569 return true;
14570 }
14571 }
14572 break;
14573 }
14574
13761a11
NC
14575 case EM_MSP430:
14576 case EM_MSP430_OLD:
14577 {
14578 static Elf_Internal_Sym * saved_sym = NULL;
14579
f84ce13b
NC
14580 if (reloc == NULL)
14581 {
14582 saved_sym = NULL;
015dc7e1 14583 return true;
f84ce13b
NC
14584 }
14585
13761a11
NC
14586 switch (reloc_type)
14587 {
14588 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14589 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14590 if (uses_msp430x_relocs (filedata))
13761a11 14591 break;
1a0670f3 14592 /* Fall through. */
13761a11 14593 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14594 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14595 /* PR 21139. */
14596 if (sym_index >= num_syms)
74a965d8
AM
14597 error (_("%s reloc contains invalid symbol index "
14598 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14599 else
14600 saved_sym = symtab + sym_index;
015dc7e1 14601 return true;
13761a11
NC
14602
14603 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14604 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14605 goto handle_sym_diff;
0b4362b0 14606
13761a11
NC
14607 case 5: /* R_MSP430_16_BYTE */
14608 case 9: /* R_MSP430_8 */
7d81bc93 14609 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14610 if (uses_msp430x_relocs (filedata))
13761a11
NC
14611 break;
14612 goto handle_sym_diff;
14613
14614 case 2: /* R_MSP430_ABS16 */
14615 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14616 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14617 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14618 break;
14619 goto handle_sym_diff;
0b4362b0 14620
13761a11
NC
14621 handle_sym_diff:
14622 if (saved_sym != NULL)
14623 {
625d49fc 14624 uint64_t value;
5a805384 14625 unsigned int reloc_size = 0;
7d81bc93
JL
14626 int leb_ret = 0;
14627 switch (reloc_type)
14628 {
14629 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14630 reloc_size = 4;
14631 break;
14632 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14633 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14634 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14635 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14636 &reloc_size, &leb_ret);
7d81bc93
JL
14637 break;
14638 default:
14639 reloc_size = 2;
14640 break;
14641 }
13761a11 14642
5a805384 14643 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14644 error (_("MSP430 ULEB128 field at %#" PRIx64
14645 " contains invalid ULEB128 value\n"),
14646 reloc->r_offset);
7d81bc93 14647 else if (sym_index >= num_syms)
74a965d8
AM
14648 error (_("%s reloc contains invalid symbol index "
14649 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14650 else
f84ce13b
NC
14651 {
14652 value = reloc->r_addend + (symtab[sym_index].st_value
14653 - saved_sym->st_value);
14654
b32e566b 14655 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14656 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14657 else
14658 /* PR 21137 */
26c527e6
AM
14659 error (_("MSP430 sym diff reloc contains invalid offset: "
14660 "%#" PRIx64 "\n"),
14661 reloc->r_offset);
f84ce13b 14662 }
13761a11
NC
14663
14664 saved_sym = NULL;
015dc7e1 14665 return true;
13761a11
NC
14666 }
14667 break;
14668
14669 default:
14670 if (saved_sym != NULL)
071436c6 14671 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14672 break;
14673 }
14674 break;
14675 }
14676
cf13d699
NC
14677 case EM_MN10300:
14678 case EM_CYGNUS_MN10300:
14679 {
14680 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14681
f84ce13b
NC
14682 if (reloc == NULL)
14683 {
14684 saved_sym = NULL;
015dc7e1 14685 return true;
f84ce13b
NC
14686 }
14687
cf13d699
NC
14688 switch (reloc_type)
14689 {
14690 case 34: /* R_MN10300_ALIGN */
015dc7e1 14691 return true;
cf13d699 14692 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14693 if (sym_index >= num_syms)
74a965d8
AM
14694 error (_("%s reloc contains invalid symbol index "
14695 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14696 else
14697 saved_sym = symtab + sym_index;
015dc7e1 14698 return true;
f84ce13b 14699
cf13d699
NC
14700 case 1: /* R_MN10300_32 */
14701 case 2: /* R_MN10300_16 */
14702 if (saved_sym != NULL)
14703 {
03f7786e 14704 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14705 uint64_t value;
252b5132 14706
f84ce13b 14707 if (sym_index >= num_syms)
74a965d8
AM
14708 error (_("%s reloc contains invalid symbol index "
14709 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14710 else
f84ce13b
NC
14711 {
14712 value = reloc->r_addend + (symtab[sym_index].st_value
14713 - saved_sym->st_value);
14714
b32e566b 14715 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14716 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14717 else
26c527e6
AM
14718 error (_("MN10300 sym diff reloc contains invalid offset:"
14719 " %#" PRIx64 "\n"),
14720 reloc->r_offset);
f84ce13b 14721 }
252b5132 14722
cf13d699 14723 saved_sym = NULL;
015dc7e1 14724 return true;
cf13d699
NC
14725 }
14726 break;
14727 default:
14728 if (saved_sym != NULL)
071436c6 14729 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14730 break;
14731 }
14732 break;
14733 }
6ff71e76
NC
14734
14735 case EM_RL78:
14736 {
625d49fc
AM
14737 static uint64_t saved_sym1 = 0;
14738 static uint64_t saved_sym2 = 0;
14739 static uint64_t value;
6ff71e76 14740
f84ce13b
NC
14741 if (reloc == NULL)
14742 {
14743 saved_sym1 = saved_sym2 = 0;
015dc7e1 14744 return true;
f84ce13b
NC
14745 }
14746
6ff71e76
NC
14747 switch (reloc_type)
14748 {
14749 case 0x80: /* R_RL78_SYM. */
14750 saved_sym1 = saved_sym2;
f84ce13b 14751 if (sym_index >= num_syms)
74a965d8
AM
14752 error (_("%s reloc contains invalid symbol index "
14753 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14754 else
14755 {
14756 saved_sym2 = symtab[sym_index].st_value;
14757 saved_sym2 += reloc->r_addend;
14758 }
015dc7e1 14759 return true;
6ff71e76
NC
14760
14761 case 0x83: /* R_RL78_OPsub. */
14762 value = saved_sym1 - saved_sym2;
14763 saved_sym2 = saved_sym1 = 0;
015dc7e1 14764 return true;
6ff71e76
NC
14765 break;
14766
14767 case 0x41: /* R_RL78_ABS32. */
b32e566b 14768 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14769 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14770 else
26c527e6
AM
14771 error (_("RL78 sym diff reloc contains invalid offset: "
14772 "%#" PRIx64 "\n"),
14773 reloc->r_offset);
6ff71e76 14774 value = 0;
015dc7e1 14775 return true;
6ff71e76
NC
14776
14777 case 0x43: /* R_RL78_ABS16. */
b32e566b 14778 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14779 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14780 else
26c527e6
AM
14781 error (_("RL78 sym diff reloc contains invalid offset: "
14782 "%#" PRIx64 "\n"),
14783 reloc->r_offset);
6ff71e76 14784 value = 0;
015dc7e1 14785 return true;
6ff71e76
NC
14786
14787 default:
14788 break;
14789 }
14790 break;
14791 }
252b5132
RH
14792 }
14793
015dc7e1 14794 return false;
252b5132
RH
14795}
14796
aca88567
NC
14797/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14798 DWARF debug sections. This is a target specific test. Note - we do not
14799 go through the whole including-target-headers-multiple-times route, (as
14800 we have already done with <elf/h8.h>) because this would become very
14801 messy and even then this function would have to contain target specific
14802 information (the names of the relocs instead of their numeric values).
14803 FIXME: This is not the correct way to solve this problem. The proper way
14804 is to have target specific reloc sizing and typing functions created by
14805 the reloc-macros.h header, in the same way that it already creates the
14806 reloc naming functions. */
14807
015dc7e1 14808static bool
dda8d76d 14809is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14810{
d347c9df 14811 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14812 switch (filedata->file_header.e_machine)
aca88567 14813 {
41e92641 14814 case EM_386:
22abe556 14815 case EM_IAMCU:
41e92641 14816 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14817 case EM_68K:
14818 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14819 case EM_860:
14820 return reloc_type == 1; /* R_860_32. */
14821 case EM_960:
14822 return reloc_type == 2; /* R_960_32. */
a06ea964 14823 case EM_AARCH64:
9282b95a
JW
14824 return (reloc_type == 258
14825 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14826 case EM_BPF:
14827 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14828 case EM_ADAPTEVA_EPIPHANY:
14829 return reloc_type == 3;
aca88567 14830 case EM_ALPHA:
137b6b5f 14831 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14832 case EM_ARC:
14833 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14834 case EM_ARC_COMPACT:
14835 case EM_ARC_COMPACT2:
b5c37946
SJ
14836 case EM_ARC_COMPACT3:
14837 case EM_ARC_COMPACT3_64:
886a2506 14838 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14839 case EM_ARM:
14840 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14841 case EM_AVR_OLD:
aca88567
NC
14842 case EM_AVR:
14843 return reloc_type == 1;
14844 case EM_BLACKFIN:
14845 return reloc_type == 0x12; /* R_byte4_data. */
14846 case EM_CRIS:
14847 return reloc_type == 3; /* R_CRIS_32. */
14848 case EM_CR16:
14849 return reloc_type == 3; /* R_CR16_NUM32. */
14850 case EM_CRX:
14851 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14852 case EM_CSKY:
14853 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14854 case EM_CYGNUS_FRV:
14855 return reloc_type == 1;
41e92641
NC
14856 case EM_CYGNUS_D10V:
14857 case EM_D10V:
14858 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14859 case EM_CYGNUS_D30V:
14860 case EM_D30V:
14861 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14862 case EM_DLX:
14863 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14864 case EM_CYGNUS_FR30:
14865 case EM_FR30:
14866 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14867 case EM_FT32:
14868 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14869 case EM_H8S:
14870 case EM_H8_300:
14871 case EM_H8_300H:
14872 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14873 case EM_IA_64:
262cdac7
AM
14874 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14875 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14876 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14877 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14878 case EM_IP2K_OLD:
14879 case EM_IP2K:
14880 return reloc_type == 2; /* R_IP2K_32. */
14881 case EM_IQ2000:
14882 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
14883 case EM_KVX:
14884 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
14885 case EM_LATTICEMICO32:
14886 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14887 case EM_LOONGARCH:
14888 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14889 case EM_M32C_OLD:
aca88567
NC
14890 case EM_M32C:
14891 return reloc_type == 3; /* R_M32C_32. */
14892 case EM_M32R:
14893 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14894 case EM_68HC11:
14895 case EM_68HC12:
14896 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14897 case EM_S12Z:
2849d19f
JD
14898 return reloc_type == 7 || /* R_S12Z_EXT32 */
14899 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14900 case EM_MCORE:
14901 return reloc_type == 1; /* R_MCORE_ADDR32. */
14902 case EM_CYGNUS_MEP:
14903 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14904 case EM_METAG:
14905 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14906 case EM_MICROBLAZE:
14907 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14908 case EM_MIPS:
14909 return reloc_type == 2; /* R_MIPS_32. */
14910 case EM_MMIX:
14911 return reloc_type == 4; /* R_MMIX_32. */
14912 case EM_CYGNUS_MN10200:
14913 case EM_MN10200:
14914 return reloc_type == 1; /* R_MN10200_32. */
14915 case EM_CYGNUS_MN10300:
14916 case EM_MN10300:
14917 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14918 case EM_MOXIE:
14919 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14920 case EM_MSP430_OLD:
14921 case EM_MSP430:
13761a11 14922 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14923 case EM_MT:
14924 return reloc_type == 2; /* R_MT_32. */
35c08157 14925 case EM_NDS32:
81c5e376 14926 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14927 case EM_ALTERA_NIOS2:
36591ba1 14928 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14929 case EM_NIOS32:
14930 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14931 case EM_OR1K:
14932 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14933 case EM_PARISC:
9abca702 14934 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14935 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14936 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14937 case EM_PJ:
14938 case EM_PJ_OLD:
14939 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14940 case EM_PPC64:
14941 return reloc_type == 1; /* R_PPC64_ADDR32. */
14942 case EM_PPC:
14943 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14944 case EM_TI_PRU:
14945 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14946 case EM_RISCV:
14947 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14948 case EM_RL78:
14949 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14950 case EM_RX:
14951 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14952 case EM_S370:
14953 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14954 case EM_S390_OLD:
14955 case EM_S390:
14956 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14957 case EM_SCORE:
14958 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14959 case EM_SH:
14960 return reloc_type == 1; /* R_SH_DIR32. */
14961 case EM_SPARC32PLUS:
14962 case EM_SPARCV9:
14963 case EM_SPARC:
14964 return reloc_type == 3 /* R_SPARC_32. */
14965 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14966 case EM_SPU:
14967 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14968 case EM_TI_C6000:
14969 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14970 case EM_TILEGX:
14971 return reloc_type == 2; /* R_TILEGX_32. */
14972 case EM_TILEPRO:
14973 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14974 case EM_CYGNUS_V850:
14975 case EM_V850:
14976 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14977 case EM_V800:
14978 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14979 case EM_VAX:
14980 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14981 case EM_VISIUM:
14982 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14983 case EM_WEBASSEMBLY:
14984 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14985 case EM_X86_64:
8a9036a4 14986 case EM_L1OM:
7a9068fe 14987 case EM_K1OM:
aca88567 14988 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14989 case EM_XGATE:
14990 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14991 case EM_XSTORMY16:
14992 return reloc_type == 1; /* R_XSTROMY16_32. */
14993 case EM_XTENSA_OLD:
14994 case EM_XTENSA:
14995 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14996 case EM_Z80:
14997 return reloc_type == 6; /* R_Z80_32. */
aca88567 14998 default:
bee0ee85
NC
14999 {
15000 static unsigned int prev_warn = 0;
15001
15002 /* Avoid repeating the same warning multiple times. */
dda8d76d 15003 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15004 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15005 filedata->file_header.e_machine);
15006 prev_warn = filedata->file_header.e_machine;
015dc7e1 15007 return false;
bee0ee85 15008 }
aca88567
NC
15009 }
15010}
15011
15012/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15013 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15014
015dc7e1 15015static bool
dda8d76d 15016is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15017{
dda8d76d 15018 switch (filedata->file_header.e_machine)
d347c9df 15019 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15020 {
41e92641 15021 case EM_386:
22abe556 15022 case EM_IAMCU:
3e0873ac 15023 return reloc_type == 2; /* R_386_PC32. */
aca88567 15024 case EM_68K:
3e0873ac 15025 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15026 case EM_AARCH64:
15027 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15028 case EM_ADAPTEVA_EPIPHANY:
15029 return reloc_type == 6;
aca88567
NC
15030 case EM_ALPHA:
15031 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15032 case EM_ARC_COMPACT:
15033 case EM_ARC_COMPACT2:
b5c37946
SJ
15034 case EM_ARC_COMPACT3:
15035 case EM_ARC_COMPACT3_64:
726c18e1 15036 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15037 case EM_ARM:
3e0873ac 15038 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15039 case EM_AVR_OLD:
15040 case EM_AVR:
15041 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15042 case EM_LOONGARCH:
15043 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15044 case EM_MICROBLAZE:
15045 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15046 case EM_OR1K:
15047 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15048 case EM_PARISC:
85acf597 15049 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15050 case EM_PPC:
15051 return reloc_type == 26; /* R_PPC_REL32. */
15052 case EM_PPC64:
3e0873ac 15053 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15054 case EM_RISCV:
15055 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15056 case EM_S390_OLD:
15057 case EM_S390:
3e0873ac 15058 return reloc_type == 5; /* R_390_PC32. */
aca88567 15059 case EM_SH:
3e0873ac 15060 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15061 case EM_SPARC32PLUS:
15062 case EM_SPARCV9:
15063 case EM_SPARC:
3e0873ac 15064 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15065 case EM_SPU:
15066 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15067 case EM_TILEGX:
15068 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15069 case EM_TILEPRO:
15070 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15071 case EM_VISIUM:
15072 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15073 case EM_X86_64:
8a9036a4 15074 case EM_L1OM:
7a9068fe 15075 case EM_K1OM:
3e0873ac 15076 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15077 case EM_VAX:
15078 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15079 case EM_XTENSA_OLD:
15080 case EM_XTENSA:
15081 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15082 case EM_KVX:
15083 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15084 default:
15085 /* Do not abort or issue an error message here. Not all targets use
15086 pc-relative 32-bit relocs in their DWARF debug information and we
15087 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15088 more helpful warning message will be generated by apply_relocations
15089 anyway, so just return. */
015dc7e1 15090 return false;
aca88567
NC
15091 }
15092}
15093
15094/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15095 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15096
015dc7e1 15097static bool
dda8d76d 15098is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15099{
dda8d76d 15100 switch (filedata->file_header.e_machine)
aca88567 15101 {
a06ea964
NC
15102 case EM_AARCH64:
15103 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15104 case EM_ARC_COMPACT3_64:
15105 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15106 case EM_ALPHA:
15107 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15108 case EM_IA_64:
262cdac7
AM
15109 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15110 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15111 case EM_LOONGARCH:
15112 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15113 case EM_PARISC:
15114 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15115 case EM_PPC64:
15116 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15117 case EM_RISCV:
15118 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15119 case EM_SPARC32PLUS:
15120 case EM_SPARCV9:
15121 case EM_SPARC:
714da62f
NC
15122 return reloc_type == 32 /* R_SPARC_64. */
15123 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15124 case EM_X86_64:
8a9036a4 15125 case EM_L1OM:
7a9068fe 15126 case EM_K1OM:
aca88567 15127 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15128 case EM_S390_OLD:
15129 case EM_S390:
aa137e4d
NC
15130 return reloc_type == 22; /* R_S390_64. */
15131 case EM_TILEGX:
15132 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15133 case EM_MIPS:
aa137e4d 15134 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15135 case EM_KVX:
15136 return reloc_type == 3; /* R_KVX_64 */
aca88567 15137 default:
015dc7e1 15138 return false;
aca88567
NC
15139 }
15140}
15141
85acf597
RH
15142/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15143 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15144
015dc7e1 15145static bool
dda8d76d 15146is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15147{
dda8d76d 15148 switch (filedata->file_header.e_machine)
85acf597 15149 {
a06ea964
NC
15150 case EM_AARCH64:
15151 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15152 case EM_ALPHA:
aa137e4d 15153 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15154 case EM_IA_64:
262cdac7
AM
15155 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15156 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15157 case EM_PARISC:
aa137e4d 15158 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15159 case EM_PPC64:
aa137e4d 15160 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15161 case EM_SPARC32PLUS:
15162 case EM_SPARCV9:
15163 case EM_SPARC:
aa137e4d 15164 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15165 case EM_X86_64:
8a9036a4 15166 case EM_L1OM:
7a9068fe 15167 case EM_K1OM:
aa137e4d 15168 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15169 case EM_S390_OLD:
15170 case EM_S390:
aa137e4d
NC
15171 return reloc_type == 23; /* R_S390_PC64. */
15172 case EM_TILEGX:
15173 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15174 default:
015dc7e1 15175 return false;
85acf597
RH
15176 }
15177}
15178
4dc3c23d
AM
15179/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15180 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15181
015dc7e1 15182static bool
dda8d76d 15183is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15184{
dda8d76d 15185 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15186 {
15187 case EM_CYGNUS_MN10200:
15188 case EM_MN10200:
15189 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15190 case EM_FT32:
15191 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15192 case EM_Z80:
15193 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15194 default:
015dc7e1 15195 return false;
4dc3c23d
AM
15196 }
15197}
15198
aca88567
NC
15199/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15200 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15201
015dc7e1 15202static bool
dda8d76d 15203is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15204{
d347c9df 15205 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15206 switch (filedata->file_header.e_machine)
4b78141a 15207 {
886a2506
NC
15208 case EM_ARC:
15209 case EM_ARC_COMPACT:
15210 case EM_ARC_COMPACT2:
b5c37946
SJ
15211 case EM_ARC_COMPACT3:
15212 case EM_ARC_COMPACT3_64:
886a2506 15213 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15214 case EM_ADAPTEVA_EPIPHANY:
15215 return reloc_type == 5;
aca88567
NC
15216 case EM_AVR_OLD:
15217 case EM_AVR:
15218 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15219 case EM_CYGNUS_D10V:
15220 case EM_D10V:
15221 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15222 case EM_FT32:
15223 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15224 case EM_H8S:
15225 case EM_H8_300:
15226 case EM_H8_300H:
aca88567
NC
15227 return reloc_type == R_H8_DIR16;
15228 case EM_IP2K_OLD:
15229 case EM_IP2K:
15230 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15231 case EM_M32C_OLD:
f4236fe4
DD
15232 case EM_M32C:
15233 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15234 case EM_CYGNUS_MN10200:
15235 case EM_MN10200:
15236 return reloc_type == 2; /* R_MN10200_16. */
15237 case EM_CYGNUS_MN10300:
15238 case EM_MN10300:
15239 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15240 case EM_KVX:
15241 return reloc_type == 1; /* R_KVX_16 */
aca88567 15242 case EM_MSP430:
dda8d76d 15243 if (uses_msp430x_relocs (filedata))
13761a11 15244 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15245 /* Fall through. */
78c8d46c 15246 case EM_MSP430_OLD:
aca88567 15247 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15248 case EM_NDS32:
81c5e376 15249 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15250 case EM_ALTERA_NIOS2:
36591ba1 15251 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15252 case EM_NIOS32:
15253 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15254 case EM_OR1K:
15255 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15256 case EM_RISCV:
15257 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15258 case EM_TI_PRU:
15259 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15260 case EM_TI_C6000:
15261 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15262 case EM_VISIUM:
15263 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15264 case EM_XGATE:
15265 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15266 case EM_Z80:
15267 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15268 default:
015dc7e1 15269 return false;
4b78141a
NC
15270 }
15271}
15272
39e07931
AS
15273/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15274 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15275
015dc7e1 15276static bool
39e07931
AS
15277is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15278{
15279 switch (filedata->file_header.e_machine)
15280 {
15281 case EM_RISCV:
15282 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15283 case EM_Z80:
15284 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15285 case EM_MICROBLAZE:
15286 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15287 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15288 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15289 default:
015dc7e1 15290 return false;
39e07931
AS
15291 }
15292}
15293
15294/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15295 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15296
015dc7e1 15297static bool
39e07931
AS
15298is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15299{
15300 switch (filedata->file_header.e_machine)
15301 {
15302 case EM_RISCV:
15303 return reloc_type == 53; /* R_RISCV_SET6. */
15304 default:
015dc7e1 15305 return false;
39e07931
AS
15306 }
15307}
15308
03336641
JW
15309/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15310 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15311
015dc7e1 15312static bool
03336641
JW
15313is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15314{
15315 /* Please keep this table alpha-sorted for ease of visual lookup. */
15316 switch (filedata->file_header.e_machine)
15317 {
76244462 15318 case EM_LOONGARCH:
15319 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15320 case EM_RISCV:
15321 return reloc_type == 35; /* R_RISCV_ADD32. */
15322 default:
015dc7e1 15323 return false;
03336641
JW
15324 }
15325}
15326
15327/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15328 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15329
015dc7e1 15330static bool
03336641
JW
15331is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15332{
15333 /* Please keep this table alpha-sorted for ease of visual lookup. */
15334 switch (filedata->file_header.e_machine)
15335 {
76244462 15336 case EM_LOONGARCH:
15337 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15338 case EM_RISCV:
15339 return reloc_type == 39; /* R_RISCV_SUB32. */
15340 default:
015dc7e1 15341 return false;
03336641
JW
15342 }
15343}
15344
15345/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15346 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15347
015dc7e1 15348static bool
03336641
JW
15349is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15350{
15351 /* Please keep this table alpha-sorted for ease of visual lookup. */
15352 switch (filedata->file_header.e_machine)
15353 {
76244462 15354 case EM_LOONGARCH:
15355 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15356 case EM_RISCV:
15357 return reloc_type == 36; /* R_RISCV_ADD64. */
15358 default:
015dc7e1 15359 return false;
03336641
JW
15360 }
15361}
15362
15363/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15364 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15365
015dc7e1 15366static bool
03336641
JW
15367is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15368{
15369 /* Please keep this table alpha-sorted for ease of visual lookup. */
15370 switch (filedata->file_header.e_machine)
15371 {
76244462 15372 case EM_LOONGARCH:
15373 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15374 case EM_RISCV:
15375 return reloc_type == 40; /* R_RISCV_SUB64. */
15376 default:
015dc7e1 15377 return false;
03336641
JW
15378 }
15379}
15380
15381/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15382 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15383
015dc7e1 15384static bool
03336641
JW
15385is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15386{
15387 /* Please keep this table alpha-sorted for ease of visual lookup. */
15388 switch (filedata->file_header.e_machine)
15389 {
76244462 15390 case EM_LOONGARCH:
15391 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15392 case EM_RISCV:
15393 return reloc_type == 34; /* R_RISCV_ADD16. */
15394 default:
015dc7e1 15395 return false;
03336641
JW
15396 }
15397}
15398
15399/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15400 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15401
015dc7e1 15402static bool
03336641
JW
15403is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15404{
15405 /* Please keep this table alpha-sorted for ease of visual lookup. */
15406 switch (filedata->file_header.e_machine)
15407 {
76244462 15408 case EM_LOONGARCH:
15409 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15410 case EM_RISCV:
15411 return reloc_type == 38; /* R_RISCV_SUB16. */
15412 default:
015dc7e1 15413 return false;
03336641
JW
15414 }
15415}
15416
15417/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15418 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15419
015dc7e1 15420static bool
03336641
JW
15421is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15422{
15423 /* Please keep this table alpha-sorted for ease of visual lookup. */
15424 switch (filedata->file_header.e_machine)
15425 {
76244462 15426 case EM_LOONGARCH:
15427 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15428 case EM_RISCV:
15429 return reloc_type == 33; /* R_RISCV_ADD8. */
15430 default:
015dc7e1 15431 return false;
03336641
JW
15432 }
15433}
15434
15435/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15436 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15437
015dc7e1 15438static bool
03336641
JW
15439is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15440{
15441 /* Please keep this table alpha-sorted for ease of visual lookup. */
15442 switch (filedata->file_header.e_machine)
15443 {
76244462 15444 case EM_LOONGARCH:
15445 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15446 case EM_RISCV:
15447 return reloc_type == 37; /* R_RISCV_SUB8. */
15448 default:
015dc7e1 15449 return false;
03336641
JW
15450 }
15451}
15452
76244462 15453/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15454 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15455
15456static bool
15457is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15458{
15459 switch (filedata->file_header.e_machine)
15460 {
15461 case EM_LOONGARCH:
15462 return reloc_type == 105; /* R_LARCH_ADD6. */
15463 default:
15464 return false;
15465 }
15466}
15467
39e07931
AS
15468/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15469 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15470
015dc7e1 15471static bool
39e07931
AS
15472is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15473{
15474 switch (filedata->file_header.e_machine)
15475 {
76244462 15476 case EM_LOONGARCH:
15477 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15478 case EM_RISCV:
15479 return reloc_type == 52; /* R_RISCV_SUB6. */
15480 default:
015dc7e1 15481 return false;
39e07931
AS
15482 }
15483}
15484
2a7b2e88
JK
15485/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15486 relocation entries (possibly formerly used for SHT_GROUP sections). */
15487
015dc7e1 15488static bool
dda8d76d 15489is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15490{
dda8d76d 15491 switch (filedata->file_header.e_machine)
2a7b2e88 15492 {
cb8f3167 15493 case EM_386: /* R_386_NONE. */
d347c9df 15494 case EM_68K: /* R_68K_NONE. */
cfb8c092 15495 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15496 case EM_ALPHA: /* R_ALPHA_NONE. */
15497 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15498 case EM_ARC: /* R_ARC_NONE. */
886a2506 15499 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15500 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15501 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15502 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15503 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15504 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15505 case EM_FT32: /* R_FT32_NONE. */
15506 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15507 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15508 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15509 case EM_L1OM: /* R_X86_64_NONE. */
15510 case EM_M32R: /* R_M32R_NONE. */
15511 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15512 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15513 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15514 case EM_NIOS32: /* R_NIOS_NONE. */
15515 case EM_OR1K: /* R_OR1K_NONE. */
15516 case EM_PARISC: /* R_PARISC_NONE. */
15517 case EM_PPC64: /* R_PPC64_NONE. */
15518 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15519 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15520 case EM_S390: /* R_390_NONE. */
15521 case EM_S390_OLD:
15522 case EM_SH: /* R_SH_NONE. */
15523 case EM_SPARC32PLUS:
15524 case EM_SPARC: /* R_SPARC_NONE. */
15525 case EM_SPARCV9:
aa137e4d
NC
15526 case EM_TILEGX: /* R_TILEGX_NONE. */
15527 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15528 case EM_TI_C6000:/* R_C6000_NONE. */
15529 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15530 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15531 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15532 return reloc_type == 0;
d347c9df 15533
a06ea964
NC
15534 case EM_AARCH64:
15535 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15536 case EM_AVR_OLD:
15537 case EM_AVR:
15538 return (reloc_type == 0 /* R_AVR_NONE. */
15539 || reloc_type == 30 /* R_AVR_DIFF8. */
15540 || reloc_type == 31 /* R_AVR_DIFF16. */
15541 || reloc_type == 32 /* R_AVR_DIFF32. */);
15542 case EM_METAG:
15543 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15544 case EM_NDS32:
81c5e376
AM
15545 return (reloc_type == 0 /* R_NDS32_NONE. */
15546 || reloc_type == 205 /* R_NDS32_DIFF8. */
15547 || reloc_type == 206 /* R_NDS32_DIFF16. */
15548 || reloc_type == 207 /* R_NDS32_DIFF32. */
15549 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15550 case EM_TI_PRU:
15551 return (reloc_type == 0 /* R_PRU_NONE. */
15552 || reloc_type == 65 /* R_PRU_DIFF8. */
15553 || reloc_type == 66 /* R_PRU_DIFF16. */
15554 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15555 case EM_XTENSA_OLD:
15556 case EM_XTENSA:
4dc3c23d
AM
15557 return (reloc_type == 0 /* R_XTENSA_NONE. */
15558 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15559 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15560 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15561 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15562 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15563 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15564 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15565 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15566 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15567 }
015dc7e1 15568 return false;
2a7b2e88
JK
15569}
15570
d1c4b12b
NC
15571/* Returns TRUE if there is a relocation against
15572 section NAME at OFFSET bytes. */
15573
015dc7e1 15574bool
31e5a3a3 15575reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15576{
15577 Elf_Internal_Rela * relocs;
15578 Elf_Internal_Rela * rp;
15579
15580 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15581 return false;
d1c4b12b
NC
15582
15583 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15584
15585 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15586 if (rp->r_offset == offset)
015dc7e1 15587 return true;
d1c4b12b 15588
015dc7e1 15589 return false;
d1c4b12b
NC
15590}
15591
cf13d699 15592/* Apply relocations to a section.
32ec8896
NC
15593 Returns TRUE upon success, FALSE otherwise.
15594 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15595 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15596 will be set to the number of relocs loaded.
15597
cf13d699 15598 Note: So far support has been added only for those relocations
32ec8896
NC
15599 which can be found in debug sections. FIXME: Add support for
15600 more relocations ? */
1b315056 15601
015dc7e1 15602static bool
be7d229a
AM
15603apply_relocations (Filedata *filedata,
15604 const Elf_Internal_Shdr *section,
15605 unsigned char *start,
15606 size_t size,
15607 void **relocs_return,
26c527e6 15608 uint64_t *num_relocs_return)
1b315056 15609{
cf13d699 15610 Elf_Internal_Shdr * relsec;
0d2a7a93 15611 unsigned char * end = start + size;
cb8f3167 15612
d1c4b12b
NC
15613 if (relocs_return != NULL)
15614 {
15615 * (Elf_Internal_Rela **) relocs_return = NULL;
15616 * num_relocs_return = 0;
15617 }
15618
dda8d76d 15619 if (filedata->file_header.e_type != ET_REL)
32ec8896 15620 /* No relocs to apply. */
015dc7e1 15621 return true;
1b315056 15622
cf13d699 15623 /* Find the reloc section associated with the section. */
dda8d76d
NC
15624 for (relsec = filedata->section_headers;
15625 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15626 ++relsec)
252b5132 15627 {
015dc7e1 15628 bool is_rela;
26c527e6 15629 uint64_t num_relocs;
2cf0635d
NC
15630 Elf_Internal_Rela * relocs;
15631 Elf_Internal_Rela * rp;
15632 Elf_Internal_Shdr * symsec;
15633 Elf_Internal_Sym * symtab;
26c527e6 15634 uint64_t num_syms;
2cf0635d 15635 Elf_Internal_Sym * sym;
252b5132 15636
41e92641 15637 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15638 || relsec->sh_info >= filedata->file_header.e_shnum
15639 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15640 || relsec->sh_size == 0
dda8d76d 15641 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15642 continue;
428409d5 15643
a788aedd
AM
15644 symsec = filedata->section_headers + relsec->sh_link;
15645 if (symsec->sh_type != SHT_SYMTAB
15646 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15647 return false;
a788aedd 15648
41e92641
NC
15649 is_rela = relsec->sh_type == SHT_RELA;
15650
15651 if (is_rela)
15652 {
dda8d76d 15653 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15654 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15655 return false;
41e92641
NC
15656 }
15657 else
15658 {
dda8d76d 15659 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15660 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15661 return false;
41e92641
NC
15662 }
15663
15664 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15665 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15666 is_rela = false;
428409d5 15667
4de91c10 15668 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15669
41e92641 15670 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15671 {
625d49fc 15672 uint64_t addend;
015dc7e1
AM
15673 unsigned int reloc_type;
15674 unsigned int reloc_size;
15675 bool reloc_inplace = false;
15676 bool reloc_subtract = false;
15677 unsigned char *rloc;
26c527e6 15678 uint64_t sym_index;
4b78141a 15679
dda8d76d 15680 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15681
dda8d76d 15682 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15683 continue;
dda8d76d 15684 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15685 continue;
dda8d76d
NC
15686 else if (is_32bit_abs_reloc (filedata, reloc_type)
15687 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15688 reloc_size = 4;
dda8d76d
NC
15689 else if (is_64bit_abs_reloc (filedata, reloc_type)
15690 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15691 reloc_size = 8;
dda8d76d 15692 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15693 reloc_size = 3;
dda8d76d 15694 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15695 reloc_size = 2;
39e07931
AS
15696 else if (is_8bit_abs_reloc (filedata, reloc_type)
15697 || is_6bit_abs_reloc (filedata, reloc_type))
15698 reloc_size = 1;
03336641
JW
15699 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15700 reloc_type))
15701 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15702 {
15703 reloc_size = 4;
015dc7e1 15704 reloc_inplace = true;
03336641
JW
15705 }
15706 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15707 reloc_type))
15708 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15709 {
15710 reloc_size = 8;
015dc7e1 15711 reloc_inplace = true;
03336641
JW
15712 }
15713 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15714 reloc_type))
15715 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15716 {
15717 reloc_size = 2;
015dc7e1 15718 reloc_inplace = true;
03336641
JW
15719 }
15720 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15721 reloc_type))
15722 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15723 {
15724 reloc_size = 1;
015dc7e1 15725 reloc_inplace = true;
03336641 15726 }
39e07931 15727 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15728 reloc_type))
15729 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15730 {
15731 reloc_size = 1;
015dc7e1 15732 reloc_inplace = true;
39e07931 15733 }
aca88567 15734 else
4b78141a 15735 {
bee0ee85 15736 static unsigned int prev_reloc = 0;
dda8d76d 15737
bee0ee85
NC
15738 if (reloc_type != prev_reloc)
15739 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15740 reloc_type, printable_section_name (filedata, section));
bee0ee85 15741 prev_reloc = reloc_type;
4b78141a
NC
15742 continue;
15743 }
103f02d3 15744
91d6fa6a 15745 rloc = start + rp->r_offset;
75802ccb 15746 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15747 {
26c527e6
AM
15748 warn (_("skipping invalid relocation offset %#" PRIx64
15749 " in section %s\n"),
15750 rp->r_offset,
dda8d76d 15751 printable_section_name (filedata, section));
700dd8b7
L
15752 continue;
15753 }
103f02d3 15754
26c527e6 15755 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15756 if (sym_index >= num_syms)
15757 {
26c527e6
AM
15758 warn (_("skipping invalid relocation symbol index %#" PRIx64
15759 " in section %s\n"),
dda8d76d 15760 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15761 continue;
15762 }
15763 sym = symtab + sym_index;
41e92641
NC
15764
15765 /* If the reloc has a symbol associated with it,
55f25fc3
L
15766 make sure that it is of an appropriate type.
15767
15768 Relocations against symbols without type can happen.
15769 Gcc -feliminate-dwarf2-dups may generate symbols
15770 without type for debug info.
15771
15772 Icc generates relocations against function symbols
15773 instead of local labels.
15774
15775 Relocations against object symbols can happen, eg when
15776 referencing a global array. For an example of this see
15777 the _clz.o binary in libgcc.a. */
aca88567 15778 if (sym != symtab
b8871f35 15779 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15780 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15781 {
26c527e6 15782 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15783 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15784 printable_section_name (filedata, relsec),
26c527e6 15785 rp - relocs);
aca88567 15786 continue;
5b18a4bc 15787 }
252b5132 15788
4dc3c23d
AM
15789 addend = 0;
15790 if (is_rela)
15791 addend += rp->r_addend;
c47320c3
AM
15792 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15793 partial_inplace. */
4dc3c23d 15794 if (!is_rela
dda8d76d 15795 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15796 && reloc_type == 1)
dda8d76d
NC
15797 || ((filedata->file_header.e_machine == EM_PJ
15798 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15799 && reloc_type == 1)
dda8d76d
NC
15800 || ((filedata->file_header.e_machine == EM_D30V
15801 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15802 && reloc_type == 12)
15803 || reloc_inplace)
39e07931
AS
15804 {
15805 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15806 addend += byte_get (rloc, reloc_size) & 0x3f;
15807 else
15808 addend += byte_get (rloc, reloc_size);
15809 }
cb8f3167 15810
dda8d76d
NC
15811 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15812 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15813 {
15814 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15815 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15816 addend -= 8;
91d6fa6a 15817 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15818 reloc_size);
15819 }
39e07931 15820 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15821 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15822 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15823 {
15824 if (reloc_subtract)
15825 addend -= sym->st_value;
15826 else
15827 addend += sym->st_value;
15828 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15829 byte_put (rloc, addend, reloc_size);
15830 }
03336641
JW
15831 else if (reloc_subtract)
15832 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15833 else
91d6fa6a 15834 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15835 }
252b5132 15836
5b18a4bc 15837 free (symtab);
f84ce13b
NC
15838 /* Let the target specific reloc processing code know that
15839 we have finished with these relocs. */
dda8d76d 15840 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15841
15842 if (relocs_return)
15843 {
15844 * (Elf_Internal_Rela **) relocs_return = relocs;
15845 * num_relocs_return = num_relocs;
15846 }
15847 else
15848 free (relocs);
15849
5b18a4bc
NC
15850 break;
15851 }
32ec8896 15852
015dc7e1 15853 return true;
5b18a4bc 15854}
103f02d3 15855
cf13d699 15856#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15857static bool
dda8d76d 15858disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15859{
dda8d76d 15860 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15861
74e1a04b 15862 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15863
015dc7e1 15864 return true;
cf13d699
NC
15865}
15866#endif
15867
15868/* Reads in the contents of SECTION from FILE, returning a pointer
15869 to a malloc'ed buffer or NULL if something went wrong. */
15870
15871static char *
dda8d76d 15872get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15873{
be7d229a 15874 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15875
15876 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15877 {
c6b78c96 15878 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15879 printable_section_name (filedata, section));
cf13d699
NC
15880 return NULL;
15881 }
15882
dda8d76d 15883 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15884 _("section contents"));
cf13d699
NC
15885}
15886
1f5a3546 15887/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15888
015dc7e1 15889static bool
45f5fe46
NC
15890uncompress_section_contents (bool is_zstd,
15891 unsigned char ** buffer,
15892 uint64_t uncompressed_size,
15893 uint64_t * size,
15894 uint64_t file_size)
0e602686 15895{
31e5a3a3
AM
15896 uint64_t compressed_size = *size;
15897 unsigned char *compressed_buffer = *buffer;
45f5fe46 15898 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15899 z_stream strm;
15900 int rc;
15901
45f5fe46
NC
15902 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15903 upper limit of ~10x compression. Any compression larger than that is
15904 thought to be due to fuzzing of the compression header. */
15905 if (uncompressed_size > file_size * 10)
15906 {
15907 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15908 uncompressed_size);
15909 goto fail;
15910 }
15911
15912 uncompressed_buffer = xmalloc (uncompressed_size);
15913
1f5a3546
FS
15914 if (is_zstd)
15915 {
15916#ifdef HAVE_ZSTD
15917 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15918 compressed_buffer, compressed_size);
15919 if (ZSTD_isError (ret))
15920 goto fail;
15921#endif
15922 }
15923 else
15924 {
15925 /* It is possible the section consists of several compressed
15926 buffers concatenated together, so we uncompress in a loop. */
15927 /* PR 18313: The state field in the z_stream structure is supposed
15928 to be invisible to the user (ie us), but some compilers will
15929 still complain about it being used without initialisation. So
15930 we first zero the entire z_stream structure and then set the fields
15931 that we need. */
15932 memset (&strm, 0, sizeof strm);
15933 strm.avail_in = compressed_size;
15934 strm.next_in = (Bytef *)compressed_buffer;
15935 strm.avail_out = uncompressed_size;
15936
15937 rc = inflateInit (&strm);
15938 while (strm.avail_in > 0)
15939 {
15940 if (rc != Z_OK)
15941 break;
15942 strm.next_out = ((Bytef *)uncompressed_buffer
15943 + (uncompressed_size - strm.avail_out));
15944 rc = inflate (&strm, Z_FINISH);
15945 if (rc != Z_STREAM_END)
15946 break;
15947 rc = inflateReset (&strm);
15948 }
15949 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15950 goto fail;
15951 }
0e602686
NC
15952
15953 *buffer = uncompressed_buffer;
15954 *size = uncompressed_size;
015dc7e1 15955 return true;
0e602686
NC
15956
15957 fail:
15958 free (uncompressed_buffer);
15959 /* Indicate decompression failure. */
15960 *buffer = NULL;
015dc7e1 15961 return false;
0e602686 15962}
dd24e3da 15963
015dc7e1 15964static bool
dda8d76d 15965dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15966{
015dc7e1 15967 Elf_Internal_Shdr *relsec;
be7d229a 15968 uint64_t num_bytes;
015dc7e1
AM
15969 unsigned char *data;
15970 unsigned char *end;
15971 unsigned char *real_start;
15972 unsigned char *start;
15973 bool some_strings_shown;
cf13d699 15974
dda8d76d 15975 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15976 if (start == NULL)
c6b78c96 15977 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15978 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15979
0e602686 15980 num_bytes = section->sh_size;
cf13d699 15981
835f2fae
NC
15982 if (filedata->is_separate)
15983 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15984 printable_section_name (filedata, section),
15985 filedata->file_name);
15986 else
15987 printf (_("\nString dump of section '%s':\n"),
15988 printable_section_name (filedata, section));
cf13d699 15989
0e602686
NC
15990 if (decompress_dumps)
15991 {
31e5a3a3
AM
15992 uint64_t new_size = num_bytes;
15993 uint64_t uncompressed_size = 0;
1f5a3546 15994 bool is_zstd = false;
0e602686
NC
15995
15996 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15997 {
15998 Elf_Internal_Chdr chdr;
15999 unsigned int compression_header_size
ebdf1ebf
NC
16000 = get_compression_header (& chdr, (unsigned char *) start,
16001 num_bytes);
5844b465
NC
16002 if (compression_header_size == 0)
16003 /* An error message will have already been generated
16004 by get_compression_header. */
16005 goto error_out;
0e602686 16006
89dbeac7 16007 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16008 ;
16009#ifdef HAVE_ZSTD
89dbeac7 16010 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16011 is_zstd = true;
16012#endif
16013 else
0e602686 16014 {
813dabb9 16015 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16016 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16017 goto error_out;
813dabb9 16018 }
813dabb9
L
16019 uncompressed_size = chdr.ch_size;
16020 start += compression_header_size;
16021 new_size -= compression_header_size;
0e602686
NC
16022 }
16023 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16024 {
16025 /* Read the zlib header. In this case, it should be "ZLIB"
16026 followed by the uncompressed section size, 8 bytes in
16027 big-endian order. */
16028 uncompressed_size = start[4]; uncompressed_size <<= 8;
16029 uncompressed_size += start[5]; uncompressed_size <<= 8;
16030 uncompressed_size += start[6]; uncompressed_size <<= 8;
16031 uncompressed_size += start[7]; uncompressed_size <<= 8;
16032 uncompressed_size += start[8]; uncompressed_size <<= 8;
16033 uncompressed_size += start[9]; uncompressed_size <<= 8;
16034 uncompressed_size += start[10]; uncompressed_size <<= 8;
16035 uncompressed_size += start[11];
16036 start += 12;
16037 new_size -= 12;
16038 }
16039
1835f746
NC
16040 if (uncompressed_size)
16041 {
1f5a3546 16042 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16043 &new_size, filedata->file_size))
1835f746
NC
16044 num_bytes = new_size;
16045 else
16046 {
16047 error (_("Unable to decompress section %s\n"),
dda8d76d 16048 printable_section_name (filedata, section));
f761cb13 16049 goto error_out;
1835f746
NC
16050 }
16051 }
bc303e5d
NC
16052 else
16053 start = real_start;
0e602686 16054 }
fd8008d8 16055
cf13d699
NC
16056 /* If the section being dumped has relocations against it the user might
16057 be expecting these relocations to have been applied. Check for this
16058 case and issue a warning message in order to avoid confusion.
16059 FIXME: Maybe we ought to have an option that dumps a section with
16060 relocs applied ? */
dda8d76d
NC
16061 for (relsec = filedata->section_headers;
16062 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16063 ++relsec)
16064 {
16065 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16066 || relsec->sh_info >= filedata->file_header.e_shnum
16067 || filedata->section_headers + relsec->sh_info != section
cf13d699 16068 || relsec->sh_size == 0
dda8d76d 16069 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16070 continue;
16071
16072 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16073 break;
16074 }
16075
cf13d699
NC
16076 data = start;
16077 end = start + num_bytes;
015dc7e1 16078 some_strings_shown = false;
cf13d699 16079
ba3265d0
NC
16080#ifdef HAVE_MBSTATE_T
16081 mbstate_t state;
16082 /* Initialise the multibyte conversion state. */
16083 memset (& state, 0, sizeof (state));
16084#endif
16085
015dc7e1 16086 bool continuing = false;
ba3265d0 16087
cf13d699
NC
16088 while (data < end)
16089 {
16090 while (!ISPRINT (* data))
16091 if (++ data >= end)
16092 break;
16093
16094 if (data < end)
16095 {
071436c6
NC
16096 size_t maxlen = end - data;
16097
ba3265d0
NC
16098 if (continuing)
16099 {
16100 printf (" ");
015dc7e1 16101 continuing = false;
ba3265d0
NC
16102 }
16103 else
16104 {
26c527e6 16105 printf (" [%6tx] ", data - start);
ba3265d0
NC
16106 }
16107
4082ef84
NC
16108 if (maxlen > 0)
16109 {
f3da8a96 16110 char c = 0;
ba3265d0
NC
16111
16112 while (maxlen)
16113 {
16114 c = *data++;
16115
16116 if (c == 0)
16117 break;
16118
16119 /* PR 25543: Treat new-lines as string-ending characters. */
16120 if (c == '\n')
16121 {
16122 printf ("\\n\n");
16123 if (*data != 0)
015dc7e1 16124 continuing = true;
ba3265d0
NC
16125 break;
16126 }
16127
16128 /* Do not print control characters directly as they can affect terminal
16129 settings. Such characters usually appear in the names generated
16130 by the assembler for local labels. */
16131 if (ISCNTRL (c))
16132 {
16133 printf ("^%c", c + 0x40);
16134 }
16135 else if (ISPRINT (c))
16136 {
16137 putchar (c);
16138 }
16139 else
16140 {
16141 size_t n;
16142#ifdef HAVE_MBSTATE_T
16143 wchar_t w;
16144#endif
16145 /* Let printf do the hard work of displaying multibyte characters. */
16146 printf ("%.1s", data - 1);
16147#ifdef HAVE_MBSTATE_T
16148 /* Try to find out how many bytes made up the character that was
16149 just printed. Advance the symbol pointer past the bytes that
16150 were displayed. */
16151 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16152#else
16153 n = 1;
16154#endif
16155 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16156 data += (n - 1);
16157 }
16158 }
16159
16160 if (c != '\n')
16161 putchar ('\n');
4082ef84
NC
16162 }
16163 else
16164 {
16165 printf (_("<corrupt>\n"));
16166 data = end;
16167 }
015dc7e1 16168 some_strings_shown = true;
cf13d699
NC
16169 }
16170 }
16171
16172 if (! some_strings_shown)
16173 printf (_(" No strings found in this section."));
16174
0e602686 16175 free (real_start);
cf13d699
NC
16176
16177 putchar ('\n');
015dc7e1 16178 return true;
f761cb13
AM
16179
16180error_out:
16181 free (real_start);
015dc7e1 16182 return false;
cf13d699
NC
16183}
16184
015dc7e1
AM
16185static bool
16186dump_section_as_bytes (Elf_Internal_Shdr *section,
16187 Filedata *filedata,
16188 bool relocate)
cf13d699 16189{
be7d229a
AM
16190 Elf_Internal_Shdr *relsec;
16191 size_t bytes;
16192 uint64_t section_size;
625d49fc 16193 uint64_t addr;
be7d229a
AM
16194 unsigned char *data;
16195 unsigned char *real_start;
16196 unsigned char *start;
0e602686 16197
dda8d76d 16198 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16199 if (start == NULL)
c6b78c96 16200 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16201 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16202
0e602686 16203 section_size = section->sh_size;
cf13d699 16204
835f2fae
NC
16205 if (filedata->is_separate)
16206 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16207 printable_section_name (filedata, section),
16208 filedata->file_name);
16209 else
16210 printf (_("\nHex dump of section '%s':\n"),
16211 printable_section_name (filedata, section));
cf13d699 16212
0e602686
NC
16213 if (decompress_dumps)
16214 {
31e5a3a3
AM
16215 uint64_t new_size = section_size;
16216 uint64_t uncompressed_size = 0;
1f5a3546 16217 bool is_zstd = false;
0e602686
NC
16218
16219 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16220 {
16221 Elf_Internal_Chdr chdr;
16222 unsigned int compression_header_size
ebdf1ebf 16223 = get_compression_header (& chdr, start, section_size);
0e602686 16224
5844b465
NC
16225 if (compression_header_size == 0)
16226 /* An error message will have already been generated
16227 by get_compression_header. */
16228 goto error_out;
16229
89dbeac7 16230 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16231 ;
16232#ifdef HAVE_ZSTD
89dbeac7 16233 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16234 is_zstd = true;
16235#endif
16236 else
0e602686 16237 {
813dabb9 16238 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16239 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16240 goto error_out;
0e602686 16241 }
813dabb9
L
16242 uncompressed_size = chdr.ch_size;
16243 start += compression_header_size;
16244 new_size -= compression_header_size;
0e602686
NC
16245 }
16246 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16247 {
16248 /* Read the zlib header. In this case, it should be "ZLIB"
16249 followed by the uncompressed section size, 8 bytes in
16250 big-endian order. */
16251 uncompressed_size = start[4]; uncompressed_size <<= 8;
16252 uncompressed_size += start[5]; uncompressed_size <<= 8;
16253 uncompressed_size += start[6]; uncompressed_size <<= 8;
16254 uncompressed_size += start[7]; uncompressed_size <<= 8;
16255 uncompressed_size += start[8]; uncompressed_size <<= 8;
16256 uncompressed_size += start[9]; uncompressed_size <<= 8;
16257 uncompressed_size += start[10]; uncompressed_size <<= 8;
16258 uncompressed_size += start[11];
16259 start += 12;
16260 new_size -= 12;
16261 }
16262
f055032e
NC
16263 if (uncompressed_size)
16264 {
1f5a3546 16265 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16266 &new_size, filedata->file_size))
bc303e5d
NC
16267 {
16268 section_size = new_size;
16269 }
f055032e
NC
16270 else
16271 {
16272 error (_("Unable to decompress section %s\n"),
dda8d76d 16273 printable_section_name (filedata, section));
bc303e5d 16274 /* FIXME: Print the section anyway ? */
f761cb13 16275 goto error_out;
f055032e
NC
16276 }
16277 }
bc303e5d
NC
16278 else
16279 start = real_start;
0e602686 16280 }
14ae95f2 16281
cf13d699
NC
16282 if (relocate)
16283 {
dda8d76d 16284 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 16285 goto error_out;
cf13d699
NC
16286 }
16287 else
16288 {
16289 /* If the section being dumped has relocations against it the user might
16290 be expecting these relocations to have been applied. Check for this
16291 case and issue a warning message in order to avoid confusion.
16292 FIXME: Maybe we ought to have an option that dumps a section with
16293 relocs applied ? */
dda8d76d
NC
16294 for (relsec = filedata->section_headers;
16295 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16296 ++relsec)
16297 {
16298 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16299 || relsec->sh_info >= filedata->file_header.e_shnum
16300 || filedata->section_headers + relsec->sh_info != section
cf13d699 16301 || relsec->sh_size == 0
dda8d76d 16302 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16303 continue;
16304
16305 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16306 break;
16307 }
16308 }
16309
16310 addr = section->sh_addr;
0e602686 16311 bytes = section_size;
cf13d699
NC
16312 data = start;
16313
16314 while (bytes)
16315 {
16316 int j;
16317 int k;
16318 int lbytes;
16319
16320 lbytes = (bytes > 16 ? 16 : bytes);
16321
26c527e6 16322 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16323
16324 for (j = 0; j < 16; j++)
16325 {
16326 if (j < lbytes)
16327 printf ("%2.2x", data[j]);
16328 else
16329 printf (" ");
16330
16331 if ((j & 3) == 3)
16332 printf (" ");
16333 }
16334
16335 for (j = 0; j < lbytes; j++)
16336 {
16337 k = data[j];
16338 if (k >= ' ' && k < 0x7f)
16339 printf ("%c", k);
16340 else
16341 printf (".");
16342 }
16343
16344 putchar ('\n');
16345
16346 data += lbytes;
16347 addr += lbytes;
16348 bytes -= lbytes;
16349 }
16350
0e602686 16351 free (real_start);
cf13d699
NC
16352
16353 putchar ('\n');
015dc7e1 16354 return true;
f761cb13
AM
16355
16356 error_out:
16357 free (real_start);
015dc7e1 16358 return false;
cf13d699
NC
16359}
16360
094e34f2 16361#ifdef ENABLE_LIBCTF
7d9813f1
NA
16362static ctf_sect_t *
16363shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16364{
b6ac461a 16365 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16366 buf->cts_size = shdr->sh_size;
16367 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16368
16369 return buf;
16370}
16371
16372/* Formatting callback function passed to ctf_dump. Returns either the pointer
16373 it is passed, or a pointer to newly-allocated storage, in which case
16374 dump_ctf() will free it when it no longer needs it. */
16375
2f6ecaed
NA
16376static char *
16377dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16378 char *s, void *arg)
7d9813f1 16379{
3e50a591 16380 const char *blanks = arg;
7d9813f1
NA
16381 char *new_s;
16382
3e50a591 16383 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16384 return s;
16385 return new_s;
16386}
16387
926c9e76
NA
16388/* Dump CTF errors/warnings. */
16389static void
139633c3 16390dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16391{
16392 ctf_next_t *it = NULL;
16393 char *errtext;
16394 int is_warning;
16395 int err;
16396
16397 /* Dump accumulated errors and warnings. */
16398 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16399 {
5e9b84f7 16400 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16401 errtext);
16402 free (errtext);
16403 }
16404 if (err != ECTF_NEXT_END)
16405 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16406}
16407
2f6ecaed
NA
16408/* Dump one CTF archive member. */
16409
80b56fad
NA
16410static void
16411dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16412 size_t member)
2f6ecaed 16413{
2f6ecaed
NA
16414 const char *things[] = {"Header", "Labels", "Data objects",
16415 "Function objects", "Variables", "Types", "Strings",
16416 ""};
16417 const char **thing;
16418 size_t i;
16419
80b56fad
NA
16420 /* Don't print out the name of the default-named archive member if it appears
16421 first in the list. The name .ctf appears everywhere, even for things that
16422 aren't really archives, so printing it out is liable to be confusing; also,
16423 the common case by far is for only one archive member to exist, and hiding
16424 it in that case seems worthwhile. */
2f6ecaed 16425
80b56fad
NA
16426 if (strcmp (name, ".ctf") != 0 || member != 0)
16427 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16428
80b56fad
NA
16429 if (ctf_parent_name (ctf) != NULL)
16430 ctf_import (ctf, parent);
2f6ecaed
NA
16431
16432 for (i = 0, thing = things; *thing[0]; thing++, i++)
16433 {
16434 ctf_dump_state_t *s = NULL;
16435 char *item;
16436
16437 printf ("\n %s:\n", *thing);
16438 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16439 (void *) " ")) != NULL)
16440 {
16441 printf ("%s\n", item);
16442 free (item);
16443 }
16444
16445 if (ctf_errno (ctf))
16446 {
16447 error (_("Iteration failed: %s, %s\n"), *thing,
16448 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16449 break;
2f6ecaed
NA
16450 }
16451 }
8b37e7b6 16452
926c9e76 16453 dump_ctf_errs (ctf);
2f6ecaed
NA
16454}
16455
015dc7e1 16456static bool
7d9813f1
NA
16457dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16458{
7d9813f1
NA
16459 Elf_Internal_Shdr * symtab_sec = NULL;
16460 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16461 void * data = NULL;
16462 void * symdata = NULL;
16463 void * strdata = NULL;
80b56fad 16464 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16465 ctf_sect_t * symsectp = NULL;
16466 ctf_sect_t * strsectp = NULL;
2f6ecaed 16467 ctf_archive_t * ctfa = NULL;
139633c3 16468 ctf_dict_t * parent = NULL;
80b56fad 16469 ctf_dict_t * fp;
7d9813f1 16470
80b56fad
NA
16471 ctf_next_t *i = NULL;
16472 const char *name;
16473 size_t member = 0;
7d9813f1 16474 int err;
015dc7e1 16475 bool ret = false;
7d9813f1
NA
16476
16477 shdr_to_ctf_sect (&ctfsect, section, filedata);
16478 data = get_section_contents (section, filedata);
16479 ctfsect.cts_data = data;
16480
616febde 16481 if (!dump_ctf_symtab_name)
3d16b64e 16482 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16483
16484 if (!dump_ctf_strtab_name)
3d16b64e 16485 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16486
16487 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16488 {
16489 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16490 {
16491 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16492 goto fail;
16493 }
16494 if ((symdata = (void *) get_data (NULL, filedata,
16495 symtab_sec->sh_offset, 1,
16496 symtab_sec->sh_size,
16497 _("symbols"))) == NULL)
16498 goto fail;
16499 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16500 symsect.cts_data = symdata;
16501 }
835f2fae 16502
df16e041 16503 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16504 {
16505 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16506 {
16507 error (_("No string table section named %s\n"),
16508 dump_ctf_strtab_name);
16509 goto fail;
16510 }
16511 if ((strdata = (void *) get_data (NULL, filedata,
16512 strtab_sec->sh_offset, 1,
16513 strtab_sec->sh_size,
16514 _("strings"))) == NULL)
16515 goto fail;
16516 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16517 strsect.cts_data = strdata;
16518 }
835f2fae 16519
2f6ecaed
NA
16520 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16521 libctf papers over the difference, so we can pretend it is always an
80b56fad 16522 archive. */
7d9813f1 16523
2f6ecaed 16524 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16525 {
926c9e76 16526 dump_ctf_errs (NULL);
7d9813f1
NA
16527 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16528 goto fail;
16529 }
16530
96c61be5
NA
16531 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16532 != ELFDATA2MSB);
16533
80b56fad
NA
16534 /* Preload the parent dict, since it will need to be imported into every
16535 child in turn. */
16536 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16537 {
926c9e76 16538 dump_ctf_errs (NULL);
2f6ecaed
NA
16539 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16540 goto fail;
7d9813f1
NA
16541 }
16542
015dc7e1 16543 ret = true;
7d9813f1 16544
835f2fae
NC
16545 if (filedata->is_separate)
16546 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16547 printable_section_name (filedata, section),
16548 filedata->file_name);
16549 else
16550 printf (_("\nDump of CTF section '%s':\n"),
16551 printable_section_name (filedata, section));
7d9813f1 16552
80b56fad
NA
16553 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16554 dump_ctf_archive_member (fp, name, parent, member++);
16555 if (err != ECTF_NEXT_END)
16556 {
16557 dump_ctf_errs (NULL);
16558 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16559 ret = false;
16560 }
7d9813f1
NA
16561
16562 fail:
139633c3 16563 ctf_dict_close (parent);
2f6ecaed 16564 ctf_close (ctfa);
7d9813f1
NA
16565 free (data);
16566 free (symdata);
16567 free (strdata);
16568 return ret;
16569}
094e34f2 16570#endif
7d9813f1 16571
42b6953b
IB
16572static bool
16573dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16574{
16575 void * data = NULL;
16576 sframe_decoder_ctx *sfd_ctx = NULL;
16577 const char *print_name = printable_section_name (filedata, section);
16578
16579 bool ret = true;
16580 size_t sf_size;
16581 int err = 0;
16582
16583 if (strcmp (print_name, "") == 0)
16584 {
16585 error (_("Section name must be provided \n"));
16586 ret = false;
16587 return ret;
16588 }
16589
16590 data = get_section_contents (section, filedata);
16591 sf_size = section->sh_size;
16592 /* Decode the contents of the section. */
16593 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16594 if (!sfd_ctx)
16595 {
16596 ret = false;
16597 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16598 goto fail;
16599 }
16600
16601 printf (_("Contents of the SFrame section %s:"), print_name);
16602 /* Dump the contents as text. */
16603 dump_sframe (sfd_ctx, section->sh_addr);
16604
16605 fail:
16606 free (data);
16607 return ret;
16608}
16609
015dc7e1 16610static bool
dda8d76d
NC
16611load_specific_debug_section (enum dwarf_section_display_enum debug,
16612 const Elf_Internal_Shdr * sec,
16613 void * data)
1007acb3 16614{
2cf0635d 16615 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16616 char buf [64];
dda8d76d 16617 Filedata * filedata = (Filedata *) data;
9abca702 16618
19e6b90e 16619 if (section->start != NULL)
dda8d76d
NC
16620 {
16621 /* If it is already loaded, do nothing. */
16622 if (streq (section->filename, filedata->file_name))
015dc7e1 16623 return true;
dda8d76d
NC
16624 free (section->start);
16625 }
1007acb3 16626
19e6b90e
L
16627 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16628 section->address = sec->sh_addr;
dda8d76d
NC
16629 section->filename = filedata->file_name;
16630 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16631 sec->sh_offset, 1,
16632 sec->sh_size, buf);
59245841
NC
16633 if (section->start == NULL)
16634 section->size = 0;
16635 else
16636 {
77115a4a 16637 unsigned char *start = section->start;
31e5a3a3
AM
16638 uint64_t size = sec->sh_size;
16639 uint64_t uncompressed_size = 0;
1f5a3546 16640 bool is_zstd = false;
77115a4a
L
16641
16642 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16643 {
16644 Elf_Internal_Chdr chdr;
d8024a91
NC
16645 unsigned int compression_header_size;
16646
f53be977
L
16647 if (size < (is_32bit_elf
16648 ? sizeof (Elf32_External_Chdr)
16649 : sizeof (Elf64_External_Chdr)))
d8024a91 16650 {
55be8fd0 16651 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16652 section->name);
015dc7e1 16653 return false;
d8024a91
NC
16654 }
16655
ebdf1ebf 16656 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16657 if (compression_header_size == 0)
16658 /* An error message will have already been generated
16659 by get_compression_header. */
015dc7e1 16660 return false;
d8024a91 16661
89dbeac7 16662 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16663 ;
16664#ifdef HAVE_ZSTD
89dbeac7 16665 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16666 is_zstd = true;
16667#endif
16668 else
813dabb9
L
16669 {
16670 warn (_("section '%s' has unsupported compress type: %d\n"),
16671 section->name, chdr.ch_type);
015dc7e1 16672 return false;
813dabb9 16673 }
dab394de 16674 uncompressed_size = chdr.ch_size;
77115a4a
L
16675 start += compression_header_size;
16676 size -= compression_header_size;
16677 }
dab394de
L
16678 else if (size > 12 && streq ((char *) start, "ZLIB"))
16679 {
16680 /* Read the zlib header. In this case, it should be "ZLIB"
16681 followed by the uncompressed section size, 8 bytes in
16682 big-endian order. */
16683 uncompressed_size = start[4]; uncompressed_size <<= 8;
16684 uncompressed_size += start[5]; uncompressed_size <<= 8;
16685 uncompressed_size += start[6]; uncompressed_size <<= 8;
16686 uncompressed_size += start[7]; uncompressed_size <<= 8;
16687 uncompressed_size += start[8]; uncompressed_size <<= 8;
16688 uncompressed_size += start[9]; uncompressed_size <<= 8;
16689 uncompressed_size += start[10]; uncompressed_size <<= 8;
16690 uncompressed_size += start[11];
16691 start += 12;
16692 size -= 12;
16693 }
16694
1835f746 16695 if (uncompressed_size)
77115a4a 16696 {
1f5a3546 16697 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16698 &size, filedata->file_size))
1835f746
NC
16699 {
16700 /* Free the compressed buffer, update the section buffer
16701 and the section size if uncompress is successful. */
16702 free (section->start);
16703 section->start = start;
16704 }
16705 else
16706 {
16707 error (_("Unable to decompress section %s\n"),
dda8d76d 16708 printable_section_name (filedata, sec));
015dc7e1 16709 return false;
1835f746 16710 }
77115a4a 16711 }
bc303e5d 16712
77115a4a 16713 section->size = size;
59245841 16714 }
4a114e3e 16715
1b315056 16716 if (section->start == NULL)
015dc7e1 16717 return false;
1b315056 16718
19e6b90e 16719 if (debug_displays [debug].relocate)
32ec8896 16720 {
dda8d76d 16721 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16722 & section->reloc_info, & section->num_relocs))
015dc7e1 16723 return false;
32ec8896 16724 }
d1c4b12b
NC
16725 else
16726 {
16727 section->reloc_info = NULL;
16728 section->num_relocs = 0;
16729 }
1007acb3 16730
015dc7e1 16731 return true;
1007acb3
L
16732}
16733
301a9420
AM
16734#if HAVE_LIBDEBUGINFOD
16735/* Return a hex string representation of the build-id. */
16736unsigned char *
16737get_build_id (void * data)
16738{
ca0e11aa 16739 Filedata * filedata = (Filedata *) data;
301a9420 16740 Elf_Internal_Shdr * shdr;
26c527e6 16741 size_t i;
301a9420 16742
55be8fd0
NC
16743 /* Iterate through notes to find note.gnu.build-id.
16744 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16745 for (i = 0, shdr = filedata->section_headers;
16746 i < filedata->file_header.e_shnum && shdr != NULL;
16747 i++, shdr++)
16748 {
16749 if (shdr->sh_type != SHT_NOTE)
16750 continue;
16751
16752 char * next;
16753 char * end;
16754 size_t data_remaining;
16755 size_t min_notesz;
16756 Elf_External_Note * enote;
16757 Elf_Internal_Note inote;
16758
625d49fc
AM
16759 uint64_t offset = shdr->sh_offset;
16760 uint64_t align = shdr->sh_addralign;
16761 uint64_t length = shdr->sh_size;
301a9420
AM
16762
16763 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16764 if (enote == NULL)
16765 continue;
16766
16767 if (align < 4)
16768 align = 4;
16769 else if (align != 4 && align != 8)
f761cb13
AM
16770 {
16771 free (enote);
16772 continue;
16773 }
301a9420
AM
16774
16775 end = (char *) enote + length;
16776 data_remaining = end - (char *) enote;
16777
16778 if (!is_ia64_vms (filedata))
16779 {
16780 min_notesz = offsetof (Elf_External_Note, name);
16781 if (data_remaining < min_notesz)
16782 {
55be8fd0
NC
16783 warn (_("\
16784malformed note encountered in section %s whilst scanning for build-id note\n"),
16785 printable_section_name (filedata, shdr));
f761cb13 16786 free (enote);
55be8fd0 16787 continue;
301a9420
AM
16788 }
16789 data_remaining -= min_notesz;
16790
16791 inote.type = BYTE_GET (enote->type);
16792 inote.namesz = BYTE_GET (enote->namesz);
16793 inote.namedata = enote->name;
16794 inote.descsz = BYTE_GET (enote->descsz);
16795 inote.descdata = ((char *) enote
16796 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16797 inote.descpos = offset + (inote.descdata - (char *) enote);
16798 next = ((char *) enote
16799 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16800 }
16801 else
16802 {
16803 Elf64_External_VMS_Note *vms_enote;
16804
16805 /* PR binutils/15191
16806 Make sure that there is enough data to read. */
16807 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16808 if (data_remaining < min_notesz)
16809 {
55be8fd0
NC
16810 warn (_("\
16811malformed note encountered in section %s whilst scanning for build-id note\n"),
16812 printable_section_name (filedata, shdr));
f761cb13 16813 free (enote);
55be8fd0 16814 continue;
301a9420
AM
16815 }
16816 data_remaining -= min_notesz;
16817
16818 vms_enote = (Elf64_External_VMS_Note *) enote;
16819 inote.type = BYTE_GET (vms_enote->type);
16820 inote.namesz = BYTE_GET (vms_enote->namesz);
16821 inote.namedata = vms_enote->name;
16822 inote.descsz = BYTE_GET (vms_enote->descsz);
16823 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16824 inote.descpos = offset + (inote.descdata - (char *) enote);
16825 next = inote.descdata + align_power (inote.descsz, 3);
16826 }
16827
16828 /* Skip malformed notes. */
16829 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16830 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16831 || (size_t) (next - inote.descdata) < inote.descsz
16832 || ((size_t) (next - inote.descdata)
16833 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16834 {
55be8fd0
NC
16835 warn (_("\
16836malformed note encountered in section %s whilst scanning for build-id note\n"),
16837 printable_section_name (filedata, shdr));
f761cb13 16838 free (enote);
301a9420
AM
16839 continue;
16840 }
16841
16842 /* Check if this is the build-id note. If so then convert the build-id
16843 bytes to a hex string. */
16844 if (inote.namesz > 0
24d127aa 16845 && startswith (inote.namedata, "GNU")
301a9420
AM
16846 && inote.type == NT_GNU_BUILD_ID)
16847 {
26c527e6 16848 size_t j;
301a9420
AM
16849 char * build_id;
16850
16851 build_id = malloc (inote.descsz * 2 + 1);
16852 if (build_id == NULL)
f761cb13
AM
16853 {
16854 free (enote);
16855 return NULL;
16856 }
301a9420
AM
16857
16858 for (j = 0; j < inote.descsz; ++j)
16859 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16860 build_id[inote.descsz * 2] = '\0';
f761cb13 16861 free (enote);
301a9420 16862
55be8fd0 16863 return (unsigned char *) build_id;
301a9420 16864 }
f761cb13 16865 free (enote);
301a9420
AM
16866 }
16867
16868 return NULL;
16869}
16870#endif /* HAVE_LIBDEBUGINFOD */
16871
657d0d47
CC
16872/* If this is not NULL, load_debug_section will only look for sections
16873 within the list of sections given here. */
32ec8896 16874static unsigned int * section_subset = NULL;
657d0d47 16875
015dc7e1 16876bool
dda8d76d 16877load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16878{
2cf0635d
NC
16879 struct dwarf_section * section = &debug_displays [debug].section;
16880 Elf_Internal_Shdr * sec;
dda8d76d
NC
16881 Filedata * filedata = (Filedata *) data;
16882
e1dbfc17
L
16883 if (!dump_any_debugging)
16884 return false;
16885
f425ec66
NC
16886 /* Without section headers we cannot find any sections. */
16887 if (filedata->section_headers == NULL)
015dc7e1 16888 return false;
f425ec66 16889
9c1ce108
AM
16890 if (filedata->string_table == NULL
16891 && filedata->file_header.e_shstrndx != SHN_UNDEF
16892 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16893 {
16894 Elf_Internal_Shdr * strs;
16895
16896 /* Read in the string table, so that we have section names to scan. */
16897 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16898
4dff97b2 16899 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16900 {
9c1ce108
AM
16901 filedata->string_table
16902 = (char *) get_data (NULL, filedata, strs->sh_offset,
16903 1, strs->sh_size, _("string table"));
dda8d76d 16904
9c1ce108
AM
16905 filedata->string_table_length
16906 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16907 }
16908 }
d966045b
DJ
16909
16910 /* Locate the debug section. */
dda8d76d 16911 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16912 if (sec != NULL)
16913 section->name = section->uncompressed_name;
16914 else
16915 {
dda8d76d 16916 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16917 if (sec != NULL)
16918 section->name = section->compressed_name;
16919 }
16920 if (sec == NULL)
015dc7e1 16921 return false;
d966045b 16922
657d0d47
CC
16923 /* If we're loading from a subset of sections, and we've loaded
16924 a section matching this name before, it's likely that it's a
16925 different one. */
16926 if (section_subset != NULL)
16927 free_debug_section (debug);
16928
dda8d76d 16929 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16930}
16931
19e6b90e
L
16932void
16933free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16934{
2cf0635d 16935 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16936
19e6b90e
L
16937 if (section->start == NULL)
16938 return;
1007acb3 16939
19e6b90e
L
16940 free ((char *) section->start);
16941 section->start = NULL;
16942 section->address = 0;
16943 section->size = 0;
a788aedd 16944
9db70fc3
AM
16945 free (section->reloc_info);
16946 section->reloc_info = NULL;
16947 section->num_relocs = 0;
1007acb3
L
16948}
16949
015dc7e1 16950static bool
dda8d76d 16951display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16952{
84714f86
AM
16953 const char *name = (section_name_valid (filedata, section)
16954 ? section_name (filedata, section) : "");
16955 const char *print_name = printable_section_name (filedata, section);
be7d229a 16956 uint64_t length;
015dc7e1 16957 bool result = true;
3f5e193b 16958 int i;
1007acb3 16959
19e6b90e
L
16960 length = section->sh_size;
16961 if (length == 0)
1007acb3 16962 {
74e1a04b 16963 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16964 return true;
1007acb3 16965 }
5dff79d8
NC
16966 if (section->sh_type == SHT_NOBITS)
16967 {
16968 /* There is no point in dumping the contents of a debugging section
16969 which has the NOBITS type - the bits in the file will be random.
16970 This can happen when a file containing a .eh_frame section is
16971 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16972 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16973 print_name);
015dc7e1 16974 return false;
5dff79d8 16975 }
1007acb3 16976
24d127aa 16977 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16978 name = ".debug_info";
1007acb3 16979
19e6b90e
L
16980 /* See if we know how to display the contents of this section. */
16981 for (i = 0; i < max; i++)
d85bf2ba
NC
16982 {
16983 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16984 struct dwarf_section_display * display = debug_displays + i;
16985 struct dwarf_section * sec = & display->section;
d966045b 16986
d85bf2ba 16987 if (streq (sec->uncompressed_name, name)
24d127aa 16988 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16989 || streq (sec->compressed_name, name))
16990 {
015dc7e1 16991 bool secondary = (section != find_section (filedata, name));
1007acb3 16992
d85bf2ba
NC
16993 if (secondary)
16994 free_debug_section (id);
dda8d76d 16995
24d127aa 16996 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16997 sec->name = name;
16998 else if (streq (sec->uncompressed_name, name))
16999 sec->name = sec->uncompressed_name;
17000 else
17001 sec->name = sec->compressed_name;
657d0d47 17002
d85bf2ba
NC
17003 if (load_specific_debug_section (id, section, filedata))
17004 {
17005 /* If this debug section is part of a CU/TU set in a .dwp file,
17006 restrict load_debug_section to the sections in that set. */
17007 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17008
d85bf2ba 17009 result &= display->display (sec, filedata);
657d0d47 17010
d85bf2ba 17011 section_subset = NULL;
1007acb3 17012
44266f36 17013 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17014 free_debug_section (id);
17015 }
17016 break;
17017 }
17018 }
1007acb3 17019
19e6b90e 17020 if (i == max)
1007acb3 17021 {
74e1a04b 17022 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17023 result = false;
1007acb3
L
17024 }
17025
19e6b90e 17026 return result;
5b18a4bc 17027}
103f02d3 17028
aef1f6d0
DJ
17029/* Set DUMP_SECTS for all sections where dumps were requested
17030 based on section name. */
17031
17032static void
dda8d76d 17033initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17034{
2cf0635d 17035 struct dump_list_entry * cur;
aef1f6d0
DJ
17036
17037 for (cur = dump_sects_byname; cur; cur = cur->next)
17038 {
17039 unsigned int i;
015dc7e1 17040 bool any = false;
aef1f6d0 17041
dda8d76d 17042 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17043 if (section_name_valid (filedata, filedata->section_headers + i)
17044 && streq (section_name (filedata, filedata->section_headers + i),
17045 cur->name))
aef1f6d0 17046 {
6431e409 17047 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17048 any = true;
aef1f6d0
DJ
17049 }
17050
835f2fae
NC
17051 if (!any && !filedata->is_separate)
17052 warn (_("Section '%s' was not dumped because it does not exist\n"),
17053 cur->name);
aef1f6d0
DJ
17054 }
17055}
17056
015dc7e1 17057static bool
dda8d76d 17058process_section_contents (Filedata * filedata)
5b18a4bc 17059{
2cf0635d 17060 Elf_Internal_Shdr * section;
19e6b90e 17061 unsigned int i;
015dc7e1 17062 bool res = true;
103f02d3 17063
19e6b90e 17064 if (! do_dump)
015dc7e1 17065 return true;
103f02d3 17066
dda8d76d 17067 initialise_dumps_byname (filedata);
aef1f6d0 17068
dda8d76d 17069 for (i = 0, section = filedata->section_headers;
6431e409 17070 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17071 i++, section++)
17072 {
6431e409 17073 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17074
d6bfbc39
NC
17075 if (filedata->is_separate && ! process_links)
17076 dump &= DEBUG_DUMP;
047c3dbf 17077
19e6b90e 17078#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17079 if (dump & DISASS_DUMP)
17080 {
17081 if (! disassemble_section (section, filedata))
015dc7e1 17082 res = false;
dda8d76d 17083 }
19e6b90e 17084#endif
dda8d76d 17085 if (dump & HEX_DUMP)
32ec8896 17086 {
015dc7e1
AM
17087 if (! dump_section_as_bytes (section, filedata, false))
17088 res = false;
32ec8896 17089 }
103f02d3 17090
dda8d76d 17091 if (dump & RELOC_DUMP)
32ec8896 17092 {
015dc7e1
AM
17093 if (! dump_section_as_bytes (section, filedata, true))
17094 res = false;
32ec8896 17095 }
09c11c86 17096
dda8d76d 17097 if (dump & STRING_DUMP)
32ec8896 17098 {
dda8d76d 17099 if (! dump_section_as_strings (section, filedata))
015dc7e1 17100 res = false;
32ec8896 17101 }
cf13d699 17102
dda8d76d 17103 if (dump & DEBUG_DUMP)
32ec8896 17104 {
dda8d76d 17105 if (! display_debug_section (i, section, filedata))
015dc7e1 17106 res = false;
32ec8896 17107 }
7d9813f1 17108
094e34f2 17109#ifdef ENABLE_LIBCTF
7d9813f1
NA
17110 if (dump & CTF_DUMP)
17111 {
17112 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17113 res = false;
7d9813f1 17114 }
094e34f2 17115#endif
42b6953b
IB
17116 if (dump & SFRAME_DUMP)
17117 {
17118 if (! dump_section_as_sframe (section, filedata))
17119 res = false;
17120 }
5b18a4bc 17121 }
103f02d3 17122
835f2fae 17123 if (! filedata->is_separate)
0ee3043f 17124 {
835f2fae
NC
17125 /* Check to see if the user requested a
17126 dump of a section that does not exist. */
17127 for (; i < filedata->dump.num_dump_sects; i++)
17128 if (filedata->dump.dump_sects[i])
17129 {
ca0e11aa 17130 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17131 res = false;
835f2fae 17132 }
0ee3043f 17133 }
32ec8896
NC
17134
17135 return res;
5b18a4bc 17136}
103f02d3 17137
5b18a4bc 17138static void
19e6b90e 17139process_mips_fpe_exception (int mask)
5b18a4bc 17140{
19e6b90e
L
17141 if (mask)
17142 {
015dc7e1 17143 bool first = true;
32ec8896 17144
19e6b90e 17145 if (mask & OEX_FPU_INEX)
015dc7e1 17146 fputs ("INEX", stdout), first = false;
19e6b90e 17147 if (mask & OEX_FPU_UFLO)
015dc7e1 17148 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17149 if (mask & OEX_FPU_OFLO)
015dc7e1 17150 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17151 if (mask & OEX_FPU_DIV0)
015dc7e1 17152 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17153 if (mask & OEX_FPU_INVAL)
17154 printf ("%sINVAL", first ? "" : "|");
17155 }
5b18a4bc 17156 else
19e6b90e 17157 fputs ("0", stdout);
5b18a4bc 17158}
103f02d3 17159
f6f0e17b
NC
17160/* Display's the value of TAG at location P. If TAG is
17161 greater than 0 it is assumed to be an unknown tag, and
17162 a message is printed to this effect. Otherwise it is
17163 assumed that a message has already been printed.
17164
17165 If the bottom bit of TAG is set it assumed to have a
17166 string value, otherwise it is assumed to have an integer
17167 value.
17168
17169 Returns an updated P pointing to the first unread byte
17170 beyond the end of TAG's value.
17171
17172 Reads at or beyond END will not be made. */
17173
17174static unsigned char *
60abdbed 17175display_tag_value (signed int tag,
f6f0e17b
NC
17176 unsigned char * p,
17177 const unsigned char * const end)
17178{
26c527e6 17179 uint64_t val;
f6f0e17b
NC
17180
17181 if (tag > 0)
17182 printf (" Tag_unknown_%d: ", tag);
17183
17184 if (p >= end)
17185 {
4082ef84 17186 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17187 }
17188 else if (tag & 1)
17189 {
071436c6
NC
17190 /* PR 17531 file: 027-19978-0.004. */
17191 size_t maxlen = (end - p) - 1;
17192
17193 putchar ('"');
4082ef84
NC
17194 if (maxlen > 0)
17195 {
b6ac461a 17196 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17197 p += strnlen ((char *) p, maxlen) + 1;
17198 }
17199 else
17200 {
17201 printf (_("<corrupt string tag>"));
17202 p = (unsigned char *) end;
17203 }
071436c6 17204 printf ("\"\n");
f6f0e17b
NC
17205 }
17206 else
17207 {
cd30bcef 17208 READ_ULEB (val, p, end);
26c527e6 17209 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17210 }
17211
4082ef84 17212 assert (p <= end);
f6f0e17b
NC
17213 return p;
17214}
17215
53a346d8
CZ
17216/* ARC ABI attributes section. */
17217
17218static unsigned char *
17219display_arc_attribute (unsigned char * p,
17220 const unsigned char * const end)
17221{
17222 unsigned int tag;
53a346d8
CZ
17223 unsigned int val;
17224
cd30bcef 17225 READ_ULEB (tag, p, end);
53a346d8
CZ
17226
17227 switch (tag)
17228 {
17229 case Tag_ARC_PCS_config:
cd30bcef 17230 READ_ULEB (val, p, end);
53a346d8
CZ
17231 printf (" Tag_ARC_PCS_config: ");
17232 switch (val)
17233 {
17234 case 0:
17235 printf (_("Absent/Non standard\n"));
17236 break;
17237 case 1:
17238 printf (_("Bare metal/mwdt\n"));
17239 break;
17240 case 2:
17241 printf (_("Bare metal/newlib\n"));
17242 break;
17243 case 3:
17244 printf (_("Linux/uclibc\n"));
17245 break;
17246 case 4:
17247 printf (_("Linux/glibc\n"));
17248 break;
17249 default:
17250 printf (_("Unknown\n"));
17251 break;
17252 }
17253 break;
17254
17255 case Tag_ARC_CPU_base:
cd30bcef 17256 READ_ULEB (val, p, end);
53a346d8
CZ
17257 printf (" Tag_ARC_CPU_base: ");
17258 switch (val)
17259 {
17260 default:
17261 case TAG_CPU_NONE:
17262 printf (_("Absent\n"));
17263 break;
17264 case TAG_CPU_ARC6xx:
17265 printf ("ARC6xx\n");
17266 break;
17267 case TAG_CPU_ARC7xx:
17268 printf ("ARC7xx\n");
17269 break;
17270 case TAG_CPU_ARCEM:
17271 printf ("ARCEM\n");
17272 break;
17273 case TAG_CPU_ARCHS:
17274 printf ("ARCHS\n");
17275 break;
17276 }
17277 break;
17278
17279 case Tag_ARC_CPU_variation:
cd30bcef 17280 READ_ULEB (val, p, end);
53a346d8
CZ
17281 printf (" Tag_ARC_CPU_variation: ");
17282 switch (val)
17283 {
17284 default:
17285 if (val > 0 && val < 16)
53a346d8 17286 printf ("Core%d\n", val);
d8cbc93b
JL
17287 else
17288 printf ("Unknown\n");
17289 break;
17290
53a346d8
CZ
17291 case 0:
17292 printf (_("Absent\n"));
17293 break;
17294 }
17295 break;
17296
17297 case Tag_ARC_CPU_name:
17298 printf (" Tag_ARC_CPU_name: ");
17299 p = display_tag_value (-1, p, end);
17300 break;
17301
17302 case Tag_ARC_ABI_rf16:
cd30bcef 17303 READ_ULEB (val, p, end);
53a346d8
CZ
17304 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17305 break;
17306
17307 case Tag_ARC_ABI_osver:
cd30bcef 17308 READ_ULEB (val, p, end);
53a346d8
CZ
17309 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17310 break;
17311
17312 case Tag_ARC_ABI_pic:
17313 case Tag_ARC_ABI_sda:
cd30bcef 17314 READ_ULEB (val, p, end);
53a346d8
CZ
17315 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17316 : " Tag_ARC_ABI_pic: ");
17317 switch (val)
17318 {
17319 case 0:
17320 printf (_("Absent\n"));
17321 break;
17322 case 1:
17323 printf ("MWDT\n");
17324 break;
17325 case 2:
17326 printf ("GNU\n");
17327 break;
17328 default:
17329 printf (_("Unknown\n"));
17330 break;
17331 }
17332 break;
17333
17334 case Tag_ARC_ABI_tls:
cd30bcef 17335 READ_ULEB (val, p, end);
53a346d8
CZ
17336 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17337 break;
17338
17339 case Tag_ARC_ABI_enumsize:
cd30bcef 17340 READ_ULEB (val, p, end);
53a346d8
CZ
17341 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17342 _("smallest"));
17343 break;
17344
17345 case Tag_ARC_ABI_exceptions:
cd30bcef 17346 READ_ULEB (val, p, end);
53a346d8
CZ
17347 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17348 : _("default"));
17349 break;
17350
17351 case Tag_ARC_ABI_double_size:
cd30bcef 17352 READ_ULEB (val, p, end);
53a346d8
CZ
17353 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17354 break;
17355
17356 case Tag_ARC_ISA_config:
17357 printf (" Tag_ARC_ISA_config: ");
17358 p = display_tag_value (-1, p, end);
17359 break;
17360
17361 case Tag_ARC_ISA_apex:
17362 printf (" Tag_ARC_ISA_apex: ");
17363 p = display_tag_value (-1, p, end);
17364 break;
17365
17366 case Tag_ARC_ISA_mpy_option:
cd30bcef 17367 READ_ULEB (val, p, end);
53a346d8
CZ
17368 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17369 break;
17370
db1e1b45 17371 case Tag_ARC_ATR_version:
cd30bcef 17372 READ_ULEB (val, p, end);
db1e1b45 17373 printf (" Tag_ARC_ATR_version: %d\n", val);
17374 break;
17375
53a346d8
CZ
17376 default:
17377 return display_tag_value (tag & 1, p, end);
17378 }
17379
17380 return p;
17381}
17382
11c1ff18
PB
17383/* ARM EABI attributes section. */
17384typedef struct
17385{
70e99720 17386 unsigned int tag;
2cf0635d 17387 const char * name;
11c1ff18 17388 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17389 unsigned int type;
288f0ba2 17390 const char *const *table;
11c1ff18
PB
17391} arm_attr_public_tag;
17392
288f0ba2 17393static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17394 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17395 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17396 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17397 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17398static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17399static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17400 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17401static const char *const arm_attr_tag_FP_arch[] =
bca38921 17402 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17403 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17404static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17405static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17406 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17407 "NEON for ARMv8.1"};
288f0ba2 17408static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17409 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17410 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17411static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17412 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17413static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17414 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17415static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17416 {"Absolute", "PC-relative", "None"};
288f0ba2 17417static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17418 {"None", "direct", "GOT-indirect"};
288f0ba2 17419static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17420 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17421static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17422static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17423 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17424static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17425static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17426static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17427 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17428static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17429 {"Unused", "small", "int", "forced to int"};
288f0ba2 17430static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17431 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17432static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17433 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17434static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17435 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17436static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17437 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17438 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17439static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17440 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17441 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17442static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17443static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17444 {"Not Allowed", "Allowed"};
288f0ba2 17445static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17446 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17447static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17448 {"Follow architecture", "Allowed"};
288f0ba2 17449static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17450 {"Not Allowed", "Allowed"};
288f0ba2 17451static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17452 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17453 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17454static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17455static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17456 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17457 "TrustZone and Virtualization Extensions"};
288f0ba2 17458static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17459 {"Not Allowed", "Allowed"};
11c1ff18 17460
288f0ba2 17461static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17462 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17463
99db83d0
AC
17464static const char * arm_attr_tag_PAC_extension[] =
17465 {"No PAC/AUT instructions",
17466 "PAC/AUT instructions permitted in the NOP space",
17467 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17468
4b535030
AC
17469static const char * arm_attr_tag_BTI_extension[] =
17470 {"BTI instructions not permitted",
17471 "BTI instructions permitted in the NOP space",
17472 "BTI instructions permitted in the NOP and in the non-NOP space"};
17473
b81ee92f
AC
17474static const char * arm_attr_tag_BTI_use[] =
17475 {"Compiled without branch target enforcement",
17476 "Compiled with branch target enforcement"};
17477
c9fed665
AC
17478static const char * arm_attr_tag_PACRET_use[] =
17479 {"Compiled without return address signing and authentication",
17480 "Compiled with return address signing and authentication"};
17481
11c1ff18
PB
17482#define LOOKUP(id, name) \
17483 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17484static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17485{
17486 {4, "CPU_raw_name", 1, NULL},
17487 {5, "CPU_name", 1, NULL},
17488 LOOKUP(6, CPU_arch),
17489 {7, "CPU_arch_profile", 0, NULL},
17490 LOOKUP(8, ARM_ISA_use),
17491 LOOKUP(9, THUMB_ISA_use),
75375b3e 17492 LOOKUP(10, FP_arch),
11c1ff18 17493 LOOKUP(11, WMMX_arch),
f5f53991
AS
17494 LOOKUP(12, Advanced_SIMD_arch),
17495 LOOKUP(13, PCS_config),
11c1ff18
PB
17496 LOOKUP(14, ABI_PCS_R9_use),
17497 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17498 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17499 LOOKUP(17, ABI_PCS_GOT_use),
17500 LOOKUP(18, ABI_PCS_wchar_t),
17501 LOOKUP(19, ABI_FP_rounding),
17502 LOOKUP(20, ABI_FP_denormal),
17503 LOOKUP(21, ABI_FP_exceptions),
17504 LOOKUP(22, ABI_FP_user_exceptions),
17505 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17506 {24, "ABI_align_needed", 0, NULL},
17507 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17508 LOOKUP(26, ABI_enum_size),
17509 LOOKUP(27, ABI_HardFP_use),
17510 LOOKUP(28, ABI_VFP_args),
17511 LOOKUP(29, ABI_WMMX_args),
17512 LOOKUP(30, ABI_optimization_goals),
17513 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17514 {32, "compatibility", 0, NULL},
f5f53991 17515 LOOKUP(34, CPU_unaligned_access),
75375b3e 17516 LOOKUP(36, FP_HP_extension),
8e79c3df 17517 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17518 LOOKUP(42, MPextension_use),
17519 LOOKUP(44, DIV_use),
15afaa63 17520 LOOKUP(46, DSP_extension),
a7ad558c 17521 LOOKUP(48, MVE_arch),
99db83d0 17522 LOOKUP(50, PAC_extension),
4b535030 17523 LOOKUP(52, BTI_extension),
b81ee92f 17524 LOOKUP(74, BTI_use),
c9fed665 17525 LOOKUP(76, PACRET_use),
f5f53991
AS
17526 {64, "nodefaults", 0, NULL},
17527 {65, "also_compatible_with", 0, NULL},
17528 LOOKUP(66, T2EE_use),
17529 {67, "conformance", 1, NULL},
17530 LOOKUP(68, Virtualization_use),
cd21e546 17531 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17532};
17533#undef LOOKUP
17534
11c1ff18 17535static unsigned char *
f6f0e17b
NC
17536display_arm_attribute (unsigned char * p,
17537 const unsigned char * const end)
11c1ff18 17538{
70e99720 17539 unsigned int tag;
70e99720 17540 unsigned int val;
2cf0635d 17541 arm_attr_public_tag * attr;
11c1ff18 17542 unsigned i;
70e99720 17543 unsigned int type;
11c1ff18 17544
cd30bcef 17545 READ_ULEB (tag, p, end);
11c1ff18 17546 attr = NULL;
2cf0635d 17547 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17548 {
17549 if (arm_attr_public_tags[i].tag == tag)
17550 {
17551 attr = &arm_attr_public_tags[i];
17552 break;
17553 }
17554 }
17555
17556 if (attr)
17557 {
17558 printf (" Tag_%s: ", attr->name);
17559 switch (attr->type)
17560 {
17561 case 0:
17562 switch (tag)
17563 {
17564 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17565 READ_ULEB (val, p, end);
11c1ff18
PB
17566 switch (val)
17567 {
2b692964
NC
17568 case 0: printf (_("None\n")); break;
17569 case 'A': printf (_("Application\n")); break;
17570 case 'R': printf (_("Realtime\n")); break;
17571 case 'M': printf (_("Microcontroller\n")); break;
17572 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17573 default: printf ("??? (%d)\n", val); break;
17574 }
17575 break;
17576
75375b3e 17577 case 24: /* Tag_align_needed. */
cd30bcef 17578 READ_ULEB (val, p, end);
75375b3e
MGD
17579 switch (val)
17580 {
2b692964
NC
17581 case 0: printf (_("None\n")); break;
17582 case 1: printf (_("8-byte\n")); break;
17583 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17584 case 3: printf ("??? 3\n"); break;
17585 default:
17586 if (val <= 12)
dd24e3da 17587 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17588 1 << val);
17589 else
17590 printf ("??? (%d)\n", val);
17591 break;
17592 }
17593 break;
17594
17595 case 25: /* Tag_align_preserved. */
cd30bcef 17596 READ_ULEB (val, p, end);
75375b3e
MGD
17597 switch (val)
17598 {
2b692964
NC
17599 case 0: printf (_("None\n")); break;
17600 case 1: printf (_("8-byte, except leaf SP\n")); break;
17601 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17602 case 3: printf ("??? 3\n"); break;
17603 default:
17604 if (val <= 12)
dd24e3da 17605 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17606 1 << val);
17607 else
17608 printf ("??? (%d)\n", val);
17609 break;
17610 }
17611 break;
17612
11c1ff18 17613 case 32: /* Tag_compatibility. */
071436c6 17614 {
cd30bcef 17615 READ_ULEB (val, p, end);
071436c6 17616 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17617 if (p < end - 1)
17618 {
17619 size_t maxlen = (end - p) - 1;
17620
b6ac461a 17621 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17622 p += strnlen ((char *) p, maxlen) + 1;
17623 }
17624 else
17625 {
17626 printf (_("<corrupt>"));
17627 p = (unsigned char *) end;
17628 }
071436c6 17629 putchar ('\n');
071436c6 17630 }
11c1ff18
PB
17631 break;
17632
f5f53991 17633 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17634 /* PR 17531: file: 001-505008-0.01. */
17635 if (p < end)
17636 p++;
2b692964 17637 printf (_("True\n"));
f5f53991
AS
17638 break;
17639
17640 case 65: /* Tag_also_compatible_with. */
cd30bcef 17641 READ_ULEB (val, p, end);
f5f53991
AS
17642 if (val == 6 /* Tag_CPU_arch. */)
17643 {
cd30bcef 17644 READ_ULEB (val, p, end);
071436c6 17645 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17646 printf ("??? (%d)\n", val);
17647 else
17648 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17649 }
17650 else
17651 printf ("???\n");
071436c6
NC
17652 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17653 ;
f5f53991
AS
17654 break;
17655
11c1ff18 17656 default:
bee0ee85
NC
17657 printf (_("<unknown: %d>\n"), tag);
17658 break;
11c1ff18
PB
17659 }
17660 return p;
17661
17662 case 1:
f6f0e17b 17663 return display_tag_value (-1, p, end);
11c1ff18 17664 case 2:
f6f0e17b 17665 return display_tag_value (0, p, end);
11c1ff18
PB
17666
17667 default:
17668 assert (attr->type & 0x80);
cd30bcef 17669 READ_ULEB (val, p, end);
11c1ff18
PB
17670 type = attr->type & 0x7f;
17671 if (val >= type)
17672 printf ("??? (%d)\n", val);
17673 else
17674 printf ("%s\n", attr->table[val]);
17675 return p;
17676 }
17677 }
11c1ff18 17678
f6f0e17b 17679 return display_tag_value (tag, p, end);
11c1ff18
PB
17680}
17681
104d59d1 17682static unsigned char *
60bca95a 17683display_gnu_attribute (unsigned char * p,
60abdbed 17684 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17685 const unsigned char * const end)
104d59d1 17686{
cd30bcef 17687 unsigned int tag;
60abdbed 17688 unsigned int val;
104d59d1 17689
cd30bcef 17690 READ_ULEB (tag, p, end);
104d59d1
JM
17691
17692 /* Tag_compatibility is the only generic GNU attribute defined at
17693 present. */
17694 if (tag == 32)
17695 {
cd30bcef 17696 READ_ULEB (val, p, end);
071436c6
NC
17697
17698 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17699 if (p == end)
17700 {
071436c6 17701 printf (_("<corrupt>\n"));
f6f0e17b
NC
17702 warn (_("corrupt vendor attribute\n"));
17703 }
17704 else
17705 {
4082ef84
NC
17706 if (p < end - 1)
17707 {
17708 size_t maxlen = (end - p) - 1;
071436c6 17709
b6ac461a 17710 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17711 p += strnlen ((char *) p, maxlen) + 1;
17712 }
17713 else
17714 {
17715 printf (_("<corrupt>"));
17716 p = (unsigned char *) end;
17717 }
071436c6 17718 putchar ('\n');
f6f0e17b 17719 }
104d59d1
JM
17720 return p;
17721 }
17722
17723 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17724 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17725
f6f0e17b 17726 return display_tag_value (tag, p, end);
104d59d1
JM
17727}
17728
85f7484a
PB
17729static unsigned char *
17730display_m68k_gnu_attribute (unsigned char * p,
17731 unsigned int tag,
17732 const unsigned char * const end)
17733{
17734 unsigned int val;
17735
17736 if (tag == Tag_GNU_M68K_ABI_FP)
17737 {
17738 printf (" Tag_GNU_M68K_ABI_FP: ");
17739 if (p == end)
17740 {
17741 printf (_("<corrupt>\n"));
17742 return p;
17743 }
17744 READ_ULEB (val, p, end);
17745
17746 if (val > 3)
17747 printf ("(%#x), ", val);
17748
17749 switch (val & 3)
17750 {
17751 case 0:
17752 printf (_("unspecified hard/soft float\n"));
17753 break;
17754 case 1:
17755 printf (_("hard float\n"));
17756 break;
17757 case 2:
17758 printf (_("soft float\n"));
17759 break;
17760 }
17761 return p;
17762 }
17763
17764 return display_tag_value (tag & 1, p, end);
17765}
17766
34c8bcba 17767static unsigned char *
f6f0e17b 17768display_power_gnu_attribute (unsigned char * p,
60abdbed 17769 unsigned int tag,
f6f0e17b 17770 const unsigned char * const end)
34c8bcba 17771{
005d79fd 17772 unsigned int val;
34c8bcba
JM
17773
17774 if (tag == Tag_GNU_Power_ABI_FP)
17775 {
34c8bcba 17776 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17777 if (p == end)
005d79fd
AM
17778 {
17779 printf (_("<corrupt>\n"));
17780 return p;
17781 }
cd30bcef 17782 READ_ULEB (val, p, end);
60bca95a 17783
005d79fd
AM
17784 if (val > 15)
17785 printf ("(%#x), ", val);
17786
17787 switch (val & 3)
34c8bcba
JM
17788 {
17789 case 0:
005d79fd 17790 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17791 break;
17792 case 1:
005d79fd 17793 printf (_("hard float, "));
34c8bcba
JM
17794 break;
17795 case 2:
005d79fd 17796 printf (_("soft float, "));
34c8bcba 17797 break;
3c7b9897 17798 case 3:
005d79fd 17799 printf (_("single-precision hard float, "));
3c7b9897 17800 break;
005d79fd
AM
17801 }
17802
17803 switch (val & 0xC)
17804 {
17805 case 0:
17806 printf (_("unspecified long double\n"));
17807 break;
17808 case 4:
17809 printf (_("128-bit IBM long double\n"));
17810 break;
17811 case 8:
17812 printf (_("64-bit long double\n"));
17813 break;
17814 case 12:
17815 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17816 break;
17817 }
17818 return p;
005d79fd 17819 }
34c8bcba 17820
c6e65352
DJ
17821 if (tag == Tag_GNU_Power_ABI_Vector)
17822 {
c6e65352 17823 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17824 if (p == end)
005d79fd
AM
17825 {
17826 printf (_("<corrupt>\n"));
17827 return p;
17828 }
cd30bcef 17829 READ_ULEB (val, p, end);
005d79fd
AM
17830
17831 if (val > 3)
17832 printf ("(%#x), ", val);
17833
17834 switch (val & 3)
c6e65352
DJ
17835 {
17836 case 0:
005d79fd 17837 printf (_("unspecified\n"));
c6e65352
DJ
17838 break;
17839 case 1:
005d79fd 17840 printf (_("generic\n"));
c6e65352
DJ
17841 break;
17842 case 2:
17843 printf ("AltiVec\n");
17844 break;
17845 case 3:
17846 printf ("SPE\n");
17847 break;
c6e65352
DJ
17848 }
17849 return p;
005d79fd 17850 }
c6e65352 17851
f82e0623
NF
17852 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17853 {
005d79fd 17854 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17855 if (p == end)
f6f0e17b 17856 {
005d79fd 17857 printf (_("<corrupt>\n"));
f6f0e17b
NC
17858 return p;
17859 }
cd30bcef 17860 READ_ULEB (val, p, end);
0b4362b0 17861
005d79fd
AM
17862 if (val > 2)
17863 printf ("(%#x), ", val);
17864
17865 switch (val & 3)
17866 {
17867 case 0:
17868 printf (_("unspecified\n"));
17869 break;
17870 case 1:
17871 printf ("r3/r4\n");
17872 break;
17873 case 2:
17874 printf (_("memory\n"));
17875 break;
17876 case 3:
17877 printf ("???\n");
17878 break;
17879 }
f82e0623
NF
17880 return p;
17881 }
17882
f6f0e17b 17883 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17884}
17885
643f7afb
AK
17886static unsigned char *
17887display_s390_gnu_attribute (unsigned char * p,
60abdbed 17888 unsigned int tag,
643f7afb
AK
17889 const unsigned char * const end)
17890{
cd30bcef 17891 unsigned int val;
643f7afb
AK
17892
17893 if (tag == Tag_GNU_S390_ABI_Vector)
17894 {
643f7afb 17895 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17896 READ_ULEB (val, p, end);
643f7afb
AK
17897
17898 switch (val)
17899 {
17900 case 0:
17901 printf (_("any\n"));
17902 break;
17903 case 1:
17904 printf (_("software\n"));
17905 break;
17906 case 2:
17907 printf (_("hardware\n"));
17908 break;
17909 default:
17910 printf ("??? (%d)\n", val);
17911 break;
17912 }
17913 return p;
17914 }
17915
17916 return display_tag_value (tag & 1, p, end);
17917}
17918
9e8c70f9 17919static void
60abdbed 17920display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17921{
17922 if (mask)
17923 {
015dc7e1 17924 bool first = true;
071436c6 17925
9e8c70f9 17926 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17927 fputs ("mul32", stdout), first = false;
9e8c70f9 17928 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17929 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17930 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17931 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17932 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17933 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17934 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17935 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17936 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17937 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17938 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17939 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17940 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17941 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17942 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17943 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17944 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17945 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17946 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17947 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17948 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17949 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17950 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17951 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17952 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17953 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17954 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17955 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17956 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17957 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17958 }
17959 else
071436c6
NC
17960 fputc ('0', stdout);
17961 fputc ('\n', stdout);
9e8c70f9
DM
17962}
17963
3d68f91c 17964static void
60abdbed 17965display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17966{
17967 if (mask)
17968 {
015dc7e1 17969 bool first = true;
071436c6 17970
3d68f91c 17971 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17972 fputs ("fjathplus", stdout), first = false;
3d68f91c 17973 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17974 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17975 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17976 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17977 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17978 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17979 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17980 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17981 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17982 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17983 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17984 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17985 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17986 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17987 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17988 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17989 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17990 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17991 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17992 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17993 }
17994 else
071436c6
NC
17995 fputc ('0', stdout);
17996 fputc ('\n', stdout);
3d68f91c
JM
17997}
17998
9e8c70f9 17999static unsigned char *
f6f0e17b 18000display_sparc_gnu_attribute (unsigned char * p,
60abdbed 18001 unsigned int tag,
f6f0e17b 18002 const unsigned char * const end)
9e8c70f9 18003{
cd30bcef 18004 unsigned int val;
3d68f91c 18005
9e8c70f9
DM
18006 if (tag == Tag_GNU_Sparc_HWCAPS)
18007 {
cd30bcef 18008 READ_ULEB (val, p, end);
9e8c70f9 18009 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18010 display_sparc_hwcaps (val);
18011 return p;
3d68f91c
JM
18012 }
18013 if (tag == Tag_GNU_Sparc_HWCAPS2)
18014 {
cd30bcef 18015 READ_ULEB (val, p, end);
3d68f91c
JM
18016 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18017 display_sparc_hwcaps2 (val);
18018 return p;
18019 }
9e8c70f9 18020
f6f0e17b 18021 return display_tag_value (tag, p, end);
9e8c70f9
DM
18022}
18023
351cdf24 18024static void
32ec8896 18025print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18026{
18027 switch (val)
18028 {
18029 case Val_GNU_MIPS_ABI_FP_ANY:
18030 printf (_("Hard or soft float\n"));
18031 break;
18032 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18033 printf (_("Hard float (double precision)\n"));
18034 break;
18035 case Val_GNU_MIPS_ABI_FP_SINGLE:
18036 printf (_("Hard float (single precision)\n"));
18037 break;
18038 case Val_GNU_MIPS_ABI_FP_SOFT:
18039 printf (_("Soft float\n"));
18040 break;
18041 case Val_GNU_MIPS_ABI_FP_OLD_64:
18042 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18043 break;
18044 case Val_GNU_MIPS_ABI_FP_XX:
18045 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18046 break;
18047 case Val_GNU_MIPS_ABI_FP_64:
18048 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18049 break;
18050 case Val_GNU_MIPS_ABI_FP_64A:
18051 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18052 break;
3350cc01
CM
18053 case Val_GNU_MIPS_ABI_FP_NAN2008:
18054 printf (_("NaN 2008 compatibility\n"));
18055 break;
351cdf24
MF
18056 default:
18057 printf ("??? (%d)\n", val);
18058 break;
18059 }
18060}
18061
2cf19d5c 18062static unsigned char *
f6f0e17b 18063display_mips_gnu_attribute (unsigned char * p,
60abdbed 18064 unsigned int tag,
f6f0e17b 18065 const unsigned char * const end)
2cf19d5c 18066{
2cf19d5c
JM
18067 if (tag == Tag_GNU_MIPS_ABI_FP)
18068 {
32ec8896 18069 unsigned int val;
f6f0e17b 18070
2cf19d5c 18071 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18072 READ_ULEB (val, p, end);
351cdf24 18073 print_mips_fp_abi_value (val);
2cf19d5c
JM
18074 return p;
18075 }
18076
a9f58168
CF
18077 if (tag == Tag_GNU_MIPS_ABI_MSA)
18078 {
32ec8896 18079 unsigned int val;
a9f58168 18080
a9f58168 18081 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18082 READ_ULEB (val, p, end);
a9f58168
CF
18083
18084 switch (val)
18085 {
18086 case Val_GNU_MIPS_ABI_MSA_ANY:
18087 printf (_("Any MSA or not\n"));
18088 break;
18089 case Val_GNU_MIPS_ABI_MSA_128:
18090 printf (_("128-bit MSA\n"));
18091 break;
18092 default:
18093 printf ("??? (%d)\n", val);
18094 break;
18095 }
18096 return p;
18097 }
18098
f6f0e17b 18099 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18100}
18101
59e6276b 18102static unsigned char *
f6f0e17b
NC
18103display_tic6x_attribute (unsigned char * p,
18104 const unsigned char * const end)
59e6276b 18105{
60abdbed 18106 unsigned int tag;
cd30bcef 18107 unsigned int val;
59e6276b 18108
cd30bcef 18109 READ_ULEB (tag, p, end);
59e6276b
JM
18110
18111 switch (tag)
18112 {
75fa6dc1 18113 case Tag_ISA:
75fa6dc1 18114 printf (" Tag_ISA: ");
cd30bcef 18115 READ_ULEB (val, p, end);
59e6276b
JM
18116
18117 switch (val)
18118 {
75fa6dc1 18119 case C6XABI_Tag_ISA_none:
59e6276b
JM
18120 printf (_("None\n"));
18121 break;
75fa6dc1 18122 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18123 printf ("C62x\n");
18124 break;
75fa6dc1 18125 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18126 printf ("C67x\n");
18127 break;
75fa6dc1 18128 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18129 printf ("C67x+\n");
18130 break;
75fa6dc1 18131 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18132 printf ("C64x\n");
18133 break;
75fa6dc1 18134 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18135 printf ("C64x+\n");
18136 break;
75fa6dc1 18137 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18138 printf ("C674x\n");
18139 break;
18140 default:
18141 printf ("??? (%d)\n", val);
18142 break;
18143 }
18144 return p;
18145
87779176 18146 case Tag_ABI_wchar_t:
87779176 18147 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18148 READ_ULEB (val, p, end);
87779176
JM
18149 switch (val)
18150 {
18151 case 0:
18152 printf (_("Not used\n"));
18153 break;
18154 case 1:
18155 printf (_("2 bytes\n"));
18156 break;
18157 case 2:
18158 printf (_("4 bytes\n"));
18159 break;
18160 default:
18161 printf ("??? (%d)\n", val);
18162 break;
18163 }
18164 return p;
18165
18166 case Tag_ABI_stack_align_needed:
87779176 18167 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18168 READ_ULEB (val, p, end);
87779176
JM
18169 switch (val)
18170 {
18171 case 0:
18172 printf (_("8-byte\n"));
18173 break;
18174 case 1:
18175 printf (_("16-byte\n"));
18176 break;
18177 default:
18178 printf ("??? (%d)\n", val);
18179 break;
18180 }
18181 return p;
18182
18183 case Tag_ABI_stack_align_preserved:
cd30bcef 18184 READ_ULEB (val, p, end);
87779176
JM
18185 printf (" Tag_ABI_stack_align_preserved: ");
18186 switch (val)
18187 {
18188 case 0:
18189 printf (_("8-byte\n"));
18190 break;
18191 case 1:
18192 printf (_("16-byte\n"));
18193 break;
18194 default:
18195 printf ("??? (%d)\n", val);
18196 break;
18197 }
18198 return p;
18199
b5593623 18200 case Tag_ABI_DSBT:
cd30bcef 18201 READ_ULEB (val, p, end);
b5593623
JM
18202 printf (" Tag_ABI_DSBT: ");
18203 switch (val)
18204 {
18205 case 0:
18206 printf (_("DSBT addressing not used\n"));
18207 break;
18208 case 1:
18209 printf (_("DSBT addressing used\n"));
18210 break;
18211 default:
18212 printf ("??? (%d)\n", val);
18213 break;
18214 }
18215 return p;
18216
87779176 18217 case Tag_ABI_PID:
cd30bcef 18218 READ_ULEB (val, p, end);
87779176
JM
18219 printf (" Tag_ABI_PID: ");
18220 switch (val)
18221 {
18222 case 0:
18223 printf (_("Data addressing position-dependent\n"));
18224 break;
18225 case 1:
18226 printf (_("Data addressing position-independent, GOT near DP\n"));
18227 break;
18228 case 2:
18229 printf (_("Data addressing position-independent, GOT far from DP\n"));
18230 break;
18231 default:
18232 printf ("??? (%d)\n", val);
18233 break;
18234 }
18235 return p;
18236
18237 case Tag_ABI_PIC:
cd30bcef 18238 READ_ULEB (val, p, end);
87779176
JM
18239 printf (" Tag_ABI_PIC: ");
18240 switch (val)
18241 {
18242 case 0:
18243 printf (_("Code addressing position-dependent\n"));
18244 break;
18245 case 1:
18246 printf (_("Code addressing position-independent\n"));
18247 break;
18248 default:
18249 printf ("??? (%d)\n", val);
18250 break;
18251 }
18252 return p;
18253
18254 case Tag_ABI_array_object_alignment:
cd30bcef 18255 READ_ULEB (val, p, end);
87779176
JM
18256 printf (" Tag_ABI_array_object_alignment: ");
18257 switch (val)
18258 {
18259 case 0:
18260 printf (_("8-byte\n"));
18261 break;
18262 case 1:
18263 printf (_("4-byte\n"));
18264 break;
18265 case 2:
18266 printf (_("16-byte\n"));
18267 break;
18268 default:
18269 printf ("??? (%d)\n", val);
18270 break;
18271 }
18272 return p;
18273
18274 case Tag_ABI_array_object_align_expected:
cd30bcef 18275 READ_ULEB (val, p, end);
87779176
JM
18276 printf (" Tag_ABI_array_object_align_expected: ");
18277 switch (val)
18278 {
18279 case 0:
18280 printf (_("8-byte\n"));
18281 break;
18282 case 1:
18283 printf (_("4-byte\n"));
18284 break;
18285 case 2:
18286 printf (_("16-byte\n"));
18287 break;
18288 default:
18289 printf ("??? (%d)\n", val);
18290 break;
18291 }
18292 return p;
18293
3cbd1c06 18294 case Tag_ABI_compatibility:
071436c6 18295 {
cd30bcef 18296 READ_ULEB (val, p, end);
071436c6 18297 printf (" Tag_ABI_compatibility: ");
071436c6 18298 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18299 if (p < end - 1)
18300 {
18301 size_t maxlen = (end - p) - 1;
18302
b6ac461a 18303 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18304 p += strnlen ((char *) p, maxlen) + 1;
18305 }
18306 else
18307 {
18308 printf (_("<corrupt>"));
18309 p = (unsigned char *) end;
18310 }
071436c6 18311 putchar ('\n');
071436c6
NC
18312 return p;
18313 }
87779176
JM
18314
18315 case Tag_ABI_conformance:
071436c6 18316 {
4082ef84
NC
18317 printf (" Tag_ABI_conformance: \"");
18318 if (p < end - 1)
18319 {
18320 size_t maxlen = (end - p) - 1;
071436c6 18321
b6ac461a 18322 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18323 p += strnlen ((char *) p, maxlen) + 1;
18324 }
18325 else
18326 {
18327 printf (_("<corrupt>"));
18328 p = (unsigned char *) end;
18329 }
071436c6 18330 printf ("\"\n");
071436c6
NC
18331 return p;
18332 }
59e6276b
JM
18333 }
18334
f6f0e17b
NC
18335 return display_tag_value (tag, p, end);
18336}
59e6276b 18337
f6f0e17b 18338static void
60abdbed 18339display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18340{
26c527e6 18341 uint64_t addr = 0;
f6f0e17b
NC
18342 size_t bytes = end - p;
18343
feceaa59 18344 assert (end >= p);
f6f0e17b 18345 while (bytes)
87779176 18346 {
f6f0e17b
NC
18347 int j;
18348 int k;
18349 int lbytes = (bytes > 16 ? 16 : bytes);
18350
26c527e6 18351 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18352
18353 for (j = 0; j < 16; j++)
18354 {
18355 if (j < lbytes)
18356 printf ("%2.2x", p[j]);
18357 else
18358 printf (" ");
18359
18360 if ((j & 3) == 3)
18361 printf (" ");
18362 }
18363
18364 for (j = 0; j < lbytes; j++)
18365 {
18366 k = p[j];
18367 if (k >= ' ' && k < 0x7f)
18368 printf ("%c", k);
18369 else
18370 printf (".");
18371 }
18372
18373 putchar ('\n');
18374
18375 p += lbytes;
18376 bytes -= lbytes;
18377 addr += lbytes;
87779176 18378 }
59e6276b 18379
f6f0e17b 18380 putchar ('\n');
59e6276b
JM
18381}
18382
13761a11 18383static unsigned char *
b0191216 18384display_msp430_attribute (unsigned char * p,
26c527e6 18385 const unsigned char * const end)
13761a11 18386{
26c527e6
AM
18387 uint64_t val;
18388 uint64_t tag;
13761a11 18389
cd30bcef 18390 READ_ULEB (tag, p, end);
0b4362b0 18391
13761a11
NC
18392 switch (tag)
18393 {
18394 case OFBA_MSPABI_Tag_ISA:
13761a11 18395 printf (" Tag_ISA: ");
cd30bcef 18396 READ_ULEB (val, p, end);
13761a11
NC
18397 switch (val)
18398 {
18399 case 0: printf (_("None\n")); break;
18400 case 1: printf (_("MSP430\n")); break;
18401 case 2: printf (_("MSP430X\n")); break;
26c527e6 18402 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18403 }
18404 break;
18405
18406 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18407 printf (" Tag_Code_Model: ");
cd30bcef 18408 READ_ULEB (val, p, end);
13761a11
NC
18409 switch (val)
18410 {
18411 case 0: printf (_("None\n")); break;
18412 case 1: printf (_("Small\n")); break;
18413 case 2: printf (_("Large\n")); break;
26c527e6 18414 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18415 }
18416 break;
18417
18418 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18419 printf (" Tag_Data_Model: ");
cd30bcef 18420 READ_ULEB (val, p, end);
13761a11
NC
18421 switch (val)
18422 {
18423 case 0: printf (_("None\n")); break;
18424 case 1: printf (_("Small\n")); break;
18425 case 2: printf (_("Large\n")); break;
18426 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18427 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18428 }
18429 break;
18430
18431 default:
26c527e6 18432 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18433
18434 if (tag & 1)
18435 {
071436c6 18436 putchar ('"');
4082ef84
NC
18437 if (p < end - 1)
18438 {
18439 size_t maxlen = (end - p) - 1;
18440
b6ac461a 18441 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18442 p += strnlen ((char *) p, maxlen) + 1;
18443 }
18444 else
18445 {
18446 printf (_("<corrupt>"));
18447 p = (unsigned char *) end;
18448 }
071436c6 18449 printf ("\"\n");
13761a11
NC
18450 }
18451 else
18452 {
cd30bcef 18453 READ_ULEB (val, p, end);
26c527e6 18454 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18455 }
18456 break;
18457 }
18458
4082ef84 18459 assert (p <= end);
13761a11
NC
18460 return p;
18461}
18462
c0ea7c52
JL
18463static unsigned char *
18464display_msp430_gnu_attribute (unsigned char * p,
18465 unsigned int tag,
18466 const unsigned char * const end)
18467{
18468 if (tag == Tag_GNU_MSP430_Data_Region)
18469 {
26c527e6 18470 uint64_t val;
c0ea7c52 18471
c0ea7c52 18472 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18473 READ_ULEB (val, p, end);
c0ea7c52
JL
18474
18475 switch (val)
18476 {
18477 case Val_GNU_MSP430_Data_Region_Any:
18478 printf (_("Any Region\n"));
18479 break;
18480 case Val_GNU_MSP430_Data_Region_Lower:
18481 printf (_("Lower Region Only\n"));
18482 break;
18483 default:
26c527e6 18484 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18485 }
18486 return p;
18487 }
18488 return display_tag_value (tag & 1, p, end);
18489}
18490
2dc8dd17
JW
18491struct riscv_attr_tag_t {
18492 const char *name;
cd30bcef 18493 unsigned int tag;
2dc8dd17
JW
18494};
18495
18496static struct riscv_attr_tag_t riscv_attr_tag[] =
18497{
18498#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18499 T(arch),
18500 T(priv_spec),
18501 T(priv_spec_minor),
18502 T(priv_spec_revision),
18503 T(unaligned_access),
18504 T(stack_align),
18505#undef T
18506};
18507
18508static unsigned char *
18509display_riscv_attribute (unsigned char *p,
18510 const unsigned char * const end)
18511{
26c527e6
AM
18512 uint64_t val;
18513 uint64_t tag;
2dc8dd17
JW
18514 struct riscv_attr_tag_t *attr = NULL;
18515 unsigned i;
18516
cd30bcef 18517 READ_ULEB (tag, p, end);
2dc8dd17
JW
18518
18519 /* Find the name of attribute. */
18520 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18521 {
18522 if (riscv_attr_tag[i].tag == tag)
18523 {
18524 attr = &riscv_attr_tag[i];
18525 break;
18526 }
18527 }
18528
18529 if (attr)
18530 printf (" %s: ", attr->name);
18531 else
18532 return display_tag_value (tag, p, end);
18533
18534 switch (tag)
18535 {
18536 case Tag_RISCV_priv_spec:
18537 case Tag_RISCV_priv_spec_minor:
18538 case Tag_RISCV_priv_spec_revision:
cd30bcef 18539 READ_ULEB (val, p, end);
26c527e6 18540 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18541 break;
18542 case Tag_RISCV_unaligned_access:
cd30bcef 18543 READ_ULEB (val, p, end);
2dc8dd17
JW
18544 switch (val)
18545 {
18546 case 0:
18547 printf (_("No unaligned access\n"));
18548 break;
18549 case 1:
18550 printf (_("Unaligned access\n"));
18551 break;
18552 }
18553 break;
18554 case Tag_RISCV_stack_align:
cd30bcef 18555 READ_ULEB (val, p, end);
26c527e6 18556 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18557 break;
18558 case Tag_RISCV_arch:
18559 p = display_tag_value (-1, p, end);
18560 break;
18561 default:
18562 return display_tag_value (tag, p, end);
18563 }
18564
18565 return p;
18566}
18567
0861f561
CQ
18568static unsigned char *
18569display_csky_attribute (unsigned char * p,
18570 const unsigned char * const end)
18571{
26c527e6
AM
18572 uint64_t tag;
18573 uint64_t val;
0861f561
CQ
18574 READ_ULEB (tag, p, end);
18575
18576 if (tag >= Tag_CSKY_MAX)
18577 {
18578 return display_tag_value (-1, p, end);
18579 }
18580
18581 switch (tag)
18582 {
18583 case Tag_CSKY_ARCH_NAME:
18584 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18585 return display_tag_value (-1, p, end);
18586 case Tag_CSKY_CPU_NAME:
18587 printf (" Tag_CSKY_CPU_NAME:\t\t");
18588 return display_tag_value (-1, p, end);
18589
18590 case Tag_CSKY_ISA_FLAGS:
18591 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18592 return display_tag_value (0, p, end);
18593 case Tag_CSKY_ISA_EXT_FLAGS:
18594 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18595 return display_tag_value (0, p, end);
18596
18597 case Tag_CSKY_DSP_VERSION:
18598 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18599 READ_ULEB (val, p, end);
18600 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18601 printf ("DSP Extension\n");
18602 else if (val == VAL_CSKY_DSP_VERSION_2)
18603 printf ("DSP 2.0\n");
18604 break;
18605
18606 case Tag_CSKY_VDSP_VERSION:
18607 printf (" Tag_CSKY_VDSP_VERSION:\t");
18608 READ_ULEB (val, p, end);
26c527e6 18609 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18610 break;
18611
18612 case Tag_CSKY_FPU_VERSION:
18613 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18614 READ_ULEB (val, p, end);
18615 if (val == VAL_CSKY_FPU_VERSION_1)
18616 printf ("ABIV1 FPU Version 1\n");
18617 else if (val == VAL_CSKY_FPU_VERSION_2)
18618 printf ("FPU Version 2\n");
18619 break;
18620
18621 case Tag_CSKY_FPU_ABI:
18622 printf (" Tag_CSKY_FPU_ABI:\t\t");
18623 READ_ULEB (val, p, end);
18624 if (val == VAL_CSKY_FPU_ABI_HARD)
18625 printf ("Hard\n");
18626 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18627 printf ("SoftFP\n");
18628 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18629 printf ("Soft\n");
18630 break;
18631 case Tag_CSKY_FPU_ROUNDING:
18632 READ_ULEB (val, p, end);
f253158f
NC
18633 if (val == 1)
18634 {
18635 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18636 printf ("Needed\n");
18637 }
0861f561
CQ
18638 break;
18639 case Tag_CSKY_FPU_DENORMAL:
18640 READ_ULEB (val, p, end);
f253158f
NC
18641 if (val == 1)
18642 {
18643 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18644 printf ("Needed\n");
18645 }
0861f561
CQ
18646 break;
18647 case Tag_CSKY_FPU_Exception:
18648 READ_ULEB (val, p, end);
f253158f
NC
18649 if (val == 1)
18650 {
18651 printf (" Tag_CSKY_FPU_Exception:\t");
18652 printf ("Needed\n");
18653 }
0861f561
CQ
18654 break;
18655 case Tag_CSKY_FPU_NUMBER_MODULE:
18656 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18657 return display_tag_value (-1, p, end);
18658 case Tag_CSKY_FPU_HARDFP:
18659 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18660 READ_ULEB (val, p, end);
18661 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18662 printf (" Half");
18663 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18664 printf (" Single");
18665 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18666 printf (" Double");
18667 printf ("\n");
18668 break;
18669 default:
18670 return display_tag_value (tag, p, end);
18671 }
18672 return p;
18673}
18674
015dc7e1 18675static bool
dda8d76d 18676process_attributes (Filedata * filedata,
60bca95a 18677 const char * public_name,
104d59d1 18678 unsigned int proc_type,
f6f0e17b 18679 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18680 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18681{
2cf0635d 18682 Elf_Internal_Shdr * sect;
11c1ff18 18683 unsigned i;
015dc7e1 18684 bool res = true;
11c1ff18
PB
18685
18686 /* Find the section header so that we get the size. */
dda8d76d
NC
18687 for (i = 0, sect = filedata->section_headers;
18688 i < filedata->file_header.e_shnum;
11c1ff18
PB
18689 i++, sect++)
18690 {
071436c6
NC
18691 unsigned char * contents;
18692 unsigned char * p;
18693
104d59d1 18694 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18695 continue;
18696
dda8d76d 18697 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18698 sect->sh_size, _("attributes"));
60bca95a 18699 if (contents == NULL)
32ec8896 18700 {
015dc7e1 18701 res = false;
32ec8896
NC
18702 continue;
18703 }
60bca95a 18704
11c1ff18 18705 p = contents;
60abdbed
NC
18706 /* The first character is the version of the attributes.
18707 Currently only version 1, (aka 'A') is recognised here. */
18708 if (*p != 'A')
32ec8896
NC
18709 {
18710 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18711 res = false;
32ec8896 18712 }
60abdbed 18713 else
11c1ff18 18714 {
625d49fc 18715 uint64_t section_len;
071436c6
NC
18716
18717 section_len = sect->sh_size - 1;
11c1ff18 18718 p++;
60bca95a 18719
071436c6 18720 while (section_len > 0)
11c1ff18 18721 {
625d49fc 18722 uint64_t attr_len;
e9847026 18723 unsigned int namelen;
015dc7e1
AM
18724 bool public_section;
18725 bool gnu_section;
11c1ff18 18726
071436c6 18727 if (section_len <= 4)
e0a31db1
NC
18728 {
18729 error (_("Tag section ends prematurely\n"));
015dc7e1 18730 res = false;
e0a31db1
NC
18731 break;
18732 }
071436c6 18733 attr_len = byte_get (p, 4);
11c1ff18 18734 p += 4;
60bca95a 18735
071436c6 18736 if (attr_len > section_len)
11c1ff18 18737 {
071436c6
NC
18738 error (_("Bad attribute length (%u > %u)\n"),
18739 (unsigned) attr_len, (unsigned) section_len);
18740 attr_len = section_len;
015dc7e1 18741 res = false;
11c1ff18 18742 }
74e1a04b 18743 /* PR 17531: file: 001-101425-0.004 */
071436c6 18744 else if (attr_len < 5)
74e1a04b 18745 {
071436c6 18746 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18747 res = false;
74e1a04b
NC
18748 break;
18749 }
e9847026 18750
071436c6
NC
18751 section_len -= attr_len;
18752 attr_len -= 4;
18753
18754 namelen = strnlen ((char *) p, attr_len) + 1;
18755 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18756 {
18757 error (_("Corrupt attribute section name\n"));
015dc7e1 18758 res = false;
e9847026
NC
18759 break;
18760 }
18761
071436c6 18762 printf (_("Attribute Section: "));
b6ac461a 18763 print_symbol_name (INT_MAX, (const char *) p);
071436c6 18764 putchar ('\n');
60bca95a
NC
18765
18766 if (public_name && streq ((char *) p, public_name))
015dc7e1 18767 public_section = true;
11c1ff18 18768 else
015dc7e1 18769 public_section = false;
60bca95a
NC
18770
18771 if (streq ((char *) p, "gnu"))
015dc7e1 18772 gnu_section = true;
104d59d1 18773 else
015dc7e1 18774 gnu_section = false;
60bca95a 18775
11c1ff18 18776 p += namelen;
071436c6 18777 attr_len -= namelen;
e0a31db1 18778
071436c6 18779 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18780 {
e0a31db1 18781 int tag;
cd30bcef 18782 unsigned int val;
625d49fc 18783 uint64_t size;
071436c6 18784 unsigned char * end;
60bca95a 18785
e0a31db1 18786 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18787 if (attr_len < 6)
e0a31db1
NC
18788 {
18789 error (_("Unused bytes at end of section\n"));
015dc7e1 18790 res = false;
e0a31db1
NC
18791 section_len = 0;
18792 break;
18793 }
18794
18795 tag = *(p++);
11c1ff18 18796 size = byte_get (p, 4);
071436c6 18797 if (size > attr_len)
11c1ff18 18798 {
e9847026 18799 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18800 (unsigned) size, (unsigned) attr_len);
015dc7e1 18801 res = false;
071436c6 18802 size = attr_len;
11c1ff18 18803 }
e0a31db1
NC
18804 /* PR binutils/17531: Safe handling of corrupt files. */
18805 if (size < 6)
18806 {
18807 error (_("Bad subsection length (%u < 6)\n"),
18808 (unsigned) size);
015dc7e1 18809 res = false;
e0a31db1
NC
18810 section_len = 0;
18811 break;
18812 }
60bca95a 18813
071436c6 18814 attr_len -= size;
11c1ff18 18815 end = p + size - 1;
071436c6 18816 assert (end <= contents + sect->sh_size);
11c1ff18 18817 p += 4;
60bca95a 18818
11c1ff18
PB
18819 switch (tag)
18820 {
18821 case 1:
2b692964 18822 printf (_("File Attributes\n"));
11c1ff18
PB
18823 break;
18824 case 2:
2b692964 18825 printf (_("Section Attributes:"));
11c1ff18
PB
18826 goto do_numlist;
18827 case 3:
2b692964 18828 printf (_("Symbol Attributes:"));
1a0670f3 18829 /* Fall through. */
11c1ff18
PB
18830 do_numlist:
18831 for (;;)
18832 {
cd30bcef 18833 READ_ULEB (val, p, end);
11c1ff18
PB
18834 if (val == 0)
18835 break;
18836 printf (" %d", val);
18837 }
18838 printf ("\n");
18839 break;
18840 default:
2b692964 18841 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18842 public_section = false;
11c1ff18
PB
18843 break;
18844 }
60bca95a 18845
071436c6 18846 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18847 {
18848 while (p < end)
f6f0e17b 18849 p = display_pub_attribute (p, end);
60abdbed 18850 assert (p == end);
104d59d1 18851 }
071436c6 18852 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18853 {
18854 while (p < end)
18855 p = display_gnu_attribute (p,
f6f0e17b
NC
18856 display_proc_gnu_attribute,
18857 end);
60abdbed 18858 assert (p == end);
11c1ff18 18859 }
071436c6 18860 else if (p < end)
11c1ff18 18861 {
071436c6 18862 printf (_(" Unknown attribute:\n"));
f6f0e17b 18863 display_raw_attribute (p, end);
11c1ff18
PB
18864 p = end;
18865 }
071436c6
NC
18866 else
18867 attr_len = 0;
11c1ff18
PB
18868 }
18869 }
18870 }
d70c5fc7 18871
60bca95a 18872 free (contents);
11c1ff18 18873 }
32ec8896
NC
18874
18875 return res;
11c1ff18
PB
18876}
18877
ccb4c951
RS
18878/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18879 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18880 and return the VMA of the next entry, or -1 if there was a problem.
18881 Does not read from DATA_END or beyond. */
ccb4c951 18882
625d49fc
AM
18883static uint64_t
18884print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18885 unsigned char * data_end)
ccb4c951
RS
18886{
18887 printf (" ");
18888 print_vma (addr, LONG_HEX);
18889 printf (" ");
18890 if (addr < pltgot + 0xfff0)
18891 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18892 else
18893 printf ("%10s", "");
18894 printf (" ");
18895 if (data == NULL)
2b692964 18896 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18897 else
18898 {
625d49fc 18899 uint64_t entry;
82b1b41b 18900 unsigned char * from = data + addr - pltgot;
ccb4c951 18901
82b1b41b
NC
18902 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18903 {
18904 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18905 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18906 return (uint64_t) -1;
82b1b41b
NC
18907 }
18908 else
18909 {
18910 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18911 print_vma (entry, LONG_HEX);
18912 }
ccb4c951
RS
18913 }
18914 return addr + (is_32bit_elf ? 4 : 8);
18915}
18916
861fb55a
DJ
18917/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18918 PLTGOT. Print the Address and Initial fields of an entry at VMA
18919 ADDR and return the VMA of the next entry. */
18920
625d49fc
AM
18921static uint64_t
18922print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18923{
18924 printf (" ");
18925 print_vma (addr, LONG_HEX);
18926 printf (" ");
18927 if (data == NULL)
2b692964 18928 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18929 else
18930 {
625d49fc 18931 uint64_t entry;
861fb55a
DJ
18932
18933 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18934 print_vma (entry, LONG_HEX);
18935 }
18936 return addr + (is_32bit_elf ? 4 : 8);
18937}
18938
351cdf24
MF
18939static void
18940print_mips_ases (unsigned int mask)
18941{
18942 if (mask & AFL_ASE_DSP)
18943 fputs ("\n\tDSP ASE", stdout);
18944 if (mask & AFL_ASE_DSPR2)
18945 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18946 if (mask & AFL_ASE_DSPR3)
18947 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18948 if (mask & AFL_ASE_EVA)
18949 fputs ("\n\tEnhanced VA Scheme", stdout);
18950 if (mask & AFL_ASE_MCU)
18951 fputs ("\n\tMCU (MicroController) ASE", stdout);
18952 if (mask & AFL_ASE_MDMX)
18953 fputs ("\n\tMDMX ASE", stdout);
18954 if (mask & AFL_ASE_MIPS3D)
18955 fputs ("\n\tMIPS-3D ASE", stdout);
18956 if (mask & AFL_ASE_MT)
18957 fputs ("\n\tMT ASE", stdout);
18958 if (mask & AFL_ASE_SMARTMIPS)
18959 fputs ("\n\tSmartMIPS ASE", stdout);
18960 if (mask & AFL_ASE_VIRT)
18961 fputs ("\n\tVZ ASE", stdout);
18962 if (mask & AFL_ASE_MSA)
18963 fputs ("\n\tMSA ASE", stdout);
18964 if (mask & AFL_ASE_MIPS16)
18965 fputs ("\n\tMIPS16 ASE", stdout);
18966 if (mask & AFL_ASE_MICROMIPS)
18967 fputs ("\n\tMICROMIPS ASE", stdout);
18968 if (mask & AFL_ASE_XPA)
18969 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18970 if (mask & AFL_ASE_MIPS16E2)
18971 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18972 if (mask & AFL_ASE_CRC)
18973 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18974 if (mask & AFL_ASE_GINV)
18975 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18976 if (mask & AFL_ASE_LOONGSON_MMI)
18977 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18978 if (mask & AFL_ASE_LOONGSON_CAM)
18979 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18980 if (mask & AFL_ASE_LOONGSON_EXT)
18981 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18982 if (mask & AFL_ASE_LOONGSON_EXT2)
18983 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18984 if (mask == 0)
18985 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18986 else if ((mask & ~AFL_ASE_MASK) != 0)
18987 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18988}
18989
18990static void
18991print_mips_isa_ext (unsigned int isa_ext)
18992{
18993 switch (isa_ext)
18994 {
18995 case 0:
18996 fputs (_("None"), stdout);
18997 break;
18998 case AFL_EXT_XLR:
18999 fputs ("RMI XLR", stdout);
19000 break;
2c629856
N
19001 case AFL_EXT_OCTEON3:
19002 fputs ("Cavium Networks Octeon3", stdout);
19003 break;
351cdf24
MF
19004 case AFL_EXT_OCTEON2:
19005 fputs ("Cavium Networks Octeon2", stdout);
19006 break;
19007 case AFL_EXT_OCTEONP:
19008 fputs ("Cavium Networks OcteonP", stdout);
19009 break;
351cdf24
MF
19010 case AFL_EXT_OCTEON:
19011 fputs ("Cavium Networks Octeon", stdout);
19012 break;
19013 case AFL_EXT_5900:
19014 fputs ("Toshiba R5900", stdout);
19015 break;
19016 case AFL_EXT_4650:
19017 fputs ("MIPS R4650", stdout);
19018 break;
19019 case AFL_EXT_4010:
19020 fputs ("LSI R4010", stdout);
19021 break;
19022 case AFL_EXT_4100:
19023 fputs ("NEC VR4100", stdout);
19024 break;
19025 case AFL_EXT_3900:
19026 fputs ("Toshiba R3900", stdout);
19027 break;
19028 case AFL_EXT_10000:
19029 fputs ("MIPS R10000", stdout);
19030 break;
19031 case AFL_EXT_SB1:
19032 fputs ("Broadcom SB-1", stdout);
19033 break;
19034 case AFL_EXT_4111:
19035 fputs ("NEC VR4111/VR4181", stdout);
19036 break;
19037 case AFL_EXT_4120:
19038 fputs ("NEC VR4120", stdout);
19039 break;
19040 case AFL_EXT_5400:
19041 fputs ("NEC VR5400", stdout);
19042 break;
19043 case AFL_EXT_5500:
19044 fputs ("NEC VR5500", stdout);
19045 break;
19046 case AFL_EXT_LOONGSON_2E:
19047 fputs ("ST Microelectronics Loongson 2E", stdout);
19048 break;
19049 case AFL_EXT_LOONGSON_2F:
19050 fputs ("ST Microelectronics Loongson 2F", stdout);
19051 break;
38bf472a
MR
19052 case AFL_EXT_INTERAPTIV_MR2:
19053 fputs ("Imagination interAptiv MR2", stdout);
19054 break;
351cdf24 19055 default:
00ac7aa0 19056 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19057 }
19058}
19059
32ec8896 19060static signed int
351cdf24
MF
19061get_mips_reg_size (int reg_size)
19062{
19063 return (reg_size == AFL_REG_NONE) ? 0
19064 : (reg_size == AFL_REG_32) ? 32
19065 : (reg_size == AFL_REG_64) ? 64
19066 : (reg_size == AFL_REG_128) ? 128
19067 : -1;
19068}
19069
015dc7e1 19070static bool
dda8d76d 19071process_mips_specific (Filedata * filedata)
5b18a4bc 19072{
2cf0635d 19073 Elf_Internal_Dyn * entry;
351cdf24 19074 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19075 size_t liblist_offset = 0;
19076 size_t liblistno = 0;
19077 size_t conflictsno = 0;
19078 size_t options_offset = 0;
19079 size_t conflicts_offset = 0;
861fb55a
DJ
19080 size_t pltrelsz = 0;
19081 size_t pltrel = 0;
625d49fc
AM
19082 uint64_t pltgot = 0;
19083 uint64_t mips_pltgot = 0;
19084 uint64_t jmprel = 0;
19085 uint64_t local_gotno = 0;
19086 uint64_t gotsym = 0;
19087 uint64_t symtabno = 0;
015dc7e1 19088 bool res = true;
103f02d3 19089
dda8d76d 19090 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19091 display_mips_gnu_attribute))
015dc7e1 19092 res = false;
2cf19d5c 19093
dda8d76d 19094 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19095
19096 if (sect != NULL)
19097 {
19098 Elf_External_ABIFlags_v0 *abiflags_ext;
19099 Elf_Internal_ABIFlags_v0 abiflags_in;
19100
19101 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19102 {
19103 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19104 res = false;
32ec8896 19105 }
351cdf24
MF
19106 else
19107 {
dda8d76d 19108 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19109 sect->sh_size, _("MIPS ABI Flags section"));
19110 if (abiflags_ext)
19111 {
19112 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19113 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19114 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19115 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19116 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19117 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19118 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19119 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19120 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19121 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19122 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19123
19124 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19125 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19126 if (abiflags_in.isa_rev > 1)
19127 printf ("r%d", abiflags_in.isa_rev);
19128 printf ("\nGPR size: %d",
19129 get_mips_reg_size (abiflags_in.gpr_size));
19130 printf ("\nCPR1 size: %d",
19131 get_mips_reg_size (abiflags_in.cpr1_size));
19132 printf ("\nCPR2 size: %d",
19133 get_mips_reg_size (abiflags_in.cpr2_size));
19134 fputs ("\nFP ABI: ", stdout);
19135 print_mips_fp_abi_value (abiflags_in.fp_abi);
19136 fputs ("ISA Extension: ", stdout);
19137 print_mips_isa_ext (abiflags_in.isa_ext);
19138 fputs ("\nASEs:", stdout);
19139 print_mips_ases (abiflags_in.ases);
19140 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19141 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19142 fputc ('\n', stdout);
19143 free (abiflags_ext);
19144 }
19145 }
19146 }
19147
19e6b90e 19148 /* We have a lot of special sections. Thanks SGI! */
978c4450 19149 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19150 {
19151 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19152 sect = find_section (filedata, ".got");
bbdd9a68
MR
19153 if (sect != NULL)
19154 {
19155 unsigned char *data_end;
19156 unsigned char *data;
625d49fc 19157 uint64_t ent, end;
bbdd9a68
MR
19158 int addr_size;
19159
19160 pltgot = sect->sh_addr;
19161
19162 ent = pltgot;
19163 addr_size = (is_32bit_elf ? 4 : 8);
19164 end = pltgot + sect->sh_size;
19165
dda8d76d 19166 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19167 end - pltgot, 1,
19168 _("Global Offset Table data"));
19169 /* PR 12855: Null data is handled gracefully throughout. */
19170 data_end = data + (end - pltgot);
19171
19172 printf (_("\nStatic GOT:\n"));
19173 printf (_(" Canonical gp value: "));
19174 print_vma (ent + 0x7ff0, LONG_HEX);
19175 printf ("\n\n");
19176
19177 /* In a dynamic binary GOT[0] is reserved for the dynamic
19178 loader to store the lazy resolver pointer, however in
19179 a static binary it may well have been omitted and GOT
19180 reduced to a table of addresses.
19181 PR 21344: Check for the entry being fully available
19182 before fetching it. */
19183 if (data
19184 && data + ent - pltgot + addr_size <= data_end
19185 && byte_get (data + ent - pltgot, addr_size) == 0)
19186 {
19187 printf (_(" Reserved entries:\n"));
19188 printf (_(" %*s %10s %*s\n"),
19189 addr_size * 2, _("Address"), _("Access"),
19190 addr_size * 2, _("Value"));
19191 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19192 printf ("\n");
625d49fc 19193 if (ent == (uint64_t) -1)
bbdd9a68
MR
19194 goto sgot_print_fail;
19195
19196 /* Check for the MSB of GOT[1] being set, identifying a
19197 GNU object. This entry will be used by some runtime
19198 loaders, to store the module pointer. Otherwise this
19199 is an ordinary local entry.
19200 PR 21344: Check for the entry being fully available
19201 before fetching it. */
19202 if (data
19203 && data + ent - pltgot + addr_size <= data_end
19204 && (byte_get (data + ent - pltgot, addr_size)
19205 >> (addr_size * 8 - 1)) != 0)
19206 {
19207 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19208 printf ("\n");
625d49fc 19209 if (ent == (uint64_t) -1)
bbdd9a68
MR
19210 goto sgot_print_fail;
19211 }
19212 printf ("\n");
19213 }
19214
f17e9d8a 19215 if (data != NULL && ent < end)
bbdd9a68
MR
19216 {
19217 printf (_(" Local entries:\n"));
19218 printf (" %*s %10s %*s\n",
19219 addr_size * 2, _("Address"), _("Access"),
19220 addr_size * 2, _("Value"));
19221 while (ent < end)
19222 {
19223 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19224 printf ("\n");
625d49fc 19225 if (ent == (uint64_t) -1)
bbdd9a68
MR
19226 goto sgot_print_fail;
19227 }
19228 printf ("\n");
19229 }
19230
19231 sgot_print_fail:
9db70fc3 19232 free (data);
bbdd9a68
MR
19233 }
19234 return res;
19235 }
252b5132 19236
978c4450 19237 for (entry = filedata->dynamic_section;
071436c6 19238 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19239 (entry < filedata->dynamic_section + filedata->dynamic_nent
19240 && entry->d_tag != DT_NULL);
071436c6 19241 ++entry)
252b5132
RH
19242 switch (entry->d_tag)
19243 {
19244 case DT_MIPS_LIBLIST:
d93f0186 19245 liblist_offset
dda8d76d 19246 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19247 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19248 break;
19249 case DT_MIPS_LIBLISTNO:
19250 liblistno = entry->d_un.d_val;
19251 break;
19252 case DT_MIPS_OPTIONS:
dda8d76d 19253 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19254 break;
19255 case DT_MIPS_CONFLICT:
d93f0186 19256 conflicts_offset
dda8d76d 19257 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19258 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19259 break;
19260 case DT_MIPS_CONFLICTNO:
19261 conflictsno = entry->d_un.d_val;
19262 break;
ccb4c951 19263 case DT_PLTGOT:
861fb55a
DJ
19264 pltgot = entry->d_un.d_ptr;
19265 break;
ccb4c951
RS
19266 case DT_MIPS_LOCAL_GOTNO:
19267 local_gotno = entry->d_un.d_val;
19268 break;
19269 case DT_MIPS_GOTSYM:
19270 gotsym = entry->d_un.d_val;
19271 break;
19272 case DT_MIPS_SYMTABNO:
19273 symtabno = entry->d_un.d_val;
19274 break;
861fb55a
DJ
19275 case DT_MIPS_PLTGOT:
19276 mips_pltgot = entry->d_un.d_ptr;
19277 break;
19278 case DT_PLTREL:
19279 pltrel = entry->d_un.d_val;
19280 break;
19281 case DT_PLTRELSZ:
19282 pltrelsz = entry->d_un.d_val;
19283 break;
19284 case DT_JMPREL:
19285 jmprel = entry->d_un.d_ptr;
19286 break;
252b5132
RH
19287 default:
19288 break;
19289 }
19290
19291 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19292 {
2cf0635d 19293 Elf32_External_Lib * elib;
252b5132
RH
19294 size_t cnt;
19295
dda8d76d 19296 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19297 sizeof (Elf32_External_Lib),
19298 liblistno,
19299 _("liblist section data"));
a6e9f9df 19300 if (elib)
252b5132 19301 {
26c527e6
AM
19302 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19303 "\nSection '.liblist' contains %zu entries:\n",
19304 liblistno),
19305 liblistno);
2b692964 19306 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19307 stdout);
19308
19309 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19310 {
a6e9f9df 19311 Elf32_Lib liblist;
91d6fa6a 19312 time_t atime;
d5b07ef4 19313 char timebuf[128];
2cf0635d 19314 struct tm * tmp;
a6e9f9df
AM
19315
19316 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19317 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19318 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19319 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19320 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19321
91d6fa6a 19322 tmp = gmtime (&atime);
e9e44622
JJ
19323 snprintf (timebuf, sizeof (timebuf),
19324 "%04u-%02u-%02uT%02u:%02u:%02u",
19325 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19326 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19327
26c527e6 19328 printf ("%3zu: ", cnt);
84714f86 19329 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19330 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19331 else
2b692964 19332 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19333 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19334 liblist.l_version);
a6e9f9df
AM
19335
19336 if (liblist.l_flags == 0)
2b692964 19337 puts (_(" NONE"));
a6e9f9df
AM
19338 else
19339 {
19340 static const struct
252b5132 19341 {
2cf0635d 19342 const char * name;
a6e9f9df 19343 int bit;
252b5132 19344 }
a6e9f9df
AM
19345 l_flags_vals[] =
19346 {
19347 { " EXACT_MATCH", LL_EXACT_MATCH },
19348 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19349 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19350 { " EXPORTS", LL_EXPORTS },
19351 { " DELAY_LOAD", LL_DELAY_LOAD },
19352 { " DELTA", LL_DELTA }
19353 };
19354 int flags = liblist.l_flags;
19355 size_t fcnt;
19356
60bca95a 19357 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19358 if ((flags & l_flags_vals[fcnt].bit) != 0)
19359 {
19360 fputs (l_flags_vals[fcnt].name, stdout);
19361 flags ^= l_flags_vals[fcnt].bit;
19362 }
19363 if (flags != 0)
19364 printf (" %#x", (unsigned int) flags);
252b5132 19365
a6e9f9df
AM
19366 puts ("");
19367 }
252b5132 19368 }
252b5132 19369
a6e9f9df
AM
19370 free (elib);
19371 }
32ec8896 19372 else
015dc7e1 19373 res = false;
252b5132
RH
19374 }
19375
19376 if (options_offset != 0)
19377 {
2cf0635d 19378 Elf_External_Options * eopt;
252b5132
RH
19379 size_t offset;
19380 int cnt;
19381
19382 /* Find the section header so that we get the size. */
dda8d76d 19383 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19384 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19385 if (sect == NULL)
19386 {
19387 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19388 return false;
071436c6 19389 }
7fc0c668
NC
19390 /* PR 24243 */
19391 if (sect->sh_size < sizeof (* eopt))
19392 {
19393 error (_("The MIPS options section is too small.\n"));
015dc7e1 19394 return false;
7fc0c668 19395 }
252b5132 19396
dda8d76d 19397 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19398 sect->sh_size, _("options"));
a6e9f9df 19399 if (eopt)
252b5132 19400 {
fd17d1e6 19401 Elf_Internal_Options option;
76da6bbe 19402
a6e9f9df 19403 offset = cnt = 0;
82b1b41b 19404 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19405 {
2cf0635d 19406 Elf_External_Options * eoption;
fd17d1e6 19407 unsigned int optsize;
252b5132 19408
a6e9f9df 19409 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19410
fd17d1e6 19411 optsize = BYTE_GET (eoption->size);
76da6bbe 19412
82b1b41b 19413 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19414 if (optsize < sizeof (* eopt)
19415 || optsize > sect->sh_size - offset)
82b1b41b 19416 {
645f43a8 19417 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19418 optsize);
645f43a8 19419 free (eopt);
015dc7e1 19420 return false;
82b1b41b 19421 }
fd17d1e6 19422 offset += optsize;
a6e9f9df
AM
19423 ++cnt;
19424 }
252b5132 19425
d3a49aa8
AM
19426 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19427 "\nSection '%s' contains %d entries:\n",
19428 cnt),
dda8d76d 19429 printable_section_name (filedata, sect), cnt);
76da6bbe 19430
82b1b41b 19431 offset = 0;
a6e9f9df 19432 while (cnt-- > 0)
252b5132 19433 {
a6e9f9df 19434 size_t len;
fd17d1e6
AM
19435 Elf_External_Options * eoption;
19436
19437 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19438
19439 option.kind = BYTE_GET (eoption->kind);
19440 option.size = BYTE_GET (eoption->size);
19441 option.section = BYTE_GET (eoption->section);
19442 option.info = BYTE_GET (eoption->info);
a6e9f9df 19443
fd17d1e6 19444 switch (option.kind)
252b5132 19445 {
a6e9f9df
AM
19446 case ODK_NULL:
19447 /* This shouldn't happen. */
d0c4e780 19448 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19449 option.section, option.info);
a6e9f9df 19450 break;
2e6be59c 19451
a6e9f9df
AM
19452 case ODK_REGINFO:
19453 printf (" REGINFO ");
dda8d76d 19454 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19455 {
2cf0635d 19456 Elf32_External_RegInfo * ereg;
b34976b6 19457 Elf32_RegInfo reginfo;
a6e9f9df 19458
2e6be59c 19459 /* 32bit form. */
fd17d1e6
AM
19460 if (option.size < (sizeof (Elf_External_Options)
19461 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19462 {
19463 printf (_("<corrupt>\n"));
19464 error (_("Truncated MIPS REGINFO option\n"));
19465 cnt = 0;
19466 break;
19467 }
19468
fd17d1e6 19469 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19470
a6e9f9df
AM
19471 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19472 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19473 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19474 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19475 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19476 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19477
d0c4e780
AM
19478 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19479 reginfo.ri_gprmask, reginfo.ri_gp_value);
19480 printf (" "
19481 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19482 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19483 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19484 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19485 }
19486 else
19487 {
19488 /* 64 bit form. */
2cf0635d 19489 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19490 Elf64_Internal_RegInfo reginfo;
19491
fd17d1e6
AM
19492 if (option.size < (sizeof (Elf_External_Options)
19493 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19494 {
19495 printf (_("<corrupt>\n"));
19496 error (_("Truncated MIPS REGINFO option\n"));
19497 cnt = 0;
19498 break;
19499 }
19500
fd17d1e6 19501 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19502 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19503 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19504 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19505 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19506 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19507 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19508
d0c4e780
AM
19509 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19510 reginfo.ri_gprmask, reginfo.ri_gp_value);
19511 printf (" "
19512 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19513 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19514 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19515 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19516 }
fd17d1e6 19517 offset += option.size;
a6e9f9df 19518 continue;
2e6be59c 19519
a6e9f9df
AM
19520 case ODK_EXCEPTIONS:
19521 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19522 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19523 fputs (") fpe_max(", stdout);
fd17d1e6 19524 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19525 fputs (")", stdout);
19526
fd17d1e6 19527 if (option.info & OEX_PAGE0)
a6e9f9df 19528 fputs (" PAGE0", stdout);
fd17d1e6 19529 if (option.info & OEX_SMM)
a6e9f9df 19530 fputs (" SMM", stdout);
fd17d1e6 19531 if (option.info & OEX_FPDBUG)
a6e9f9df 19532 fputs (" FPDBUG", stdout);
fd17d1e6 19533 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19534 fputs (" DISMISS", stdout);
19535 break;
2e6be59c 19536
a6e9f9df
AM
19537 case ODK_PAD:
19538 fputs (" PAD ", stdout);
fd17d1e6 19539 if (option.info & OPAD_PREFIX)
a6e9f9df 19540 fputs (" PREFIX", stdout);
fd17d1e6 19541 if (option.info & OPAD_POSTFIX)
a6e9f9df 19542 fputs (" POSTFIX", stdout);
fd17d1e6 19543 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19544 fputs (" SYMBOL", stdout);
19545 break;
2e6be59c 19546
a6e9f9df
AM
19547 case ODK_HWPATCH:
19548 fputs (" HWPATCH ", stdout);
fd17d1e6 19549 if (option.info & OHW_R4KEOP)
a6e9f9df 19550 fputs (" R4KEOP", stdout);
fd17d1e6 19551 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19552 fputs (" R8KPFETCH", stdout);
fd17d1e6 19553 if (option.info & OHW_R5KEOP)
a6e9f9df 19554 fputs (" R5KEOP", stdout);
fd17d1e6 19555 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19556 fputs (" R5KCVTL", stdout);
19557 break;
2e6be59c 19558
a6e9f9df
AM
19559 case ODK_FILL:
19560 fputs (" FILL ", stdout);
19561 /* XXX Print content of info word? */
19562 break;
2e6be59c 19563
a6e9f9df
AM
19564 case ODK_TAGS:
19565 fputs (" TAGS ", stdout);
19566 /* XXX Print content of info word? */
19567 break;
2e6be59c 19568
a6e9f9df
AM
19569 case ODK_HWAND:
19570 fputs (" HWAND ", stdout);
fd17d1e6 19571 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19572 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19573 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19574 fputs (" R4KEOP_CLEAN", stdout);
19575 break;
2e6be59c 19576
a6e9f9df
AM
19577 case ODK_HWOR:
19578 fputs (" HWOR ", stdout);
fd17d1e6 19579 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19580 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19581 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19582 fputs (" R4KEOP_CLEAN", stdout);
19583 break;
2e6be59c 19584
a6e9f9df 19585 case ODK_GP_GROUP:
d0c4e780 19586 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19587 option.info & OGP_GROUP,
19588 (option.info & OGP_SELF) >> 16);
a6e9f9df 19589 break;
2e6be59c 19590
a6e9f9df 19591 case ODK_IDENT:
d0c4e780 19592 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19593 option.info & OGP_GROUP,
19594 (option.info & OGP_SELF) >> 16);
a6e9f9df 19595 break;
2e6be59c 19596
a6e9f9df
AM
19597 default:
19598 /* This shouldn't happen. */
d0c4e780 19599 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19600 option.kind, option.section, option.info);
a6e9f9df 19601 break;
252b5132 19602 }
a6e9f9df 19603
2cf0635d 19604 len = sizeof (* eopt);
fd17d1e6 19605 while (len < option.size)
82b1b41b 19606 {
fd17d1e6 19607 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19608
82b1b41b
NC
19609 if (ISPRINT (datum))
19610 printf ("%c", datum);
19611 else
19612 printf ("\\%03o", datum);
19613 len ++;
19614 }
a6e9f9df 19615 fputs ("\n", stdout);
82b1b41b 19616
fd17d1e6 19617 offset += option.size;
252b5132 19618 }
a6e9f9df 19619 free (eopt);
252b5132 19620 }
32ec8896 19621 else
015dc7e1 19622 res = false;
252b5132
RH
19623 }
19624
19625 if (conflicts_offset != 0 && conflictsno != 0)
19626 {
2cf0635d 19627 Elf32_Conflict * iconf;
252b5132
RH
19628 size_t cnt;
19629
978c4450 19630 if (filedata->dynamic_symbols == NULL)
252b5132 19631 {
591a748a 19632 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19633 return false;
252b5132
RH
19634 }
19635
7296a62a
NC
19636 /* PR 21345 - print a slightly more helpful error message
19637 if we are sure that the cmalloc will fail. */
645f43a8 19638 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19639 {
26c527e6
AM
19640 error (_("Overlarge number of conflicts detected: %zx\n"),
19641 conflictsno);
015dc7e1 19642 return false;
7296a62a
NC
19643 }
19644
3f5e193b 19645 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19646 if (iconf == NULL)
19647 {
8b73c356 19648 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19649 return false;
252b5132
RH
19650 }
19651
9ea033b2 19652 if (is_32bit_elf)
252b5132 19653 {
2cf0635d 19654 Elf32_External_Conflict * econf32;
a6e9f9df 19655
3f5e193b 19656 econf32 = (Elf32_External_Conflict *)
95099889
AM
19657 get_data (NULL, filedata, conflicts_offset,
19658 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19659 if (!econf32)
5a814d6d
AM
19660 {
19661 free (iconf);
015dc7e1 19662 return false;
5a814d6d 19663 }
252b5132
RH
19664
19665 for (cnt = 0; cnt < conflictsno; ++cnt)
19666 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19667
19668 free (econf32);
252b5132
RH
19669 }
19670 else
19671 {
2cf0635d 19672 Elf64_External_Conflict * econf64;
a6e9f9df 19673
3f5e193b 19674 econf64 = (Elf64_External_Conflict *)
95099889
AM
19675 get_data (NULL, filedata, conflicts_offset,
19676 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19677 if (!econf64)
5a814d6d
AM
19678 {
19679 free (iconf);
015dc7e1 19680 return false;
5a814d6d 19681 }
252b5132
RH
19682
19683 for (cnt = 0; cnt < conflictsno; ++cnt)
19684 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19685
19686 free (econf64);
252b5132
RH
19687 }
19688
26c527e6
AM
19689 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19690 "\nSection '.conflict' contains %zu entries:\n",
19691 conflictsno),
19692 conflictsno);
252b5132
RH
19693 puts (_(" Num: Index Value Name"));
19694
19695 for (cnt = 0; cnt < conflictsno; ++cnt)
19696 {
26c527e6 19697 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19698
978c4450 19699 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19700 printf (_("<corrupt symbol index>"));
d79b3d50 19701 else
e0a31db1
NC
19702 {
19703 Elf_Internal_Sym * psym;
19704
978c4450 19705 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19706 print_vma (psym->st_value, FULL_HEX);
19707 putchar (' ');
84714f86 19708 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19709 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19710 else
19711 printf (_("<corrupt: %14ld>"), psym->st_name);
19712 }
31104126 19713 putchar ('\n');
252b5132
RH
19714 }
19715
252b5132
RH
19716 free (iconf);
19717 }
19718
ccb4c951
RS
19719 if (pltgot != 0 && local_gotno != 0)
19720 {
625d49fc 19721 uint64_t ent, local_end, global_end;
bbeee7ea 19722 size_t i, offset;
2cf0635d 19723 unsigned char * data;
82b1b41b 19724 unsigned char * data_end;
bbeee7ea 19725 int addr_size;
ccb4c951 19726
91d6fa6a 19727 ent = pltgot;
ccb4c951
RS
19728 addr_size = (is_32bit_elf ? 4 : 8);
19729 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19730
74e1a04b
NC
19731 /* PR binutils/17533 file: 012-111227-0.004 */
19732 if (symtabno < gotsym)
19733 {
26c527e6
AM
19734 error (_("The GOT symbol offset (%" PRIu64
19735 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19736 gotsym, symtabno);
015dc7e1 19737 return false;
74e1a04b 19738 }
82b1b41b 19739
74e1a04b 19740 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19741 /* PR 17531: file: 54c91a34. */
19742 if (global_end < local_end)
19743 {
26c527e6 19744 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19745 return false;
82b1b41b 19746 }
948f632f 19747
dda8d76d
NC
19748 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19749 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19750 global_end - pltgot, 1,
19751 _("Global Offset Table data"));
919383ac 19752 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19753 data_end = data + (global_end - pltgot);
59245841 19754
ccb4c951
RS
19755 printf (_("\nPrimary GOT:\n"));
19756 printf (_(" Canonical gp value: "));
19757 print_vma (pltgot + 0x7ff0, LONG_HEX);
19758 printf ("\n\n");
19759
19760 printf (_(" Reserved entries:\n"));
19761 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19762 addr_size * 2, _("Address"), _("Access"),
19763 addr_size * 2, _("Initial"));
82b1b41b 19764 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19765 printf (_(" Lazy resolver\n"));
625d49fc 19766 if (ent == (uint64_t) -1)
82b1b41b 19767 goto got_print_fail;
75ec1fdb 19768
c4ab9505
MR
19769 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19770 This entry will be used by some runtime loaders, to store the
19771 module pointer. Otherwise this is an ordinary local entry.
19772 PR 21344: Check for the entry being fully available before
19773 fetching it. */
19774 if (data
19775 && data + ent - pltgot + addr_size <= data_end
19776 && (byte_get (data + ent - pltgot, addr_size)
19777 >> (addr_size * 8 - 1)) != 0)
19778 {
19779 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19780 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19781 if (ent == (uint64_t) -1)
c4ab9505 19782 goto got_print_fail;
ccb4c951
RS
19783 }
19784 printf ("\n");
19785
f17e9d8a 19786 if (data != NULL && ent < local_end)
ccb4c951
RS
19787 {
19788 printf (_(" Local entries:\n"));
cc5914eb 19789 printf (" %*s %10s %*s\n",
2b692964
NC
19790 addr_size * 2, _("Address"), _("Access"),
19791 addr_size * 2, _("Initial"));
91d6fa6a 19792 while (ent < local_end)
ccb4c951 19793 {
82b1b41b 19794 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19795 printf ("\n");
625d49fc 19796 if (ent == (uint64_t) -1)
82b1b41b 19797 goto got_print_fail;
ccb4c951
RS
19798 }
19799 printf ("\n");
19800 }
19801
f17e9d8a 19802 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19803 {
19804 int sym_width;
19805
19806 printf (_(" Global entries:\n"));
cc5914eb 19807 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19808 addr_size * 2, _("Address"),
19809 _("Access"),
2b692964 19810 addr_size * 2, _("Initial"),
9cf03b7e
NC
19811 addr_size * 2, _("Sym.Val."),
19812 _("Type"),
19813 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19814 _("Ndx"), _("Name"));
0b4362b0 19815
ccb4c951 19816 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19817
ccb4c951
RS
19818 for (i = gotsym; i < symtabno; i++)
19819 {
82b1b41b 19820 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19821 printf (" ");
e0a31db1 19822
978c4450 19823 if (filedata->dynamic_symbols == NULL)
e0a31db1 19824 printf (_("<no dynamic symbols>"));
978c4450 19825 else if (i < filedata->num_dynamic_syms)
e0a31db1 19826 {
978c4450 19827 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19828
19829 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
19830 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19831
19832 bool is_special;
19833 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19834 if (is_special)
19835 printf ("%3s ", s);
19836 else
19837 printf ("%3u ", psym->st_shndx);
e0a31db1 19838
84714f86 19839 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19840 print_symbol_name (sym_width,
84714f86 19841 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19842 else
19843 printf (_("<corrupt: %14ld>"), psym->st_name);
19844 }
ccb4c951 19845 else
26c527e6
AM
19846 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19847 i);
e0a31db1 19848
ccb4c951 19849 printf ("\n");
625d49fc 19850 if (ent == (uint64_t) -1)
82b1b41b 19851 break;
ccb4c951
RS
19852 }
19853 printf ("\n");
19854 }
19855
82b1b41b 19856 got_print_fail:
9db70fc3 19857 free (data);
ccb4c951
RS
19858 }
19859
861fb55a
DJ
19860 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19861 {
625d49fc 19862 uint64_t ent, end;
26c527e6
AM
19863 uint64_t offset, rel_offset;
19864 uint64_t count, i;
2cf0635d 19865 unsigned char * data;
861fb55a 19866 int addr_size, sym_width;
2cf0635d 19867 Elf_Internal_Rela * rels;
861fb55a 19868
dda8d76d 19869 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19870 if (pltrel == DT_RELA)
19871 {
dda8d76d 19872 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19873 return false;
861fb55a
DJ
19874 }
19875 else
19876 {
dda8d76d 19877 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19878 return false;
861fb55a
DJ
19879 }
19880
91d6fa6a 19881 ent = mips_pltgot;
861fb55a
DJ
19882 addr_size = (is_32bit_elf ? 4 : 8);
19883 end = mips_pltgot + (2 + count) * addr_size;
19884
dda8d76d
NC
19885 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19886 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19887 1, _("Procedure Linkage Table data"));
59245841 19888 if (data == NULL)
288f0ba2
AM
19889 {
19890 free (rels);
015dc7e1 19891 return false;
288f0ba2 19892 }
59245841 19893
9cf03b7e 19894 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19895 printf (_(" Reserved entries:\n"));
19896 printf (_(" %*s %*s Purpose\n"),
2b692964 19897 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19898 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19899 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19900 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19901 printf (_(" Module pointer\n"));
861fb55a
DJ
19902 printf ("\n");
19903
19904 printf (_(" Entries:\n"));
cc5914eb 19905 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19906 addr_size * 2, _("Address"),
19907 addr_size * 2, _("Initial"),
19908 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19909 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19910 for (i = 0; i < count; i++)
19911 {
26c527e6 19912 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19913
91d6fa6a 19914 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19915 printf (" ");
e0a31db1 19916
978c4450 19917 if (idx >= filedata->num_dynamic_syms)
26c527e6 19918 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19919 else
e0a31db1 19920 {
978c4450 19921 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19922
19923 print_vma (psym->st_value, LONG_HEX);
19924 printf (" %-7s %3s ",
dda8d76d 19925 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 19926 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 19927 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19928 print_symbol_name (sym_width,
84714f86 19929 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19930 else
19931 printf (_("<corrupt: %14ld>"), psym->st_name);
19932 }
861fb55a
DJ
19933 printf ("\n");
19934 }
19935 printf ("\n");
19936
9db70fc3 19937 free (data);
861fb55a
DJ
19938 free (rels);
19939 }
19940
32ec8896 19941 return res;
252b5132
RH
19942}
19943
015dc7e1 19944static bool
dda8d76d 19945process_nds32_specific (Filedata * filedata)
35c08157
KLC
19946{
19947 Elf_Internal_Shdr *sect = NULL;
19948
dda8d76d 19949 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19950 if (sect != NULL && sect->sh_size >= 4)
35c08157 19951 {
9c7b8e9b
AM
19952 unsigned char *buf;
19953 unsigned int flag;
35c08157
KLC
19954
19955 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19956 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19957 _("NDS32 elf flags section"));
35c08157 19958
9c7b8e9b 19959 if (buf == NULL)
015dc7e1 19960 return false;
32ec8896 19961
9c7b8e9b
AM
19962 flag = byte_get (buf, 4);
19963 free (buf);
19964 switch (flag & 0x3)
35c08157
KLC
19965 {
19966 case 0:
19967 printf ("(VEC_SIZE):\tNo entry.\n");
19968 break;
19969 case 1:
19970 printf ("(VEC_SIZE):\t4 bytes\n");
19971 break;
19972 case 2:
19973 printf ("(VEC_SIZE):\t16 bytes\n");
19974 break;
19975 case 3:
19976 printf ("(VEC_SIZE):\treserved\n");
19977 break;
19978 }
19979 }
19980
015dc7e1 19981 return true;
35c08157
KLC
19982}
19983
015dc7e1 19984static bool
dda8d76d 19985process_gnu_liblist (Filedata * filedata)
047b2264 19986{
2cf0635d
NC
19987 Elf_Internal_Shdr * section;
19988 Elf_Internal_Shdr * string_sec;
19989 Elf32_External_Lib * elib;
19990 char * strtab;
c256ffe7 19991 size_t strtab_size;
047b2264 19992 size_t cnt;
26c527e6 19993 uint64_t num_liblist;
047b2264 19994 unsigned i;
015dc7e1 19995 bool res = true;
047b2264
JJ
19996
19997 if (! do_arch)
015dc7e1 19998 return true;
047b2264 19999
dda8d76d
NC
20000 for (i = 0, section = filedata->section_headers;
20001 i < filedata->file_header.e_shnum;
b34976b6 20002 i++, section++)
047b2264
JJ
20003 {
20004 switch (section->sh_type)
20005 {
20006 case SHT_GNU_LIBLIST:
dda8d76d 20007 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20008 break;
20009
3f5e193b 20010 elib = (Elf32_External_Lib *)
dda8d76d 20011 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20012 _("liblist section data"));
047b2264
JJ
20013
20014 if (elib == NULL)
32ec8896 20015 {
015dc7e1 20016 res = false;
32ec8896
NC
20017 break;
20018 }
047b2264 20019
dda8d76d
NC
20020 string_sec = filedata->section_headers + section->sh_link;
20021 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20022 string_sec->sh_size,
20023 _("liblist string table"));
047b2264
JJ
20024 if (strtab == NULL
20025 || section->sh_entsize != sizeof (Elf32_External_Lib))
20026 {
20027 free (elib);
2842702f 20028 free (strtab);
015dc7e1 20029 res = false;
047b2264
JJ
20030 break;
20031 }
59245841 20032 strtab_size = string_sec->sh_size;
047b2264 20033
d3a49aa8 20034 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20035 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20036 " entries:\n",
20037 "\nLibrary list section '%s' contains %" PRIu64
20038 " entries:\n",
d3a49aa8 20039 num_liblist),
dda8d76d 20040 printable_section_name (filedata, section),
d3a49aa8 20041 num_liblist);
047b2264 20042
2b692964 20043 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20044
20045 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20046 ++cnt)
20047 {
20048 Elf32_Lib liblist;
91d6fa6a 20049 time_t atime;
d5b07ef4 20050 char timebuf[128];
2cf0635d 20051 struct tm * tmp;
047b2264
JJ
20052
20053 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20054 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20055 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20056 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20057 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20058
91d6fa6a 20059 tmp = gmtime (&atime);
e9e44622
JJ
20060 snprintf (timebuf, sizeof (timebuf),
20061 "%04u-%02u-%02uT%02u:%02u:%02u",
20062 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20063 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20064
26c527e6 20065 printf ("%3zu: ", cnt);
047b2264 20066 if (do_wide)
c256ffe7 20067 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20068 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20069 else
c256ffe7 20070 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20071 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20072 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20073 liblist.l_version, liblist.l_flags);
20074 }
20075
20076 free (elib);
2842702f 20077 free (strtab);
047b2264
JJ
20078 }
20079 }
20080
32ec8896 20081 return res;
047b2264
JJ
20082}
20083
9437c45b 20084static const char *
dda8d76d 20085get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20086{
20087 static char buff[64];
103f02d3 20088
dda8d76d 20089 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20090 switch (e_type)
20091 {
57346661 20092 case NT_AUXV:
1ec5cd37 20093 return _("NT_AUXV (auxiliary vector)");
57346661 20094 case NT_PRSTATUS:
1ec5cd37 20095 return _("NT_PRSTATUS (prstatus structure)");
57346661 20096 case NT_FPREGSET:
1ec5cd37 20097 return _("NT_FPREGSET (floating point registers)");
57346661 20098 case NT_PRPSINFO:
1ec5cd37 20099 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20100 case NT_TASKSTRUCT:
1ec5cd37 20101 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20102 case NT_GDB_TDESC:
20103 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20104 case NT_PRXFPREG:
1ec5cd37 20105 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20106 case NT_PPC_VMX:
20107 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20108 case NT_PPC_VSX:
20109 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20110 case NT_PPC_TAR:
20111 return _("NT_PPC_TAR (ppc TAR register)");
20112 case NT_PPC_PPR:
20113 return _("NT_PPC_PPR (ppc PPR register)");
20114 case NT_PPC_DSCR:
20115 return _("NT_PPC_DSCR (ppc DSCR register)");
20116 case NT_PPC_EBB:
20117 return _("NT_PPC_EBB (ppc EBB registers)");
20118 case NT_PPC_PMU:
20119 return _("NT_PPC_PMU (ppc PMU registers)");
20120 case NT_PPC_TM_CGPR:
20121 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20122 case NT_PPC_TM_CFPR:
20123 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20124 case NT_PPC_TM_CVMX:
20125 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20126 case NT_PPC_TM_CVSX:
3fd21718 20127 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20128 case NT_PPC_TM_SPR:
20129 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20130 case NT_PPC_TM_CTAR:
20131 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20132 case NT_PPC_TM_CPPR:
20133 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20134 case NT_PPC_TM_CDSCR:
20135 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20136 case NT_386_TLS:
20137 return _("NT_386_TLS (x86 TLS information)");
20138 case NT_386_IOPERM:
20139 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20140 case NT_X86_XSTATE:
20141 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20142 case NT_X86_CET:
20143 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
20144 case NT_S390_HIGH_GPRS:
20145 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20146 case NT_S390_TIMER:
20147 return _("NT_S390_TIMER (s390 timer register)");
20148 case NT_S390_TODCMP:
20149 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20150 case NT_S390_TODPREG:
20151 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20152 case NT_S390_CTRS:
20153 return _("NT_S390_CTRS (s390 control registers)");
20154 case NT_S390_PREFIX:
20155 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20156 case NT_S390_LAST_BREAK:
20157 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20158 case NT_S390_SYSTEM_CALL:
20159 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20160 case NT_S390_TDB:
20161 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20162 case NT_S390_VXRS_LOW:
20163 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20164 case NT_S390_VXRS_HIGH:
20165 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20166 case NT_S390_GS_CB:
20167 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20168 case NT_S390_GS_BC:
20169 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20170 case NT_ARM_VFP:
20171 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20172 case NT_ARM_TLS:
20173 return _("NT_ARM_TLS (AArch TLS registers)");
20174 case NT_ARM_HW_BREAK:
20175 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20176 case NT_ARM_HW_WATCH:
20177 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20178 case NT_ARM_SYSTEM_CALL:
20179 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20180 case NT_ARM_SVE:
20181 return _("NT_ARM_SVE (AArch SVE registers)");
20182 case NT_ARM_PAC_MASK:
20183 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20184 case NT_ARM_PACA_KEYS:
20185 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20186 case NT_ARM_PACG_KEYS:
20187 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20188 case NT_ARM_TAGGED_ADDR_CTRL:
20189 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20190 case NT_ARM_SSVE:
20191 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20192 case NT_ARM_ZA:
20193 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20194 case NT_ARM_ZT:
20195 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20196 case NT_ARM_PAC_ENABLED_KEYS:
20197 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20198 case NT_ARC_V2:
20199 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20200 case NT_RISCV_CSR:
20201 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20202 case NT_PSTATUS:
1ec5cd37 20203 return _("NT_PSTATUS (pstatus structure)");
57346661 20204 case NT_FPREGS:
1ec5cd37 20205 return _("NT_FPREGS (floating point registers)");
57346661 20206 case NT_PSINFO:
1ec5cd37 20207 return _("NT_PSINFO (psinfo structure)");
57346661 20208 case NT_LWPSTATUS:
1ec5cd37 20209 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20210 case NT_LWPSINFO:
1ec5cd37 20211 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20212 case NT_WIN32PSTATUS:
1ec5cd37 20213 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20214 case NT_SIGINFO:
20215 return _("NT_SIGINFO (siginfo_t data)");
20216 case NT_FILE:
20217 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20218 default:
20219 break;
20220 }
20221 else
20222 switch (e_type)
20223 {
20224 case NT_VERSION:
20225 return _("NT_VERSION (version)");
20226 case NT_ARCH:
20227 return _("NT_ARCH (architecture)");
9ef920e9 20228 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20229 return _("OPEN");
9ef920e9 20230 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20231 return _("func");
c8795e1f
NC
20232 case NT_GO_BUILDID:
20233 return _("GO BUILDID");
3ac925fc
LB
20234 case FDO_PACKAGING_METADATA:
20235 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20236 default:
20237 break;
20238 }
20239
e9e44622 20240 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20241 return buff;
779fe533
NC
20242}
20243
015dc7e1 20244static bool
9ece1fa9
TT
20245print_core_note (Elf_Internal_Note *pnote)
20246{
20247 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20248 uint64_t count, page_size;
9ece1fa9
TT
20249 unsigned char *descdata, *filenames, *descend;
20250
20251 if (pnote->type != NT_FILE)
04ac15ab
AS
20252 {
20253 if (do_wide)
20254 printf ("\n");
015dc7e1 20255 return true;
04ac15ab 20256 }
9ece1fa9 20257
9ece1fa9
TT
20258 if (!is_32bit_elf)
20259 {
20260 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20261 /* Still "successful". */
015dc7e1 20262 return true;
9ece1fa9 20263 }
9ece1fa9
TT
20264
20265 if (pnote->descsz < 2 * addr_size)
20266 {
32ec8896 20267 error (_(" Malformed note - too short for header\n"));
015dc7e1 20268 return false;
9ece1fa9
TT
20269 }
20270
20271 descdata = (unsigned char *) pnote->descdata;
20272 descend = descdata + pnote->descsz;
20273
20274 if (descdata[pnote->descsz - 1] != '\0')
20275 {
32ec8896 20276 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20277 return false;
9ece1fa9
TT
20278 }
20279
20280 count = byte_get (descdata, addr_size);
20281 descdata += addr_size;
20282
20283 page_size = byte_get (descdata, addr_size);
20284 descdata += addr_size;
20285
625d49fc 20286 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20287 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20288 {
32ec8896 20289 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20290 return false;
9ece1fa9
TT
20291 }
20292
20293 printf (_(" Page size: "));
20294 print_vma (page_size, DEC);
20295 printf ("\n");
20296
20297 printf (_(" %*s%*s%*s\n"),
20298 (int) (2 + 2 * addr_size), _("Start"),
20299 (int) (4 + 2 * addr_size), _("End"),
20300 (int) (4 + 2 * addr_size), _("Page Offset"));
20301 filenames = descdata + count * 3 * addr_size;
595712bb 20302 while (count-- > 0)
9ece1fa9 20303 {
625d49fc 20304 uint64_t start, end, file_ofs;
9ece1fa9
TT
20305
20306 if (filenames == descend)
20307 {
32ec8896 20308 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20309 return false;
9ece1fa9
TT
20310 }
20311
20312 start = byte_get (descdata, addr_size);
20313 descdata += addr_size;
20314 end = byte_get (descdata, addr_size);
20315 descdata += addr_size;
20316 file_ofs = byte_get (descdata, addr_size);
20317 descdata += addr_size;
20318
20319 printf (" ");
20320 print_vma (start, FULL_HEX);
20321 printf (" ");
20322 print_vma (end, FULL_HEX);
20323 printf (" ");
20324 print_vma (file_ofs, FULL_HEX);
20325 printf ("\n %s\n", filenames);
20326
20327 filenames += 1 + strlen ((char *) filenames);
20328 }
20329
015dc7e1 20330 return true;
9ece1fa9
TT
20331}
20332
1118d252
RM
20333static const char *
20334get_gnu_elf_note_type (unsigned e_type)
20335{
1449284b 20336 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20337 switch (e_type)
20338 {
20339 case NT_GNU_ABI_TAG:
20340 return _("NT_GNU_ABI_TAG (ABI version tag)");
20341 case NT_GNU_HWCAP:
20342 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20343 case NT_GNU_BUILD_ID:
20344 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20345 case NT_GNU_GOLD_VERSION:
20346 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20347 case NT_GNU_PROPERTY_TYPE_0:
20348 return _("NT_GNU_PROPERTY_TYPE_0");
20349 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20350 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20351 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20352 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20353 default:
1449284b
NC
20354 {
20355 static char buff[64];
1118d252 20356
1449284b
NC
20357 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20358 return buff;
20359 }
20360 }
1118d252
RM
20361}
20362
a9eafb08
L
20363static void
20364decode_x86_compat_isa (unsigned int bitmask)
20365{
20366 while (bitmask)
20367 {
20368 unsigned int bit = bitmask & (- bitmask);
20369
20370 bitmask &= ~ bit;
20371 switch (bit)
20372 {
20373 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20374 printf ("i486");
20375 break;
20376 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20377 printf ("586");
20378 break;
20379 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20380 printf ("686");
20381 break;
20382 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20383 printf ("SSE");
20384 break;
20385 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20386 printf ("SSE2");
20387 break;
20388 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20389 printf ("SSE3");
20390 break;
20391 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20392 printf ("SSSE3");
20393 break;
20394 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20395 printf ("SSE4_1");
20396 break;
20397 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20398 printf ("SSE4_2");
20399 break;
20400 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20401 printf ("AVX");
20402 break;
20403 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20404 printf ("AVX2");
20405 break;
20406 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20407 printf ("AVX512F");
20408 break;
20409 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20410 printf ("AVX512CD");
20411 break;
20412 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20413 printf ("AVX512ER");
20414 break;
20415 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20416 printf ("AVX512PF");
20417 break;
20418 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20419 printf ("AVX512VL");
20420 break;
20421 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20422 printf ("AVX512DQ");
20423 break;
20424 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20425 printf ("AVX512BW");
20426 break;
65b3d26e
L
20427 default:
20428 printf (_("<unknown: %x>"), bit);
20429 break;
a9eafb08
L
20430 }
20431 if (bitmask)
20432 printf (", ");
20433 }
20434}
20435
9ef920e9 20436static void
32930e4e 20437decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20438{
0a59decb 20439 if (!bitmask)
90c745dc
L
20440 {
20441 printf (_("<None>"));
20442 return;
20443 }
90c745dc 20444
9ef920e9
NC
20445 while (bitmask)
20446 {
1fc87489 20447 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20448
20449 bitmask &= ~ bit;
20450 switch (bit)
20451 {
32930e4e 20452 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20453 printf ("CMOV");
20454 break;
32930e4e 20455 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20456 printf ("SSE");
20457 break;
32930e4e 20458 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20459 printf ("SSE2");
20460 break;
32930e4e 20461 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20462 printf ("SSE3");
20463 break;
32930e4e 20464 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20465 printf ("SSSE3");
20466 break;
32930e4e 20467 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20468 printf ("SSE4_1");
20469 break;
32930e4e 20470 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20471 printf ("SSE4_2");
20472 break;
32930e4e 20473 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20474 printf ("AVX");
20475 break;
32930e4e 20476 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20477 printf ("AVX2");
20478 break;
32930e4e 20479 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20480 printf ("FMA");
20481 break;
32930e4e 20482 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20483 printf ("AVX512F");
20484 break;
32930e4e 20485 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20486 printf ("AVX512CD");
20487 break;
32930e4e 20488 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20489 printf ("AVX512ER");
20490 break;
32930e4e 20491 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20492 printf ("AVX512PF");
20493 break;
32930e4e 20494 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20495 printf ("AVX512VL");
20496 break;
32930e4e 20497 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20498 printf ("AVX512DQ");
20499 break;
32930e4e 20500 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20501 printf ("AVX512BW");
20502 break;
32930e4e 20503 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20504 printf ("AVX512_4FMAPS");
20505 break;
32930e4e 20506 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20507 printf ("AVX512_4VNNIW");
20508 break;
32930e4e 20509 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20510 printf ("AVX512_BITALG");
20511 break;
32930e4e 20512 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20513 printf ("AVX512_IFMA");
20514 break;
32930e4e 20515 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20516 printf ("AVX512_VBMI");
20517 break;
32930e4e 20518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20519 printf ("AVX512_VBMI2");
20520 break;
32930e4e 20521 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20522 printf ("AVX512_VNNI");
20523 break;
32930e4e 20524 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20525 printf ("AVX512_BF16");
20526 break;
65b3d26e
L
20527 default:
20528 printf (_("<unknown: %x>"), bit);
20529 break;
9ef920e9
NC
20530 }
20531 if (bitmask)
20532 printf (", ");
20533 }
20534}
20535
28cdbb18
SM
20536static const char *
20537get_amdgpu_elf_note_type (unsigned int e_type)
20538{
20539 switch (e_type)
20540 {
20541 case NT_AMDGPU_METADATA:
20542 return _("NT_AMDGPU_METADATA (code object metadata)");
20543 default:
20544 {
20545 static char buf[64];
20546 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20547 return buf;
20548 }
20549 }
20550}
20551
32930e4e
L
20552static void
20553decode_x86_isa (unsigned int bitmask)
20554{
32930e4e
L
20555 while (bitmask)
20556 {
20557 unsigned int bit = bitmask & (- bitmask);
20558
20559 bitmask &= ~ bit;
20560 switch (bit)
20561 {
b0ab0693
L
20562 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20563 printf ("x86-64-baseline");
20564 break;
32930e4e
L
20565 case GNU_PROPERTY_X86_ISA_1_V2:
20566 printf ("x86-64-v2");
20567 break;
20568 case GNU_PROPERTY_X86_ISA_1_V3:
20569 printf ("x86-64-v3");
20570 break;
20571 case GNU_PROPERTY_X86_ISA_1_V4:
20572 printf ("x86-64-v4");
20573 break;
20574 default:
20575 printf (_("<unknown: %x>"), bit);
20576 break;
20577 }
20578 if (bitmask)
20579 printf (", ");
20580 }
20581}
20582
ee2fdd6f 20583static void
a9eafb08 20584decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20585{
0a59decb 20586 if (!bitmask)
90c745dc
L
20587 {
20588 printf (_("<None>"));
20589 return;
20590 }
90c745dc 20591
ee2fdd6f
L
20592 while (bitmask)
20593 {
20594 unsigned int bit = bitmask & (- bitmask);
20595
20596 bitmask &= ~ bit;
20597 switch (bit)
20598 {
20599 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20600 printf ("IBT");
ee2fdd6f 20601 break;
48580982 20602 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20603 printf ("SHSTK");
48580982 20604 break;
279d901e
L
20605 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20606 printf ("LAM_U48");
20607 break;
20608 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20609 printf ("LAM_U57");
20610 break;
ee2fdd6f
L
20611 default:
20612 printf (_("<unknown: %x>"), bit);
20613 break;
20614 }
20615 if (bitmask)
20616 printf (", ");
20617 }
20618}
20619
a9eafb08
L
20620static void
20621decode_x86_feature_2 (unsigned int bitmask)
20622{
0a59decb 20623 if (!bitmask)
90c745dc
L
20624 {
20625 printf (_("<None>"));
20626 return;
20627 }
90c745dc 20628
a9eafb08
L
20629 while (bitmask)
20630 {
20631 unsigned int bit = bitmask & (- bitmask);
20632
20633 bitmask &= ~ bit;
20634 switch (bit)
20635 {
20636 case GNU_PROPERTY_X86_FEATURE_2_X86:
20637 printf ("x86");
20638 break;
20639 case GNU_PROPERTY_X86_FEATURE_2_X87:
20640 printf ("x87");
20641 break;
20642 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20643 printf ("MMX");
20644 break;
20645 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20646 printf ("XMM");
20647 break;
20648 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20649 printf ("YMM");
20650 break;
20651 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20652 printf ("ZMM");
20653 break;
a308b89d
L
20654 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20655 printf ("TMM");
20656 break;
32930e4e
L
20657 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20658 printf ("MASK");
20659 break;
a9eafb08
L
20660 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20661 printf ("FXSR");
20662 break;
20663 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20664 printf ("XSAVE");
20665 break;
20666 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20667 printf ("XSAVEOPT");
20668 break;
20669 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20670 printf ("XSAVEC");
20671 break;
65b3d26e
L
20672 default:
20673 printf (_("<unknown: %x>"), bit);
20674 break;
a9eafb08
L
20675 }
20676 if (bitmask)
20677 printf (", ");
20678 }
20679}
20680
cd702818
SD
20681static void
20682decode_aarch64_feature_1_and (unsigned int bitmask)
20683{
20684 while (bitmask)
20685 {
20686 unsigned int bit = bitmask & (- bitmask);
20687
20688 bitmask &= ~ bit;
20689 switch (bit)
20690 {
20691 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20692 printf ("BTI");
20693 break;
20694
20695 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20696 printf ("PAC");
20697 break;
20698
20699 default:
20700 printf (_("<unknown: %x>"), bit);
20701 break;
20702 }
20703 if (bitmask)
20704 printf (", ");
20705 }
20706}
20707
6320fd00
L
20708static void
20709decode_1_needed (unsigned int bitmask)
20710{
20711 while (bitmask)
20712 {
20713 unsigned int bit = bitmask & (- bitmask);
20714
20715 bitmask &= ~ bit;
20716 switch (bit)
20717 {
20718 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20719 printf ("indirect external access");
20720 break;
20721 default:
20722 printf (_("<unknown: %x>"), bit);
20723 break;
20724 }
20725 if (bitmask)
20726 printf (", ");
20727 }
20728}
20729
9ef920e9 20730static void
dda8d76d 20731print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20732{
20733 unsigned char * ptr = (unsigned char *) pnote->descdata;
20734 unsigned char * ptr_end = ptr + pnote->descsz;
20735 unsigned int size = is_32bit_elf ? 4 : 8;
20736
20737 printf (_(" Properties: "));
20738
1fc87489 20739 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20740 {
20741 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20742 return;
20743 }
20744
6ab2c4ed 20745 while (ptr < ptr_end)
9ef920e9 20746 {
1fc87489 20747 unsigned int j;
6ab2c4ed
MC
20748 unsigned int type;
20749 unsigned int datasz;
20750
20751 if ((size_t) (ptr_end - ptr) < 8)
20752 {
20753 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20754 break;
20755 }
20756
20757 type = byte_get (ptr, 4);
20758 datasz = byte_get (ptr + 4, 4);
9ef920e9 20759
1fc87489 20760 ptr += 8;
9ef920e9 20761
6ab2c4ed 20762 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20763 {
1fc87489
L
20764 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20765 type, datasz);
9ef920e9 20766 break;
1fc87489 20767 }
9ef920e9 20768
1fc87489
L
20769 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20770 {
dda8d76d
NC
20771 if (filedata->file_header.e_machine == EM_X86_64
20772 || filedata->file_header.e_machine == EM_IAMCU
20773 || filedata->file_header.e_machine == EM_386)
1fc87489 20774 {
aa7bca9b
L
20775 unsigned int bitmask;
20776
20777 if (datasz == 4)
0a59decb 20778 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20779 else
20780 bitmask = 0;
20781
1fc87489
L
20782 switch (type)
20783 {
20784 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20785 if (datasz != 4)
aa7bca9b
L
20786 printf (_("x86 ISA used: <corrupt length: %#x> "),
20787 datasz);
1fc87489 20788 else
aa7bca9b
L
20789 {
20790 printf ("x86 ISA used: ");
20791 decode_x86_isa (bitmask);
20792 }
1fc87489 20793 goto next;
9ef920e9 20794
1fc87489 20795 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20796 if (datasz != 4)
aa7bca9b
L
20797 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20798 datasz);
1fc87489 20799 else
aa7bca9b
L
20800 {
20801 printf ("x86 ISA needed: ");
20802 decode_x86_isa (bitmask);
20803 }
1fc87489 20804 goto next;
9ef920e9 20805
ee2fdd6f 20806 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20807 if (datasz != 4)
aa7bca9b
L
20808 printf (_("x86 feature: <corrupt length: %#x> "),
20809 datasz);
ee2fdd6f 20810 else
aa7bca9b
L
20811 {
20812 printf ("x86 feature: ");
a9eafb08
L
20813 decode_x86_feature_1 (bitmask);
20814 }
20815 goto next;
20816
20817 case GNU_PROPERTY_X86_FEATURE_2_USED:
20818 if (datasz != 4)
20819 printf (_("x86 feature used: <corrupt length: %#x> "),
20820 datasz);
20821 else
20822 {
20823 printf ("x86 feature used: ");
20824 decode_x86_feature_2 (bitmask);
20825 }
20826 goto next;
20827
20828 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20829 if (datasz != 4)
20830 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20831 else
20832 {
20833 printf ("x86 feature needed: ");
20834 decode_x86_feature_2 (bitmask);
20835 }
20836 goto next;
20837
20838 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20839 if (datasz != 4)
20840 printf (_("x86 ISA used: <corrupt length: %#x> "),
20841 datasz);
20842 else
20843 {
20844 printf ("x86 ISA used: ");
20845 decode_x86_compat_isa (bitmask);
20846 }
20847 goto next;
20848
20849 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20850 if (datasz != 4)
20851 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20852 datasz);
20853 else
20854 {
20855 printf ("x86 ISA needed: ");
20856 decode_x86_compat_isa (bitmask);
aa7bca9b 20857 }
ee2fdd6f
L
20858 goto next;
20859
32930e4e
L
20860 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20861 if (datasz != 4)
20862 printf (_("x86 ISA used: <corrupt length: %#x> "),
20863 datasz);
20864 else
20865 {
20866 printf ("x86 ISA used: ");
20867 decode_x86_compat_2_isa (bitmask);
20868 }
20869 goto next;
20870
20871 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20872 if (datasz != 4)
20873 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20874 datasz);
20875 else
20876 {
20877 printf ("x86 ISA needed: ");
20878 decode_x86_compat_2_isa (bitmask);
20879 }
20880 goto next;
20881
1fc87489
L
20882 default:
20883 break;
20884 }
20885 }
cd702818
SD
20886 else if (filedata->file_header.e_machine == EM_AARCH64)
20887 {
20888 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20889 {
20890 printf ("AArch64 feature: ");
20891 if (datasz != 4)
20892 printf (_("<corrupt length: %#x> "), datasz);
20893 else
20894 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20895 goto next;
20896 }
20897 }
1fc87489
L
20898 }
20899 else
20900 {
20901 switch (type)
9ef920e9 20902 {
1fc87489
L
20903 case GNU_PROPERTY_STACK_SIZE:
20904 printf (_("stack size: "));
20905 if (datasz != size)
20906 printf (_("<corrupt length: %#x> "), datasz);
20907 else
26c527e6 20908 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20909 goto next;
20910
20911 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20912 printf ("no copy on protected ");
20913 if (datasz)
20914 printf (_("<corrupt length: %#x> "), datasz);
20915 goto next;
20916
20917 default:
5a767724
L
20918 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20919 && type <= GNU_PROPERTY_UINT32_AND_HI)
20920 || (type >= GNU_PROPERTY_UINT32_OR_LO
20921 && type <= GNU_PROPERTY_UINT32_OR_HI))
20922 {
6320fd00
L
20923 switch (type)
20924 {
20925 case GNU_PROPERTY_1_NEEDED:
20926 if (datasz != 4)
20927 printf (_("1_needed: <corrupt length: %#x> "),
20928 datasz);
20929 else
20930 {
20931 unsigned int bitmask = byte_get (ptr, 4);
20932 printf ("1_needed: ");
20933 decode_1_needed (bitmask);
20934 }
20935 goto next;
20936
20937 default:
20938 break;
20939 }
5a767724
L
20940 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20941 printf (_("UINT32_AND (%#x): "), type);
20942 else
20943 printf (_("UINT32_OR (%#x): "), type);
20944 if (datasz != 4)
20945 printf (_("<corrupt length: %#x> "), datasz);
20946 else
20947 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20948 goto next;
20949 }
9ef920e9
NC
20950 break;
20951 }
9ef920e9
NC
20952 }
20953
1fc87489
L
20954 if (type < GNU_PROPERTY_LOPROC)
20955 printf (_("<unknown type %#x data: "), type);
20956 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20957 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20958 else
20959 printf (_("<application-specific type %#x data: "), type);
20960 for (j = 0; j < datasz; ++j)
20961 printf ("%02x ", ptr[j] & 0xff);
20962 printf (">");
20963
dc1e8a47 20964 next:
9ef920e9 20965 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20966 if (ptr == ptr_end)
20967 break;
1fc87489 20968
6ab2c4ed
MC
20969 if (do_wide)
20970 printf (", ");
20971 else
20972 printf ("\n\t");
9ef920e9
NC
20973 }
20974
20975 printf ("\n");
20976}
20977
015dc7e1 20978static bool
dda8d76d 20979print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20980{
1449284b 20981 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20982 switch (pnote->type)
20983 {
20984 case NT_GNU_BUILD_ID:
20985 {
26c527e6 20986 size_t i;
664f90a3
TT
20987
20988 printf (_(" Build ID: "));
20989 for (i = 0; i < pnote->descsz; ++i)
20990 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20991 printf ("\n");
664f90a3
TT
20992 }
20993 break;
20994
20995 case NT_GNU_ABI_TAG:
20996 {
26c527e6 20997 unsigned int os, major, minor, subminor;
664f90a3
TT
20998 const char *osname;
20999
3102e897
NC
21000 /* PR 17531: file: 030-599401-0.004. */
21001 if (pnote->descsz < 16)
21002 {
21003 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21004 break;
21005 }
21006
664f90a3
TT
21007 os = byte_get ((unsigned char *) pnote->descdata, 4);
21008 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21009 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21010 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21011
21012 switch (os)
21013 {
21014 case GNU_ABI_TAG_LINUX:
21015 osname = "Linux";
21016 break;
21017 case GNU_ABI_TAG_HURD:
21018 osname = "Hurd";
21019 break;
21020 case GNU_ABI_TAG_SOLARIS:
21021 osname = "Solaris";
21022 break;
21023 case GNU_ABI_TAG_FREEBSD:
21024 osname = "FreeBSD";
21025 break;
21026 case GNU_ABI_TAG_NETBSD:
21027 osname = "NetBSD";
21028 break;
14ae95f2
RM
21029 case GNU_ABI_TAG_SYLLABLE:
21030 osname = "Syllable";
21031 break;
21032 case GNU_ABI_TAG_NACL:
21033 osname = "NaCl";
21034 break;
664f90a3
TT
21035 default:
21036 osname = "Unknown";
21037 break;
21038 }
21039
26c527e6 21040 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21041 major, minor, subminor);
21042 }
21043 break;
926c5385
CC
21044
21045 case NT_GNU_GOLD_VERSION:
21046 {
26c527e6 21047 size_t i;
926c5385
CC
21048
21049 printf (_(" Version: "));
21050 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21051 printf ("%c", pnote->descdata[i]);
21052 printf ("\n");
21053 }
21054 break;
1449284b
NC
21055
21056 case NT_GNU_HWCAP:
21057 {
26c527e6 21058 unsigned int num_entries, mask;
1449284b
NC
21059
21060 /* Hardware capabilities information. Word 0 is the number of entries.
21061 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21062 is a series of entries, where each entry is a single byte followed
21063 by a nul terminated string. The byte gives the bit number to test
21064 if enabled in the bitmask. */
21065 printf (_(" Hardware Capabilities: "));
21066 if (pnote->descsz < 8)
21067 {
32ec8896 21068 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21069 return false;
1449284b
NC
21070 }
21071 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21072 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21073 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21074 /* FIXME: Add code to display the entries... */
21075 }
21076 break;
21077
9ef920e9 21078 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21079 print_gnu_property_note (filedata, pnote);
9ef920e9 21080 break;
9abca702 21081
1449284b
NC
21082 default:
21083 /* Handle unrecognised types. An error message should have already been
21084 created by get_gnu_elf_note_type(), so all that we need to do is to
21085 display the data. */
21086 {
26c527e6 21087 size_t i;
1449284b
NC
21088
21089 printf (_(" Description data: "));
21090 for (i = 0; i < pnote->descsz; ++i)
21091 printf ("%02x ", pnote->descdata[i] & 0xff);
21092 printf ("\n");
21093 }
21094 break;
664f90a3
TT
21095 }
21096
015dc7e1 21097 return true;
664f90a3
TT
21098}
21099
685080f2
NC
21100static const char *
21101get_v850_elf_note_type (enum v850_notes n_type)
21102{
21103 static char buff[64];
21104
21105 switch (n_type)
21106 {
21107 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21108 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21109 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21110 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21111 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21112 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21113 default:
21114 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21115 return buff;
21116 }
21117}
21118
015dc7e1 21119static bool
685080f2
NC
21120print_v850_note (Elf_Internal_Note * pnote)
21121{
21122 unsigned int val;
21123
21124 if (pnote->descsz != 4)
015dc7e1 21125 return false;
32ec8896 21126
685080f2
NC
21127 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21128
21129 if (val == 0)
21130 {
21131 printf (_("not set\n"));
015dc7e1 21132 return true;
685080f2
NC
21133 }
21134
21135 switch (pnote->type)
21136 {
21137 case V850_NOTE_ALIGNMENT:
21138 switch (val)
21139 {
015dc7e1
AM
21140 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21141 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21142 }
21143 break;
14ae95f2 21144
685080f2
NC
21145 case V850_NOTE_DATA_SIZE:
21146 switch (val)
21147 {
015dc7e1
AM
21148 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21149 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21150 }
21151 break;
14ae95f2 21152
685080f2
NC
21153 case V850_NOTE_FPU_INFO:
21154 switch (val)
21155 {
015dc7e1
AM
21156 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21157 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21158 }
21159 break;
14ae95f2 21160
685080f2
NC
21161 case V850_NOTE_MMU_INFO:
21162 case V850_NOTE_CACHE_INFO:
21163 case V850_NOTE_SIMD_INFO:
21164 if (val == EF_RH850_SIMD)
21165 {
21166 printf (_("yes\n"));
015dc7e1 21167 return true;
685080f2
NC
21168 }
21169 break;
21170
21171 default:
21172 /* An 'unknown note type' message will already have been displayed. */
21173 break;
21174 }
21175
21176 printf (_("unknown value: %x\n"), val);
015dc7e1 21177 return false;
685080f2
NC
21178}
21179
015dc7e1 21180static bool
c6056a74
SF
21181process_netbsd_elf_note (Elf_Internal_Note * pnote)
21182{
21183 unsigned int version;
21184
21185 switch (pnote->type)
21186 {
21187 case NT_NETBSD_IDENT:
b966f55f
AM
21188 if (pnote->descsz < 1)
21189 break;
c6056a74
SF
21190 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21191 if ((version / 10000) % 100)
b966f55f 21192 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21193 version, version / 100000000, (version / 1000000) % 100,
21194 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21195 'A' + (version / 10000) % 26);
c6056a74
SF
21196 else
21197 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21198 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21199 (version / 100) % 100);
015dc7e1 21200 return true;
c6056a74
SF
21201
21202 case NT_NETBSD_MARCH:
9abca702 21203 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21204 pnote->descdata);
015dc7e1 21205 return true;
c6056a74 21206
9abca702 21207 case NT_NETBSD_PAX:
b966f55f
AM
21208 if (pnote->descsz < 1)
21209 break;
9abca702
CZ
21210 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21211 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21212 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21213 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21214 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21215 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21216 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21217 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21218 return true;
c6056a74 21219 }
b966f55f
AM
21220
21221 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21222 pnote->descsz, pnote->type);
015dc7e1 21223 return false;
c6056a74
SF
21224}
21225
f4ddf30f 21226static const char *
dda8d76d 21227get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21228{
f4ddf30f
JB
21229 switch (e_type)
21230 {
21231 case NT_FREEBSD_THRMISC:
21232 return _("NT_THRMISC (thrmisc structure)");
21233 case NT_FREEBSD_PROCSTAT_PROC:
21234 return _("NT_PROCSTAT_PROC (proc data)");
21235 case NT_FREEBSD_PROCSTAT_FILES:
21236 return _("NT_PROCSTAT_FILES (files data)");
21237 case NT_FREEBSD_PROCSTAT_VMMAP:
21238 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21239 case NT_FREEBSD_PROCSTAT_GROUPS:
21240 return _("NT_PROCSTAT_GROUPS (groups data)");
21241 case NT_FREEBSD_PROCSTAT_UMASK:
21242 return _("NT_PROCSTAT_UMASK (umask data)");
21243 case NT_FREEBSD_PROCSTAT_RLIMIT:
21244 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21245 case NT_FREEBSD_PROCSTAT_OSREL:
21246 return _("NT_PROCSTAT_OSREL (osreldate data)");
21247 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21248 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21249 case NT_FREEBSD_PROCSTAT_AUXV:
21250 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21251 case NT_FREEBSD_PTLWPINFO:
21252 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21253 case NT_FREEBSD_X86_SEGBASES:
21254 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21255 }
dda8d76d 21256 return get_note_type (filedata, e_type);
f4ddf30f
JB
21257}
21258
9437c45b 21259static const char *
dda8d76d 21260get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21261{
21262 static char buff[64];
21263
540e6170
CZ
21264 switch (e_type)
21265 {
21266 case NT_NETBSDCORE_PROCINFO:
21267 /* NetBSD core "procinfo" structure. */
21268 return _("NetBSD procinfo structure");
9437c45b 21269
540e6170
CZ
21270 case NT_NETBSDCORE_AUXV:
21271 return _("NetBSD ELF auxiliary vector data");
9437c45b 21272
06d949ec
KR
21273 case NT_NETBSDCORE_LWPSTATUS:
21274 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21275
540e6170 21276 default:
06d949ec 21277 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21278 defined for NetBSD core files. If the note type is less
21279 than the start of the machine-dependent note types, we don't
21280 understand it. */
21281
21282 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21283 {
21284 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21285 return buff;
21286 }
21287 break;
9437c45b
JT
21288 }
21289
dda8d76d 21290 switch (filedata->file_header.e_machine)
9437c45b
JT
21291 {
21292 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21293 and PT_GETFPREGS == mach+2. */
21294
21295 case EM_OLD_ALPHA:
21296 case EM_ALPHA:
21297 case EM_SPARC:
21298 case EM_SPARC32PLUS:
21299 case EM_SPARCV9:
21300 switch (e_type)
21301 {
2b692964 21302 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21303 return _("PT_GETREGS (reg structure)");
2b692964 21304 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21305 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21306 default:
21307 break;
21308 }
21309 break;
21310
c0d38b0e
CZ
21311 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21312 There's also old PT___GETREGS40 == mach + 1 for old reg
21313 structure which lacks GBR. */
21314 case EM_SH:
21315 switch (e_type)
21316 {
21317 case NT_NETBSDCORE_FIRSTMACH + 1:
21318 return _("PT___GETREGS40 (old reg structure)");
21319 case NT_NETBSDCORE_FIRSTMACH + 3:
21320 return _("PT_GETREGS (reg structure)");
21321 case NT_NETBSDCORE_FIRSTMACH + 5:
21322 return _("PT_GETFPREGS (fpreg structure)");
21323 default:
21324 break;
21325 }
21326 break;
21327
9437c45b
JT
21328 /* On all other arch's, PT_GETREGS == mach+1 and
21329 PT_GETFPREGS == mach+3. */
21330 default:
21331 switch (e_type)
21332 {
2b692964 21333 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21334 return _("PT_GETREGS (reg structure)");
2b692964 21335 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21336 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21337 default:
21338 break;
21339 }
21340 }
21341
9cf03b7e 21342 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21343 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21344 return buff;
21345}
21346
98ca73af
FC
21347static const char *
21348get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21349{
21350 switch (e_type)
21351 {
21352 case NT_OPENBSD_PROCINFO:
21353 return _("OpenBSD procinfo structure");
21354 case NT_OPENBSD_AUXV:
21355 return _("OpenBSD ELF auxiliary vector data");
21356 case NT_OPENBSD_REGS:
21357 return _("OpenBSD regular registers");
21358 case NT_OPENBSD_FPREGS:
21359 return _("OpenBSD floating point registers");
21360 case NT_OPENBSD_WCOOKIE:
21361 return _("OpenBSD window cookie");
21362 }
21363
21364 return get_note_type (filedata, e_type);
21365}
21366
e263a66b
CC
21367static const char *
21368get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21369{
21370 switch (e_type)
21371 {
21372 case QNT_DEBUG_FULLPATH:
21373 return _("QNX debug fullpath");
21374 case QNT_DEBUG_RELOC:
21375 return _("QNX debug relocation");
21376 case QNT_STACK:
21377 return _("QNX stack");
21378 case QNT_GENERATOR:
21379 return _("QNX generator");
21380 case QNT_DEFAULT_LIB:
21381 return _("QNX default library");
21382 case QNT_CORE_SYSINFO:
21383 return _("QNX core sysinfo");
21384 case QNT_CORE_INFO:
21385 return _("QNX core info");
21386 case QNT_CORE_STATUS:
21387 return _("QNX core status");
21388 case QNT_CORE_GREG:
21389 return _("QNX general registers");
21390 case QNT_CORE_FPREG:
21391 return _("QNX floating point registers");
21392 case QNT_LINK_MAP:
21393 return _("QNX link map");
21394 }
21395
21396 return get_note_type (filedata, e_type);
21397}
21398
70616151
TT
21399static const char *
21400get_stapsdt_note_type (unsigned e_type)
21401{
21402 static char buff[64];
21403
21404 switch (e_type)
21405 {
21406 case NT_STAPSDT:
21407 return _("NT_STAPSDT (SystemTap probe descriptors)");
21408
21409 default:
21410 break;
21411 }
21412
21413 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21414 return buff;
21415}
21416
015dc7e1 21417static bool
c6a9fc58
TT
21418print_stapsdt_note (Elf_Internal_Note *pnote)
21419{
3ca60c57 21420 size_t len, maxlen;
26c527e6 21421 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21422 char *data = pnote->descdata;
21423 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21424 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21425 char *provider, *probe, *arg_fmt;
21426
3ca60c57
NC
21427 if (pnote->descsz < (addr_size * 3))
21428 goto stapdt_note_too_small;
21429
c6a9fc58
TT
21430 pc = byte_get ((unsigned char *) data, addr_size);
21431 data += addr_size;
3ca60c57 21432
c6a9fc58
TT
21433 base_addr = byte_get ((unsigned char *) data, addr_size);
21434 data += addr_size;
3ca60c57 21435
c6a9fc58
TT
21436 semaphore = byte_get ((unsigned char *) data, addr_size);
21437 data += addr_size;
21438
3ca60c57
NC
21439 if (data >= data_end)
21440 goto stapdt_note_too_small;
21441 maxlen = data_end - data;
21442 len = strnlen (data, maxlen);
21443 if (len < maxlen)
21444 {
21445 provider = data;
21446 data += len + 1;
21447 }
21448 else
21449 goto stapdt_note_too_small;
21450
21451 if (data >= data_end)
21452 goto stapdt_note_too_small;
21453 maxlen = data_end - data;
21454 len = strnlen (data, maxlen);
21455 if (len < maxlen)
21456 {
21457 probe = data;
21458 data += len + 1;
21459 }
21460 else
21461 goto stapdt_note_too_small;
9abca702 21462
3ca60c57
NC
21463 if (data >= data_end)
21464 goto stapdt_note_too_small;
21465 maxlen = data_end - data;
21466 len = strnlen (data, maxlen);
21467 if (len < maxlen)
21468 {
21469 arg_fmt = data;
21470 data += len + 1;
21471 }
21472 else
21473 goto stapdt_note_too_small;
c6a9fc58
TT
21474
21475 printf (_(" Provider: %s\n"), provider);
21476 printf (_(" Name: %s\n"), probe);
21477 printf (_(" Location: "));
21478 print_vma (pc, FULL_HEX);
21479 printf (_(", Base: "));
21480 print_vma (base_addr, FULL_HEX);
21481 printf (_(", Semaphore: "));
21482 print_vma (semaphore, FULL_HEX);
9cf03b7e 21483 printf ("\n");
c6a9fc58
TT
21484 printf (_(" Arguments: %s\n"), arg_fmt);
21485
21486 return data == data_end;
3ca60c57
NC
21487
21488 stapdt_note_too_small:
21489 printf (_(" <corrupt - note is too small>\n"));
21490 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21491 return false;
c6a9fc58
TT
21492}
21493
e5382207
LB
21494static bool
21495print_fdo_note (Elf_Internal_Note * pnote)
21496{
21497 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21498 {
21499 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21500 return true;
21501 }
21502 return false;
21503}
21504
00e98fc7
TG
21505static const char *
21506get_ia64_vms_note_type (unsigned e_type)
21507{
21508 static char buff[64];
21509
21510 switch (e_type)
21511 {
21512 case NT_VMS_MHD:
21513 return _("NT_VMS_MHD (module header)");
21514 case NT_VMS_LNM:
21515 return _("NT_VMS_LNM (language name)");
21516 case NT_VMS_SRC:
21517 return _("NT_VMS_SRC (source files)");
21518 case NT_VMS_TITLE:
9cf03b7e 21519 return "NT_VMS_TITLE";
00e98fc7
TG
21520 case NT_VMS_EIDC:
21521 return _("NT_VMS_EIDC (consistency check)");
21522 case NT_VMS_FPMODE:
21523 return _("NT_VMS_FPMODE (FP mode)");
21524 case NT_VMS_LINKTIME:
9cf03b7e 21525 return "NT_VMS_LINKTIME";
00e98fc7
TG
21526 case NT_VMS_IMGNAM:
21527 return _("NT_VMS_IMGNAM (image name)");
21528 case NT_VMS_IMGID:
21529 return _("NT_VMS_IMGID (image id)");
21530 case NT_VMS_LINKID:
21531 return _("NT_VMS_LINKID (link id)");
21532 case NT_VMS_IMGBID:
21533 return _("NT_VMS_IMGBID (build id)");
21534 case NT_VMS_GSTNAM:
21535 return _("NT_VMS_GSTNAM (sym table name)");
21536 case NT_VMS_ORIG_DYN:
9cf03b7e 21537 return "NT_VMS_ORIG_DYN";
00e98fc7 21538 case NT_VMS_PATCHTIME:
9cf03b7e 21539 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21540 default:
21541 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21542 return buff;
21543 }
21544}
21545
015dc7e1 21546static bool
00e98fc7
TG
21547print_ia64_vms_note (Elf_Internal_Note * pnote)
21548{
26c527e6 21549 unsigned int maxlen = pnote->descsz;
8d18bf79 21550
26c527e6 21551 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21552 goto desc_size_fail;
21553
00e98fc7
TG
21554 switch (pnote->type)
21555 {
21556 case NT_VMS_MHD:
8d18bf79
NC
21557 if (maxlen <= 36)
21558 goto desc_size_fail;
21559
26c527e6 21560 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21561
21562 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21563 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21564 if (l + 34 < maxlen)
21565 {
21566 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21567 if (l + 35 < maxlen)
21568 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21569 else
21570 printf (_(" Module version : <missing>\n"));
21571 }
00e98fc7 21572 else
8d18bf79
NC
21573 {
21574 printf (_(" Module name : <missing>\n"));
21575 printf (_(" Module version : <missing>\n"));
21576 }
00e98fc7 21577 break;
8d18bf79 21578
00e98fc7 21579 case NT_VMS_LNM:
8d18bf79 21580 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21581 break;
8d18bf79 21582
00e98fc7 21583 case NT_VMS_FPMODE:
9cf03b7e 21584 printf (_(" Floating Point mode: "));
8d18bf79
NC
21585 if (maxlen < 8)
21586 goto desc_size_fail;
21587 /* FIXME: Generate an error if descsz > 8 ? */
21588
b8281767 21589 printf ("0x%016" PRIx64 "\n",
625d49fc 21590 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21591 break;
8d18bf79 21592
00e98fc7
TG
21593 case NT_VMS_LINKTIME:
21594 printf (_(" Link time: "));
8d18bf79
NC
21595 if (maxlen < 8)
21596 goto desc_size_fail;
21597 /* FIXME: Generate an error if descsz > 8 ? */
21598
0e3c1eeb 21599 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21600 printf ("\n");
21601 break;
8d18bf79 21602
00e98fc7
TG
21603 case NT_VMS_PATCHTIME:
21604 printf (_(" Patch time: "));
8d18bf79
NC
21605 if (maxlen < 8)
21606 goto desc_size_fail;
21607 /* FIXME: Generate an error if descsz > 8 ? */
21608
0e3c1eeb 21609 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21610 printf ("\n");
21611 break;
8d18bf79 21612
00e98fc7 21613 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21614 if (maxlen < 34)
21615 goto desc_size_fail;
21616
00e98fc7 21617 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21618 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21619 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21620 printf (_(" Last modified : "));
0e3c1eeb 21621 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21622 printf (_("\n Link flags : "));
b8281767 21623 printf ("0x%016" PRIx64 "\n",
625d49fc 21624 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21625 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21626 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21627 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21628 break;
8d18bf79 21629
00e98fc7 21630 case NT_VMS_IMGNAM:
8d18bf79 21631 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21632 break;
8d18bf79 21633
00e98fc7 21634 case NT_VMS_GSTNAM:
8d18bf79 21635 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21636 break;
8d18bf79 21637
00e98fc7 21638 case NT_VMS_IMGID:
8d18bf79 21639 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21640 break;
8d18bf79 21641
00e98fc7 21642 case NT_VMS_LINKID:
8d18bf79 21643 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21644 break;
8d18bf79 21645
00e98fc7 21646 default:
015dc7e1 21647 return false;
00e98fc7 21648 }
8d18bf79 21649
015dc7e1 21650 return true;
8d18bf79
NC
21651
21652 desc_size_fail:
21653 printf (_(" <corrupt - data size is too small>\n"));
21654 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21655 return false;
00e98fc7
TG
21656}
21657
fd486f32
AM
21658struct build_attr_cache {
21659 Filedata *filedata;
21660 char *strtab;
26c527e6 21661 uint64_t strtablen;
fd486f32 21662 Elf_Internal_Sym *symtab;
26c527e6 21663 uint64_t nsyms;
fd486f32
AM
21664} ba_cache;
21665
6f156d7a
NC
21666/* Find the symbol associated with a build attribute that is attached
21667 to address OFFSET. If PNAME is non-NULL then store the name of
21668 the symbol (if found) in the provided pointer, Returns NULL if a
21669 symbol could not be found. */
c799a79d 21670
6f156d7a 21671static Elf_Internal_Sym *
015dc7e1 21672get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21673 uint64_t offset,
015dc7e1
AM
21674 bool is_open_attr,
21675 const char **pname)
9ef920e9 21676{
fd486f32
AM
21677 Elf_Internal_Sym *saved_sym = NULL;
21678 Elf_Internal_Sym *sym;
9ef920e9 21679
dda8d76d 21680 if (filedata->section_headers != NULL
fd486f32 21681 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21682 {
c799a79d 21683 Elf_Internal_Shdr * symsec;
9ef920e9 21684
fd486f32
AM
21685 free (ba_cache.strtab);
21686 ba_cache.strtab = NULL;
21687 free (ba_cache.symtab);
21688 ba_cache.symtab = NULL;
21689
c799a79d 21690 /* Load the symbol and string sections. */
dda8d76d
NC
21691 for (symsec = filedata->section_headers;
21692 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21693 symsec ++)
9ef920e9 21694 {
28d13567
AM
21695 if (symsec->sh_type == SHT_SYMTAB
21696 && get_symtab (filedata, symsec,
21697 &ba_cache.symtab, &ba_cache.nsyms,
21698 &ba_cache.strtab, &ba_cache.strtablen))
21699 break;
9ef920e9 21700 }
fd486f32 21701 ba_cache.filedata = filedata;
9ef920e9
NC
21702 }
21703
fd486f32 21704 if (ba_cache.symtab == NULL)
6f156d7a 21705 return NULL;
9ef920e9 21706
c799a79d 21707 /* Find a symbol whose value matches offset. */
fd486f32 21708 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21709 if (sym->st_value == offset)
21710 {
fd486f32 21711 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21712 /* Huh ? This should not happen. */
21713 continue;
9ef920e9 21714
fd486f32 21715 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21716 continue;
9ef920e9 21717
9b9b1092 21718 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21719 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21720 if (ba_cache.strtab[sym->st_name] == '$'
21721 && ba_cache.strtab[sym->st_name + 1] != 0
21722 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21723 continue;
21724
c799a79d
NC
21725 if (is_open_attr)
21726 {
21727 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21728 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21729 FUNC symbols entirely. */
21730 switch (ELF_ST_TYPE (sym->st_info))
21731 {
c799a79d 21732 case STT_OBJECT:
6f156d7a 21733 case STT_FILE:
c799a79d 21734 saved_sym = sym;
6f156d7a
NC
21735 if (sym->st_size)
21736 {
21737 /* If the symbol has a size associated
21738 with it then we can stop searching. */
fd486f32 21739 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21740 }
c799a79d 21741 continue;
9ef920e9 21742
c799a79d
NC
21743 case STT_FUNC:
21744 /* Ignore function symbols. */
21745 continue;
21746
21747 default:
21748 break;
21749 }
21750
21751 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21752 {
c799a79d
NC
21753 case STB_GLOBAL:
21754 if (saved_sym == NULL
21755 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21756 saved_sym = sym;
21757 break;
c871dade 21758
c799a79d
NC
21759 case STB_LOCAL:
21760 if (saved_sym == NULL)
21761 saved_sym = sym;
21762 break;
21763
21764 default:
9ef920e9
NC
21765 break;
21766 }
21767 }
c799a79d
NC
21768 else
21769 {
21770 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21771 continue;
21772
21773 saved_sym = sym;
21774 break;
21775 }
21776 }
21777
6f156d7a 21778 if (saved_sym && pname)
fd486f32 21779 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21780
21781 return saved_sym;
c799a79d
NC
21782}
21783
d20e98ab
NC
21784/* Returns true iff addr1 and addr2 are in the same section. */
21785
015dc7e1 21786static bool
26c527e6 21787same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21788{
21789 Elf_Internal_Shdr * a1;
21790 Elf_Internal_Shdr * a2;
21791
21792 a1 = find_section_by_address (filedata, addr1);
21793 a2 = find_section_by_address (filedata, addr2);
9abca702 21794
d20e98ab
NC
21795 return a1 == a2 && a1 != NULL;
21796}
21797
015dc7e1 21798static bool
dda8d76d
NC
21799print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21800 Filedata * filedata)
c799a79d 21801{
26c527e6
AM
21802 static uint64_t global_offset = 0;
21803 static uint64_t global_end = 0;
21804 static uint64_t func_offset = 0;
21805 static uint64_t func_end = 0;
c871dade 21806
015dc7e1
AM
21807 Elf_Internal_Sym *sym;
21808 const char *name;
26c527e6
AM
21809 uint64_t start;
21810 uint64_t end;
015dc7e1 21811 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21812
21813 switch (pnote->descsz)
c799a79d 21814 {
6f156d7a
NC
21815 case 0:
21816 /* A zero-length description means that the range of
21817 the previous note of the same type should be used. */
c799a79d 21818 if (is_open_attr)
c871dade 21819 {
6f156d7a 21820 if (global_end > global_offset)
26c527e6
AM
21821 printf (_(" Applies to region from %#" PRIx64
21822 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21823 else
26c527e6
AM
21824 printf (_(" Applies to region from %#" PRIx64
21825 "\n"), global_offset);
c799a79d
NC
21826 }
21827 else
21828 {
6f156d7a 21829 if (func_end > func_offset)
26c527e6
AM
21830 printf (_(" Applies to region from %#" PRIx64
21831 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21832 else
26c527e6
AM
21833 printf (_(" Applies to region from %#" PRIx64
21834 "\n"), func_offset);
c871dade 21835 }
015dc7e1 21836 return true;
9ef920e9 21837
6f156d7a
NC
21838 case 4:
21839 start = byte_get ((unsigned char *) pnote->descdata, 4);
21840 end = 0;
21841 break;
21842
21843 case 8:
c74147bb
NC
21844 start = byte_get ((unsigned char *) pnote->descdata, 4);
21845 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21846 break;
21847
21848 case 16:
21849 start = byte_get ((unsigned char *) pnote->descdata, 8);
21850 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21851 break;
9abca702 21852
6f156d7a 21853 default:
c799a79d
NC
21854 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21855 printf (_(" <invalid descsz>"));
015dc7e1 21856 return false;
c799a79d
NC
21857 }
21858
6f156d7a
NC
21859 name = NULL;
21860 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21861 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21862 in order to avoid them being confused with the start address of the
21863 first function in the file... */
21864 if (sym == NULL && is_open_attr)
21865 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21866 & name);
6f156d7a
NC
21867
21868 if (end == 0 && sym != NULL && sym->st_size > 0)
21869 end = start + sym->st_size;
c799a79d
NC
21870
21871 if (is_open_attr)
21872 {
d20e98ab
NC
21873 /* FIXME: Need to properly allow for section alignment.
21874 16 is just the alignment used on x86_64. */
21875 if (global_end > 0
21876 && start > BFD_ALIGN (global_end, 16)
21877 /* Build notes are not guaranteed to be organised in order of
21878 increasing address, but we should find the all of the notes
21879 for one section in the same place. */
21880 && same_section (filedata, start, global_end))
26c527e6
AM
21881 warn (_("Gap in build notes detected from %#" PRIx64
21882 " to %#" PRIx64 "\n"),
6f156d7a
NC
21883 global_end + 1, start - 1);
21884
26c527e6 21885 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21886 global_offset = start;
21887
21888 if (end)
21889 {
26c527e6 21890 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21891 global_end = end;
21892 }
c799a79d
NC
21893 }
21894 else
21895 {
26c527e6 21896 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21897 func_offset = start;
21898
21899 if (end)
21900 {
26c527e6 21901 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21902 func_end = end;
21903 }
c799a79d
NC
21904 }
21905
6f156d7a
NC
21906 if (sym && name)
21907 printf (_(" (%s)"), name);
21908
21909 printf ("\n");
015dc7e1 21910 return true;
9ef920e9
NC
21911}
21912
015dc7e1 21913static bool
9ef920e9
NC
21914print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21915{
1d15e434
NC
21916 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21917 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21918 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21919 char name_type;
21920 char name_attribute;
1d15e434 21921 const char * expected_types;
9ef920e9
NC
21922 const char * name = pnote->namedata;
21923 const char * text;
88305e1b 21924 signed int left;
9ef920e9
NC
21925
21926 if (name == NULL || pnote->namesz < 2)
21927 {
21928 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21929 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21930 return false;
9ef920e9
NC
21931 }
21932
6f156d7a
NC
21933 if (do_wide)
21934 left = 28;
21935 else
21936 left = 20;
88305e1b
NC
21937
21938 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21939 if (name[0] == 'G' && name[1] == 'A')
21940 {
6f156d7a
NC
21941 if (pnote->namesz < 4)
21942 {
21943 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21944 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21945 return false;
6f156d7a
NC
21946 }
21947
88305e1b
NC
21948 printf ("GA");
21949 name += 2;
21950 left -= 2;
21951 }
21952
9ef920e9
NC
21953 switch ((name_type = * name))
21954 {
21955 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21956 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21957 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21958 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21959 printf ("%c", * name);
88305e1b 21960 left --;
9ef920e9
NC
21961 break;
21962 default:
21963 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 21964 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 21965 return false;
9ef920e9
NC
21966 }
21967
9ef920e9
NC
21968 ++ name;
21969 text = NULL;
21970
21971 switch ((name_attribute = * name))
21972 {
21973 case GNU_BUILD_ATTRIBUTE_VERSION:
21974 text = _("<version>");
1d15e434 21975 expected_types = string_expected;
9ef920e9
NC
21976 ++ name;
21977 break;
21978 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21979 text = _("<stack prot>");
75d7d298 21980 expected_types = "!+*";
9ef920e9
NC
21981 ++ name;
21982 break;
21983 case GNU_BUILD_ATTRIBUTE_RELRO:
21984 text = _("<relro>");
1d15e434 21985 expected_types = bool_expected;
9ef920e9
NC
21986 ++ name;
21987 break;
21988 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21989 text = _("<stack size>");
1d15e434 21990 expected_types = number_expected;
9ef920e9
NC
21991 ++ name;
21992 break;
21993 case GNU_BUILD_ATTRIBUTE_TOOL:
21994 text = _("<tool>");
1d15e434 21995 expected_types = string_expected;
9ef920e9
NC
21996 ++ name;
21997 break;
21998 case GNU_BUILD_ATTRIBUTE_ABI:
21999 text = _("<ABI>");
22000 expected_types = "$*";
22001 ++ name;
22002 break;
22003 case GNU_BUILD_ATTRIBUTE_PIC:
22004 text = _("<PIC>");
1d15e434 22005 expected_types = number_expected;
9ef920e9
NC
22006 ++ name;
22007 break;
a8be5506
NC
22008 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22009 text = _("<short enum>");
1d15e434 22010 expected_types = bool_expected;
a8be5506
NC
22011 ++ name;
22012 break;
9ef920e9
NC
22013 default:
22014 if (ISPRINT (* name))
22015 {
22016 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22017
22018 if (len > left && ! do_wide)
22019 len = left;
75d7d298 22020 printf ("%.*s:", len, name);
9ef920e9 22021 left -= len;
0dd6ae21 22022 name += len;
9ef920e9
NC
22023 }
22024 else
22025 {
3e6b6445 22026 static char tmpbuf [128];
88305e1b 22027
3e6b6445
NC
22028 error (_("unrecognised byte in name field: %d\n"), * name);
22029 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22030 text = tmpbuf;
22031 name ++;
9ef920e9
NC
22032 }
22033 expected_types = "*$!+";
22034 break;
22035 }
22036
22037 if (text)
88305e1b 22038 left -= printf ("%s", text);
9ef920e9
NC
22039
22040 if (strchr (expected_types, name_type) == NULL)
75d7d298 22041 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22042
26c527e6 22043 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22044 {
26c527e6
AM
22045 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22046 pnote->namesz,
22047 name - pnote->namedata);
015dc7e1 22048 return false;
9ef920e9
NC
22049 }
22050
22051 if (left < 1 && ! do_wide)
015dc7e1 22052 return true;
9ef920e9
NC
22053
22054 switch (name_type)
22055 {
22056 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22057 {
26c527e6
AM
22058 unsigned int bytes;
22059 uint64_t val = 0;
22060 unsigned int shift = 0;
22061 char *decoded = NULL;
ddef72cd 22062
b06b2c92
NC
22063 bytes = pnote->namesz - (name - pnote->namedata);
22064 if (bytes > 0)
22065 /* The -1 is because the name field is always 0 terminated, and we
22066 want to be able to ensure that the shift in the while loop below
22067 will not overflow. */
22068 -- bytes;
22069
ddef72cd
NC
22070 if (bytes > sizeof (val))
22071 {
3e6b6445
NC
22072 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22073 bytes);
22074 bytes = sizeof (val);
ddef72cd 22075 }
3e6b6445
NC
22076 /* We do not bother to warn if bytes == 0 as this can
22077 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22078
22079 while (bytes --)
22080 {
26c527e6 22081 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22082
22083 val |= byte << shift;
9ef920e9
NC
22084 shift += 8;
22085 }
22086
75d7d298 22087 switch (name_attribute)
9ef920e9 22088 {
75d7d298 22089 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22090 switch (val)
22091 {
75d7d298
NC
22092 case 0: decoded = "static"; break;
22093 case 1: decoded = "pic"; break;
22094 case 2: decoded = "PIC"; break;
22095 case 3: decoded = "pie"; break;
22096 case 4: decoded = "PIE"; break;
22097 default: break;
9ef920e9 22098 }
75d7d298
NC
22099 break;
22100 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22101 switch (val)
9ef920e9 22102 {
75d7d298
NC
22103 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22104 case 0: decoded = "off"; break;
22105 case 1: decoded = "on"; break;
22106 case 2: decoded = "all"; break;
22107 case 3: decoded = "strong"; break;
22108 case 4: decoded = "explicit"; break;
22109 default: break;
9ef920e9 22110 }
75d7d298
NC
22111 break;
22112 default:
22113 break;
9ef920e9
NC
22114 }
22115
75d7d298 22116 if (decoded != NULL)
3e6b6445 22117 {
b6ac461a 22118 print_symbol_name (-left, decoded);
3e6b6445
NC
22119 left = 0;
22120 }
22121 else if (val == 0)
22122 {
22123 printf ("0x0");
22124 left -= 3;
22125 }
9ef920e9 22126 else
75d7d298
NC
22127 {
22128 if (do_wide)
26c527e6 22129 left -= printf ("0x%" PRIx64, val);
75d7d298 22130 else
26c527e6 22131 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22132 }
9ef920e9
NC
22133 }
22134 break;
22135 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22136 left -= print_symbol_name (- left, name);
9ef920e9
NC
22137 break;
22138 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22139 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22140 break;
22141 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22142 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22143 break;
22144 }
22145
22146 if (do_wide && left > 0)
22147 printf ("%-*s", left, " ");
9abca702 22148
015dc7e1 22149 return true;
9ef920e9
NC
22150}
22151
2952f10c
SM
22152/* Print the contents of PNOTE as hex. */
22153
22154static void
22155print_note_contents_hex (Elf_Internal_Note *pnote)
22156{
22157 if (pnote->descsz)
22158 {
26c527e6 22159 size_t i;
2952f10c
SM
22160
22161 printf (_(" description data: "));
22162 for (i = 0; i < pnote->descsz; i++)
22163 printf ("%02x ", pnote->descdata[i] & 0xff);
22164 if (!do_wide)
22165 printf ("\n");
22166 }
22167
22168 if (do_wide)
22169 printf ("\n");
22170}
22171
22172#if defined HAVE_MSGPACK
22173
22174static void
22175print_indents (int n)
22176{
22177 printf (" ");
22178
22179 for (int i = 0; i < n; i++)
22180 printf (" ");
22181}
22182
22183/* Print OBJ in human-readable form. */
22184
22185static void
22186dump_msgpack_obj (const msgpack_object *obj, int indent)
22187{
22188 switch (obj->type)
22189 {
22190 case MSGPACK_OBJECT_NIL:
22191 printf ("(nil)");
22192 break;
22193
22194 case MSGPACK_OBJECT_BOOLEAN:
22195 printf ("%s", obj->via.boolean ? "true" : "false");
22196 break;
22197
22198 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22199 printf ("%" PRIu64, obj->via.u64);
22200 break;
22201
22202 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22203 printf ("%" PRIi64, obj->via.i64);
22204 break;
22205
22206 case MSGPACK_OBJECT_FLOAT32:
22207 case MSGPACK_OBJECT_FLOAT64:
22208 printf ("%f", obj->via.f64);
22209 break;
22210
22211 case MSGPACK_OBJECT_STR:
22212 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22213 break;
22214
22215 case MSGPACK_OBJECT_ARRAY:
22216 {
22217 const msgpack_object_array *array = &obj->via.array;
22218
22219 printf ("[\n");
22220 ++indent;
22221
22222 for (uint32_t i = 0; i < array->size; ++i)
22223 {
22224 const msgpack_object *item = &array->ptr[i];
22225
22226 print_indents (indent);
22227 dump_msgpack_obj (item, indent);
22228 printf (",\n");
22229 }
22230
22231 --indent;
22232 print_indents (indent);
22233 printf ("]");
22234 break;
22235 }
22236 break;
22237
22238 case MSGPACK_OBJECT_MAP:
22239 {
22240 const msgpack_object_map *map = &obj->via.map;
22241
22242 printf ("{\n");
22243 ++indent;
22244
22245 for (uint32_t i = 0; i < map->size; ++i)
22246 {
22247 const msgpack_object_kv *kv = &map->ptr[i];
22248 const msgpack_object *key = &kv->key;
22249 const msgpack_object *val = &kv->val;
22250
22251 print_indents (indent);
22252 dump_msgpack_obj (key, indent);
22253 printf (": ");
22254 dump_msgpack_obj (val, indent);
22255
22256 printf (",\n");
22257 }
22258
22259 --indent;
22260 print_indents (indent);
22261 printf ("}");
22262
22263 break;
22264 }
22265
22266 case MSGPACK_OBJECT_BIN:
22267 printf ("(bin)");
22268 break;
22269
22270 case MSGPACK_OBJECT_EXT:
22271 printf ("(ext)");
22272 break;
22273 }
22274}
22275
22276static void
22277dump_msgpack (const msgpack_unpacked *msg)
22278{
22279 print_indents (0);
22280 dump_msgpack_obj (&msg->data, 0);
22281 printf ("\n");
22282}
22283
22284#endif /* defined HAVE_MSGPACK */
22285
22286static bool
22287print_amdgpu_note (Elf_Internal_Note *pnote)
22288{
22289#if defined HAVE_MSGPACK
22290 /* If msgpack is available, decode and dump the note's content. */
22291 bool ret;
22292 msgpack_unpacked msg;
22293 msgpack_unpack_return msgpack_ret;
22294
22295 assert (pnote->type == NT_AMDGPU_METADATA);
22296
22297 msgpack_unpacked_init (&msg);
22298 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22299 NULL);
22300
22301 switch (msgpack_ret)
22302 {
22303 case MSGPACK_UNPACK_SUCCESS:
22304 dump_msgpack (&msg);
22305 ret = true;
22306 break;
22307
22308 default:
22309 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22310 ret = false;
22311 break;
22312 }
22313
22314 msgpack_unpacked_destroy (&msg);
22315 return ret;
22316#else
22317 /* msgpack is not available, dump contents as hex. */
22318 print_note_contents_hex (pnote);
22319 return true;
22320#endif
22321}
22322
e263a66b
CC
22323static bool
22324print_qnx_note (Elf_Internal_Note *pnote)
22325{
22326 switch (pnote->type)
22327 {
22328 case QNT_STACK:
22329 if (pnote->descsz != 12)
22330 goto desc_size_fail;
22331
22332 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22333 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22334 printf (_(" Stack allocated: %" PRIx32 "\n"),
22335 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22336 printf (_(" Executable: %s\n"),
22337 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22338 break;
22339
22340 default:
22341 print_note_contents_hex(pnote);
22342 }
22343 return true;
22344
22345desc_size_fail:
22346 printf (_(" <corrupt - data size is too small>\n"));
22347 error (_("corrupt QNX note: data size is too small\n"));
22348 return false;
22349}
22350
22351
6d118b09
NC
22352/* Note that by the ELF standard, the name field is already null byte
22353 terminated, and namesz includes the terminating null byte.
22354 I.E. the value of namesz for the name "FSF" is 4.
22355
e3c8793a 22356 If the value of namesz is zero, there is no name present. */
9ef920e9 22357
015dc7e1 22358static bool
9ef920e9 22359process_note (Elf_Internal_Note * pnote,
dda8d76d 22360 Filedata * filedata)
779fe533 22361{
2cf0635d
NC
22362 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22363 const char * nt;
9437c45b
JT
22364
22365 if (pnote->namesz == 0)
1ec5cd37
NC
22366 /* If there is no note name, then use the default set of
22367 note type strings. */
dda8d76d 22368 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22369
24d127aa 22370 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22371 /* GNU-specific object file notes. */
22372 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22373
28cdbb18
SM
22374 else if (startswith (pnote->namedata, "AMDGPU"))
22375 /* AMDGPU-specific object file notes. */
22376 nt = get_amdgpu_elf_note_type (pnote->type);
22377
24d127aa 22378 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22379 /* FreeBSD-specific core file notes. */
dda8d76d 22380 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22381
24d127aa 22382 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22383 /* NetBSD-specific core file notes. */
dda8d76d 22384 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22385
24d127aa 22386 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22387 /* NetBSD-specific core file notes. */
22388 return process_netbsd_elf_note (pnote);
22389
24d127aa 22390 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22391 /* NetBSD-specific core file notes. */
22392 return process_netbsd_elf_note (pnote);
22393
98ca73af
FC
22394 else if (startswith (pnote->namedata, "OpenBSD"))
22395 /* OpenBSD-specific core file notes. */
22396 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22397
e263a66b
CC
22398 else if (startswith (pnote->namedata, "QNX"))
22399 /* QNX-specific core file notes. */
22400 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22401
e9b095a5 22402 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22403 {
22404 /* SPU-specific core file notes. */
22405 nt = pnote->namedata + 4;
22406 name = "SPU";
22407 }
22408
24d127aa 22409 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22410 /* VMS/ia64-specific file notes. */
22411 nt = get_ia64_vms_note_type (pnote->type);
22412
24d127aa 22413 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22414 nt = get_stapsdt_note_type (pnote->type);
22415
9437c45b 22416 else
1ec5cd37
NC
22417 /* Don't recognize this note name; just use the default set of
22418 note type strings. */
dda8d76d 22419 nt = get_note_type (filedata, pnote->type);
9437c45b 22420
1449284b 22421 printf (" ");
9ef920e9 22422
24d127aa 22423 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22424 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22425 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22426 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22427 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22428 print_gnu_build_attribute_name (pnote);
22429 else
b6ac461a 22430 print_symbol_name (-20, name);
9ef920e9
NC
22431
22432 if (do_wide)
22433 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22434 else
22435 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22436
24d127aa 22437 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22438 return print_ia64_vms_note (pnote);
24d127aa 22439 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22440 return print_gnu_note (filedata, pnote);
24d127aa 22441 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22442 return print_stapsdt_note (pnote);
24d127aa 22443 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22444 return print_core_note (pnote);
e5382207
LB
22445 else if (startswith (pnote->namedata, "FDO"))
22446 return print_fdo_note (pnote);
24d127aa 22447 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22448 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22449 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22450 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22451 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22452 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22453 else if (startswith (pnote->namedata, "AMDGPU")
22454 && pnote->type == NT_AMDGPU_METADATA)
22455 return print_amdgpu_note (pnote);
e263a66b
CC
22456 else if (startswith (pnote->namedata, "QNX"))
22457 return print_qnx_note (pnote);
779fe533 22458
2952f10c 22459 print_note_contents_hex (pnote);
015dc7e1 22460 return true;
1449284b 22461}
6d118b09 22462
015dc7e1 22463static bool
dda8d76d
NC
22464process_notes_at (Filedata * filedata,
22465 Elf_Internal_Shdr * section,
625d49fc
AM
22466 uint64_t offset,
22467 uint64_t length,
22468 uint64_t align)
779fe533 22469{
015dc7e1
AM
22470 Elf_External_Note *pnotes;
22471 Elf_External_Note *external;
22472 char *end;
22473 bool res = true;
103f02d3 22474
779fe533 22475 if (length <= 0)
015dc7e1 22476 return false;
103f02d3 22477
1449284b
NC
22478 if (section)
22479 {
dda8d76d 22480 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22481 if (pnotes)
32ec8896 22482 {
dda8d76d 22483 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22484 {
22485 free (pnotes);
015dc7e1 22486 return false;
f761cb13 22487 }
32ec8896 22488 }
1449284b
NC
22489 }
22490 else
82ed9683 22491 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22492 _("notes"));
4dff97b2 22493
dd24e3da 22494 if (pnotes == NULL)
015dc7e1 22495 return false;
779fe533 22496
103f02d3 22497 external = pnotes;
103f02d3 22498
ca0e11aa
NC
22499 if (filedata->is_separate)
22500 printf (_("In linked file '%s': "), filedata->file_name);
22501 else
22502 printf ("\n");
1449284b 22503 if (section)
ca0e11aa 22504 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22505 else
26c527e6
AM
22506 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22507 " with length 0x%08" PRIx64 ":\n"),
22508 offset, length);
1449284b 22509
82ed9683
L
22510 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22511 specifies that notes should be aligned to 4 bytes in 32-bit
22512 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22513 we also support 4 byte alignment in 64-bit objects. If section
22514 alignment is less than 4, we treate alignment as 4 bytes. */
22515 if (align < 4)
22516 align = 4;
22517 else if (align != 4 && align != 8)
22518 {
26c527e6
AM
22519 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22520 align);
a788aedd 22521 free (pnotes);
015dc7e1 22522 return false;
82ed9683
L
22523 }
22524
dbe15e4e 22525 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22526
c8071705
NC
22527 end = (char *) pnotes + length;
22528 while ((char *) external < end)
779fe533 22529 {
b34976b6 22530 Elf_Internal_Note inote;
15b42fb0 22531 size_t min_notesz;
4dff97b2 22532 char * next;
2cf0635d 22533 char * temp = NULL;
c8071705 22534 size_t data_remaining = end - (char *) external;
6d118b09 22535
dda8d76d 22536 if (!is_ia64_vms (filedata))
15b42fb0 22537 {
9dd3a467
NC
22538 /* PR binutils/15191
22539 Make sure that there is enough data to read. */
15b42fb0
AM
22540 min_notesz = offsetof (Elf_External_Note, name);
22541 if (data_remaining < min_notesz)
9dd3a467 22542 {
26c527e6 22543 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22544 "not enough for a full note\n",
26c527e6 22545 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22546 "not enough for a full note\n",
22547 data_remaining),
26c527e6 22548 data_remaining);
9dd3a467
NC
22549 break;
22550 }
5396a86e
AM
22551 data_remaining -= min_notesz;
22552
15b42fb0
AM
22553 inote.type = BYTE_GET (external->type);
22554 inote.namesz = BYTE_GET (external->namesz);
22555 inote.namedata = external->name;
22556 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22557 inote.descdata = ((char *) external
4dff97b2 22558 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22559 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22560 next = ((char *) external
4dff97b2 22561 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22562 }
00e98fc7 22563 else
15b42fb0
AM
22564 {
22565 Elf64_External_VMS_Note *vms_external;
00e98fc7 22566
9dd3a467
NC
22567 /* PR binutils/15191
22568 Make sure that there is enough data to read. */
15b42fb0
AM
22569 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22570 if (data_remaining < min_notesz)
9dd3a467 22571 {
26c527e6 22572 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22573 "not enough for a full note\n",
26c527e6 22574 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22575 "not enough for a full note\n",
22576 data_remaining),
26c527e6 22577 data_remaining);
9dd3a467
NC
22578 break;
22579 }
5396a86e 22580 data_remaining -= min_notesz;
3e55a963 22581
15b42fb0
AM
22582 vms_external = (Elf64_External_VMS_Note *) external;
22583 inote.type = BYTE_GET (vms_external->type);
22584 inote.namesz = BYTE_GET (vms_external->namesz);
22585 inote.namedata = vms_external->name;
22586 inote.descsz = BYTE_GET (vms_external->descsz);
22587 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22588 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22589 next = inote.descdata + align_power (inote.descsz, 3);
22590 }
22591
5396a86e
AM
22592 /* PR 17531: file: 3443835e. */
22593 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22594 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22595 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22596 || (size_t) (next - inote.descdata) < inote.descsz
22597 || ((size_t) (next - inote.descdata)
22598 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22599 {
26c527e6
AM
22600 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22601 (char *) external - (char *) pnotes);
22602 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22603 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22604 break;
22605 }
22606
15b42fb0 22607 external = (Elf_External_Note *) next;
dd24e3da 22608
6d118b09
NC
22609 /* Verify that name is null terminated. It appears that at least
22610 one version of Linux (RedHat 6.0) generates corefiles that don't
22611 comply with the ELF spec by failing to include the null byte in
22612 namesz. */
18344509 22613 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22614 {
5396a86e 22615 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22616 {
5396a86e
AM
22617 temp = (char *) malloc (inote.namesz + 1);
22618 if (temp == NULL)
22619 {
22620 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22621 res = false;
5396a86e
AM
22622 break;
22623 }
76da6bbe 22624
5396a86e
AM
22625 memcpy (temp, inote.namedata, inote.namesz);
22626 inote.namedata = temp;
22627 }
22628 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22629 }
22630
dda8d76d 22631 if (! process_note (& inote, filedata))
015dc7e1 22632 res = false;
103f02d3 22633
9db70fc3
AM
22634 free (temp);
22635 temp = NULL;
779fe533
NC
22636 }
22637
22638 free (pnotes);
103f02d3 22639
779fe533
NC
22640 return res;
22641}
22642
015dc7e1 22643static bool
dda8d76d 22644process_corefile_note_segments (Filedata * filedata)
779fe533 22645{
015dc7e1 22646 Elf_Internal_Phdr *segment;
b34976b6 22647 unsigned int i;
015dc7e1 22648 bool res = true;
103f02d3 22649
dda8d76d 22650 if (! get_program_headers (filedata))
015dc7e1 22651 return true;
103f02d3 22652
dda8d76d
NC
22653 for (i = 0, segment = filedata->program_headers;
22654 i < filedata->file_header.e_phnum;
b34976b6 22655 i++, segment++)
779fe533
NC
22656 {
22657 if (segment->p_type == PT_NOTE)
625d49fc
AM
22658 if (! process_notes_at (filedata, NULL, segment->p_offset,
22659 segment->p_filesz, segment->p_align))
015dc7e1 22660 res = false;
779fe533 22661 }
103f02d3 22662
779fe533
NC
22663 return res;
22664}
22665
015dc7e1 22666static bool
625d49fc 22667process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22668{
22669 Elf_External_Note * pnotes;
22670 Elf_External_Note * external;
c8071705 22671 char * end;
015dc7e1 22672 bool res = true;
685080f2
NC
22673
22674 if (length <= 0)
015dc7e1 22675 return false;
685080f2 22676
dda8d76d 22677 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22678 _("v850 notes"));
22679 if (pnotes == NULL)
015dc7e1 22680 return false;
685080f2
NC
22681
22682 external = pnotes;
c8071705 22683 end = (char*) pnotes + length;
685080f2 22684
26c527e6
AM
22685 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22686 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22687 offset, length);
685080f2 22688
c8071705 22689 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22690 {
22691 Elf_External_Note * next;
22692 Elf_Internal_Note inote;
22693
22694 inote.type = BYTE_GET (external->type);
22695 inote.namesz = BYTE_GET (external->namesz);
22696 inote.namedata = external->name;
22697 inote.descsz = BYTE_GET (external->descsz);
22698 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22699 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22700
c8071705
NC
22701 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22702 {
22703 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22704 inote.descdata = inote.namedata;
22705 inote.namesz = 0;
22706 }
22707
685080f2
NC
22708 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22709
c8071705 22710 if ( ((char *) next > end)
685080f2
NC
22711 || ((char *) next < (char *) pnotes))
22712 {
26c527e6
AM
22713 warn (_("corrupt descsz found in note at offset %#tx\n"),
22714 (char *) external - (char *) pnotes);
22715 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22716 inote.type, inote.namesz, inote.descsz);
22717 break;
22718 }
22719
22720 external = next;
22721
22722 /* Prevent out-of-bounds indexing. */
c8071705 22723 if ( inote.namedata + inote.namesz > end
685080f2
NC
22724 || inote.namedata + inote.namesz < inote.namedata)
22725 {
26c527e6
AM
22726 warn (_("corrupt namesz found in note at offset %#zx\n"),
22727 (char *) external - (char *) pnotes);
22728 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22729 inote.type, inote.namesz, inote.descsz);
22730 break;
22731 }
22732
22733 printf (" %s: ", get_v850_elf_note_type (inote.type));
22734
22735 if (! print_v850_note (& inote))
22736 {
015dc7e1 22737 res = false;
26c527e6 22738 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22739 inote.namesz, inote.descsz);
22740 }
22741 }
22742
22743 free (pnotes);
22744
22745 return res;
22746}
22747
015dc7e1 22748static bool
dda8d76d 22749process_note_sections (Filedata * filedata)
1ec5cd37 22750{
015dc7e1 22751 Elf_Internal_Shdr *section;
26c527e6 22752 size_t i;
32ec8896 22753 unsigned int n = 0;
015dc7e1 22754 bool res = true;
1ec5cd37 22755
dda8d76d
NC
22756 for (i = 0, section = filedata->section_headers;
22757 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22758 i++, section++)
685080f2
NC
22759 {
22760 if (section->sh_type == SHT_NOTE)
22761 {
625d49fc
AM
22762 if (! process_notes_at (filedata, section, section->sh_offset,
22763 section->sh_size, section->sh_addralign))
015dc7e1 22764 res = false;
685080f2
NC
22765 n++;
22766 }
22767
dda8d76d
NC
22768 if (( filedata->file_header.e_machine == EM_V800
22769 || filedata->file_header.e_machine == EM_V850
22770 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22771 && section->sh_type == SHT_RENESAS_INFO)
22772 {
625d49fc
AM
22773 if (! process_v850_notes (filedata, section->sh_offset,
22774 section->sh_size))
015dc7e1 22775 res = false;
685080f2
NC
22776 n++;
22777 }
22778 }
df565f32
NC
22779
22780 if (n == 0)
22781 /* Try processing NOTE segments instead. */
dda8d76d 22782 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22783
22784 return res;
22785}
22786
015dc7e1 22787static bool
dda8d76d 22788process_notes (Filedata * filedata)
779fe533
NC
22789{
22790 /* If we have not been asked to display the notes then do nothing. */
22791 if (! do_notes)
015dc7e1 22792 return true;
103f02d3 22793
dda8d76d
NC
22794 if (filedata->file_header.e_type != ET_CORE)
22795 return process_note_sections (filedata);
103f02d3 22796
779fe533 22797 /* No program headers means no NOTE segment. */
dda8d76d
NC
22798 if (filedata->file_header.e_phnum > 0)
22799 return process_corefile_note_segments (filedata);
779fe533 22800
ca0e11aa
NC
22801 if (filedata->is_separate)
22802 printf (_("No notes found in linked file '%s'.\n"),
22803 filedata->file_name);
22804 else
22805 printf (_("No notes found file.\n"));
22806
015dc7e1 22807 return true;
779fe533
NC
22808}
22809
60abdbed
NC
22810static unsigned char *
22811display_public_gnu_attributes (unsigned char * start,
22812 const unsigned char * const end)
22813{
22814 printf (_(" Unknown GNU attribute: %s\n"), start);
22815
22816 start += strnlen ((char *) start, end - start);
22817 display_raw_attribute (start, end);
22818
22819 return (unsigned char *) end;
22820}
22821
22822static unsigned char *
22823display_generic_attribute (unsigned char * start,
22824 unsigned int tag,
22825 const unsigned char * const end)
22826{
22827 if (tag == 0)
22828 return (unsigned char *) end;
22829
22830 return display_tag_value (tag, start, end);
22831}
22832
015dc7e1 22833static bool
dda8d76d 22834process_arch_specific (Filedata * filedata)
252b5132 22835{
a952a375 22836 if (! do_arch)
015dc7e1 22837 return true;
a952a375 22838
dda8d76d 22839 switch (filedata->file_header.e_machine)
252b5132 22840 {
53a346d8
CZ
22841 case EM_ARC:
22842 case EM_ARC_COMPACT:
22843 case EM_ARC_COMPACT2:
b5c37946
SJ
22844 case EM_ARC_COMPACT3:
22845 case EM_ARC_COMPACT3_64:
dda8d76d 22846 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22847 display_arc_attribute,
22848 display_generic_attribute);
11c1ff18 22849 case EM_ARM:
dda8d76d 22850 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22851 display_arm_attribute,
22852 display_generic_attribute);
22853
252b5132 22854 case EM_MIPS:
4fe85591 22855 case EM_MIPS_RS3_LE:
dda8d76d 22856 return process_mips_specific (filedata);
60abdbed
NC
22857
22858 case EM_MSP430:
dda8d76d 22859 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22860 display_msp430_attribute,
c0ea7c52 22861 display_msp430_gnu_attribute);
60abdbed 22862
2dc8dd17
JW
22863 case EM_RISCV:
22864 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22865 display_riscv_attribute,
22866 display_generic_attribute);
22867
35c08157 22868 case EM_NDS32:
dda8d76d 22869 return process_nds32_specific (filedata);
60abdbed 22870
85f7484a
PB
22871 case EM_68K:
22872 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22873 display_m68k_gnu_attribute);
22874
34c8bcba 22875 case EM_PPC:
b82317dd 22876 case EM_PPC64:
dda8d76d 22877 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22878 display_power_gnu_attribute);
22879
643f7afb
AK
22880 case EM_S390:
22881 case EM_S390_OLD:
dda8d76d 22882 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22883 display_s390_gnu_attribute);
22884
9e8c70f9
DM
22885 case EM_SPARC:
22886 case EM_SPARC32PLUS:
22887 case EM_SPARCV9:
dda8d76d 22888 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22889 display_sparc_gnu_attribute);
22890
59e6276b 22891 case EM_TI_C6000:
dda8d76d 22892 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22893 display_tic6x_attribute,
22894 display_generic_attribute);
22895
0861f561
CQ
22896 case EM_CSKY:
22897 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22898 display_csky_attribute, NULL);
22899
252b5132 22900 default:
dda8d76d 22901 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22902 display_public_gnu_attributes,
22903 display_generic_attribute);
252b5132 22904 }
252b5132
RH
22905}
22906
015dc7e1 22907static bool
dda8d76d 22908get_file_header (Filedata * filedata)
252b5132 22909{
9ea033b2 22910 /* Read in the identity array. */
dda8d76d 22911 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22912 return false;
252b5132 22913
9ea033b2 22914 /* Determine how to read the rest of the header. */
dda8d76d 22915 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22916 {
1a0670f3
AM
22917 default:
22918 case ELFDATANONE:
adab8cdc
AO
22919 case ELFDATA2LSB:
22920 byte_get = byte_get_little_endian;
22921 byte_put = byte_put_little_endian;
22922 break;
22923 case ELFDATA2MSB:
22924 byte_get = byte_get_big_endian;
22925 byte_put = byte_put_big_endian;
22926 break;
9ea033b2
NC
22927 }
22928
22929 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22930 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22931
22932 /* Read in the rest of the header. */
22933 if (is_32bit_elf)
22934 {
22935 Elf32_External_Ehdr ehdr32;
252b5132 22936
dda8d76d 22937 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22938 return false;
103f02d3 22939
dda8d76d
NC
22940 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22941 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22942 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22943 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22944 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22945 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22946 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22947 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22948 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22949 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22950 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22951 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22952 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22953 }
252b5132 22954 else
9ea033b2
NC
22955 {
22956 Elf64_External_Ehdr ehdr64;
a952a375 22957
dda8d76d 22958 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22959 return false;
103f02d3 22960
dda8d76d
NC
22961 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22962 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22963 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22964 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22965 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22966 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22967 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22968 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22969 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22970 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22971 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22972 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22973 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22974 }
252b5132 22975
015dc7e1 22976 return true;
252b5132
RH
22977}
22978
13acb58d
AM
22979static void
22980free_filedata (Filedata *filedata)
22981{
22982 free (filedata->program_interpreter);
13acb58d 22983 free (filedata->program_headers);
13acb58d 22984 free (filedata->section_headers);
13acb58d 22985 free (filedata->string_table);
13acb58d 22986 free (filedata->dump.dump_sects);
13acb58d 22987 free (filedata->dynamic_strings);
13acb58d 22988 free (filedata->dynamic_symbols);
13acb58d 22989 free (filedata->dynamic_syminfo);
13acb58d 22990 free (filedata->dynamic_section);
13acb58d
AM
22991
22992 while (filedata->symtab_shndx_list != NULL)
22993 {
22994 elf_section_list *next = filedata->symtab_shndx_list->next;
22995 free (filedata->symtab_shndx_list);
22996 filedata->symtab_shndx_list = next;
22997 }
22998
22999 free (filedata->section_headers_groups);
13acb58d
AM
23000
23001 if (filedata->section_groups)
23002 {
23003 size_t i;
23004 struct group_list * g;
23005 struct group_list * next;
23006
23007 for (i = 0; i < filedata->group_count; i++)
23008 {
23009 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23010 {
23011 next = g->next;
23012 free (g);
23013 }
23014 }
23015
23016 free (filedata->section_groups);
13acb58d 23017 }
066f8fbe
AM
23018 memset (&filedata->section_headers, 0,
23019 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23020}
23021
dda8d76d
NC
23022static void
23023close_file (Filedata * filedata)
23024{
23025 if (filedata)
23026 {
23027 if (filedata->handle)
23028 fclose (filedata->handle);
23029 free (filedata);
23030 }
23031}
23032
23033void
23034close_debug_file (void * data)
23035{
13acb58d 23036 free_filedata ((Filedata *) data);
dda8d76d
NC
23037 close_file ((Filedata *) data);
23038}
23039
23040static Filedata *
015dc7e1 23041open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23042{
23043 struct stat statbuf;
23044 Filedata * filedata = NULL;
23045
23046 if (stat (pathname, & statbuf) < 0
23047 || ! S_ISREG (statbuf.st_mode))
23048 goto fail;
23049
23050 filedata = calloc (1, sizeof * filedata);
23051 if (filedata == NULL)
23052 goto fail;
23053
23054 filedata->handle = fopen (pathname, "rb");
23055 if (filedata->handle == NULL)
23056 goto fail;
23057
be7d229a 23058 filedata->file_size = statbuf.st_size;
dda8d76d 23059 filedata->file_name = pathname;
ca0e11aa 23060 filedata->is_separate = is_separate;
dda8d76d
NC
23061
23062 if (! get_file_header (filedata))
23063 goto fail;
23064
4de91c10
AM
23065 if (!get_section_headers (filedata, false))
23066 goto fail;
dda8d76d
NC
23067
23068 return filedata;
23069
23070 fail:
23071 if (filedata)
23072 {
23073 if (filedata->handle)
23074 fclose (filedata->handle);
23075 free (filedata);
23076 }
23077 return NULL;
23078}
23079
23080void *
23081open_debug_file (const char * pathname)
23082{
015dc7e1 23083 return open_file (pathname, true);
dda8d76d
NC
23084}
23085
835f2fae
NC
23086static void
23087initialise_dump_sects (Filedata * filedata)
23088{
23089 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23090 Note we do this even if cmdline_dump_sects is empty because we
23091 must make sure that the dump_sets array is zeroed out before each
23092 object file is processed. */
23093 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23094 memset (filedata->dump.dump_sects, 0,
23095 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23096
23097 if (cmdline.num_dump_sects > 0)
23098 {
23099 if (filedata->dump.num_dump_sects == 0)
23100 /* A sneaky way of allocating the dump_sects array. */
23101 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23102
23103 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23104 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23105 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23106 }
23107}
23108
94585d6d
NC
23109static bool
23110might_need_separate_debug_info (Filedata * filedata)
23111{
23112 /* Debuginfo files do not need further separate file loading. */
23113 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23114 return false;
23115
23116 /* Since do_follow_links might be enabled by default, only treat it as an
23117 indication that separate files should be loaded if setting it was a
23118 deliberate user action. */
23119 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23120 return true;
23121
23122 if (process_links || do_syms || do_unwind
23123 || dump_any_debugging || do_dump || do_debugging)
23124 return true;
23125
23126 return false;
23127}
23128
fb52b2f4
NC
23129/* Process one ELF object file according to the command line options.
23130 This file may actually be stored in an archive. The file is
32ec8896
NC
23131 positioned at the start of the ELF object. Returns TRUE if no
23132 problems were encountered, FALSE otherwise. */
fb52b2f4 23133
015dc7e1 23134static bool
dda8d76d 23135process_object (Filedata * filedata)
252b5132 23136{
015dc7e1 23137 bool have_separate_files;
252b5132 23138 unsigned int i;
015dc7e1 23139 bool res;
252b5132 23140
dda8d76d 23141 if (! get_file_header (filedata))
252b5132 23142 {
dda8d76d 23143 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23144 return false;
252b5132
RH
23145 }
23146
23147 /* Initialise per file variables. */
978c4450
AM
23148 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23149 filedata->version_info[i] = 0;
252b5132 23150
978c4450
AM
23151 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23152 filedata->dynamic_info[i] = 0;
23153 filedata->dynamic_info_DT_GNU_HASH = 0;
23154 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23155
23156 /* Process the file. */
23157 if (show_name)
dda8d76d 23158 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23159
835f2fae 23160 initialise_dump_sects (filedata);
d70c5fc7 23161
4de91c10
AM
23162 /* There may be some extensions in the first section header. Don't
23163 bomb if we can't read it. */
23164 get_section_headers (filedata, true);
23165
dda8d76d 23166 if (! process_file_header (filedata))
4de91c10
AM
23167 {
23168 res = false;
23169 goto out;
23170 }
252b5132 23171
e331b18d
AM
23172 /* Throw away the single section header read above, so that we
23173 re-read the entire set. */
23174 free (filedata->section_headers);
23175 filedata->section_headers = NULL;
23176
dda8d76d 23177 if (! process_section_headers (filedata))
2f62977e 23178 {
32ec8896 23179 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23180 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23181
2f62977e 23182 if (! do_using_dynamic)
015dc7e1 23183 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23184 }
252b5132 23185
dda8d76d 23186 if (! process_section_groups (filedata))
32ec8896 23187 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23188 do_unwind = false;
d1f5c6e3 23189
93df3340
AM
23190 process_program_headers (filedata);
23191
23192 res = process_dynamic_section (filedata);
252b5132 23193
dda8d76d 23194 if (! process_relocs (filedata))
015dc7e1 23195 res = false;
252b5132 23196
dda8d76d 23197 if (! process_unwind (filedata))
015dc7e1 23198 res = false;
4d6ed7c8 23199
dda8d76d 23200 if (! process_symbol_table (filedata))
015dc7e1 23201 res = false;
252b5132 23202
0f03783c 23203 if (! process_lto_symbol_tables (filedata))
015dc7e1 23204 res = false;
b9e920ec 23205
dda8d76d 23206 if (! process_syminfo (filedata))
015dc7e1 23207 res = false;
252b5132 23208
dda8d76d 23209 if (! process_version_sections (filedata))
015dc7e1 23210 res = false;
252b5132 23211
94585d6d 23212 if (might_need_separate_debug_info (filedata))
24841daa 23213 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23214 else
015dc7e1 23215 have_separate_files = false;
dda8d76d
NC
23216
23217 if (! process_section_contents (filedata))
015dc7e1 23218 res = false;
f5842774 23219
24841daa 23220 if (have_separate_files)
dda8d76d 23221 {
24841daa
NC
23222 separate_info * d;
23223
23224 for (d = first_separate_info; d != NULL; d = d->next)
23225 {
835f2fae
NC
23226 initialise_dump_sects (d->handle);
23227
ca0e11aa 23228 if (process_links && ! process_file_header (d->handle))
015dc7e1 23229 res = false;
ca0e11aa 23230 else if (! process_section_headers (d->handle))
015dc7e1 23231 res = false;
d6bfbc39 23232 else if (! process_section_contents (d->handle))
015dc7e1 23233 res = false;
ca0e11aa
NC
23234 else if (process_links)
23235 {
ca0e11aa 23236 if (! process_section_groups (d->handle))
015dc7e1 23237 res = false;
93df3340 23238 process_program_headers (d->handle);
ca0e11aa 23239 if (! process_dynamic_section (d->handle))
015dc7e1 23240 res = false;
ca0e11aa 23241 if (! process_relocs (d->handle))
015dc7e1 23242 res = false;
ca0e11aa 23243 if (! process_unwind (d->handle))
015dc7e1 23244 res = false;
ca0e11aa 23245 if (! process_symbol_table (d->handle))
015dc7e1 23246 res = false;
ca0e11aa 23247 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23248 res = false;
ca0e11aa 23249 if (! process_syminfo (d->handle))
015dc7e1 23250 res = false;
ca0e11aa 23251 if (! process_version_sections (d->handle))
015dc7e1 23252 res = false;
ca0e11aa 23253 if (! process_notes (d->handle))
015dc7e1 23254 res = false;
ca0e11aa 23255 }
24841daa
NC
23256 }
23257
23258 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23259 }
23260
23261 if (! process_notes (filedata))
015dc7e1 23262 res = false;
103f02d3 23263
dda8d76d 23264 if (! process_gnu_liblist (filedata))
015dc7e1 23265 res = false;
047b2264 23266
dda8d76d 23267 if (! process_arch_specific (filedata))
015dc7e1 23268 res = false;
252b5132 23269
4de91c10 23270 out:
13acb58d 23271 free_filedata (filedata);
e4b17d5c 23272
19e6b90e 23273 free_debug_memory ();
18bd398b 23274
32ec8896 23275 return res;
252b5132
RH
23276}
23277
2cf0635d 23278/* Process an ELF archive.
32ec8896
NC
23279 On entry the file is positioned just after the ARMAG string.
23280 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23281
015dc7e1
AM
23282static bool
23283process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23284{
23285 struct archive_info arch;
23286 struct archive_info nested_arch;
23287 size_t got;
015dc7e1 23288 bool ret = true;
2cf0635d 23289
015dc7e1 23290 show_name = true;
2cf0635d
NC
23291
23292 /* The ARCH structure is used to hold information about this archive. */
23293 arch.file_name = NULL;
23294 arch.file = NULL;
23295 arch.index_array = NULL;
23296 arch.sym_table = NULL;
23297 arch.longnames = NULL;
23298
23299 /* The NESTED_ARCH structure is used as a single-item cache of information
23300 about a nested archive (when members of a thin archive reside within
23301 another regular archive file). */
23302 nested_arch.file_name = NULL;
23303 nested_arch.file = NULL;
23304 nested_arch.index_array = NULL;
23305 nested_arch.sym_table = NULL;
23306 nested_arch.longnames = NULL;
23307
dda8d76d 23308 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23309 filedata->file_size, is_thin_archive,
23310 do_archive_index) != 0)
2cf0635d 23311 {
015dc7e1 23312 ret = false;
2cf0635d 23313 goto out;
4145f1d5 23314 }
fb52b2f4 23315
4145f1d5
NC
23316 if (do_archive_index)
23317 {
2cf0635d 23318 if (arch.sym_table == NULL)
1cb7d8b1
AM
23319 error (_("%s: unable to dump the index as none was found\n"),
23320 filedata->file_name);
4145f1d5
NC
23321 else
23322 {
26c527e6
AM
23323 uint64_t i, l;
23324 uint64_t current_pos;
4145f1d5 23325
26c527e6
AM
23326 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23327 " %#" PRIx64 " bytes in the symbol table)\n"),
23328 filedata->file_name, arch.index_num,
1cb7d8b1 23329 arch.sym_size);
dda8d76d
NC
23330
23331 current_pos = ftell (filedata->handle);
4145f1d5 23332
2cf0635d 23333 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23334 {
1cb7d8b1
AM
23335 if (i == 0
23336 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23337 {
23338 char * member_name
23339 = get_archive_member_name_at (&arch, arch.index_array[i],
23340 &nested_arch);
2cf0635d 23341
1cb7d8b1
AM
23342 if (member_name != NULL)
23343 {
23344 char * qualified_name
23345 = make_qualified_name (&arch, &nested_arch,
23346 member_name);
2cf0635d 23347
1cb7d8b1
AM
23348 if (qualified_name != NULL)
23349 {
23350 printf (_("Contents of binary %s at offset "),
23351 qualified_name);
c2a7d3f5
NC
23352 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23353 putchar ('\n');
1cb7d8b1
AM
23354 free (qualified_name);
23355 }
fd486f32 23356 free (member_name);
4145f1d5
NC
23357 }
23358 }
2cf0635d
NC
23359
23360 if (l >= arch.sym_size)
4145f1d5 23361 {
1cb7d8b1
AM
23362 error (_("%s: end of the symbol table reached "
23363 "before the end of the index\n"),
dda8d76d 23364 filedata->file_name);
015dc7e1 23365 ret = false;
cb8f3167 23366 break;
4145f1d5 23367 }
591f7597 23368 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23369 printf ("\t%.*s\n",
23370 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23371 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23372 }
23373
67ce483b 23374 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23375 l = (l + 7) & ~ 7;
23376 else
23377 l += l & 1;
23378
2cf0635d 23379 if (l < arch.sym_size)
32ec8896 23380 {
26c527e6 23381 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23382 "but without corresponding entries in "
23383 "the index table\n",
26c527e6 23384 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23385 "but without corresponding entries in "
23386 "the index table\n",
23387 arch.sym_size - l),
dda8d76d 23388 filedata->file_name, arch.sym_size - l);
015dc7e1 23389 ret = false;
32ec8896 23390 }
4145f1d5 23391
63cf857e 23392 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23393 {
1cb7d8b1
AM
23394 error (_("%s: failed to seek back to start of object files "
23395 "in the archive\n"),
dda8d76d 23396 filedata->file_name);
015dc7e1 23397 ret = false;
2cf0635d 23398 goto out;
4145f1d5 23399 }
fb52b2f4 23400 }
4145f1d5
NC
23401
23402 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23403 && !do_segments && !do_header && !do_dump && !do_version
23404 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23405 && !do_section_groups && !do_dyn_syms)
2cf0635d 23406 {
015dc7e1 23407 ret = true; /* Archive index only. */
2cf0635d
NC
23408 goto out;
23409 }
fb52b2f4
NC
23410 }
23411
fb52b2f4
NC
23412 while (1)
23413 {
2cf0635d
NC
23414 char * name;
23415 size_t namelen;
23416 char * qualified_name;
23417
23418 /* Read the next archive header. */
63cf857e 23419 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23420 {
23421 error (_("%s: failed to seek to next archive header\n"),
23422 arch.file_name);
015dc7e1 23423 ret = false;
1cb7d8b1
AM
23424 break;
23425 }
dda8d76d 23426 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23427 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23428 {
23429 if (got == 0)
2cf0635d 23430 break;
28e817cc
NC
23431 /* PR 24049 - we cannot use filedata->file_name as this will
23432 have already been freed. */
23433 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23434
015dc7e1 23435 ret = false;
1cb7d8b1
AM
23436 break;
23437 }
2cf0635d 23438 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23439 {
23440 error (_("%s: did not find a valid archive header\n"),
23441 arch.file_name);
015dc7e1 23442 ret = false;
1cb7d8b1
AM
23443 break;
23444 }
2cf0635d
NC
23445
23446 arch.next_arhdr_offset += sizeof arch.arhdr;
23447
978c4450 23448 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23449
23450 name = get_archive_member_name (&arch, &nested_arch);
23451 if (name == NULL)
fb52b2f4 23452 {
28e817cc 23453 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23454 ret = false;
d989285c 23455 break;
fb52b2f4 23456 }
2cf0635d 23457 namelen = strlen (name);
fb52b2f4 23458
2cf0635d
NC
23459 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23460 if (qualified_name == NULL)
fb52b2f4 23461 {
28e817cc 23462 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23463 free (name);
015dc7e1 23464 ret = false;
d989285c 23465 break;
fb52b2f4
NC
23466 }
23467
2cf0635d 23468 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23469 {
23470 /* This is a proxy for an external member of a thin archive. */
23471 Filedata * member_filedata;
23472 char * member_file_name = adjust_relative_path
dda8d76d 23473 (filedata->file_name, name, namelen);
32ec8896 23474
fd486f32 23475 free (name);
1cb7d8b1
AM
23476 if (member_file_name == NULL)
23477 {
fd486f32 23478 free (qualified_name);
015dc7e1 23479 ret = false;
1cb7d8b1
AM
23480 break;
23481 }
2cf0635d 23482
015dc7e1 23483 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23484 if (member_filedata == NULL)
23485 {
23486 error (_("Input file '%s' is not readable.\n"), member_file_name);
23487 free (member_file_name);
fd486f32 23488 free (qualified_name);
015dc7e1 23489 ret = false;
1cb7d8b1
AM
23490 break;
23491 }
2cf0635d 23492
978c4450 23493 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23494 member_filedata->file_name = qualified_name;
2cf0635d 23495
75a2da57
AH
23496 /* The call to process_object() expects the file to be at the beginning. */
23497 rewind (member_filedata->handle);
23498
1cb7d8b1 23499 if (! process_object (member_filedata))
015dc7e1 23500 ret = false;
2cf0635d 23501
1cb7d8b1
AM
23502 close_file (member_filedata);
23503 free (member_file_name);
1cb7d8b1 23504 }
2cf0635d 23505 else if (is_thin_archive)
1cb7d8b1
AM
23506 {
23507 Filedata thin_filedata;
eb02c04d 23508
1cb7d8b1 23509 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23510
a043396b
NC
23511 /* PR 15140: Allow for corrupt thin archives. */
23512 if (nested_arch.file == NULL)
23513 {
23514 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23515 qualified_name, name);
fd486f32
AM
23516 free (qualified_name);
23517 free (name);
015dc7e1 23518 ret = false;
a043396b
NC
23519 break;
23520 }
fd486f32 23521 free (name);
a043396b 23522
1cb7d8b1 23523 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23524 filedata->archive_file_offset
23525 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23526
1cb7d8b1
AM
23527 /* The nested archive file will have been opened and setup by
23528 get_archive_member_name. */
63cf857e
AM
23529 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23530 SEEK_SET) != 0)
1cb7d8b1
AM
23531 {
23532 error (_("%s: failed to seek to archive member.\n"),
23533 nested_arch.file_name);
fd486f32 23534 free (qualified_name);
015dc7e1 23535 ret = false;
1cb7d8b1
AM
23536 break;
23537 }
2cf0635d 23538
dda8d76d
NC
23539 thin_filedata.handle = nested_arch.file;
23540 thin_filedata.file_name = qualified_name;
9abca702 23541
1cb7d8b1 23542 if (! process_object (& thin_filedata))
015dc7e1 23543 ret = false;
1cb7d8b1 23544 }
2cf0635d 23545 else
1cb7d8b1 23546 {
fd486f32 23547 free (name);
978c4450 23548 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23549 filedata->file_name = qualified_name;
1cb7d8b1 23550 if (! process_object (filedata))
015dc7e1 23551 ret = false;
237877b8 23552 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23553 /* Stop looping with "negative" archive_file_size. */
978c4450 23554 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23555 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23556 }
fb52b2f4 23557
2cf0635d 23558 free (qualified_name);
fb52b2f4
NC
23559 }
23560
4145f1d5 23561 out:
2cf0635d
NC
23562 if (nested_arch.file != NULL)
23563 fclose (nested_arch.file);
23564 release_archive (&nested_arch);
23565 release_archive (&arch);
fb52b2f4 23566
d989285c 23567 return ret;
fb52b2f4
NC
23568}
23569
015dc7e1 23570static bool
2cf0635d 23571process_file (char * file_name)
fb52b2f4 23572{
dda8d76d 23573 Filedata * filedata = NULL;
fb52b2f4
NC
23574 struct stat statbuf;
23575 char armag[SARMAG];
015dc7e1 23576 bool ret = true;
fb52b2f4
NC
23577
23578 if (stat (file_name, &statbuf) < 0)
23579 {
f24ddbdd
NC
23580 if (errno == ENOENT)
23581 error (_("'%s': No such file\n"), file_name);
23582 else
23583 error (_("Could not locate '%s'. System error message: %s\n"),
23584 file_name, strerror (errno));
015dc7e1 23585 return false;
f24ddbdd
NC
23586 }
23587
23588 if (! S_ISREG (statbuf.st_mode))
23589 {
23590 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23591 return false;
fb52b2f4
NC
23592 }
23593
dda8d76d
NC
23594 filedata = calloc (1, sizeof * filedata);
23595 if (filedata == NULL)
23596 {
23597 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23598 return false;
dda8d76d
NC
23599 }
23600
23601 filedata->file_name = file_name;
23602 filedata->handle = fopen (file_name, "rb");
23603 if (filedata->handle == NULL)
fb52b2f4 23604 {
f24ddbdd 23605 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23606 free (filedata);
015dc7e1 23607 return false;
fb52b2f4
NC
23608 }
23609
dda8d76d 23610 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23611 {
4145f1d5 23612 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23613 fclose (filedata->handle);
23614 free (filedata);
015dc7e1 23615 return false;
fb52b2f4
NC
23616 }
23617
be7d229a 23618 filedata->file_size = statbuf.st_size;
015dc7e1 23619 filedata->is_separate = false;
f54498b4 23620
fb52b2f4 23621 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23622 {
015dc7e1
AM
23623 if (! process_archive (filedata, false))
23624 ret = false;
32ec8896 23625 }
2cf0635d 23626 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23627 {
015dc7e1
AM
23628 if ( ! process_archive (filedata, true))
23629 ret = false;
32ec8896 23630 }
fb52b2f4
NC
23631 else
23632 {
1b513401 23633 if (do_archive_index && !check_all)
4145f1d5
NC
23634 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23635 file_name);
23636
dda8d76d 23637 rewind (filedata->handle);
978c4450 23638 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23639
dda8d76d 23640 if (! process_object (filedata))
015dc7e1 23641 ret = false;
fb52b2f4
NC
23642 }
23643
dda8d76d 23644 fclose (filedata->handle);
8fb879cd
AM
23645 free (filedata->section_headers);
23646 free (filedata->program_headers);
23647 free (filedata->string_table);
6431e409 23648 free (filedata->dump.dump_sects);
dda8d76d 23649 free (filedata);
32ec8896 23650
fd486f32 23651 free (ba_cache.strtab);
1bd6175a 23652 ba_cache.strtab = NULL;
fd486f32 23653 free (ba_cache.symtab);
1bd6175a 23654 ba_cache.symtab = NULL;
fd486f32
AM
23655 ba_cache.filedata = NULL;
23656
fb52b2f4
NC
23657 return ret;
23658}
23659
252b5132
RH
23660#ifdef SUPPORT_DISASSEMBLY
23661/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23662 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23663 symbols. */
252b5132
RH
23664
23665void
2cf0635d 23666print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23667{
23668 fprintf (outfile,"0x%8.8x", addr);
23669}
23670
e3c8793a 23671/* Needed by the i386 disassembler. */
dda8d76d 23672
252b5132
RH
23673void
23674db_task_printsym (unsigned int addr)
23675{
23676 print_address (addr, stderr);
23677}
23678#endif
23679
23680int
2cf0635d 23681main (int argc, char ** argv)
252b5132 23682{
ff78d6d6
L
23683 int err;
23684
87b9f255 23685#ifdef HAVE_LC_MESSAGES
252b5132 23686 setlocale (LC_MESSAGES, "");
3882b010 23687#endif
3882b010 23688 setlocale (LC_CTYPE, "");
252b5132
RH
23689 bindtextdomain (PACKAGE, LOCALEDIR);
23690 textdomain (PACKAGE);
23691
869b9d07
MM
23692 expandargv (&argc, &argv);
23693
dda8d76d 23694 parse_args (& cmdline, argc, argv);
59f14fc0 23695
18bd398b 23696 if (optind < (argc - 1))
1b513401
NC
23697 /* When displaying information for more than one file,
23698 prefix the information with the file name. */
015dc7e1 23699 show_name = true;
5656ba2c
L
23700 else if (optind >= argc)
23701 {
1b513401 23702 /* Ensure that the warning is always displayed. */
015dc7e1 23703 do_checks = true;
1b513401 23704
5656ba2c
L
23705 warn (_("Nothing to do.\n"));
23706 usage (stderr);
23707 }
18bd398b 23708
015dc7e1 23709 err = false;
252b5132 23710 while (optind < argc)
32ec8896 23711 if (! process_file (argv[optind++]))
015dc7e1 23712 err = true;
252b5132 23713
9db70fc3 23714 free (cmdline.dump_sects);
252b5132 23715
7d9813f1
NA
23716 free (dump_ctf_symtab_name);
23717 free (dump_ctf_strtab_name);
23718 free (dump_ctf_parent_name);
23719
32ec8896 23720 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23721}