]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
[gdb/testsuite] Fix stray file in get_compiler_info
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
fd67aa11 2 Copyright (C) 1998-2024 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. */
8e8d0b63 191#ifdef SUPPORT_DISASSEMBLY
dda8d76d 192#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
8e8d0b63 193#endif
dda8d76d
NC
194#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
195#define STRING_DUMP (1 << 3) /* The -p command line switch. */
196#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 197#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 198#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
8e8d0b63 199#define AUTO_DUMP (1 << 7) /* The -j command line switch. */
dda8d76d
NC
200
201typedef unsigned char dump_type;
202
203/* A linked list of the section names for which dumps were requested. */
204struct dump_list_entry
205{
206 char * name;
207 dump_type type;
208 struct dump_list_entry * next;
209};
210
6431e409
AM
211/* A dynamic array of flags indicating for which sections a dump
212 has been requested via command line switches. */
1b513401
NC
213struct dump_data
214{
6431e409
AM
215 dump_type * dump_sects;
216 unsigned int num_dump_sects;
217};
218
219static struct dump_data cmdline;
220
221static struct dump_list_entry * dump_sects_byname;
222
2cf0635d 223char * program_name = "readelf";
dda8d76d 224
015dc7e1
AM
225static bool show_name = false;
226static bool do_dynamic = false;
227static bool do_syms = false;
228static bool do_dyn_syms = false;
229static bool do_lto_syms = false;
230static bool do_reloc = false;
231static bool do_sections = false;
232static bool do_section_groups = false;
233static bool do_section_details = false;
234static bool do_segments = false;
235static bool do_unwind = false;
236static bool do_using_dynamic = false;
237static bool do_header = false;
238static bool do_dump = false;
239static bool do_version = false;
240static bool do_histogram = false;
241static bool do_debugging = false;
242static bool do_ctf = false;
42b6953b 243static bool do_sframe = false;
015dc7e1
AM
244static bool do_arch = false;
245static bool do_notes = false;
246static bool do_archive_index = false;
247static bool check_all = false;
248static bool is_32bit_elf = false;
249static bool decompress_dumps = false;
250static bool do_not_show_symbol_truncation = false;
251static bool do_demangle = false; /* Pretty print C++ symbol names. */
252static bool process_links = false;
e1dbfc17 253static bool dump_any_debugging = false;
b6ac461a 254static bool extra_sym_info = false;
79bc120c 255static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 256static int sym_base = 0;
252b5132 257
7d9813f1
NA
258static char *dump_ctf_parent_name;
259static char *dump_ctf_symtab_name;
260static char *dump_ctf_strtab_name;
261
e4b17d5c
L
262struct group_list
263{
dda8d76d
NC
264 struct group_list * next;
265 unsigned int section_index;
e4b17d5c
L
266};
267
268struct group
269{
dda8d76d
NC
270 struct group_list * root;
271 unsigned int group_index;
e4b17d5c
L
272};
273
978c4450
AM
274typedef struct filedata
275{
276 const char * file_name;
015dc7e1 277 bool is_separate;
978c4450 278 FILE * handle;
be7d229a 279 uint64_t file_size;
978c4450 280 Elf_Internal_Ehdr file_header;
26c527e6
AM
281 uint64_t archive_file_offset;
282 uint64_t archive_file_size;
066f8fbe 283 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
284 Elf_Internal_Shdr * section_headers;
285 Elf_Internal_Phdr * program_headers;
286 char * string_table;
26c527e6
AM
287 uint64_t string_table_length;
288 uint64_t dynamic_addr;
be7d229a 289 uint64_t dynamic_size;
26c527e6 290 uint64_t dynamic_nent;
978c4450 291 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 292 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 293 char * dynamic_strings;
26c527e6 294 uint64_t dynamic_strings_length;
8ac10c5b 295 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 296 uint64_t num_dynamic_syms;
978c4450 297 Elf_Internal_Sym * dynamic_symbols;
26c527e6 298 uint64_t version_info[16];
978c4450
AM
299 unsigned int dynamic_syminfo_nent;
300 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 301 uint64_t dynamic_syminfo_offset;
be7d229a
AM
302 uint64_t nbuckets;
303 uint64_t nchains;
625d49fc
AM
304 uint64_t * buckets;
305 uint64_t * chains;
be7d229a
AM
306 uint64_t ngnubuckets;
307 uint64_t ngnuchains;
625d49fc
AM
308 uint64_t * gnubuckets;
309 uint64_t * gnuchains;
310 uint64_t * mipsxlat;
311 uint64_t gnusymidx;
13acb58d 312 char * program_interpreter;
bc227f4c 313 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
314 uint64_t dynamic_info_DT_GNU_HASH;
315 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
316 elf_section_list * symtab_shndx_list;
317 size_t group_count;
318 struct group * section_groups;
319 struct group ** section_headers_groups;
320 /* A dynamic array of flags indicating for which sections a dump of
321 some kind has been requested. It is reset on a per-object file
322 basis and then initialised from the cmdline_dump_sects array,
323 the results of interpreting the -w switch, and the
324 dump_sects_byname list. */
325 struct dump_data dump;
326} Filedata;
aef1f6d0 327
c256ffe7 328/* How to print a vma value. */
843dd992
NC
329typedef enum print_mode
330{
331 HEX,
047c3dbf 332 HEX_5,
843dd992
NC
333 DEC,
334 DEC_5,
335 UNSIGNED,
047c3dbf 336 UNSIGNED_5,
843dd992 337 PREFIX_HEX,
047c3dbf 338 PREFIX_HEX_5,
843dd992 339 FULL_HEX,
047c3dbf 340 LONG_HEX,
fcf8f323 341 ZERO_HEX,
047c3dbf
NL
342 OCTAL,
343 OCTAL_5
843dd992
NC
344}
345print_mode;
346
b3aa80b4
NC
347typedef enum unicode_display_type
348{
349 unicode_default = 0,
350 unicode_locale,
351 unicode_escape,
352 unicode_hex,
353 unicode_highlight,
354 unicode_invalid
355} unicode_display_type;
356
357static unicode_display_type unicode_display = unicode_default;
358
a7fd1186
FS
359typedef enum
360{
361 reltype_unknown,
362 reltype_rel,
363 reltype_rela,
364 reltype_relr
365} relocation_type;
366
bb4d2ac2
L
367/* Versioned symbol info. */
368enum versioned_symbol_info
369{
370 symbol_undefined,
371 symbol_hidden,
372 symbol_public
373};
374
63cf857e
AM
375static int
376fseek64 (FILE *stream, int64_t offset, int whence)
377{
378#if defined (HAVE_FSEEKO64)
379 off64_t o = offset;
380 if (o != offset)
381 {
382 errno = EINVAL;
383 return -1;
384 }
385 return fseeko64 (stream, o, whence);
386#elif defined (HAVE_FSEEKO)
387 off_t o = offset;
388 if (o != offset)
389 {
390 errno = EINVAL;
391 return -1;
392 }
393 return fseeko (stream, o, whence);
394#else
395 long o = offset;
396 if (o != offset)
397 {
398 errno = EINVAL;
399 return -1;
400 }
401 return fseek (stream, o, whence);
402#endif
403}
404
32ec8896 405static const char * get_symbol_version_string
26c527e6 406 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 407 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 408
8e8d0b63
NC
409static bool process_notes_at
410 (Filedata *, Elf_Internal_Shdr *, uint64_t, uint64_t, uint64_t);
411
9c19a809
NC
412#define UNKNOWN -1
413
84714f86
AM
414static inline const char *
415section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
416{
417 return filedata->string_table + hdr->sh_name;
418}
b9e920ec 419
84714f86
AM
420static inline bool
421section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
422{
b6ac461a
NC
423 return (filedata != NULL
424 && hdr != NULL
84714f86
AM
425 && filedata->string_table != NULL
426 && hdr->sh_name < filedata->string_table_length);
427}
b9e920ec 428
b6ac461a
NC
429/* Returns true if the given index is real/valid. Note: "real" here
430 means "references a real section in the section header" and not
431 "is a valid section index as per the ELF standard". */
432
433static inline bool
434section_index_real (const Filedata *filedata, unsigned int ndx)
84714f86 435{
b6ac461a
NC
436 return (filedata != NULL
437 && filedata->section_headers != NULL
438 && ndx < filedata->file_header.e_shnum
439 && ndx > 0);
84714f86 440}
b6ac461a 441
ee42cf8c 442#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 443
84714f86
AM
444static inline bool
445valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
446{
447 return strtab != NULL && offset < strtab_size;
448}
449
450static inline bool
451valid_dynamic_name (const Filedata *filedata, uint64_t offset)
452{
453 return valid_symbol_name (filedata->dynamic_strings,
454 filedata->dynamic_strings_length, offset);
455}
456
d79b3d50
NC
457/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
458 already been called and verified that the string exists. */
84714f86
AM
459static inline const char *
460get_dynamic_name (const Filedata *filedata, size_t offset)
461{
462 return filedata->dynamic_strings + offset;
463}
18bd398b 464
61865e30
NC
465#define REMOVE_ARCH_BITS(ADDR) \
466 do \
467 { \
dda8d76d 468 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
469 (ADDR) &= ~1; \
470 } \
471 while (0)
f16a9783
MS
472
473/* Get the correct GNU hash section name. */
978c4450
AM
474#define GNU_HASH_SECTION_NAME(filedata) \
475 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 476\f
dda8d76d
NC
477/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
478 OFFSET + the offset of the current archive member, if we are examining an
479 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
480 allocate a buffer using malloc and fill that. In either case return the
481 pointer to the start of the retrieved data or NULL if something went wrong.
482 If something does go wrong and REASON is not NULL then emit an error
483 message using REASON as part of the context. */
59245841 484
c256ffe7 485static void *
be7d229a
AM
486get_data (void *var,
487 Filedata *filedata,
26c527e6 488 uint64_t offset,
be7d229a
AM
489 uint64_t size,
490 uint64_t nmemb,
491 const char *reason)
a6e9f9df 492{
2cf0635d 493 void * mvar;
be7d229a 494 uint64_t amt = size * nmemb;
a6e9f9df 495
c256ffe7 496 if (size == 0 || nmemb == 0)
a6e9f9df
AM
497 return NULL;
498
be7d229a
AM
499 /* If size_t is smaller than uint64_t, eg because you are building
500 on a 32-bit host, then make sure that when the sizes are cast to
501 size_t no information is lost. */
7c1c1904
AM
502 if ((size_t) size != size
503 || (size_t) nmemb != nmemb
be7d229a
AM
504 || (size_t) amt != amt
505 || amt / size != nmemb
506 || (size_t) amt + 1 == 0)
57028622
NC
507 {
508 if (reason)
b8281767
AM
509 error (_("Size overflow prevents reading %" PRIu64
510 " elements of size %" PRIu64 " for %s\n"),
be7d229a 511 nmemb, size, reason);
57028622
NC
512 return NULL;
513 }
514
c22b42ce 515 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 516 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
517 if (filedata->archive_file_offset > filedata->file_size
518 || offset > filedata->file_size - filedata->archive_file_offset
519 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 520 {
049b0c3a 521 if (reason)
b8281767 522 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 523 amt, reason);
a6e9f9df
AM
524 return NULL;
525 }
526
63cf857e
AM
527 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
528 SEEK_SET))
071436c6
NC
529 {
530 if (reason)
26c527e6 531 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 532 filedata->archive_file_offset + offset, reason);
071436c6
NC
533 return NULL;
534 }
535
a6e9f9df
AM
536 mvar = var;
537 if (mvar == NULL)
538 {
7c1c1904
AM
539 /* + 1 so that we can '\0' terminate invalid string table sections. */
540 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
541
542 if (mvar == NULL)
543 {
049b0c3a 544 if (reason)
b8281767 545 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 546 amt, reason);
a6e9f9df
AM
547 return NULL;
548 }
c256ffe7 549
c9c1d674 550 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
551 }
552
dda8d76d 553 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 554 {
049b0c3a 555 if (reason)
b8281767 556 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 557 amt, reason);
a6e9f9df
AM
558 if (mvar != var)
559 free (mvar);
560 return NULL;
561 }
562
563 return mvar;
564}
565
32ec8896
NC
566/* Print a VMA value in the MODE specified.
567 Returns the number of characters displayed. */
cb8f3167 568
32ec8896 569static unsigned int
625d49fc 570print_vma (uint64_t vma, print_mode mode)
66543521 571{
32ec8896 572 unsigned int nc = 0;
66543521 573
14a91970 574 switch (mode)
66543521 575 {
14a91970
AM
576 case FULL_HEX:
577 nc = printf ("0x");
1a0670f3 578 /* Fall through. */
14a91970 579 case LONG_HEX:
f493c217 580 if (!is_32bit_elf)
625d49fc
AM
581 return nc + printf ("%16.16" PRIx64, vma);
582 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 583
fcf8f323
NC
584 case ZERO_HEX:
585 if (is_32bit_elf)
586 return printf ("%08" PRIx64, vma);
587 return printf ("%016" PRIx64, vma);
588
14a91970
AM
589 case DEC_5:
590 if (vma <= 99999)
625d49fc 591 return printf ("%5" PRId64, vma);
1a0670f3 592 /* Fall through. */
14a91970
AM
593 case PREFIX_HEX:
594 nc = printf ("0x");
1a0670f3 595 /* Fall through. */
14a91970 596 case HEX:
625d49fc 597 return nc + printf ("%" PRIx64, vma);
b19aac67 598
047c3dbf
NL
599 case PREFIX_HEX_5:
600 nc = printf ("0x");
601 /* Fall through. */
602 case HEX_5:
625d49fc 603 return nc + printf ("%05" PRIx64, vma);
047c3dbf 604
14a91970 605 case DEC:
625d49fc 606 return printf ("%" PRId64, vma);
b19aac67 607
14a91970 608 case UNSIGNED:
625d49fc 609 return printf ("%" PRIu64, vma);
32ec8896 610
047c3dbf 611 case UNSIGNED_5:
625d49fc 612 return printf ("%5" PRIu64, vma);
047c3dbf
NL
613
614 case OCTAL:
625d49fc 615 return printf ("%" PRIo64, vma);
047c3dbf
NL
616
617 case OCTAL_5:
625d49fc 618 return printf ("%5" PRIo64, vma);
047c3dbf 619
32ec8896
NC
620 default:
621 /* FIXME: Report unrecognised mode ? */
622 return 0;
f7a99963 623 }
f7a99963
NC
624}
625
047c3dbf 626
7bfd842d 627/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 628 multibye characters (assuming the host environment supports them).
31104126 629
b6ac461a
NC
630 Display at most abs(WIDTH) characters, truncating as necessary,
631 unless do_wide or extra_sym_info is true.
7bfd842d 632
0942c7ab
NC
633 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
634 abs(WIDTH) - 5 characters followed by "[...]".
635
7bfd842d
NC
636 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
637 padding as necessary.
171191ba
NC
638
639 Returns the number of emitted characters. */
640
641static unsigned int
b6ac461a 642print_symbol_name (signed int width, const char * symbol)
31104126 643{
015dc7e1
AM
644 bool extra_padding = false;
645 bool do_dots = false;
32ec8896 646 signed int num_printed = 0;
3bfcb652 647#ifdef HAVE_MBSTATE_T
7bfd842d 648 mbstate_t state;
3bfcb652 649#endif
32ec8896 650 unsigned int width_remaining;
79bc120c 651 const void * alloced_symbol = NULL;
961c521f 652
7bfd842d 653 if (width < 0)
961c521f 654 {
88305e1b 655 /* Keep the width positive. This helps the code below. */
961c521f 656 width = - width;
015dc7e1 657 extra_padding = true;
0b4362b0 658 }
56d8f8a9
NC
659 else if (width == 0)
660 return 0;
961c521f 661
b6ac461a 662 if (do_wide || extra_sym_info)
7bfd842d
NC
663 /* Set the remaining width to a very large value.
664 This simplifies the code below. */
665 width_remaining = INT_MAX;
666 else
0942c7ab
NC
667 {
668 width_remaining = width;
b6ac461a 669
0942c7ab
NC
670 if (! do_not_show_symbol_truncation
671 && (int) strlen (symbol) > width)
672 {
673 width_remaining -= 5;
674 if ((int) width_remaining < 0)
675 width_remaining = 0;
015dc7e1 676 do_dots = true;
0942c7ab
NC
677 }
678 }
cb8f3167 679
3bfcb652 680#ifdef HAVE_MBSTATE_T
7bfd842d
NC
681 /* Initialise the multibyte conversion state. */
682 memset (& state, 0, sizeof (state));
3bfcb652 683#endif
961c521f 684
79bc120c
NC
685 if (do_demangle && *symbol)
686 {
687 const char * res = cplus_demangle (symbol, demangle_flags);
688
689 if (res != NULL)
690 alloced_symbol = symbol = res;
691 }
692
7bfd842d
NC
693 while (width_remaining)
694 {
695 size_t n;
7bfd842d 696 const char c = *symbol++;
961c521f 697
7bfd842d 698 if (c == 0)
961c521f
NC
699 break;
700
b3aa80b4
NC
701 if (ISPRINT (c))
702 {
703 putchar (c);
704 width_remaining --;
705 num_printed ++;
706 }
707 else if (ISCNTRL (c))
961c521f 708 {
b3aa80b4
NC
709 /* Do not print control characters directly as they can affect terminal
710 settings. Such characters usually appear in the names generated
711 by the assembler for local labels. */
712
7bfd842d 713 if (width_remaining < 2)
961c521f
NC
714 break;
715
7bfd842d
NC
716 printf ("^%c", c + 0x40);
717 width_remaining -= 2;
171191ba 718 num_printed += 2;
961c521f 719 }
b3aa80b4 720 else if (c == 0x7f)
7bfd842d 721 {
b3aa80b4
NC
722 if (width_remaining < 5)
723 break;
724 printf ("<DEL>");
725 width_remaining -= 5;
726 num_printed += 5;
727 }
728 else if (unicode_display != unicode_locale
729 && unicode_display != unicode_default)
730 {
731 /* Display unicode characters as something else. */
732 unsigned char bytes[4];
733 bool is_utf8;
795588ae 734 unsigned int nbytes;
b3aa80b4
NC
735
736 bytes[0] = c;
737
738 if (bytes[0] < 0xc0)
739 {
740 nbytes = 1;
741 is_utf8 = false;
742 }
743 else
744 {
745 bytes[1] = *symbol++;
746
747 if ((bytes[1] & 0xc0) != 0x80)
748 {
749 is_utf8 = false;
750 /* Do not consume this character. It may only
751 be the first byte in the sequence that was
752 corrupt. */
753 --symbol;
754 nbytes = 1;
755 }
756 else if ((bytes[0] & 0x20) == 0)
757 {
758 is_utf8 = true;
759 nbytes = 2;
760 }
761 else
762 {
763 bytes[2] = *symbol++;
764
765 if ((bytes[2] & 0xc0) != 0x80)
766 {
767 is_utf8 = false;
768 symbol -= 2;
769 nbytes = 1;
770 }
771 else if ((bytes[0] & 0x10) == 0)
772 {
773 is_utf8 = true;
774 nbytes = 3;
775 }
776 else
777 {
778 bytes[3] = *symbol++;
779
780 nbytes = 4;
781
782 if ((bytes[3] & 0xc0) != 0x80)
783 {
784 is_utf8 = false;
785 symbol -= 3;
786 nbytes = 1;
787 }
788 else
789 is_utf8 = true;
790 }
791 }
792 }
793
794 if (unicode_display == unicode_invalid)
795 is_utf8 = false;
796
797 if (unicode_display == unicode_hex || ! is_utf8)
798 {
795588ae 799 unsigned int i;
b3aa80b4
NC
800
801 if (width_remaining < (nbytes * 2) + 2)
802 break;
803
804 putchar (is_utf8 ? '<' : '{');
805 printf ("0x");
806 for (i = 0; i < nbytes; i++)
807 printf ("%02x", bytes[i]);
808 putchar (is_utf8 ? '>' : '}');
809 }
810 else
811 {
812 if (unicode_display == unicode_highlight && isatty (1))
813 printf ("\x1B[31;47m"); /* Red. */
814
815 switch (nbytes)
816 {
817 case 2:
818 if (width_remaining < 6)
819 break;
820 printf ("\\u%02x%02x",
821 (bytes[0] & 0x1c) >> 2,
822 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
823 break;
824 case 3:
825 if (width_remaining < 6)
826 break;
827 printf ("\\u%02x%02x",
828 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
829 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
830 break;
831 case 4:
832 if (width_remaining < 8)
833 break;
834 printf ("\\u%02x%02x%02x",
835 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
836 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
837 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
838
839 break;
840 default:
841 /* URG. */
842 break;
843 }
844
845 if (unicode_display == unicode_highlight && isatty (1))
846 printf ("\033[0m"); /* Default colour. */
847 }
848
849 if (bytes[nbytes - 1] == 0)
850 break;
7bfd842d 851 }
961c521f
NC
852 else
853 {
3bfcb652
NC
854#ifdef HAVE_MBSTATE_T
855 wchar_t w;
856#endif
7bfd842d
NC
857 /* Let printf do the hard work of displaying multibyte characters. */
858 printf ("%.1s", symbol - 1);
859 width_remaining --;
860 num_printed ++;
861
3bfcb652 862#ifdef HAVE_MBSTATE_T
7bfd842d
NC
863 /* Try to find out how many bytes made up the character that was
864 just printed. Advance the symbol pointer past the bytes that
865 were displayed. */
866 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
867#else
868 n = 1;
869#endif
7bfd842d
NC
870 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
871 symbol += (n - 1);
961c521f 872 }
961c521f 873 }
171191ba 874
0942c7ab
NC
875 if (do_dots)
876 num_printed += printf ("[...]");
877
7bfd842d 878 if (extra_padding && num_printed < width)
171191ba
NC
879 {
880 /* Fill in the remaining spaces. */
7bfd842d
NC
881 printf ("%-*s", width - num_printed, " ");
882 num_printed = width;
171191ba
NC
883 }
884
79bc120c 885 free ((void *) alloced_symbol);
171191ba 886 return num_printed;
31104126
NC
887}
888
1449284b 889/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
890 the given section's name. Like print_symbol, except that it does not try
891 to print multibyte characters, it just interprets them as hex values. */
892
893static const char *
dda8d76d 894printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 895{
b6ac461a
NC
896#define NUM_SEC_NAME_BUFS 5
897#define MAX_PRINT_SEC_NAME_LEN 256
898
899 static int sec_name_buf_index = 0;
900 /* We use a rotating array of static buffers, so that multiple successive calls
901 to printable_section_name() will still work. eg when used in a printf. */
902 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
903
904 const char * name;
905 char * buf;
906 char * buf_start;
74e1a04b
NC
907 char c;
908 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
909
b6ac461a
NC
910 /* Validate the input parameters. */
911 if (filedata == NULL)
912 return _("<internal error>");
913 if (sec == NULL)
914 return _("<none>");
915 if (filedata->string_table == NULL)
916 return _("<no-strings>");
917 if (sec->sh_name >= filedata->string_table_length)
918 return _("<corrupt>");
919
920 /* Select a buffer to use. */
921 buf_start = buf = sec_name_buf[sec_name_buf_index];
922 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
923 sec_name_buf_index = 0;
924
925 name = section_name (filedata, sec);
926
74e1a04b
NC
927 while ((c = * name ++) != 0)
928 {
929 if (ISCNTRL (c))
930 {
931 if (remaining < 2)
932 break;
948f632f 933
74e1a04b
NC
934 * buf ++ = '^';
935 * buf ++ = c + 0x40;
936 remaining -= 2;
937 }
938 else if (ISPRINT (c))
939 {
940 * buf ++ = c;
941 remaining -= 1;
942 }
943 else
944 {
945 static char hex[17] = "0123456789ABCDEF";
946
947 if (remaining < 4)
948 break;
949 * buf ++ = '<';
950 * buf ++ = hex[(c & 0xf0) >> 4];
951 * buf ++ = hex[c & 0x0f];
952 * buf ++ = '>';
953 remaining -= 4;
954 }
955
956 if (remaining == 0)
957 break;
958 }
959
960 * buf = 0;
b6ac461a
NC
961 return buf_start;
962}
963
964/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
965 This OS has so many departures from the ELF standard that we test it at
966 many places. */
967
968static inline bool
969is_ia64_vms (Filedata * filedata)
970{
971 return filedata->file_header.e_machine == EM_IA_64
972 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
74e1a04b
NC
973}
974
975static const char *
b6ac461a
NC
976printable_section_name_from_index (Filedata * filedata,
977 size_t ndx,
978 bool * is_special)
74e1a04b 979{
b6ac461a
NC
980 if (is_special != NULL)
981 * is_special = true;
982
983 switch (ndx)
984 {
985 case SHN_UNDEF: return "UND";
986 case SHN_ABS: return "ABS";
987 case SHN_COMMON: return "COM";
988 break;
989 }
990
991 if (filedata != NULL)
992 {
993 switch (filedata->file_header.e_machine)
994 {
995 case EM_MIPS:
996 if (ndx == SHN_MIPS_SCOMMON)
997 return "SCOMMON";
998 if (ndx == SHN_MIPS_SUNDEFINED)
999 return "SUNDEF";
1000 break;
1001
1002 case EM_TI_C6000:
1003 if (ndx == SHN_TIC6X_SCOMMON)
1004 return "SCOM";
1005 break;
1006
1007 case EM_X86_64:
1008 case EM_L1OM:
1009 case EM_K1OM:
1010 if (ndx == SHN_X86_64_LCOMMON)
1011 return "LARGE_COM";
1012 break;
1013
1014 case EM_IA_64:
1015 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1016 && ndx == SHN_IA_64_ANSI_COMMON)
1017 return "ANSI_COM";
1018
1019 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1020 return "VMS_SYMVEC";
1021 break;
1022
1023 default:
1024 break;
1025 }
74e1a04b 1026
b6ac461a
NC
1027 if (filedata->section_headers != NULL
1028 && ndx < filedata->file_header.e_shnum)
1029 {
1030 const char * res;
1031
1032 res = printable_section_name (filedata, filedata->section_headers + ndx);
1033 if (is_special != NULL)
1034 * is_special = (res[0] == '<');
1035
1036 return res;
1037 }
1038 }
1039
1040 static char name_buf[40];
1041 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1042
1043 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1044 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1045 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1046 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1047 else if (ndx >= SHN_LORESERVE)
1048 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1049 else if (filedata->file_header.e_shnum != 0
1050 && ndx >= filedata->file_header.e_shnum)
1051 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1052 else
1053 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1054
1055 return name_buf;
74e1a04b
NC
1056}
1057
89fac5e3
RS
1058/* Return a pointer to section NAME, or NULL if no such section exists. */
1059
1060static Elf_Internal_Shdr *
dda8d76d 1061find_section (Filedata * filedata, const char * name)
89fac5e3
RS
1062{
1063 unsigned int i;
1064
68807c3c
NC
1065 if (filedata->section_headers == NULL)
1066 return NULL;
dda8d76d
NC
1067
1068 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
1069 if (section_name_valid (filedata, filedata->section_headers + i)
1070 && streq (section_name (filedata, filedata->section_headers + i),
1071 name))
dda8d76d 1072 return filedata->section_headers + i;
89fac5e3
RS
1073
1074 return NULL;
1075}
1076
0b6ae522
DJ
1077/* Return a pointer to a section containing ADDR, or NULL if no such
1078 section exists. */
1079
1080static Elf_Internal_Shdr *
625d49fc 1081find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
1082{
1083 unsigned int i;
1084
68807c3c
NC
1085 if (filedata->section_headers == NULL)
1086 return NULL;
1087
dda8d76d 1088 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 1089 {
dda8d76d
NC
1090 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1091
0b6ae522
DJ
1092 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1093 return sec;
1094 }
1095
1096 return NULL;
1097}
1098
071436c6 1099static Elf_Internal_Shdr *
dda8d76d 1100find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
1101{
1102 unsigned int i;
1103
68807c3c
NC
1104 if (filedata->section_headers == NULL)
1105 return NULL;
1106
dda8d76d 1107 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 1108 {
dda8d76d
NC
1109 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1110
071436c6
NC
1111 if (sec->sh_type == type)
1112 return sec;
1113 }
1114
1115 return NULL;
1116}
1117
fcf8f323
NC
1118static Elf_Internal_Shdr *
1119find_section_by_name (Filedata * filedata, const char * name)
1120{
1121 unsigned int i;
1122
1123 if (filedata->section_headers == NULL || filedata->string_table_length == 0)
1124 return NULL;
1125
1126 for (i = 0; i < filedata->file_header.e_shnum; i++)
1127 {
1128 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1129
1130 if (sec->sh_name < filedata->string_table_length
1131 && streq (name, filedata->string_table + sec->sh_name))
1132 return sec;
1133 }
1134
1135 return NULL;
1136}
1137
657d0d47
CC
1138/* Return a pointer to section NAME, or NULL if no such section exists,
1139 restricted to the list of sections given in SET. */
1140
1141static Elf_Internal_Shdr *
dda8d76d 1142find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
1143{
1144 unsigned int i;
1145
68807c3c
NC
1146 if (filedata->section_headers == NULL)
1147 return NULL;
1148
657d0d47
CC
1149 if (set != NULL)
1150 {
1151 while ((i = *set++) > 0)
b814a36d
NC
1152 {
1153 /* See PR 21156 for a reproducer. */
dda8d76d 1154 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1155 continue; /* FIXME: Should we issue an error message ? */
1156
84714f86
AM
1157 if (section_name_valid (filedata, filedata->section_headers + i)
1158 && streq (section_name (filedata, filedata->section_headers + i),
1159 name))
dda8d76d 1160 return filedata->section_headers + i;
b814a36d 1161 }
657d0d47
CC
1162 }
1163
dda8d76d 1164 return find_section (filedata, name);
657d0d47
CC
1165}
1166
bcedfee6 1167/* Guess the relocation size commonly used by the specific machines. */
252b5132 1168
015dc7e1 1169static bool
2dc4cec1 1170guess_is_rela (unsigned int e_machine)
252b5132 1171{
9c19a809 1172 switch (e_machine)
252b5132
RH
1173 {
1174 /* Targets that use REL relocations. */
252b5132 1175 case EM_386:
22abe556 1176 case EM_IAMCU:
f954747f 1177 case EM_960:
e9f53129 1178 case EM_ARM:
2b0337b0 1179 case EM_D10V:
252b5132 1180 case EM_CYGNUS_D10V:
e9f53129 1181 case EM_DLX:
252b5132 1182 case EM_MIPS:
4fe85591 1183 case EM_MIPS_RS3_LE:
e9f53129 1184 case EM_CYGNUS_M32R:
1c0d3aa6 1185 case EM_SCORE:
f6c1a2d5 1186 case EM_XGATE:
fe944acf 1187 case EM_NFP:
aca4efc7 1188 case EM_BPF:
015dc7e1 1189 return false;
103f02d3 1190
252b5132
RH
1191 /* Targets that use RELA relocations. */
1192 case EM_68K:
f954747f 1193 case EM_860:
a06ea964 1194 case EM_AARCH64:
cfb8c092 1195 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1196 case EM_ALPHA:
1197 case EM_ALTERA_NIOS2:
886a2506
NC
1198 case EM_ARC:
1199 case EM_ARC_COMPACT:
1200 case EM_ARC_COMPACT2:
b5c37946
SJ
1201 case EM_ARC_COMPACT3:
1202 case EM_ARC_COMPACT3_64:
e9f53129
AM
1203 case EM_AVR:
1204 case EM_AVR_OLD:
1205 case EM_BLACKFIN:
60bca95a 1206 case EM_CR16:
e9f53129
AM
1207 case EM_CRIS:
1208 case EM_CRX:
b8891f8d 1209 case EM_CSKY:
2b0337b0 1210 case EM_D30V:
252b5132 1211 case EM_CYGNUS_D30V:
2b0337b0 1212 case EM_FR30:
3f8107ab 1213 case EM_FT32:
252b5132 1214 case EM_CYGNUS_FR30:
5c70f934 1215 case EM_CYGNUS_FRV:
e9f53129
AM
1216 case EM_H8S:
1217 case EM_H8_300:
1218 case EM_H8_300H:
800eeca4 1219 case EM_IA_64:
1e4cf259
NC
1220 case EM_IP2K:
1221 case EM_IP2K_OLD:
3b36097d 1222 case EM_IQ2000:
6e712424 1223 case EM_KVX:
84e94c90 1224 case EM_LATTICEMICO32:
ff7eeb89 1225 case EM_M32C_OLD:
49f58d10 1226 case EM_M32C:
e9f53129
AM
1227 case EM_M32R:
1228 case EM_MCORE:
15ab5209 1229 case EM_CYGNUS_MEP:
a3c62988 1230 case EM_METAG:
e9f53129
AM
1231 case EM_MMIX:
1232 case EM_MN10200:
1233 case EM_CYGNUS_MN10200:
1234 case EM_MN10300:
1235 case EM_CYGNUS_MN10300:
5506d11a 1236 case EM_MOXIE:
e9f53129
AM
1237 case EM_MSP430:
1238 case EM_MSP430_OLD:
d031aafb 1239 case EM_MT:
35c08157 1240 case EM_NDS32:
64fd6348 1241 case EM_NIOS32:
73589c9d 1242 case EM_OR1K:
e9f53129
AM
1243 case EM_PPC64:
1244 case EM_PPC:
2b100bb5 1245 case EM_TI_PRU:
e23eba97 1246 case EM_RISCV:
99c513f6 1247 case EM_RL78:
c7927a3c 1248 case EM_RX:
e9f53129
AM
1249 case EM_S390:
1250 case EM_S390_OLD:
1251 case EM_SH:
1252 case EM_SPARC:
1253 case EM_SPARC32PLUS:
1254 case EM_SPARCV9:
1255 case EM_SPU:
40b36596 1256 case EM_TI_C6000:
aa137e4d
NC
1257 case EM_TILEGX:
1258 case EM_TILEPRO:
708e2187 1259 case EM_V800:
e9f53129
AM
1260 case EM_V850:
1261 case EM_CYGNUS_V850:
1262 case EM_VAX:
619ed720 1263 case EM_VISIUM:
e9f53129 1264 case EM_X86_64:
8a9036a4 1265 case EM_L1OM:
7a9068fe 1266 case EM_K1OM:
e9f53129
AM
1267 case EM_XSTORMY16:
1268 case EM_XTENSA:
1269 case EM_XTENSA_OLD:
7ba29e2a
NC
1270 case EM_MICROBLAZE:
1271 case EM_MICROBLAZE_OLD:
f96bd6c2 1272 case EM_WEBASSEMBLY:
015dc7e1 1273 return true;
103f02d3 1274
e9f53129
AM
1275 case EM_68HC05:
1276 case EM_68HC08:
1277 case EM_68HC11:
1278 case EM_68HC16:
1279 case EM_FX66:
1280 case EM_ME16:
d1133906 1281 case EM_MMA:
d1133906
NC
1282 case EM_NCPU:
1283 case EM_NDR1:
e9f53129 1284 case EM_PCP:
d1133906 1285 case EM_ST100:
e9f53129 1286 case EM_ST19:
d1133906 1287 case EM_ST7:
e9f53129
AM
1288 case EM_ST9PLUS:
1289 case EM_STARCORE:
d1133906 1290 case EM_SVX:
e9f53129 1291 case EM_TINYJ:
9c19a809
NC
1292 default:
1293 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1294 return false;
9c19a809
NC
1295 }
1296}
252b5132 1297
dda8d76d 1298/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1299 Returns TRUE upon success, FALSE otherwise. If successful then a
1300 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1301 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1302 responsibility to free the allocated buffer. */
1303
015dc7e1 1304static bool
26c527e6
AM
1305slurp_rela_relocs (Filedata *filedata,
1306 uint64_t rel_offset,
1307 uint64_t rel_size,
1308 Elf_Internal_Rela **relasp,
1309 uint64_t *nrelasp)
9c19a809 1310{
2cf0635d 1311 Elf_Internal_Rela * relas;
26c527e6 1312 uint64_t nrelas;
4d6ed7c8 1313 unsigned int i;
252b5132 1314
4d6ed7c8
NC
1315 if (is_32bit_elf)
1316 {
2cf0635d 1317 Elf32_External_Rela * erelas;
103f02d3 1318
dda8d76d 1319 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1320 rel_size, _("32-bit relocation data"));
a6e9f9df 1321 if (!erelas)
015dc7e1 1322 return false;
252b5132 1323
4d6ed7c8 1324 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1325
3f5e193b
NC
1326 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1327 sizeof (Elf_Internal_Rela));
103f02d3 1328
4d6ed7c8
NC
1329 if (relas == NULL)
1330 {
c256ffe7 1331 free (erelas);
591a748a 1332 error (_("out of memory parsing relocs\n"));
015dc7e1 1333 return false;
4d6ed7c8 1334 }
103f02d3 1335
4d6ed7c8
NC
1336 for (i = 0; i < nrelas; i++)
1337 {
1338 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1339 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1340 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1341 }
103f02d3 1342
4d6ed7c8
NC
1343 free (erelas);
1344 }
1345 else
1346 {
2cf0635d 1347 Elf64_External_Rela * erelas;
103f02d3 1348
dda8d76d 1349 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1350 rel_size, _("64-bit relocation data"));
a6e9f9df 1351 if (!erelas)
015dc7e1 1352 return false;
4d6ed7c8
NC
1353
1354 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1355
3f5e193b
NC
1356 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1357 sizeof (Elf_Internal_Rela));
103f02d3 1358
4d6ed7c8
NC
1359 if (relas == NULL)
1360 {
c256ffe7 1361 free (erelas);
591a748a 1362 error (_("out of memory parsing relocs\n"));
015dc7e1 1363 return false;
9c19a809 1364 }
4d6ed7c8
NC
1365
1366 for (i = 0; i < nrelas; i++)
9c19a809 1367 {
66543521
AM
1368 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1369 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1370 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1371
dda8d76d
NC
1372 if (filedata->file_header.e_machine == EM_MIPS
1373 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1374 {
1375 /* In little-endian objects, r_info isn't really a
1376 64-bit little-endian value: it has a 32-bit
1377 little-endian symbol index followed by four
1378 individual byte fields. Reorder INFO
1379 accordingly. */
625d49fc 1380 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1381 inf = (((inf & 0xffffffff) << 32)
1382 | ((inf >> 56) & 0xff)
1383 | ((inf >> 40) & 0xff00)
1384 | ((inf >> 24) & 0xff0000)
1385 | ((inf >> 8) & 0xff000000));
1386 relas[i].r_info = inf;
861fb55a 1387 }
4d6ed7c8 1388 }
103f02d3 1389
4d6ed7c8
NC
1390 free (erelas);
1391 }
32ec8896 1392
4d6ed7c8
NC
1393 *relasp = relas;
1394 *nrelasp = nrelas;
015dc7e1 1395 return true;
4d6ed7c8 1396}
103f02d3 1397
dda8d76d 1398/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1399 Returns TRUE upon success, FALSE otherwise. If successful then a
1400 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1401 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1402 responsibility to free the allocated buffer. */
1403
015dc7e1 1404static bool
26c527e6
AM
1405slurp_rel_relocs (Filedata *filedata,
1406 uint64_t rel_offset,
1407 uint64_t rel_size,
1408 Elf_Internal_Rela **relsp,
1409 uint64_t *nrelsp)
4d6ed7c8 1410{
2cf0635d 1411 Elf_Internal_Rela * rels;
26c527e6 1412 uint64_t nrels;
4d6ed7c8 1413 unsigned int i;
103f02d3 1414
4d6ed7c8
NC
1415 if (is_32bit_elf)
1416 {
2cf0635d 1417 Elf32_External_Rel * erels;
103f02d3 1418
dda8d76d 1419 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1420 rel_size, _("32-bit relocation data"));
a6e9f9df 1421 if (!erels)
015dc7e1 1422 return false;
103f02d3 1423
4d6ed7c8 1424 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1425
3f5e193b 1426 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1427
4d6ed7c8
NC
1428 if (rels == NULL)
1429 {
c256ffe7 1430 free (erels);
591a748a 1431 error (_("out of memory parsing relocs\n"));
015dc7e1 1432 return false;
4d6ed7c8
NC
1433 }
1434
1435 for (i = 0; i < nrels; i++)
1436 {
1437 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1438 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1439 rels[i].r_addend = 0;
9ea033b2 1440 }
4d6ed7c8
NC
1441
1442 free (erels);
9c19a809
NC
1443 }
1444 else
1445 {
2cf0635d 1446 Elf64_External_Rel * erels;
9ea033b2 1447
dda8d76d 1448 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1449 rel_size, _("64-bit relocation data"));
a6e9f9df 1450 if (!erels)
015dc7e1 1451 return false;
103f02d3 1452
4d6ed7c8 1453 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1454
3f5e193b 1455 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1456
4d6ed7c8 1457 if (rels == NULL)
9c19a809 1458 {
c256ffe7 1459 free (erels);
591a748a 1460 error (_("out of memory parsing relocs\n"));
015dc7e1 1461 return false;
4d6ed7c8 1462 }
103f02d3 1463
4d6ed7c8
NC
1464 for (i = 0; i < nrels; i++)
1465 {
66543521
AM
1466 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1467 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1468 rels[i].r_addend = 0;
861fb55a 1469
dda8d76d
NC
1470 if (filedata->file_header.e_machine == EM_MIPS
1471 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1472 {
1473 /* In little-endian objects, r_info isn't really a
1474 64-bit little-endian value: it has a 32-bit
1475 little-endian symbol index followed by four
1476 individual byte fields. Reorder INFO
1477 accordingly. */
625d49fc 1478 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1479 inf = (((inf & 0xffffffff) << 32)
1480 | ((inf >> 56) & 0xff)
1481 | ((inf >> 40) & 0xff00)
1482 | ((inf >> 24) & 0xff0000)
1483 | ((inf >> 8) & 0xff000000));
1484 rels[i].r_info = inf;
861fb55a 1485 }
4d6ed7c8 1486 }
103f02d3 1487
4d6ed7c8
NC
1488 free (erels);
1489 }
32ec8896 1490
4d6ed7c8
NC
1491 *relsp = rels;
1492 *nrelsp = nrels;
015dc7e1 1493 return true;
4d6ed7c8 1494}
103f02d3 1495
aca88567
NC
1496/* Returns the reloc type extracted from the reloc info field. */
1497
1498static unsigned int
625d49fc 1499get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1500{
1501 if (is_32bit_elf)
1502 return ELF32_R_TYPE (reloc_info);
1503
dda8d76d 1504 switch (filedata->file_header.e_machine)
aca88567
NC
1505 {
1506 case EM_MIPS:
1507 /* Note: We assume that reloc_info has already been adjusted for us. */
1508 return ELF64_MIPS_R_TYPE (reloc_info);
1509
1510 case EM_SPARCV9:
1511 return ELF64_R_TYPE_ID (reloc_info);
1512
1513 default:
1514 return ELF64_R_TYPE (reloc_info);
1515 }
1516}
1517
1518/* Return the symbol index extracted from the reloc info field. */
1519
625d49fc
AM
1520static uint64_t
1521get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1522{
1523 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1524}
1525
015dc7e1 1526static inline bool
dda8d76d 1527uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1528{
1529 return
dda8d76d 1530 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1531 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1532 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1533 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1534 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1535}
1536
fcf8f323
NC
1537
1538static const char *
1539get_symbol_at (Elf_Internal_Sym * symtab,
1540 uint64_t nsyms,
1541 char * strtab,
1542 uint64_t strtablen,
1543 uint64_t where,
1544 uint64_t * offset_return)
1545{
1546 Elf_Internal_Sym * beg = symtab;
1547 Elf_Internal_Sym * end = symtab + nsyms;
1548 Elf_Internal_Sym * best = NULL;
1549 uint64_t dist = 0x100000;
1550
3b3e2090
NC
1551 /* Paranoia. */
1552 if (symtab == NULL || nsyms == 0 || strtab == NULL || strtablen == 0)
1553 return NULL;
1554
fcf8f323
NC
1555 /* FIXME: Since this function is likely to be called repeatedly with
1556 slightly increasing addresses each time, we could speed things up by
1557 caching the last returned value and starting our search from there. */
1558 while (beg < end)
1559 {
1560 Elf_Internal_Sym * sym;
1561 uint64_t value;
1562
1563 sym = beg + (end - beg) / 2;
1564
1565 value = sym->st_value;
1566
1567 if (sym->st_name != 0
1568 && where >= value
1569 && where - value < dist)
1570 {
1571 best = sym;
1572 dist = where - value;
1573 if (dist == 0)
1574 break;
1575 }
1576
1577 if (where < value)
1578 end = sym;
1579 else
1580 beg = sym + 1;
1581 }
1582
1583 if (best == NULL)
1584 return NULL;
1585
1586 if (best->st_name >= strtablen)
1587 return NULL;
1588
1589 if (offset_return != NULL)
1590 * offset_return = dist;
1591
1592 return strtab + best->st_name;
1593}
1594
1595static void
1596print_relr_addr_and_sym (Elf_Internal_Sym * symtab,
1597 uint64_t nsyms,
1598 char * strtab,
1599 uint64_t strtablen,
1600 uint64_t where)
1601{
1602 const char * symname = NULL;
1603 uint64_t offset = 0;
1604
1605 print_vma (where, ZERO_HEX);
1606 printf (" ");
1607
1608 symname = get_symbol_at (symtab, nsyms, strtab, strtablen, where, & offset);
1609
1610 if (symname == NULL)
1611 printf ("<no sym>");
1612 else if (offset == 0)
1613 print_symbol_name (38, symname);
1614 else
1615 {
1616 print_symbol_name (28, symname);
1617 printf (" + ");
1618 print_vma (offset, PREFIX_HEX);
1619 }
1620}
1621
1622static /* signed */ int
1623symcmp (const void *p, const void *q)
1624{
1625 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1626 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1627
1628 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1629}
1630
3b3e2090
NC
1631static uint64_t
1632count_relr_relocations (Filedata * filedata,
1633 Elf_Internal_Shdr * section)
1634{
1635 uint64_t * relrs;
1636 uint64_t nentries;
1637 uint64_t i;
1638 uint64_t count;
1639 int entsize;
1640
1641 if (section == NULL
1642 || section->sh_type != SHT_RELR
1643 || section->sh_size == 0)
1644 return 0;
1645
1646 entsize = section->sh_entsize;
1647 if (entsize == 0)
1648 entsize = is_32bit_elf
1649 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1650 else if (entsize != sizeof (Elf32_External_Relr)
1651 && entsize != sizeof (Elf64_External_Relr))
1652 return 0;
1653
1654 nentries = section->sh_size / entsize;
1655 if (nentries == 0)
1656 return 0;
1657
1658 /* FIXME: This call to get_data duplicates one that follows in
1659 dump_relr_relocations(). They could be combined into just
1660 one call. */
1661 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1662 section->sh_size, _("RELR relocation data"));
1663 if (relrs == NULL)
1664 return 0;
1665
1666 for (count = i = 0; i < nentries; i++)
1667 {
1668 uint64_t entry;
1669
1670 if (entsize == sizeof (Elf32_External_Relr))
1671 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1672 else
1673 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1674
1675 if ((entry & 1) == 0)
1676 {
1677 ++ count;
1678 }
1679 else
1680 {
1681 if (entry == 1)
1682 continue;
1683
1684 for (; entry >>= 1;)
1685 if ((entry & 1) == 1)
1686 ++ count;
1687 }
1688 }
1689
1690 free (relrs);
1691 return count;
1692}
1693
fcf8f323
NC
1694static bool
1695dump_relr_relocations (Filedata * filedata,
1696 Elf_Internal_Shdr * section,
1697 Elf_Internal_Sym * symtab,
1698 uint64_t nsyms,
1699 char * strtab,
1700 uint64_t strtablen)
1701{
1702 uint64_t * relrs;
1703 uint64_t nentries, i;
1704 uint64_t relr_size = section->sh_size;
1705 int relr_entsize = section->sh_entsize;
1706 uint64_t relr_offset = section->sh_offset;
1707 uint64_t where = 0;
1708 int num_bits_in_entry;
1709
fcf8f323 1710 if (relr_entsize == 0)
3b3e2090
NC
1711 relr_entsize = is_32bit_elf
1712 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
fcf8f323
NC
1713
1714 nentries = relr_size / relr_entsize;
1715
3b3e2090
NC
1716 if (nentries == 0)
1717 return true;
1718
fcf8f323
NC
1719 if (relr_entsize == sizeof (Elf32_External_Relr))
1720 num_bits_in_entry = 31;
1721 else if (relr_entsize == sizeof (Elf64_External_Relr))
1722 num_bits_in_entry = 63;
1723 else
1724 {
1725 warn (_("Unexpected entsize for RELR section\n"));
1726 return false;
1727 }
fcf8f323 1728
3b3e2090
NC
1729 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1730 if (relrs == NULL)
1731 return false;
1732
1733 if (symtab != NULL)
1734 {
1735 /* Symbol tables are not sorted on address, but we want a quick lookup
1736 for the symbol associated with each address computed below, so sort
1737 the table now. FIXME: This assumes that the symbol table will not
1738 be used later on for some other purpose. */
1739 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
1740 }
1741
1742 if (relr_entsize == sizeof (Elf32_External_Relr))
21061c38 1743 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323 1744 else
21061c38 1745 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323
NC
1746
1747 for (i = 0; i < nentries; i++)
1748 {
1749 uint64_t entry;
1750
3b3e2090 1751 if (relr_entsize == sizeof (Elf32_External_Relr))
fcf8f323
NC
1752 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1753 else
1754 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1755
1756 /* We assume that there will never be more than 9999 entries. */
1757 printf (_("%04u: "), (unsigned int) i);
1758 print_vma (entry, ZERO_HEX);
1759 printf (" ");
1760
1761 if ((entry & 1) == 0)
1762 {
1763 where = entry;
1764 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, where);
fcf8f323
NC
1765 printf ("\n");
1766 where += relr_entsize;
1767 }
1768 else
1769 {
1770 bool first = true;
1771 int j;
1772
1773 /* The least significant bit is ignored. */
1774 if (entry == 1)
3b3e2090
NC
1775 /* This can actually happen when the linker is allowed to shrink
1776 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1777 continue;
fcf8f323
NC
1778 else if (i == 0)
1779 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1780
1781 for (j = 0; entry >>= 1; j++)
1782 if ((entry & 1) == 1)
1783 {
1784 uint64_t addr = where + (j * relr_entsize);
1785
1786 if (first)
1787 {
1788 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
fcf8f323
NC
1789 first = false;
1790 }
1791 else
1792 {
1793 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
1794 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
1795 }
1796 }
1797
1798 printf ("\n");
1799 where += num_bits_in_entry * relr_entsize;
1800 }
1801 }
1802
1803 free (relrs);
1804 return true;
1805}
1806
d3ba0551
AM
1807/* Display the contents of the relocation data found at the specified
1808 offset. */
ee42cf8c 1809
015dc7e1 1810static bool
fcf8f323
NC
1811dump_relocations (Filedata * filedata,
1812 uint64_t rel_offset,
1813 uint64_t rel_size,
1814 Elf_Internal_Sym * symtab,
1815 uint64_t nsyms,
1816 char * strtab,
1817 uint64_t strtablen,
1818 relocation_type rel_type,
1819 bool is_dynsym)
26c527e6
AM
1820{
1821 size_t i;
2cf0635d 1822 Elf_Internal_Rela * rels;
015dc7e1 1823 bool res = true;
103f02d3 1824
a7fd1186
FS
1825 if (rel_type == reltype_unknown)
1826 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1827
a7fd1186 1828 if (rel_type == reltype_rela)
4d6ed7c8 1829 {
dda8d76d 1830 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1831 return false;
4d6ed7c8 1832 }
a7fd1186 1833 else if (rel_type == reltype_rel)
4d6ed7c8 1834 {
dda8d76d 1835 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1836 return false;
252b5132 1837 }
a7fd1186
FS
1838 else if (rel_type == reltype_relr)
1839 {
fcf8f323
NC
1840 /* This should have been handled by display_relocations(). */
1841 return false;
a7fd1186 1842 }
252b5132 1843
410f7a12
L
1844 if (is_32bit_elf)
1845 {
a7fd1186 1846 if (rel_type == reltype_rela)
2c71103e
NC
1847 {
1848 if (do_wide)
1849 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1850 else
1851 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1852 }
410f7a12 1853 else
2c71103e
NC
1854 {
1855 if (do_wide)
1856 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1857 else
1858 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1859 }
410f7a12 1860 }
252b5132 1861 else
410f7a12 1862 {
a7fd1186 1863 if (rel_type == reltype_rela)
2c71103e
NC
1864 {
1865 if (do_wide)
8beeaeb7 1866 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1867 else
1868 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1869 }
410f7a12 1870 else
2c71103e
NC
1871 {
1872 if (do_wide)
8beeaeb7 1873 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1874 else
1875 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1876 }
410f7a12 1877 }
252b5132
RH
1878
1879 for (i = 0; i < rel_size; i++)
1880 {
2cf0635d 1881 const char * rtype;
625d49fc
AM
1882 uint64_t offset;
1883 uint64_t inf;
1884 uint64_t symtab_index;
1885 uint64_t type;
103f02d3 1886
b34976b6 1887 offset = rels[i].r_offset;
91d6fa6a 1888 inf = rels[i].r_info;
103f02d3 1889
dda8d76d 1890 type = get_reloc_type (filedata, inf);
91d6fa6a 1891 symtab_index = get_reloc_symindex (inf);
252b5132 1892
410f7a12
L
1893 if (is_32bit_elf)
1894 {
39dbeff8
AM
1895 printf ("%8.8lx %8.8lx ",
1896 (unsigned long) offset & 0xffffffff,
91d6fa6a 1897 (unsigned long) inf & 0xffffffff);
410f7a12
L
1898 }
1899 else
1900 {
39dbeff8 1901 printf (do_wide
b8281767
AM
1902 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1903 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1904 offset, inf);
410f7a12 1905 }
103f02d3 1906
dda8d76d 1907 switch (filedata->file_header.e_machine)
252b5132
RH
1908 {
1909 default:
1910 rtype = NULL;
1911 break;
1912
a06ea964
NC
1913 case EM_AARCH64:
1914 rtype = elf_aarch64_reloc_type (type);
1915 break;
1916
2b0337b0 1917 case EM_M32R:
252b5132 1918 case EM_CYGNUS_M32R:
9ea033b2 1919 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1920 break;
1921
1922 case EM_386:
22abe556 1923 case EM_IAMCU:
9ea033b2 1924 rtype = elf_i386_reloc_type (type);
252b5132
RH
1925 break;
1926
ba2685cc
AM
1927 case EM_68HC11:
1928 case EM_68HC12:
1929 rtype = elf_m68hc11_reloc_type (type);
1930 break;
75751cd9 1931
7b4ae824
JD
1932 case EM_S12Z:
1933 rtype = elf_s12z_reloc_type (type);
1934 break;
1935
252b5132 1936 case EM_68K:
9ea033b2 1937 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1938 break;
1939
f954747f
AM
1940 case EM_960:
1941 rtype = elf_i960_reloc_type (type);
1942 break;
1943
adde6300 1944 case EM_AVR:
2b0337b0 1945 case EM_AVR_OLD:
adde6300
AM
1946 rtype = elf_avr_reloc_type (type);
1947 break;
1948
9ea033b2
NC
1949 case EM_OLD_SPARCV9:
1950 case EM_SPARC32PLUS:
1951 case EM_SPARCV9:
252b5132 1952 case EM_SPARC:
9ea033b2 1953 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1954 break;
1955
e9f53129
AM
1956 case EM_SPU:
1957 rtype = elf_spu_reloc_type (type);
1958 break;
1959
708e2187
NC
1960 case EM_V800:
1961 rtype = v800_reloc_type (type);
1962 break;
2b0337b0 1963 case EM_V850:
252b5132 1964 case EM_CYGNUS_V850:
9ea033b2 1965 rtype = v850_reloc_type (type);
252b5132
RH
1966 break;
1967
2b0337b0 1968 case EM_D10V:
252b5132 1969 case EM_CYGNUS_D10V:
9ea033b2 1970 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1971 break;
1972
2b0337b0 1973 case EM_D30V:
252b5132 1974 case EM_CYGNUS_D30V:
9ea033b2 1975 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1976 break;
1977
d172d4ba
NC
1978 case EM_DLX:
1979 rtype = elf_dlx_reloc_type (type);
1980 break;
1981
252b5132 1982 case EM_SH:
9ea033b2 1983 rtype = elf_sh_reloc_type (type);
252b5132
RH
1984 break;
1985
2b0337b0 1986 case EM_MN10300:
252b5132 1987 case EM_CYGNUS_MN10300:
9ea033b2 1988 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1989 break;
1990
2b0337b0 1991 case EM_MN10200:
252b5132 1992 case EM_CYGNUS_MN10200:
9ea033b2 1993 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1994 break;
1995
2b0337b0 1996 case EM_FR30:
252b5132 1997 case EM_CYGNUS_FR30:
9ea033b2 1998 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1999 break;
2000
ba2685cc
AM
2001 case EM_CYGNUS_FRV:
2002 rtype = elf_frv_reloc_type (type);
2003 break;
5c70f934 2004
b8891f8d
AJ
2005 case EM_CSKY:
2006 rtype = elf_csky_reloc_type (type);
2007 break;
2008
3f8107ab
AM
2009 case EM_FT32:
2010 rtype = elf_ft32_reloc_type (type);
2011 break;
2012
252b5132 2013 case EM_MCORE:
9ea033b2 2014 rtype = elf_mcore_reloc_type (type);
252b5132
RH
2015 break;
2016
3c3bdf30
NC
2017 case EM_MMIX:
2018 rtype = elf_mmix_reloc_type (type);
2019 break;
2020
5506d11a
AM
2021 case EM_MOXIE:
2022 rtype = elf_moxie_reloc_type (type);
2023 break;
2024
2469cfa2 2025 case EM_MSP430:
dda8d76d 2026 if (uses_msp430x_relocs (filedata))
13761a11
NC
2027 {
2028 rtype = elf_msp430x_reloc_type (type);
2029 break;
2030 }
1a0670f3 2031 /* Fall through. */
2469cfa2
NC
2032 case EM_MSP430_OLD:
2033 rtype = elf_msp430_reloc_type (type);
2034 break;
2035
35c08157
KLC
2036 case EM_NDS32:
2037 rtype = elf_nds32_reloc_type (type);
2038 break;
2039
252b5132 2040 case EM_PPC:
9ea033b2 2041 rtype = elf_ppc_reloc_type (type);
252b5132
RH
2042 break;
2043
c833c019
AM
2044 case EM_PPC64:
2045 rtype = elf_ppc64_reloc_type (type);
2046 break;
2047
252b5132 2048 case EM_MIPS:
4fe85591 2049 case EM_MIPS_RS3_LE:
9ea033b2 2050 rtype = elf_mips_reloc_type (type);
252b5132
RH
2051 break;
2052
e23eba97
NC
2053 case EM_RISCV:
2054 rtype = elf_riscv_reloc_type (type);
2055 break;
2056
252b5132 2057 case EM_ALPHA:
9ea033b2 2058 rtype = elf_alpha_reloc_type (type);
252b5132
RH
2059 break;
2060
2061 case EM_ARM:
9ea033b2 2062 rtype = elf_arm_reloc_type (type);
252b5132
RH
2063 break;
2064
584da044 2065 case EM_ARC:
886a2506
NC
2066 case EM_ARC_COMPACT:
2067 case EM_ARC_COMPACT2:
b5c37946
SJ
2068 case EM_ARC_COMPACT3:
2069 case EM_ARC_COMPACT3_64:
9ea033b2 2070 rtype = elf_arc_reloc_type (type);
252b5132
RH
2071 break;
2072
2073 case EM_PARISC:
69e617ca 2074 rtype = elf_hppa_reloc_type (type);
252b5132 2075 break;
7d466069 2076
b8720f9d
JL
2077 case EM_H8_300:
2078 case EM_H8_300H:
2079 case EM_H8S:
2080 rtype = elf_h8_reloc_type (type);
2081 break;
2082
73589c9d
CS
2083 case EM_OR1K:
2084 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
2085 break;
2086
7d466069 2087 case EM_PJ:
2b0337b0 2088 case EM_PJ_OLD:
7d466069
ILT
2089 rtype = elf_pj_reloc_type (type);
2090 break;
800eeca4
JW
2091 case EM_IA_64:
2092 rtype = elf_ia64_reloc_type (type);
2093 break;
1b61cf92 2094
6e712424
PI
2095 case EM_KVX:
2096 rtype = elf_kvx_reloc_type (type);
2097 break;
2098
1b61cf92
HPN
2099 case EM_CRIS:
2100 rtype = elf_cris_reloc_type (type);
2101 break;
535c37ff 2102
f954747f
AM
2103 case EM_860:
2104 rtype = elf_i860_reloc_type (type);
2105 break;
2106
bcedfee6 2107 case EM_X86_64:
8a9036a4 2108 case EM_L1OM:
7a9068fe 2109 case EM_K1OM:
bcedfee6
NC
2110 rtype = elf_x86_64_reloc_type (type);
2111 break;
a85d7ed0 2112
f954747f
AM
2113 case EM_S370:
2114 rtype = i370_reloc_type (type);
2115 break;
2116
53c7db4b
KH
2117 case EM_S390_OLD:
2118 case EM_S390:
2119 rtype = elf_s390_reloc_type (type);
2120 break;
93fbbb04 2121
1c0d3aa6
NC
2122 case EM_SCORE:
2123 rtype = elf_score_reloc_type (type);
2124 break;
2125
93fbbb04
GK
2126 case EM_XSTORMY16:
2127 rtype = elf_xstormy16_reloc_type (type);
2128 break;
179d3252 2129
1fe1f39c
NC
2130 case EM_CRX:
2131 rtype = elf_crx_reloc_type (type);
2132 break;
2133
179d3252
JT
2134 case EM_VAX:
2135 rtype = elf_vax_reloc_type (type);
2136 break;
1e4cf259 2137
619ed720
EB
2138 case EM_VISIUM:
2139 rtype = elf_visium_reloc_type (type);
2140 break;
2141
aca4efc7
JM
2142 case EM_BPF:
2143 rtype = elf_bpf_reloc_type (type);
2144 break;
2145
cfb8c092
NC
2146 case EM_ADAPTEVA_EPIPHANY:
2147 rtype = elf_epiphany_reloc_type (type);
2148 break;
2149
1e4cf259
NC
2150 case EM_IP2K:
2151 case EM_IP2K_OLD:
2152 rtype = elf_ip2k_reloc_type (type);
2153 break;
3b36097d
SC
2154
2155 case EM_IQ2000:
2156 rtype = elf_iq2000_reloc_type (type);
2157 break;
88da6820
NC
2158
2159 case EM_XTENSA_OLD:
2160 case EM_XTENSA:
2161 rtype = elf_xtensa_reloc_type (type);
2162 break;
a34e3ecb 2163
84e94c90
NC
2164 case EM_LATTICEMICO32:
2165 rtype = elf_lm32_reloc_type (type);
2166 break;
2167
ff7eeb89 2168 case EM_M32C_OLD:
49f58d10
JB
2169 case EM_M32C:
2170 rtype = elf_m32c_reloc_type (type);
2171 break;
2172
d031aafb
NS
2173 case EM_MT:
2174 rtype = elf_mt_reloc_type (type);
a34e3ecb 2175 break;
1d65ded4
CM
2176
2177 case EM_BLACKFIN:
2178 rtype = elf_bfin_reloc_type (type);
2179 break;
15ab5209
DB
2180
2181 case EM_CYGNUS_MEP:
2182 rtype = elf_mep_reloc_type (type);
2183 break;
60bca95a
NC
2184
2185 case EM_CR16:
2186 rtype = elf_cr16_reloc_type (type);
2187 break;
dd24e3da 2188
7ba29e2a
NC
2189 case EM_MICROBLAZE:
2190 case EM_MICROBLAZE_OLD:
2191 rtype = elf_microblaze_reloc_type (type);
2192 break;
c7927a3c 2193
99c513f6
DD
2194 case EM_RL78:
2195 rtype = elf_rl78_reloc_type (type);
2196 break;
2197
c7927a3c
NC
2198 case EM_RX:
2199 rtype = elf_rx_reloc_type (type);
2200 break;
c29aca4a 2201
a3c62988
NC
2202 case EM_METAG:
2203 rtype = elf_metag_reloc_type (type);
2204 break;
2205
40b36596
JM
2206 case EM_TI_C6000:
2207 rtype = elf_tic6x_reloc_type (type);
2208 break;
aa137e4d
NC
2209
2210 case EM_TILEGX:
2211 rtype = elf_tilegx_reloc_type (type);
2212 break;
2213
2214 case EM_TILEPRO:
2215 rtype = elf_tilepro_reloc_type (type);
2216 break;
f6c1a2d5 2217
f96bd6c2
PC
2218 case EM_WEBASSEMBLY:
2219 rtype = elf_wasm32_reloc_type (type);
2220 break;
2221
f6c1a2d5
NC
2222 case EM_XGATE:
2223 rtype = elf_xgate_reloc_type (type);
2224 break;
36591ba1
SL
2225
2226 case EM_ALTERA_NIOS2:
2227 rtype = elf_nios2_reloc_type (type);
2228 break;
2b100bb5
DD
2229
2230 case EM_TI_PRU:
2231 rtype = elf_pru_reloc_type (type);
2232 break;
fe944acf
FT
2233
2234 case EM_NFP:
2235 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2236 rtype = elf_nfp3200_reloc_type (type);
2237 else
2238 rtype = elf_nfp_reloc_type (type);
2239 break;
6655dba2
SB
2240
2241 case EM_Z80:
2242 rtype = elf_z80_reloc_type (type);
2243 break;
e9a0721f 2244
2245 case EM_LOONGARCH:
2246 rtype = elf_loongarch_reloc_type (type);
2247 break;
2248
0c857ef4
SM
2249 case EM_AMDGPU:
2250 rtype = elf_amdgpu_reloc_type (type);
2251 break;
252b5132
RH
2252 }
2253
2254 if (rtype == NULL)
39dbeff8 2255 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2256 else
5c144731 2257 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2258
dda8d76d 2259 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2260 && rtype != NULL
7ace3541 2261 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2262 && rel_type == reltype_rela)
7ace3541
RH
2263 {
2264 switch (rels[i].r_addend)
2265 {
2266 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2267 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2268 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2269 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2270 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2271 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2272 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2273 default: rtype = NULL;
2274 }
32ec8896 2275
7ace3541
RH
2276 if (rtype)
2277 printf (" (%s)", rtype);
2278 else
2279 {
2280 putchar (' ');
26c527e6
AM
2281 printf (_("<unknown addend: %" PRIx64 ">"),
2282 rels[i].r_addend);
015dc7e1 2283 res = false;
7ace3541
RH
2284 }
2285 }
2286 else if (symtab_index)
252b5132 2287 {
af3fc3bc 2288 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2289 {
27a45f42
AS
2290 error (_(" bad symbol index: %08lx in reloc\n"),
2291 (unsigned long) symtab_index);
015dc7e1 2292 res = false;
32ec8896 2293 }
af3fc3bc 2294 else
19936277 2295 {
2cf0635d 2296 Elf_Internal_Sym * psym;
bb4d2ac2
L
2297 const char * version_string;
2298 enum versioned_symbol_info sym_info;
2299 unsigned short vna_other;
19936277 2300
af3fc3bc 2301 psym = symtab + symtab_index;
103f02d3 2302
bb4d2ac2 2303 version_string
dda8d76d 2304 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2305 strtab, strtablen,
2306 symtab_index,
2307 psym,
2308 &sym_info,
2309 &vna_other);
2310
af3fc3bc 2311 printf (" ");
171191ba 2312
d8045f23
NC
2313 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2314 {
2315 const char * name;
2316 unsigned int len;
2317 unsigned int width = is_32bit_elf ? 8 : 14;
2318
2319 /* Relocations against GNU_IFUNC symbols do not use the value
2320 of the symbol as the address to relocate against. Instead
2321 they invoke the function named by the symbol and use its
2322 result as the address for relocation.
2323
2324 To indicate this to the user, do not display the value of
2325 the symbol in the "Symbols's Value" field. Instead show
2326 its name followed by () as a hint that the symbol is
2327 invoked. */
2328
2329 if (strtab == NULL
2330 || psym->st_name == 0
2331 || psym->st_name >= strtablen)
2332 name = "??";
2333 else
2334 name = strtab + psym->st_name;
2335
b6ac461a 2336 len = print_symbol_name (width, name);
bb4d2ac2
L
2337 if (version_string)
2338 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2339 version_string);
d8045f23
NC
2340 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2341 }
2342 else
2343 {
2344 print_vma (psym->st_value, LONG_HEX);
171191ba 2345
d8045f23
NC
2346 printf (is_32bit_elf ? " " : " ");
2347 }
103f02d3 2348
af3fc3bc 2349 if (psym->st_name == 0)
f1ef08cb 2350 {
2cf0635d 2351 const char * sec_name = "<null>";
f1ef08cb
AM
2352
2353 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2354 sec_name = printable_section_name_from_index
2355 (filedata, psym->st_shndx, NULL);
2356
2357 print_symbol_name (22, sec_name);
f1ef08cb 2358 }
af3fc3bc 2359 else if (strtab == NULL)
d79b3d50 2360 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2361 else if (psym->st_name >= strtablen)
32ec8896 2362 {
27a45f42
AS
2363 error (_("<corrupt string table index: %3ld>\n"),
2364 psym->st_name);
015dc7e1 2365 res = false;
32ec8896 2366 }
af3fc3bc 2367 else
bb4d2ac2 2368 {
b6ac461a 2369 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2370 if (version_string)
2371 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2372 version_string);
2373 }
103f02d3 2374
a7fd1186 2375 if (rel_type == reltype_rela)
171191ba 2376 {
625d49fc 2377 uint64_t off = rels[i].r_addend;
171191ba 2378
625d49fc
AM
2379 if ((int64_t) off < 0)
2380 printf (" - %" PRIx64, -off);
171191ba 2381 else
625d49fc 2382 printf (" + %" PRIx64, off);
171191ba 2383 }
19936277 2384 }
252b5132 2385 }
a7fd1186 2386 else if (rel_type == reltype_rela)
f7a99963 2387 {
625d49fc 2388 uint64_t off = rels[i].r_addend;
e04d7088
L
2389
2390 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2391 if ((int64_t) off < 0)
2392 printf ("-%" PRIx64, -off);
e04d7088 2393 else
625d49fc 2394 printf ("%" PRIx64, off);
f7a99963 2395 }
252b5132 2396
dda8d76d 2397 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2398 && rtype != NULL
2399 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2400 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2401
252b5132 2402 putchar ('\n');
2c71103e 2403
dda8d76d 2404 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2405 {
625d49fc
AM
2406 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2407 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2408 const char * rtype2 = elf_mips_reloc_type (type2);
2409 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2410
2c71103e
NC
2411 printf (" Type2: ");
2412
2413 if (rtype2 == NULL)
39dbeff8
AM
2414 printf (_("unrecognized: %-7lx"),
2415 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2416 else
2417 printf ("%-17.17s", rtype2);
2418
18bd398b 2419 printf ("\n Type3: ");
2c71103e
NC
2420
2421 if (rtype3 == NULL)
39dbeff8
AM
2422 printf (_("unrecognized: %-7lx"),
2423 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2424 else
2425 printf ("%-17.17s", rtype3);
2426
53c7db4b 2427 putchar ('\n');
2c71103e 2428 }
252b5132
RH
2429 }
2430
c8286bd1 2431 free (rels);
32ec8896
NC
2432
2433 return res;
252b5132
RH
2434}
2435
37c18eed
SD
2436static const char *
2437get_aarch64_dynamic_type (unsigned long type)
2438{
2439 switch (type)
2440 {
2441 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2442 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2443 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2444 default:
2445 return NULL;
2446 }
2447}
2448
252b5132 2449static const char *
d3ba0551 2450get_mips_dynamic_type (unsigned long type)
252b5132
RH
2451{
2452 switch (type)
2453 {
2454 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2455 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2456 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2457 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2458 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2459 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2460 case DT_MIPS_MSYM: return "MIPS_MSYM";
2461 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2462 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2463 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2464 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2465 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2466 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2467 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2468 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2469 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2470 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2471 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2472 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2473 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2474 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2475 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2476 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2477 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2478 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2479 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2480 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2481 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2482 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2483 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2484 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2485 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2486 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2487 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2488 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2489 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2490 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2491 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2492 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2493 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2494 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2495 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2496 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2497 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2498 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2499 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2500 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2501 default:
2502 return NULL;
2503 }
2504}
2505
9a097730 2506static const char *
d3ba0551 2507get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2508{
2509 switch (type)
2510 {
2511 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2512 default:
2513 return NULL;
2514 }
103f02d3
UD
2515}
2516
7490d522
AM
2517static const char *
2518get_ppc_dynamic_type (unsigned long type)
2519{
2520 switch (type)
2521 {
a7f2871e 2522 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2523 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2524 default:
2525 return NULL;
2526 }
2527}
2528
f1cb7e17 2529static const char *
d3ba0551 2530get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2531{
2532 switch (type)
2533 {
a7f2871e
AM
2534 case DT_PPC64_GLINK: return "PPC64_GLINK";
2535 case DT_PPC64_OPD: return "PPC64_OPD";
2536 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2537 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2538 default:
2539 return NULL;
2540 }
2541}
2542
103f02d3 2543static const char *
d3ba0551 2544get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2545{
2546 switch (type)
2547 {
2548 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2549 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2550 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2551 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2552 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2553 case DT_HP_PREINIT: return "HP_PREINIT";
2554 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2555 case DT_HP_NEEDED: return "HP_NEEDED";
2556 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2557 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2558 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2559 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2560 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2561 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2562 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2563 case DT_HP_FILTERED: return "HP_FILTERED";
2564 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2565 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2566 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2567 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2568 case DT_PLT: return "PLT";
2569 case DT_PLT_SIZE: return "PLT_SIZE";
2570 case DT_DLT: return "DLT";
2571 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2572 default:
2573 return NULL;
2574 }
2575}
9a097730 2576
ecc51f48 2577static const char *
d3ba0551 2578get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2579{
2580 switch (type)
2581 {
148b93f2
NC
2582 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2583 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2584 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2585 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2586 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2587 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2588 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2589 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2590 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2591 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2592 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2593 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2594 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2595 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2596 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2597 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2598 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2599 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2600 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2601 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2602 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2603 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2604 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2605 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2606 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2607 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2608 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2609 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2610 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2611 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2612 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2613 default:
2614 return NULL;
2615 }
2616}
2617
fd85a6a1
NC
2618static const char *
2619get_solaris_section_type (unsigned long type)
2620{
2621 switch (type)
2622 {
2623 case 0x6fffffee: return "SUNW_ancillary";
2624 case 0x6fffffef: return "SUNW_capchain";
2625 case 0x6ffffff0: return "SUNW_capinfo";
2626 case 0x6ffffff1: return "SUNW_symsort";
2627 case 0x6ffffff2: return "SUNW_tlssort";
2628 case 0x6ffffff3: return "SUNW_LDYNSYM";
2629 case 0x6ffffff4: return "SUNW_dof";
2630 case 0x6ffffff5: return "SUNW_cap";
2631 case 0x6ffffff6: return "SUNW_SIGNATURE";
2632 case 0x6ffffff7: return "SUNW_ANNOTATE";
2633 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2634 case 0x6ffffff9: return "SUNW_DEBUG";
2635 case 0x6ffffffa: return "SUNW_move";
2636 case 0x6ffffffb: return "SUNW_COMDAT";
2637 case 0x6ffffffc: return "SUNW_syminfo";
2638 case 0x6ffffffd: return "SUNW_verdef";
2639 case 0x6ffffffe: return "SUNW_verneed";
2640 case 0x6fffffff: return "SUNW_versym";
2641 case 0x70000000: return "SPARC_GOTDATA";
2642 default: return NULL;
2643 }
2644}
2645
fabcb361
RH
2646static const char *
2647get_alpha_dynamic_type (unsigned long type)
2648{
2649 switch (type)
2650 {
2651 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2652 default: return NULL;
fabcb361
RH
2653 }
2654}
2655
1c0d3aa6
NC
2656static const char *
2657get_score_dynamic_type (unsigned long type)
2658{
2659 switch (type)
2660 {
2661 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2662 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2663 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2664 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2665 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2666 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2667 default: return NULL;
1c0d3aa6
NC
2668 }
2669}
2670
40b36596
JM
2671static const char *
2672get_tic6x_dynamic_type (unsigned long type)
2673{
2674 switch (type)
2675 {
2676 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2677 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2678 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2679 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2680 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2681 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2682 default: return NULL;
40b36596
JM
2683 }
2684}
1c0d3aa6 2685
36591ba1
SL
2686static const char *
2687get_nios2_dynamic_type (unsigned long type)
2688{
2689 switch (type)
2690 {
2691 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2692 default: return NULL;
36591ba1
SL
2693 }
2694}
2695
fd85a6a1
NC
2696static const char *
2697get_solaris_dynamic_type (unsigned long type)
2698{
2699 switch (type)
2700 {
2701 case 0x6000000d: return "SUNW_AUXILIARY";
2702 case 0x6000000e: return "SUNW_RTLDINF";
2703 case 0x6000000f: return "SUNW_FILTER";
2704 case 0x60000010: return "SUNW_CAP";
2705 case 0x60000011: return "SUNW_SYMTAB";
2706 case 0x60000012: return "SUNW_SYMSZ";
2707 case 0x60000013: return "SUNW_SORTENT";
2708 case 0x60000014: return "SUNW_SYMSORT";
2709 case 0x60000015: return "SUNW_SYMSORTSZ";
2710 case 0x60000016: return "SUNW_TLSSORT";
2711 case 0x60000017: return "SUNW_TLSSORTSZ";
2712 case 0x60000018: return "SUNW_CAPINFO";
2713 case 0x60000019: return "SUNW_STRPAD";
2714 case 0x6000001a: return "SUNW_CAPCHAIN";
2715 case 0x6000001b: return "SUNW_LDMACH";
2716 case 0x6000001d: return "SUNW_CAPCHAINENT";
2717 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2718 case 0x60000021: return "SUNW_PARENT";
2719 case 0x60000023: return "SUNW_ASLR";
2720 case 0x60000025: return "SUNW_RELAX";
2721 case 0x60000029: return "SUNW_NXHEAP";
2722 case 0x6000002b: return "SUNW_NXSTACK";
2723
2724 case 0x70000001: return "SPARC_REGISTER";
2725 case 0x7ffffffd: return "AUXILIARY";
2726 case 0x7ffffffe: return "USED";
2727 case 0x7fffffff: return "FILTER";
2728
15f205b1 2729 default: return NULL;
fd85a6a1
NC
2730 }
2731}
2732
8155b853
NC
2733static const char *
2734get_riscv_dynamic_type (unsigned long type)
2735{
2736 switch (type)
2737 {
2738 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2739 default:
2740 return NULL;
2741 }
2742}
2743
832ca732
L
2744static const char *
2745get_x86_64_dynamic_type (unsigned long type)
2746{
2747 switch (type)
2748 {
2749 case DT_X86_64_PLT:
2750 return "DT_X86_64_PLT";
2751 case DT_X86_64_PLTSZ:
2752 return "DT_X86_64_PLTSZ";
2753 case DT_X86_64_PLTENT:
2754 return "DT_X86_64_PLTENT";
2755 default:
2756 return NULL;
2757 }
2758}
2759
252b5132 2760static const char *
dda8d76d 2761get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2762{
e9e44622 2763 static char buff[64];
252b5132
RH
2764
2765 switch (type)
2766 {
2767 case DT_NULL: return "NULL";
2768 case DT_NEEDED: return "NEEDED";
2769 case DT_PLTRELSZ: return "PLTRELSZ";
2770 case DT_PLTGOT: return "PLTGOT";
2771 case DT_HASH: return "HASH";
2772 case DT_STRTAB: return "STRTAB";
2773 case DT_SYMTAB: return "SYMTAB";
2774 case DT_RELA: return "RELA";
2775 case DT_RELASZ: return "RELASZ";
2776 case DT_RELAENT: return "RELAENT";
2777 case DT_STRSZ: return "STRSZ";
2778 case DT_SYMENT: return "SYMENT";
2779 case DT_INIT: return "INIT";
2780 case DT_FINI: return "FINI";
2781 case DT_SONAME: return "SONAME";
2782 case DT_RPATH: return "RPATH";
2783 case DT_SYMBOLIC: return "SYMBOLIC";
2784 case DT_REL: return "REL";
2785 case DT_RELSZ: return "RELSZ";
2786 case DT_RELENT: return "RELENT";
dd207c13
FS
2787 case DT_RELR: return "RELR";
2788 case DT_RELRSZ: return "RELRSZ";
2789 case DT_RELRENT: return "RELRENT";
252b5132
RH
2790 case DT_PLTREL: return "PLTREL";
2791 case DT_DEBUG: return "DEBUG";
2792 case DT_TEXTREL: return "TEXTREL";
2793 case DT_JMPREL: return "JMPREL";
2794 case DT_BIND_NOW: return "BIND_NOW";
2795 case DT_INIT_ARRAY: return "INIT_ARRAY";
2796 case DT_FINI_ARRAY: return "FINI_ARRAY";
2797 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2798 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2799 case DT_RUNPATH: return "RUNPATH";
2800 case DT_FLAGS: return "FLAGS";
2d0e6f43 2801
d1133906
NC
2802 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2803 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2804 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2805
05107a46 2806 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2807 case DT_PLTPADSZ: return "PLTPADSZ";
2808 case DT_MOVEENT: return "MOVEENT";
2809 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2810 case DT_FEATURE: return "FEATURE";
252b5132
RH
2811 case DT_POSFLAG_1: return "POSFLAG_1";
2812 case DT_SYMINSZ: return "SYMINSZ";
2813 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2814
252b5132 2815 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2816 case DT_CONFIG: return "CONFIG";
2817 case DT_DEPAUDIT: return "DEPAUDIT";
2818 case DT_AUDIT: return "AUDIT";
2819 case DT_PLTPAD: return "PLTPAD";
2820 case DT_MOVETAB: return "MOVETAB";
252b5132 2821 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2822
252b5132 2823 case DT_VERSYM: return "VERSYM";
103f02d3 2824
67a4f2b7
AO
2825 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2826 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2827 case DT_RELACOUNT: return "RELACOUNT";
2828 case DT_RELCOUNT: return "RELCOUNT";
2829 case DT_FLAGS_1: return "FLAGS_1";
2830 case DT_VERDEF: return "VERDEF";
2831 case DT_VERDEFNUM: return "VERDEFNUM";
2832 case DT_VERNEED: return "VERNEED";
2833 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2834
019148e4 2835 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2836 case DT_USED: return "USED";
2837 case DT_FILTER: return "FILTER";
103f02d3 2838
047b2264
JJ
2839 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2840 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2841 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2842 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2843 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2844 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2845 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2846
252b5132
RH
2847 default:
2848 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2849 {
2cf0635d 2850 const char * result;
103f02d3 2851
dda8d76d 2852 switch (filedata->file_header.e_machine)
252b5132 2853 {
37c18eed
SD
2854 case EM_AARCH64:
2855 result = get_aarch64_dynamic_type (type);
2856 break;
252b5132 2857 case EM_MIPS:
4fe85591 2858 case EM_MIPS_RS3_LE:
252b5132
RH
2859 result = get_mips_dynamic_type (type);
2860 break;
9a097730
RH
2861 case EM_SPARCV9:
2862 result = get_sparc64_dynamic_type (type);
2863 break;
7490d522
AM
2864 case EM_PPC:
2865 result = get_ppc_dynamic_type (type);
2866 break;
f1cb7e17
AM
2867 case EM_PPC64:
2868 result = get_ppc64_dynamic_type (type);
2869 break;
ecc51f48
NC
2870 case EM_IA_64:
2871 result = get_ia64_dynamic_type (type);
2872 break;
fabcb361
RH
2873 case EM_ALPHA:
2874 result = get_alpha_dynamic_type (type);
2875 break;
1c0d3aa6
NC
2876 case EM_SCORE:
2877 result = get_score_dynamic_type (type);
2878 break;
40b36596
JM
2879 case EM_TI_C6000:
2880 result = get_tic6x_dynamic_type (type);
2881 break;
36591ba1
SL
2882 case EM_ALTERA_NIOS2:
2883 result = get_nios2_dynamic_type (type);
2884 break;
8155b853
NC
2885 case EM_RISCV:
2886 result = get_riscv_dynamic_type (type);
2887 break;
832ca732
L
2888 case EM_X86_64:
2889 result = get_x86_64_dynamic_type (type);
2890 break;
252b5132 2891 default:
dda8d76d 2892 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2893 result = get_solaris_dynamic_type (type);
2894 else
2895 result = NULL;
252b5132
RH
2896 break;
2897 }
2898
2899 if (result != NULL)
2900 return result;
2901
e9e44622 2902 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2903 }
eec8f817 2904 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2905 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2906 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2907 {
2cf0635d 2908 const char * result;
103f02d3 2909
dda8d76d 2910 switch (filedata->file_header.e_machine)
103f02d3
UD
2911 {
2912 case EM_PARISC:
2913 result = get_parisc_dynamic_type (type);
2914 break;
148b93f2
NC
2915 case EM_IA_64:
2916 result = get_ia64_dynamic_type (type);
2917 break;
103f02d3 2918 default:
dda8d76d 2919 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2920 result = get_solaris_dynamic_type (type);
2921 else
2922 result = NULL;
103f02d3
UD
2923 break;
2924 }
2925
2926 if (result != NULL)
2927 return result;
2928
e9e44622
JJ
2929 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2930 type);
103f02d3 2931 }
252b5132 2932 else
e9e44622 2933 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2934
252b5132
RH
2935 return buff;
2936 }
2937}
2938
93df3340
AM
2939static bool get_program_headers (Filedata *);
2940static bool get_dynamic_section (Filedata *);
2941
2942static void
2943locate_dynamic_section (Filedata *filedata)
2944{
26c527e6 2945 uint64_t dynamic_addr = 0;
be7d229a 2946 uint64_t dynamic_size = 0;
93df3340
AM
2947
2948 if (filedata->file_header.e_phnum != 0
2949 && get_program_headers (filedata))
2950 {
2951 Elf_Internal_Phdr *segment;
2952 unsigned int i;
2953
2954 for (i = 0, segment = filedata->program_headers;
2955 i < filedata->file_header.e_phnum;
2956 i++, segment++)
2957 {
2958 if (segment->p_type == PT_DYNAMIC)
2959 {
2960 dynamic_addr = segment->p_offset;
2961 dynamic_size = segment->p_filesz;
2962
2963 if (filedata->section_headers != NULL)
2964 {
2965 Elf_Internal_Shdr *sec;
2966
2967 sec = find_section (filedata, ".dynamic");
2968 if (sec != NULL)
2969 {
2970 if (sec->sh_size == 0
2971 || sec->sh_type == SHT_NOBITS)
2972 {
2973 dynamic_addr = 0;
2974 dynamic_size = 0;
2975 }
2976 else
2977 {
2978 dynamic_addr = sec->sh_offset;
2979 dynamic_size = sec->sh_size;
2980 }
2981 }
2982 }
2983
2984 if (dynamic_addr > filedata->file_size
2985 || (dynamic_size > filedata->file_size - dynamic_addr))
2986 {
2987 dynamic_addr = 0;
2988 dynamic_size = 0;
2989 }
2990 break;
2991 }
2992 }
2993 }
2994 filedata->dynamic_addr = dynamic_addr;
2995 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2996}
2997
2998static bool
2999is_pie (Filedata *filedata)
3000{
3001 Elf_Internal_Dyn *entry;
3002
3003 if (filedata->dynamic_size == 0)
3004 locate_dynamic_section (filedata);
3005 if (filedata->dynamic_size <= 1)
3006 return false;
3007
3008 if (!get_dynamic_section (filedata))
3009 return false;
3010
3011 for (entry = filedata->dynamic_section;
3012 entry < filedata->dynamic_section + filedata->dynamic_nent;
3013 entry++)
3014 {
3015 if (entry->d_tag == DT_FLAGS_1)
3016 {
3017 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3018 return true;
3019 break;
3020 }
3021 }
3022 return false;
3023}
3024
252b5132 3025static char *
93df3340 3026get_file_type (Filedata *filedata)
252b5132 3027{
93df3340 3028 unsigned e_type = filedata->file_header.e_type;
89246a0e 3029 static char buff[64];
252b5132
RH
3030
3031 switch (e_type)
3032 {
32ec8896
NC
3033 case ET_NONE: return _("NONE (None)");
3034 case ET_REL: return _("REL (Relocatable file)");
3035 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
3036 case ET_DYN:
3037 if (is_pie (filedata))
3038 return _("DYN (Position-Independent Executable file)");
3039 else
3040 return _("DYN (Shared object file)");
32ec8896 3041 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
3042
3043 default:
3044 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 3045 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 3046 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 3047 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 3048 else
e9e44622 3049 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
3050 return buff;
3051 }
3052}
3053
3054static char *
d3ba0551 3055get_machine_name (unsigned e_machine)
252b5132 3056{
b34976b6 3057 static char buff[64]; /* XXX */
252b5132
RH
3058
3059 switch (e_machine)
3060 {
55e22ca8
NC
3061 /* Please keep this switch table sorted by increasing EM_ value. */
3062 /* 0 */
c45021f2
NC
3063 case EM_NONE: return _("None");
3064 case EM_M32: return "WE32100";
3065 case EM_SPARC: return "Sparc";
3066 case EM_386: return "Intel 80386";
3067 case EM_68K: return "MC68000";
3068 case EM_88K: return "MC88000";
22abe556 3069 case EM_IAMCU: return "Intel MCU";
fb70ec17 3070 case EM_860: return "Intel 80860";
c45021f2
NC
3071 case EM_MIPS: return "MIPS R3000";
3072 case EM_S370: return "IBM System/370";
55e22ca8 3073 /* 10 */
7036c0e1 3074 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 3075 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 3076 case EM_PARISC: return "HPPA";
55e22ca8 3077 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 3078 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 3079 case EM_960: return "Intel 80960";
c45021f2 3080 case EM_PPC: return "PowerPC";
55e22ca8 3081 /* 20 */
285d1771 3082 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
3083 case EM_S390_OLD:
3084 case EM_S390: return "IBM S/390";
3085 case EM_SPU: return "SPU";
3086 /* 30 */
3087 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
3088 case EM_FR20: return "Fujitsu FR20";
3089 case EM_RH32: return "TRW RH32";
b34976b6 3090 case EM_MCORE: return "MCORE";
55e22ca8 3091 /* 40 */
7036c0e1
AJ
3092 case EM_ARM: return "ARM";
3093 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 3094 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
3095 case EM_SPARCV9: return "Sparc v9";
3096 case EM_TRICORE: return "Siemens Tricore";
584da044 3097 case EM_ARC: return "ARC";
c2dcd04e
NC
3098 case EM_H8_300: return "Renesas H8/300";
3099 case EM_H8_300H: return "Renesas H8/300H";
3100 case EM_H8S: return "Renesas H8S";
3101 case EM_H8_500: return "Renesas H8/500";
55e22ca8 3102 /* 50 */
30800947 3103 case EM_IA_64: return "Intel IA-64";
252b5132
RH
3104 case EM_MIPS_X: return "Stanford MIPS-X";
3105 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 3106 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
3107 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3108 case EM_PCP: return "Siemens PCP";
3109 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 3110 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
3111 case EM_STARCORE: return "Motorola Star*Core processor";
3112 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 3113 /* 60 */
7036c0e1
AJ
3114 case EM_ST100: return "STMicroelectronics ST100 processor";
3115 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 3116 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
3117 case EM_PDSP: return "Sony DSP processor";
3118 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3119 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
3120 case EM_FX66: return "Siemens FX66 microcontroller";
3121 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3122 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3123 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 3124 /* 70 */
7036c0e1
AJ
3125 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3126 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3127 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3128 case EM_SVX: return "Silicon Graphics SVx";
3129 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3130 case EM_VAX: return "Digital VAX";
1b61cf92 3131 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
3132 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3133 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3134 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 3135 /* 80 */
b34976b6 3136 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 3137 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 3138 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
3139 case EM_AVR_OLD:
3140 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3141 case EM_CYGNUS_FR30:
3142 case EM_FR30: return "Fujitsu FR30";
3143 case EM_CYGNUS_D10V:
3144 case EM_D10V: return "d10v";
3145 case EM_CYGNUS_D30V:
3146 case EM_D30V: return "d30v";
3147 case EM_CYGNUS_V850:
3148 case EM_V850: return "Renesas V850";
3149 case EM_CYGNUS_M32R:
3150 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3151 case EM_CYGNUS_MN10300:
3152 case EM_MN10300: return "mn10300";
3153 /* 90 */
3154 case EM_CYGNUS_MN10200:
3155 case EM_MN10200: return "mn10200";
3156 case EM_PJ: return "picoJava";
73589c9d 3157 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 3158 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
3159 case EM_XTENSA_OLD:
3160 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
3161 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3162 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3163 case EM_NS32K: return "National Semiconductor 32000 series";
3164 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
3165 case EM_SNP1K: return "Trebia SNP 1000 processor";
3166 /* 100 */
9abca702 3167 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
3168 case EM_IP2K_OLD:
3169 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
3170 case EM_MAX: return "MAX Processor";
3171 case EM_CR: return "National Semiconductor CompactRISC";
3172 case EM_F2MC16: return "Fujitsu F2MC16";
3173 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 3174 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
3175 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3176 case EM_SEP: return "Sharp embedded microprocessor";
3177 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 3178 /* 110 */
11636f9e
JM
3179 case EM_UNICORE: return "Unicore";
3180 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3181 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 3182 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
3183 case EM_CRX: return "National Semiconductor CRX microprocessor";
3184 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 3185 case EM_C166:
d70c5fc7 3186 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
3187 case EM_M16C: return "Renesas M16C series microprocessors";
3188 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3189 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
3190 /* 120 */
3191 case EM_M32C: return "Renesas M32c";
3192 /* 130 */
11636f9e
JM
3193 case EM_TSK3000: return "Altium TSK3000 core";
3194 case EM_RS08: return "Freescale RS08 embedded processor";
3195 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 3196 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
3197 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3198 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 3199 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 3200 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 3201 /* 140 */
11636f9e
JM
3202 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3203 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3204 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
3205 case EM_TI_PRU: return "TI PRU I/O processor";
3206 /* 160 */
11636f9e
JM
3207 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3208 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3209 case EM_R32C: return "Renesas R32C series microprocessors";
3210 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3211 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3212 case EM_8051: return "Intel 8051 and variants";
3213 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3214 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3215 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3216 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 3217 /* 170 */
11636f9e
JM
3218 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3219 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3220 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3221 case EM_RX: return "Renesas RX";
a3c62988 3222 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3223 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3224 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3225 case EM_CR16:
3226 case EM_MICROBLAZE:
3227 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3228 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3229 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3230 /* 180 */
3231 case EM_L1OM: return "Intel L1OM";
3232 case EM_K1OM: return "Intel K1OM";
3233 case EM_INTEL182: return "Intel (reserved)";
3234 case EM_AARCH64: return "AArch64";
3235 case EM_ARM184: return "ARM (reserved)";
3236 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3237 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3238 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3239 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3240 /* 190 */
11636f9e 3241 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3242 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3243 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3244 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3245 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3246 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3247 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3248 case EM_RL78: return "Renesas RL78";
6d913794 3249 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3250 case EM_78K0R: return "Renesas 78K0R";
3251 /* 200 */
6d913794 3252 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3253 case EM_BA1: return "Beyond BA1 CPU architecture";
3254 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3255 case EM_XCORE: return "XMOS xCORE processor family";
3256 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3257 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3258 /* 210 */
6d913794
NC
3259 case EM_KM32: return "KM211 KM32 32-bit processor";
3260 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3261 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3262 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3263 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3264 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3265 case EM_COGE: return "Cognitive Smart Memory Processor";
3266 case EM_COOL: return "Bluechip Systems CoolEngine";
3267 case EM_NORC: return "Nanoradio Optimized RISC";
3268 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3269 /* 220 */
15f205b1 3270 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3271 case EM_VISIUM: return "CDS VISIUMcore processor";
3272 case EM_FT32: return "FTDI Chip FT32";
3273 case EM_MOXIE: return "Moxie";
3274 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3275 /* 230 (all reserved) */
3276 /* 240 */
55e22ca8
NC
3277 case EM_RISCV: return "RISC-V";
3278 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3279 case EM_CEVA: return "CEVA Processor Architecture Family";
3280 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3281 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3282 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3283 case EM_IMG1: return "Imagination Technologies";
3284 /* 250 */
fe944acf 3285 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3286 case EM_VE: return "NEC Vector Engine";
3287 case EM_CSKY: return "C-SKY";
b5c37946 3288 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3289 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3290 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3291 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3292 case EM_65816: return "WDC 65816/65C816";
01a8c731 3293 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3294 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3295
3296 /* Large numbers... */
3297 case EM_MT: return "Morpho Techologies MT processor";
3298 case EM_ALPHA: return "Alpha";
3299 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3300 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3301 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3302 case EM_IQ2000: return "Vitesse IQ2000";
3303 case EM_M32C_OLD:
3304 case EM_NIOS32: return "Altera Nios";
3305 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3306 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3307 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3308 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3309
252b5132 3310 default:
35d9dd2f 3311 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3312 return buff;
3313 }
3314}
3315
f8c4789c
AM
3316static char *
3317decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3318{
3319 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3320 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3321 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3322 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3323 architectures.
3324
3325 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3326 but also sets a specific architecture type in the e_flags field.
3327
3328 However, when decoding the flags we don't worry if we see an
3329 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3330 ARCEM architecture type. */
3331
3332 switch (e_flags & EF_ARC_MACH_MSK)
3333 {
3334 /* We only expect these to occur for EM_ARC_COMPACT2. */
3335 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3336 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3337 break;
3338 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3339 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3340 break;
3341
3342 /* We only expect these to occur for EM_ARC_COMPACT. */
3343 case E_ARC_MACH_ARC600:
f8c4789c 3344 out = stpcpy (out, ", ARC600");
a9522a21
AB
3345 break;
3346 case E_ARC_MACH_ARC601:
f8c4789c 3347 out = stpcpy (out, ", ARC601");
a9522a21
AB
3348 break;
3349 case E_ARC_MACH_ARC700:
f8c4789c 3350 out = stpcpy (out, ", ARC700");
a9522a21
AB
3351 break;
3352
3353 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3354 new ELF with new architecture being read by an old version of
3355 readelf, or (c) An ELF built with non-GNU compiler that does not
3356 set the architecture in the e_flags. */
3357 default:
3358 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3359 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3360 else
f8c4789c 3361 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3362 break;
3363 }
3364
3365 switch (e_flags & EF_ARC_OSABI_MSK)
3366 {
3367 case E_ARC_OSABI_ORIG:
f8c4789c 3368 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3369 break;
3370 case E_ARC_OSABI_V2:
f8c4789c 3371 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3372 break;
3373 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3374 case E_ARC_OSABI_V3:
f8c4789c 3375 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3376 break;
53a346d8 3377 case E_ARC_OSABI_V4:
f8c4789c 3378 out = stpcpy (out, ", v4 ABI");
53a346d8 3379 break;
a9522a21 3380 default:
f8c4789c 3381 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3382 break;
3383 }
f8c4789c 3384 return out;
a9522a21
AB
3385}
3386
f8c4789c
AM
3387static char *
3388decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3389{
3390 unsigned eabi;
015dc7e1 3391 bool unknown = false;
f3485b74
NC
3392
3393 eabi = EF_ARM_EABI_VERSION (e_flags);
3394 e_flags &= ~ EF_ARM_EABIMASK;
3395
3396 /* Handle "generic" ARM flags. */
3397 if (e_flags & EF_ARM_RELEXEC)
3398 {
f8c4789c 3399 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3400 e_flags &= ~ EF_ARM_RELEXEC;
3401 }
76da6bbe 3402
18a20338
CL
3403 if (e_flags & EF_ARM_PIC)
3404 {
f8c4789c 3405 out = stpcpy (out, ", position independent");
18a20338
CL
3406 e_flags &= ~ EF_ARM_PIC;
3407 }
3408
f3485b74
NC
3409 /* Now handle EABI specific flags. */
3410 switch (eabi)
3411 {
3412 default:
f8c4789c 3413 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3414 if (e_flags)
015dc7e1 3415 unknown = true;
f3485b74
NC
3416 break;
3417
3418 case EF_ARM_EABI_VER1:
f8c4789c 3419 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3420 while (e_flags)
3421 {
3422 unsigned flag;
76da6bbe 3423
f3485b74
NC
3424 /* Process flags one bit at a time. */
3425 flag = e_flags & - e_flags;
3426 e_flags &= ~ flag;
76da6bbe 3427
f3485b74
NC
3428 switch (flag)
3429 {
a5bcd848 3430 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3431 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3432 break;
76da6bbe 3433
f3485b74 3434 default:
015dc7e1 3435 unknown = true;
f3485b74
NC
3436 break;
3437 }
3438 }
3439 break;
76da6bbe 3440
a5bcd848 3441 case EF_ARM_EABI_VER2:
f8c4789c 3442 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3443 while (e_flags)
3444 {
3445 unsigned flag;
3446
3447 /* Process flags one bit at a time. */
3448 flag = e_flags & - e_flags;
3449 e_flags &= ~ flag;
3450
3451 switch (flag)
3452 {
3453 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3454 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3455 break;
3456
3457 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3458 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3459 break;
3460
3461 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3462 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3463 break;
3464
3465 default:
015dc7e1 3466 unknown = true;
a5bcd848
PB
3467 break;
3468 }
3469 }
3470 break;
3471
d507cf36 3472 case EF_ARM_EABI_VER3:
f8c4789c 3473 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3474 break;
3475
3476 case EF_ARM_EABI_VER4:
f8c4789c 3477 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3478 while (e_flags)
3479 {
3480 unsigned flag;
3481
3482 /* Process flags one bit at a time. */
3483 flag = e_flags & - e_flags;
3484 e_flags &= ~ flag;
3485
3486 switch (flag)
3487 {
3488 case EF_ARM_BE8:
f8c4789c 3489 out = stpcpy (out, ", BE8");
3bfcb652
NC
3490 break;
3491
3492 case EF_ARM_LE8:
f8c4789c 3493 out = stpcpy (out, ", LE8");
3bfcb652
NC
3494 break;
3495
3496 default:
015dc7e1 3497 unknown = true;
3bfcb652
NC
3498 break;
3499 }
3bfcb652
NC
3500 }
3501 break;
3a4a14e9
PB
3502
3503 case EF_ARM_EABI_VER5:
f8c4789c 3504 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3505 while (e_flags)
3506 {
3507 unsigned flag;
3508
3509 /* Process flags one bit at a time. */
3510 flag = e_flags & - e_flags;
3511 e_flags &= ~ flag;
3512
3513 switch (flag)
3514 {
3515 case EF_ARM_BE8:
f8c4789c 3516 out = stpcpy (out, ", BE8");
d507cf36
PB
3517 break;
3518
3519 case EF_ARM_LE8:
f8c4789c 3520 out = stpcpy (out, ", LE8");
d507cf36
PB
3521 break;
3522
3bfcb652 3523 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3524 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3525 break;
3526
3527 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3528 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3529 break;
3530
d507cf36 3531 default:
015dc7e1 3532 unknown = true;
d507cf36
PB
3533 break;
3534 }
3535 }
3536 break;
3537
f3485b74 3538 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3539 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3540 while (e_flags)
3541 {
3542 unsigned flag;
76da6bbe 3543
f3485b74
NC
3544 /* Process flags one bit at a time. */
3545 flag = e_flags & - e_flags;
3546 e_flags &= ~ flag;
76da6bbe 3547
f3485b74
NC
3548 switch (flag)
3549 {
a5bcd848 3550 case EF_ARM_INTERWORK:
f8c4789c 3551 out = stpcpy (out, ", interworking enabled");
f3485b74 3552 break;
76da6bbe 3553
a5bcd848 3554 case EF_ARM_APCS_26:
f8c4789c 3555 out = stpcpy (out, ", uses APCS/26");
f3485b74 3556 break;
76da6bbe 3557
a5bcd848 3558 case EF_ARM_APCS_FLOAT:
f8c4789c 3559 out = stpcpy (out, ", uses APCS/float");
f3485b74 3560 break;
76da6bbe 3561
a5bcd848 3562 case EF_ARM_PIC:
f8c4789c 3563 out = stpcpy (out, ", position independent");
f3485b74 3564 break;
76da6bbe 3565
a5bcd848 3566 case EF_ARM_ALIGN8:
f8c4789c 3567 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3568 break;
76da6bbe 3569
a5bcd848 3570 case EF_ARM_NEW_ABI:
f8c4789c 3571 out = stpcpy (out, ", uses new ABI");
f3485b74 3572 break;
76da6bbe 3573
a5bcd848 3574 case EF_ARM_OLD_ABI:
f8c4789c 3575 out = stpcpy (out, ", uses old ABI");
f3485b74 3576 break;
76da6bbe 3577
a5bcd848 3578 case EF_ARM_SOFT_FLOAT:
f8c4789c 3579 out = stpcpy (out, ", software FP");
f3485b74 3580 break;
76da6bbe 3581
90e01f86 3582 case EF_ARM_VFP_FLOAT:
f8c4789c 3583 out = stpcpy (out, ", VFP");
90e01f86
ILT
3584 break;
3585
fde78edd 3586 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3587 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3588 break;
3589
f3485b74 3590 default:
015dc7e1 3591 unknown = true;
f3485b74
NC
3592 break;
3593 }
3594 }
3595 }
f3485b74
NC
3596
3597 if (unknown)
f8c4789c
AM
3598 out = stpcpy (out,_(", <unknown>"));
3599 return out;
f3485b74
NC
3600}
3601
f8c4789c
AM
3602static char *
3603decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3604{
343433df
AB
3605 switch (e_flags & EF_AVR_MACH)
3606 {
3607 case E_AVR_MACH_AVR1:
f8c4789c 3608 out = stpcpy (out, ", avr:1");
343433df
AB
3609 break;
3610 case E_AVR_MACH_AVR2:
f8c4789c 3611 out = stpcpy (out, ", avr:2");
343433df
AB
3612 break;
3613 case E_AVR_MACH_AVR25:
f8c4789c 3614 out = stpcpy (out, ", avr:25");
343433df
AB
3615 break;
3616 case E_AVR_MACH_AVR3:
f8c4789c 3617 out = stpcpy (out, ", avr:3");
343433df
AB
3618 break;
3619 case E_AVR_MACH_AVR31:
f8c4789c 3620 out = stpcpy (out, ", avr:31");
343433df
AB
3621 break;
3622 case E_AVR_MACH_AVR35:
f8c4789c 3623 out = stpcpy (out, ", avr:35");
343433df
AB
3624 break;
3625 case E_AVR_MACH_AVR4:
f8c4789c 3626 out = stpcpy (out, ", avr:4");
343433df
AB
3627 break;
3628 case E_AVR_MACH_AVR5:
f8c4789c 3629 out = stpcpy (out, ", avr:5");
343433df
AB
3630 break;
3631 case E_AVR_MACH_AVR51:
f8c4789c 3632 out = stpcpy (out, ", avr:51");
343433df
AB
3633 break;
3634 case E_AVR_MACH_AVR6:
f8c4789c 3635 out = stpcpy (out, ", avr:6");
343433df
AB
3636 break;
3637 case E_AVR_MACH_AVRTINY:
f8c4789c 3638 out = stpcpy (out, ", avr:100");
343433df
AB
3639 break;
3640 case E_AVR_MACH_XMEGA1:
f8c4789c 3641 out = stpcpy (out, ", avr:101");
343433df
AB
3642 break;
3643 case E_AVR_MACH_XMEGA2:
f8c4789c 3644 out = stpcpy (out, ", avr:102");
343433df
AB
3645 break;
3646 case E_AVR_MACH_XMEGA3:
f8c4789c 3647 out = stpcpy (out, ", avr:103");
343433df
AB
3648 break;
3649 case E_AVR_MACH_XMEGA4:
f8c4789c 3650 out = stpcpy (out, ", avr:104");
343433df
AB
3651 break;
3652 case E_AVR_MACH_XMEGA5:
f8c4789c 3653 out = stpcpy (out, ", avr:105");
343433df
AB
3654 break;
3655 case E_AVR_MACH_XMEGA6:
f8c4789c 3656 out = stpcpy (out, ", avr:106");
343433df
AB
3657 break;
3658 case E_AVR_MACH_XMEGA7:
f8c4789c 3659 out = stpcpy (out, ", avr:107");
343433df
AB
3660 break;
3661 default:
f8c4789c 3662 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3663 break;
3664 }
3665
343433df 3666 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3667 out = stpcpy (out, ", link-relax");
3668 return out;
343433df
AB
3669}
3670
f8c4789c
AM
3671static char *
3672decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3673{
3674 if (e_flags & EF_BFIN_PIC)
3675 out = stpcpy (out, ", PIC");
3676
3677 if (e_flags & EF_BFIN_FDPIC)
3678 out = stpcpy (out, ", FDPIC");
3679
3680 if (e_flags & EF_BFIN_CODE_IN_L1)
3681 out = stpcpy (out, ", code in L1");
3682
3683 if (e_flags & EF_BFIN_DATA_IN_L1)
3684 out = stpcpy (out, ", data in L1");
3685 return out;
3686}
3687
3688static char *
3689decode_FRV_machine_flags (char *out, unsigned e_flags)
3690{
3691 switch (e_flags & EF_FRV_CPU_MASK)
3692 {
3693 case EF_FRV_CPU_GENERIC:
3694 break;
3695
3696 default:
3697 out = stpcpy (out, ", fr???");
3698 break;
3699
3700 case EF_FRV_CPU_FR300:
3701 out = stpcpy (out, ", fr300");
3702 break;
3703
3704 case EF_FRV_CPU_FR400:
3705 out = stpcpy (out, ", fr400");
3706 break;
3707 case EF_FRV_CPU_FR405:
3708 out = stpcpy (out, ", fr405");
3709 break;
3710
3711 case EF_FRV_CPU_FR450:
3712 out = stpcpy (out, ", fr450");
3713 break;
3714
3715 case EF_FRV_CPU_FR500:
3716 out = stpcpy (out, ", fr500");
3717 break;
3718 case EF_FRV_CPU_FR550:
3719 out = stpcpy (out, ", fr550");
3720 break;
3721
3722 case EF_FRV_CPU_SIMPLE:
3723 out = stpcpy (out, ", simple");
3724 break;
3725 case EF_FRV_CPU_TOMCAT:
3726 out = stpcpy (out, ", tomcat");
3727 break;
3728 }
3729 return out;
3730}
3731
3732static char *
3733decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3734{
3735 if ((e_flags & EF_IA_64_ABI64))
3736 out = stpcpy (out, ", 64-bit");
3737 else
3738 out = stpcpy (out, ", 32-bit");
3739 if ((e_flags & EF_IA_64_REDUCEDFP))
3740 out = stpcpy (out, ", reduced fp model");
3741 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3742 out = stpcpy (out, ", no function descriptors, constant gp");
3743 else if ((e_flags & EF_IA_64_CONS_GP))
3744 out = stpcpy (out, ", constant gp");
3745 if ((e_flags & EF_IA_64_ABSOLUTE))
3746 out = stpcpy (out, ", absolute");
3747 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3748 {
3749 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3750 out = stpcpy (out, ", vms_linkages");
3751 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3752 {
3753 case EF_IA_64_VMS_COMCOD_SUCCESS:
3754 break;
3755 case EF_IA_64_VMS_COMCOD_WARNING:
3756 out = stpcpy (out, ", warning");
3757 break;
3758 case EF_IA_64_VMS_COMCOD_ERROR:
3759 out = stpcpy (out, ", error");
3760 break;
3761 case EF_IA_64_VMS_COMCOD_ABORT:
3762 out = stpcpy (out, ", abort");
3763 break;
3764 default:
3765 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3766 e_flags & EF_IA_64_VMS_COMCOD);
3767 out = stpcpy (out, ", <unknown>");
3768 }
3769 }
3770 return out;
3771}
3772
3773static char *
3774decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3775{
3776 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3777 out = stpcpy (out, ", SOFT-FLOAT");
3778 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3779 out = stpcpy (out, ", SINGLE-FLOAT");
3780 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3781 out = stpcpy (out, ", DOUBLE-FLOAT");
3782
3783 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3784 out = stpcpy (out, ", OBJ-v0");
3785 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3786 out = stpcpy (out, ", OBJ-v1");
3787 return out;
3788}
3789
3790static char *
3791decode_M68K_machine_flags (char *out, unsigned int e_flags)
3792{
3793 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3794 out = stpcpy (out, ", m68000");
3795 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3796 out = stpcpy (out, ", cpu32");
3797 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3798 out = stpcpy (out, ", fido_a");
3799 else
3800 {
3801 char const *isa = _("unknown");
3802 char const *mac = _("unknown mac");
3803 char const *additional = NULL;
3804
3805 switch (e_flags & EF_M68K_CF_ISA_MASK)
3806 {
3807 case EF_M68K_CF_ISA_A_NODIV:
3808 isa = "A";
3809 additional = ", nodiv";
3810 break;
3811 case EF_M68K_CF_ISA_A:
3812 isa = "A";
3813 break;
3814 case EF_M68K_CF_ISA_A_PLUS:
3815 isa = "A+";
3816 break;
3817 case EF_M68K_CF_ISA_B_NOUSP:
3818 isa = "B";
3819 additional = ", nousp";
3820 break;
3821 case EF_M68K_CF_ISA_B:
3822 isa = "B";
3823 break;
3824 case EF_M68K_CF_ISA_C:
3825 isa = "C";
3826 break;
3827 case EF_M68K_CF_ISA_C_NODIV:
3828 isa = "C";
3829 additional = ", nodiv";
3830 break;
3831 }
3832 out = stpcpy (out, ", cf, isa ");
3833 out = stpcpy (out, isa);
3834 if (additional)
3835 out = stpcpy (out, additional);
3836 if (e_flags & EF_M68K_CF_FLOAT)
3837 out = stpcpy (out, ", float");
3838 switch (e_flags & EF_M68K_CF_MAC_MASK)
3839 {
3840 case 0:
3841 mac = NULL;
3842 break;
3843 case EF_M68K_CF_MAC:
3844 mac = "mac";
3845 break;
3846 case EF_M68K_CF_EMAC:
3847 mac = "emac";
3848 break;
3849 case EF_M68K_CF_EMAC_B:
3850 mac = "emac_b";
3851 break;
3852 }
3853 if (mac)
3854 {
3855 out = stpcpy (out, ", ");
3856 out = stpcpy (out, mac);
3857 }
3858 }
3859 return out;
3860}
3861
3862static char *
3863decode_MeP_machine_flags (char *out, unsigned int e_flags)
3864{
3865 switch (e_flags & EF_MEP_CPU_MASK)
3866 {
3867 case EF_MEP_CPU_MEP:
3868 out = stpcpy (out, ", generic MeP");
3869 break;
3870 case EF_MEP_CPU_C2:
3871 out = stpcpy (out, ", MeP C2");
3872 break;
3873 case EF_MEP_CPU_C3:
3874 out = stpcpy (out, ", MeP C3");
3875 break;
3876 case EF_MEP_CPU_C4:
3877 out = stpcpy (out, ", MeP C4");
3878 break;
3879 case EF_MEP_CPU_C5:
3880 out = stpcpy (out, ", MeP C5");
3881 break;
3882 case EF_MEP_CPU_H1:
3883 out = stpcpy (out, ", MeP H1");
3884 break;
3885 default:
3886 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3887 break;
3888 }
3889
3890 switch (e_flags & EF_MEP_COP_MASK)
3891 {
3892 case EF_MEP_COP_NONE:
3893 break;
3894 case EF_MEP_COP_AVC:
3895 out = stpcpy (out, ", AVC coprocessor");
3896 break;
3897 case EF_MEP_COP_AVC2:
3898 out = stpcpy (out, ", AVC2 coprocessor");
3899 break;
3900 case EF_MEP_COP_FMAX:
3901 out = stpcpy (out, ", FMAX coprocessor");
3902 break;
3903 case EF_MEP_COP_IVC2:
3904 out = stpcpy (out, ", IVC2 coprocessor");
3905 break;
3906 default:
3907 out = stpcpy (out, _("<unknown MeP copro type>"));
3908 break;
3909 }
3910
3911 if (e_flags & EF_MEP_LIBRARY)
3912 out = stpcpy (out, ", Built for Library");
3913
3914 if (e_flags & EF_MEP_INDEX_MASK)
3915 out += sprintf (out, ", Configuration Index: %#x",
3916 e_flags & EF_MEP_INDEX_MASK);
3917
3918 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3919 out += sprintf (out, _(", unknown flags bits: %#x"),
3920 e_flags & ~ EF_MEP_ALL_FLAGS);
3921 return out;
3922}
3923
3924static char *
3925decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3926{
3927 if (e_flags & EF_MIPS_NOREORDER)
3928 out = stpcpy (out, ", noreorder");
3929
3930 if (e_flags & EF_MIPS_PIC)
3931 out = stpcpy (out, ", pic");
3932
3933 if (e_flags & EF_MIPS_CPIC)
3934 out = stpcpy (out, ", cpic");
3935
3936 if (e_flags & EF_MIPS_UCODE)
3937 out = stpcpy (out, ", ugen_reserved");
3938
3939 if (e_flags & EF_MIPS_ABI2)
3940 out = stpcpy (out, ", abi2");
3941
3942 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3943 out = stpcpy (out, ", odk first");
3944
3945 if (e_flags & EF_MIPS_32BITMODE)
3946 out = stpcpy (out, ", 32bitmode");
3947
3948 if (e_flags & EF_MIPS_NAN2008)
3949 out = stpcpy (out, ", nan2008");
3950
3951 if (e_flags & EF_MIPS_FP64)
3952 out = stpcpy (out, ", fp64");
3953
3954 switch ((e_flags & EF_MIPS_MACH))
3955 {
d173146d 3956 case EF_MIPS_MACH_3900:
f8c4789c
AM
3957 out = stpcpy (out, ", 3900");
3958 break;
d173146d 3959 case EF_MIPS_MACH_4010:
f8c4789c
AM
3960 out = stpcpy (out, ", 4010");
3961 break;
d173146d 3962 case EF_MIPS_MACH_4100:
f8c4789c
AM
3963 out = stpcpy (out, ", 4100");
3964 break;
d173146d 3965 case EF_MIPS_MACH_4111:
f8c4789c
AM
3966 out = stpcpy (out, ", 4111");
3967 break;
d173146d 3968 case EF_MIPS_MACH_4120:
f8c4789c
AM
3969 out = stpcpy (out, ", 4120");
3970 break;
d173146d 3971 case EF_MIPS_MACH_4650:
f8c4789c
AM
3972 out = stpcpy (out, ", 4650");
3973 break;
d173146d 3974 case EF_MIPS_MACH_5400:
f8c4789c
AM
3975 out = stpcpy (out, ", 5400");
3976 break;
d173146d 3977 case EF_MIPS_MACH_5500:
f8c4789c
AM
3978 out = stpcpy (out, ", 5500");
3979 break;
d173146d 3980 case EF_MIPS_MACH_5900:
f8c4789c
AM
3981 out = stpcpy (out, ", 5900");
3982 break;
d173146d 3983 case EF_MIPS_MACH_SB1:
f8c4789c
AM
3984 out = stpcpy (out, ", sb1");
3985 break;
d173146d 3986 case EF_MIPS_MACH_9000:
f8c4789c
AM
3987 out = stpcpy (out, ", 9000");
3988 break;
d173146d 3989 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
3990 out = stpcpy (out, ", loongson-2e");
3991 break;
d173146d 3992 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
3993 out = stpcpy (out, ", loongson-2f");
3994 break;
d173146d 3995 case EF_MIPS_MACH_GS464:
f8c4789c
AM
3996 out = stpcpy (out, ", gs464");
3997 break;
d173146d 3998 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
3999 out = stpcpy (out, ", gs464e");
4000 break;
d173146d 4001 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
4002 out = stpcpy (out, ", gs264e");
4003 break;
d173146d 4004 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
4005 out = stpcpy (out, ", octeon");
4006 break;
d173146d 4007 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
4008 out = stpcpy (out, ", octeon2");
4009 break;
d173146d 4010 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
4011 out = stpcpy (out, ", octeon3");
4012 break;
d173146d 4013 case EF_MIPS_MACH_XLR:
f8c4789c
AM
4014 out = stpcpy (out, ", xlr");
4015 break;
d173146d 4016 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
4017 out = stpcpy (out, ", interaptiv-mr2");
4018 break;
d173146d 4019 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
4020 out = stpcpy (out, ", allegrex");
4021 break;
4022 case 0:
4023 /* We simply ignore the field in this case to avoid confusion:
4024 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4025 extension. */
4026 break;
4027 default:
4028 out = stpcpy (out, _(", unknown CPU"));
4029 break;
4030 }
4031
4032 switch ((e_flags & EF_MIPS_ABI))
4033 {
d173146d 4034 case EF_MIPS_ABI_O32:
f8c4789c
AM
4035 out = stpcpy (out, ", o32");
4036 break;
d173146d 4037 case EF_MIPS_ABI_O64:
f8c4789c
AM
4038 out = stpcpy (out, ", o64");
4039 break;
d173146d 4040 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
4041 out = stpcpy (out, ", eabi32");
4042 break;
d173146d 4043 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
4044 out = stpcpy (out, ", eabi64");
4045 break;
4046 case 0:
4047 /* We simply ignore the field in this case to avoid confusion:
4048 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4049 This means it is likely to be an o32 file, but not for
4050 sure. */
4051 break;
4052 default:
4053 out = stpcpy (out, _(", unknown ABI"));
4054 break;
4055 }
4056
4057 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4058 out = stpcpy (out, ", mdmx");
4059
4060 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4061 out = stpcpy (out, ", mips16");
4062
4063 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4064 out = stpcpy (out, ", micromips");
4065
4066 switch ((e_flags & EF_MIPS_ARCH))
4067 {
d173146d 4068 case EF_MIPS_ARCH_1:
f8c4789c
AM
4069 out = stpcpy (out, ", mips1");
4070 break;
d173146d 4071 case EF_MIPS_ARCH_2:
f8c4789c
AM
4072 out = stpcpy (out, ", mips2");
4073 break;
d173146d 4074 case EF_MIPS_ARCH_3:
f8c4789c
AM
4075 out = stpcpy (out, ", mips3");
4076 break;
d173146d 4077 case EF_MIPS_ARCH_4:
f8c4789c
AM
4078 out = stpcpy (out, ", mips4");
4079 break;
d173146d 4080 case EF_MIPS_ARCH_5:
f8c4789c
AM
4081 out = stpcpy (out, ", mips5");
4082 break;
d173146d 4083 case EF_MIPS_ARCH_32:
f8c4789c
AM
4084 out = stpcpy (out, ", mips32");
4085 break;
d173146d 4086 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
4087 out = stpcpy (out, ", mips32r2");
4088 break;
d173146d 4089 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
4090 out = stpcpy (out, ", mips32r6");
4091 break;
d173146d 4092 case EF_MIPS_ARCH_64:
f8c4789c
AM
4093 out = stpcpy (out, ", mips64");
4094 break;
d173146d 4095 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
4096 out = stpcpy (out, ", mips64r2");
4097 break;
d173146d 4098 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
4099 out = stpcpy (out, ", mips64r6");
4100 break;
4101 default:
4102 out = stpcpy (out, _(", unknown ISA"));
4103 break;
4104 }
4105 return out;
4106}
4107
4108static char *
4109decode_MSP430_machine_flags (char *out, unsigned e_flags)
4110{
4111 out = stpcpy (out, _(": architecture variant: "));
4112 switch (e_flags & EF_MSP430_MACH)
4113 {
4114 case E_MSP430_MACH_MSP430x11:
4115 out = stpcpy (out, "MSP430x11");
4116 break;
4117 case E_MSP430_MACH_MSP430x11x1:
4118 out = stpcpy (out, "MSP430x11x1 ");
4119 break;
4120 case E_MSP430_MACH_MSP430x12:
4121 out = stpcpy (out, "MSP430x12");
4122 break;
4123 case E_MSP430_MACH_MSP430x13:
4124 out = stpcpy (out, "MSP430x13");
4125 break;
4126 case E_MSP430_MACH_MSP430x14:
4127 out = stpcpy (out, "MSP430x14");
4128 break;
4129 case E_MSP430_MACH_MSP430x15:
4130 out = stpcpy (out, "MSP430x15");
4131 break;
4132 case E_MSP430_MACH_MSP430x16:
4133 out = stpcpy (out, "MSP430x16");
4134 break;
4135 case E_MSP430_MACH_MSP430x31:
4136 out = stpcpy (out, "MSP430x31");
4137 break;
4138 case E_MSP430_MACH_MSP430x32:
4139 out = stpcpy (out, "MSP430x32");
4140 break;
4141 case E_MSP430_MACH_MSP430x33:
4142 out = stpcpy (out, "MSP430x33");
4143 break;
4144 case E_MSP430_MACH_MSP430x41:
4145 out = stpcpy (out, "MSP430x41");
4146 break;
4147 case E_MSP430_MACH_MSP430x42:
4148 out = stpcpy (out, "MSP430x42");
4149 break;
4150 case E_MSP430_MACH_MSP430x43:
4151 out = stpcpy (out, "MSP430x43");
4152 break;
4153 case E_MSP430_MACH_MSP430x44:
4154 out = stpcpy (out, "MSP430x44");
4155 break;
4156 case E_MSP430_MACH_MSP430X :
4157 out = stpcpy (out, "MSP430X");
4158 break;
4159 default:
4160 out = stpcpy (out, _(": unknown"));
4161 break;
4162 }
4163
4164 if (e_flags & ~ EF_MSP430_MACH)
4165 out = stpcpy (out, _(": unknown extra flag bits also present"));
4166 return out;
4167}
4168
4169static char *
4170decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
4171{
4172 unsigned abi;
4173 unsigned arch;
4174 unsigned config;
4175 unsigned version;
015dc7e1 4176 bool has_fpu = false;
35c08157
KLC
4177
4178 static const char *ABI_STRINGS[] =
4179 {
4180 "ABI v0", /* use r5 as return register; only used in N1213HC */
4181 "ABI v1", /* use r0 as return register */
4182 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4183 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
4184 "AABI",
4185 "ABI2 FP+"
35c08157
KLC
4186 };
4187 static const char *VER_STRINGS[] =
4188 {
4189 "Andes ELF V1.3 or older",
4190 "Andes ELF V1.3.1",
4191 "Andes ELF V1.4"
4192 };
4193 static const char *ARCH_STRINGS[] =
4194 {
4195 "",
4196 "Andes Star v1.0",
4197 "Andes Star v2.0",
4198 "Andes Star v3.0",
4199 "Andes Star v3.0m"
4200 };
4201
4202 abi = EF_NDS_ABI & e_flags;
4203 arch = EF_NDS_ARCH & e_flags;
4204 config = EF_NDS_INST & e_flags;
4205 version = EF_NDS32_ELF_VERSION & e_flags;
4206
35c08157
KLC
4207 switch (abi)
4208 {
4209 case E_NDS_ABI_V0:
4210 case E_NDS_ABI_V1:
4211 case E_NDS_ABI_V2:
4212 case E_NDS_ABI_V2FP:
4213 case E_NDS_ABI_AABI:
40c7a7cb 4214 case E_NDS_ABI_V2FP_PLUS:
35c08157 4215 /* In case there are holes in the array. */
f8c4789c 4216 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
4217 break;
4218
4219 default:
f8c4789c 4220 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4221 break;
4222 }
4223
4224 switch (version)
4225 {
4226 case E_NDS32_ELF_VER_1_2:
4227 case E_NDS32_ELF_VER_1_3:
4228 case E_NDS32_ELF_VER_1_4:
f8c4789c 4229 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4230 break;
4231
4232 default:
f8c4789c 4233 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4234 break;
4235 }
4236
4237 if (E_NDS_ABI_V0 == abi)
4238 {
4239 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4240 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4241 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4242 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4243 return out;
35c08157
KLC
4244 }
4245
4246 switch (arch)
4247 {
4248 case E_NDS_ARCH_STAR_V1_0:
4249 case E_NDS_ARCH_STAR_V2_0:
4250 case E_NDS_ARCH_STAR_V3_0:
4251 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4252 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4253 break;
4254
4255 default:
f8c4789c 4256 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4257 /* ARCH version determines how the e_flags are interpreted.
4258 If it is unknown, we cannot proceed. */
f8c4789c 4259 return out;
35c08157
KLC
4260 }
4261
4262 /* Newer ABI; Now handle architecture specific flags. */
4263 if (arch == E_NDS_ARCH_STAR_V1_0)
4264 {
4265 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4266 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4267
4268 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4269 out = stpcpy (out, ", MAC");
35c08157
KLC
4270
4271 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4272 out = stpcpy (out, ", DIV");
35c08157
KLC
4273
4274 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4275 out = stpcpy (out, ", 16b");
35c08157
KLC
4276 }
4277 else
4278 {
4279 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4280 {
4281 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4282 out = stpcpy (out, ", [B8]");
35c08157 4283 else
f8c4789c 4284 out = stpcpy (out, ", EX9");
35c08157
KLC
4285 }
4286
4287 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4288 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4289
4290 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4291 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4292
4293 if (config & E_NDS32_HAS_16BIT_INST)
4294 {
4295 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4296 out = stpcpy (out, ", 16b");
35c08157 4297 else
f8c4789c 4298 out = stpcpy (out, ", IFC");
35c08157
KLC
4299 }
4300 }
4301
4302 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4303 out = stpcpy (out, ", PERF1");
35c08157
KLC
4304
4305 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4306 out = stpcpy (out, ", PERF2");
35c08157
KLC
4307
4308 if (config & E_NDS32_HAS_FPU_INST)
4309 {
015dc7e1 4310 has_fpu = true;
f8c4789c 4311 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4312 }
4313
4314 if (config & E_NDS32_HAS_FPU_DP_INST)
4315 {
015dc7e1 4316 has_fpu = true;
f8c4789c 4317 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4318 }
4319
4320 if (config & E_NDS32_HAS_FPU_MAC_INST)
4321 {
015dc7e1 4322 has_fpu = true;
f8c4789c 4323 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4324 }
4325
4326 if (has_fpu)
4327 {
4328 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4329 {
4330 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4331 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4332 break;
4333 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4334 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4335 break;
4336 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4337 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4338 break;
4339 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4340 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4341 break;
4342 }
4343 }
4344
4345 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4346 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4347
4348 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4349 out = stpcpy (out, ", STR");
35c08157
KLC
4350
4351 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4352 out = stpcpy (out, ", 16REG");
35c08157
KLC
4353
4354 if (config & E_NDS32_HAS_VIDEO_INST)
4355 {
4356 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4357 out = stpcpy (out, ", VIDEO");
35c08157 4358 else
f8c4789c 4359 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4360 }
4361
4362 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4363 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4364
4365 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4366 out = stpcpy (out, ", L2C");
4367
4368 return out;
35c08157
KLC
4369}
4370
f8c4789c
AM
4371static char *
4372decode_PARISC_machine_flags (char *out, unsigned e_flags)
4373{
4374 switch (e_flags & EF_PARISC_ARCH)
4375 {
4376 case EFA_PARISC_1_0:
4377 out = stpcpy (out, ", PA-RISC 1.0");
4378 break;
4379 case EFA_PARISC_1_1:
4380 out = stpcpy (out, ", PA-RISC 1.1");
4381 break;
4382 case EFA_PARISC_2_0:
4383 out = stpcpy (out, ", PA-RISC 2.0");
4384 break;
4385 default:
4386 break;
4387 }
4388 if (e_flags & EF_PARISC_TRAPNIL)
4389 out = stpcpy (out, ", trapnil");
4390 if (e_flags & EF_PARISC_EXT)
4391 out = stpcpy (out, ", ext");
4392 if (e_flags & EF_PARISC_LSB)
4393 out = stpcpy (out, ", lsb");
4394 if (e_flags & EF_PARISC_WIDE)
4395 out = stpcpy (out, ", wide");
4396 if (e_flags & EF_PARISC_NO_KABP)
4397 out = stpcpy (out, ", no kabp");
4398 if (e_flags & EF_PARISC_LAZYSWAP)
4399 out = stpcpy (out, ", lazyswap");
4400 return out;
4401}
4402
4403static char *
4404decode_RISCV_machine_flags (char *out, unsigned e_flags)
4405{
4406 if (e_flags & EF_RISCV_RVC)
4407 out = stpcpy (out, ", RVC");
4408
4409 if (e_flags & EF_RISCV_RVE)
4410 out = stpcpy (out, ", RVE");
4411
4412 if (e_flags & EF_RISCV_TSO)
4413 out = stpcpy (out, ", TSO");
4414
4415 switch (e_flags & EF_RISCV_FLOAT_ABI)
4416 {
4417 case EF_RISCV_FLOAT_ABI_SOFT:
4418 out = stpcpy (out, ", soft-float ABI");
4419 break;
4420
4421 case EF_RISCV_FLOAT_ABI_SINGLE:
4422 out = stpcpy (out, ", single-float ABI");
4423 break;
4424
4425 case EF_RISCV_FLOAT_ABI_DOUBLE:
4426 out = stpcpy (out, ", double-float ABI");
4427 break;
4428
4429 case EF_RISCV_FLOAT_ABI_QUAD:
4430 out = stpcpy (out, ", quad-float ABI");
4431 break;
4432 }
4433 return out;
4434}
4435
4436static char *
4437decode_RL78_machine_flags (char *out, unsigned e_flags)
4438{
4439 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4440 {
4441 case E_FLAG_RL78_ANY_CPU:
4442 break;
4443 case E_FLAG_RL78_G10:
4444 out = stpcpy (out, ", G10");
4445 break;
4446 case E_FLAG_RL78_G13:
4447 out = stpcpy (out, ", G13");
4448 break;
4449 case E_FLAG_RL78_G14:
4450 out = stpcpy (out, ", G14");
4451 break;
4452 }
4453 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4454 out = stpcpy (out, ", 64-bit doubles");
4455 return out;
4456}
4457
4458static char *
4459decode_RX_machine_flags (char *out, unsigned e_flags)
4460{
4461 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4462 out = stpcpy (out, ", 64-bit doubles");
4463 if (e_flags & E_FLAG_RX_DSP)
4464 out = stpcpy (out, ", dsp");
4465 if (e_flags & E_FLAG_RX_PID)
4466 out = stpcpy (out, ", pid");
4467 if (e_flags & E_FLAG_RX_ABI)
4468 out = stpcpy (out, ", RX ABI");
4469 if (e_flags & E_FLAG_RX_SINSNS_SET)
4470 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4471 ? ", uses String instructions"
4472 : ", bans String instructions"));
4473 if (e_flags & E_FLAG_RX_V2)
4474 out = stpcpy (out, ", V2");
4475 if (e_flags & E_FLAG_RX_V3)
4476 out = stpcpy (out, ", V3");
4477 return out;
4478}
4479
4480static char *
4481decode_SH_machine_flags (char *out, unsigned e_flags)
4482{
4483 switch ((e_flags & EF_SH_MACH_MASK))
4484 {
4485 case EF_SH1:
4486 out = stpcpy (out, ", sh1");
4487 break;
4488 case EF_SH2:
4489 out = stpcpy (out, ", sh2");
4490 break;
4491 case EF_SH3:
4492 out = stpcpy (out, ", sh3");
4493 break;
4494 case EF_SH_DSP:
4495 out = stpcpy (out, ", sh-dsp");
4496 break;
4497 case EF_SH3_DSP:
4498 out = stpcpy (out, ", sh3-dsp");
4499 break;
4500 case EF_SH4AL_DSP:
4501 out = stpcpy (out, ", sh4al-dsp");
4502 break;
4503 case EF_SH3E:
4504 out = stpcpy (out, ", sh3e");
4505 break;
4506 case EF_SH4:
4507 out = stpcpy (out, ", sh4");
4508 break;
4509 case EF_SH5:
4510 out = stpcpy (out, ", sh5");
4511 break;
4512 case EF_SH2E:
4513 out = stpcpy (out, ", sh2e");
4514 break;
4515 case EF_SH4A:
4516 out = stpcpy (out, ", sh4a");
4517 break;
4518 case EF_SH2A:
4519 out = stpcpy (out, ", sh2a");
4520 break;
4521 case EF_SH4_NOFPU:
4522 out = stpcpy (out, ", sh4-nofpu");
4523 break;
4524 case EF_SH4A_NOFPU:
4525 out = stpcpy (out, ", sh4a-nofpu");
4526 break;
4527 case EF_SH2A_NOFPU:
4528 out = stpcpy (out, ", sh2a-nofpu");
4529 break;
4530 case EF_SH3_NOMMU:
4531 out = stpcpy (out, ", sh3-nommu");
4532 break;
4533 case EF_SH4_NOMMU_NOFPU:
4534 out = stpcpy (out, ", sh4-nommu-nofpu");
4535 break;
4536 case EF_SH2A_SH4_NOFPU:
4537 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4538 break;
4539 case EF_SH2A_SH3_NOFPU:
4540 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4541 break;
4542 case EF_SH2A_SH4:
4543 out = stpcpy (out, ", sh2a-or-sh4");
4544 break;
4545 case EF_SH2A_SH3E:
4546 out = stpcpy (out, ", sh2a-or-sh3e");
4547 break;
4548 default:
4549 out = stpcpy (out, _(", unknown ISA"));
4550 break;
4551 }
4552
4553 if (e_flags & EF_SH_PIC)
4554 out = stpcpy (out, ", pic");
4555
4556 if (e_flags & EF_SH_FDPIC)
4557 out = stpcpy (out, ", fdpic");
4558 return out;
4559}
4560
4561static char *
4562decode_SPARC_machine_flags (char *out, unsigned e_flags)
4563{
4564 if (e_flags & EF_SPARC_32PLUS)
4565 out = stpcpy (out, ", v8+");
4566
4567 if (e_flags & EF_SPARC_SUN_US1)
4568 out = stpcpy (out, ", ultrasparcI");
4569
4570 if (e_flags & EF_SPARC_SUN_US3)
4571 out = stpcpy (out, ", ultrasparcIII");
4572
4573 if (e_flags & EF_SPARC_HAL_R1)
4574 out = stpcpy (out, ", halr1");
4575
4576 if (e_flags & EF_SPARC_LEDATA)
4577 out = stpcpy (out, ", ledata");
4578
4579 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4580 out = stpcpy (out, ", tso");
4581
4582 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4583 out = stpcpy (out, ", pso");
4584
4585 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4586 out = stpcpy (out, ", rmo");
4587 return out;
4588}
4589
4590static char *
4591decode_V800_machine_flags (char *out, unsigned int e_flags)
4592{
4593 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4594 out = stpcpy (out, ", RH850 ABI");
4595
4596 if (e_flags & EF_V800_850E3)
4597 out = stpcpy (out, ", V3 architecture");
4598
4599 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4600 out = stpcpy (out, ", FPU not used");
4601
4602 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4603 out = stpcpy (out, ", regmode: COMMON");
4604
4605 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4606 out = stpcpy (out, ", r4 not used");
4607
4608 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4609 out = stpcpy (out, ", r30 not used");
4610
4611 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4612 out = stpcpy (out, ", r5 not used");
4613
4614 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4615 out = stpcpy (out, ", r2 not used");
4616
4617 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4618 {
4619 switch (e_flags & - e_flags)
4620 {
4621 case EF_RH850_FPU_DOUBLE:
4622 out = stpcpy (out, ", double precision FPU");
4623 break;
4624 case EF_RH850_FPU_SINGLE:
4625 out = stpcpy (out, ", single precision FPU");
4626 break;
4627 case EF_RH850_REGMODE22:
4628 out = stpcpy (out, ", regmode:22");
4629 break;
4630 case EF_RH850_REGMODE32:
4631 out = stpcpy (out, ", regmode:23");
4632 break;
4633 case EF_RH850_GP_FIX:
4634 out = stpcpy (out, ", r4 fixed");
4635 break;
4636 case EF_RH850_GP_NOFIX:
4637 out = stpcpy (out, ", r4 free");
4638 break;
4639 case EF_RH850_EP_FIX:
4640 out = stpcpy (out, ", r30 fixed");
4641 break;
4642 case EF_RH850_EP_NOFIX:
4643 out = stpcpy (out, ", r30 free");
4644 break;
4645 case EF_RH850_TP_FIX:
4646 out = stpcpy (out, ", r5 fixed");
4647 break;
4648 case EF_RH850_TP_NOFIX:
4649 out = stpcpy (out, ", r5 free");
4650 break;
4651 case EF_RH850_REG2_RESERVE:
4652 out = stpcpy (out, ", r2 fixed");
4653 break;
4654 case EF_RH850_REG2_NORESERVE:
4655 out = stpcpy (out, ", r2 free");
4656 break;
4657 default:
4658 break;
4659 }
4660 }
4661 return out;
4662}
4663
4664static char *
4665decode_V850_machine_flags (char *out, unsigned int e_flags)
4666{
4667 switch (e_flags & EF_V850_ARCH)
4668 {
4669 case E_V850E3V5_ARCH:
4670 out = stpcpy (out, ", v850e3v5");
4671 break;
4672 case E_V850E2V3_ARCH:
4673 out = stpcpy (out, ", v850e2v3");
4674 break;
4675 case E_V850E2_ARCH:
4676 out = stpcpy (out, ", v850e2");
4677 break;
4678 case E_V850E1_ARCH:
4679 out = stpcpy (out, ", v850e1");
4680 break;
4681 case E_V850E_ARCH:
4682 out = stpcpy (out, ", v850e");
4683 break;
4684 case E_V850_ARCH:
4685 out = stpcpy (out, ", v850");
4686 break;
4687 default:
4688 out = stpcpy (out, _(", unknown v850 architecture variant"));
4689 break;
4690 }
4691 return out;
4692}
4693
4694static char *
4695decode_Z80_machine_flags (char *out, unsigned int e_flags)
4696{
4697 switch (e_flags & EF_Z80_MACH_MSK)
4698 {
4699 case EF_Z80_MACH_Z80:
4700 out = stpcpy (out, ", Z80");
4701 break;
4702 case EF_Z80_MACH_Z180:
4703 out = stpcpy (out, ", Z180");
4704 break;
4705 case EF_Z80_MACH_R800:
4706 out = stpcpy (out, ", R800");
4707 break;
4708 case EF_Z80_MACH_EZ80_Z80:
4709 out = stpcpy (out, ", EZ80");
4710 break;
4711 case EF_Z80_MACH_EZ80_ADL:
4712 out = stpcpy (out, ", EZ80, ADL");
4713 break;
4714 case EF_Z80_MACH_GBZ80:
4715 out = stpcpy (out, ", GBZ80");
4716 break;
4717 case EF_Z80_MACH_Z80N:
4718 out = stpcpy (out, ", Z80N");
4719 break;
4720 default:
4721 out = stpcpy (out, _(", unknown"));
4722 break;
4723 }
4724 return out;
4725}
4726
4727static char *
4728decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4729{
4730 unsigned char *e_ident = filedata->file_header.e_ident;
4731 unsigned char osabi = e_ident[EI_OSABI];
4732 unsigned char abiversion = e_ident[EI_ABIVERSION];
4733 unsigned int mach;
4734
4735 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4736 it has been deprecated for a while.
4737
4738 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4739 of writing, they use the same flags as HSA v3, so the code below uses that
4740 assumption. */
4741 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4742 return out;
c077c580
SM
4743
4744 mach = e_flags & EF_AMDGPU_MACH;
4745 switch (mach)
4746 {
4747#define AMDGPU_CASE(code, string) \
f8c4789c 4748 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4749 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4750 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4751 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4752 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4753 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4754 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4755 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4756 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4757 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4758 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4759 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4760 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4761 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4762 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4763 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4764 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4765 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4766 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4767 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4768 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4769 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4770 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4771 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4772 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4773 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4774 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4775 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4776 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4777 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4778 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4779 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4780 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4781 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4782 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4783 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4784 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4785 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4786 default:
f8c4789c 4787 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4788 break;
4789#undef AMDGPU_CASE
4790 }
4791
c077c580
SM
4792 e_flags &= ~EF_AMDGPU_MACH;
4793
4794 if ((osabi == ELFOSABI_AMDGPU_HSA
4795 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4796 || osabi != ELFOSABI_AMDGPU_HSA)
4797 {
4798 /* For HSA v3 and other OS ABIs. */
4799 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4800 {
f8c4789c 4801 out = stpcpy (out, ", xnack on");
c077c580
SM
4802 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4803 }
4804
4805 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4806 {
f8c4789c 4807 out = stpcpy (out, ", sramecc on");
c077c580
SM
4808 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4809 }
4810 }
4811 else
4812 {
4813 /* For HSA v4+. */
4814 int xnack, sramecc;
4815
4816 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4817 switch (xnack)
4818 {
4819 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4820 break;
4821
4822 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4823 out = stpcpy (out, ", xnack any");
c077c580
SM
4824 break;
4825
4826 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4827 out = stpcpy (out, ", xnack off");
c077c580
SM
4828 break;
4829
4830 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4831 out = stpcpy (out, ", xnack on");
c077c580
SM
4832 break;
4833
4834 default:
f8c4789c 4835 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4836 break;
4837 }
4838
c077c580
SM
4839 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4840
4841 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4842 switch (sramecc)
4843 {
4844 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4845 break;
4846
4847 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4848 out = stpcpy (out, ", sramecc any");
c077c580
SM
4849 break;
4850
4851 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4852 out = stpcpy (out, ", sramecc off");
c077c580
SM
4853 break;
4854
4855 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4856 out = stpcpy (out, ", sramecc on");
c077c580
SM
4857 break;
4858
4859 default:
f8c4789c 4860 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4861 break;
4862 }
4863
c077c580
SM
4864 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4865 }
4866
4867 if (e_flags != 0)
f8c4789c
AM
4868 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4869 return out;
c077c580
SM
4870}
4871
252b5132 4872static char *
dda8d76d 4873get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4874{
b34976b6 4875 static char buf[1024];
f8c4789c 4876 char *out = buf;
252b5132
RH
4877
4878 buf[0] = '\0';
76da6bbe 4879
252b5132
RH
4880 if (e_flags)
4881 {
4882 switch (e_machine)
4883 {
4884 default:
4885 break;
4886
b5c37946 4887 case EM_ARC_COMPACT3:
f8c4789c 4888 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4889 break;
4890
4891 case EM_ARC_COMPACT3_64:
f8c4789c 4892 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4893 break;
4894
886a2506 4895 case EM_ARC_COMPACT2:
886a2506 4896 case EM_ARC_COMPACT:
f8c4789c
AM
4897 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4898 break;
886a2506 4899
f3485b74 4900 case EM_ARM:
f8c4789c 4901 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4902 break;
76da6bbe 4903
f8c4789c
AM
4904 case EM_AVR:
4905 out = decode_AVR_machine_flags (out, e_flags);
4906 break;
343433df 4907
781303ce 4908 case EM_BLACKFIN:
f8c4789c 4909 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4910 break;
4911
ec2dfb42 4912 case EM_CYGNUS_FRV:
f8c4789c 4913 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4914 break;
ec2dfb42 4915
53c7db4b 4916 case EM_68K:
f8c4789c 4917 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4918 break;
33c63f9d 4919
c077c580 4920 case EM_AMDGPU:
f8c4789c 4921 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4922 break;
4923
153a2776 4924 case EM_CYGNUS_MEP:
f8c4789c 4925 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4926 break;
4927
252b5132
RH
4928 case EM_PPC:
4929 if (e_flags & EF_PPC_EMB)
f8c4789c 4930 out = stpcpy (out, ", emb");
252b5132
RH
4931
4932 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4933 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4934
4935 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4936 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4937 break;
4938
ee67d69a
AM
4939 case EM_PPC64:
4940 if (e_flags & EF_PPC64_ABI)
f8c4789c 4941 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4942 break;
4943
708e2187 4944 case EM_V800:
f8c4789c 4945 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4946 break;
4947
2b0337b0 4948 case EM_V850:
252b5132 4949 case EM_CYGNUS_V850:
f8c4789c 4950 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4951 break;
4952
2b0337b0 4953 case EM_M32R:
252b5132
RH
4954 case EM_CYGNUS_M32R:
4955 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4956 out = stpcpy (out, ", m32r");
252b5132
RH
4957 break;
4958
4959 case EM_MIPS:
4fe85591 4960 case EM_MIPS_RS3_LE:
f8c4789c 4961 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4962 break;
351b4b40 4963
35c08157 4964 case EM_NDS32:
f8c4789c 4965 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4966 break;
4967
fe944acf
FT
4968 case EM_NFP:
4969 switch (EF_NFP_MACH (e_flags))
4970 {
4971 case E_NFP_MACH_3200:
f8c4789c 4972 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4973 break;
4974 case E_NFP_MACH_6000:
f8c4789c 4975 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4976 break;
4977 }
4978 break;
4979
e23eba97 4980 case EM_RISCV:
f8c4789c 4981 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4982 break;
4983
ccde1100 4984 case EM_SH:
f8c4789c 4985 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4986 break;
948f632f 4987
f8c4789c
AM
4988 case EM_OR1K:
4989 if (e_flags & EF_OR1K_NODELAY)
4990 out = stpcpy (out, ", no delay");
4991 break;
57346661 4992
f8c4789c
AM
4993 case EM_BPF:
4994 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4995 break;
b5c37946 4996
351b4b40 4997 case EM_SPARCV9:
f8c4789c 4998 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4999 break;
7d466069 5000
103f02d3 5001 case EM_PARISC:
f8c4789c 5002 out = decode_PARISC_machine_flags (out, e_flags);
30800947 5003 break;
76da6bbe 5004
7d466069 5005 case EM_PJ:
2b0337b0 5006 case EM_PJ_OLD:
7d466069 5007 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 5008 out = stpcpy (out, ", new calling convention");
7d466069
ILT
5009
5010 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 5011 out = stpcpy (out, ", gnu calling convention");
7d466069 5012 break;
4d6ed7c8
NC
5013
5014 case EM_IA_64:
f8c4789c 5015 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 5016 break;
179d3252
JT
5017
5018 case EM_VAX:
5019 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 5020 out = stpcpy (out, ", non-PIC");
179d3252 5021 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 5022 out = stpcpy (out, ", D-Float");
179d3252 5023 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 5024 out = stpcpy (out, ", G-Float");
179d3252 5025 break;
c7927a3c 5026
f8c4789c 5027 case EM_VISIUM:
619ed720 5028 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 5029 out = stpcpy (out, ", mcm");
619ed720 5030 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 5031 out = stpcpy (out, ", mcm24");
619ed720 5032 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 5033 out = stpcpy (out, ", gr6");
619ed720
EB
5034 break;
5035
4046d87a 5036 case EM_RL78:
f8c4789c 5037 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 5038 break;
0b4362b0 5039
c7927a3c 5040 case EM_RX:
f8c4789c 5041 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 5042 break;
55786da2
AK
5043
5044 case EM_S390:
5045 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 5046 out = stpcpy (out, ", highgprs");
d4cb0ea0 5047 break;
40b36596
JM
5048
5049 case EM_TI_C6000:
5050 if ((e_flags & EF_C6000_REL))
f8c4789c 5051 out = stpcpy (out, ", relocatable module");
d4cb0ea0 5052 break;
13761a11 5053
6e712424
PI
5054 case EM_KVX:
5055 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5056 strcat (buf, ", Kalray VLIW kv3-1");
5057 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5058 strcat (buf, ", Kalray VLIW kv3-2");
5059 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5060 strcat (buf, ", Kalray VLIW kv4-1");
5061 else
5062 strcat (buf, ", unknown KVX MPPA");
5063 break;
5064
13761a11 5065 case EM_MSP430:
f8c4789c 5066 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
5067 break;
5068
5069 case EM_Z80:
f8c4789c 5070 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 5071 break;
c4a7e6b5 5072
f8c4789c
AM
5073 case EM_LOONGARCH:
5074 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 5075 break;
252b5132
RH
5076 }
5077 }
5078
5079 return buf;
5080}
5081
252b5132 5082static const char *
dda8d76d 5083get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
5084{
5085 static char buff[32];
5086
5087 switch (osabi)
5088 {
5089 case ELFOSABI_NONE: return "UNIX - System V";
5090 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5091 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 5092 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
5093 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5094 case ELFOSABI_AIX: return "UNIX - AIX";
5095 case ELFOSABI_IRIX: return "UNIX - IRIX";
5096 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5097 case ELFOSABI_TRU64: return "UNIX - TRU64";
5098 case ELFOSABI_MODESTO: return "Novell - Modesto";
5099 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5100 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5101 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 5102 case ELFOSABI_AROS: return "AROS";
11636f9e 5103 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
5104 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5105 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 5106 default:
40b36596 5107 if (osabi >= 64)
dda8d76d 5108 switch (filedata->file_header.e_machine)
40b36596 5109 {
37870be8
SM
5110 case EM_AMDGPU:
5111 switch (osabi)
5112 {
5113 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5114 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5115 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5116 default:
5117 break;
5118 }
5119 break;
5120
40b36596
JM
5121 case EM_ARM:
5122 switch (osabi)
5123 {
5124 case ELFOSABI_ARM: return "ARM";
18a20338 5125 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
5126 default:
5127 break;
5128 }
5129 break;
5130
5131 case EM_MSP430:
5132 case EM_MSP430_OLD:
619ed720 5133 case EM_VISIUM:
40b36596
JM
5134 switch (osabi)
5135 {
5136 case ELFOSABI_STANDALONE: return _("Standalone App");
5137 default:
5138 break;
5139 }
5140 break;
5141
5142 case EM_TI_C6000:
5143 switch (osabi)
5144 {
5145 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5146 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5147 default:
5148 break;
5149 }
5150 break;
5151
5152 default:
5153 break;
5154 }
e9e44622 5155 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
5156 return buff;
5157 }
5158}
5159
a06ea964
NC
5160static const char *
5161get_aarch64_segment_type (unsigned long type)
5162{
5163 switch (type)
5164 {
32ec8896 5165 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 5166 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 5167 default: return NULL;
a06ea964 5168 }
a06ea964
NC
5169}
5170
b294bdf8
MM
5171static const char *
5172get_arm_segment_type (unsigned long type)
5173{
5174 switch (type)
5175 {
32ec8896
NC
5176 case PT_ARM_EXIDX: return "EXIDX";
5177 default: return NULL;
b294bdf8 5178 }
b294bdf8
MM
5179}
5180
b4cbbe8f
AK
5181static const char *
5182get_s390_segment_type (unsigned long type)
5183{
5184 switch (type)
5185 {
5186 case PT_S390_PGSTE: return "S390_PGSTE";
5187 default: return NULL;
5188 }
5189}
5190
d3ba0551
AM
5191static const char *
5192get_mips_segment_type (unsigned long type)
252b5132
RH
5193{
5194 switch (type)
5195 {
32ec8896
NC
5196 case PT_MIPS_REGINFO: return "REGINFO";
5197 case PT_MIPS_RTPROC: return "RTPROC";
5198 case PT_MIPS_OPTIONS: return "OPTIONS";
5199 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5200 default: return NULL;
252b5132 5201 }
252b5132
RH
5202}
5203
103f02d3 5204static const char *
d3ba0551 5205get_parisc_segment_type (unsigned long type)
103f02d3
UD
5206{
5207 switch (type)
5208 {
103f02d3
UD
5209 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5210 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 5211 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 5212 default: return NULL;
103f02d3 5213 }
103f02d3
UD
5214}
5215
4d6ed7c8 5216static const char *
d3ba0551 5217get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
5218{
5219 switch (type)
5220 {
5221 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5222 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5223 default: return NULL;
4d6ed7c8 5224 }
4d6ed7c8
NC
5225}
5226
40b36596
JM
5227static const char *
5228get_tic6x_segment_type (unsigned long type)
5229{
5230 switch (type)
5231 {
32ec8896
NC
5232 case PT_C6000_PHATTR: return "C6000_PHATTR";
5233 default: return NULL;
40b36596 5234 }
40b36596
JM
5235}
5236
fbc95f1e
KC
5237static const char *
5238get_riscv_segment_type (unsigned long type)
5239{
5240 switch (type)
5241 {
5242 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5243 default: return NULL;
5244 }
5245}
5246
df3a023b
AM
5247static const char *
5248get_hpux_segment_type (unsigned long type, unsigned e_machine)
5249{
5250 if (e_machine == EM_PARISC)
5251 switch (type)
5252 {
5253 case PT_HP_TLS: return "HP_TLS";
5254 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5255 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5256 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5257 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5258 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5259 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5260 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5261 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5262 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5263 case PT_HP_PARALLEL: return "HP_PARALLEL";
5264 case PT_HP_FASTBIND: return "HP_FASTBIND";
5265 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5266 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5267 case PT_HP_STACK: return "HP_STACK";
5268 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5269 default: return NULL;
5270 }
5271
5272 if (e_machine == EM_IA_64)
5273 switch (type)
5274 {
5275 case PT_HP_TLS: return "HP_TLS";
5276 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5277 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5278 case PT_IA_64_HP_STACK: return "HP_STACK";
5279 default: return NULL;
5280 }
5281
5282 return NULL;
5283}
5284
5522f910
NC
5285static const char *
5286get_solaris_segment_type (unsigned long type)
5287{
5288 switch (type)
5289 {
5290 case 0x6464e550: return "PT_SUNW_UNWIND";
5291 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5292 case 0x6ffffff7: return "PT_LOSUNW";
5293 case 0x6ffffffa: return "PT_SUNWBSS";
5294 case 0x6ffffffb: return "PT_SUNWSTACK";
5295 case 0x6ffffffc: return "PT_SUNWDTRACE";
5296 case 0x6ffffffd: return "PT_SUNWCAP";
5297 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5298 default: return NULL;
5522f910
NC
5299 }
5300}
5301
252b5132 5302static const char *
dda8d76d 5303get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5304{
b34976b6 5305 static char buff[32];
252b5132
RH
5306
5307 switch (p_type)
5308 {
b34976b6
AM
5309 case PT_NULL: return "NULL";
5310 case PT_LOAD: return "LOAD";
252b5132 5311 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5312 case PT_INTERP: return "INTERP";
5313 case PT_NOTE: return "NOTE";
5314 case PT_SHLIB: return "SHLIB";
5315 case PT_PHDR: return "PHDR";
13ae64f3 5316 case PT_TLS: return "TLS";
32ec8896 5317 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5318 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5319 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5320 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5321 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5322
80251d41 5323 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5324 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5325 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5326 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
d86205c3 5327 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
3eba3ef3 5328 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5329
252b5132 5330 default:
df3a023b 5331 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5332 {
2cf0635d 5333 const char * result;
103f02d3 5334
dda8d76d 5335 switch (filedata->file_header.e_machine)
252b5132 5336 {
a06ea964
NC
5337 case EM_AARCH64:
5338 result = get_aarch64_segment_type (p_type);
5339 break;
b294bdf8
MM
5340 case EM_ARM:
5341 result = get_arm_segment_type (p_type);
5342 break;
252b5132 5343 case EM_MIPS:
4fe85591 5344 case EM_MIPS_RS3_LE:
252b5132
RH
5345 result = get_mips_segment_type (p_type);
5346 break;
103f02d3
UD
5347 case EM_PARISC:
5348 result = get_parisc_segment_type (p_type);
5349 break;
4d6ed7c8
NC
5350 case EM_IA_64:
5351 result = get_ia64_segment_type (p_type);
5352 break;
40b36596
JM
5353 case EM_TI_C6000:
5354 result = get_tic6x_segment_type (p_type);
5355 break;
b4cbbe8f
AK
5356 case EM_S390:
5357 case EM_S390_OLD:
5358 result = get_s390_segment_type (p_type);
5359 break;
fbc95f1e
KC
5360 case EM_RISCV:
5361 result = get_riscv_segment_type (p_type);
5362 break;
252b5132
RH
5363 default:
5364 result = NULL;
5365 break;
5366 }
103f02d3 5367
252b5132
RH
5368 if (result != NULL)
5369 return result;
103f02d3 5370
1a9ccd70 5371 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5372 }
5373 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5374 {
df3a023b 5375 const char * result = NULL;
103f02d3 5376
df3a023b 5377 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5378 {
df3a023b
AM
5379 case ELFOSABI_GNU:
5380 case ELFOSABI_FREEBSD:
5381 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5382 {
5383 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5384 result = buff;
5385 }
103f02d3 5386 break;
df3a023b
AM
5387 case ELFOSABI_HPUX:
5388 result = get_hpux_segment_type (p_type,
5389 filedata->file_header.e_machine);
5390 break;
5391 case ELFOSABI_SOLARIS:
5392 result = get_solaris_segment_type (p_type);
00428cca 5393 break;
103f02d3 5394 default:
103f02d3
UD
5395 break;
5396 }
103f02d3
UD
5397 if (result != NULL)
5398 return result;
5399
1a9ccd70 5400 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5401 }
252b5132 5402 else
e9e44622 5403 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5404
5405 return buff;
5406 }
5407}
5408
53a346d8
CZ
5409static const char *
5410get_arc_section_type_name (unsigned int sh_type)
5411{
5412 switch (sh_type)
5413 {
5414 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5415 default:
5416 break;
5417 }
5418 return NULL;
5419}
5420
252b5132 5421static const char *
d3ba0551 5422get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5423{
5424 switch (sh_type)
5425 {
b34976b6
AM
5426 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5427 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5428 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5429 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5430 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5431 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5432 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5433 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5434 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5435 case SHT_MIPS_RELD: return "MIPS_RELD";
5436 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5437 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5438 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5439 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5440 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5441 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5442 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5443 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5444 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5445 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5446 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5447 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5448 case SHT_MIPS_LINE: return "MIPS_LINE";
5449 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5450 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5451 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5452 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5453 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5454 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5455 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5456 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5457 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5458 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5459 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5460 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5461 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5462 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5463 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5464 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5465 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5466 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5467 default:
5468 break;
5469 }
5470 return NULL;
5471}
5472
103f02d3 5473static const char *
d3ba0551 5474get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5475{
5476 switch (sh_type)
5477 {
5478 case SHT_PARISC_EXT: return "PARISC_EXT";
5479 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5480 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5481 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5482 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5483 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5484 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5485 default: return NULL;
103f02d3 5486 }
103f02d3
UD
5487}
5488
4d6ed7c8 5489static const char *
dda8d76d 5490get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5491{
18bd398b 5492 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5493 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5494 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5495
4d6ed7c8
NC
5496 switch (sh_type)
5497 {
148b93f2
NC
5498 case SHT_IA_64_EXT: return "IA_64_EXT";
5499 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5500 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5501 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5502 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5503 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5504 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5505 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5506 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5507 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5508 default:
5509 break;
5510 }
5511 return NULL;
5512}
5513
d2b2c203
DJ
5514static const char *
5515get_x86_64_section_type_name (unsigned int sh_type)
5516{
5517 switch (sh_type)
5518 {
5519 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5520 default: return NULL;
d2b2c203 5521 }
d2b2c203
DJ
5522}
5523
a06ea964
NC
5524static const char *
5525get_aarch64_section_type_name (unsigned int sh_type)
5526{
5527 switch (sh_type)
5528 {
32ec8896
NC
5529 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5530 default: return NULL;
a06ea964 5531 }
a06ea964
NC
5532}
5533
40a18ebd
NC
5534static const char *
5535get_arm_section_type_name (unsigned int sh_type)
5536{
5537 switch (sh_type)
5538 {
7f6fed87
NC
5539 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5540 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5541 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5542 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5543 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5544 default: return NULL;
40a18ebd 5545 }
40a18ebd
NC
5546}
5547
40b36596
JM
5548static const char *
5549get_tic6x_section_type_name (unsigned int sh_type)
5550{
5551 switch (sh_type)
5552 {
32ec8896
NC
5553 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5554 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5555 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5556 case SHT_TI_ICODE: return "TI_ICODE";
5557 case SHT_TI_XREF: return "TI_XREF";
5558 case SHT_TI_HANDLER: return "TI_HANDLER";
5559 case SHT_TI_INITINFO: return "TI_INITINFO";
5560 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5561 default: return NULL;
40b36596 5562 }
40b36596
JM
5563}
5564
13761a11 5565static const char *
b0191216 5566get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5567{
5568 switch (sh_type)
5569 {
32ec8896
NC
5570 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5571 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5572 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5573 default: return NULL;
13761a11
NC
5574 }
5575}
5576
fe944acf
FT
5577static const char *
5578get_nfp_section_type_name (unsigned int sh_type)
5579{
5580 switch (sh_type)
5581 {
5582 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5583 case SHT_NFP_INITREG: return "NFP_INITREG";
5584 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5585 default: return NULL;
5586 }
5587}
5588
685080f2
NC
5589static const char *
5590get_v850_section_type_name (unsigned int sh_type)
5591{
5592 switch (sh_type)
5593 {
32ec8896
NC
5594 case SHT_V850_SCOMMON: return "V850 Small Common";
5595 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5596 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5597 case SHT_RENESAS_IOP: return "RENESAS IOP";
5598 case SHT_RENESAS_INFO: return "RENESAS INFO";
5599 default: return NULL;
685080f2
NC
5600 }
5601}
5602
2dc8dd17
JW
5603static const char *
5604get_riscv_section_type_name (unsigned int sh_type)
5605{
5606 switch (sh_type)
5607 {
5608 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5609 default: return NULL;
5610 }
5611}
5612
0861f561
CQ
5613static const char *
5614get_csky_section_type_name (unsigned int sh_type)
5615{
5616 switch (sh_type)
5617 {
5618 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5619 default: return NULL;
5620 }
5621}
5622
252b5132 5623static const char *
dda8d76d 5624get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5625{
b34976b6 5626 static char buff[32];
9fb71ee4 5627 const char * result;
252b5132
RH
5628
5629 switch (sh_type)
5630 {
5631 case SHT_NULL: return "NULL";
5632 case SHT_PROGBITS: return "PROGBITS";
5633 case SHT_SYMTAB: return "SYMTAB";
5634 case SHT_STRTAB: return "STRTAB";
5635 case SHT_RELA: return "RELA";
5636 case SHT_HASH: return "HASH";
5637 case SHT_DYNAMIC: return "DYNAMIC";
5638 case SHT_NOTE: return "NOTE";
5639 case SHT_NOBITS: return "NOBITS";
5640 case SHT_REL: return "REL";
5641 case SHT_SHLIB: return "SHLIB";
5642 case SHT_DYNSYM: return "DYNSYM";
8e8d0b63 5643 /* 12 and 13 are not defined. */
d1133906
NC
5644 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5645 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5646 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586 5647 case SHT_GROUP: return "GROUP";
67ce483b 5648 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
8e8d0b63
NC
5649 case SHT_RELR: return "RELR";
5650 /* End of generic section types. */
5651
5652 /* OS specific section types: */
252b5132
RH
5653 case SHT_GNU_verdef: return "VERDEF";
5654 case SHT_GNU_verneed: return "VERNEED";
5655 case SHT_GNU_versym: return "VERSYM";
8e8d0b63 5656 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
b34976b6 5657 case 0x6ffffff0: return "VERSYM";
8e8d0b63
NC
5658 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5659 case SHT_GNU_HASH: return "GNU_HASH";
5660 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
b34976b6 5661 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5662 case 0x7ffffffd: return "AUXILIARY";
5663 case 0x7fffffff: return "FILTER";
5664
5665 default:
5666 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5667 {
dda8d76d 5668 switch (filedata->file_header.e_machine)
252b5132 5669 {
53a346d8
CZ
5670 case EM_ARC:
5671 case EM_ARC_COMPACT:
5672 case EM_ARC_COMPACT2:
b5c37946
SJ
5673 case EM_ARC_COMPACT3:
5674 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5675 result = get_arc_section_type_name (sh_type);
5676 break;
252b5132 5677 case EM_MIPS:
4fe85591 5678 case EM_MIPS_RS3_LE:
252b5132
RH
5679 result = get_mips_section_type_name (sh_type);
5680 break;
103f02d3
UD
5681 case EM_PARISC:
5682 result = get_parisc_section_type_name (sh_type);
5683 break;
4d6ed7c8 5684 case EM_IA_64:
dda8d76d 5685 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5686 break;
d2b2c203 5687 case EM_X86_64:
8a9036a4 5688 case EM_L1OM:
7a9068fe 5689 case EM_K1OM:
d2b2c203
DJ
5690 result = get_x86_64_section_type_name (sh_type);
5691 break;
a06ea964
NC
5692 case EM_AARCH64:
5693 result = get_aarch64_section_type_name (sh_type);
5694 break;
40a18ebd
NC
5695 case EM_ARM:
5696 result = get_arm_section_type_name (sh_type);
5697 break;
40b36596
JM
5698 case EM_TI_C6000:
5699 result = get_tic6x_section_type_name (sh_type);
5700 break;
13761a11 5701 case EM_MSP430:
b0191216 5702 result = get_msp430_section_type_name (sh_type);
13761a11 5703 break;
fe944acf
FT
5704 case EM_NFP:
5705 result = get_nfp_section_type_name (sh_type);
5706 break;
685080f2
NC
5707 case EM_V800:
5708 case EM_V850:
5709 case EM_CYGNUS_V850:
5710 result = get_v850_section_type_name (sh_type);
5711 break;
2dc8dd17
JW
5712 case EM_RISCV:
5713 result = get_riscv_section_type_name (sh_type);
5714 break;
0861f561
CQ
5715 case EM_CSKY:
5716 result = get_csky_section_type_name (sh_type);
5717 break;
252b5132
RH
5718 default:
5719 result = NULL;
5720 break;
5721 }
5722
5723 if (result != NULL)
5724 return result;
5725
9fb71ee4 5726 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5727 }
5728 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5729 {
dda8d76d 5730 switch (filedata->file_header.e_machine)
148b93f2
NC
5731 {
5732 case EM_IA_64:
dda8d76d 5733 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5734 break;
5735 default:
dda8d76d 5736 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5737 result = get_solaris_section_type (sh_type);
5738 else
1b4b80bf
NC
5739 {
5740 switch (sh_type)
5741 {
5742 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5743 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5744 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5745 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5746 default:
5747 result = NULL;
5748 break;
5749 }
5750 }
148b93f2
NC
5751 break;
5752 }
5753
5754 if (result != NULL)
5755 return result;
5756
9fb71ee4 5757 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5758 }
252b5132 5759 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5760 {
dda8d76d 5761 switch (filedata->file_header.e_machine)
685080f2
NC
5762 {
5763 case EM_V800:
5764 case EM_V850:
5765 case EM_CYGNUS_V850:
9fb71ee4 5766 result = get_v850_section_type_name (sh_type);
a9fb83be 5767 break;
685080f2 5768 default:
9fb71ee4 5769 result = NULL;
685080f2
NC
5770 break;
5771 }
5772
9fb71ee4
NC
5773 if (result != NULL)
5774 return result;
5775
5776 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5777 }
252b5132 5778 else
a7dbfd1c
NC
5779 /* This message is probably going to be displayed in a 15
5780 character wide field, so put the hex value first. */
5781 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5782
252b5132
RH
5783 return buff;
5784 }
5785}
5786
79bc120c
NC
5787enum long_option_values
5788{
5789 OPTION_DEBUG_DUMP = 512,
5790 OPTION_DYN_SYMS,
0f03783c 5791 OPTION_LTO_SYMS,
79bc120c
NC
5792 OPTION_DWARF_DEPTH,
5793 OPTION_DWARF_START,
5794 OPTION_DWARF_CHECK,
5795 OPTION_CTF_DUMP,
5796 OPTION_CTF_PARENT,
5797 OPTION_CTF_SYMBOLS,
5798 OPTION_CTF_STRINGS,
42b6953b 5799 OPTION_SFRAME_DUMP,
79bc120c
NC
5800 OPTION_WITH_SYMBOL_VERSIONS,
5801 OPTION_RECURSE_LIMIT,
5802 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5803 OPTION_NO_DEMANGLING,
b6ac461a 5804 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5805 OPTION_SYM_BASE
79bc120c 5806};
2979dc34 5807
85b1c36d 5808static struct option options[] =
252b5132 5809{
79bc120c
NC
5810 /* Note - This table is alpha-sorted on the 'val'
5811 field in order to make adding new options easier. */
5812 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5813 {"all", no_argument, 0, 'a'},
79bc120c
NC
5814 {"demangle", optional_argument, 0, 'C'},
5815 {"archive-index", no_argument, 0, 'c'},
5816 {"use-dynamic", no_argument, 0, 'D'},
5817 {"dynamic", no_argument, 0, 'd'},
b34976b6 5818 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5819 {"section-groups", no_argument, 0, 'g'},
5820 {"help", no_argument, 0, 'H'},
5821 {"file-header", no_argument, 0, 'h'},
b34976b6 5822 {"histogram", no_argument, 0, 'I'},
8e8d0b63 5823 {"display-section", required_argument, 0, 'j'},
79bc120c
NC
5824 {"lint", no_argument, 0, 'L'},
5825 {"enable-checks", no_argument, 0, 'L'},
5826 {"program-headers", no_argument, 0, 'l'},
b34976b6 5827 {"segments", no_argument, 0, 'l'},
595cf52e 5828 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5829 {"notes", no_argument, 0, 'n'},
ca0e11aa 5830 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5831 {"string-dump", required_argument, 0, 'p'},
5832 {"relocated-dump", required_argument, 0, 'R'},
5833 {"relocs", no_argument, 0, 'r'},
5834 {"section-headers", no_argument, 0, 'S'},
5835 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5836 {"symbols", no_argument, 0, 's'},
5837 {"syms", no_argument, 0, 's'},
79bc120c
NC
5838 {"silent-truncation",no_argument, 0, 'T'},
5839 {"section-details", no_argument, 0, 't'},
b3aa80b4 5840 {"unicode", required_argument, NULL, 'U'},
09c11c86 5841 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5842 {"version-info", no_argument, 0, 'V'},
5843 {"version", no_argument, 0, 'v'},
5844 {"wide", no_argument, 0, 'W'},
b6ac461a 5845 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5846 {"hex-dump", required_argument, 0, 'x'},
0e602686 5847 {"decompress", no_argument, 0, 'z'},
252b5132 5848
79bc120c 5849 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5850 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5851 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5852 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5853 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5854 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5855 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5856 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5857 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5858 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5859 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5860#ifdef ENABLE_LIBCTF
d344b407 5861 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5862 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5863 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5864 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5865#endif
42b6953b 5866 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5867 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5868
b34976b6 5869 {0, no_argument, 0, 0}
252b5132
RH
5870};
5871
5872static void
2cf0635d 5873usage (FILE * stream)
252b5132 5874{
92f01d61
JM
5875 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5876 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5877 fprintf (stream, _(" Options are:\n"));
5878 fprintf (stream, _("\
5879 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5880 fprintf (stream, _("\
5881 -h --file-header Display the ELF file header\n"));
5882 fprintf (stream, _("\
5883 -l --program-headers Display the program headers\n"));
5884 fprintf (stream, _("\
5885 --segments An alias for --program-headers\n"));
5886 fprintf (stream, _("\
5887 -S --section-headers Display the sections' header\n"));
5888 fprintf (stream, _("\
5889 --sections An alias for --section-headers\n"));
5890 fprintf (stream, _("\
5891 -g --section-groups Display the section groups\n"));
5892 fprintf (stream, _("\
5893 -t --section-details Display the section details\n"));
5894 fprintf (stream, _("\
5895 -e --headers Equivalent to: -h -l -S\n"));
5896 fprintf (stream, _("\
5897 -s --syms Display the symbol table\n"));
5898 fprintf (stream, _("\
5899 --symbols An alias for --syms\n"));
5900 fprintf (stream, _("\
5901 --dyn-syms Display the dynamic symbol table\n"));
5902 fprintf (stream, _("\
5903 --lto-syms Display LTO symbol tables\n"));
5904 fprintf (stream, _("\
047c3dbf
NL
5905 --sym-base=[0|8|10|16] \n\
5906 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5907 mixed (the default), octal, decimal, hexadecimal.\n"));
5908 fprintf (stream, _("\
0d646226
AM
5909 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5910 display_demangler_styles (stream, _("\
5911 STYLE can be "));
d6249f5f
AM
5912 fprintf (stream, _("\
5913 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5914 fprintf (stream, _("\
5915 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5916 fprintf (stream, _("\
5917 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5918 fprintf (stream, _("\
5919 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5920 Display unicode characters as determined by the current locale\n\
5921 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5922 escape sequences, or treat them as invalid and display as\n\
5923 \"{hex sequences}\"\n"));
d6249f5f 5924 fprintf (stream, _("\
b6ac461a
NC
5925 -X --extra-sym-info Display extra information when showing symbols\n"));
5926 fprintf (stream, _("\
5927 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5928 fprintf (stream, _("\
5929 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5930 fprintf (stream, _("\
5931 -r --relocs Display the relocations (if present)\n"));
5932 fprintf (stream, _("\
5933 -u --unwind Display the unwind info (if present)\n"));
5934 fprintf (stream, _("\
5935 -d --dynamic Display the dynamic section (if present)\n"));
5936 fprintf (stream, _("\
5937 -V --version-info Display the version sections (if present)\n"));
5938 fprintf (stream, _("\
5939 -A --arch-specific Display architecture specific information (if any)\n"));
5940 fprintf (stream, _("\
5941 -c --archive-index Display the symbol/file index in an archive\n"));
5942 fprintf (stream, _("\
5943 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5944 fprintf (stream, _("\
5945 -L --lint|--enable-checks\n\
5946 Display warning messages for possible problems\n"));
5947 fprintf (stream, _("\
09c11c86 5948 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5949 Dump the contents of section <number|name> as bytes\n"));
5950 fprintf (stream, _("\
09c11c86 5951 -p --string-dump=<number|name>\n\
d6249f5f
AM
5952 Dump the contents of section <number|name> as strings\n"));
5953 fprintf (stream, _("\
cf13d699 5954 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5955 Dump the relocated contents of section <number|name>\n"));
5956 fprintf (stream, _("\
5957 -z --decompress Decompress section before dumping it\n"));
8e8d0b63
NC
5958 fprintf (stream, _("\n\
5959 -j --display-section=<name|number>\n\
5960 Display the contents of the indicated section. Can be repeated\n"));
d6249f5f
AM
5961 fprintf (stream, _("\
5962 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5963 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5964 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5965 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5966 U/=trace_info]\n\
5967 Display the contents of DWARF debug sections\n"));
5968 fprintf (stream, _("\
5969 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5970 debuginfo files\n"));
5971 fprintf (stream, _("\
5972 -P --process-links Display the contents of non-debug sections in separate\n\
5973 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5974#if DEFAULT_FOR_FOLLOW_LINKS
5975 fprintf (stream, _("\
d6249f5f
AM
5976 -wK --debug-dump=follow-links\n\
5977 Follow links to separate debug info files (default)\n"));
5978 fprintf (stream, _("\
5979 -wN --debug-dump=no-follow-links\n\
5980 Do not follow links to separate debug info files\n"));
c46b7066
NC
5981#else
5982 fprintf (stream, _("\
d6249f5f
AM
5983 -wK --debug-dump=follow-links\n\
5984 Follow links to separate debug info files\n"));
5985 fprintf (stream, _("\
5986 -wN --debug-dump=no-follow-links\n\
5987 Do not follow links to separate debug info files\n\
5988 (default)\n"));
bed566bb
NC
5989#endif
5990#if HAVE_LIBDEBUGINFOD
5991 fprintf (stream, _("\
5992 -wD --debug-dump=use-debuginfod\n\
5993 When following links, also query debuginfod servers (default)\n"));
5994 fprintf (stream, _("\
5995 -wE --debug-dump=do-not-use-debuginfod\n\
5996 When following links, do not query debuginfod servers\n"));
c46b7066 5997#endif
fd2f0033 5998 fprintf (stream, _("\
d6249f5f
AM
5999 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6000 fprintf (stream, _("\
6001 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 6002#ifdef ENABLE_LIBCTF
7d9813f1 6003 fprintf (stream, _("\
d6249f5f
AM
6004 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6005 fprintf (stream, _("\
80b56fad 6006 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 6007 fprintf (stream, _("\
7d9813f1 6008 --ctf-symbols=<number|name>\n\
d6249f5f
AM
6009 Use section <number|name> as the CTF external symtab\n"));
6010 fprintf (stream, _("\
7d9813f1 6011 --ctf-strings=<number|name>\n\
d6249f5f 6012 Use section <number|name> as the CTF external strtab\n"));
094e34f2 6013#endif
42b6953b
IB
6014 fprintf (stream, _("\
6015 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 6016
252b5132 6017#ifdef SUPPORT_DISASSEMBLY
92f01d61 6018 fprintf (stream, _("\
09c11c86
NC
6019 -i --instruction-dump=<number|name>\n\
6020 Disassemble the contents of section <number|name>\n"));
252b5132 6021#endif
92f01d61 6022 fprintf (stream, _("\
d6249f5f
AM
6023 -I --histogram Display histogram of bucket list lengths\n"));
6024 fprintf (stream, _("\
6025 -W --wide Allow output width to exceed 80 characters\n"));
6026 fprintf (stream, _("\
6027 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6028 fprintf (stream, _("\
6029 @<file> Read options from <file>\n"));
6030 fprintf (stream, _("\
6031 -H --help Display this information\n"));
6032 fprintf (stream, _("\
8b53311e 6033 -v --version Display the version number of readelf\n"));
1118d252 6034
92f01d61
JM
6035 if (REPORT_BUGS_TO[0] && stream == stdout)
6036 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 6037
92f01d61 6038 exit (stream == stdout ? 0 : 1);
252b5132
RH
6039}
6040
18bd398b
NC
6041/* Record the fact that the user wants the contents of section number
6042 SECTION to be displayed using the method(s) encoded as flags bits
6043 in TYPE. Note, TYPE can be zero if we are creating the array for
6044 the first time. */
6045
252b5132 6046static void
6431e409
AM
6047request_dump_bynumber (struct dump_data *dumpdata,
6048 unsigned int section, dump_type type)
252b5132 6049{
6431e409 6050 if (section >= dumpdata->num_dump_sects)
252b5132 6051 {
2cf0635d 6052 dump_type * new_dump_sects;
252b5132 6053
3f5e193b 6054 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 6055 sizeof (* new_dump_sects));
252b5132
RH
6056
6057 if (new_dump_sects == NULL)
591a748a 6058 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
6059 else
6060 {
6431e409 6061 if (dumpdata->dump_sects)
21b65bac
NC
6062 {
6063 /* Copy current flag settings. */
6431e409
AM
6064 memcpy (new_dump_sects, dumpdata->dump_sects,
6065 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 6066
6431e409 6067 free (dumpdata->dump_sects);
21b65bac 6068 }
252b5132 6069
6431e409
AM
6070 dumpdata->dump_sects = new_dump_sects;
6071 dumpdata->num_dump_sects = section + 1;
252b5132
RH
6072 }
6073 }
6074
6431e409
AM
6075 if (dumpdata->dump_sects)
6076 dumpdata->dump_sects[section] |= type;
252b5132
RH
6077}
6078
aef1f6d0
DJ
6079/* Request a dump by section name. */
6080
6081static void
2cf0635d 6082request_dump_byname (const char * section, dump_type type)
aef1f6d0 6083{
2cf0635d 6084 struct dump_list_entry * new_request;
aef1f6d0 6085
3f5e193b
NC
6086 new_request = (struct dump_list_entry *)
6087 malloc (sizeof (struct dump_list_entry));
aef1f6d0 6088 if (!new_request)
591a748a 6089 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6090
6091 new_request->name = strdup (section);
6092 if (!new_request->name)
591a748a 6093 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6094
6095 new_request->type = type;
6096
6097 new_request->next = dump_sects_byname;
6098 dump_sects_byname = new_request;
6099}
6100
cf13d699 6101static inline void
6431e409 6102request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
6103{
6104 int section;
6105 char * cp;
6106
015dc7e1 6107 do_dump = true;
cf13d699
NC
6108 section = strtoul (optarg, & cp, 0);
6109
6110 if (! *cp && section >= 0)
6431e409 6111 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
6112 else
6113 request_dump_byname (optarg, type);
6114}
6115
252b5132 6116static void
6431e409 6117parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
6118{
6119 int c;
6120
6121 if (argc < 2)
92f01d61 6122 usage (stderr);
252b5132
RH
6123
6124 while ((c = getopt_long
8e8d0b63 6125 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 6126 {
252b5132
RH
6127 switch (c)
6128 {
6129 case 0:
6130 /* Long options. */
6131 break;
6132 case 'H':
92f01d61 6133 usage (stdout);
252b5132
RH
6134 break;
6135
6136 case 'a':
015dc7e1
AM
6137 do_syms = true;
6138 do_reloc = true;
6139 do_unwind = true;
6140 do_dynamic = true;
6141 do_header = true;
6142 do_sections = true;
6143 do_section_groups = true;
6144 do_segments = true;
6145 do_version = true;
6146 do_histogram = true;
6147 do_arch = true;
6148 do_notes = true;
252b5132 6149 break;
79bc120c 6150
f5842774 6151 case 'g':
015dc7e1 6152 do_section_groups = true;
f5842774 6153 break;
5477e8a0 6154 case 't':
595cf52e 6155 case 'N':
015dc7e1
AM
6156 do_sections = true;
6157 do_section_details = true;
595cf52e 6158 break;
252b5132 6159 case 'e':
015dc7e1
AM
6160 do_header = true;
6161 do_sections = true;
6162 do_segments = true;
252b5132 6163 break;
a952a375 6164 case 'A':
015dc7e1 6165 do_arch = true;
a952a375 6166 break;
252b5132 6167 case 'D':
015dc7e1 6168 do_using_dynamic = true;
252b5132
RH
6169 break;
6170 case 'r':
015dc7e1 6171 do_reloc = true;
252b5132 6172 break;
4d6ed7c8 6173 case 'u':
015dc7e1 6174 do_unwind = true;
4d6ed7c8 6175 break;
252b5132 6176 case 'h':
015dc7e1 6177 do_header = true;
252b5132
RH
6178 break;
6179 case 'l':
015dc7e1 6180 do_segments = true;
252b5132
RH
6181 break;
6182 case 's':
015dc7e1 6183 do_syms = true;
252b5132
RH
6184 break;
6185 case 'S':
015dc7e1 6186 do_sections = true;
252b5132
RH
6187 break;
6188 case 'd':
015dc7e1 6189 do_dynamic = true;
252b5132 6190 break;
a952a375 6191 case 'I':
015dc7e1 6192 do_histogram = true;
a952a375 6193 break;
779fe533 6194 case 'n':
015dc7e1 6195 do_notes = true;
779fe533 6196 break;
4145f1d5 6197 case 'c':
015dc7e1 6198 do_archive_index = true;
4145f1d5 6199 break;
1b513401 6200 case 'L':
015dc7e1 6201 do_checks = true;
1b513401 6202 break;
ca0e11aa 6203 case 'P':
015dc7e1
AM
6204 process_links = true;
6205 do_follow_links = true;
e1dbfc17 6206 dump_any_debugging = true;
ca0e11aa 6207 break;
8e8d0b63
NC
6208 case 'j':
6209 request_dump (dumpdata, AUTO_DUMP);
6210 break;
252b5132 6211 case 'x':
6431e409 6212 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 6213 break;
09c11c86 6214 case 'p':
6431e409 6215 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
6216 break;
6217 case 'R':
6431e409 6218 request_dump (dumpdata, RELOC_DUMP);
09c11c86 6219 break;
0e602686 6220 case 'z':
015dc7e1 6221 decompress_dumps = true;
0e602686 6222 break;
252b5132 6223 case 'w':
0f03783c 6224 if (optarg == NULL)
613ff48b 6225 {
015dc7e1 6226 do_debugging = true;
94585d6d
NC
6227 do_dump = true;
6228 dump_any_debugging = true;
613ff48b
CC
6229 dwarf_select_sections_all ();
6230 }
252b5132
RH
6231 else
6232 {
015dc7e1 6233 do_debugging = false;
94585d6d
NC
6234 if (dwarf_select_sections_by_letters (optarg))
6235 {
6236 do_dump = true;
6237 dump_any_debugging = true;
6238 }
252b5132
RH
6239 }
6240 break;
2979dc34 6241 case OPTION_DEBUG_DUMP:
0f03783c 6242 if (optarg == NULL)
d6249f5f 6243 {
94585d6d 6244 do_dump = true;
d6249f5f 6245 do_debugging = true;
94585d6d 6246 dump_any_debugging = true;
d6249f5f
AM
6247 dwarf_select_sections_all ();
6248 }
2979dc34
JJ
6249 else
6250 {
015dc7e1 6251 do_debugging = false;
94585d6d
NC
6252 if (dwarf_select_sections_by_names (optarg))
6253 {
6254 do_dump = true;
6255 dump_any_debugging = true;
6256 }
2979dc34
JJ
6257 }
6258 break;
fd2f0033
TT
6259 case OPTION_DWARF_DEPTH:
6260 {
6261 char *cp;
6262
6263 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6264 }
6265 break;
6266 case OPTION_DWARF_START:
6267 {
6268 char *cp;
6269
6270 dwarf_start_die = strtoul (optarg, & cp, 0);
6271 }
6272 break;
4723351a 6273 case OPTION_DWARF_CHECK:
015dc7e1 6274 dwarf_check = true;
4723351a 6275 break;
7d9813f1 6276 case OPTION_CTF_DUMP:
015dc7e1 6277 do_ctf = true;
6431e409 6278 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6279 break;
6280 case OPTION_CTF_SYMBOLS:
df16e041 6281 free (dump_ctf_symtab_name);
7d9813f1
NA
6282 dump_ctf_symtab_name = strdup (optarg);
6283 break;
6284 case OPTION_CTF_STRINGS:
df16e041 6285 free (dump_ctf_strtab_name);
7d9813f1
NA
6286 dump_ctf_strtab_name = strdup (optarg);
6287 break;
6288 case OPTION_CTF_PARENT:
df16e041 6289 free (dump_ctf_parent_name);
7d9813f1
NA
6290 dump_ctf_parent_name = strdup (optarg);
6291 break;
42b6953b
IB
6292 case OPTION_SFRAME_DUMP:
6293 do_sframe = true;
6294 /* Providing section name is optional. request_dump (), however,
6295 thrives on non NULL optarg. Handle it explicitly here. */
6296 if (optarg != NULL)
6297 request_dump (dumpdata, SFRAME_DUMP);
6298 else
6299 {
6300 do_dump = true;
6301 const char *sframe_sec_name = strdup (".sframe");
6302 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6303 }
6304 break;
2c610e4b 6305 case OPTION_DYN_SYMS:
015dc7e1 6306 do_dyn_syms = true;
2c610e4b 6307 break;
0f03783c 6308 case OPTION_LTO_SYMS:
015dc7e1 6309 do_lto_syms = true;
0f03783c 6310 break;
b6ac461a
NC
6311 case 'X':
6312 extra_sym_info = true;
6313 break;
6314 case OPTION_NO_EXTRA_SYM_INFO:
6315 extra_sym_info = false;
6316 break;
6317
252b5132
RH
6318#ifdef SUPPORT_DISASSEMBLY
6319 case 'i':
6431e409 6320 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6321 break;
252b5132
RH
6322#endif
6323 case 'v':
6324 print_version (program_name);
6325 break;
6326 case 'V':
015dc7e1 6327 do_version = true;
252b5132 6328 break;
d974e256 6329 case 'W':
015dc7e1 6330 do_wide = true;
d974e256 6331 break;
0942c7ab 6332 case 'T':
015dc7e1 6333 do_not_show_symbol_truncation = true;
0942c7ab 6334 break;
79bc120c 6335 case 'C':
015dc7e1 6336 do_demangle = true;
79bc120c
NC
6337 if (optarg != NULL)
6338 {
6339 enum demangling_styles style;
6340
6341 style = cplus_demangle_name_to_style (optarg);
6342 if (style == unknown_demangling)
6343 error (_("unknown demangling style `%s'"), optarg);
6344
6345 cplus_demangle_set_style (style);
6346 }
6347 break;
6348 case OPTION_NO_DEMANGLING:
015dc7e1 6349 do_demangle = false;
79bc120c
NC
6350 break;
6351 case OPTION_RECURSE_LIMIT:
6352 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6353 break;
6354 case OPTION_NO_RECURSE_LIMIT:
6355 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6356 break;
6357 case OPTION_WITH_SYMBOL_VERSIONS:
6358 /* Ignored for backward compatibility. */
6359 break;
b9e920ec 6360
b3aa80b4
NC
6361 case 'U':
6362 if (optarg == NULL)
6363 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6364 else if (streq (optarg, "default") || streq (optarg, "d"))
6365 unicode_display = unicode_default;
6366 else if (streq (optarg, "locale") || streq (optarg, "l"))
6367 unicode_display = unicode_locale;
6368 else if (streq (optarg, "escape") || streq (optarg, "e"))
6369 unicode_display = unicode_escape;
6370 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6371 unicode_display = unicode_invalid;
6372 else if (streq (optarg, "hex") || streq (optarg, "x"))
6373 unicode_display = unicode_hex;
6374 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6375 unicode_display = unicode_highlight;
6376 else
6377 error (_("invalid argument to -U/--unicode: %s"), optarg);
6378 break;
6379
047c3dbf
NL
6380 case OPTION_SYM_BASE:
6381 sym_base = 0;
6382 if (optarg != NULL)
6383 {
6384 sym_base = strtoul (optarg, NULL, 0);
6385 switch (sym_base)
6386 {
6387 case 0:
6388 case 8:
6389 case 10:
6390 case 16:
6391 break;
6392
6393 default:
6394 sym_base = 0;
6395 break;
6396 }
6397 }
6398 break;
6399
252b5132 6400 default:
252b5132
RH
6401 /* xgettext:c-format */
6402 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6403 /* Fall through. */
252b5132 6404 case '?':
92f01d61 6405 usage (stderr);
252b5132
RH
6406 }
6407 }
6408
4d6ed7c8 6409 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6410 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6411 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6412 && !do_section_groups && !do_archive_index
0f03783c 6413 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6414 {
6415 if (do_checks)
6416 {
015dc7e1
AM
6417 check_all = true;
6418 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6419 do_segments = do_header = do_dump = do_version = true;
6420 do_histogram = do_debugging = do_arch = do_notes = true;
6421 do_section_groups = do_archive_index = do_dyn_syms = true;
6422 do_lto_syms = true;
1b513401
NC
6423 }
6424 else
6425 usage (stderr);
6426 }
252b5132
RH
6427}
6428
6429static const char *
d3ba0551 6430get_elf_class (unsigned int elf_class)
252b5132 6431{
b34976b6 6432 static char buff[32];
103f02d3 6433
252b5132
RH
6434 switch (elf_class)
6435 {
6436 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6437 case ELFCLASS32: return "ELF32";
6438 case ELFCLASS64: return "ELF64";
ab5e7794 6439 default:
e9e44622 6440 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6441 return buff;
252b5132
RH
6442 }
6443}
6444
6445static const char *
d3ba0551 6446get_data_encoding (unsigned int encoding)
252b5132 6447{
b34976b6 6448 static char buff[32];
103f02d3 6449
252b5132
RH
6450 switch (encoding)
6451 {
6452 case ELFDATANONE: return _("none");
33c63f9d
CM
6453 case ELFDATA2LSB: return _("2's complement, little endian");
6454 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6455 default:
e9e44622 6456 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6457 return buff;
252b5132
RH
6458 }
6459}
6460
521f7268
NC
6461static bool
6462check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6463{
6464 if (header->e_ident[EI_MAG0] == ELFMAG0
6465 && header->e_ident[EI_MAG1] == ELFMAG1
6466 && header->e_ident[EI_MAG2] == ELFMAG2
6467 && header->e_ident[EI_MAG3] == ELFMAG3)
6468 return true;
6469
6470 /* Some compilers produce object files that are not in the ELF file format.
6471 As an aid to users of readelf, try to identify these cases and suggest
6472 alternative tools.
6473
6474 FIXME: It is not clear if all four bytes are used as constant magic
6475 valus by all compilers. It may be necessary to recode this function if
6476 different tools use different length sequences. */
6477
6478 static struct
6479 {
6480 unsigned char magic[4];
6481 const char * obj_message;
6482 const char * ar_message;
6483 }
6484 known_magic[] =
6485 {
6486 { { 'B', 'C', 0xc0, 0xde },
6487 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6488 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6489 },
6490 { { 'g', 'o', ' ', 'o' },
6491 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6492 NULL
6493 }
6494 };
6495 int i;
6496
6497 for (i = ARRAY_SIZE (known_magic); i--;)
6498 {
6499 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6500 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6501 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6502 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6503 {
6504 /* Some compiler's analyzer tools do not handle archives,
6505 so we provide two different kinds of error message. */
6506 if (filedata->archive_file_size > 0
6507 && known_magic[i].ar_message != NULL)
b3ea2010 6508 error ("%s", known_magic[i].ar_message);
521f7268 6509 else
b3ea2010 6510 error ("%s", known_magic[i].obj_message);
521f7268
NC
6511 return false;
6512 }
6513 }
6514
6515 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6516 return false;
6517}
6518
dda8d76d 6519/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6520
015dc7e1 6521static bool
dda8d76d 6522process_file_header (Filedata * filedata)
252b5132 6523{
dda8d76d
NC
6524 Elf_Internal_Ehdr * header = & filedata->file_header;
6525
521f7268
NC
6526 if (! check_magic_number (filedata, header))
6527 return false;
252b5132 6528
ca0e11aa
NC
6529 if (! filedata->is_separate)
6530 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6531
252b5132
RH
6532 if (do_header)
6533 {
32ec8896 6534 unsigned i;
252b5132 6535
ca0e11aa
NC
6536 if (filedata->is_separate)
6537 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6538 else
6539 printf (_("ELF Header:\n"));
252b5132 6540 printf (_(" Magic: "));
b34976b6 6541 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6542 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6543 printf ("\n");
6544 printf (_(" Class: %s\n"),
dda8d76d 6545 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6546 printf (_(" Data: %s\n"),
dda8d76d 6547 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6548 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6549 header->e_ident[EI_VERSION],
6550 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6551 ? _(" (current)")
dda8d76d 6552 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6553 ? _(" <unknown>")
789be9f7 6554 : "")));
252b5132 6555 printf (_(" OS/ABI: %s\n"),
dda8d76d 6556 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6557 printf (_(" ABI Version: %d\n"),
dda8d76d 6558 header->e_ident[EI_ABIVERSION]);
252b5132 6559 printf (_(" Type: %s\n"),
93df3340 6560 get_file_type (filedata));
252b5132 6561 printf (_(" Machine: %s\n"),
dda8d76d 6562 get_machine_name (header->e_machine));
252b5132 6563 printf (_(" Version: 0x%lx\n"),
e8a64888 6564 header->e_version);
76da6bbe 6565
f7a99963 6566 printf (_(" Entry point address: "));
e8a64888 6567 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6568 printf (_("\n Start of program headers: "));
e8a64888 6569 print_vma (header->e_phoff, DEC);
f7a99963 6570 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6571 print_vma (header->e_shoff, DEC);
f7a99963 6572 printf (_(" (bytes into file)\n"));
76da6bbe 6573
252b5132 6574 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6575 header->e_flags,
dda8d76d 6576 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6577 printf (_(" Size of this header: %u (bytes)\n"),
6578 header->e_ehsize);
6579 printf (_(" Size of program headers: %u (bytes)\n"),
6580 header->e_phentsize);
6581 printf (_(" Number of program headers: %u"),
6582 header->e_phnum);
dda8d76d
NC
6583 if (filedata->section_headers != NULL
6584 && header->e_phnum == PN_XNUM
6585 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6586 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6587 putc ('\n', stdout);
e8a64888
AM
6588 printf (_(" Size of section headers: %u (bytes)\n"),
6589 header->e_shentsize);
6590 printf (_(" Number of section headers: %u"),
6591 header->e_shnum);
dda8d76d 6592 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6593 {
6594 header->e_shnum = filedata->section_headers[0].sh_size;
6595 printf (" (%u)", header->e_shnum);
6596 }
560f3c1c 6597 putc ('\n', stdout);
e8a64888
AM
6598 printf (_(" Section header string table index: %u"),
6599 header->e_shstrndx);
dda8d76d
NC
6600 if (filedata->section_headers != NULL
6601 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6602 {
6603 header->e_shstrndx = filedata->section_headers[0].sh_link;
6604 printf (" (%u)", header->e_shstrndx);
6605 }
6606 if (header->e_shstrndx != SHN_UNDEF
6607 && header->e_shstrndx >= header->e_shnum)
6608 {
6609 header->e_shstrndx = SHN_UNDEF;
6610 printf (_(" <corrupt: out of range>"));
6611 }
560f3c1c
AM
6612 putc ('\n', stdout);
6613 }
6614
dda8d76d 6615 if (filedata->section_headers != NULL)
560f3c1c 6616 {
dda8d76d
NC
6617 if (header->e_phnum == PN_XNUM
6618 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6619 {
6620 /* Throw away any cached read of PN_XNUM headers. */
6621 free (filedata->program_headers);
6622 filedata->program_headers = NULL;
6623 header->e_phnum = filedata->section_headers[0].sh_info;
6624 }
dda8d76d
NC
6625 if (header->e_shnum == SHN_UNDEF)
6626 header->e_shnum = filedata->section_headers[0].sh_size;
6627 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6628 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6629 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6630 header->e_shstrndx = SHN_UNDEF;
252b5132 6631 }
103f02d3 6632
015dc7e1 6633 return true;
9ea033b2
NC
6634}
6635
dda8d76d
NC
6636/* Read in the program headers from FILEDATA and store them in PHEADERS.
6637 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6638
015dc7e1 6639static bool
dda8d76d 6640get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6641{
2cf0635d
NC
6642 Elf32_External_Phdr * phdrs;
6643 Elf32_External_Phdr * external;
6644 Elf_Internal_Phdr * internal;
b34976b6 6645 unsigned int i;
dda8d76d
NC
6646 unsigned int size = filedata->file_header.e_phentsize;
6647 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6648
6649 /* PR binutils/17531: Cope with unexpected section header sizes. */
6650 if (size == 0 || num == 0)
015dc7e1 6651 return false;
e0a31db1
NC
6652 if (size < sizeof * phdrs)
6653 {
6654 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6655 return false;
e0a31db1
NC
6656 }
6657 if (size > sizeof * phdrs)
6658 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6659
dda8d76d 6660 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6661 size, num, _("program headers"));
6662 if (phdrs == NULL)
015dc7e1 6663 return false;
9ea033b2 6664
91d6fa6a 6665 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6666 i < filedata->file_header.e_phnum;
b34976b6 6667 i++, internal++, external++)
252b5132 6668 {
9ea033b2
NC
6669 internal->p_type = BYTE_GET (external->p_type);
6670 internal->p_offset = BYTE_GET (external->p_offset);
6671 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6672 internal->p_paddr = BYTE_GET (external->p_paddr);
6673 internal->p_filesz = BYTE_GET (external->p_filesz);
6674 internal->p_memsz = BYTE_GET (external->p_memsz);
6675 internal->p_flags = BYTE_GET (external->p_flags);
6676 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6677 }
6678
9ea033b2 6679 free (phdrs);
015dc7e1 6680 return true;
252b5132
RH
6681}
6682
dda8d76d
NC
6683/* Read in the program headers from FILEDATA and store them in PHEADERS.
6684 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6685
015dc7e1 6686static bool
dda8d76d 6687get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6688{
2cf0635d
NC
6689 Elf64_External_Phdr * phdrs;
6690 Elf64_External_Phdr * external;
6691 Elf_Internal_Phdr * internal;
b34976b6 6692 unsigned int i;
dda8d76d
NC
6693 unsigned int size = filedata->file_header.e_phentsize;
6694 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6695
6696 /* PR binutils/17531: Cope with unexpected section header sizes. */
6697 if (size == 0 || num == 0)
015dc7e1 6698 return false;
e0a31db1
NC
6699 if (size < sizeof * phdrs)
6700 {
6701 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6702 return false;
e0a31db1
NC
6703 }
6704 if (size > sizeof * phdrs)
6705 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6706
dda8d76d 6707 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6708 size, num, _("program headers"));
a6e9f9df 6709 if (!phdrs)
015dc7e1 6710 return false;
9ea033b2 6711
91d6fa6a 6712 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6713 i < filedata->file_header.e_phnum;
b34976b6 6714 i++, internal++, external++)
9ea033b2
NC
6715 {
6716 internal->p_type = BYTE_GET (external->p_type);
6717 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6718 internal->p_offset = BYTE_GET (external->p_offset);
6719 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6720 internal->p_paddr = BYTE_GET (external->p_paddr);
6721 internal->p_filesz = BYTE_GET (external->p_filesz);
6722 internal->p_memsz = BYTE_GET (external->p_memsz);
6723 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6724 }
6725
6726 free (phdrs);
015dc7e1 6727 return true;
9ea033b2 6728}
252b5132 6729
32ec8896 6730/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6731
015dc7e1 6732static bool
dda8d76d 6733get_program_headers (Filedata * filedata)
d93f0186 6734{
2cf0635d 6735 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6736
6737 /* Check cache of prior read. */
dda8d76d 6738 if (filedata->program_headers != NULL)
015dc7e1 6739 return true;
d93f0186 6740
82156ab7
NC
6741 /* Be kind to memory checkers by looking for
6742 e_phnum values which we know must be invalid. */
dda8d76d 6743 if (filedata->file_header.e_phnum
82156ab7 6744 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6745 >= filedata->file_size)
82156ab7
NC
6746 {
6747 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6748 filedata->file_header.e_phnum);
015dc7e1 6749 return false;
82156ab7 6750 }
d93f0186 6751
dda8d76d 6752 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6753 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6754 if (phdrs == NULL)
6755 {
8b73c356 6756 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6757 filedata->file_header.e_phnum);
015dc7e1 6758 return false;
d93f0186
NC
6759 }
6760
6761 if (is_32bit_elf
dda8d76d
NC
6762 ? get_32bit_program_headers (filedata, phdrs)
6763 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6764 {
dda8d76d 6765 filedata->program_headers = phdrs;
015dc7e1 6766 return true;
d93f0186
NC
6767 }
6768
6769 free (phdrs);
015dc7e1 6770 return false;
d93f0186
NC
6771}
6772
93df3340 6773/* Print program header info and locate dynamic section. */
2f62977e 6774
93df3340 6775static void
dda8d76d 6776process_program_headers (Filedata * filedata)
252b5132 6777{
2cf0635d 6778 Elf_Internal_Phdr * segment;
b34976b6 6779 unsigned int i;
1a9ccd70 6780 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6781
dda8d76d 6782 if (filedata->file_header.e_phnum == 0)
252b5132 6783 {
82f2dbf7 6784 /* PR binutils/12467. */
dda8d76d 6785 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6786 warn (_("possibly corrupt ELF header - it has a non-zero program"
6787 " header offset, but no program headers\n"));
82f2dbf7 6788 else if (do_segments)
ca0e11aa
NC
6789 {
6790 if (filedata->is_separate)
6791 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6792 filedata->file_name);
6793 else
6794 printf (_("\nThere are no program headers in this file.\n"));
6795 }
93df3340 6796 goto no_headers;
252b5132
RH
6797 }
6798
6799 if (do_segments && !do_header)
6800 {
ca0e11aa
NC
6801 if (filedata->is_separate)
6802 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6803 filedata->file_name, get_file_type (filedata));
ca0e11aa 6804 else
93df3340 6805 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6806 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6807 filedata->file_header.e_entry);
b8281767
AM
6808 printf (ngettext ("There is %d program header,"
6809 " starting at offset %" PRIu64 "\n",
6810 "There are %d program headers,"
6811 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6812 filedata->file_header.e_phnum),
6813 filedata->file_header.e_phnum,
625d49fc 6814 filedata->file_header.e_phoff);
252b5132
RH
6815 }
6816
dda8d76d 6817 if (! get_program_headers (filedata))
93df3340 6818 goto no_headers;
103f02d3 6819
252b5132
RH
6820 if (do_segments)
6821 {
dda8d76d 6822 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6823 printf (_("\nProgram Headers:\n"));
6824 else
6825 printf (_("\nProgram Headers:\n"));
76da6bbe 6826
f7a99963
NC
6827 if (is_32bit_elf)
6828 printf
6829 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6830 else if (do_wide)
6831 printf
6832 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6833 else
6834 {
6835 printf
6836 (_(" Type Offset VirtAddr PhysAddr\n"));
6837 printf
6838 (_(" FileSiz MemSiz Flags Align\n"));
6839 }
252b5132
RH
6840 }
6841
26c527e6 6842 uint64_t dynamic_addr = 0;
be7d229a 6843 uint64_t dynamic_size = 0;
dda8d76d
NC
6844 for (i = 0, segment = filedata->program_headers;
6845 i < filedata->file_header.e_phnum;
b34976b6 6846 i++, segment++)
252b5132
RH
6847 {
6848 if (do_segments)
6849 {
dda8d76d 6850 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6851
6852 if (is_32bit_elf)
6853 {
6854 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6855 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6856 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6857 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6858 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6859 printf ("%c%c%c ",
6860 (segment->p_flags & PF_R ? 'R' : ' '),
6861 (segment->p_flags & PF_W ? 'W' : ' '),
6862 (segment->p_flags & PF_X ? 'E' : ' '));
6863 printf ("%#lx", (unsigned long) segment->p_align);
6864 }
d974e256
JJ
6865 else if (do_wide)
6866 {
6867 if ((unsigned long) segment->p_offset == segment->p_offset)
6868 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6869 else
6870 {
6871 print_vma (segment->p_offset, FULL_HEX);
6872 putchar (' ');
6873 }
6874
6875 print_vma (segment->p_vaddr, FULL_HEX);
6876 putchar (' ');
6877 print_vma (segment->p_paddr, FULL_HEX);
6878 putchar (' ');
6879
6880 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6881 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6882 else
6883 {
6884 print_vma (segment->p_filesz, FULL_HEX);
6885 putchar (' ');
6886 }
6887
6888 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6889 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6890 else
6891 {
f48e6c45 6892 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6893 }
6894
6895 printf (" %c%c%c ",
6896 (segment->p_flags & PF_R ? 'R' : ' '),
6897 (segment->p_flags & PF_W ? 'W' : ' '),
6898 (segment->p_flags & PF_X ? 'E' : ' '));
6899
6900 if ((unsigned long) segment->p_align == segment->p_align)
6901 printf ("%#lx", (unsigned long) segment->p_align);
6902 else
6903 {
6904 print_vma (segment->p_align, PREFIX_HEX);
6905 }
6906 }
f7a99963
NC
6907 else
6908 {
6909 print_vma (segment->p_offset, FULL_HEX);
6910 putchar (' ');
6911 print_vma (segment->p_vaddr, FULL_HEX);
6912 putchar (' ');
6913 print_vma (segment->p_paddr, FULL_HEX);
6914 printf ("\n ");
6915 print_vma (segment->p_filesz, FULL_HEX);
6916 putchar (' ');
6917 print_vma (segment->p_memsz, FULL_HEX);
6918 printf (" %c%c%c ",
6919 (segment->p_flags & PF_R ? 'R' : ' '),
6920 (segment->p_flags & PF_W ? 'W' : ' '),
6921 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6922 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6923 }
252b5132 6924
1a9ccd70
NC
6925 putc ('\n', stdout);
6926 }
f54498b4 6927
252b5132
RH
6928 switch (segment->p_type)
6929 {
1a9ccd70 6930 case PT_LOAD:
502d895c
NC
6931#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6932 required by the ELF standard, several programs, including the Linux
6933 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6934 if (previous_load
6935 && previous_load->p_vaddr > segment->p_vaddr)
6936 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6937#endif
1a9ccd70
NC
6938 if (segment->p_memsz < segment->p_filesz)
6939 error (_("the segment's file size is larger than its memory size\n"));
6940 previous_load = segment;
6941 break;
6942
6943 case PT_PHDR:
6944 /* PR 20815 - Verify that the program header is loaded into memory. */
6945 if (i > 0 && previous_load != NULL)
6946 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6947 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6948 {
6949 unsigned int j;
6950
dda8d76d 6951 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6952 {
6953 Elf_Internal_Phdr *load = filedata->program_headers + j;
6954 if (load->p_type == PT_LOAD
6955 && load->p_offset <= segment->p_offset
6956 && (load->p_offset + load->p_filesz
6957 >= segment->p_offset + segment->p_filesz)
6958 && load->p_vaddr <= segment->p_vaddr
6959 && (load->p_vaddr + load->p_filesz
6960 >= segment->p_vaddr + segment->p_filesz))
6961 break;
6962 }
dda8d76d 6963 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6964 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6965 }
6966 break;
6967
252b5132 6968 case PT_DYNAMIC:
93df3340 6969 if (dynamic_addr)
252b5132
RH
6970 error (_("more than one dynamic segment\n"));
6971
20737c13
AM
6972 /* By default, assume that the .dynamic section is the first
6973 section in the DYNAMIC segment. */
93df3340
AM
6974 dynamic_addr = segment->p_offset;
6975 dynamic_size = segment->p_filesz;
20737c13 6976
b2d38a17
NC
6977 /* Try to locate the .dynamic section. If there is
6978 a section header table, we can easily locate it. */
dda8d76d 6979 if (filedata->section_headers != NULL)
b2d38a17 6980 {
2cf0635d 6981 Elf_Internal_Shdr * sec;
b2d38a17 6982
dda8d76d 6983 sec = find_section (filedata, ".dynamic");
89fac5e3 6984 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6985 {
93df3340
AM
6986 /* A corresponding .dynamic section is expected, but on
6987 IA-64/OpenVMS it is OK for it to be missing. */
6988 if (!is_ia64_vms (filedata))
6989 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6990 break;
6991 }
6992
42bb2e33 6993 if (sec->sh_type == SHT_NOBITS)
20737c13 6994 {
93df3340
AM
6995 dynamic_addr = 0;
6996 dynamic_size = 0;
20737c13
AM
6997 break;
6998 }
42bb2e33 6999
93df3340
AM
7000 dynamic_addr = sec->sh_offset;
7001 dynamic_size = sec->sh_size;
b2d38a17 7002
8ac10c5b
L
7003 /* The PT_DYNAMIC segment, which is used by the run-time
7004 loader, should exactly match the .dynamic section. */
7005 if (do_checks
93df3340
AM
7006 && (dynamic_addr != segment->p_offset
7007 || dynamic_size != segment->p_filesz))
8ac10c5b
L
7008 warn (_("\
7009the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 7010 }
39e224f6
MW
7011
7012 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7013 segment. Check this after matching against the section headers
7014 so we don't warn on debuginfo file (which have NOBITS .dynamic
7015 sections). */
93df3340
AM
7016 if (dynamic_addr > filedata->file_size
7017 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
7018 {
7019 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
7020 dynamic_addr = 0;
7021 dynamic_size = 0;
39e224f6 7022 }
252b5132
RH
7023 break;
7024
7025 case PT_INTERP:
13acb58d
AM
7026 if (segment->p_offset >= filedata->file_size
7027 || segment->p_filesz > filedata->file_size - segment->p_offset
7028 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
7029 || fseek64 (filedata->handle,
7030 filedata->archive_file_offset + segment->p_offset,
7031 SEEK_SET))
252b5132
RH
7032 error (_("Unable to find program interpreter name\n"));
7033 else
7034 {
13acb58d
AM
7035 size_t len = segment->p_filesz;
7036 free (filedata->program_interpreter);
7037 filedata->program_interpreter = xmalloc (len + 1);
7038 len = fread (filedata->program_interpreter, 1, len,
7039 filedata->handle);
7040 filedata->program_interpreter[len] = 0;
252b5132
RH
7041
7042 if (do_segments)
f54498b4 7043 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 7044 filedata->program_interpreter);
252b5132
RH
7045 }
7046 break;
7047 }
252b5132
RH
7048 }
7049
dda8d76d
NC
7050 if (do_segments
7051 && filedata->section_headers != NULL
7052 && filedata->string_table != NULL)
252b5132
RH
7053 {
7054 printf (_("\n Section to Segment mapping:\n"));
7055 printf (_(" Segment Sections...\n"));
7056
dda8d76d 7057 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 7058 {
9ad5cbcf 7059 unsigned int j;
2cf0635d 7060 Elf_Internal_Shdr * section;
252b5132 7061
dda8d76d
NC
7062 segment = filedata->program_headers + i;
7063 section = filedata->section_headers + 1;
252b5132
RH
7064
7065 printf (" %2.2d ", i);
7066
dda8d76d 7067 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 7068 {
f4638467
AM
7069 if (!ELF_TBSS_SPECIAL (section, segment)
7070 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 7071 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
7072 }
7073
7074 putc ('\n',stdout);
7075 }
7076 }
7077
93df3340
AM
7078 filedata->dynamic_addr = dynamic_addr;
7079 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7080 return;
7081
7082 no_headers:
7083 filedata->dynamic_addr = 0;
7084 filedata->dynamic_size = 1;
252b5132
RH
7085}
7086
7087
d93f0186
NC
7088/* Find the file offset corresponding to VMA by using the program headers. */
7089
26c527e6 7090static int64_t
625d49fc 7091offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 7092{
2cf0635d 7093 Elf_Internal_Phdr * seg;
d93f0186 7094
dda8d76d 7095 if (! get_program_headers (filedata))
d93f0186
NC
7096 {
7097 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7098 return (long) vma;
7099 }
7100
dda8d76d
NC
7101 for (seg = filedata->program_headers;
7102 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
7103 ++seg)
7104 {
7105 if (seg->p_type != PT_LOAD)
7106 continue;
7107
7108 if (vma >= (seg->p_vaddr & -seg->p_align)
7109 && vma + size <= seg->p_vaddr + seg->p_filesz)
7110 return vma - seg->p_vaddr + seg->p_offset;
7111 }
7112
26c527e6
AM
7113 warn (_("Virtual address %#" PRIx64
7114 " not located in any PT_LOAD segment.\n"), vma);
7115 return vma;
d93f0186
NC
7116}
7117
7118
dda8d76d
NC
7119/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7120 If PROBE is true, this is just a probe and we do not generate any error
7121 messages if the load fails. */
049b0c3a 7122
015dc7e1
AM
7123static bool
7124get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 7125{
2cf0635d
NC
7126 Elf32_External_Shdr * shdrs;
7127 Elf_Internal_Shdr * internal;
dda8d76d
NC
7128 unsigned int i;
7129 unsigned int size = filedata->file_header.e_shentsize;
7130 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7131
7132 /* PR binutils/17531: Cope with unexpected section header sizes. */
7133 if (size == 0 || num == 0)
015dc7e1 7134 return false;
907b52f4
NC
7135
7136 /* The section header cannot be at the start of the file - that is
7137 where the ELF file header is located. A file with absolutely no
7138 sections in it will use a shoff of 0. */
7139 if (filedata->file_header.e_shoff == 0)
7140 return false;
7141
049b0c3a
NC
7142 if (size < sizeof * shdrs)
7143 {
7144 if (! probe)
7145 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7146 return false;
049b0c3a
NC
7147 }
7148 if (!probe && size > sizeof * shdrs)
7149 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 7150
dda8d76d 7151 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
7152 size, num,
7153 probe ? NULL : _("section headers"));
7154 if (shdrs == NULL)
015dc7e1 7155 return false;
252b5132 7156
dda8d76d
NC
7157 filedata->section_headers = (Elf_Internal_Shdr *)
7158 cmalloc (num, sizeof (Elf_Internal_Shdr));
7159 if (filedata->section_headers == NULL)
252b5132 7160 {
049b0c3a 7161 if (!probe)
8b73c356 7162 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7163 free (shdrs);
015dc7e1 7164 return false;
252b5132
RH
7165 }
7166
dda8d76d 7167 for (i = 0, internal = filedata->section_headers;
560f3c1c 7168 i < num;
b34976b6 7169 i++, internal++)
252b5132
RH
7170 {
7171 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7172 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7173 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7174 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7175 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7176 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7177 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7178 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7179 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7180 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
7181 if (!probe && internal->sh_link > num)
7182 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7183 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7184 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
7185 }
7186
7187 free (shdrs);
015dc7e1 7188 return true;
252b5132
RH
7189}
7190
dda8d76d
NC
7191/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7192
015dc7e1
AM
7193static bool
7194get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 7195{
dda8d76d
NC
7196 Elf64_External_Shdr * shdrs;
7197 Elf_Internal_Shdr * internal;
7198 unsigned int i;
7199 unsigned int size = filedata->file_header.e_shentsize;
7200 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7201
7202 /* PR binutils/17531: Cope with unexpected section header sizes. */
7203 if (size == 0 || num == 0)
015dc7e1 7204 return false;
dda8d76d 7205
907b52f4
NC
7206 /* The section header cannot be at the start of the file - that is
7207 where the ELF file header is located. A file with absolutely no
7208 sections in it will use a shoff of 0. */
7209 if (filedata->file_header.e_shoff == 0)
7210 return false;
7211
049b0c3a
NC
7212 if (size < sizeof * shdrs)
7213 {
7214 if (! probe)
7215 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7216 return false;
049b0c3a 7217 }
dda8d76d 7218
049b0c3a
NC
7219 if (! probe && size > sizeof * shdrs)
7220 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 7221
dda8d76d
NC
7222 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7223 filedata->file_header.e_shoff,
049b0c3a
NC
7224 size, num,
7225 probe ? NULL : _("section headers"));
7226 if (shdrs == NULL)
015dc7e1 7227 return false;
9ea033b2 7228
dda8d76d
NC
7229 filedata->section_headers = (Elf_Internal_Shdr *)
7230 cmalloc (num, sizeof (Elf_Internal_Shdr));
7231 if (filedata->section_headers == NULL)
9ea033b2 7232 {
049b0c3a 7233 if (! probe)
8b73c356 7234 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7235 free (shdrs);
015dc7e1 7236 return false;
9ea033b2
NC
7237 }
7238
dda8d76d 7239 for (i = 0, internal = filedata->section_headers;
560f3c1c 7240 i < num;
b34976b6 7241 i++, internal++)
9ea033b2
NC
7242 {
7243 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7244 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7245 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7246 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7247 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7248 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7249 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7250 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7251 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7252 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7253 if (!probe && internal->sh_link > num)
7254 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7255 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7256 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7257 }
7258
7259 free (shdrs);
015dc7e1 7260 return true;
9ea033b2
NC
7261}
7262
4de91c10
AM
7263static bool
7264get_section_headers (Filedata *filedata, bool probe)
7265{
7266 if (filedata->section_headers != NULL)
7267 return true;
7268
4de91c10
AM
7269 if (is_32bit_elf)
7270 return get_32bit_section_headers (filedata, probe);
7271 else
7272 return get_64bit_section_headers (filedata, probe);
7273}
7274
252b5132 7275static Elf_Internal_Sym *
26c527e6
AM
7276get_32bit_elf_symbols (Filedata *filedata,
7277 Elf_Internal_Shdr *section,
7278 uint64_t *num_syms_return)
252b5132 7279{
26c527e6 7280 uint64_t number = 0;
dd24e3da 7281 Elf32_External_Sym * esyms = NULL;
ba5cdace 7282 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7283 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7284 Elf_Internal_Sym * psym;
b34976b6 7285 unsigned int j;
e3d39609 7286 elf_section_list * entry;
252b5132 7287
c9c1d674
EG
7288 if (section->sh_size == 0)
7289 {
7290 if (num_syms_return != NULL)
7291 * num_syms_return = 0;
7292 return NULL;
7293 }
7294
dd24e3da 7295 /* Run some sanity checks first. */
c9c1d674 7296 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7297 {
26c527e6 7298 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7299 printable_section_name (filedata, section),
26c527e6 7300 section->sh_entsize);
ba5cdace 7301 goto exit_point;
dd24e3da
NC
7302 }
7303
dda8d76d 7304 if (section->sh_size > filedata->file_size)
f54498b4 7305 {
26c527e6 7306 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7307 printable_section_name (filedata, section),
26c527e6 7308 section->sh_size);
f54498b4
NC
7309 goto exit_point;
7310 }
7311
dd24e3da
NC
7312 number = section->sh_size / section->sh_entsize;
7313
7314 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7315 {
26c527e6
AM
7316 error (_("Size (%#" PRIx64 ") of section %s "
7317 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7318 section->sh_size,
dda8d76d 7319 printable_section_name (filedata, section),
26c527e6 7320 section->sh_entsize);
ba5cdace 7321 goto exit_point;
dd24e3da
NC
7322 }
7323
dda8d76d 7324 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7325 section->sh_size, _("symbols"));
dd24e3da 7326 if (esyms == NULL)
ba5cdace 7327 goto exit_point;
252b5132 7328
e3d39609 7329 shndx = NULL;
978c4450 7330 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7331 {
26c527e6 7332 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7333 continue;
7334
7335 if (shndx != NULL)
7336 {
7337 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7338 free (shndx);
7339 }
7340
7341 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7342 entry->hdr->sh_offset,
7343 1, entry->hdr->sh_size,
7344 _("symbol table section indices"));
7345 if (shndx == NULL)
7346 goto exit_point;
7347
7348 /* PR17531: file: heap-buffer-overflow */
7349 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7350 {
26c527e6 7351 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7352 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7353 entry->hdr->sh_size,
7354 section->sh_size);
e3d39609 7355 goto exit_point;
c9c1d674 7356 }
e3d39609 7357 }
9ad5cbcf 7358
3f5e193b 7359 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7360
7361 if (isyms == NULL)
7362 {
26c527e6 7363 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7364 goto exit_point;
252b5132
RH
7365 }
7366
dd24e3da 7367 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7368 {
7369 psym->st_name = BYTE_GET (esyms[j].st_name);
7370 psym->st_value = BYTE_GET (esyms[j].st_value);
7371 psym->st_size = BYTE_GET (esyms[j].st_size);
7372 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7373 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7374 psym->st_shndx
7375 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7376 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7377 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7378 psym->st_info = BYTE_GET (esyms[j].st_info);
7379 psym->st_other = BYTE_GET (esyms[j].st_other);
7380 }
7381
dd24e3da 7382 exit_point:
e3d39609
NC
7383 free (shndx);
7384 free (esyms);
252b5132 7385
ba5cdace
NC
7386 if (num_syms_return != NULL)
7387 * num_syms_return = isyms == NULL ? 0 : number;
7388
252b5132
RH
7389 return isyms;
7390}
7391
9ea033b2 7392static Elf_Internal_Sym *
26c527e6
AM
7393get_64bit_elf_symbols (Filedata *filedata,
7394 Elf_Internal_Shdr *section,
7395 uint64_t *num_syms_return)
9ea033b2 7396{
26c527e6 7397 uint64_t number = 0;
ba5cdace
NC
7398 Elf64_External_Sym * esyms = NULL;
7399 Elf_External_Sym_Shndx * shndx = NULL;
7400 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7401 Elf_Internal_Sym * psym;
b34976b6 7402 unsigned int j;
e3d39609 7403 elf_section_list * entry;
9ea033b2 7404
c9c1d674
EG
7405 if (section->sh_size == 0)
7406 {
7407 if (num_syms_return != NULL)
7408 * num_syms_return = 0;
7409 return NULL;
7410 }
7411
dd24e3da 7412 /* Run some sanity checks first. */
c9c1d674 7413 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7414 {
26c527e6 7415 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7416 printable_section_name (filedata, section),
26c527e6 7417 section->sh_entsize);
ba5cdace 7418 goto exit_point;
dd24e3da
NC
7419 }
7420
dda8d76d 7421 if (section->sh_size > filedata->file_size)
f54498b4 7422 {
26c527e6 7423 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7424 printable_section_name (filedata, section),
26c527e6 7425 section->sh_size);
f54498b4
NC
7426 goto exit_point;
7427 }
7428
dd24e3da
NC
7429 number = section->sh_size / section->sh_entsize;
7430
7431 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7432 {
26c527e6
AM
7433 error (_("Size (%#" PRIx64 ") of section %s "
7434 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7435 section->sh_size,
dda8d76d 7436 printable_section_name (filedata, section),
26c527e6 7437 section->sh_entsize);
ba5cdace 7438 goto exit_point;
dd24e3da
NC
7439 }
7440
dda8d76d 7441 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7442 section->sh_size, _("symbols"));
a6e9f9df 7443 if (!esyms)
ba5cdace 7444 goto exit_point;
9ea033b2 7445
e3d39609 7446 shndx = NULL;
978c4450 7447 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7448 {
26c527e6 7449 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7450 continue;
7451
7452 if (shndx != NULL)
7453 {
7454 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7455 free (shndx);
c9c1d674 7456 }
e3d39609
NC
7457
7458 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7459 entry->hdr->sh_offset,
7460 1, entry->hdr->sh_size,
7461 _("symbol table section indices"));
7462 if (shndx == NULL)
7463 goto exit_point;
7464
7465 /* PR17531: file: heap-buffer-overflow */
7466 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7467 {
26c527e6 7468 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7469 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7470 entry->hdr->sh_size,
7471 section->sh_size);
e3d39609
NC
7472 goto exit_point;
7473 }
7474 }
9ad5cbcf 7475
3f5e193b 7476 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7477
7478 if (isyms == NULL)
7479 {
26c527e6 7480 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7481 goto exit_point;
9ea033b2
NC
7482 }
7483
ba5cdace 7484 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7485 {
7486 psym->st_name = BYTE_GET (esyms[j].st_name);
7487 psym->st_info = BYTE_GET (esyms[j].st_info);
7488 psym->st_other = BYTE_GET (esyms[j].st_other);
7489 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7490
4fbb74a6 7491 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7492 psym->st_shndx
7493 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7494 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7495 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7496
66543521
AM
7497 psym->st_value = BYTE_GET (esyms[j].st_value);
7498 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7499 }
7500
ba5cdace 7501 exit_point:
e3d39609
NC
7502 free (shndx);
7503 free (esyms);
ba5cdace
NC
7504
7505 if (num_syms_return != NULL)
7506 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7507
7508 return isyms;
7509}
7510
4de91c10
AM
7511static Elf_Internal_Sym *
7512get_elf_symbols (Filedata *filedata,
7513 Elf_Internal_Shdr *section,
26c527e6 7514 uint64_t *num_syms_return)
4de91c10
AM
7515{
7516 if (is_32bit_elf)
7517 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7518 else
7519 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7520}
7521
d1133906 7522static const char *
625d49fc 7523get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7524{
5477e8a0 7525 static char buff[1024];
2cf0635d 7526 char * p = buff;
32ec8896
NC
7527 unsigned int field_size = is_32bit_elf ? 8 : 16;
7528 signed int sindex;
7529 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7530 uint64_t os_flags = 0;
7531 uint64_t proc_flags = 0;
7532 uint64_t unknown_flags = 0;
148b93f2 7533 static const struct
5477e8a0 7534 {
2cf0635d 7535 const char * str;
32ec8896 7536 unsigned int len;
5477e8a0
L
7537 }
7538 flags [] =
7539 {
cfcac11d
NC
7540 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7541 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7542 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7543 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7544 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7545 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7546 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7547 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7548 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7549 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7550 /* IA-64 specific. */
7551 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7552 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7553 /* IA-64 OpenVMS specific. */
7554 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7555 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7556 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7557 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7558 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7559 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7560 /* Generic. */
cfcac11d 7561 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7562 /* SPARC specific. */
77115a4a 7563 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7564 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7565 /* ARM specific. */
7566 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7567 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7568 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7569 /* GNU specific. */
7570 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7571 /* VLE specific. */
7572 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7573 /* GNU specific. */
7574 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7575 };
7576
7577 if (do_section_details)
f8c4789c
AM
7578 p += sprintf (p, "[%*.*lx]: ",
7579 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7580
d1133906
NC
7581 while (sh_flags)
7582 {
625d49fc 7583 uint64_t flag;
d1133906
NC
7584
7585 flag = sh_flags & - sh_flags;
7586 sh_flags &= ~ flag;
76da6bbe 7587
5477e8a0 7588 if (do_section_details)
d1133906 7589 {
5477e8a0
L
7590 switch (flag)
7591 {
91d6fa6a
NC
7592 case SHF_WRITE: sindex = 0; break;
7593 case SHF_ALLOC: sindex = 1; break;
7594 case SHF_EXECINSTR: sindex = 2; break;
7595 case SHF_MERGE: sindex = 3; break;
7596 case SHF_STRINGS: sindex = 4; break;
7597 case SHF_INFO_LINK: sindex = 5; break;
7598 case SHF_LINK_ORDER: sindex = 6; break;
7599 case SHF_OS_NONCONFORMING: sindex = 7; break;
7600 case SHF_GROUP: sindex = 8; break;
7601 case SHF_TLS: sindex = 9; break;
18ae9cc1 7602 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7603 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7604
5477e8a0 7605 default:
91d6fa6a 7606 sindex = -1;
dda8d76d 7607 switch (filedata->file_header.e_machine)
148b93f2 7608 {
cfcac11d 7609 case EM_IA_64:
148b93f2 7610 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7611 sindex = 10;
148b93f2 7612 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7613 sindex = 11;
dda8d76d 7614 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7615 switch (flag)
7616 {
91d6fa6a
NC
7617 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7618 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7619 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7620 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7621 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7622 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7623 default: break;
7624 }
cfcac11d
NC
7625 break;
7626
caa83f8b 7627 case EM_386:
22abe556 7628 case EM_IAMCU:
caa83f8b 7629 case EM_X86_64:
7f502d6c 7630 case EM_L1OM:
7a9068fe 7631 case EM_K1OM:
cfcac11d
NC
7632 case EM_OLD_SPARCV9:
7633 case EM_SPARC32PLUS:
7634 case EM_SPARCV9:
7635 case EM_SPARC:
18ae9cc1 7636 if (flag == SHF_ORDERED)
91d6fa6a 7637 sindex = 19;
cfcac11d 7638 break;
ac4c9b04
MG
7639
7640 case EM_ARM:
7641 switch (flag)
7642 {
7643 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7644 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7645 case SHF_COMDEF: sindex = 23; break;
7646 default: break;
7647 }
7648 break;
83eef883
AFB
7649 case EM_PPC:
7650 if (flag == SHF_PPC_VLE)
7651 sindex = 25;
7652 break;
99fabbc9
JL
7653 default:
7654 break;
7655 }
ac4c9b04 7656
99fabbc9
JL
7657 switch (filedata->file_header.e_ident[EI_OSABI])
7658 {
7659 case ELFOSABI_GNU:
7660 case ELFOSABI_FREEBSD:
7661 if (flag == SHF_GNU_RETAIN)
7662 sindex = 26;
7663 /* Fall through */
7664 case ELFOSABI_NONE:
7665 if (flag == SHF_GNU_MBIND)
7666 /* We should not recognize SHF_GNU_MBIND for
7667 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7668 not set the EI_OSABI header byte. */
7669 sindex = 24;
7670 break;
cfcac11d
NC
7671 default:
7672 break;
148b93f2 7673 }
99fabbc9 7674 break;
5477e8a0
L
7675 }
7676
91d6fa6a 7677 if (sindex != -1)
5477e8a0 7678 {
8d5ff12c
L
7679 if (p != buff + field_size + 4)
7680 {
7681 if (size < (10 + 2))
bee0ee85
NC
7682 {
7683 warn (_("Internal error: not enough buffer room for section flag info"));
7684 return _("<unknown>");
7685 }
8d5ff12c
L
7686 size -= 2;
7687 *p++ = ',';
7688 *p++ = ' ';
7689 }
7690
91d6fa6a
NC
7691 size -= flags [sindex].len;
7692 p = stpcpy (p, flags [sindex].str);
5477e8a0 7693 }
3b22753a 7694 else if (flag & SHF_MASKOS)
8d5ff12c 7695 os_flags |= flag;
d1133906 7696 else if (flag & SHF_MASKPROC)
8d5ff12c 7697 proc_flags |= flag;
d1133906 7698 else
8d5ff12c 7699 unknown_flags |= flag;
5477e8a0
L
7700 }
7701 else
7702 {
7703 switch (flag)
7704 {
7705 case SHF_WRITE: *p = 'W'; break;
7706 case SHF_ALLOC: *p = 'A'; break;
7707 case SHF_EXECINSTR: *p = 'X'; break;
7708 case SHF_MERGE: *p = 'M'; break;
7709 case SHF_STRINGS: *p = 'S'; break;
7710 case SHF_INFO_LINK: *p = 'I'; break;
7711 case SHF_LINK_ORDER: *p = 'L'; break;
7712 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7713 case SHF_GROUP: *p = 'G'; break;
7714 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7715 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7716 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7717
7718 default:
dda8d76d
NC
7719 if ((filedata->file_header.e_machine == EM_X86_64
7720 || filedata->file_header.e_machine == EM_L1OM
7721 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7722 && flag == SHF_X86_64_LARGE)
7723 *p = 'l';
dda8d76d 7724 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7725 && flag == SHF_ARM_PURECODE)
99fabbc9 7726 *p = 'y';
dda8d76d 7727 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7728 && flag == SHF_PPC_VLE)
99fabbc9 7729 *p = 'v';
5477e8a0
L
7730 else if (flag & SHF_MASKOS)
7731 {
99fabbc9
JL
7732 switch (filedata->file_header.e_ident[EI_OSABI])
7733 {
7734 case ELFOSABI_GNU:
7735 case ELFOSABI_FREEBSD:
7736 if (flag == SHF_GNU_RETAIN)
7737 {
7738 *p = 'R';
7739 break;
7740 }
7741 /* Fall through */
7742 case ELFOSABI_NONE:
7743 if (flag == SHF_GNU_MBIND)
7744 {
7745 /* We should not recognize SHF_GNU_MBIND for
7746 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7747 not set the EI_OSABI header byte. */
7748 *p = 'D';
7749 break;
7750 }
7751 /* Fall through */
7752 default:
7753 *p = 'o';
7754 sh_flags &= ~SHF_MASKOS;
7755 break;
7756 }
5477e8a0
L
7757 }
7758 else if (flag & SHF_MASKPROC)
7759 {
7760 *p = 'p';
7761 sh_flags &= ~ SHF_MASKPROC;
7762 }
7763 else
7764 *p = 'x';
7765 break;
7766 }
7767 p++;
d1133906
NC
7768 }
7769 }
76da6bbe 7770
8d5ff12c
L
7771 if (do_section_details)
7772 {
7773 if (os_flags)
7774 {
8d5ff12c
L
7775 if (p != buff + field_size + 4)
7776 {
f8c4789c 7777 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7778 {
7779 warn (_("Internal error: not enough buffer room for section flag info"));
7780 return _("<unknown>");
7781 }
8d5ff12c
L
7782 size -= 2;
7783 *p++ = ',';
7784 *p++ = ' ';
7785 }
f8c4789c
AM
7786 size -= 5 + field_size;
7787 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7788 (unsigned long) os_flags);
8d5ff12c
L
7789 }
7790 if (proc_flags)
7791 {
8d5ff12c
L
7792 if (p != buff + field_size + 4)
7793 {
f8c4789c 7794 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7795 {
7796 warn (_("Internal error: not enough buffer room for section flag info"));
7797 return _("<unknown>");
7798 }
8d5ff12c
L
7799 size -= 2;
7800 *p++ = ',';
7801 *p++ = ' ';
7802 }
f8c4789c
AM
7803 size -= 7 + field_size;
7804 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7805 (unsigned long) proc_flags);
8d5ff12c
L
7806 }
7807 if (unknown_flags)
7808 {
8d5ff12c
L
7809 if (p != buff + field_size + 4)
7810 {
f8c4789c 7811 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7812 {
7813 warn (_("Internal error: not enough buffer room for section flag info"));
7814 return _("<unknown>");
7815 }
8d5ff12c
L
7816 size -= 2;
7817 *p++ = ',';
7818 *p++ = ' ';
7819 }
f8c4789c
AM
7820 size -= 10 + field_size;
7821 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7822 (unsigned long) unknown_flags);
8d5ff12c
L
7823 }
7824 }
7825
e9e44622 7826 *p = '\0';
d1133906
NC
7827 return buff;
7828}
7829
5844b465 7830static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7831get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7832 uint64_t size)
77115a4a
L
7833{
7834 if (is_32bit_elf)
7835 {
7836 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7837
ebdf1ebf
NC
7838 if (size < sizeof (* echdr))
7839 {
7840 error (_("Compressed section is too small even for a compression header\n"));
7841 return 0;
7842 }
7843
77115a4a
L
7844 chdr->ch_type = BYTE_GET (echdr->ch_type);
7845 chdr->ch_size = BYTE_GET (echdr->ch_size);
7846 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7847 return sizeof (*echdr);
7848 }
7849 else
7850 {
7851 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7852
ebdf1ebf
NC
7853 if (size < sizeof (* echdr))
7854 {
7855 error (_("Compressed section is too small even for a compression header\n"));
7856 return 0;
7857 }
7858
77115a4a
L
7859 chdr->ch_type = BYTE_GET (echdr->ch_type);
7860 chdr->ch_size = BYTE_GET (echdr->ch_size);
7861 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7862 return sizeof (*echdr);
7863 }
7864}
7865
015dc7e1 7866static bool
dda8d76d 7867process_section_headers (Filedata * filedata)
252b5132 7868{
2cf0635d 7869 Elf_Internal_Shdr * section;
b34976b6 7870 unsigned int i;
252b5132 7871
dda8d76d 7872 if (filedata->file_header.e_shnum == 0)
252b5132 7873 {
82f2dbf7 7874 /* PR binutils/12467. */
dda8d76d 7875 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7876 {
7877 warn (_("possibly corrupt ELF file header - it has a non-zero"
7878 " section header offset, but no section headers\n"));
015dc7e1 7879 return false;
32ec8896 7880 }
82f2dbf7 7881 else if (do_sections)
252b5132
RH
7882 printf (_("\nThere are no sections in this file.\n"));
7883
015dc7e1 7884 return true;
252b5132
RH
7885 }
7886
7887 if (do_sections && !do_header)
ca0e11aa
NC
7888 {
7889 if (filedata->is_separate && process_links)
7890 printf (_("In linked file '%s': "), filedata->file_name);
7891 if (! filedata->is_separate || process_links)
7892 printf (ngettext ("There is %d section header, "
26c527e6 7893 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7894 "There are %d section headers, "
26c527e6 7895 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7896 filedata->file_header.e_shnum),
7897 filedata->file_header.e_shnum,
26c527e6 7898 filedata->file_header.e_shoff);
ca0e11aa 7899 }
252b5132 7900
4de91c10
AM
7901 if (!get_section_headers (filedata, false))
7902 return false;
252b5132
RH
7903
7904 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7905 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7906 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7907 {
dda8d76d 7908 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7909
c256ffe7
JJ
7910 if (section->sh_size != 0)
7911 {
dda8d76d
NC
7912 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7913 1, section->sh_size,
7914 _("string table"));
0de14b54 7915
dda8d76d 7916 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7917 }
252b5132
RH
7918 }
7919
7920 /* Scan the sections for the dynamic symbol table
e3c8793a 7921 and dynamic string table and debug sections. */
89fac5e3 7922 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7923 switch (filedata->file_header.e_machine)
89fac5e3
RS
7924 {
7925 case EM_MIPS:
7926 case EM_MIPS_RS3_LE:
7927 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7928 FDE addresses. However, the ABI also has a semi-official ILP32
7929 variant for which the normal FDE address size rules apply.
7930
7931 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7932 section, where XX is the size of longs in bits. Unfortunately,
7933 earlier compilers provided no way of distinguishing ILP32 objects
7934 from LP64 objects, so if there's any doubt, we should assume that
7935 the official LP64 form is being used. */
d173146d 7936 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 7937 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7938 eh_addr_size = 8;
7939 break;
0f56a26a
DD
7940
7941 case EM_H8_300:
7942 case EM_H8_300H:
dda8d76d 7943 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7944 {
7945 case E_H8_MACH_H8300:
7946 case E_H8_MACH_H8300HN:
7947 case E_H8_MACH_H8300SN:
7948 case E_H8_MACH_H8300SXN:
7949 eh_addr_size = 2;
7950 break;
7951 case E_H8_MACH_H8300H:
7952 case E_H8_MACH_H8300S:
7953 case E_H8_MACH_H8300SX:
7954 eh_addr_size = 4;
7955 break;
7956 }
f4236fe4
DD
7957 break;
7958
ff7eeb89 7959 case EM_M32C_OLD:
f4236fe4 7960 case EM_M32C:
dda8d76d 7961 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7962 {
7963 case EF_M32C_CPU_M16C:
7964 eh_addr_size = 2;
7965 break;
7966 }
7967 break;
89fac5e3
RS
7968 }
7969
76ca31c0
NC
7970#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7971 do \
7972 { \
be7d229a 7973 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7974 if (section->sh_entsize != expected_entsize) \
9dd3a467 7975 { \
f493c217 7976 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7977 i, section->sh_entsize); \
f493c217 7978 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7979 expected_entsize); \
9dd3a467 7980 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7981 } \
7982 } \
08d8fa11 7983 while (0)
9dd3a467
NC
7984
7985#define CHECK_ENTSIZE(section, i, type) \
1b513401 7986 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7987 sizeof (Elf64_External_##type))
7988
dda8d76d
NC
7989 for (i = 0, section = filedata->section_headers;
7990 i < filedata->file_header.e_shnum;
b34976b6 7991 i++, section++)
252b5132 7992 {
b6ac461a 7993 const char *name = printable_section_name (filedata, section);
252b5132 7994
1b513401
NC
7995 /* Run some sanity checks on the headers and
7996 possibly fill in some file data as well. */
7997 switch (section->sh_type)
252b5132 7998 {
1b513401 7999 case SHT_DYNSYM:
978c4450 8000 if (filedata->dynamic_symbols != NULL)
252b5132
RH
8001 {
8002 error (_("File contains multiple dynamic symbol tables\n"));
8003 continue;
8004 }
8005
08d8fa11 8006 CHECK_ENTSIZE (section, i, Sym);
978c4450 8007 filedata->dynamic_symbols
4de91c10 8008 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 8009 filedata->dynamic_symtab_section = section;
1b513401
NC
8010 break;
8011
8012 case SHT_STRTAB:
8013 if (streq (name, ".dynstr"))
252b5132 8014 {
1b513401
NC
8015 if (filedata->dynamic_strings != NULL)
8016 {
8017 error (_("File contains multiple dynamic string tables\n"));
8018 continue;
8019 }
8020
8021 filedata->dynamic_strings
8022 = (char *) get_data (NULL, filedata, section->sh_offset,
8023 1, section->sh_size, _("dynamic strings"));
8024 filedata->dynamic_strings_length
8025 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 8026 filedata->dynamic_strtab_section = section;
252b5132 8027 }
1b513401
NC
8028 break;
8029
8030 case SHT_SYMTAB_SHNDX:
8031 {
8032 elf_section_list * entry = xmalloc (sizeof * entry);
8033
8034 entry->hdr = section;
8035 entry->next = filedata->symtab_shndx_list;
8036 filedata->symtab_shndx_list = entry;
8037 }
8038 break;
8039
8040 case SHT_SYMTAB:
8041 CHECK_ENTSIZE (section, i, Sym);
8042 break;
8043
8044 case SHT_GROUP:
8045 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8046 break;
252b5132 8047
1b513401
NC
8048 case SHT_REL:
8049 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 8050 if (do_checks && section->sh_size == 0)
1b513401
NC
8051 warn (_("Section '%s': zero-sized relocation section\n"), name);
8052 break;
8053
8054 case SHT_RELA:
8055 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 8056 if (do_checks && section->sh_size == 0)
1b513401
NC
8057 warn (_("Section '%s': zero-sized relocation section\n"), name);
8058 break;
8059
682351b9
AM
8060 case SHT_RELR:
8061 CHECK_ENTSIZE (section, i, Relr);
8062 break;
8063
1b513401
NC
8064 case SHT_NOTE:
8065 case SHT_PROGBITS:
546cb2d8
NC
8066 /* Having a zero sized section is not illegal according to the
8067 ELF standard, but it might be an indication that something
8068 is wrong. So issue a warning if we are running in lint mode. */
8069 if (do_checks && section->sh_size == 0)
1b513401
NC
8070 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8071 break;
8072
8073 default:
8074 break;
8075 }
8076
8077 if ((do_debugging || do_debug_info || do_debug_abbrevs
8078 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8079 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
8080 || do_debug_str || do_debug_str_offsets || do_debug_loc
8081 || do_debug_ranges
1b513401 8082 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
8083 && (startswith (name, ".debug_")
8084 || startswith (name, ".zdebug_")))
252b5132 8085 {
1b315056
CS
8086 if (name[1] == 'z')
8087 name += sizeof (".zdebug_") - 1;
8088 else
8089 name += sizeof (".debug_") - 1;
252b5132
RH
8090
8091 if (do_debugging
24d127aa
ML
8092 || (do_debug_info && startswith (name, "info"))
8093 || (do_debug_info && startswith (name, "types"))
8094 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 8095 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
8096 || (do_debug_lines && startswith (name, "line."))
8097 || (do_debug_pubnames && startswith (name, "pubnames"))
8098 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8099 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8100 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8101 || (do_debug_aranges && startswith (name, "aranges"))
8102 || (do_debug_ranges && startswith (name, "ranges"))
8103 || (do_debug_ranges && startswith (name, "rnglists"))
8104 || (do_debug_frames && startswith (name, "frame"))
8105 || (do_debug_macinfo && startswith (name, "macinfo"))
8106 || (do_debug_macinfo && startswith (name, "macro"))
8107 || (do_debug_str && startswith (name, "str"))
8108 || (do_debug_links && startswith (name, "sup"))
8109 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8110 || (do_debug_loc && startswith (name, "loc"))
8111 || (do_debug_loc && startswith (name, "loclists"))
8112 || (do_debug_addr && startswith (name, "addr"))
8113 || (do_debug_cu_index && startswith (name, "cu_index"))
8114 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 8115 )
6431e409 8116 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 8117 }
a262ae96 8118 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 8119 else if ((do_debugging || do_debug_info)
24d127aa 8120 && startswith (name, ".gnu.linkonce.wi."))
6431e409 8121 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 8122 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 8123 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
1878f44b
NC
8124 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8125 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
8126 else if (do_gdb_index && (streq (name, ".gdb_index")
8127 || streq (name, ".debug_names")))
6431e409 8128 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
8129 /* Trace sections for Itanium VMS. */
8130 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8131 || do_trace_aranges)
24d127aa 8132 && startswith (name, ".trace_"))
6f875884
TG
8133 {
8134 name += sizeof (".trace_") - 1;
8135
8136 if (do_debugging
8137 || (do_trace_info && streq (name, "info"))
8138 || (do_trace_abbrevs && streq (name, "abbrev"))
8139 || (do_trace_aranges && streq (name, "aranges"))
8140 )
6431e409 8141 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 8142 }
dda8d76d 8143 else if ((do_debugging || do_debug_links)
24d127aa
ML
8144 && (startswith (name, ".gnu_debuglink")
8145 || startswith (name, ".gnu_debugaltlink")))
6431e409 8146 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
8147 }
8148
8149 if (! do_sections)
015dc7e1 8150 return true;
252b5132 8151
ca0e11aa 8152 if (filedata->is_separate && ! process_links)
015dc7e1 8153 return true;
ca0e11aa
NC
8154
8155 if (filedata->is_separate)
8156 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
8157 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
8158 printf (_("\nSection Headers:\n"));
8159 else
8160 printf (_("\nSection Header:\n"));
76da6bbe 8161
f7a99963 8162 if (is_32bit_elf)
595cf52e 8163 {
5477e8a0 8164 if (do_section_details)
595cf52e
L
8165 {
8166 printf (_(" [Nr] Name\n"));
5477e8a0 8167 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
8168 }
8169 else
8170 printf
8171 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8172 }
d974e256 8173 else if (do_wide)
595cf52e 8174 {
5477e8a0 8175 if (do_section_details)
595cf52e
L
8176 {
8177 printf (_(" [Nr] Name\n"));
5477e8a0 8178 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
8179 }
8180 else
8181 printf
8182 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8183 }
f7a99963
NC
8184 else
8185 {
5477e8a0 8186 if (do_section_details)
595cf52e
L
8187 {
8188 printf (_(" [Nr] Name\n"));
5477e8a0
L
8189 printf (_(" Type Address Offset Link\n"));
8190 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
8191 }
8192 else
8193 {
8194 printf (_(" [Nr] Name Type Address Offset\n"));
8195 printf (_(" Size EntSize Flags Link Info Align\n"));
8196 }
f7a99963 8197 }
252b5132 8198
5477e8a0
L
8199 if (do_section_details)
8200 printf (_(" Flags\n"));
8201
dda8d76d
NC
8202 for (i = 0, section = filedata->section_headers;
8203 i < filedata->file_header.e_shnum;
b34976b6 8204 i++, section++)
252b5132 8205 {
dd905818
NC
8206 /* Run some sanity checks on the section header. */
8207
8208 /* Check the sh_link field. */
8209 switch (section->sh_type)
8210 {
285e3f99 8211 case SHT_REL:
fcf8f323 8212 case SHT_RELR:
285e3f99
AM
8213 case SHT_RELA:
8214 if (section->sh_link == 0
8215 && (filedata->file_header.e_type == ET_EXEC
8216 || filedata->file_header.e_type == ET_DYN))
8217 /* A dynamic relocation section where all entries use a
8218 zero symbol index need not specify a symtab section. */
8219 break;
8220 /* Fall through. */
dd905818
NC
8221 case SHT_SYMTAB_SHNDX:
8222 case SHT_GROUP:
8223 case SHT_HASH:
8224 case SHT_GNU_HASH:
8225 case SHT_GNU_versym:
285e3f99 8226 if (section->sh_link == 0
dda8d76d
NC
8227 || section->sh_link >= filedata->file_header.e_shnum
8228 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8229 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
8230 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8231 i, section->sh_link);
8232 break;
8233
8234 case SHT_DYNAMIC:
8235 case SHT_SYMTAB:
8236 case SHT_DYNSYM:
8237 case SHT_GNU_verneed:
8238 case SHT_GNU_verdef:
8239 case SHT_GNU_LIBLIST:
285e3f99 8240 if (section->sh_link == 0
dda8d76d
NC
8241 || section->sh_link >= filedata->file_header.e_shnum
8242 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8243 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8244 i, section->sh_link);
8245 break;
8246
8247 case SHT_INIT_ARRAY:
8248 case SHT_FINI_ARRAY:
8249 case SHT_PREINIT_ARRAY:
8250 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8251 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8252 i, section->sh_link);
8253 break;
8254
8255 default:
8256 /* FIXME: Add support for target specific section types. */
8257#if 0 /* Currently we do not check other section types as there are too
8258 many special cases. Stab sections for example have a type
8259 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8260 section. */
8261 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8262 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8263 i, section->sh_link);
8264#endif
8265 break;
8266 }
8267
8268 /* Check the sh_info field. */
8269 switch (section->sh_type)
8270 {
8271 case SHT_REL:
8272 case SHT_RELA:
285e3f99
AM
8273 if (section->sh_info == 0
8274 && (filedata->file_header.e_type == ET_EXEC
8275 || filedata->file_header.e_type == ET_DYN))
8276 /* Dynamic relocations apply to segments, so they do not
8277 need to specify the section they relocate. */
8278 break;
8279 if (section->sh_info == 0
dda8d76d
NC
8280 || section->sh_info >= filedata->file_header.e_shnum
8281 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8282 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8283 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8284 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8285 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8286 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8287 /* FIXME: Are other section types valid ? */
dda8d76d 8288 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8289 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8290 i, section->sh_info);
dd905818
NC
8291 break;
8292
8293 case SHT_DYNAMIC:
8294 case SHT_HASH:
8295 case SHT_SYMTAB_SHNDX:
8296 case SHT_INIT_ARRAY:
8297 case SHT_FINI_ARRAY:
8298 case SHT_PREINIT_ARRAY:
8299 if (section->sh_info != 0)
8300 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8301 i, section->sh_info);
8302 break;
8303
8304 case SHT_GROUP:
8305 case SHT_SYMTAB:
8306 case SHT_DYNSYM:
8307 /* A symbol index - we assume that it is valid. */
8308 break;
8309
8310 default:
8311 /* FIXME: Add support for target specific section types. */
8312 if (section->sh_type == SHT_NOBITS)
8313 /* NOBITS section headers with non-zero sh_info fields can be
8314 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8315 information. The stripped sections have their headers
8316 preserved but their types set to SHT_NOBITS. So do not check
8317 this type of section. */
dd905818
NC
8318 ;
8319 else if (section->sh_flags & SHF_INFO_LINK)
8320 {
dda8d76d 8321 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8322 warn (_("[%2u]: Expected link to another section in info field"), i);
8323 }
a91e1603
L
8324 else if (section->sh_type < SHT_LOOS
8325 && (section->sh_flags & SHF_GNU_MBIND) == 0
8326 && section->sh_info != 0)
dd905818
NC
8327 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8328 i, section->sh_info);
8329 break;
8330 }
8331
3e6b6445 8332 /* Check the sh_size field. */
dda8d76d 8333 if (section->sh_size > filedata->file_size
3e6b6445
NC
8334 && section->sh_type != SHT_NOBITS
8335 && section->sh_type != SHT_NULL
8336 && section->sh_type < SHT_LOOS)
8337 warn (_("Size of section %u is larger than the entire file!\n"), i);
8338
7bfd842d 8339 printf (" [%2u] ", i);
5477e8a0 8340 if (do_section_details)
dda8d76d 8341 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8342 else
b6ac461a 8343 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8344
ea52a088 8345 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8346 get_section_type_name (filedata, section->sh_type));
0b4362b0 8347
f7a99963
NC
8348 if (is_32bit_elf)
8349 {
cfcac11d
NC
8350 const char * link_too_big = NULL;
8351
f7a99963 8352 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8353
f7a99963
NC
8354 printf ( " %6.6lx %6.6lx %2.2lx",
8355 (unsigned long) section->sh_offset,
8356 (unsigned long) section->sh_size,
8357 (unsigned long) section->sh_entsize);
d1133906 8358
5477e8a0
L
8359 if (do_section_details)
8360 fputs (" ", stdout);
8361 else
dda8d76d 8362 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8363
dda8d76d 8364 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8365 {
8366 link_too_big = "";
8367 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8368 an error but it can have special values in Solaris binaries. */
dda8d76d 8369 switch (filedata->file_header.e_machine)
cfcac11d 8370 {
caa83f8b 8371 case EM_386:
22abe556 8372 case EM_IAMCU:
caa83f8b 8373 case EM_X86_64:
7f502d6c 8374 case EM_L1OM:
7a9068fe 8375 case EM_K1OM:
cfcac11d
NC
8376 case EM_OLD_SPARCV9:
8377 case EM_SPARC32PLUS:
8378 case EM_SPARCV9:
8379 case EM_SPARC:
8380 if (section->sh_link == (SHN_BEFORE & 0xffff))
8381 link_too_big = "BEFORE";
8382 else if (section->sh_link == (SHN_AFTER & 0xffff))
8383 link_too_big = "AFTER";
8384 break;
8385 default:
8386 break;
8387 }
8388 }
8389
8390 if (do_section_details)
8391 {
8392 if (link_too_big != NULL && * link_too_big)
8393 printf ("<%s> ", link_too_big);
8394 else
8395 printf ("%2u ", section->sh_link);
8396 printf ("%3u %2lu\n", section->sh_info,
8397 (unsigned long) section->sh_addralign);
8398 }
8399 else
8400 printf ("%2u %3u %2lu\n",
8401 section->sh_link,
8402 section->sh_info,
8403 (unsigned long) section->sh_addralign);
8404
8405 if (link_too_big && ! * link_too_big)
8406 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8407 i, section->sh_link);
f7a99963 8408 }
d974e256
JJ
8409 else if (do_wide)
8410 {
8411 print_vma (section->sh_addr, LONG_HEX);
8412
8413 if ((long) section->sh_offset == section->sh_offset)
8414 printf (" %6.6lx", (unsigned long) section->sh_offset);
8415 else
8416 {
8417 putchar (' ');
8418 print_vma (section->sh_offset, LONG_HEX);
8419 }
8420
8421 if ((unsigned long) section->sh_size == section->sh_size)
8422 printf (" %6.6lx", (unsigned long) section->sh_size);
8423 else
8424 {
8425 putchar (' ');
8426 print_vma (section->sh_size, LONG_HEX);
8427 }
8428
8429 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8430 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8431 else
8432 {
8433 putchar (' ');
8434 print_vma (section->sh_entsize, LONG_HEX);
8435 }
8436
5477e8a0
L
8437 if (do_section_details)
8438 fputs (" ", stdout);
8439 else
dda8d76d 8440 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8441
72de5009 8442 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8443
8444 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8445 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8446 else
8447 {
8448 print_vma (section->sh_addralign, DEC);
8449 putchar ('\n');
8450 }
8451 }
5477e8a0 8452 else if (do_section_details)
595cf52e 8453 {
55cc53e9 8454 putchar (' ');
595cf52e
L
8455 print_vma (section->sh_addr, LONG_HEX);
8456 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8457 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8458 else
8459 {
8460 printf (" ");
8461 print_vma (section->sh_offset, LONG_HEX);
8462 }
72de5009 8463 printf (" %u\n ", section->sh_link);
595cf52e 8464 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8465 putchar (' ');
595cf52e
L
8466 print_vma (section->sh_entsize, LONG_HEX);
8467
72de5009
AM
8468 printf (" %-16u %lu\n",
8469 section->sh_info,
595cf52e
L
8470 (unsigned long) section->sh_addralign);
8471 }
f7a99963
NC
8472 else
8473 {
8474 putchar (' ');
8475 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8476 if ((long) section->sh_offset == section->sh_offset)
8477 printf (" %8.8lx", (unsigned long) section->sh_offset);
8478 else
8479 {
8480 printf (" ");
8481 print_vma (section->sh_offset, LONG_HEX);
8482 }
f7a99963
NC
8483 printf ("\n ");
8484 print_vma (section->sh_size, LONG_HEX);
8485 printf (" ");
8486 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8487
dda8d76d 8488 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8489
72de5009
AM
8490 printf (" %2u %3u %lu\n",
8491 section->sh_link,
8492 section->sh_info,
f7a99963
NC
8493 (unsigned long) section->sh_addralign);
8494 }
5477e8a0
L
8495
8496 if (do_section_details)
77115a4a 8497 {
dda8d76d 8498 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8499 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8500 {
8501 /* Minimum section size is 12 bytes for 32-bit compression
8502 header + 12 bytes for compressed data header. */
8503 unsigned char buf[24];
d8024a91 8504
77115a4a 8505 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8506 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8507 sizeof (buf), _("compression header")))
8508 {
8509 Elf_Internal_Chdr chdr;
d8024a91 8510
5844b465
NC
8511 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8512 printf (_(" [<corrupt>]\n"));
77115a4a 8513 else
5844b465 8514 {
89dbeac7 8515 if (chdr.ch_type == ch_compress_zlib)
5844b465 8516 printf (" ZLIB, ");
89dbeac7 8517 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8518 printf (" ZSTD, ");
5844b465
NC
8519 else
8520 printf (_(" [<unknown>: 0x%x], "),
8521 chdr.ch_type);
8522 print_vma (chdr.ch_size, LONG_HEX);
8523 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8524 }
77115a4a
L
8525 }
8526 }
8527 }
252b5132
RH
8528 }
8529
5477e8a0 8530 if (!do_section_details)
3dbcc61d 8531 {
9fb71ee4
NC
8532 /* The ordering of the letters shown here matches the ordering of the
8533 corresponding SHF_xxx values, and hence the order in which these
8534 letters will be displayed to the user. */
8535 printf (_("Key to Flags:\n\
8536 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8537 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8538 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8539 switch (filedata->file_header.e_ident[EI_OSABI])
8540 {
8541 case ELFOSABI_GNU:
8542 case ELFOSABI_FREEBSD:
8543 printf (_("R (retain), "));
8544 /* Fall through */
8545 case ELFOSABI_NONE:
8546 printf (_("D (mbind), "));
8547 break;
8548 default:
8549 break;
8550 }
dda8d76d
NC
8551 if (filedata->file_header.e_machine == EM_X86_64
8552 || filedata->file_header.e_machine == EM_L1OM
8553 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8554 printf (_("l (large), "));
dda8d76d 8555 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8556 printf (_("y (purecode), "));
dda8d76d 8557 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8558 printf (_("v (VLE), "));
9fb71ee4 8559 printf ("p (processor specific)\n");
0b4362b0 8560 }
d1133906 8561
015dc7e1 8562 return true;
252b5132
RH
8563}
8564
015dc7e1 8565static bool
fcf8f323
NC
8566get_symtab (Filedata * filedata,
8567 Elf_Internal_Shdr * symsec,
8568 Elf_Internal_Sym ** symtab,
8569 uint64_t * nsyms,
8570 char ** strtab,
8571 uint64_t * strtablen)
28d13567
AM
8572{
8573 *strtab = NULL;
8574 *strtablen = 0;
4de91c10 8575 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8576
8577 if (*symtab == NULL)
015dc7e1 8578 return false;
28d13567
AM
8579
8580 if (symsec->sh_link != 0)
8581 {
8582 Elf_Internal_Shdr *strsec;
8583
8584 if (symsec->sh_link >= filedata->file_header.e_shnum)
8585 {
8586 error (_("Bad sh_link in symbol table section\n"));
8587 free (*symtab);
8588 *symtab = NULL;
8589 *nsyms = 0;
015dc7e1 8590 return false;
28d13567
AM
8591 }
8592
8593 strsec = filedata->section_headers + symsec->sh_link;
8594
8595 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8596 1, strsec->sh_size, _("string table"));
8597 if (*strtab == NULL)
8598 {
8599 free (*symtab);
8600 *symtab = NULL;
8601 *nsyms = 0;
015dc7e1 8602 return false;
28d13567
AM
8603 }
8604 *strtablen = strsec->sh_size;
8605 }
015dc7e1 8606 return true;
28d13567
AM
8607}
8608
f5842774
L
8609static const char *
8610get_group_flags (unsigned int flags)
8611{
1449284b 8612 static char buff[128];
220453ec 8613
6d913794
NC
8614 if (flags == 0)
8615 return "";
8616 else if (flags == GRP_COMDAT)
8617 return "COMDAT ";
f5842774 8618
89246a0e
AM
8619 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8620 flags,
8621 flags & GRP_MASKOS ? _("<OS specific>") : "",
8622 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8623 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8624 ? _("<unknown>") : ""));
6d913794 8625
f5842774
L
8626 return buff;
8627}
8628
015dc7e1 8629static bool
dda8d76d 8630process_section_groups (Filedata * filedata)
f5842774 8631{
2cf0635d 8632 Elf_Internal_Shdr * section;
f5842774 8633 unsigned int i;
2cf0635d
NC
8634 struct group * group;
8635 Elf_Internal_Shdr * symtab_sec;
8636 Elf_Internal_Shdr * strtab_sec;
8637 Elf_Internal_Sym * symtab;
26c527e6 8638 uint64_t num_syms;
2cf0635d 8639 char * strtab;
c256ffe7 8640 size_t strtab_size;
d1f5c6e3
L
8641
8642 /* Don't process section groups unless needed. */
8643 if (!do_unwind && !do_section_groups)
015dc7e1 8644 return true;
f5842774 8645
dda8d76d 8646 if (filedata->file_header.e_shnum == 0)
f5842774
L
8647 {
8648 if (do_section_groups)
ca0e11aa
NC
8649 {
8650 if (filedata->is_separate)
8651 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8652 filedata->file_name);
8653 else
8654 printf (_("\nThere are no section groups in this file.\n"));
8655 }
015dc7e1 8656 return true;
f5842774
L
8657 }
8658
dda8d76d 8659 if (filedata->section_headers == NULL)
f5842774
L
8660 {
8661 error (_("Section headers are not available!\n"));
fa1908fd 8662 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8663 return false;
f5842774
L
8664 }
8665
978c4450
AM
8666 filedata->section_headers_groups
8667 = (struct group **) calloc (filedata->file_header.e_shnum,
8668 sizeof (struct group *));
e4b17d5c 8669
978c4450 8670 if (filedata->section_headers_groups == NULL)
e4b17d5c 8671 {
8b73c356 8672 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8673 filedata->file_header.e_shnum);
015dc7e1 8674 return false;
e4b17d5c
L
8675 }
8676
f5842774 8677 /* Scan the sections for the group section. */
978c4450 8678 filedata->group_count = 0;
dda8d76d
NC
8679 for (i = 0, section = filedata->section_headers;
8680 i < filedata->file_header.e_shnum;
f5842774 8681 i++, section++)
e4b17d5c 8682 if (section->sh_type == SHT_GROUP)
978c4450 8683 filedata->group_count++;
e4b17d5c 8684
978c4450 8685 if (filedata->group_count == 0)
d1f5c6e3
L
8686 {
8687 if (do_section_groups)
ca0e11aa
NC
8688 {
8689 if (filedata->is_separate)
8690 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8691 filedata->file_name);
8692 else
8693 printf (_("\nThere are no section groups in this file.\n"));
8694 }
d1f5c6e3 8695
015dc7e1 8696 return true;
d1f5c6e3
L
8697 }
8698
978c4450
AM
8699 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8700 sizeof (struct group));
e4b17d5c 8701
978c4450 8702 if (filedata->section_groups == NULL)
e4b17d5c 8703 {
26c527e6 8704 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8705 return false;
e4b17d5c
L
8706 }
8707
d1f5c6e3
L
8708 symtab_sec = NULL;
8709 strtab_sec = NULL;
8710 symtab = NULL;
ba5cdace 8711 num_syms = 0;
d1f5c6e3 8712 strtab = NULL;
c256ffe7 8713 strtab_size = 0;
ca0e11aa
NC
8714
8715 if (filedata->is_separate)
8716 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8717
978c4450 8718 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8719 i < filedata->file_header.e_shnum;
e4b17d5c 8720 i++, section++)
f5842774
L
8721 {
8722 if (section->sh_type == SHT_GROUP)
8723 {
dda8d76d 8724 const char * name = printable_section_name (filedata, section);
74e1a04b 8725 const char * group_name;
2cf0635d
NC
8726 unsigned char * start;
8727 unsigned char * indices;
f5842774 8728 unsigned int entry, j, size;
2cf0635d
NC
8729 Elf_Internal_Shdr * sec;
8730 Elf_Internal_Sym * sym;
f5842774
L
8731
8732 /* Get the symbol table. */
dda8d76d
NC
8733 if (section->sh_link >= filedata->file_header.e_shnum
8734 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8735 != SHT_SYMTAB))
f5842774
L
8736 {
8737 error (_("Bad sh_link in group section `%s'\n"), name);
8738 continue;
8739 }
d1f5c6e3
L
8740
8741 if (symtab_sec != sec)
8742 {
8743 symtab_sec = sec;
9db70fc3 8744 free (symtab);
4de91c10 8745 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8746 }
f5842774 8747
dd24e3da
NC
8748 if (symtab == NULL)
8749 {
8750 error (_("Corrupt header in group section `%s'\n"), name);
8751 continue;
8752 }
8753
ba5cdace
NC
8754 if (section->sh_info >= num_syms)
8755 {
8756 error (_("Bad sh_info in group section `%s'\n"), name);
8757 continue;
8758 }
8759
f5842774
L
8760 sym = symtab + section->sh_info;
8761
8762 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8763 {
4fbb74a6 8764 if (sym->st_shndx == 0
dda8d76d 8765 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8766 {
8767 error (_("Bad sh_info in group section `%s'\n"), name);
8768 continue;
8769 }
ba2685cc 8770
b6ac461a
NC
8771 group_name = printable_section_name (filedata,
8772 filedata->section_headers
8773 + sym->st_shndx);
c256ffe7 8774 strtab_sec = NULL;
9db70fc3 8775 free (strtab);
f5842774 8776 strtab = NULL;
c256ffe7 8777 strtab_size = 0;
f5842774
L
8778 }
8779 else
8780 {
8781 /* Get the string table. */
dda8d76d 8782 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8783 {
8784 strtab_sec = NULL;
9db70fc3 8785 free (strtab);
c256ffe7
JJ
8786 strtab = NULL;
8787 strtab_size = 0;
8788 }
8789 else if (strtab_sec
dda8d76d 8790 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8791 {
8792 strtab_sec = sec;
9db70fc3 8793 free (strtab);
071436c6 8794
dda8d76d 8795 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8796 1, strtab_sec->sh_size,
8797 _("string table"));
c256ffe7 8798 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8799 }
c256ffe7 8800 group_name = sym->st_name < strtab_size
2b692964 8801 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8802 }
8803
c9c1d674
EG
8804 /* PR 17531: file: loop. */
8805 if (section->sh_entsize > section->sh_size)
8806 {
26c527e6
AM
8807 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8808 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8809 printable_section_name (filedata, section),
26c527e6
AM
8810 section->sh_entsize,
8811 section->sh_size);
61dd8e19 8812 continue;
c9c1d674
EG
8813 }
8814
dda8d76d 8815 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8816 1, section->sh_size,
8817 _("section data"));
59245841
NC
8818 if (start == NULL)
8819 continue;
f5842774
L
8820
8821 indices = start;
8822 size = (section->sh_size / section->sh_entsize) - 1;
8823 entry = byte_get (indices, 4);
8824 indices += 4;
e4b17d5c
L
8825
8826 if (do_section_groups)
8827 {
2b692964 8828 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8829 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8830
e4b17d5c
L
8831 printf (_(" [Index] Name\n"));
8832 }
8833
8834 group->group_index = i;
8835
f5842774
L
8836 for (j = 0; j < size; j++)
8837 {
2cf0635d 8838 struct group_list * g;
e4b17d5c 8839
f5842774
L
8840 entry = byte_get (indices, 4);
8841 indices += 4;
8842
dda8d76d 8843 if (entry >= filedata->file_header.e_shnum)
391cb864 8844 {
57028622
NC
8845 static unsigned num_group_errors = 0;
8846
8847 if (num_group_errors ++ < 10)
8848 {
8849 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8850 entry, i, filedata->file_header.e_shnum - 1);
57028622 8851 if (num_group_errors == 10)
67ce483b 8852 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8853 }
391cb864
L
8854 continue;
8855 }
391cb864 8856
978c4450 8857 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8858 {
d1f5c6e3
L
8859 if (entry)
8860 {
57028622
NC
8861 static unsigned num_errs = 0;
8862
8863 if (num_errs ++ < 10)
8864 {
8865 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8866 entry, i,
978c4450 8867 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8868 if (num_errs == 10)
8869 warn (_("Further error messages about already contained group sections suppressed\n"));
8870 }
d1f5c6e3
L
8871 continue;
8872 }
8873 else
8874 {
8875 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8876 section group. We just warn it the first time
d1f5c6e3 8877 and ignore it afterwards. */
015dc7e1 8878 static bool warned = false;
d1f5c6e3
L
8879 if (!warned)
8880 {
8881 error (_("section 0 in group section [%5u]\n"),
978c4450 8882 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8883 warned = true;
d1f5c6e3
L
8884 }
8885 }
e4b17d5c
L
8886 }
8887
978c4450 8888 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8889
8890 if (do_section_groups)
8891 {
dda8d76d
NC
8892 sec = filedata->section_headers + entry;
8893 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8894 }
8895
3f5e193b 8896 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8897 g->section_index = entry;
8898 g->next = group->root;
8899 group->root = g;
f5842774
L
8900 }
8901
9db70fc3 8902 free (start);
e4b17d5c
L
8903
8904 group++;
f5842774
L
8905 }
8906 }
8907
9db70fc3
AM
8908 free (symtab);
8909 free (strtab);
015dc7e1 8910 return true;
f5842774
L
8911}
8912
28f997cf
TG
8913/* Data used to display dynamic fixups. */
8914
8915struct ia64_vms_dynfixup
8916{
625d49fc
AM
8917 uint64_t needed_ident; /* Library ident number. */
8918 uint64_t needed; /* Index in the dstrtab of the library name. */
8919 uint64_t fixup_needed; /* Index of the library. */
8920 uint64_t fixup_rela_cnt; /* Number of fixups. */
8921 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8922};
8923
8924/* Data used to display dynamic relocations. */
8925
8926struct ia64_vms_dynimgrela
8927{
625d49fc
AM
8928 uint64_t img_rela_cnt; /* Number of relocations. */
8929 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8930};
8931
8932/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8933 library). */
8934
015dc7e1 8935static bool
dda8d76d
NC
8936dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8937 struct ia64_vms_dynfixup * fixup,
8938 const char * strtab,
8939 unsigned int strtab_sz)
28f997cf 8940{
32ec8896 8941 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8942 size_t i;
32ec8896 8943 const char * lib_name;
28f997cf 8944
978c4450
AM
8945 imfs = get_data (NULL, filedata,
8946 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8947 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8948 _("dynamic section image fixups"));
8949 if (!imfs)
015dc7e1 8950 return false;
28f997cf
TG
8951
8952 if (fixup->needed < strtab_sz)
8953 lib_name = strtab + fixup->needed;
8954 else
8955 {
26c527e6
AM
8956 warn (_("corrupt library name index of %#" PRIx64
8957 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8958 lib_name = "???";
8959 }
736990c4 8960
26c527e6
AM
8961 printf (_("\nImage fixups for needed library #%" PRId64
8962 ": %s - ident: %" PRIx64 "\n"),
8963 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8964 printf
8965 (_("Seg Offset Type SymVec DataType\n"));
8966
26c527e6 8967 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8968 {
8969 unsigned int type;
8970 const char *rtype;
8971
8972 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8973 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8974 type = BYTE_GET (imfs [i].type);
8975 rtype = elf_ia64_reloc_type (type);
8976 if (rtype == NULL)
f493c217 8977 printf ("0x%08x ", type);
28f997cf 8978 else
f493c217 8979 printf ("%-32s ", rtype);
28f997cf
TG
8980 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8981 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8982 }
8983
8984 free (imfs);
015dc7e1 8985 return true;
28f997cf
TG
8986}
8987
8988/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8989
015dc7e1 8990static bool
dda8d76d 8991dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8992{
8993 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8994 size_t i;
28f997cf 8995
978c4450
AM
8996 imrs = get_data (NULL, filedata,
8997 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8998 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8999 _("dynamic section image relocations"));
28f997cf 9000 if (!imrs)
015dc7e1 9001 return false;
28f997cf
TG
9002
9003 printf (_("\nImage relocs\n"));
9004 printf
9005 (_("Seg Offset Type Addend Seg Sym Off\n"));
9006
26c527e6 9007 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
9008 {
9009 unsigned int type;
9010 const char *rtype;
9011
9012 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 9013 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
9014 type = BYTE_GET (imrs [i].type);
9015 rtype = elf_ia64_reloc_type (type);
9016 if (rtype == NULL)
9017 printf ("0x%08x ", type);
9018 else
9019 printf ("%-31s ", rtype);
9020 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9021 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 9022 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
9023 }
9024
9025 free (imrs);
015dc7e1 9026 return true;
28f997cf
TG
9027}
9028
9029/* Display IA-64 OpenVMS dynamic relocations and fixups. */
9030
015dc7e1 9031static bool
dda8d76d 9032process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
9033{
9034 struct ia64_vms_dynfixup fixup;
9035 struct ia64_vms_dynimgrela imgrela;
9036 Elf_Internal_Dyn *entry;
625d49fc
AM
9037 uint64_t strtab_off = 0;
9038 uint64_t strtab_sz = 0;
28f997cf 9039 char *strtab = NULL;
015dc7e1 9040 bool res = true;
28f997cf
TG
9041
9042 memset (&fixup, 0, sizeof (fixup));
9043 memset (&imgrela, 0, sizeof (imgrela));
9044
9045 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
9046 for (entry = filedata->dynamic_section;
9047 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
9048 entry++)
9049 {
9050 switch (entry->d_tag)
9051 {
9052 case DT_IA_64_VMS_STRTAB_OFFSET:
9053 strtab_off = entry->d_un.d_val;
9054 break;
9055 case DT_STRSZ:
9056 strtab_sz = entry->d_un.d_val;
9057 if (strtab == NULL)
978c4450
AM
9058 strtab = get_data (NULL, filedata,
9059 filedata->dynamic_addr + strtab_off,
28f997cf 9060 1, strtab_sz, _("dynamic string section"));
736990c4
NC
9061 if (strtab == NULL)
9062 strtab_sz = 0;
28f997cf
TG
9063 break;
9064
9065 case DT_IA_64_VMS_NEEDED_IDENT:
9066 fixup.needed_ident = entry->d_un.d_val;
9067 break;
9068 case DT_NEEDED:
9069 fixup.needed = entry->d_un.d_val;
9070 break;
9071 case DT_IA_64_VMS_FIXUP_NEEDED:
9072 fixup.fixup_needed = entry->d_un.d_val;
9073 break;
9074 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9075 fixup.fixup_rela_cnt = entry->d_un.d_val;
9076 break;
9077 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9078 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 9079 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 9080 res = false;
28f997cf 9081 break;
28f997cf
TG
9082 case DT_IA_64_VMS_IMG_RELA_CNT:
9083 imgrela.img_rela_cnt = entry->d_un.d_val;
9084 break;
9085 case DT_IA_64_VMS_IMG_RELA_OFF:
9086 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 9087 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 9088 res = false;
28f997cf
TG
9089 break;
9090
9091 default:
9092 break;
9093 }
9094 }
9095
9db70fc3 9096 free (strtab);
28f997cf
TG
9097
9098 return res;
9099}
9100
85b1c36d 9101static struct
566b0d53 9102{
2cf0635d 9103 const char * name;
566b0d53
L
9104 int reloc;
9105 int size;
a7fd1186 9106 relocation_type rel_type;
32ec8896
NC
9107}
9108 dynamic_relocations [] =
566b0d53 9109{
a7fd1186
FS
9110 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9111 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9112 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9113 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
9114};
9115
8e8d0b63
NC
9116static relocation_type
9117rel_type_from_sh_type (unsigned int sh_type)
9118{
9119 switch (sh_type)
9120 {
9121 case SHT_RELA: return reltype_rela;
9122 case SHT_REL: return reltype_rel;
9123 case SHT_RELR: return reltype_relr;
9124 default: return reltype_unknown;
9125 }
9126}
9127
9128static bool
9129display_relocations (Elf_Internal_Shdr * section,
9130 Filedata * filedata)
9131{
fcf8f323
NC
9132 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9133
9134 if (rel_type == reltype_unknown)
8e8d0b63
NC
9135 return false;
9136
9137 uint64_t rel_size = section->sh_size;
9138
9139 if (rel_size == 0)
9140 return false;
9141
9142 if (filedata->is_separate)
9143 printf (_("\nIn linked file '%s' relocation section "),
9144 filedata->file_name);
9145 else
9146 printf (_("\nRelocation section "));
9147
9148 if (filedata->string_table == NULL)
9149 printf ("%d", section->sh_name);
9150 else
9151 printf ("'%s'", printable_section_name (filedata, section));
9152
9153 uint64_t num_rela = rel_size / section->sh_entsize;
9154 uint64_t rel_offset = section->sh_offset;
9155
3b3e2090
NC
9156 if (rel_type == reltype_relr)
9157 {
9158 /* Just stating the 'number of entries' in a RELR section can be
9159 misleading, since this is not the number of locations relocated, but
9160 the number of words in the compressed RELR format. So also provide
9161 the number of locations affected. */
9162 if (num_rela == 1)
9163 /* This is unlikely, but possible. */
9164 printf (_(" at offset %#" PRIx64
9165 " contains 1 entry which relocates 1 location:\n"),
9166 rel_offset);
9167 else
9168 printf (_(" at offset %#" PRIx64 " contains %" PRIu64
9169 " entries which relocate %" PRIu64 " locations:\n"),
9170 rel_offset, num_rela, count_relr_relocations (filedata, section));
9171 }
9172 else
9173 {
9174 printf (ngettext (" at offset %#" PRIx64
9175 " contains %" PRIu64 " entry:\n",
9176 " at offset %#" PRIx64
9177 " contains %" PRIu64 " entries:\n",
9178 num_rela),
9179 rel_offset, num_rela);
9180 }
8e8d0b63 9181
fcf8f323
NC
9182 Elf_Internal_Shdr * symsec;
9183 Elf_Internal_Sym * symtab = NULL;
9184 uint64_t nsyms = 0;
9185 uint64_t strtablen = 0;
9186 char * strtab = NULL;
8e8d0b63
NC
9187
9188 if (section->sh_link == 0
9189 || section->sh_link >= filedata->file_header.e_shnum)
fcf8f323
NC
9190 {
9191 /* Symbol data not available.
9192 This can happen, especially with RELR relocs.
9193 See if there is a .symtab section present.
9194 If so then use it. */
9195 symsec = find_section_by_name (filedata, ".symtab");
9196 }
9197 else
9198 {
9199 symsec = filedata->section_headers + section->sh_link;
8e8d0b63 9200
fcf8f323
NC
9201 if (symsec->sh_type != SHT_SYMTAB
9202 && symsec->sh_type != SHT_DYNSYM)
9203 return false;
9204 }
8e8d0b63 9205
fcf8f323
NC
9206 if (symsec != NULL
9207 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
8e8d0b63
NC
9208 return false;
9209
fcf8f323
NC
9210 bool res;
9211
9212 if (rel_type == reltype_relr)
9213 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9214 else
9215 res = dump_relocations (filedata, rel_offset, rel_size,
9216 symtab, nsyms, strtab, strtablen,
9217 rel_type,
9218 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
8e8d0b63
NC
9219 free (strtab);
9220 free (symtab);
9221
9222 return res;
9223}
9224
252b5132 9225/* Process the reloc section. */
18bd398b 9226
015dc7e1 9227static bool
dda8d76d 9228process_relocs (Filedata * filedata)
252b5132 9229{
26c527e6
AM
9230 uint64_t rel_size;
9231 uint64_t rel_offset;
252b5132 9232
252b5132 9233 if (!do_reloc)
015dc7e1 9234 return true;
252b5132
RH
9235
9236 if (do_using_dynamic)
9237 {
a7fd1186 9238 relocation_type rel_type;
2cf0635d 9239 const char * name;
015dc7e1 9240 bool has_dynamic_reloc;
566b0d53 9241 unsigned int i;
0de14b54 9242
015dc7e1 9243 has_dynamic_reloc = false;
252b5132 9244
566b0d53 9245 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 9246 {
a7fd1186 9247 rel_type = dynamic_relocations [i].rel_type;
566b0d53 9248 name = dynamic_relocations [i].name;
978c4450
AM
9249 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9250 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 9251
32ec8896 9252 if (rel_size)
015dc7e1 9253 has_dynamic_reloc = true;
566b0d53 9254
a7fd1186 9255 if (rel_type == reltype_unknown)
aa903cfb 9256 {
566b0d53 9257 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 9258 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
9259 {
9260 case DT_REL:
a7fd1186 9261 rel_type = reltype_rel;
566b0d53
L
9262 break;
9263 case DT_RELA:
a7fd1186 9264 rel_type = reltype_rela;
566b0d53
L
9265 break;
9266 }
aa903cfb 9267 }
252b5132 9268
566b0d53
L
9269 if (rel_size)
9270 {
ca0e11aa
NC
9271 if (filedata->is_separate)
9272 printf
26c527e6
AM
9273 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9274 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
9275 filedata->file_name, name, rel_offset, rel_size);
9276 else
9277 printf
26c527e6
AM
9278 (_("\n'%s' relocation section at offset %#" PRIx64
9279 " contains %" PRId64 " bytes:\n"),
ca0e11aa 9280 name, rel_offset, rel_size);
252b5132 9281
dda8d76d
NC
9282 dump_relocations (filedata,
9283 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 9284 rel_size,
978c4450
AM
9285 filedata->dynamic_symbols,
9286 filedata->num_dynamic_syms,
9287 filedata->dynamic_strings,
9288 filedata->dynamic_strings_length,
a7fd1186 9289 rel_type, true /* is_dynamic */);
566b0d53 9290 }
252b5132 9291 }
566b0d53 9292
dda8d76d
NC
9293 if (is_ia64_vms (filedata))
9294 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 9295 has_dynamic_reloc = true;
28f997cf 9296
566b0d53 9297 if (! has_dynamic_reloc)
ca0e11aa
NC
9298 {
9299 if (filedata->is_separate)
9300 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9301 filedata->file_name);
9302 else
9303 printf (_("\nThere are no dynamic relocations in this file.\n"));
9304 }
252b5132
RH
9305 }
9306 else
9307 {
2cf0635d 9308 Elf_Internal_Shdr * section;
26c527e6 9309 size_t i;
015dc7e1 9310 bool found = false;
252b5132 9311
dda8d76d
NC
9312 for (i = 0, section = filedata->section_headers;
9313 i < filedata->file_header.e_shnum;
b34976b6 9314 i++, section++)
252b5132 9315 {
8e8d0b63
NC
9316 if (display_relocations (section, filedata))
9317 found = true;
252b5132
RH
9318 }
9319
9320 if (! found)
45ac8f4f
NC
9321 {
9322 /* Users sometimes forget the -D option, so try to be helpful. */
9323 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9324 {
978c4450 9325 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9326 {
ca0e11aa
NC
9327 if (filedata->is_separate)
9328 printf (_("\nThere are no static relocations in linked file '%s'."),
9329 filedata->file_name);
9330 else
9331 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9332 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9333
9334 break;
9335 }
9336 }
9337 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9338 {
9339 if (filedata->is_separate)
9340 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9341 filedata->file_name);
9342 else
9343 printf (_("\nThere are no relocations in this file.\n"));
9344 }
45ac8f4f 9345 }
252b5132
RH
9346 }
9347
015dc7e1 9348 return true;
252b5132
RH
9349}
9350
4d6ed7c8
NC
9351/* An absolute address consists of a section and an offset. If the
9352 section is NULL, the offset itself is the address, otherwise, the
9353 address equals to LOAD_ADDRESS(section) + offset. */
9354
9355struct absaddr
948f632f
DA
9356{
9357 unsigned short section;
625d49fc 9358 uint64_t offset;
948f632f 9359};
4d6ed7c8 9360
948f632f
DA
9361/* Find the nearest symbol at or below ADDR. Returns the symbol
9362 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9363
4d6ed7c8 9364static void
26c527e6
AM
9365find_symbol_for_address (Filedata *filedata,
9366 Elf_Internal_Sym *symtab,
9367 uint64_t nsyms,
9368 const char *strtab,
9369 uint64_t strtab_size,
9370 struct absaddr addr,
9371 const char **symname,
9372 uint64_t *offset)
4d6ed7c8 9373{
625d49fc 9374 uint64_t dist = 0x100000;
2cf0635d 9375 Elf_Internal_Sym * sym;
948f632f
DA
9376 Elf_Internal_Sym * beg;
9377 Elf_Internal_Sym * end;
2cf0635d 9378 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9379
0b6ae522 9380 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9381 beg = symtab;
9382 end = symtab + nsyms;
0b6ae522 9383
948f632f 9384 while (beg < end)
4d6ed7c8 9385 {
625d49fc 9386 uint64_t value;
948f632f
DA
9387
9388 sym = beg + (end - beg) / 2;
0b6ae522 9389
948f632f 9390 value = sym->st_value;
0b6ae522
DJ
9391 REMOVE_ARCH_BITS (value);
9392
948f632f 9393 if (sym->st_name != 0
4d6ed7c8 9394 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9395 && addr.offset >= value
9396 && addr.offset - value < dist)
4d6ed7c8
NC
9397 {
9398 best = sym;
0b6ae522 9399 dist = addr.offset - value;
4d6ed7c8
NC
9400 if (!dist)
9401 break;
9402 }
948f632f
DA
9403
9404 if (addr.offset < value)
9405 end = sym;
9406 else
9407 beg = sym + 1;
4d6ed7c8 9408 }
1b31d05e 9409
4d6ed7c8
NC
9410 if (best)
9411 {
57346661 9412 *symname = (best->st_name >= strtab_size
2b692964 9413 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9414 *offset = dist;
9415 return;
9416 }
1b31d05e 9417
4d6ed7c8
NC
9418 *symname = NULL;
9419 *offset = addr.offset;
9420}
9421
948f632f
DA
9422/* Process the unwind section. */
9423
9424#include "unwind-ia64.h"
9425
9426struct ia64_unw_table_entry
9427{
9428 struct absaddr start;
9429 struct absaddr end;
9430 struct absaddr info;
9431};
9432
9433struct ia64_unw_aux_info
9434{
32ec8896 9435 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9436 uint64_t table_len; /* Length of unwind table. */
32ec8896 9437 unsigned char * info; /* Unwind info. */
26c527e6 9438 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9439 uint64_t info_addr; /* Starting address of unwind info. */
9440 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9441 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9442 uint64_t nsyms; /* Number of symbols. */
32ec8896 9443 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9444 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9445 char * strtab; /* The string table. */
26c527e6 9446 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9447};
9448
015dc7e1 9449static bool
dda8d76d 9450dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9451{
2cf0635d 9452 struct ia64_unw_table_entry * tp;
26c527e6 9453 size_t j, nfuns;
4d6ed7c8 9454 int in_body;
015dc7e1 9455 bool res = true;
7036c0e1 9456
948f632f
DA
9457 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9458 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9459 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9460 aux->funtab[nfuns++] = aux->symtab[j];
9461 aux->nfuns = nfuns;
9462 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9463
4d6ed7c8
NC
9464 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9465 {
625d49fc
AM
9466 uint64_t stamp;
9467 uint64_t offset;
2cf0635d
NC
9468 const unsigned char * dp;
9469 const unsigned char * head;
53774b7e 9470 const unsigned char * end;
2cf0635d 9471 const char * procname;
4d6ed7c8 9472
dda8d76d 9473 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9474 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9475
9476 fputs ("\n<", stdout);
9477
9478 if (procname)
9479 {
9480 fputs (procname, stdout);
9481
9482 if (offset)
26c527e6 9483 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9484 }
9485
9486 fputs (">: [", stdout);
9487 print_vma (tp->start.offset, PREFIX_HEX);
9488 fputc ('-', stdout);
9489 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9490 printf ("], info at +0x%" PRIx64 "\n",
9491 tp->info.offset - aux->seg_base);
4d6ed7c8 9492
53774b7e
NC
9493 /* PR 17531: file: 86232b32. */
9494 if (aux->info == NULL)
9495 continue;
9496
97c0a079
AM
9497 offset = tp->info.offset;
9498 if (tp->info.section)
9499 {
9500 if (tp->info.section >= filedata->file_header.e_shnum)
9501 {
26c527e6
AM
9502 warn (_("Invalid section %u in table entry %td\n"),
9503 tp->info.section, tp - aux->table);
015dc7e1 9504 res = false;
97c0a079
AM
9505 continue;
9506 }
9507 offset += filedata->section_headers[tp->info.section].sh_addr;
9508 }
9509 offset -= aux->info_addr;
53774b7e 9510 /* PR 17531: file: 0997b4d1. */
90679903
AM
9511 if (offset >= aux->info_size
9512 || aux->info_size - offset < 8)
53774b7e 9513 {
26c527e6
AM
9514 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9515 tp->info.offset, tp - aux->table);
015dc7e1 9516 res = false;
53774b7e
NC
9517 continue;
9518 }
9519
97c0a079 9520 head = aux->info + offset;
a4a00738 9521 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9522
86f55779 9523 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9524 (unsigned) UNW_VER (stamp),
9525 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9526 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9527 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9528 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9529
9530 if (UNW_VER (stamp) != 1)
9531 {
2b692964 9532 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9533 continue;
9534 }
9535
9536 in_body = 0;
53774b7e
NC
9537 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9538 /* PR 17531: file: 16ceda89. */
9539 if (end > aux->info + aux->info_size)
9540 end = aux->info + aux->info_size;
9541 for (dp = head + 8; dp < end;)
b4477bc8 9542 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9543 }
948f632f
DA
9544
9545 free (aux->funtab);
32ec8896
NC
9546
9547 return res;
4d6ed7c8
NC
9548}
9549
015dc7e1 9550static bool
dda8d76d
NC
9551slurp_ia64_unwind_table (Filedata * filedata,
9552 struct ia64_unw_aux_info * aux,
9553 Elf_Internal_Shdr * sec)
4d6ed7c8 9554{
26c527e6 9555 uint64_t size, nrelas, i;
2cf0635d
NC
9556 Elf_Internal_Phdr * seg;
9557 struct ia64_unw_table_entry * tep;
9558 Elf_Internal_Shdr * relsec;
9559 Elf_Internal_Rela * rela;
9560 Elf_Internal_Rela * rp;
9561 unsigned char * table;
9562 unsigned char * tp;
9563 Elf_Internal_Sym * sym;
9564 const char * relname;
4d6ed7c8 9565
53774b7e
NC
9566 aux->table_len = 0;
9567
4d6ed7c8
NC
9568 /* First, find the starting address of the segment that includes
9569 this section: */
9570
dda8d76d 9571 if (filedata->file_header.e_phnum)
4d6ed7c8 9572 {
dda8d76d 9573 if (! get_program_headers (filedata))
015dc7e1 9574 return false;
4d6ed7c8 9575
dda8d76d
NC
9576 for (seg = filedata->program_headers;
9577 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9578 ++seg)
4d6ed7c8
NC
9579 {
9580 if (seg->p_type != PT_LOAD)
9581 continue;
9582
9583 if (sec->sh_addr >= seg->p_vaddr
9584 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9585 {
9586 aux->seg_base = seg->p_vaddr;
9587 break;
9588 }
9589 }
4d6ed7c8
NC
9590 }
9591
9592 /* Second, build the unwind table from the contents of the unwind section: */
9593 size = sec->sh_size;
dda8d76d 9594 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9595 _("unwind table"));
a6e9f9df 9596 if (!table)
015dc7e1 9597 return false;
4d6ed7c8 9598
53774b7e 9599 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9600 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9601 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9602 tep = aux->table;
53774b7e
NC
9603
9604 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9605 {
9606 tep->start.section = SHN_UNDEF;
9607 tep->end.section = SHN_UNDEF;
9608 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9609 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9610 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9611 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9612 tep->start.offset += aux->seg_base;
9613 tep->end.offset += aux->seg_base;
9614 tep->info.offset += aux->seg_base;
9615 }
9616 free (table);
9617
41e92641 9618 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9619 for (relsec = filedata->section_headers;
9620 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9621 ++relsec)
9622 {
9623 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9624 || relsec->sh_info >= filedata->file_header.e_shnum
9625 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9626 continue;
9627
dda8d76d 9628 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9629 & rela, & nrelas))
53774b7e
NC
9630 {
9631 free (aux->table);
9632 aux->table = NULL;
9633 aux->table_len = 0;
015dc7e1 9634 return false;
53774b7e 9635 }
4d6ed7c8
NC
9636
9637 for (rp = rela; rp < rela + nrelas; ++rp)
9638 {
4770fb94 9639 unsigned int sym_ndx;
726bd37d
AM
9640 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9641 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9642
82b1b41b
NC
9643 /* PR 17531: file: 9fa67536. */
9644 if (relname == NULL)
9645 {
726bd37d 9646 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9647 continue;
9648 }
948f632f 9649
24d127aa 9650 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9651 {
82b1b41b 9652 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9653 continue;
9654 }
9655
89fac5e3 9656 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9657
53774b7e
NC
9658 /* PR 17531: file: 5bc8d9bf. */
9659 if (i >= aux->table_len)
9660 {
26c527e6
AM
9661 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9662 i);
53774b7e
NC
9663 continue;
9664 }
9665
4770fb94
AM
9666 sym_ndx = get_reloc_symindex (rp->r_info);
9667 if (sym_ndx >= aux->nsyms)
9668 {
9669 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9670 sym_ndx);
9671 continue;
9672 }
9673 sym = aux->symtab + sym_ndx;
9674
53774b7e 9675 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9676 {
9677 case 0:
9678 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9679 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9680 break;
9681 case 1:
9682 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9683 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9684 break;
9685 case 2:
9686 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9687 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9688 break;
9689 default:
9690 break;
9691 }
9692 }
9693
9694 free (rela);
9695 }
9696
015dc7e1 9697 return true;
4d6ed7c8
NC
9698}
9699
015dc7e1 9700static bool
dda8d76d 9701ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9702{
2cf0635d
NC
9703 Elf_Internal_Shdr * sec;
9704 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9705 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9706 struct ia64_unw_aux_info aux;
015dc7e1 9707 bool res = true;
f1467e33 9708
4d6ed7c8
NC
9709 memset (& aux, 0, sizeof (aux));
9710
dda8d76d 9711 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9712 {
28d13567 9713 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9714 {
28d13567 9715 if (aux.symtab)
4082ef84 9716 {
28d13567
AM
9717 error (_("Multiple symbol tables encountered\n"));
9718 free (aux.symtab);
9719 aux.symtab = NULL;
4082ef84 9720 free (aux.strtab);
28d13567 9721 aux.strtab = NULL;
4082ef84 9722 }
28d13567
AM
9723 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9724 &aux.strtab, &aux.strtab_size))
015dc7e1 9725 return false;
4d6ed7c8
NC
9726 }
9727 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9728 unwcount++;
9729 }
9730
9731 if (!unwcount)
9732 printf (_("\nThere are no unwind sections in this file.\n"));
9733
9734 while (unwcount-- > 0)
9735 {
84714f86 9736 const char *suffix;
579f31ac
JJ
9737 size_t len, len2;
9738
dda8d76d
NC
9739 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9740 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9741 if (sec->sh_type == SHT_IA_64_UNWIND)
9742 {
9743 unwsec = sec;
9744 break;
9745 }
4082ef84
NC
9746 /* We have already counted the number of SHT_IA64_UNWIND
9747 sections so the loop above should never fail. */
9748 assert (unwsec != NULL);
579f31ac
JJ
9749
9750 unwstart = i + 1;
9751 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9752
e4b17d5c
L
9753 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9754 {
9755 /* We need to find which section group it is in. */
4082ef84 9756 struct group_list * g;
e4b17d5c 9757
978c4450
AM
9758 if (filedata->section_headers_groups == NULL
9759 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9760 i = filedata->file_header.e_shnum;
4082ef84 9761 else
e4b17d5c 9762 {
978c4450 9763 g = filedata->section_headers_groups[i]->root;
18bd398b 9764
4082ef84
NC
9765 for (; g != NULL; g = g->next)
9766 {
dda8d76d 9767 sec = filedata->section_headers + g->section_index;
e4b17d5c 9768
84714f86
AM
9769 if (section_name_valid (filedata, sec)
9770 && streq (section_name (filedata, sec),
9771 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9772 break;
9773 }
9774
9775 if (g == NULL)
dda8d76d 9776 i = filedata->file_header.e_shnum;
4082ef84 9777 }
e4b17d5c 9778 }
84714f86
AM
9779 else if (section_name_valid (filedata, unwsec)
9780 && startswith (section_name (filedata, unwsec),
e9b095a5 9781 ELF_STRING_ia64_unwind_once))
579f31ac 9782 {
18bd398b 9783 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9784 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9785 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9786 for (i = 0, sec = filedata->section_headers;
9787 i < filedata->file_header.e_shnum;
579f31ac 9788 ++i, ++sec)
84714f86
AM
9789 if (section_name_valid (filedata, sec)
9790 && startswith (section_name (filedata, sec),
e9b095a5 9791 ELF_STRING_ia64_unwind_info_once)
84714f86 9792 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9793 break;
9794 }
9795 else
9796 {
9797 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9798 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9799 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9800 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9801 suffix = "";
84714f86
AM
9802 if (section_name_valid (filedata, unwsec)
9803 && startswith (section_name (filedata, unwsec),
9804 ELF_STRING_ia64_unwind))
9805 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9806 for (i = 0, sec = filedata->section_headers;
9807 i < filedata->file_header.e_shnum;
579f31ac 9808 ++i, ++sec)
84714f86
AM
9809 if (section_name_valid (filedata, sec)
9810 && startswith (section_name (filedata, sec),
9811 ELF_STRING_ia64_unwind_info)
9812 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9813 break;
9814 }
9815
dda8d76d 9816 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9817 {
9818 printf (_("\nCould not find unwind info section for "));
9819
dda8d76d 9820 if (filedata->string_table == NULL)
579f31ac
JJ
9821 printf ("%d", unwsec->sh_name);
9822 else
dda8d76d 9823 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9824 }
9825 else
4d6ed7c8 9826 {
4d6ed7c8 9827 aux.info_addr = sec->sh_addr;
dda8d76d 9828 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9829 sec->sh_size,
9830 _("unwind info"));
59245841 9831 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9832
579f31ac 9833 printf (_("\nUnwind section "));
4d6ed7c8 9834
dda8d76d 9835 if (filedata->string_table == NULL)
579f31ac
JJ
9836 printf ("%d", unwsec->sh_name);
9837 else
dda8d76d 9838 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9839
26c527e6
AM
9840 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9841 unwsec->sh_offset,
9842 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9843
dda8d76d 9844 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9845 && aux.table_len > 0)
dda8d76d 9846 dump_ia64_unwind (filedata, & aux);
579f31ac 9847
9db70fc3
AM
9848 free ((char *) aux.table);
9849 free ((char *) aux.info);
579f31ac
JJ
9850 aux.table = NULL;
9851 aux.info = NULL;
9852 }
4d6ed7c8 9853 }
4d6ed7c8 9854
9db70fc3
AM
9855 free (aux.symtab);
9856 free ((char *) aux.strtab);
32ec8896
NC
9857
9858 return res;
4d6ed7c8
NC
9859}
9860
3f5e193b 9861struct hppa_unw_table_entry
32ec8896
NC
9862{
9863 struct absaddr start;
9864 struct absaddr end;
9865 unsigned int Cannot_unwind:1; /* 0 */
9866 unsigned int Millicode:1; /* 1 */
9867 unsigned int Millicode_save_sr0:1; /* 2 */
9868 unsigned int Region_description:2; /* 3..4 */
9869 unsigned int reserved1:1; /* 5 */
9870 unsigned int Entry_SR:1; /* 6 */
9871 unsigned int Entry_FR:4; /* Number saved 7..10 */
9872 unsigned int Entry_GR:5; /* Number saved 11..15 */
9873 unsigned int Args_stored:1; /* 16 */
9874 unsigned int Variable_Frame:1; /* 17 */
9875 unsigned int Separate_Package_Body:1; /* 18 */
9876 unsigned int Frame_Extension_Millicode:1; /* 19 */
9877 unsigned int Stack_Overflow_Check:1; /* 20 */
9878 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9879 unsigned int Ada_Region:1; /* 22 */
9880 unsigned int cxx_info:1; /* 23 */
9881 unsigned int cxx_try_catch:1; /* 24 */
9882 unsigned int sched_entry_seq:1; /* 25 */
9883 unsigned int reserved2:1; /* 26 */
9884 unsigned int Save_SP:1; /* 27 */
9885 unsigned int Save_RP:1; /* 28 */
9886 unsigned int Save_MRP_in_frame:1; /* 29 */
9887 unsigned int extn_ptr_defined:1; /* 30 */
9888 unsigned int Cleanup_defined:1; /* 31 */
9889
9890 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9891 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9892 unsigned int Large_frame:1; /* 2 */
9893 unsigned int Pseudo_SP_Set:1; /* 3 */
9894 unsigned int reserved4:1; /* 4 */
9895 unsigned int Total_frame_size:27; /* 5..31 */
9896};
3f5e193b 9897
57346661 9898struct hppa_unw_aux_info
948f632f 9899{
32ec8896 9900 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9901 uint64_t table_len; /* Length of unwind table. */
625d49fc 9902 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9903 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9904 uint64_t nsyms; /* Number of symbols. */
32ec8896 9905 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9906 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9907 char * strtab; /* The string table. */
26c527e6 9908 uint64_t strtab_size; /* Size of string table. */
948f632f 9909};
57346661 9910
015dc7e1 9911static bool
dda8d76d 9912dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9913{
2cf0635d 9914 struct hppa_unw_table_entry * tp;
26c527e6 9915 uint64_t j, nfuns;
015dc7e1 9916 bool res = true;
948f632f
DA
9917
9918 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9919 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9920 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9921 aux->funtab[nfuns++] = aux->symtab[j];
9922 aux->nfuns = nfuns;
9923 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9924
57346661
AM
9925 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9926 {
625d49fc 9927 uint64_t offset;
2cf0635d 9928 const char * procname;
57346661 9929
dda8d76d 9930 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9931 aux->strtab_size, tp->start, &procname,
9932 &offset);
9933
9934 fputs ("\n<", stdout);
9935
9936 if (procname)
9937 {
9938 fputs (procname, stdout);
9939
9940 if (offset)
26c527e6 9941 printf ("+%" PRIx64, offset);
57346661
AM
9942 }
9943
9944 fputs (">: [", stdout);
9945 print_vma (tp->start.offset, PREFIX_HEX);
9946 fputc ('-', stdout);
9947 print_vma (tp->end.offset, PREFIX_HEX);
9948 printf ("]\n\t");
9949
18bd398b
NC
9950#define PF(_m) if (tp->_m) printf (#_m " ");
9951#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9952 PF(Cannot_unwind);
9953 PF(Millicode);
9954 PF(Millicode_save_sr0);
18bd398b 9955 /* PV(Region_description); */
57346661
AM
9956 PF(Entry_SR);
9957 PV(Entry_FR);
9958 PV(Entry_GR);
9959 PF(Args_stored);
9960 PF(Variable_Frame);
9961 PF(Separate_Package_Body);
9962 PF(Frame_Extension_Millicode);
9963 PF(Stack_Overflow_Check);
9964 PF(Two_Instruction_SP_Increment);
9965 PF(Ada_Region);
9966 PF(cxx_info);
9967 PF(cxx_try_catch);
9968 PF(sched_entry_seq);
9969 PF(Save_SP);
9970 PF(Save_RP);
9971 PF(Save_MRP_in_frame);
9972 PF(extn_ptr_defined);
9973 PF(Cleanup_defined);
9974 PF(MPE_XL_interrupt_marker);
9975 PF(HP_UX_interrupt_marker);
9976 PF(Large_frame);
9977 PF(Pseudo_SP_Set);
9978 PV(Total_frame_size);
9979#undef PF
9980#undef PV
9981 }
9982
18bd398b 9983 printf ("\n");
948f632f
DA
9984
9985 free (aux->funtab);
32ec8896
NC
9986
9987 return res;
57346661
AM
9988}
9989
015dc7e1 9990static bool
dda8d76d
NC
9991slurp_hppa_unwind_table (Filedata * filedata,
9992 struct hppa_unw_aux_info * aux,
9993 Elf_Internal_Shdr * sec)
57346661 9994{
26c527e6 9995 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9996 Elf_Internal_Phdr * seg;
9997 struct hppa_unw_table_entry * tep;
9998 Elf_Internal_Shdr * relsec;
9999 Elf_Internal_Rela * rela;
10000 Elf_Internal_Rela * rp;
10001 unsigned char * table;
10002 unsigned char * tp;
10003 Elf_Internal_Sym * sym;
10004 const char * relname;
57346661 10005
57346661
AM
10006 /* First, find the starting address of the segment that includes
10007 this section. */
dda8d76d 10008 if (filedata->file_header.e_phnum)
57346661 10009 {
dda8d76d 10010 if (! get_program_headers (filedata))
015dc7e1 10011 return false;
57346661 10012
dda8d76d
NC
10013 for (seg = filedata->program_headers;
10014 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
10015 ++seg)
10016 {
10017 if (seg->p_type != PT_LOAD)
10018 continue;
10019
10020 if (sec->sh_addr >= seg->p_vaddr
10021 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10022 {
10023 aux->seg_base = seg->p_vaddr;
10024 break;
10025 }
10026 }
10027 }
10028
10029 /* Second, build the unwind table from the contents of the unwind
10030 section. */
10031 size = sec->sh_size;
dda8d76d 10032 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 10033 _("unwind table"));
57346661 10034 if (!table)
015dc7e1 10035 return false;
57346661 10036
1c0751b2
DA
10037 unw_ent_size = 16;
10038 nentries = size / unw_ent_size;
10039 size = unw_ent_size * nentries;
57346661 10040
e3fdc001 10041 aux->table_len = nentries;
3f5e193b
NC
10042 tep = aux->table = (struct hppa_unw_table_entry *)
10043 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 10044
1c0751b2 10045 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
10046 {
10047 unsigned int tmp1, tmp2;
10048
10049 tep->start.section = SHN_UNDEF;
10050 tep->end.section = SHN_UNDEF;
10051
1c0751b2
DA
10052 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10053 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10054 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10055 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10056
10057 tep->start.offset += aux->seg_base;
10058 tep->end.offset += aux->seg_base;
57346661
AM
10059
10060 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10061 tep->Millicode = (tmp1 >> 30) & 0x1;
10062 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10063 tep->Region_description = (tmp1 >> 27) & 0x3;
10064 tep->reserved1 = (tmp1 >> 26) & 0x1;
10065 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10066 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10067 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10068 tep->Args_stored = (tmp1 >> 15) & 0x1;
10069 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10070 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10071 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10072 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10073 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10074 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10075 tep->cxx_info = (tmp1 >> 8) & 0x1;
10076 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10077 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10078 tep->reserved2 = (tmp1 >> 5) & 0x1;
10079 tep->Save_SP = (tmp1 >> 4) & 0x1;
10080 tep->Save_RP = (tmp1 >> 3) & 0x1;
10081 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10082 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10083 tep->Cleanup_defined = tmp1 & 0x1;
10084
10085 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10086 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10087 tep->Large_frame = (tmp2 >> 29) & 0x1;
10088 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10089 tep->reserved4 = (tmp2 >> 27) & 0x1;
10090 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
10091 }
10092 free (table);
10093
10094 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
10095 for (relsec = filedata->section_headers;
10096 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
10097 ++relsec)
10098 {
10099 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
10100 || relsec->sh_info >= filedata->file_header.e_shnum
10101 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
10102 continue;
10103
dda8d76d 10104 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 10105 & rela, & nrelas))
015dc7e1 10106 return false;
57346661
AM
10107
10108 for (rp = rela; rp < rela + nrelas; ++rp)
10109 {
4770fb94 10110 unsigned int sym_ndx;
726bd37d
AM
10111 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10112 relname = elf_hppa_reloc_type (r_type);
57346661 10113
726bd37d
AM
10114 if (relname == NULL)
10115 {
10116 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10117 continue;
10118 }
10119
57346661 10120 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 10121 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 10122 {
726bd37d 10123 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
10124 continue;
10125 }
10126
10127 i = rp->r_offset / unw_ent_size;
726bd37d
AM
10128 if (i >= aux->table_len)
10129 {
26c527e6
AM
10130 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10131 i);
726bd37d
AM
10132 continue;
10133 }
57346661 10134
4770fb94
AM
10135 sym_ndx = get_reloc_symindex (rp->r_info);
10136 if (sym_ndx >= aux->nsyms)
10137 {
10138 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10139 sym_ndx);
10140 continue;
10141 }
10142 sym = aux->symtab + sym_ndx;
10143
43f6cd05 10144 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
10145 {
10146 case 0:
10147 aux->table[i].start.section = sym->st_shndx;
1e456d54 10148 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
10149 break;
10150 case 1:
10151 aux->table[i].end.section = sym->st_shndx;
1e456d54 10152 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
10153 break;
10154 default:
10155 break;
10156 }
10157 }
10158
10159 free (rela);
10160 }
10161
015dc7e1 10162 return true;
57346661
AM
10163}
10164
015dc7e1 10165static bool
dda8d76d 10166hppa_process_unwind (Filedata * filedata)
57346661 10167{
57346661 10168 struct hppa_unw_aux_info aux;
2cf0635d 10169 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 10170 Elf_Internal_Shdr * sec;
26c527e6 10171 size_t i;
015dc7e1 10172 bool res = true;
57346661 10173
dda8d76d 10174 if (filedata->string_table == NULL)
015dc7e1 10175 return false;
1b31d05e
NC
10176
10177 memset (& aux, 0, sizeof (aux));
57346661 10178
dda8d76d 10179 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10180 {
28d13567 10181 if (sec->sh_type == SHT_SYMTAB)
57346661 10182 {
28d13567 10183 if (aux.symtab)
4082ef84 10184 {
28d13567
AM
10185 error (_("Multiple symbol tables encountered\n"));
10186 free (aux.symtab);
10187 aux.symtab = NULL;
4082ef84 10188 free (aux.strtab);
28d13567 10189 aux.strtab = NULL;
4082ef84 10190 }
28d13567
AM
10191 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10192 &aux.strtab, &aux.strtab_size))
015dc7e1 10193 return false;
57346661 10194 }
84714f86
AM
10195 else if (section_name_valid (filedata, sec)
10196 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
10197 unwsec = sec;
10198 }
10199
10200 if (!unwsec)
10201 printf (_("\nThere are no unwind sections in this file.\n"));
10202
dda8d76d 10203 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10204 {
84714f86
AM
10205 if (section_name_valid (filedata, sec)
10206 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 10207 {
26c527e6 10208 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 10209
26c527e6
AM
10210 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10211 "contains %" PRIu64 " entry:\n",
10212 "\nUnwind section '%s' at offset %#" PRIx64 " "
10213 "contains %" PRIu64 " entries:\n",
d3a49aa8 10214 num_unwind),
dda8d76d 10215 printable_section_name (filedata, sec),
26c527e6 10216 sec->sh_offset,
d3a49aa8 10217 num_unwind);
57346661 10218
dda8d76d 10219 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 10220 res = false;
66b09c7e
S
10221
10222 if (res && aux.table_len > 0)
32ec8896 10223 {
dda8d76d 10224 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 10225 res = false;
32ec8896 10226 }
57346661 10227
9db70fc3 10228 free ((char *) aux.table);
57346661
AM
10229 aux.table = NULL;
10230 }
10231 }
10232
9db70fc3
AM
10233 free (aux.symtab);
10234 free ((char *) aux.strtab);
32ec8896
NC
10235
10236 return res;
57346661
AM
10237}
10238
0b6ae522
DJ
10239struct arm_section
10240{
a734115a
NC
10241 unsigned char * data; /* The unwind data. */
10242 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10243 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 10244 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
10245 unsigned int rel_type; /* REL or RELA ? */
10246 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
10247};
10248
10249struct arm_unw_aux_info
10250{
dda8d76d 10251 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 10252 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 10253 uint64_t nsyms; /* Number of symbols. */
948f632f 10254 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10255 uint64_t nfuns; /* Number of these symbols. */
a734115a 10256 char * strtab; /* The file's string table. */
26c527e6 10257 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
10258};
10259
10260static const char *
dda8d76d
NC
10261arm_print_vma_and_name (Filedata * filedata,
10262 struct arm_unw_aux_info * aux,
625d49fc 10263 uint64_t fn,
dda8d76d 10264 struct absaddr addr)
0b6ae522
DJ
10265{
10266 const char *procname;
625d49fc 10267 uint64_t sym_offset;
0b6ae522
DJ
10268
10269 if (addr.section == SHN_UNDEF)
10270 addr.offset = fn;
10271
dda8d76d 10272 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
10273 aux->strtab_size, addr, &procname,
10274 &sym_offset);
10275
10276 print_vma (fn, PREFIX_HEX);
10277
10278 if (procname)
10279 {
10280 fputs (" <", stdout);
10281 fputs (procname, stdout);
10282
10283 if (sym_offset)
26c527e6 10284 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10285 fputc ('>', stdout);
10286 }
10287
10288 return procname;
10289}
10290
10291static void
10292arm_free_section (struct arm_section *arm_sec)
10293{
9db70fc3
AM
10294 free (arm_sec->data);
10295 free (arm_sec->rela);
0b6ae522
DJ
10296}
10297
a734115a
NC
10298/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10299 cached section and install SEC instead.
10300 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10301 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10302 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10303 relocation's offset in ADDR.
1b31d05e
NC
10304 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10305 into the string table of the symbol associated with the reloc. If no
10306 reloc was applied store -1 there.
10307 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10308
015dc7e1 10309static bool
dda8d76d
NC
10310get_unwind_section_word (Filedata * filedata,
10311 struct arm_unw_aux_info * aux,
1b31d05e
NC
10312 struct arm_section * arm_sec,
10313 Elf_Internal_Shdr * sec,
625d49fc 10314 uint64_t word_offset,
1b31d05e
NC
10315 unsigned int * wordp,
10316 struct absaddr * addr,
625d49fc 10317 uint64_t * sym_name)
0b6ae522
DJ
10318{
10319 Elf_Internal_Rela *rp;
10320 Elf_Internal_Sym *sym;
10321 const char * relname;
10322 unsigned int word;
015dc7e1 10323 bool wrapped;
0b6ae522 10324
e0a31db1 10325 if (sec == NULL || arm_sec == NULL)
015dc7e1 10326 return false;
e0a31db1 10327
0b6ae522
DJ
10328 addr->section = SHN_UNDEF;
10329 addr->offset = 0;
10330
1b31d05e 10331 if (sym_name != NULL)
625d49fc 10332 *sym_name = (uint64_t) -1;
1b31d05e 10333
a734115a 10334 /* If necessary, update the section cache. */
0b6ae522
DJ
10335 if (sec != arm_sec->sec)
10336 {
10337 Elf_Internal_Shdr *relsec;
10338
10339 arm_free_section (arm_sec);
10340
10341 arm_sec->sec = sec;
dda8d76d 10342 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10343 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10344 arm_sec->rela = NULL;
10345 arm_sec->nrelas = 0;
10346
dda8d76d
NC
10347 for (relsec = filedata->section_headers;
10348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10349 ++relsec)
10350 {
dda8d76d
NC
10351 if (relsec->sh_info >= filedata->file_header.e_shnum
10352 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10353 /* PR 15745: Check the section type as well. */
10354 || (relsec->sh_type != SHT_REL
10355 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10356 continue;
10357
a734115a 10358 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10359 if (relsec->sh_type == SHT_REL)
10360 {
dda8d76d 10361 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10362 relsec->sh_size,
10363 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10364 return false;
0b6ae522 10365 }
1ae40aa4 10366 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10367 {
dda8d76d 10368 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10369 relsec->sh_size,
10370 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10371 return false;
0b6ae522 10372 }
1ae40aa4 10373 break;
0b6ae522
DJ
10374 }
10375
10376 arm_sec->next_rela = arm_sec->rela;
10377 }
10378
a734115a 10379 /* If there is no unwind data we can do nothing. */
0b6ae522 10380 if (arm_sec->data == NULL)
015dc7e1 10381 return false;
0b6ae522 10382
e0a31db1 10383 /* If the offset is invalid then fail. */
f32ba729
NC
10384 if (/* PR 21343 *//* PR 18879 */
10385 sec->sh_size < 4
625d49fc 10386 || word_offset > sec->sh_size - 4)
015dc7e1 10387 return false;
e0a31db1 10388
a734115a 10389 /* Get the word at the required offset. */
0b6ae522
DJ
10390 word = byte_get (arm_sec->data + word_offset, 4);
10391
0eff7165
NC
10392 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10393 if (arm_sec->rela == NULL)
10394 {
10395 * wordp = word;
015dc7e1 10396 return true;
0eff7165
NC
10397 }
10398
a734115a 10399 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10400 wrapped = false;
0b6ae522
DJ
10401 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10402 {
625d49fc 10403 uint64_t prelval, offset;
0b6ae522
DJ
10404
10405 if (rp->r_offset > word_offset && !wrapped)
10406 {
10407 rp = arm_sec->rela;
015dc7e1 10408 wrapped = true;
0b6ae522
DJ
10409 }
10410 if (rp->r_offset > word_offset)
10411 break;
10412
10413 if (rp->r_offset & 3)
10414 {
26c527e6
AM
10415 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10416 rp->r_offset);
0b6ae522
DJ
10417 continue;
10418 }
10419
10420 if (rp->r_offset < word_offset)
10421 continue;
10422
74e1a04b
NC
10423 /* PR 17531: file: 027-161405-0.004 */
10424 if (aux->symtab == NULL)
10425 continue;
10426
0b6ae522
DJ
10427 if (arm_sec->rel_type == SHT_REL)
10428 {
10429 offset = word & 0x7fffffff;
10430 if (offset & 0x40000000)
625d49fc 10431 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10432 }
a734115a 10433 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10434 offset = rp->r_addend;
a734115a 10435 else
74e1a04b
NC
10436 {
10437 error (_("Unknown section relocation type %d encountered\n"),
10438 arm_sec->rel_type);
10439 break;
10440 }
0b6ae522 10441
071436c6
NC
10442 /* PR 17531 file: 027-1241568-0.004. */
10443 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10444 {
26c527e6
AM
10445 error (_("Bad symbol index in unwind relocation "
10446 "(%" PRIu64 " > %" PRIu64 ")\n"),
10447 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10448 break;
10449 }
10450
10451 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10452 offset += sym->st_value;
10453 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10454
a734115a 10455 /* Check that we are processing the expected reloc type. */
dda8d76d 10456 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10457 {
10458 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10459 if (relname == NULL)
10460 {
10461 warn (_("Skipping unknown ARM relocation type: %d\n"),
10462 (int) ELF32_R_TYPE (rp->r_info));
10463 continue;
10464 }
a734115a
NC
10465
10466 if (streq (relname, "R_ARM_NONE"))
10467 continue;
0b4362b0 10468
a734115a
NC
10469 if (! streq (relname, "R_ARM_PREL31"))
10470 {
071436c6 10471 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10472 continue;
10473 }
10474 }
dda8d76d 10475 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10476 {
10477 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10478 if (relname == NULL)
10479 {
10480 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10481 (int) ELF32_R_TYPE (rp->r_info));
10482 continue;
10483 }
0b4362b0 10484
a734115a
NC
10485 if (streq (relname, "R_C6000_NONE"))
10486 continue;
10487
10488 if (! streq (relname, "R_C6000_PREL31"))
10489 {
071436c6 10490 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10491 continue;
10492 }
10493
10494 prelval >>= 1;
10495 }
10496 else
74e1a04b
NC
10497 {
10498 /* This function currently only supports ARM and TI unwinders. */
10499 warn (_("Only TI and ARM unwinders are currently supported\n"));
10500 break;
10501 }
fa197c1c 10502
625d49fc 10503 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10504 addr->section = sym->st_shndx;
10505 addr->offset = offset;
74e1a04b 10506
1b31d05e
NC
10507 if (sym_name)
10508 * sym_name = sym->st_name;
0b6ae522
DJ
10509 break;
10510 }
10511
10512 *wordp = word;
10513 arm_sec->next_rela = rp;
10514
015dc7e1 10515 return true;
0b6ae522
DJ
10516}
10517
a734115a
NC
10518static const char *tic6x_unwind_regnames[16] =
10519{
0b4362b0
RM
10520 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10521 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10522 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10523};
fa197c1c 10524
0b6ae522 10525static void
fa197c1c 10526decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10527{
fa197c1c
PB
10528 int i;
10529
10530 for (i = 12; mask; mask >>= 1, i--)
10531 {
10532 if (mask & 1)
10533 {
10534 fputs (tic6x_unwind_regnames[i], stdout);
10535 if (mask > 1)
10536 fputs (", ", stdout);
10537 }
10538 }
10539}
0b6ae522
DJ
10540
10541#define ADVANCE \
10542 if (remaining == 0 && more_words) \
10543 { \
10544 data_offset += 4; \
dda8d76d 10545 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10546 data_offset, & word, & addr, NULL)) \
015dc7e1 10547 return false; \
0b6ae522
DJ
10548 remaining = 4; \
10549 more_words--; \
10550 } \
10551
10552#define GET_OP(OP) \
10553 ADVANCE; \
10554 if (remaining) \
10555 { \
10556 remaining--; \
10557 (OP) = word >> 24; \
10558 word <<= 8; \
10559 } \
10560 else \
10561 { \
2b692964 10562 printf (_("[Truncated opcode]\n")); \
015dc7e1 10563 return false; \
0b6ae522 10564 } \
cc5914eb 10565 printf ("0x%02x ", OP)
0b6ae522 10566
015dc7e1 10567static bool
dda8d76d
NC
10568decode_arm_unwind_bytecode (Filedata * filedata,
10569 struct arm_unw_aux_info * aux,
948f632f
DA
10570 unsigned int word,
10571 unsigned int remaining,
10572 unsigned int more_words,
625d49fc 10573 uint64_t data_offset,
948f632f
DA
10574 Elf_Internal_Shdr * data_sec,
10575 struct arm_section * data_arm_sec)
fa197c1c
PB
10576{
10577 struct absaddr addr;
015dc7e1 10578 bool res = true;
0b6ae522
DJ
10579
10580 /* Decode the unwinding instructions. */
10581 while (1)
10582 {
10583 unsigned int op, op2;
10584
10585 ADVANCE;
10586 if (remaining == 0)
10587 break;
10588 remaining--;
10589 op = word >> 24;
10590 word <<= 8;
10591
cc5914eb 10592 printf (" 0x%02x ", op);
0b6ae522
DJ
10593
10594 if ((op & 0xc0) == 0x00)
10595 {
10596 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10597
cc5914eb 10598 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10599 }
10600 else if ((op & 0xc0) == 0x40)
10601 {
10602 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10603
cc5914eb 10604 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10605 }
10606 else if ((op & 0xf0) == 0x80)
10607 {
10608 GET_OP (op2);
10609 if (op == 0x80 && op2 == 0)
10610 printf (_("Refuse to unwind"));
10611 else
10612 {
10613 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10614 bool first = true;
0b6ae522 10615 int i;
2b692964 10616
0b6ae522
DJ
10617 printf ("pop {");
10618 for (i = 0; i < 12; i++)
10619 if (mask & (1 << i))
10620 {
10621 if (first)
015dc7e1 10622 first = false;
0b6ae522
DJ
10623 else
10624 printf (", ");
10625 printf ("r%d", 4 + i);
10626 }
10627 printf ("}");
10628 }
10629 }
10630 else if ((op & 0xf0) == 0x90)
10631 {
10632 if (op == 0x9d || op == 0x9f)
10633 printf (_(" [Reserved]"));
10634 else
cc5914eb 10635 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10636 }
10637 else if ((op & 0xf0) == 0xa0)
10638 {
10639 int end = 4 + (op & 0x07);
015dc7e1 10640 bool first = true;
0b6ae522 10641 int i;
61865e30 10642
0b6ae522
DJ
10643 printf (" pop {");
10644 for (i = 4; i <= end; i++)
10645 {
10646 if (first)
015dc7e1 10647 first = false;
0b6ae522
DJ
10648 else
10649 printf (", ");
10650 printf ("r%d", i);
10651 }
10652 if (op & 0x08)
10653 {
1b31d05e 10654 if (!first)
0b6ae522
DJ
10655 printf (", ");
10656 printf ("r14");
10657 }
10658 printf ("}");
10659 }
10660 else if (op == 0xb0)
10661 printf (_(" finish"));
10662 else if (op == 0xb1)
10663 {
10664 GET_OP (op2);
10665 if (op2 == 0 || (op2 & 0xf0) != 0)
10666 printf (_("[Spare]"));
10667 else
10668 {
10669 unsigned int mask = op2 & 0x0f;
015dc7e1 10670 bool first = true;
0b6ae522 10671 int i;
61865e30 10672
0b6ae522
DJ
10673 printf ("pop {");
10674 for (i = 0; i < 12; i++)
10675 if (mask & (1 << i))
10676 {
10677 if (first)
015dc7e1 10678 first = false;
0b6ae522
DJ
10679 else
10680 printf (", ");
10681 printf ("r%d", i);
10682 }
10683 printf ("}");
10684 }
10685 }
10686 else if (op == 0xb2)
10687 {
b115cf96 10688 unsigned char buf[9];
0b6ae522 10689 unsigned int i, len;
26c527e6 10690 uint64_t offset;
61865e30 10691
b115cf96 10692 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10693 {
10694 GET_OP (buf[i]);
10695 if ((buf[i] & 0x80) == 0)
10696 break;
10697 }
4082ef84 10698 if (i == sizeof (buf))
32ec8896 10699 {
27a45f42 10700 error (_("corrupt change to vsp\n"));
015dc7e1 10701 res = false;
32ec8896 10702 }
4082ef84
NC
10703 else
10704 {
015dc7e1 10705 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10706 assert (len == i + 1);
10707 offset = offset * 4 + 0x204;
26c527e6 10708 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10709 }
0b6ae522 10710 }
61865e30 10711 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10712 {
61865e30
NC
10713 unsigned int first, last;
10714
10715 GET_OP (op2);
10716 first = op2 >> 4;
10717 last = op2 & 0x0f;
10718 if (op == 0xc8)
10719 first = first + 16;
10720 printf ("pop {D%d", first);
10721 if (last)
10722 printf ("-D%d", first + last);
10723 printf ("}");
10724 }
09854a88
TB
10725 else if (op == 0xb4)
10726 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10727 else if (op == 0xb5)
10728 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10729 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10730 {
10731 unsigned int count = op & 0x07;
10732
10733 printf ("pop {D8");
10734 if (count)
10735 printf ("-D%d", 8 + count);
10736 printf ("}");
10737 }
10738 else if (op >= 0xc0 && op <= 0xc5)
10739 {
10740 unsigned int count = op & 0x07;
10741
10742 printf (" pop {wR10");
10743 if (count)
10744 printf ("-wR%d", 10 + count);
10745 printf ("}");
10746 }
10747 else if (op == 0xc6)
10748 {
10749 unsigned int first, last;
10750
10751 GET_OP (op2);
10752 first = op2 >> 4;
10753 last = op2 & 0x0f;
10754 printf ("pop {wR%d", first);
10755 if (last)
10756 printf ("-wR%d", first + last);
10757 printf ("}");
10758 }
10759 else if (op == 0xc7)
10760 {
10761 GET_OP (op2);
10762 if (op2 == 0 || (op2 & 0xf0) != 0)
10763 printf (_("[Spare]"));
0b6ae522
DJ
10764 else
10765 {
61865e30 10766 unsigned int mask = op2 & 0x0f;
015dc7e1 10767 bool first = true;
61865e30
NC
10768 int i;
10769
10770 printf ("pop {");
10771 for (i = 0; i < 4; i++)
10772 if (mask & (1 << i))
10773 {
10774 if (first)
015dc7e1 10775 first = false;
61865e30
NC
10776 else
10777 printf (", ");
10778 printf ("wCGR%d", i);
10779 }
10780 printf ("}");
0b6ae522
DJ
10781 }
10782 }
61865e30 10783 else
32ec8896
NC
10784 {
10785 printf (_(" [unsupported opcode]"));
015dc7e1 10786 res = false;
32ec8896
NC
10787 }
10788
0b6ae522
DJ
10789 printf ("\n");
10790 }
32ec8896
NC
10791
10792 return res;
fa197c1c
PB
10793}
10794
015dc7e1 10795static bool
dda8d76d
NC
10796decode_tic6x_unwind_bytecode (Filedata * filedata,
10797 struct arm_unw_aux_info * aux,
948f632f
DA
10798 unsigned int word,
10799 unsigned int remaining,
10800 unsigned int more_words,
625d49fc 10801 uint64_t data_offset,
948f632f
DA
10802 Elf_Internal_Shdr * data_sec,
10803 struct arm_section * data_arm_sec)
fa197c1c
PB
10804{
10805 struct absaddr addr;
10806
10807 /* Decode the unwinding instructions. */
10808 while (1)
10809 {
10810 unsigned int op, op2;
10811
10812 ADVANCE;
10813 if (remaining == 0)
10814 break;
10815 remaining--;
10816 op = word >> 24;
10817 word <<= 8;
10818
9cf03b7e 10819 printf (" 0x%02x ", op);
fa197c1c
PB
10820
10821 if ((op & 0xc0) == 0x00)
10822 {
10823 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10824 printf (" sp = sp + %d", offset);
fa197c1c
PB
10825 }
10826 else if ((op & 0xc0) == 0x80)
10827 {
10828 GET_OP (op2);
10829 if (op == 0x80 && op2 == 0)
10830 printf (_("Refuse to unwind"));
10831 else
10832 {
10833 unsigned int mask = ((op & 0x1f) << 8) | op2;
10834 if (op & 0x20)
10835 printf ("pop compact {");
10836 else
10837 printf ("pop {");
10838
10839 decode_tic6x_unwind_regmask (mask);
10840 printf("}");
10841 }
10842 }
10843 else if ((op & 0xf0) == 0xc0)
10844 {
10845 unsigned int reg;
10846 unsigned int nregs;
10847 unsigned int i;
10848 const char *name;
a734115a
NC
10849 struct
10850 {
32ec8896
NC
10851 unsigned int offset;
10852 unsigned int reg;
fa197c1c
PB
10853 } regpos[16];
10854
10855 /* Scan entire instruction first so that GET_OP output is not
10856 interleaved with disassembly. */
10857 nregs = 0;
10858 for (i = 0; nregs < (op & 0xf); i++)
10859 {
10860 GET_OP (op2);
10861 reg = op2 >> 4;
10862 if (reg != 0xf)
10863 {
10864 regpos[nregs].offset = i * 2;
10865 regpos[nregs].reg = reg;
10866 nregs++;
10867 }
10868
10869 reg = op2 & 0xf;
10870 if (reg != 0xf)
10871 {
10872 regpos[nregs].offset = i * 2 + 1;
10873 regpos[nregs].reg = reg;
10874 nregs++;
10875 }
10876 }
10877
10878 printf (_("pop frame {"));
18344509 10879 if (nregs == 0)
fa197c1c 10880 {
18344509
NC
10881 printf (_("*corrupt* - no registers specified"));
10882 }
10883 else
10884 {
10885 reg = nregs - 1;
10886 for (i = i * 2; i > 0; i--)
fa197c1c 10887 {
18344509
NC
10888 if (regpos[reg].offset == i - 1)
10889 {
10890 name = tic6x_unwind_regnames[regpos[reg].reg];
10891 if (reg > 0)
10892 reg--;
10893 }
10894 else
10895 name = _("[pad]");
fa197c1c 10896
18344509
NC
10897 fputs (name, stdout);
10898 if (i > 1)
10899 printf (", ");
10900 }
fa197c1c
PB
10901 }
10902
10903 printf ("}");
10904 }
10905 else if (op == 0xd0)
10906 printf (" MOV FP, SP");
10907 else if (op == 0xd1)
10908 printf (" __c6xabi_pop_rts");
10909 else if (op == 0xd2)
10910 {
10911 unsigned char buf[9];
10912 unsigned int i, len;
26c527e6 10913 uint64_t offset;
a734115a 10914
fa197c1c
PB
10915 for (i = 0; i < sizeof (buf); i++)
10916 {
10917 GET_OP (buf[i]);
10918 if ((buf[i] & 0x80) == 0)
10919 break;
10920 }
0eff7165
NC
10921 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10922 if (i == sizeof (buf))
10923 {
0eff7165 10924 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10925 return false;
0eff7165 10926 }
948f632f 10927
015dc7e1 10928 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10929 assert (len == i + 1);
10930 offset = offset * 8 + 0x408;
26c527e6 10931 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10932 }
10933 else if ((op & 0xf0) == 0xe0)
10934 {
10935 if ((op & 0x0f) == 7)
10936 printf (" RETURN");
10937 else
10938 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10939 }
10940 else
10941 {
10942 printf (_(" [unsupported opcode]"));
10943 }
10944 putchar ('\n');
10945 }
32ec8896 10946
015dc7e1 10947 return true;
fa197c1c
PB
10948}
10949
625d49fc
AM
10950static uint64_t
10951arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10952{
625d49fc 10953 uint64_t offset;
fa197c1c
PB
10954
10955 offset = word & 0x7fffffff;
10956 if (offset & 0x40000000)
625d49fc 10957 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10958
dda8d76d 10959 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10960 offset <<= 1;
10961
10962 return offset + where;
10963}
10964
015dc7e1 10965static bool
dda8d76d
NC
10966decode_arm_unwind (Filedata * filedata,
10967 struct arm_unw_aux_info * aux,
1b31d05e
NC
10968 unsigned int word,
10969 unsigned int remaining,
625d49fc 10970 uint64_t data_offset,
1b31d05e
NC
10971 Elf_Internal_Shdr * data_sec,
10972 struct arm_section * data_arm_sec)
fa197c1c
PB
10973{
10974 int per_index;
10975 unsigned int more_words = 0;
37e14bc3 10976 struct absaddr addr;
625d49fc 10977 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10978 bool res = true;
fa197c1c
PB
10979
10980 if (remaining == 0)
10981 {
1b31d05e
NC
10982 /* Fetch the first word.
10983 Note - when decoding an object file the address extracted
10984 here will always be 0. So we also pass in the sym_name
10985 parameter so that we can find the symbol associated with
10986 the personality routine. */
dda8d76d 10987 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10988 & word, & addr, & sym_name))
015dc7e1 10989 return false;
1b31d05e 10990
fa197c1c
PB
10991 remaining = 4;
10992 }
c93dbb25
CZ
10993 else
10994 {
10995 addr.section = SHN_UNDEF;
10996 addr.offset = 0;
10997 }
fa197c1c
PB
10998
10999 if ((word & 0x80000000) == 0)
11000 {
11001 /* Expand prel31 for personality routine. */
625d49fc 11002 uint64_t fn;
fa197c1c
PB
11003 const char *procname;
11004
dda8d76d 11005 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 11006 printf (_(" Personality routine: "));
1b31d05e
NC
11007 if (fn == 0
11008 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 11009 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
11010 {
11011 procname = aux->strtab + sym_name;
11012 print_vma (fn, PREFIX_HEX);
11013 if (procname)
11014 {
11015 fputs (" <", stdout);
11016 fputs (procname, stdout);
11017 fputc ('>', stdout);
11018 }
11019 }
11020 else
dda8d76d 11021 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
11022 fputc ('\n', stdout);
11023
11024 /* The GCC personality routines use the standard compact
11025 encoding, starting with one byte giving the number of
11026 words. */
11027 if (procname != NULL
24d127aa
ML
11028 && (startswith (procname, "__gcc_personality_v0")
11029 || startswith (procname, "__gxx_personality_v0")
11030 || startswith (procname, "__gcj_personality_v0")
11031 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
11032 {
11033 remaining = 0;
11034 more_words = 1;
11035 ADVANCE;
11036 if (!remaining)
11037 {
11038 printf (_(" [Truncated data]\n"));
015dc7e1 11039 return false;
fa197c1c
PB
11040 }
11041 more_words = word >> 24;
11042 word <<= 8;
11043 remaining--;
11044 per_index = -1;
11045 }
11046 else
015dc7e1 11047 return true;
fa197c1c
PB
11048 }
11049 else
11050 {
1b31d05e 11051 /* ARM EHABI Section 6.3:
0b4362b0 11052
1b31d05e 11053 An exception-handling table entry for the compact model looks like:
0b4362b0 11054
1b31d05e
NC
11055 31 30-28 27-24 23-0
11056 -- ----- ----- ----
11057 1 0 index Data for personalityRoutine[index] */
11058
dda8d76d 11059 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 11060 && (word & 0x70000000))
32ec8896
NC
11061 {
11062 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 11063 res = false;
32ec8896 11064 }
1b31d05e 11065
fa197c1c 11066 per_index = (word >> 24) & 0x7f;
1b31d05e 11067 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
11068 if (per_index == 0)
11069 {
11070 more_words = 0;
11071 word <<= 8;
11072 remaining--;
11073 }
11074 else if (per_index < 3)
11075 {
11076 more_words = (word >> 16) & 0xff;
11077 word <<= 16;
11078 remaining -= 2;
11079 }
11080 }
11081
dda8d76d 11082 switch (filedata->file_header.e_machine)
fa197c1c
PB
11083 {
11084 case EM_ARM:
11085 if (per_index < 3)
11086 {
dda8d76d 11087 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11088 data_offset, data_sec, data_arm_sec))
015dc7e1 11089 res = false;
fa197c1c
PB
11090 }
11091 else
1b31d05e
NC
11092 {
11093 warn (_("Unknown ARM compact model index encountered\n"));
11094 printf (_(" [reserved]\n"));
015dc7e1 11095 res = false;
1b31d05e 11096 }
fa197c1c
PB
11097 break;
11098
11099 case EM_TI_C6000:
11100 if (per_index < 3)
11101 {
dda8d76d 11102 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11103 data_offset, data_sec, data_arm_sec))
015dc7e1 11104 res = false;
fa197c1c
PB
11105 }
11106 else if (per_index < 5)
11107 {
11108 if (((word >> 17) & 0x7f) == 0x7f)
11109 printf (_(" Restore stack from frame pointer\n"));
11110 else
11111 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11112 printf (_(" Registers restored: "));
11113 if (per_index == 4)
11114 printf (" (compact) ");
11115 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11116 putchar ('\n');
11117 printf (_(" Return register: %s\n"),
11118 tic6x_unwind_regnames[word & 0xf]);
11119 }
11120 else
1b31d05e 11121 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
11122 break;
11123
11124 default:
74e1a04b 11125 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 11126 filedata->file_header.e_machine);
015dc7e1 11127 res = false;
fa197c1c 11128 }
0b6ae522
DJ
11129
11130 /* Decode the descriptors. Not implemented. */
32ec8896
NC
11131
11132 return res;
0b6ae522
DJ
11133}
11134
015dc7e1 11135static bool
dda8d76d
NC
11136dump_arm_unwind (Filedata * filedata,
11137 struct arm_unw_aux_info * aux,
11138 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
11139{
11140 struct arm_section exidx_arm_sec, extab_arm_sec;
11141 unsigned int i, exidx_len;
26c527e6 11142 uint64_t j, nfuns;
015dc7e1 11143 bool res = true;
0b6ae522
DJ
11144
11145 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11146 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11147 exidx_len = exidx_sec->sh_size / 8;
11148
948f632f
DA
11149 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11150 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11151 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11152 aux->funtab[nfuns++] = aux->symtab[j];
11153 aux->nfuns = nfuns;
11154 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11155
0b6ae522
DJ
11156 for (i = 0; i < exidx_len; i++)
11157 {
11158 unsigned int exidx_fn, exidx_entry;
11159 struct absaddr fn_addr, entry_addr;
625d49fc 11160 uint64_t fn;
0b6ae522
DJ
11161
11162 fputc ('\n', stdout);
11163
dda8d76d 11164 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11165 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 11166 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11167 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 11168 {
948f632f 11169 free (aux->funtab);
1b31d05e
NC
11170 arm_free_section (& exidx_arm_sec);
11171 arm_free_section (& extab_arm_sec);
015dc7e1 11172 return false;
0b6ae522
DJ
11173 }
11174
83c257ca
NC
11175 /* ARM EHABI, Section 5:
11176 An index table entry consists of 2 words.
11177 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11178 if (exidx_fn & 0x80000000)
32ec8896
NC
11179 {
11180 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 11181 res = false;
32ec8896 11182 }
83c257ca 11183
dda8d76d 11184 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 11185
dda8d76d 11186 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
11187 fputs (": ", stdout);
11188
11189 if (exidx_entry == 1)
11190 {
11191 print_vma (exidx_entry, PREFIX_HEX);
11192 fputs (" [cantunwind]\n", stdout);
11193 }
11194 else if (exidx_entry & 0x80000000)
11195 {
11196 print_vma (exidx_entry, PREFIX_HEX);
11197 fputc ('\n', stdout);
dda8d76d 11198 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
11199 }
11200 else
11201 {
625d49fc 11202 uint64_t table, table_offset = 0;
0b6ae522
DJ
11203 Elf_Internal_Shdr *table_sec;
11204
11205 fputs ("@", stdout);
dda8d76d 11206 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
11207 print_vma (table, PREFIX_HEX);
11208 printf ("\n");
11209
11210 /* Locate the matching .ARM.extab. */
11211 if (entry_addr.section != SHN_UNDEF
dda8d76d 11212 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 11213 {
dda8d76d 11214 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 11215 table_offset = entry_addr.offset;
1a915552 11216 /* PR 18879 */
625d49fc 11217 if (table_offset > table_sec->sh_size)
1a915552 11218 {
26c527e6
AM
11219 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11220 table_offset,
dda8d76d 11221 printable_section_name (filedata, table_sec));
015dc7e1 11222 res = false;
1a915552
NC
11223 continue;
11224 }
0b6ae522
DJ
11225 }
11226 else
11227 {
dda8d76d 11228 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
11229 if (table_sec != NULL)
11230 table_offset = table - table_sec->sh_addr;
11231 }
32ec8896 11232
0b6ae522
DJ
11233 if (table_sec == NULL)
11234 {
26c527e6
AM
11235 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11236 table);
015dc7e1 11237 res = false;
0b6ae522
DJ
11238 continue;
11239 }
32ec8896 11240
dda8d76d 11241 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 11242 &extab_arm_sec))
015dc7e1 11243 res = false;
0b6ae522
DJ
11244 }
11245 }
11246
11247 printf ("\n");
11248
948f632f 11249 free (aux->funtab);
0b6ae522
DJ
11250 arm_free_section (&exidx_arm_sec);
11251 arm_free_section (&extab_arm_sec);
32ec8896
NC
11252
11253 return res;
0b6ae522
DJ
11254}
11255
fa197c1c 11256/* Used for both ARM and C6X unwinding tables. */
1b31d05e 11257
015dc7e1 11258static bool
dda8d76d 11259arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
11260{
11261 struct arm_unw_aux_info aux;
11262 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 11263 Elf_Internal_Shdr *sec;
26c527e6 11264 size_t i;
fa197c1c 11265 unsigned int sec_type;
015dc7e1 11266 bool res = true;
0b6ae522 11267
dda8d76d 11268 switch (filedata->file_header.e_machine)
fa197c1c
PB
11269 {
11270 case EM_ARM:
11271 sec_type = SHT_ARM_EXIDX;
11272 break;
11273
11274 case EM_TI_C6000:
11275 sec_type = SHT_C6000_UNWIND;
11276 break;
11277
0b4362b0 11278 default:
74e1a04b 11279 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11280 filedata->file_header.e_machine);
015dc7e1 11281 return false;
fa197c1c
PB
11282 }
11283
dda8d76d 11284 if (filedata->string_table == NULL)
015dc7e1 11285 return false;
1b31d05e
NC
11286
11287 memset (& aux, 0, sizeof (aux));
dda8d76d 11288 aux.filedata = filedata;
0b6ae522 11289
dda8d76d 11290 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11291 {
28d13567 11292 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11293 {
28d13567 11294 if (aux.symtab)
74e1a04b 11295 {
28d13567
AM
11296 error (_("Multiple symbol tables encountered\n"));
11297 free (aux.symtab);
11298 aux.symtab = NULL;
74e1a04b 11299 free (aux.strtab);
28d13567 11300 aux.strtab = NULL;
74e1a04b 11301 }
28d13567
AM
11302 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11303 &aux.strtab, &aux.strtab_size))
015dc7e1 11304 return false;
0b6ae522 11305 }
fa197c1c 11306 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11307 unwsec = sec;
11308 }
11309
1b31d05e 11310 if (unwsec == NULL)
0b6ae522 11311 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11312 else
dda8d76d 11313 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11314 {
11315 if (sec->sh_type == sec_type)
11316 {
26c527e6
AM
11317 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11318 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11319 "contains %" PRIu64 " entry:\n",
11320 "\nUnwind section '%s' at offset %#" PRIx64 " "
11321 "contains %" PRIu64 " entries:\n",
d3a49aa8 11322 num_unwind),
dda8d76d 11323 printable_section_name (filedata, sec),
26c527e6 11324 sec->sh_offset,
d3a49aa8 11325 num_unwind);
0b6ae522 11326
dda8d76d 11327 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11328 res = false;
1b31d05e
NC
11329 }
11330 }
0b6ae522 11331
9db70fc3
AM
11332 free (aux.symtab);
11333 free ((char *) aux.strtab);
32ec8896
NC
11334
11335 return res;
0b6ae522
DJ
11336}
11337
3ecc00ec
NC
11338static bool
11339no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11340{
11341 printf (_("No processor specific unwind information to decode\n"));
11342 return true;
11343}
11344
015dc7e1 11345static bool
dda8d76d 11346process_unwind (Filedata * filedata)
57346661 11347{
2cf0635d
NC
11348 struct unwind_handler
11349 {
32ec8896 11350 unsigned int machtype;
015dc7e1 11351 bool (* handler)(Filedata *);
2cf0635d
NC
11352 } handlers[] =
11353 {
0b6ae522 11354 { EM_ARM, arm_process_unwind },
57346661
AM
11355 { EM_IA_64, ia64_process_unwind },
11356 { EM_PARISC, hppa_process_unwind },
fa197c1c 11357 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11358 { EM_386, no_processor_specific_unwind },
11359 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11360 { 0, NULL }
57346661
AM
11361 };
11362 int i;
11363
11364 if (!do_unwind)
015dc7e1 11365 return true;
57346661
AM
11366
11367 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11368 if (filedata->file_header.e_machine == handlers[i].machtype)
11369 return handlers[i].handler (filedata);
57346661 11370
1b31d05e 11371 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11372 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11373 return true;
57346661
AM
11374}
11375
37c18eed
SD
11376static void
11377dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11378{
11379 switch (entry->d_tag)
11380 {
11381 case DT_AARCH64_BTI_PLT:
1dbade74 11382 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11383 break;
11384 default:
11385 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11386 break;
11387 }
11388 putchar ('\n');
11389}
11390
252b5132 11391static void
978c4450 11392dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11393{
11394 switch (entry->d_tag)
11395 {
11396 case DT_MIPS_FLAGS:
11397 if (entry->d_un.d_val == 0)
4b68bca3 11398 printf (_("NONE"));
252b5132
RH
11399 else
11400 {
11401 static const char * opts[] =
11402 {
11403 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11404 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11405 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11406 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11407 "RLD_ORDER_SAFE"
11408 };
11409 unsigned int cnt;
015dc7e1 11410 bool first = true;
2b692964 11411
60bca95a 11412 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11413 if (entry->d_un.d_val & (1 << cnt))
11414 {
11415 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11416 first = false;
252b5132 11417 }
252b5132
RH
11418 }
11419 break;
103f02d3 11420
252b5132 11421 case DT_MIPS_IVERSION:
84714f86 11422 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11423 printf (_("Interface Version: %s"),
84714f86 11424 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11425 else
f493c217 11426 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11427 entry->d_un.d_ptr);
252b5132 11428 break;
103f02d3 11429
252b5132
RH
11430 case DT_MIPS_TIME_STAMP:
11431 {
d5b07ef4 11432 char timebuf[128];
2cf0635d 11433 struct tm * tmp;
91d6fa6a 11434 time_t atime = entry->d_un.d_val;
82b1b41b 11435
91d6fa6a 11436 tmp = gmtime (&atime);
82b1b41b
NC
11437 /* PR 17531: file: 6accc532. */
11438 if (tmp == NULL)
11439 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11440 else
11441 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11442 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11443 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11444 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11445 }
11446 break;
103f02d3 11447
252b5132
RH
11448 case DT_MIPS_RLD_VERSION:
11449 case DT_MIPS_LOCAL_GOTNO:
11450 case DT_MIPS_CONFLICTNO:
11451 case DT_MIPS_LIBLISTNO:
11452 case DT_MIPS_SYMTABNO:
11453 case DT_MIPS_UNREFEXTNO:
11454 case DT_MIPS_HIPAGENO:
11455 case DT_MIPS_DELTA_CLASS_NO:
11456 case DT_MIPS_DELTA_INSTANCE_NO:
11457 case DT_MIPS_DELTA_RELOC_NO:
11458 case DT_MIPS_DELTA_SYM_NO:
11459 case DT_MIPS_DELTA_CLASSSYM_NO:
11460 case DT_MIPS_COMPACT_SIZE:
c69075ac 11461 print_vma (entry->d_un.d_val, DEC);
252b5132 11462 break;
103f02d3 11463
f16a9783 11464 case DT_MIPS_XHASH:
978c4450
AM
11465 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11466 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11467 /* Falls through. */
11468
103f02d3 11469 default:
4b68bca3 11470 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11471 }
4b68bca3 11472 putchar ('\n');
103f02d3
UD
11473}
11474
103f02d3 11475static void
2cf0635d 11476dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11477{
11478 switch (entry->d_tag)
11479 {
11480 case DT_HP_DLD_FLAGS:
11481 {
11482 static struct
11483 {
26c527e6 11484 unsigned int bit;
2cf0635d 11485 const char * str;
5e220199
NC
11486 }
11487 flags[] =
11488 {
11489 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11490 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11491 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11492 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11493 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11494 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11495 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11496 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11497 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11498 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11499 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11500 { DT_HP_GST, "HP_GST" },
11501 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11502 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11503 { DT_HP_NODELETE, "HP_NODELETE" },
11504 { DT_HP_GROUP, "HP_GROUP" },
11505 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11506 };
015dc7e1 11507 bool first = true;
5e220199 11508 size_t cnt;
625d49fc 11509 uint64_t val = entry->d_un.d_val;
103f02d3 11510
60bca95a 11511 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11512 if (val & flags[cnt].bit)
30800947
NC
11513 {
11514 if (! first)
11515 putchar (' ');
11516 fputs (flags[cnt].str, stdout);
015dc7e1 11517 first = false;
30800947
NC
11518 val ^= flags[cnt].bit;
11519 }
76da6bbe 11520
103f02d3 11521 if (val != 0 || first)
f7a99963
NC
11522 {
11523 if (! first)
11524 putchar (' ');
11525 print_vma (val, HEX);
11526 }
103f02d3
UD
11527 }
11528 break;
76da6bbe 11529
252b5132 11530 default:
f7a99963
NC
11531 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11532 break;
252b5132 11533 }
35b1837e 11534 putchar ('\n');
252b5132
RH
11535}
11536
28f997cf
TG
11537/* VMS vs Unix time offset and factor. */
11538
11539#define VMS_EPOCH_OFFSET 35067168000000000LL
11540#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11541#ifndef INT64_MIN
11542#define INT64_MIN (-9223372036854775807LL - 1)
11543#endif
28f997cf
TG
11544
11545/* Display a VMS time in a human readable format. */
11546
11547static void
0e3c1eeb 11548print_vms_time (int64_t vmstime)
28f997cf 11549{
dccc31de 11550 struct tm *tm = NULL;
28f997cf
TG
11551 time_t unxtime;
11552
dccc31de
AM
11553 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11554 {
11555 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11556 unxtime = vmstime;
11557 if (unxtime == vmstime)
11558 tm = gmtime (&unxtime);
11559 }
11560 if (tm != NULL)
11561 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11562 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11563 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11564}
28f997cf 11565
ecc51f48 11566static void
2cf0635d 11567dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11568{
11569 switch (entry->d_tag)
11570 {
0de14b54 11571 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11572 /* First 3 slots reserved. */
ecc51f48
NC
11573 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11574 printf (" -- ");
11575 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11576 break;
11577
28f997cf 11578 case DT_IA_64_VMS_LINKTIME:
28f997cf 11579 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11580 break;
11581
11582 case DT_IA_64_VMS_LNKFLAGS:
11583 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11584 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11585 printf (" CALL_DEBUG");
11586 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11587 printf (" NOP0BUFS");
11588 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11589 printf (" P0IMAGE");
11590 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11591 printf (" MKTHREADS");
11592 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11593 printf (" UPCALLS");
11594 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11595 printf (" IMGSTA");
11596 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11597 printf (" INITIALIZE");
11598 if (entry->d_un.d_val & VMS_LF_MAIN)
11599 printf (" MAIN");
11600 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11601 printf (" EXE_INIT");
11602 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11603 printf (" TBK_IN_IMG");
11604 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11605 printf (" DBG_IN_IMG");
11606 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11607 printf (" TBK_IN_DSF");
11608 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11609 printf (" DBG_IN_DSF");
11610 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11611 printf (" SIGNATURES");
11612 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11613 printf (" REL_SEG_OFF");
11614 break;
11615
bdf4d63a
JJ
11616 default:
11617 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11618 break;
ecc51f48 11619 }
bdf4d63a 11620 putchar ('\n');
ecc51f48
NC
11621}
11622
015dc7e1 11623static bool
dda8d76d 11624get_32bit_dynamic_section (Filedata * filedata)
252b5132 11625{
2cf0635d
NC
11626 Elf32_External_Dyn * edyn;
11627 Elf32_External_Dyn * ext;
11628 Elf_Internal_Dyn * entry;
103f02d3 11629
978c4450
AM
11630 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11631 filedata->dynamic_addr, 1,
11632 filedata->dynamic_size,
11633 _("dynamic section"));
a6e9f9df 11634 if (!edyn)
015dc7e1 11635 return false;
103f02d3 11636
071436c6
NC
11637 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11638 might not have the luxury of section headers. Look for the DT_NULL
11639 terminator to determine the number of entries. */
978c4450
AM
11640 for (ext = edyn, filedata->dynamic_nent = 0;
11641 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11642 ext++)
11643 {
978c4450 11644 filedata->dynamic_nent++;
ba2685cc
AM
11645 if (BYTE_GET (ext->d_tag) == DT_NULL)
11646 break;
11647 }
252b5132 11648
978c4450
AM
11649 filedata->dynamic_section
11650 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11651 if (filedata->dynamic_section == NULL)
252b5132 11652 {
26c527e6
AM
11653 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11654 filedata->dynamic_nent);
9ea033b2 11655 free (edyn);
015dc7e1 11656 return false;
9ea033b2 11657 }
252b5132 11658
978c4450
AM
11659 for (ext = edyn, entry = filedata->dynamic_section;
11660 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11661 ext++, entry++)
9ea033b2 11662 {
fb514b26
AM
11663 entry->d_tag = BYTE_GET (ext->d_tag);
11664 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11665 }
11666
9ea033b2
NC
11667 free (edyn);
11668
015dc7e1 11669 return true;
9ea033b2
NC
11670}
11671
015dc7e1 11672static bool
dda8d76d 11673get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11674{
2cf0635d
NC
11675 Elf64_External_Dyn * edyn;
11676 Elf64_External_Dyn * ext;
11677 Elf_Internal_Dyn * entry;
103f02d3 11678
071436c6 11679 /* Read in the data. */
978c4450
AM
11680 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11681 filedata->dynamic_addr, 1,
11682 filedata->dynamic_size,
11683 _("dynamic section"));
a6e9f9df 11684 if (!edyn)
015dc7e1 11685 return false;
103f02d3 11686
071436c6
NC
11687 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11688 might not have the luxury of section headers. Look for the DT_NULL
11689 terminator to determine the number of entries. */
978c4450 11690 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11691 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11692 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11693 ext++)
11694 {
978c4450 11695 filedata->dynamic_nent++;
66543521 11696 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11697 break;
11698 }
252b5132 11699
978c4450
AM
11700 filedata->dynamic_section
11701 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11702 if (filedata->dynamic_section == NULL)
252b5132 11703 {
26c527e6
AM
11704 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11705 filedata->dynamic_nent);
252b5132 11706 free (edyn);
015dc7e1 11707 return false;
252b5132
RH
11708 }
11709
071436c6 11710 /* Convert from external to internal formats. */
978c4450
AM
11711 for (ext = edyn, entry = filedata->dynamic_section;
11712 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11713 ext++, entry++)
252b5132 11714 {
66543521
AM
11715 entry->d_tag = BYTE_GET (ext->d_tag);
11716 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11717 }
11718
11719 free (edyn);
11720
015dc7e1 11721 return true;
9ea033b2
NC
11722}
11723
4de91c10
AM
11724static bool
11725get_dynamic_section (Filedata *filedata)
11726{
11727 if (filedata->dynamic_section)
11728 return true;
11729
11730 if (is_32bit_elf)
11731 return get_32bit_dynamic_section (filedata);
11732 else
11733 return get_64bit_dynamic_section (filedata);
11734}
11735
e9e44622 11736static void
625d49fc 11737print_dynamic_flags (uint64_t flags)
d1133906 11738{
015dc7e1 11739 bool first = true;
13ae64f3 11740
d1133906
NC
11741 while (flags)
11742 {
625d49fc 11743 uint64_t flag;
d1133906
NC
11744
11745 flag = flags & - flags;
11746 flags &= ~ flag;
11747
e9e44622 11748 if (first)
015dc7e1 11749 first = false;
e9e44622
JJ
11750 else
11751 putc (' ', stdout);
13ae64f3 11752
d1133906
NC
11753 switch (flag)
11754 {
e9e44622
JJ
11755 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11756 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11757 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11758 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11759 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11760 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11761 }
11762 }
e9e44622 11763 puts ("");
d1133906
NC
11764}
11765
625d49fc 11766static uint64_t *
be7d229a 11767get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11768{
11769 unsigned char * e_data;
625d49fc 11770 uint64_t * i_data;
10ca4b04 11771
be7d229a
AM
11772 /* If size_t is smaller than uint64_t, eg because you are building
11773 on a 32-bit host, then make sure that when number is cast to
11774 size_t no information is lost. */
11775 if ((size_t) number != number
11776 || ent_size * number / ent_size != number)
10ca4b04 11777 {
be7d229a 11778 error (_("Size overflow prevents reading %" PRIu64
b8281767 11779 " elements of size %u\n"),
be7d229a 11780 number, ent_size);
10ca4b04
L
11781 return NULL;
11782 }
11783
11784 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11785 attempting to allocate memory when the read is bound to fail. */
11786 if (ent_size * number > filedata->file_size)
11787 {
b8281767 11788 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11789 number);
10ca4b04
L
11790 return NULL;
11791 }
11792
11793 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11794 if (e_data == NULL)
11795 {
b8281767 11796 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11797 number);
10ca4b04
L
11798 return NULL;
11799 }
11800
11801 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11802 {
b8281767 11803 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11804 number * ent_size);
10ca4b04
L
11805 free (e_data);
11806 return NULL;
11807 }
11808
625d49fc 11809 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11810 if (i_data == NULL)
11811 {
b8281767 11812 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11813 number);
10ca4b04
L
11814 free (e_data);
11815 return NULL;
11816 }
11817
11818 while (number--)
11819 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11820
11821 free (e_data);
11822
11823 return i_data;
11824}
11825
26c527e6 11826static uint64_t
10ca4b04
L
11827get_num_dynamic_syms (Filedata * filedata)
11828{
26c527e6 11829 uint64_t num_of_syms = 0;
10ca4b04
L
11830
11831 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11832 return num_of_syms;
11833
978c4450 11834 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11835 {
11836 unsigned char nb[8];
11837 unsigned char nc[8];
11838 unsigned int hash_ent_size = 4;
11839
11840 if ((filedata->file_header.e_machine == EM_ALPHA
11841 || filedata->file_header.e_machine == EM_S390
11842 || filedata->file_header.e_machine == EM_S390_OLD)
11843 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11844 hash_ent_size = 8;
11845
63cf857e
AM
11846 if (fseek64 (filedata->handle,
11847 (filedata->archive_file_offset
11848 + offset_from_vma (filedata,
11849 filedata->dynamic_info[DT_HASH],
11850 sizeof nb + sizeof nc)),
11851 SEEK_SET))
10ca4b04
L
11852 {
11853 error (_("Unable to seek to start of dynamic information\n"));
11854 goto no_hash;
11855 }
11856
11857 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11858 {
11859 error (_("Failed to read in number of buckets\n"));
11860 goto no_hash;
11861 }
11862
11863 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11864 {
11865 error (_("Failed to read in number of chains\n"));
11866 goto no_hash;
11867 }
11868
978c4450
AM
11869 filedata->nbuckets = byte_get (nb, hash_ent_size);
11870 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11871
2482f306
AM
11872 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11873 {
11874 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11875 hash_ent_size);
11876 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11877 hash_ent_size);
001890e1 11878
2482f306
AM
11879 if (filedata->buckets != NULL && filedata->chains != NULL)
11880 num_of_syms = filedata->nchains;
11881 }
ceb9bf11 11882 no_hash:
10ca4b04
L
11883 if (num_of_syms == 0)
11884 {
9db70fc3
AM
11885 free (filedata->buckets);
11886 filedata->buckets = NULL;
11887 free (filedata->chains);
11888 filedata->chains = NULL;
978c4450 11889 filedata->nbuckets = 0;
10ca4b04
L
11890 }
11891 }
11892
978c4450 11893 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11894 {
11895 unsigned char nb[16];
625d49fc
AM
11896 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11897 uint64_t buckets_vma;
26c527e6 11898 uint64_t hn;
10ca4b04 11899
63cf857e
AM
11900 if (fseek64 (filedata->handle,
11901 (filedata->archive_file_offset
11902 + offset_from_vma (filedata,
11903 filedata->dynamic_info_DT_GNU_HASH,
11904 sizeof nb)),
11905 SEEK_SET))
10ca4b04
L
11906 {
11907 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11908 goto no_gnu_hash;
11909 }
11910
11911 if (fread (nb, 16, 1, filedata->handle) != 1)
11912 {
11913 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11914 goto no_gnu_hash;
11915 }
11916
978c4450
AM
11917 filedata->ngnubuckets = byte_get (nb, 4);
11918 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11919 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11920 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11921 if (is_32bit_elf)
11922 buckets_vma += bitmaskwords * 4;
11923 else
11924 buckets_vma += bitmaskwords * 8;
11925
63cf857e
AM
11926 if (fseek64 (filedata->handle,
11927 (filedata->archive_file_offset
11928 + offset_from_vma (filedata, buckets_vma, 4)),
11929 SEEK_SET))
10ca4b04
L
11930 {
11931 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11932 goto no_gnu_hash;
11933 }
11934
978c4450
AM
11935 filedata->gnubuckets
11936 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11937
978c4450 11938 if (filedata->gnubuckets == NULL)
90837ea7 11939 goto no_gnu_hash;
10ca4b04 11940
978c4450
AM
11941 for (i = 0; i < filedata->ngnubuckets; i++)
11942 if (filedata->gnubuckets[i] != 0)
10ca4b04 11943 {
978c4450 11944 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11945 goto no_gnu_hash;
10ca4b04 11946
978c4450
AM
11947 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11948 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11949 }
11950
11951 if (maxchain == 0xffffffff)
90837ea7 11952 goto no_gnu_hash;
10ca4b04 11953
978c4450 11954 maxchain -= filedata->gnusymidx;
10ca4b04 11955
63cf857e
AM
11956 if (fseek64 (filedata->handle,
11957 (filedata->archive_file_offset
11958 + offset_from_vma (filedata,
11959 buckets_vma + 4 * (filedata->ngnubuckets
11960 + maxchain),
11961 4)),
11962 SEEK_SET))
10ca4b04
L
11963 {
11964 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11965 goto no_gnu_hash;
11966 }
11967
11968 do
11969 {
11970 if (fread (nb, 4, 1, filedata->handle) != 1)
11971 {
11972 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11973 goto no_gnu_hash;
11974 }
11975
11976 if (maxchain + 1 == 0)
90837ea7 11977 goto no_gnu_hash;
10ca4b04
L
11978
11979 ++maxchain;
11980 }
11981 while ((byte_get (nb, 4) & 1) == 0);
11982
63cf857e
AM
11983 if (fseek64 (filedata->handle,
11984 (filedata->archive_file_offset
11985 + offset_from_vma (filedata, (buckets_vma
11986 + 4 * filedata->ngnubuckets),
11987 4)),
11988 SEEK_SET))
10ca4b04
L
11989 {
11990 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11991 goto no_gnu_hash;
11992 }
11993
978c4450
AM
11994 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11995 filedata->ngnuchains = maxchain;
10ca4b04 11996
978c4450 11997 if (filedata->gnuchains == NULL)
90837ea7 11998 goto no_gnu_hash;
10ca4b04 11999
978c4450 12000 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12001 {
63cf857e
AM
12002 if (fseek64 (filedata->handle,
12003 (filedata->archive_file_offset
12004 + offset_from_vma (filedata, (buckets_vma
12005 + 4 * (filedata->ngnubuckets
12006 + maxchain)), 4)),
12007 SEEK_SET))
10ca4b04
L
12008 {
12009 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12010 goto no_gnu_hash;
12011 }
12012
978c4450 12013 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
12014 if (filedata->mipsxlat == NULL)
12015 goto no_gnu_hash;
10ca4b04
L
12016 }
12017
978c4450
AM
12018 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12019 if (filedata->gnubuckets[hn] != 0)
10ca4b04 12020 {
625d49fc
AM
12021 uint64_t si = filedata->gnubuckets[hn];
12022 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
12023
12024 do
12025 {
978c4450 12026 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12027 {
c31ab5a0
AM
12028 if (off < filedata->ngnuchains
12029 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 12030 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
12031 }
12032 else
12033 {
12034 if (si >= num_of_syms)
12035 num_of_syms = si + 1;
12036 }
12037 si++;
12038 }
978c4450
AM
12039 while (off < filedata->ngnuchains
12040 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
12041 }
12042
90837ea7 12043 if (num_of_syms == 0)
10ca4b04 12044 {
90837ea7 12045 no_gnu_hash:
9db70fc3
AM
12046 free (filedata->mipsxlat);
12047 filedata->mipsxlat = NULL;
12048 free (filedata->gnuchains);
12049 filedata->gnuchains = NULL;
12050 free (filedata->gnubuckets);
12051 filedata->gnubuckets = NULL;
978c4450
AM
12052 filedata->ngnubuckets = 0;
12053 filedata->ngnuchains = 0;
10ca4b04
L
12054 }
12055 }
12056
12057 return num_of_syms;
12058}
12059
b2d38a17
NC
12060/* Parse and display the contents of the dynamic section. */
12061
015dc7e1 12062static bool
dda8d76d 12063process_dynamic_section (Filedata * filedata)
9ea033b2 12064{
2cf0635d 12065 Elf_Internal_Dyn * entry;
9ea033b2 12066
93df3340 12067 if (filedata->dynamic_size <= 1)
9ea033b2
NC
12068 {
12069 if (do_dynamic)
ca0e11aa
NC
12070 {
12071 if (filedata->is_separate)
12072 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
12073 filedata->file_name);
12074 else
12075 printf (_("\nThere is no dynamic section in this file.\n"));
12076 }
9ea033b2 12077
015dc7e1 12078 return true;
9ea033b2
NC
12079 }
12080
4de91c10
AM
12081 if (!get_dynamic_section (filedata))
12082 return false;
9ea033b2 12083
252b5132 12084 /* Find the appropriate symbol table. */
978c4450 12085 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 12086 {
26c527e6 12087 uint64_t num_of_syms;
2482f306 12088
978c4450
AM
12089 for (entry = filedata->dynamic_section;
12090 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12091 ++entry)
10ca4b04 12092 if (entry->d_tag == DT_SYMTAB)
978c4450 12093 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 12094 else if (entry->d_tag == DT_SYMENT)
978c4450 12095 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 12096 else if (entry->d_tag == DT_HASH)
978c4450 12097 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 12098 else if (entry->d_tag == DT_GNU_HASH)
978c4450 12099 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
12100 else if ((filedata->file_header.e_machine == EM_MIPS
12101 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12102 && entry->d_tag == DT_MIPS_XHASH)
12103 {
978c4450
AM
12104 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12105 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 12106 }
252b5132 12107
2482f306
AM
12108 num_of_syms = get_num_dynamic_syms (filedata);
12109
12110 if (num_of_syms != 0
12111 && filedata->dynamic_symbols == NULL
12112 && filedata->dynamic_info[DT_SYMTAB]
978c4450 12113 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
12114 {
12115 Elf_Internal_Phdr *seg;
625d49fc 12116 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 12117
2482f306
AM
12118 if (! get_program_headers (filedata))
12119 {
12120 error (_("Cannot interpret virtual addresses "
12121 "without program headers.\n"));
015dc7e1 12122 return false;
2482f306 12123 }
252b5132 12124
2482f306
AM
12125 for (seg = filedata->program_headers;
12126 seg < filedata->program_headers + filedata->file_header.e_phnum;
12127 ++seg)
12128 {
12129 if (seg->p_type != PT_LOAD)
12130 continue;
252b5132 12131
2482f306
AM
12132 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12133 {
12134 /* See PR 21379 for a reproducer. */
12135 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 12136 return false;
2482f306 12137 }
252b5132 12138
2482f306
AM
12139 if (vma >= (seg->p_vaddr & -seg->p_align)
12140 && vma < seg->p_vaddr + seg->p_filesz)
12141 {
12142 /* Since we do not know how big the symbol table is,
12143 we default to reading in up to the end of PT_LOAD
12144 segment and processing that. This is overkill, I
12145 know, but it should work. */
12146 Elf_Internal_Shdr section;
12147 section.sh_offset = (vma - seg->p_vaddr
12148 + seg->p_offset);
12149 section.sh_size = (num_of_syms
12150 * filedata->dynamic_info[DT_SYMENT]);
12151 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
12152
12153 if (do_checks
12154 && filedata->dynamic_symtab_section != NULL
12155 && ((filedata->dynamic_symtab_section->sh_offset
12156 != section.sh_offset)
12157 || (filedata->dynamic_symtab_section->sh_size
12158 != section.sh_size)
12159 || (filedata->dynamic_symtab_section->sh_entsize
12160 != section.sh_entsize)))
12161 warn (_("\
12162the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12163
2482f306
AM
12164 section.sh_name = filedata->string_table_length;
12165 filedata->dynamic_symbols
4de91c10 12166 = get_elf_symbols (filedata, &section,
2482f306
AM
12167 &filedata->num_dynamic_syms);
12168 if (filedata->dynamic_symbols == NULL
12169 || filedata->num_dynamic_syms != num_of_syms)
12170 {
12171 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 12172 return false;
2482f306
AM
12173 }
12174 break;
12175 }
12176 }
12177 }
12178 }
252b5132
RH
12179
12180 /* Similarly find a string table. */
978c4450
AM
12181 if (filedata->dynamic_strings == NULL)
12182 for (entry = filedata->dynamic_section;
12183 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
12184 ++entry)
12185 {
12186 if (entry->d_tag == DT_STRTAB)
978c4450 12187 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 12188
10ca4b04 12189 if (entry->d_tag == DT_STRSZ)
978c4450 12190 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 12191
978c4450
AM
12192 if (filedata->dynamic_info[DT_STRTAB]
12193 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 12194 {
26c527e6 12195 uint64_t offset;
be7d229a 12196 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
12197
12198 offset = offset_from_vma (filedata,
978c4450 12199 filedata->dynamic_info[DT_STRTAB],
10ca4b04 12200 str_tab_len);
8ac10c5b
L
12201 if (do_checks
12202 && filedata->dynamic_strtab_section
12203 && ((filedata->dynamic_strtab_section->sh_offset
12204 != (file_ptr) offset)
12205 || (filedata->dynamic_strtab_section->sh_size
12206 != str_tab_len)))
12207 warn (_("\
12208the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12209
978c4450
AM
12210 filedata->dynamic_strings
12211 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12212 _("dynamic string table"));
12213 if (filedata->dynamic_strings == NULL)
10ca4b04
L
12214 {
12215 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12216 break;
12217 }
e3d39609 12218
978c4450 12219 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
12220 break;
12221 }
12222 }
252b5132
RH
12223
12224 /* And find the syminfo section if available. */
978c4450 12225 if (filedata->dynamic_syminfo == NULL)
252b5132 12226 {
26c527e6 12227 uint64_t syminsz = 0;
252b5132 12228
978c4450
AM
12229 for (entry = filedata->dynamic_section;
12230 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12231 ++entry)
252b5132
RH
12232 {
12233 if (entry->d_tag == DT_SYMINENT)
12234 {
12235 /* Note: these braces are necessary to avoid a syntax
12236 error from the SunOS4 C compiler. */
049b0c3a
NC
12237 /* PR binutils/17531: A corrupt file can trigger this test.
12238 So do not use an assert, instead generate an error message. */
12239 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 12240 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 12241 (int) entry->d_un.d_val);
252b5132
RH
12242 }
12243 else if (entry->d_tag == DT_SYMINSZ)
12244 syminsz = entry->d_un.d_val;
12245 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
12246 filedata->dynamic_syminfo_offset
12247 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
12248 }
12249
978c4450 12250 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 12251 {
2cf0635d
NC
12252 Elf_External_Syminfo * extsyminfo;
12253 Elf_External_Syminfo * extsym;
12254 Elf_Internal_Syminfo * syminfo;
252b5132
RH
12255
12256 /* There is a syminfo section. Read the data. */
3f5e193b 12257 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
12258 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12259 1, syminsz, _("symbol information"));
a6e9f9df 12260 if (!extsyminfo)
015dc7e1 12261 return false;
252b5132 12262
978c4450 12263 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
12264 {
12265 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 12266 free (filedata->dynamic_syminfo);
e3d39609 12267 }
978c4450
AM
12268 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12269 if (filedata->dynamic_syminfo == NULL)
252b5132 12270 {
26c527e6
AM
12271 error (_("Out of memory allocating %" PRIu64
12272 " bytes for dynamic symbol info\n"),
12273 syminsz);
015dc7e1 12274 return false;
252b5132
RH
12275 }
12276
2482f306
AM
12277 filedata->dynamic_syminfo_nent
12278 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12279 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12280 syminfo < (filedata->dynamic_syminfo
12281 + filedata->dynamic_syminfo_nent);
86dba8ee 12282 ++syminfo, ++extsym)
252b5132 12283 {
86dba8ee
AM
12284 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12285 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12286 }
12287
12288 free (extsyminfo);
12289 }
12290 }
12291
978c4450 12292 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12293 {
f253158f 12294 if (filedata->is_separate)
26c527e6
AM
12295 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12296 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12297 filedata->dynamic_nent),
f253158f
NC
12298 filedata->file_name,
12299 filedata->dynamic_addr,
26c527e6 12300 filedata->dynamic_nent);
84a9f195 12301 else
02da71ee 12302 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12303 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12304 filedata->dynamic_nent),
84a9f195 12305 filedata->dynamic_addr,
26c527e6 12306 filedata->dynamic_nent);
ca0e11aa 12307 }
252b5132
RH
12308 if (do_dynamic)
12309 printf (_(" Tag Type Name/Value\n"));
12310
978c4450
AM
12311 for (entry = filedata->dynamic_section;
12312 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12313 entry++)
252b5132
RH
12314 {
12315 if (do_dynamic)
f7a99963 12316 {
2cf0635d 12317 const char * dtype;
e699b9ff 12318
f7a99963
NC
12319 putchar (' ');
12320 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12321 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12322 printf (" (%s)%*s", dtype,
32ec8896 12323 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12324 }
252b5132
RH
12325
12326 switch (entry->d_tag)
12327 {
d1133906
NC
12328 case DT_FLAGS:
12329 if (do_dynamic)
e9e44622 12330 print_dynamic_flags (entry->d_un.d_val);
d1133906 12331 break;
76da6bbe 12332
252b5132
RH
12333 case DT_AUXILIARY:
12334 case DT_FILTER:
019148e4
L
12335 case DT_CONFIG:
12336 case DT_DEPAUDIT:
12337 case DT_AUDIT:
252b5132
RH
12338 if (do_dynamic)
12339 {
019148e4 12340 switch (entry->d_tag)
b34976b6 12341 {
019148e4
L
12342 case DT_AUXILIARY:
12343 printf (_("Auxiliary library"));
12344 break;
12345
12346 case DT_FILTER:
12347 printf (_("Filter library"));
12348 break;
12349
b34976b6 12350 case DT_CONFIG:
019148e4
L
12351 printf (_("Configuration file"));
12352 break;
12353
12354 case DT_DEPAUDIT:
12355 printf (_("Dependency audit library"));
12356 break;
12357
12358 case DT_AUDIT:
12359 printf (_("Audit library"));
12360 break;
12361 }
252b5132 12362
84714f86 12363 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12364 printf (": [%s]\n",
84714f86 12365 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12366 else
f7a99963
NC
12367 {
12368 printf (": ");
12369 print_vma (entry->d_un.d_val, PREFIX_HEX);
12370 putchar ('\n');
12371 }
252b5132
RH
12372 }
12373 break;
12374
dcefbbbd 12375 case DT_FEATURE:
252b5132
RH
12376 if (do_dynamic)
12377 {
12378 printf (_("Flags:"));
86f55779 12379
252b5132
RH
12380 if (entry->d_un.d_val == 0)
12381 printf (_(" None\n"));
12382 else
12383 {
26c527e6 12384 uint64_t val = entry->d_un.d_val;
86f55779 12385
252b5132
RH
12386 if (val & DTF_1_PARINIT)
12387 {
12388 printf (" PARINIT");
12389 val ^= DTF_1_PARINIT;
12390 }
dcefbbbd
L
12391 if (val & DTF_1_CONFEXP)
12392 {
12393 printf (" CONFEXP");
12394 val ^= DTF_1_CONFEXP;
12395 }
252b5132 12396 if (val != 0)
26c527e6 12397 printf (" %" PRIx64, val);
252b5132
RH
12398 puts ("");
12399 }
12400 }
12401 break;
12402
12403 case DT_POSFLAG_1:
12404 if (do_dynamic)
12405 {
12406 printf (_("Flags:"));
86f55779 12407
252b5132
RH
12408 if (entry->d_un.d_val == 0)
12409 printf (_(" None\n"));
12410 else
12411 {
26c527e6 12412 uint64_t val = entry->d_un.d_val;
86f55779 12413
252b5132
RH
12414 if (val & DF_P1_LAZYLOAD)
12415 {
12416 printf (" LAZYLOAD");
12417 val ^= DF_P1_LAZYLOAD;
12418 }
12419 if (val & DF_P1_GROUPPERM)
12420 {
12421 printf (" GROUPPERM");
12422 val ^= DF_P1_GROUPPERM;
12423 }
12424 if (val != 0)
26c527e6 12425 printf (" %" PRIx64, val);
252b5132
RH
12426 puts ("");
12427 }
12428 }
12429 break;
12430
12431 case DT_FLAGS_1:
12432 if (do_dynamic)
12433 {
12434 printf (_("Flags:"));
12435 if (entry->d_un.d_val == 0)
12436 printf (_(" None\n"));
12437 else
12438 {
26c527e6 12439 uint64_t val = entry->d_un.d_val;
86f55779 12440
252b5132
RH
12441 if (val & DF_1_NOW)
12442 {
12443 printf (" NOW");
12444 val ^= DF_1_NOW;
12445 }
12446 if (val & DF_1_GLOBAL)
12447 {
12448 printf (" GLOBAL");
12449 val ^= DF_1_GLOBAL;
12450 }
12451 if (val & DF_1_GROUP)
12452 {
12453 printf (" GROUP");
12454 val ^= DF_1_GROUP;
12455 }
12456 if (val & DF_1_NODELETE)
12457 {
12458 printf (" NODELETE");
12459 val ^= DF_1_NODELETE;
12460 }
12461 if (val & DF_1_LOADFLTR)
12462 {
12463 printf (" LOADFLTR");
12464 val ^= DF_1_LOADFLTR;
12465 }
12466 if (val & DF_1_INITFIRST)
12467 {
12468 printf (" INITFIRST");
12469 val ^= DF_1_INITFIRST;
12470 }
12471 if (val & DF_1_NOOPEN)
12472 {
12473 printf (" NOOPEN");
12474 val ^= DF_1_NOOPEN;
12475 }
12476 if (val & DF_1_ORIGIN)
12477 {
12478 printf (" ORIGIN");
12479 val ^= DF_1_ORIGIN;
12480 }
12481 if (val & DF_1_DIRECT)
12482 {
12483 printf (" DIRECT");
12484 val ^= DF_1_DIRECT;
12485 }
12486 if (val & DF_1_TRANS)
12487 {
12488 printf (" TRANS");
12489 val ^= DF_1_TRANS;
12490 }
12491 if (val & DF_1_INTERPOSE)
12492 {
12493 printf (" INTERPOSE");
12494 val ^= DF_1_INTERPOSE;
12495 }
f7db6139 12496 if (val & DF_1_NODEFLIB)
dcefbbbd 12497 {
f7db6139
L
12498 printf (" NODEFLIB");
12499 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12500 }
12501 if (val & DF_1_NODUMP)
12502 {
12503 printf (" NODUMP");
12504 val ^= DF_1_NODUMP;
12505 }
34b60028 12506 if (val & DF_1_CONFALT)
dcefbbbd 12507 {
34b60028
L
12508 printf (" CONFALT");
12509 val ^= DF_1_CONFALT;
12510 }
12511 if (val & DF_1_ENDFILTEE)
12512 {
12513 printf (" ENDFILTEE");
12514 val ^= DF_1_ENDFILTEE;
12515 }
12516 if (val & DF_1_DISPRELDNE)
12517 {
12518 printf (" DISPRELDNE");
12519 val ^= DF_1_DISPRELDNE;
12520 }
12521 if (val & DF_1_DISPRELPND)
12522 {
12523 printf (" DISPRELPND");
12524 val ^= DF_1_DISPRELPND;
12525 }
12526 if (val & DF_1_NODIRECT)
12527 {
12528 printf (" NODIRECT");
12529 val ^= DF_1_NODIRECT;
12530 }
12531 if (val & DF_1_IGNMULDEF)
12532 {
12533 printf (" IGNMULDEF");
12534 val ^= DF_1_IGNMULDEF;
12535 }
12536 if (val & DF_1_NOKSYMS)
12537 {
12538 printf (" NOKSYMS");
12539 val ^= DF_1_NOKSYMS;
12540 }
12541 if (val & DF_1_NOHDR)
12542 {
12543 printf (" NOHDR");
12544 val ^= DF_1_NOHDR;
12545 }
12546 if (val & DF_1_EDITED)
12547 {
12548 printf (" EDITED");
12549 val ^= DF_1_EDITED;
12550 }
12551 if (val & DF_1_NORELOC)
12552 {
12553 printf (" NORELOC");
12554 val ^= DF_1_NORELOC;
12555 }
12556 if (val & DF_1_SYMINTPOSE)
12557 {
12558 printf (" SYMINTPOSE");
12559 val ^= DF_1_SYMINTPOSE;
12560 }
12561 if (val & DF_1_GLOBAUDIT)
12562 {
12563 printf (" GLOBAUDIT");
12564 val ^= DF_1_GLOBAUDIT;
12565 }
12566 if (val & DF_1_SINGLETON)
12567 {
12568 printf (" SINGLETON");
12569 val ^= DF_1_SINGLETON;
dcefbbbd 12570 }
5c383f02
RO
12571 if (val & DF_1_STUB)
12572 {
12573 printf (" STUB");
12574 val ^= DF_1_STUB;
12575 }
12576 if (val & DF_1_PIE)
12577 {
12578 printf (" PIE");
12579 val ^= DF_1_PIE;
12580 }
b1202ffa
L
12581 if (val & DF_1_KMOD)
12582 {
12583 printf (" KMOD");
12584 val ^= DF_1_KMOD;
12585 }
12586 if (val & DF_1_WEAKFILTER)
12587 {
12588 printf (" WEAKFILTER");
12589 val ^= DF_1_WEAKFILTER;
12590 }
12591 if (val & DF_1_NOCOMMON)
12592 {
12593 printf (" NOCOMMON");
12594 val ^= DF_1_NOCOMMON;
12595 }
252b5132 12596 if (val != 0)
26c527e6 12597 printf (" %" PRIx64, val);
252b5132
RH
12598 puts ("");
12599 }
12600 }
12601 break;
12602
12603 case DT_PLTREL:
978c4450 12604 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12605 if (do_dynamic)
dda8d76d 12606 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12607 break;
12608
12609 case DT_NULL :
12610 case DT_NEEDED :
12611 case DT_PLTGOT :
12612 case DT_HASH :
12613 case DT_STRTAB :
12614 case DT_SYMTAB :
12615 case DT_RELA :
12616 case DT_INIT :
12617 case DT_FINI :
12618 case DT_SONAME :
12619 case DT_RPATH :
12620 case DT_SYMBOLIC:
12621 case DT_REL :
a7fd1186 12622 case DT_RELR :
252b5132
RH
12623 case DT_DEBUG :
12624 case DT_TEXTREL :
12625 case DT_JMPREL :
019148e4 12626 case DT_RUNPATH :
978c4450 12627 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12628
12629 if (do_dynamic)
12630 {
84714f86 12631 const char *name;
252b5132 12632
84714f86
AM
12633 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12634 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12635 else
d79b3d50 12636 name = NULL;
252b5132
RH
12637
12638 if (name)
12639 {
12640 switch (entry->d_tag)
12641 {
12642 case DT_NEEDED:
12643 printf (_("Shared library: [%s]"), name);
12644
13acb58d
AM
12645 if (filedata->program_interpreter
12646 && streq (name, filedata->program_interpreter))
f7a99963 12647 printf (_(" program interpreter"));
252b5132
RH
12648 break;
12649
12650 case DT_SONAME:
f7a99963 12651 printf (_("Library soname: [%s]"), name);
252b5132
RH
12652 break;
12653
12654 case DT_RPATH:
f7a99963 12655 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12656 break;
12657
019148e4
L
12658 case DT_RUNPATH:
12659 printf (_("Library runpath: [%s]"), name);
12660 break;
12661
252b5132 12662 default:
f7a99963
NC
12663 print_vma (entry->d_un.d_val, PREFIX_HEX);
12664 break;
252b5132
RH
12665 }
12666 }
12667 else
f7a99963
NC
12668 print_vma (entry->d_un.d_val, PREFIX_HEX);
12669
12670 putchar ('\n');
252b5132
RH
12671 }
12672 break;
12673
12674 case DT_PLTRELSZ:
12675 case DT_RELASZ :
12676 case DT_STRSZ :
12677 case DT_RELSZ :
12678 case DT_RELAENT :
a7fd1186
FS
12679 case DT_RELRENT :
12680 case DT_RELRSZ :
252b5132
RH
12681 case DT_SYMENT :
12682 case DT_RELENT :
978c4450 12683 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12684 /* Fall through. */
252b5132
RH
12685 case DT_PLTPADSZ:
12686 case DT_MOVEENT :
12687 case DT_MOVESZ :
04d8355a 12688 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12689 case DT_INIT_ARRAYSZ:
12690 case DT_FINI_ARRAYSZ:
047b2264
JJ
12691 case DT_GNU_CONFLICTSZ:
12692 case DT_GNU_LIBLISTSZ:
252b5132 12693 if (do_dynamic)
f7a99963
NC
12694 {
12695 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12696 printf (_(" (bytes)\n"));
f7a99963 12697 }
252b5132
RH
12698 break;
12699
12700 case DT_VERDEFNUM:
12701 case DT_VERNEEDNUM:
12702 case DT_RELACOUNT:
12703 case DT_RELCOUNT:
12704 if (do_dynamic)
f7a99963
NC
12705 {
12706 print_vma (entry->d_un.d_val, UNSIGNED);
12707 putchar ('\n');
12708 }
252b5132
RH
12709 break;
12710
12711 case DT_SYMINSZ:
12712 case DT_SYMINENT:
12713 case DT_SYMINFO:
12714 case DT_USED:
12715 case DT_INIT_ARRAY:
12716 case DT_FINI_ARRAY:
12717 if (do_dynamic)
12718 {
d79b3d50 12719 if (entry->d_tag == DT_USED
84714f86 12720 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12721 {
84714f86
AM
12722 const char *name
12723 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12724
b34976b6 12725 if (*name)
252b5132
RH
12726 {
12727 printf (_("Not needed object: [%s]\n"), name);
12728 break;
12729 }
12730 }
103f02d3 12731
f7a99963
NC
12732 print_vma (entry->d_un.d_val, PREFIX_HEX);
12733 putchar ('\n');
252b5132
RH
12734 }
12735 break;
12736
12737 case DT_BIND_NOW:
12738 /* The value of this entry is ignored. */
35b1837e
AM
12739 if (do_dynamic)
12740 putchar ('\n');
252b5132 12741 break;
103f02d3 12742
047b2264
JJ
12743 case DT_GNU_PRELINKED:
12744 if (do_dynamic)
12745 {
2cf0635d 12746 struct tm * tmp;
91d6fa6a 12747 time_t atime = entry->d_un.d_val;
047b2264 12748
91d6fa6a 12749 tmp = gmtime (&atime);
071436c6
NC
12750 /* PR 17533 file: 041-1244816-0.004. */
12751 if (tmp == NULL)
26c527e6
AM
12752 printf (_("<corrupt time val: %" PRIx64),
12753 (uint64_t) atime);
071436c6
NC
12754 else
12755 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12756 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12757 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12758
12759 }
12760 break;
12761
fdc90cb4 12762 case DT_GNU_HASH:
978c4450 12763 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12764 if (do_dynamic)
12765 {
12766 print_vma (entry->d_un.d_val, PREFIX_HEX);
12767 putchar ('\n');
12768 }
12769 break;
12770
a5da3dee
VDM
12771 case DT_GNU_FLAGS_1:
12772 if (do_dynamic)
12773 {
12774 printf (_("Flags:"));
12775 if (entry->d_un.d_val == 0)
12776 printf (_(" None\n"));
12777 else
12778 {
26c527e6 12779 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12780
12781 if (val & DF_GNU_1_UNIQUE)
12782 {
12783 printf (" UNIQUE");
12784 val ^= DF_GNU_1_UNIQUE;
12785 }
12786 if (val != 0)
26c527e6 12787 printf (" %" PRIx64, val);
a5da3dee
VDM
12788 puts ("");
12789 }
12790 }
12791 break;
12792
252b5132
RH
12793 default:
12794 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12795 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12796 = entry->d_un.d_val;
252b5132
RH
12797
12798 if (do_dynamic)
12799 {
dda8d76d 12800 switch (filedata->file_header.e_machine)
252b5132 12801 {
37c18eed
SD
12802 case EM_AARCH64:
12803 dynamic_section_aarch64_val (entry);
12804 break;
252b5132 12805 case EM_MIPS:
4fe85591 12806 case EM_MIPS_RS3_LE:
978c4450 12807 dynamic_section_mips_val (filedata, entry);
252b5132 12808 break;
103f02d3 12809 case EM_PARISC:
b2d38a17 12810 dynamic_section_parisc_val (entry);
103f02d3 12811 break;
ecc51f48 12812 case EM_IA_64:
b2d38a17 12813 dynamic_section_ia64_val (entry);
ecc51f48 12814 break;
252b5132 12815 default:
f7a99963
NC
12816 print_vma (entry->d_un.d_val, PREFIX_HEX);
12817 putchar ('\n');
252b5132
RH
12818 }
12819 }
12820 break;
12821 }
12822 }
12823
015dc7e1 12824 return true;
252b5132
RH
12825}
12826
12827static char *
d3ba0551 12828get_ver_flags (unsigned int flags)
252b5132 12829{
6d4f21f6 12830 static char buff[128];
252b5132
RH
12831
12832 buff[0] = 0;
12833
12834 if (flags == 0)
12835 return _("none");
12836
12837 if (flags & VER_FLG_BASE)
7bb1ad17 12838 strcat (buff, "BASE");
252b5132
RH
12839
12840 if (flags & VER_FLG_WEAK)
12841 {
12842 if (flags & VER_FLG_BASE)
7bb1ad17 12843 strcat (buff, " | ");
252b5132 12844
7bb1ad17 12845 strcat (buff, "WEAK");
252b5132
RH
12846 }
12847
44ec90b9
RO
12848 if (flags & VER_FLG_INFO)
12849 {
12850 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12851 strcat (buff, " | ");
44ec90b9 12852
7bb1ad17 12853 strcat (buff, "INFO");
44ec90b9
RO
12854 }
12855
12856 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12857 {
12858 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12859 strcat (buff, " | ");
12860
12861 strcat (buff, _("<unknown>"));
12862 }
252b5132
RH
12863
12864 return buff;
12865}
12866
12867/* Display the contents of the version sections. */
98fb390a 12868
015dc7e1 12869static bool
dda8d76d 12870process_version_sections (Filedata * filedata)
252b5132 12871{
2cf0635d 12872 Elf_Internal_Shdr * section;
b34976b6 12873 unsigned i;
015dc7e1 12874 bool found = false;
252b5132
RH
12875
12876 if (! do_version)
015dc7e1 12877 return true;
252b5132 12878
dda8d76d
NC
12879 for (i = 0, section = filedata->section_headers;
12880 i < filedata->file_header.e_shnum;
b34976b6 12881 i++, section++)
252b5132
RH
12882 {
12883 switch (section->sh_type)
12884 {
12885 case SHT_GNU_verdef:
12886 {
2cf0635d 12887 Elf_External_Verdef * edefs;
26c527e6
AM
12888 size_t idx;
12889 size_t cnt;
2cf0635d 12890 char * endbuf;
252b5132 12891
015dc7e1 12892 found = true;
252b5132 12893
ca0e11aa
NC
12894 if (filedata->is_separate)
12895 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12896 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12897 section->sh_info),
12898 filedata->file_name,
12899 printable_section_name (filedata, section),
12900 section->sh_info);
12901 else
12902 printf (ngettext ("\nVersion definition section '%s' "
12903 "contains %u entry:\n",
12904 "\nVersion definition section '%s' "
12905 "contains %u entries:\n",
12906 section->sh_info),
12907 printable_section_name (filedata, section),
12908 section->sh_info);
047c3dbf 12909
625d49fc 12910 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12911 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12912 section->sh_offset, section->sh_link,
b6ac461a 12913 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12914
3f5e193b 12915 edefs = (Elf_External_Verdef *)
dda8d76d 12916 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12917 _("version definition section"));
a6e9f9df
AM
12918 if (!edefs)
12919 break;
59245841 12920 endbuf = (char *) edefs + section->sh_size;
252b5132 12921
1445030f 12922 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12923 {
2cf0635d
NC
12924 char * vstart;
12925 Elf_External_Verdef * edef;
b34976b6 12926 Elf_Internal_Verdef ent;
2cf0635d 12927 Elf_External_Verdaux * eaux;
b34976b6 12928 Elf_Internal_Verdaux aux;
26c527e6 12929 size_t isum;
b34976b6 12930 int j;
103f02d3 12931
252b5132 12932 vstart = ((char *) edefs) + idx;
54806181
AM
12933 if (vstart + sizeof (*edef) > endbuf)
12934 break;
252b5132
RH
12935
12936 edef = (Elf_External_Verdef *) vstart;
12937
12938 ent.vd_version = BYTE_GET (edef->vd_version);
12939 ent.vd_flags = BYTE_GET (edef->vd_flags);
12940 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12941 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12942 ent.vd_hash = BYTE_GET (edef->vd_hash);
12943 ent.vd_aux = BYTE_GET (edef->vd_aux);
12944 ent.vd_next = BYTE_GET (edef->vd_next);
12945
26c527e6 12946 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12947 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12948
12949 printf (_(" Index: %d Cnt: %d "),
12950 ent.vd_ndx, ent.vd_cnt);
12951
452bf675 12952 /* Check for overflow. */
1445030f 12953 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12954 break;
12955
252b5132
RH
12956 vstart += ent.vd_aux;
12957
1445030f
AM
12958 if (vstart + sizeof (*eaux) > endbuf)
12959 break;
252b5132
RH
12960 eaux = (Elf_External_Verdaux *) vstart;
12961
12962 aux.vda_name = BYTE_GET (eaux->vda_name);
12963 aux.vda_next = BYTE_GET (eaux->vda_next);
12964
84714f86 12965 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12966 printf (_("Name: %s\n"),
84714f86 12967 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12968 else
12969 printf (_("Name index: %ld\n"), aux.vda_name);
12970
12971 isum = idx + ent.vd_aux;
12972
b34976b6 12973 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12974 {
1445030f
AM
12975 if (aux.vda_next < sizeof (*eaux)
12976 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12977 {
12978 warn (_("Invalid vda_next field of %lx\n"),
12979 aux.vda_next);
12980 j = ent.vd_cnt;
12981 break;
12982 }
dd24e3da 12983 /* Check for overflow. */
7e26601c 12984 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12985 break;
12986
252b5132
RH
12987 isum += aux.vda_next;
12988 vstart += aux.vda_next;
12989
54806181
AM
12990 if (vstart + sizeof (*eaux) > endbuf)
12991 break;
1445030f 12992 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12993
12994 aux.vda_name = BYTE_GET (eaux->vda_name);
12995 aux.vda_next = BYTE_GET (eaux->vda_next);
12996
84714f86 12997 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12998 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12999 isum, j,
84714f86 13000 get_dynamic_name (filedata, aux.vda_name));
252b5132 13001 else
26c527e6 13002 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
13003 isum, j, aux.vda_name);
13004 }
dd24e3da 13005
54806181
AM
13006 if (j < ent.vd_cnt)
13007 printf (_(" Version def aux past end of section\n"));
252b5132 13008
c9f02c3e
MR
13009 /* PR 17531:
13010 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
13011 if (ent.vd_next < sizeof (*edef)
13012 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13013 {
13014 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13015 cnt = section->sh_info;
13016 break;
13017 }
452bf675 13018 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
13019 break;
13020
252b5132
RH
13021 idx += ent.vd_next;
13022 }
dd24e3da 13023
54806181
AM
13024 if (cnt < section->sh_info)
13025 printf (_(" Version definition past end of section\n"));
252b5132
RH
13026
13027 free (edefs);
13028 }
13029 break;
103f02d3 13030
252b5132
RH
13031 case SHT_GNU_verneed:
13032 {
2cf0635d 13033 Elf_External_Verneed * eneed;
26c527e6
AM
13034 size_t idx;
13035 size_t cnt;
2cf0635d 13036 char * endbuf;
252b5132 13037
015dc7e1 13038 found = true;
252b5132 13039
ca0e11aa
NC
13040 if (filedata->is_separate)
13041 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13042 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13043 section->sh_info),
13044 filedata->file_name,
13045 printable_section_name (filedata, section),
13046 section->sh_info);
13047 else
13048 printf (ngettext ("\nVersion needs section '%s' "
13049 "contains %u entry:\n",
13050 "\nVersion needs section '%s' "
13051 "contains %u entries:\n",
13052 section->sh_info),
13053 printable_section_name (filedata, section),
13054 section->sh_info);
047c3dbf 13055
625d49fc 13056 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13057 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13058 section->sh_offset, section->sh_link,
b6ac461a 13059 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 13060
dda8d76d 13061 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
13062 section->sh_offset, 1,
13063 section->sh_size,
9cf03b7e 13064 _("Version Needs section"));
a6e9f9df
AM
13065 if (!eneed)
13066 break;
59245841 13067 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
13068
13069 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13070 {
2cf0635d 13071 Elf_External_Verneed * entry;
b34976b6 13072 Elf_Internal_Verneed ent;
26c527e6 13073 size_t isum;
b34976b6 13074 int j;
2cf0635d 13075 char * vstart;
252b5132
RH
13076
13077 vstart = ((char *) eneed) + idx;
54806181
AM
13078 if (vstart + sizeof (*entry) > endbuf)
13079 break;
252b5132
RH
13080
13081 entry = (Elf_External_Verneed *) vstart;
13082
13083 ent.vn_version = BYTE_GET (entry->vn_version);
13084 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13085 ent.vn_file = BYTE_GET (entry->vn_file);
13086 ent.vn_aux = BYTE_GET (entry->vn_aux);
13087 ent.vn_next = BYTE_GET (entry->vn_next);
13088
26c527e6 13089 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 13090
84714f86 13091 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 13092 printf (_(" File: %s"),
84714f86 13093 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
13094 else
13095 printf (_(" File: %lx"), ent.vn_file);
13096
13097 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13098
dd24e3da 13099 /* Check for overflow. */
7e26601c 13100 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 13101 break;
252b5132
RH
13102 vstart += ent.vn_aux;
13103
13104 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13105 {
2cf0635d 13106 Elf_External_Vernaux * eaux;
b34976b6 13107 Elf_Internal_Vernaux aux;
252b5132 13108
54806181
AM
13109 if (vstart + sizeof (*eaux) > endbuf)
13110 break;
252b5132
RH
13111 eaux = (Elf_External_Vernaux *) vstart;
13112
13113 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13114 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13115 aux.vna_other = BYTE_GET (eaux->vna_other);
13116 aux.vna_name = BYTE_GET (eaux->vna_name);
13117 aux.vna_next = BYTE_GET (eaux->vna_next);
13118
84714f86 13119 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 13120 printf (_(" %#06zx: Name: %s"),
84714f86 13121 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 13122 else
26c527e6 13123 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
13124 isum, aux.vna_name);
13125
13126 printf (_(" Flags: %s Version: %d\n"),
13127 get_ver_flags (aux.vna_flags), aux.vna_other);
13128
1445030f
AM
13129 if (aux.vna_next < sizeof (*eaux)
13130 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
13131 {
13132 warn (_("Invalid vna_next field of %lx\n"),
13133 aux.vna_next);
13134 j = ent.vn_cnt;
13135 break;
13136 }
1445030f
AM
13137 /* Check for overflow. */
13138 if (aux.vna_next > (size_t) (endbuf - vstart))
13139 break;
252b5132
RH
13140 isum += aux.vna_next;
13141 vstart += aux.vna_next;
13142 }
9cf03b7e 13143
54806181 13144 if (j < ent.vn_cnt)
f9a6a8f0 13145 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 13146
1445030f
AM
13147 if (ent.vn_next < sizeof (*entry)
13148 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 13149 {
452bf675 13150 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
13151 cnt = section->sh_info;
13152 break;
13153 }
1445030f
AM
13154 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13155 break;
252b5132
RH
13156 idx += ent.vn_next;
13157 }
9cf03b7e 13158
54806181 13159 if (cnt < section->sh_info)
9cf03b7e 13160 warn (_("Missing Version Needs information\n"));
103f02d3 13161
252b5132
RH
13162 free (eneed);
13163 }
13164 break;
13165
13166 case SHT_GNU_versym:
13167 {
2cf0635d 13168 Elf_Internal_Shdr * link_section;
26c527e6 13169 uint64_t total;
8b73c356 13170 unsigned int cnt;
2cf0635d
NC
13171 unsigned char * edata;
13172 unsigned short * data;
13173 char * strtab;
13174 Elf_Internal_Sym * symbols;
13175 Elf_Internal_Shdr * string_sec;
26c527e6
AM
13176 uint64_t num_syms;
13177 uint64_t off;
252b5132 13178
dda8d76d 13179 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13180 break;
13181
dda8d76d 13182 link_section = filedata->section_headers + section->sh_link;
08d8fa11 13183 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 13184
dda8d76d 13185 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13186 break;
13187
015dc7e1 13188 found = true;
252b5132 13189
4de91c10 13190 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
13191 if (symbols == NULL)
13192 break;
252b5132 13193
dda8d76d 13194 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 13195
dda8d76d 13196 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
13197 string_sec->sh_size,
13198 _("version string table"));
a6e9f9df 13199 if (!strtab)
0429c154
MS
13200 {
13201 free (symbols);
13202 break;
13203 }
252b5132 13204
ca0e11aa 13205 if (filedata->is_separate)
26c527e6
AM
13206 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13207 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13208 total),
13209 filedata->file_name,
13210 printable_section_name (filedata, section),
26c527e6 13211 total);
ca0e11aa
NC
13212 else
13213 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 13214 "contains %" PRIu64 " entry:\n",
ca0e11aa 13215 "\nVersion symbols section '%s' "
26c527e6 13216 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13217 total),
13218 printable_section_name (filedata, section),
26c527e6 13219 total);
252b5132 13220
625d49fc 13221 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13222 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13223 section->sh_offset, section->sh_link,
dda8d76d 13224 printable_section_name (filedata, link_section));
252b5132 13225
dda8d76d 13226 off = offset_from_vma (filedata,
978c4450 13227 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 13228 total * sizeof (short));
95099889
AM
13229 edata = (unsigned char *) get_data (NULL, filedata, off,
13230 sizeof (short), total,
13231 _("version symbol data"));
a6e9f9df
AM
13232 if (!edata)
13233 {
13234 free (strtab);
0429c154 13235 free (symbols);
a6e9f9df
AM
13236 break;
13237 }
252b5132 13238
3f5e193b 13239 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
13240
13241 for (cnt = total; cnt --;)
b34976b6
AM
13242 data[cnt] = byte_get (edata + cnt * sizeof (short),
13243 sizeof (short));
252b5132
RH
13244
13245 free (edata);
13246
13247 for (cnt = 0; cnt < total; cnt += 4)
13248 {
13249 int j, nn;
ab273396
AM
13250 char *name;
13251 char *invalid = _("*invalid*");
252b5132
RH
13252
13253 printf (" %03x:", cnt);
13254
13255 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 13256 switch (data[cnt + j])
252b5132
RH
13257 {
13258 case 0:
13259 fputs (_(" 0 (*local*) "), stdout);
13260 break;
13261
13262 case 1:
13263 fputs (_(" 1 (*global*) "), stdout);
13264 break;
13265
13266 default:
c244d050
NC
13267 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13268 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 13269
dd24e3da 13270 /* If this index value is greater than the size of the symbols
ba5cdace 13271 array, break to avoid an out-of-bounds read. */
26c527e6 13272 if (cnt + j >= num_syms)
dd24e3da
NC
13273 {
13274 warn (_("invalid index into symbol array\n"));
13275 break;
13276 }
13277
ab273396 13278 name = NULL;
978c4450 13279 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13280 {
b34976b6 13281 Elf_Internal_Verneed ivn;
26c527e6 13282 uint64_t offset;
252b5132 13283
d93f0186 13284 offset = offset_from_vma
978c4450
AM
13285 (filedata,
13286 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13287 sizeof (Elf_External_Verneed));
252b5132 13288
b34976b6 13289 do
252b5132 13290 {
b34976b6
AM
13291 Elf_Internal_Vernaux ivna;
13292 Elf_External_Verneed evn;
13293 Elf_External_Vernaux evna;
26c527e6 13294 uint64_t a_off;
252b5132 13295
dda8d76d 13296 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13297 _("version need")) == NULL)
13298 break;
0b4362b0 13299
252b5132
RH
13300 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13301 ivn.vn_next = BYTE_GET (evn.vn_next);
13302
13303 a_off = offset + ivn.vn_aux;
13304
13305 do
13306 {
dda8d76d 13307 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13308 1, _("version need aux (2)")) == NULL)
13309 {
13310 ivna.vna_next = 0;
13311 ivna.vna_other = 0;
13312 }
13313 else
13314 {
13315 ivna.vna_next = BYTE_GET (evna.vna_next);
13316 ivna.vna_other = BYTE_GET (evna.vna_other);
13317 }
252b5132
RH
13318
13319 a_off += ivna.vna_next;
13320 }
b34976b6 13321 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13322 && ivna.vna_next != 0);
13323
b34976b6 13324 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13325 {
13326 ivna.vna_name = BYTE_GET (evna.vna_name);
13327
54806181 13328 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13329 name = invalid;
54806181
AM
13330 else
13331 name = strtab + ivna.vna_name;
252b5132
RH
13332 break;
13333 }
13334
13335 offset += ivn.vn_next;
13336 }
13337 while (ivn.vn_next);
13338 }
00d93f34 13339
ab273396 13340 if (data[cnt + j] != 0x8001
978c4450 13341 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13342 {
b34976b6
AM
13343 Elf_Internal_Verdef ivd;
13344 Elf_External_Verdef evd;
26c527e6 13345 uint64_t offset;
252b5132 13346
d93f0186 13347 offset = offset_from_vma
978c4450
AM
13348 (filedata,
13349 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13350 sizeof evd);
252b5132
RH
13351
13352 do
13353 {
dda8d76d 13354 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13355 _("version def")) == NULL)
13356 {
13357 ivd.vd_next = 0;
948f632f 13358 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13359 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13360 break;
59245841
NC
13361 }
13362 else
13363 {
13364 ivd.vd_next = BYTE_GET (evd.vd_next);
13365 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13366 }
252b5132
RH
13367
13368 offset += ivd.vd_next;
13369 }
c244d050 13370 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13371 && ivd.vd_next != 0);
13372
c244d050 13373 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13374 {
b34976b6
AM
13375 Elf_External_Verdaux evda;
13376 Elf_Internal_Verdaux ivda;
252b5132
RH
13377
13378 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13379
dda8d76d 13380 if (get_data (&evda, filedata,
59245841
NC
13381 offset - ivd.vd_next + ivd.vd_aux,
13382 sizeof (evda), 1,
13383 _("version def aux")) == NULL)
13384 break;
252b5132
RH
13385
13386 ivda.vda_name = BYTE_GET (evda.vda_name);
13387
54806181 13388 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13389 name = invalid;
13390 else if (name != NULL && name != invalid)
13391 name = _("*both*");
54806181
AM
13392 else
13393 name = strtab + ivda.vda_name;
252b5132
RH
13394 }
13395 }
ab273396
AM
13396 if (name != NULL)
13397 nn += printf ("(%s%-*s",
13398 name,
13399 12 - (int) strlen (name),
13400 ")");
252b5132
RH
13401
13402 if (nn < 18)
13403 printf ("%*c", 18 - nn, ' ');
13404 }
13405
13406 putchar ('\n');
13407 }
13408
13409 free (data);
13410 free (strtab);
13411 free (symbols);
13412 }
13413 break;
103f02d3 13414
252b5132
RH
13415 default:
13416 break;
13417 }
13418 }
13419
13420 if (! found)
ca0e11aa
NC
13421 {
13422 if (filedata->is_separate)
13423 printf (_("\nNo version information found in linked file '%s'.\n"),
13424 filedata->file_name);
13425 else
13426 printf (_("\nNo version information found in this file.\n"));
13427 }
252b5132 13428
015dc7e1 13429 return true;
252b5132
RH
13430}
13431
d1133906 13432static const char *
dda8d76d 13433get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13434{
89246a0e 13435 static char buff[64];
252b5132
RH
13436
13437 switch (binding)
13438 {
b34976b6
AM
13439 case STB_LOCAL: return "LOCAL";
13440 case STB_GLOBAL: return "GLOBAL";
13441 case STB_WEAK: return "WEAK";
252b5132
RH
13442 default:
13443 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13444 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13445 binding);
252b5132 13446 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13447 {
13448 if (binding == STB_GNU_UNIQUE
df3a023b 13449 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13450 return "UNIQUE";
13451 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13452 }
252b5132 13453 else
e9e44622 13454 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13455 return buff;
13456 }
13457}
13458
d1133906 13459static const char *
dda8d76d 13460get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13461{
89246a0e 13462 static char buff[64];
252b5132
RH
13463
13464 switch (type)
13465 {
b34976b6
AM
13466 case STT_NOTYPE: return "NOTYPE";
13467 case STT_OBJECT: return "OBJECT";
13468 case STT_FUNC: return "FUNC";
13469 case STT_SECTION: return "SECTION";
13470 case STT_FILE: return "FILE";
13471 case STT_COMMON: return "COMMON";
13472 case STT_TLS: return "TLS";
15ab5209
DB
13473 case STT_RELC: return "RELC";
13474 case STT_SRELC: return "SRELC";
252b5132
RH
13475 default:
13476 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13477 {
dda8d76d 13478 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13479 return "THUMB_FUNC";
103f02d3 13480
dda8d76d 13481 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13482 return "REGISTER";
13483
dda8d76d 13484 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13485 return "PARISC_MILLI";
13486
e9e44622 13487 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13488 }
252b5132 13489 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13490 {
dda8d76d 13491 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13492 {
13493 if (type == STT_HP_OPAQUE)
13494 return "HP_OPAQUE";
13495 if (type == STT_HP_STUB)
13496 return "HP_STUB";
13497 }
13498
8654c01f
ML
13499 if (type == STT_GNU_IFUNC
13500 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13501 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13502 return "IFUNC";
13503
e9e44622 13504 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13505 }
252b5132 13506 else
e9e44622 13507 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13508 return buff;
13509 }
13510}
13511
d1133906 13512static const char *
d3ba0551 13513get_symbol_visibility (unsigned int visibility)
d1133906
NC
13514{
13515 switch (visibility)
13516 {
b34976b6
AM
13517 case STV_DEFAULT: return "DEFAULT";
13518 case STV_INTERNAL: return "INTERNAL";
13519 case STV_HIDDEN: return "HIDDEN";
d1133906 13520 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13521 default:
27a45f42 13522 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13523 return _("<unknown>");
d1133906
NC
13524 }
13525}
13526
2057d69d
CZ
13527static const char *
13528get_alpha_symbol_other (unsigned int other)
9abca702 13529{
2057d69d
CZ
13530 switch (other)
13531 {
13532 case STO_ALPHA_NOPV: return "NOPV";
13533 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13534 default:
27a45f42 13535 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13536 return _("<unknown>");
9abca702 13537 }
2057d69d
CZ
13538}
13539
fd85a6a1
NC
13540static const char *
13541get_solaris_symbol_visibility (unsigned int visibility)
13542{
13543 switch (visibility)
13544 {
13545 case 4: return "EXPORTED";
13546 case 5: return "SINGLETON";
13547 case 6: return "ELIMINATE";
13548 default: return get_symbol_visibility (visibility);
13549 }
13550}
13551
2301ed1c
SN
13552static const char *
13553get_aarch64_symbol_other (unsigned int other)
13554{
13555 static char buf[32];
13556
13557 if (other & STO_AARCH64_VARIANT_PCS)
13558 {
13559 other &= ~STO_AARCH64_VARIANT_PCS;
13560 if (other == 0)
13561 return "VARIANT_PCS";
13562 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13563 return buf;
13564 }
13565 return NULL;
13566}
13567
5e2b0d47
NC
13568static const char *
13569get_mips_symbol_other (unsigned int other)
13570{
13571 switch (other)
13572 {
32ec8896
NC
13573 case STO_OPTIONAL: return "OPTIONAL";
13574 case STO_MIPS_PLT: return "MIPS PLT";
13575 case STO_MIPS_PIC: return "MIPS PIC";
13576 case STO_MICROMIPS: return "MICROMIPS";
13577 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13578 case STO_MIPS16: return "MIPS16";
13579 default: return NULL;
5e2b0d47
NC
13580 }
13581}
13582
28f997cf 13583static const char *
dda8d76d 13584get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13585{
dda8d76d 13586 if (is_ia64_vms (filedata))
28f997cf
TG
13587 {
13588 static char res[32];
13589
13590 res[0] = 0;
13591
13592 /* Function types is for images and .STB files only. */
dda8d76d 13593 switch (filedata->file_header.e_type)
28f997cf
TG
13594 {
13595 case ET_DYN:
13596 case ET_EXEC:
13597 switch (VMS_ST_FUNC_TYPE (other))
13598 {
13599 case VMS_SFT_CODE_ADDR:
13600 strcat (res, " CA");
13601 break;
13602 case VMS_SFT_SYMV_IDX:
13603 strcat (res, " VEC");
13604 break;
13605 case VMS_SFT_FD:
13606 strcat (res, " FD");
13607 break;
13608 case VMS_SFT_RESERVE:
13609 strcat (res, " RSV");
13610 break;
13611 default:
bee0ee85
NC
13612 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13613 VMS_ST_FUNC_TYPE (other));
13614 strcat (res, " <unknown>");
13615 break;
28f997cf
TG
13616 }
13617 break;
13618 default:
13619 break;
13620 }
13621 switch (VMS_ST_LINKAGE (other))
13622 {
13623 case VMS_STL_IGNORE:
13624 strcat (res, " IGN");
13625 break;
13626 case VMS_STL_RESERVE:
13627 strcat (res, " RSV");
13628 break;
13629 case VMS_STL_STD:
13630 strcat (res, " STD");
13631 break;
13632 case VMS_STL_LNK:
13633 strcat (res, " LNK");
13634 break;
13635 default:
bee0ee85
NC
13636 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13637 VMS_ST_LINKAGE (other));
13638 strcat (res, " <unknown>");
13639 break;
28f997cf
TG
13640 }
13641
13642 if (res[0] != 0)
13643 return res + 1;
13644 else
13645 return res;
13646 }
13647 return NULL;
13648}
13649
6911b7dc
AM
13650static const char *
13651get_ppc64_symbol_other (unsigned int other)
13652{
14732552
AM
13653 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13654 return NULL;
13655
13656 other >>= STO_PPC64_LOCAL_BIT;
13657 if (other <= 6)
6911b7dc 13658 {
89246a0e 13659 static char buf[64];
14732552
AM
13660 if (other >= 2)
13661 other = ppc64_decode_local_entry (other);
13662 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13663 return buf;
13664 }
13665 return NULL;
13666}
13667
8155b853
NC
13668static const char *
13669get_riscv_symbol_other (unsigned int other)
13670{
13671 static char buf[32];
13672 buf[0] = 0;
13673
13674 if (other & STO_RISCV_VARIANT_CC)
13675 {
13676 strcat (buf, _(" VARIANT_CC"));
13677 other &= ~STO_RISCV_VARIANT_CC;
13678 }
13679
13680 if (other != 0)
13681 snprintf (buf, sizeof buf, " %x", other);
13682
13683
13684 if (buf[0] != 0)
13685 return buf + 1;
13686 else
13687 return buf;
13688}
13689
5e2b0d47 13690static const char *
dda8d76d 13691get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13692{
13693 const char * result = NULL;
89246a0e 13694 static char buff [64];
5e2b0d47
NC
13695
13696 if (other == 0)
13697 return "";
13698
dda8d76d 13699 switch (filedata->file_header.e_machine)
5e2b0d47 13700 {
2057d69d
CZ
13701 case EM_ALPHA:
13702 result = get_alpha_symbol_other (other);
13703 break;
2301ed1c
SN
13704 case EM_AARCH64:
13705 result = get_aarch64_symbol_other (other);
13706 break;
5e2b0d47
NC
13707 case EM_MIPS:
13708 result = get_mips_symbol_other (other);
28f997cf
TG
13709 break;
13710 case EM_IA_64:
dda8d76d 13711 result = get_ia64_symbol_other (filedata, other);
28f997cf 13712 break;
6911b7dc
AM
13713 case EM_PPC64:
13714 result = get_ppc64_symbol_other (other);
13715 break;
8155b853
NC
13716 case EM_RISCV:
13717 result = get_riscv_symbol_other (other);
13718 break;
5e2b0d47 13719 default:
fd85a6a1 13720 result = NULL;
5e2b0d47
NC
13721 break;
13722 }
13723
13724 if (result)
13725 return result;
13726
13727 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13728 return buff;
13729}
13730
bb4d2ac2 13731static const char *
26c527e6
AM
13732get_symbol_version_string (Filedata *filedata,
13733 bool is_dynsym,
13734 const char *strtab,
13735 size_t strtab_size,
13736 unsigned int si,
13737 Elf_Internal_Sym *psym,
13738 enum versioned_symbol_info *sym_info,
13739 unsigned short *vna_other)
bb4d2ac2 13740{
ab273396
AM
13741 unsigned char data[2];
13742 unsigned short vers_data;
26c527e6 13743 uint64_t offset;
7a815dd5 13744 unsigned short max_vd_ndx;
bb4d2ac2 13745
ab273396 13746 if (!is_dynsym
978c4450 13747 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13748 return NULL;
bb4d2ac2 13749
978c4450
AM
13750 offset = offset_from_vma (filedata,
13751 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13752 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13753
dda8d76d 13754 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13755 sizeof (data), 1, _("version data")) == NULL)
13756 return NULL;
13757
13758 vers_data = byte_get (data, 2);
bb4d2ac2 13759
1f6f5dba 13760 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13761 return NULL;
bb4d2ac2 13762
0b8b7609 13763 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13764 max_vd_ndx = 0;
13765
ab273396
AM
13766 /* Usually we'd only see verdef for defined symbols, and verneed for
13767 undefined symbols. However, symbols defined by the linker in
13768 .dynbss for variables copied from a shared library in order to
13769 avoid text relocations are defined yet have verneed. We could
13770 use a heuristic to detect the special case, for example, check
13771 for verneed first on symbols defined in SHT_NOBITS sections, but
13772 it is simpler and more reliable to just look for both verdef and
13773 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13774
ab273396
AM
13775 if (psym->st_shndx != SHN_UNDEF
13776 && vers_data != 0x8001
978c4450 13777 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13778 {
13779 Elf_Internal_Verdef ivd;
13780 Elf_Internal_Verdaux ivda;
13781 Elf_External_Verdaux evda;
26c527e6 13782 uint64_t off;
bb4d2ac2 13783
dda8d76d 13784 off = offset_from_vma (filedata,
978c4450 13785 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13786 sizeof (Elf_External_Verdef));
13787
13788 do
bb4d2ac2 13789 {
ab273396
AM
13790 Elf_External_Verdef evd;
13791
dda8d76d 13792 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13793 _("version def")) == NULL)
13794 {
13795 ivd.vd_ndx = 0;
13796 ivd.vd_aux = 0;
13797 ivd.vd_next = 0;
1f6f5dba 13798 ivd.vd_flags = 0;
ab273396
AM
13799 }
13800 else
bb4d2ac2 13801 {
ab273396
AM
13802 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13803 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13804 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13805 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13806 }
bb4d2ac2 13807
7a815dd5
L
13808 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13809 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13810
ab273396
AM
13811 off += ivd.vd_next;
13812 }
13813 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13814
ab273396
AM
13815 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13816 {
9abca702 13817 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13818 return NULL;
13819
ab273396
AM
13820 off -= ivd.vd_next;
13821 off += ivd.vd_aux;
bb4d2ac2 13822
dda8d76d 13823 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13824 _("version def aux")) != NULL)
13825 {
13826 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13827
ab273396 13828 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13829 return (ivda.vda_name < strtab_size
13830 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13831 }
13832 }
13833 }
bb4d2ac2 13834
978c4450 13835 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13836 {
13837 Elf_External_Verneed evn;
13838 Elf_Internal_Verneed ivn;
13839 Elf_Internal_Vernaux ivna;
bb4d2ac2 13840
dda8d76d 13841 offset = offset_from_vma (filedata,
978c4450 13842 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13843 sizeof evn);
13844 do
13845 {
26c527e6 13846 uint64_t vna_off;
bb4d2ac2 13847
dda8d76d 13848 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13849 _("version need")) == NULL)
13850 {
13851 ivna.vna_next = 0;
13852 ivna.vna_other = 0;
13853 ivna.vna_name = 0;
13854 break;
13855 }
bb4d2ac2 13856
ab273396
AM
13857 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13858 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13859
ab273396 13860 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13861
ab273396
AM
13862 do
13863 {
13864 Elf_External_Vernaux evna;
bb4d2ac2 13865
dda8d76d 13866 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13867 _("version need aux (3)")) == NULL)
bb4d2ac2 13868 {
ab273396
AM
13869 ivna.vna_next = 0;
13870 ivna.vna_other = 0;
13871 ivna.vna_name = 0;
bb4d2ac2 13872 }
bb4d2ac2 13873 else
bb4d2ac2 13874 {
ab273396
AM
13875 ivna.vna_other = BYTE_GET (evna.vna_other);
13876 ivna.vna_next = BYTE_GET (evna.vna_next);
13877 ivna.vna_name = BYTE_GET (evna.vna_name);
13878 }
bb4d2ac2 13879
ab273396
AM
13880 vna_off += ivna.vna_next;
13881 }
13882 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13883
ab273396
AM
13884 if (ivna.vna_other == vers_data)
13885 break;
bb4d2ac2 13886
ab273396
AM
13887 offset += ivn.vn_next;
13888 }
13889 while (ivn.vn_next != 0);
bb4d2ac2 13890
ab273396
AM
13891 if (ivna.vna_other == vers_data)
13892 {
13893 *sym_info = symbol_undefined;
13894 *vna_other = ivna.vna_other;
13895 return (ivna.vna_name < strtab_size
13896 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13897 }
7a815dd5
L
13898 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13899 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13900 return _("<corrupt>");
bb4d2ac2 13901 }
ab273396 13902 return NULL;
bb4d2ac2
L
13903}
13904
047c3dbf
NL
13905/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13906
13907static unsigned int
b6ac461a 13908print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13909{
13910 switch (base)
13911 {
13912 case 8:
13913 return print_vma (vma, OCTAL_5);
13914
13915 case 10:
13916 return print_vma (vma, UNSIGNED_5);
13917
13918 case 16:
13919 return print_vma (vma, PREFIX_HEX_5);
13920
13921 case 0:
13922 default:
13923 return print_vma (vma, DEC_5);
13924 }
13925}
13926
b6ac461a
NC
13927/* Print information on a single symbol. */
13928
10ca4b04 13929static void
b6ac461a
NC
13930print_symbol (Filedata * filedata,
13931 uint64_t symbol_index,
13932 Elf_Internal_Sym * symtab,
13933 Elf_Internal_Shdr * section,
13934 char * strtab,
13935 size_t strtab_size)
252b5132 13936{
10ca4b04
L
13937 const char *version_string;
13938 enum versioned_symbol_info sym_info;
13939 unsigned short vna_other;
23356397 13940 const char * sstr;
b6ac461a 13941 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13942
b6ac461a
NC
13943 /* FIXME: We should have a table of field widths,
13944 rather than using hard coded constants. */
13945 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13946 print_vma (psym->st_value, LONG_HEX);
13947 putchar (' ');
b6ac461a 13948 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13949 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13950 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13951 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13952 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13953 else
252b5132 13954 {
10ca4b04 13955 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13956
10ca4b04 13957 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13958
10ca4b04 13959 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13960 FIXME: Displaying this information here disrupts the layout
13961 of the table being generated. */
10ca4b04
L
13962 if (psym->st_other ^ vis)
13963 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13964 }
0942c7ab 13965
b6ac461a
NC
13966 bool is_special;
13967
13968 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13969
13970 /* Print the symbol's section index. If the index is special
13971 then print the index's name rather than its number. */
13972 if (is_special)
13973 {
13974 int printed;
13975
13976 /* Special case: If there are no section headers, and the printable
13977 name is "<section 0x...." then just display the section number
13978 as a decimal. This happens when objcopy --strip -section-headers
13979 is used. */
13980 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13981 printed = printf (" %4d ", psym->st_shndx);
13982 else
13983 printed = printf (" %4s ", sstr);
13984
13985 if (extra_sym_info && printed < 16)
13986 printf ("%*s", 16 - printed, "");
13987 }
13988 else
13989 {
13990 printf (" %4u ", psym->st_shndx);
13991
13992 if (extra_sym_info)
13993 {
13994 /* Display the section name referenced by the section index. */
13995 int printed = printf ("(%s) ", sstr);
13996 if (printed < 10)
13997 printf ("%*s", 10 - printed, "");
13998 }
13999 }
14000
14001 /* Get the symbol's name. For section symbols without a
14002 specific name use the (already computed) section name. */
23356397 14003 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 14004 && section_index_real (filedata, psym->st_shndx)
23356397
NC
14005 && psym->st_name == 0)
14006 {
b6ac461a 14007 ;
23356397
NC
14008 }
14009 else
14010 {
b6ac461a
NC
14011 bool is_valid;
14012
84714f86 14013 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
14014 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14015 }
10ca4b04
L
14016
14017 version_string
14018 = get_symbol_version_string (filedata,
14019 (section == NULL
14020 || section->sh_type == SHT_DYNSYM),
b6ac461a 14021 strtab, strtab_size, symbol_index,
10ca4b04 14022 psym, &sym_info, &vna_other);
b9e920ec 14023
0942c7ab
NC
14024 int len_avail = 21;
14025 if (! do_wide && version_string != NULL)
14026 {
ddb43bab 14027 char buffer[16];
0942c7ab 14028
ddb43bab 14029 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
14030
14031 if (sym_info == symbol_undefined)
14032 len_avail -= sprintf (buffer," (%d)", vna_other);
14033 else if (sym_info != symbol_hidden)
14034 len_avail -= 1;
14035 }
14036
b6ac461a 14037 print_symbol_name (len_avail, sstr);
b9e920ec 14038
10ca4b04
L
14039 if (version_string)
14040 {
14041 if (sym_info == symbol_undefined)
14042 printf ("@%s (%d)", version_string, vna_other);
f7a99963 14043 else
10ca4b04
L
14044 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14045 version_string);
14046 }
6bd1a22c 14047
10ca4b04 14048 putchar ('\n');
6bd1a22c 14049
10ca4b04
L
14050 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14051 && section != NULL
b6ac461a 14052 && symbol_index >= section->sh_info
10ca4b04
L
14053 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14054 && filedata->file_header.e_machine != EM_MIPS
14055 /* Solaris binaries have been found to violate this requirement as
14056 well. Not sure if this is a bug or an ABI requirement. */
14057 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 14058 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 14059 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 14060}
f16a9783 14061
0f03783c
NC
14062static const char *
14063get_lto_kind (unsigned int kind)
14064{
14065 switch (kind)
14066 {
14067 case 0: return "DEF";
14068 case 1: return "WEAKDEF";
14069 case 2: return "UNDEF";
14070 case 3: return "WEAKUNDEF";
14071 case 4: return "COMMON";
14072 default:
14073 break;
14074 }
14075
14076 static char buffer[30];
14077 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14078 sprintf (buffer, "<unknown: %u>", kind);
14079 return buffer;
14080}
14081
14082static const char *
14083get_lto_visibility (unsigned int visibility)
14084{
14085 switch (visibility)
14086 {
14087 case 0: return "DEFAULT";
14088 case 1: return "PROTECTED";
14089 case 2: return "INTERNAL";
14090 case 3: return "HIDDEN";
14091 default:
14092 break;
14093 }
14094
14095 static char buffer[30];
14096 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14097 sprintf (buffer, "<unknown: %u>", visibility);
14098 return buffer;
14099}
14100
14101static const char *
14102get_lto_sym_type (unsigned int sym_type)
14103{
14104 switch (sym_type)
14105 {
14106 case 0: return "UNKNOWN";
14107 case 1: return "FUNCTION";
14108 case 2: return "VARIABLE";
14109 default:
14110 break;
14111 }
14112
14113 static char buffer[30];
14114 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14115 sprintf (buffer, "<unknown: %u>", sym_type);
14116 return buffer;
14117}
14118
14119/* Display an LTO format symbol table.
14120 FIXME: The format of LTO symbol tables is not formalized.
14121 So this code could need changing in the future. */
14122
015dc7e1 14123static bool
0f03783c
NC
14124display_lto_symtab (Filedata * filedata,
14125 Elf_Internal_Shdr * section)
14126{
14127 if (section->sh_size == 0)
14128 {
ca0e11aa
NC
14129 if (filedata->is_separate)
14130 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14131 printable_section_name (filedata, section),
14132 filedata->file_name);
14133 else
14134 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14135 printable_section_name (filedata, section));
047c3dbf 14136
015dc7e1 14137 return true;
0f03783c
NC
14138 }
14139
14140 if (section->sh_size > filedata->file_size)
14141 {
26c527e6 14142 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 14143 printable_section_name (filedata, section),
26c527e6 14144 section->sh_size);
015dc7e1 14145 return false;
0f03783c
NC
14146 }
14147
14148 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14149 section->sh_size, 1, _("LTO symbols"));
14150 if (alloced_data == NULL)
015dc7e1 14151 return false;
0f03783c
NC
14152
14153 /* Look for extended data for the symbol table. */
765a0c0a 14154 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
14155 void * ext_data_orig = NULL;
14156 char * ext_data = NULL;
14157 char * ext_data_end = NULL;
14158 char * ext_name = NULL;
14159
14160 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
14161 (section_name (filedata, section)
14162 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
14163 && ext_name != NULL /* Paranoia. */
14164 && (ext = find_section (filedata, ext_name)) != NULL)
14165 {
14166 if (ext->sh_size < 3)
14167 error (_("LTO Symbol extension table '%s' is empty!\n"),
14168 printable_section_name (filedata, ext));
14169 else
14170 {
14171 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14172 ext->sh_size, 1,
14173 _("LTO ext symbol data"));
14174 if (ext_data != NULL)
14175 {
14176 ext_data_end = ext_data + ext->sh_size;
14177 if (* ext_data++ != 1)
14178 error (_("Unexpected version number in symbol extension table\n"));
14179 }
14180 }
14181 }
b9e920ec 14182
0f03783c
NC
14183 const unsigned char * data = (const unsigned char *) alloced_data;
14184 const unsigned char * end = data + section->sh_size;
14185
ca0e11aa
NC
14186 if (filedata->is_separate)
14187 printf (_("\nIn linked file '%s': "), filedata->file_name);
14188 else
14189 printf ("\n");
14190
0f03783c
NC
14191 if (ext_data_orig != NULL)
14192 {
14193 if (do_wide)
ca0e11aa 14194 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
14195 printable_section_name (filedata, section),
14196 printable_section_name (filedata, ext));
14197 else
14198 {
ca0e11aa 14199 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
14200 printable_section_name (filedata, section));
14201 printf (_(" and extension table '%s' contain:\n"),
14202 printable_section_name (filedata, ext));
14203 }
14204 }
14205 else
ca0e11aa 14206 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 14207 printable_section_name (filedata, section));
b9e920ec 14208
0f03783c 14209 /* FIXME: Add a wide version. */
b9e920ec 14210 if (ext_data_orig != NULL)
0f03783c
NC
14211 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14212 else
14213 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14214
14215 /* FIXME: We do not handle style prefixes. */
14216
14217 while (data < end)
14218 {
14219 const unsigned char * sym_name = data;
14220 data += strnlen ((const char *) sym_name, end - data) + 1;
14221 if (data >= end)
14222 goto fail;
14223
14224 const unsigned char * comdat_key = data;
14225 data += strnlen ((const char *) comdat_key, end - data) + 1;
14226 if (data >= end)
14227 goto fail;
14228
14229 if (data + 2 + 8 + 4 > end)
14230 goto fail;
14231
14232 unsigned int kind = *data++;
14233 unsigned int visibility = *data++;
14234
928c411d 14235 uint64_t size = byte_get (data, 8);
0f03783c
NC
14236 data += 8;
14237
928c411d 14238 uint64_t slot = byte_get (data, 4);
0f03783c
NC
14239 data += 4;
14240
14241 if (ext_data != NULL)
14242 {
14243 if (ext_data < (ext_data_end - 1))
14244 {
14245 unsigned int sym_type = * ext_data ++;
14246 unsigned int sec_kind = * ext_data ++;
14247
31e5a3a3 14248 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
14249 * comdat_key == 0 ? "-" : (char *) comdat_key,
14250 get_lto_kind (kind),
14251 get_lto_visibility (visibility),
31e5a3a3
AM
14252 size,
14253 slot,
0f03783c 14254 get_lto_sym_type (sym_type),
31e5a3a3 14255 sec_kind);
b6ac461a 14256 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
14257 }
14258 else
14259 {
14260 error (_("Ran out of LTO symbol extension data\n"));
14261 ext_data = NULL;
14262 /* FIXME: return FAIL result ? */
14263 }
14264 }
14265 else
14266 {
31e5a3a3 14267 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
14268 * comdat_key == 0 ? "-" : (char *) comdat_key,
14269 get_lto_kind (kind),
14270 get_lto_visibility (visibility),
31e5a3a3
AM
14271 size,
14272 slot);
b6ac461a 14273 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
14274 }
14275 putchar ('\n');
14276 }
14277
14278 if (ext_data != NULL && ext_data < ext_data_end)
14279 {
14280 error (_("Data remains in the LTO symbol extension table\n"));
14281 goto fail;
14282 }
14283
14284 free (alloced_data);
14285 free (ext_data_orig);
14286 free (ext_name);
015dc7e1 14287 return true;
b9e920ec 14288
0f03783c
NC
14289 fail:
14290 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14291 free (alloced_data);
14292 free (ext_data_orig);
14293 free (ext_name);
015dc7e1 14294 return false;
0f03783c
NC
14295}
14296
14297/* Display LTO symbol tables. */
14298
015dc7e1 14299static bool
0f03783c
NC
14300process_lto_symbol_tables (Filedata * filedata)
14301{
14302 Elf_Internal_Shdr * section;
14303 unsigned int i;
015dc7e1 14304 bool res = true;
0f03783c
NC
14305
14306 if (!do_lto_syms)
015dc7e1 14307 return true;
0f03783c
NC
14308
14309 if (filedata->section_headers == NULL)
015dc7e1 14310 return true;
0f03783c
NC
14311
14312 for (i = 0, section = filedata->section_headers;
14313 i < filedata->file_header.e_shnum;
14314 i++, section++)
84714f86
AM
14315 if (section_name_valid (filedata, section)
14316 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14317 res &= display_lto_symtab (filedata, section);
14318
b9e920ec 14319 return res;
0f03783c
NC
14320}
14321
b6ac461a
NC
14322static void
14323print_symbol_table_heading (void)
14324{
14325 /* FIXME: We should store the size of each field in the display in a table and
14326 then use the values inside print_symbol(), instead of that function using
14327 hard coded constants. */
14328 if (is_32bit_elf)
14329 {
14330 if (extra_sym_info)
14331 {
14332 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14333 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14334 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14335 }
14336 else if (do_wide)
14337 {
14338 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14339 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14340 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14341 }
14342 else
14343 {
14344 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14345 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14346 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14347 }
14348 }
14349 else
14350 {
14351 if (extra_sym_info)
14352 {
14353 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14354 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14355 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14356
14357 }
14358 else if (do_wide)
14359 {
14360 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14361 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14362 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14363 }
14364 else
14365 {
14366 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14367 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14368 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14369 }
14370 }
14371}
14372
8e8d0b63
NC
14373static bool
14374dump_symbol_section (Elf_Internal_Shdr * section,
14375 Filedata * filedata)
14376{
14377 if (section->sh_entsize == 0)
14378 {
14379 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14380 printable_section_name (filedata, section));
14381 return false;
14382 }
14383
14384 uint64_t num_syms = section->sh_size / section->sh_entsize;
14385
14386 if (filedata->is_separate)
14387 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14388 " contains %" PRIu64 " entry:\n",
14389 "\nIn linked file '%s' symbol section '%s'"
14390 " contains %" PRIu64 " entries:\n",
14391 num_syms),
14392 filedata->file_name,
14393 printable_section_name (filedata, section),
14394 num_syms);
14395 else
14396 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14397 " entry:\n",
14398 "\nSymbol table '%s' contains %" PRIu64
14399 " entries:\n",
14400 num_syms),
14401 printable_section_name (filedata, section),
14402 num_syms);
14403
14404 print_symbol_table_heading ();
14405
14406 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14407 if (symtab == NULL)
14408 /* An error message will have already been displayed. */
14409 return false;
14410
14411 char * strtab = NULL;
14412 uint64_t strtab_size = 0;
14413
14414 if (section->sh_link == filedata->file_header.e_shstrndx)
14415 {
14416 strtab = filedata->string_table;
14417 strtab_size = filedata->string_table_length;
14418 }
14419 else if (section->sh_link < filedata->file_header.e_shnum)
14420 {
14421 Elf_Internal_Shdr * string_sec;
14422
14423 string_sec = filedata->section_headers + section->sh_link;
14424
14425 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14426 1, string_sec->sh_size,
14427 _("string table"));
14428 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14429 }
14430
14431 uint64_t si;
14432
14433 for (si = 0; si < num_syms; si++)
14434 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14435
14436 free (symtab);
14437
14438 if (strtab != filedata->string_table)
14439 free (strtab);
14440
14441 return true;
14442}
14443
10ca4b04 14444/* Dump the symbol table. */
0f03783c 14445
015dc7e1 14446static bool
10ca4b04
L
14447process_symbol_table (Filedata * filedata)
14448{
14449 Elf_Internal_Shdr * section;
f16a9783 14450
10ca4b04 14451 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14452 return true;
6bd1a22c 14453
978c4450 14454 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14455 && do_syms
14456 && do_using_dynamic
978c4450
AM
14457 && filedata->dynamic_strings != NULL
14458 && filedata->dynamic_symbols != NULL)
6bd1a22c 14459 {
26c527e6 14460 uint64_t si;
6bd1a22c 14461
ca0e11aa
NC
14462 if (filedata->is_separate)
14463 {
26c527e6
AM
14464 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14465 " contains %" PRIu64 " entry:\n",
14466 "\nIn linked file '%s' the dynamic symbol table"
14467 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14468 filedata->num_dynamic_syms),
14469 filedata->file_name,
14470 filedata->num_dynamic_syms);
14471 }
14472 else
14473 {
26c527e6
AM
14474 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14475 " entry:\n",
14476 "\nSymbol table for image contains %" PRIu64
14477 " entries:\n",
ca0e11aa
NC
14478 filedata->num_dynamic_syms),
14479 filedata->num_dynamic_syms);
14480 }
b6ac461a
NC
14481
14482 print_symbol_table_heading ();
6bd1a22c 14483
978c4450 14484 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14485 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14486 filedata->dynamic_strings,
14487 filedata->dynamic_strings_length);
252b5132 14488 }
8b73c356 14489 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14490 && filedata->section_headers != NULL)
252b5132 14491 {
b34976b6 14492 unsigned int i;
252b5132 14493
dda8d76d
NC
14494 for (i = 0, section = filedata->section_headers;
14495 i < filedata->file_header.e_shnum;
252b5132
RH
14496 i++, section++)
14497 {
2c610e4b
L
14498 if ((section->sh_type != SHT_SYMTAB
14499 && section->sh_type != SHT_DYNSYM)
14500 || (!do_syms
14501 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14502 continue;
14503
8e8d0b63 14504 dump_symbol_section (section, filedata);
252b5132
RH
14505 }
14506 }
14507 else if (do_syms)
14508 printf
14509 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14510
978c4450 14511 if (do_histogram && filedata->buckets != NULL)
252b5132 14512 {
26c527e6
AM
14513 uint64_t *lengths;
14514 uint64_t *counts;
14515 uint64_t hn;
625d49fc 14516 uint64_t si;
26c527e6
AM
14517 uint64_t maxlength = 0;
14518 uint64_t nzero_counts = 0;
14519 uint64_t nsyms = 0;
6bd6a03d 14520 char *visited;
252b5132 14521
d3a49aa8 14522 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14523 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14524 "\nHistogram for bucket list length "
26c527e6
AM
14525 "(total of %" PRIu64 " buckets):\n",
14526 filedata->nbuckets),
14527 filedata->nbuckets);
252b5132 14528
26c527e6 14529 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14530 if (lengths == NULL)
14531 {
8b73c356 14532 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14533 goto err_out;
252b5132 14534 }
978c4450
AM
14535 visited = xcmalloc (filedata->nchains, 1);
14536 memset (visited, 0, filedata->nchains);
8b73c356
NC
14537
14538 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14539 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14540 {
978c4450 14541 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14542 {
b34976b6 14543 ++nsyms;
252b5132 14544 if (maxlength < ++lengths[hn])
b34976b6 14545 ++maxlength;
978c4450 14546 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14547 {
14548 error (_("histogram chain is corrupt\n"));
14549 break;
14550 }
14551 visited[si] = 1;
252b5132
RH
14552 }
14553 }
6bd6a03d 14554 free (visited);
252b5132 14555
26c527e6 14556 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14557 if (counts == NULL)
14558 {
b2e951ec 14559 free (lengths);
8b73c356 14560 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14561 goto err_out;
252b5132
RH
14562 }
14563
978c4450 14564 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14565 ++counts[lengths[hn]];
252b5132 14566
978c4450 14567 if (filedata->nbuckets > 0)
252b5132 14568 {
26c527e6
AM
14569 uint64_t i;
14570 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14571 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14572 for (i = 1; i <= maxlength; ++i)
103f02d3 14573 {
66543521 14574 nzero_counts += counts[i] * i;
26c527e6 14575 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14576 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14577 (nzero_counts * 100.0) / nsyms);
14578 }
252b5132
RH
14579 }
14580
14581 free (counts);
14582 free (lengths);
14583 }
14584
978c4450
AM
14585 free (filedata->buckets);
14586 filedata->buckets = NULL;
14587 filedata->nbuckets = 0;
14588 free (filedata->chains);
14589 filedata->chains = NULL;
252b5132 14590
978c4450 14591 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14592 {
26c527e6
AM
14593 uint64_t *lengths;
14594 uint64_t *counts;
14595 uint64_t hn;
14596 uint64_t maxlength = 0;
14597 uint64_t nzero_counts = 0;
14598 uint64_t nsyms = 0;
fdc90cb4 14599
f16a9783 14600 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14601 "(total of %" PRIu64 " bucket):\n",
f16a9783 14602 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14603 "(total of %" PRIu64 " buckets):\n",
14604 filedata->ngnubuckets),
978c4450 14605 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14606 filedata->ngnubuckets);
8b73c356 14607
26c527e6 14608 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14609 if (lengths == NULL)
14610 {
8b73c356 14611 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14612 goto err_out;
fdc90cb4
JJ
14613 }
14614
fdc90cb4
JJ
14615 printf (_(" Length Number %% of total Coverage\n"));
14616
978c4450
AM
14617 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14618 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14619 {
625d49fc 14620 uint64_t off, length = 1;
fdc90cb4 14621
978c4450 14622 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14623 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14624 off < filedata->ngnuchains
14625 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14626 ++off)
fdc90cb4
JJ
14627 ++length;
14628 lengths[hn] = length;
14629 if (length > maxlength)
14630 maxlength = length;
14631 nsyms += length;
14632 }
14633
26c527e6 14634 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14635 if (counts == NULL)
14636 {
b2e951ec 14637 free (lengths);
8b73c356 14638 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14639 goto err_out;
fdc90cb4
JJ
14640 }
14641
978c4450 14642 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14643 ++counts[lengths[hn]];
14644
978c4450 14645 if (filedata->ngnubuckets > 0)
fdc90cb4 14646 {
26c527e6
AM
14647 uint64_t j;
14648 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14649 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14650 for (j = 1; j <= maxlength; ++j)
14651 {
14652 nzero_counts += counts[j] * j;
26c527e6 14653 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14654 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14655 (nzero_counts * 100.0) / nsyms);
14656 }
14657 }
14658
14659 free (counts);
14660 free (lengths);
fdc90cb4 14661 }
978c4450
AM
14662 free (filedata->gnubuckets);
14663 filedata->gnubuckets = NULL;
14664 filedata->ngnubuckets = 0;
14665 free (filedata->gnuchains);
14666 filedata->gnuchains = NULL;
14667 filedata->ngnuchains = 0;
14668 free (filedata->mipsxlat);
14669 filedata->mipsxlat = NULL;
015dc7e1 14670 return true;
fd486f32
AM
14671
14672 err_out:
978c4450
AM
14673 free (filedata->gnubuckets);
14674 filedata->gnubuckets = NULL;
14675 filedata->ngnubuckets = 0;
14676 free (filedata->gnuchains);
14677 filedata->gnuchains = NULL;
14678 filedata->ngnuchains = 0;
14679 free (filedata->mipsxlat);
14680 filedata->mipsxlat = NULL;
14681 free (filedata->buckets);
14682 filedata->buckets = NULL;
14683 filedata->nbuckets = 0;
14684 free (filedata->chains);
14685 filedata->chains = NULL;
015dc7e1 14686 return false;
252b5132
RH
14687}
14688
015dc7e1 14689static bool
ca0e11aa 14690process_syminfo (Filedata * filedata)
252b5132 14691{
b4c96d0d 14692 unsigned int i;
252b5132 14693
978c4450 14694 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14695 || !do_dynamic)
14696 /* No syminfo, this is ok. */
015dc7e1 14697 return true;
252b5132
RH
14698
14699 /* There better should be a dynamic symbol section. */
978c4450 14700 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14701 return false;
252b5132 14702
ca0e11aa 14703 if (filedata->is_separate)
26c527e6
AM
14704 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14705 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14706 filedata->dynamic_syminfo_nent),
14707 filedata->file_name,
14708 filedata->dynamic_syminfo_offset,
14709 filedata->dynamic_syminfo_nent);
14710 else
26c527e6
AM
14711 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14712 " contains %d entry:\n",
14713 "\nDynamic info segment at offset %#" PRIx64
14714 " contains %d entries:\n",
978c4450 14715 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14716 filedata->dynamic_syminfo_offset,
14717 filedata->dynamic_syminfo_nent);
252b5132
RH
14718
14719 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14720 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14721 {
978c4450 14722 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14723
31104126 14724 printf ("%4d: ", i);
978c4450 14725 if (i >= filedata->num_dynamic_syms)
4082ef84 14726 printf (_("<corrupt index>"));
84714f86 14727 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14728 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14729 filedata->dynamic_symbols[i].st_name));
d79b3d50 14730 else
978c4450 14731 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14732 putchar (' ');
252b5132 14733
978c4450 14734 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14735 {
14736 case SYMINFO_BT_SELF:
14737 fputs ("SELF ", stdout);
14738 break;
14739 case SYMINFO_BT_PARENT:
14740 fputs ("PARENT ", stdout);
14741 break;
14742 default:
978c4450
AM
14743 if (filedata->dynamic_syminfo[i].si_boundto > 0
14744 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14745 && valid_dynamic_name (filedata,
978c4450 14746 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14747 {
b6ac461a 14748 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14749 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14750 putchar (' ' );
14751 }
252b5132 14752 else
978c4450 14753 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14754 break;
14755 }
14756
14757 if (flags & SYMINFO_FLG_DIRECT)
14758 printf (" DIRECT");
14759 if (flags & SYMINFO_FLG_PASSTHRU)
14760 printf (" PASSTHRU");
14761 if (flags & SYMINFO_FLG_COPY)
14762 printf (" COPY");
14763 if (flags & SYMINFO_FLG_LAZYLOAD)
14764 printf (" LAZYLOAD");
14765
14766 puts ("");
14767 }
14768
015dc7e1 14769 return true;
252b5132
RH
14770}
14771
75802ccb
CE
14772/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14773 is contained by the region START .. END. The types of ADDR, START
14774 and END should all be the same. Note both ADDR + NELEM and END
14775 point to just beyond the end of the regions that are being tested. */
14776#define IN_RANGE(START,END,ADDR,NELEM) \
14777 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14778
cf13d699
NC
14779/* Check to see if the given reloc needs to be handled in a target specific
14780 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14781 FALSE.
14782
14783 If called with reloc == NULL, then this is a signal that reloc processing
14784 for the current section has finished, and any saved state should be
14785 discarded. */
09c11c86 14786
015dc7e1 14787static bool
26c527e6
AM
14788target_specific_reloc_handling (Filedata *filedata,
14789 Elf_Internal_Rela *reloc,
14790 unsigned char *start,
14791 unsigned char *end,
14792 Elf_Internal_Sym *symtab,
14793 uint64_t num_syms)
252b5132 14794{
f84ce13b 14795 unsigned int reloc_type = 0;
26c527e6 14796 uint64_t sym_index = 0;
f84ce13b
NC
14797
14798 if (reloc)
14799 {
dda8d76d 14800 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14801 sym_index = get_reloc_symindex (reloc->r_info);
14802 }
252b5132 14803
dda8d76d 14804 switch (filedata->file_header.e_machine)
252b5132 14805 {
76244462 14806 case EM_LOONGARCH:
14807 {
14808 switch (reloc_type)
14809 {
14810 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14811 at assembly time. */
14812 case 107: /* R_LARCH_ADD_ULEB128. */
14813 case 108: /* R_LARCH_SUB_ULEB128. */
14814 {
d3f34076 14815 uint64_t value = 0;
76244462 14816 unsigned int reloc_size = 0;
14817 int leb_ret = 0;
14818
89c70cd3
AM
14819 if (reloc->r_offset < (size_t) (end - start))
14820 value = read_leb128 (start + reloc->r_offset, end, false,
14821 &reloc_size, &leb_ret);
76244462 14822 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14823 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14824 "ULEB128 value\n"),
14825 (long) reloc->r_offset);
14826
74a965d8
AM
14827 else if (sym_index >= num_syms)
14828 error (_("%s reloc contains invalid symbol index "
14829 "%" PRIu64 "\n"),
14830 (reloc_type == 107
14831 ? "R_LARCH_ADD_ULEB128"
14832 : "R_LARCH_SUB_ULEB128"),
14833 sym_index);
14834 else
76244462 14835 {
74a965d8
AM
14836 if (reloc_type == 107)
14837 value += reloc->r_addend + symtab[sym_index].st_value;
14838 else
14839 value -= reloc->r_addend + symtab[sym_index].st_value;
14840
14841 /* Write uleb128 value to p. */
14842 bfd_byte *p = start + reloc->r_offset;
14843 do
14844 {
14845 bfd_byte c = value & 0x7f;
14846 value >>= 7;
14847 if (--reloc_size != 0)
14848 c |= 0x80;
14849 *p++ = c;
14850 }
14851 while (reloc_size);
76244462 14852 }
76244462 14853
14854 return true;
14855 }
14856 }
14857 break;
14858 }
14859
13761a11
NC
14860 case EM_MSP430:
14861 case EM_MSP430_OLD:
14862 {
14863 static Elf_Internal_Sym * saved_sym = NULL;
14864
f84ce13b
NC
14865 if (reloc == NULL)
14866 {
14867 saved_sym = NULL;
015dc7e1 14868 return true;
f84ce13b
NC
14869 }
14870
13761a11
NC
14871 switch (reloc_type)
14872 {
14873 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14874 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14875 if (uses_msp430x_relocs (filedata))
13761a11 14876 break;
1a0670f3 14877 /* Fall through. */
13761a11 14878 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14879 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14880 /* PR 21139. */
14881 if (sym_index >= num_syms)
74a965d8
AM
14882 error (_("%s reloc contains invalid symbol index "
14883 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14884 else
14885 saved_sym = symtab + sym_index;
015dc7e1 14886 return true;
13761a11
NC
14887
14888 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14889 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14890 goto handle_sym_diff;
0b4362b0 14891
13761a11
NC
14892 case 5: /* R_MSP430_16_BYTE */
14893 case 9: /* R_MSP430_8 */
7d81bc93 14894 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14895 if (uses_msp430x_relocs (filedata))
13761a11
NC
14896 break;
14897 goto handle_sym_diff;
14898
14899 case 2: /* R_MSP430_ABS16 */
14900 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14901 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14902 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14903 break;
14904 goto handle_sym_diff;
0b4362b0 14905
13761a11
NC
14906 handle_sym_diff:
14907 if (saved_sym != NULL)
14908 {
625d49fc 14909 uint64_t value;
5a805384 14910 unsigned int reloc_size = 0;
7d81bc93
JL
14911 int leb_ret = 0;
14912 switch (reloc_type)
14913 {
14914 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14915 reloc_size = 4;
14916 break;
14917 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14918 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14919 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14920 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14921 &reloc_size, &leb_ret);
7d81bc93
JL
14922 break;
14923 default:
14924 reloc_size = 2;
14925 break;
14926 }
13761a11 14927
5a805384 14928 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14929 error (_("MSP430 ULEB128 field at %#" PRIx64
14930 " contains invalid ULEB128 value\n"),
14931 reloc->r_offset);
7d81bc93 14932 else if (sym_index >= num_syms)
74a965d8
AM
14933 error (_("%s reloc contains invalid symbol index "
14934 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14935 else
f84ce13b
NC
14936 {
14937 value = reloc->r_addend + (symtab[sym_index].st_value
14938 - saved_sym->st_value);
14939
b32e566b 14940 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14941 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14942 else
14943 /* PR 21137 */
26c527e6
AM
14944 error (_("MSP430 sym diff reloc contains invalid offset: "
14945 "%#" PRIx64 "\n"),
14946 reloc->r_offset);
f84ce13b 14947 }
13761a11
NC
14948
14949 saved_sym = NULL;
015dc7e1 14950 return true;
13761a11
NC
14951 }
14952 break;
14953
14954 default:
14955 if (saved_sym != NULL)
071436c6 14956 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14957 break;
14958 }
14959 break;
14960 }
14961
cf13d699
NC
14962 case EM_MN10300:
14963 case EM_CYGNUS_MN10300:
14964 {
14965 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14966
f84ce13b
NC
14967 if (reloc == NULL)
14968 {
14969 saved_sym = NULL;
015dc7e1 14970 return true;
f84ce13b
NC
14971 }
14972
cf13d699
NC
14973 switch (reloc_type)
14974 {
14975 case 34: /* R_MN10300_ALIGN */
015dc7e1 14976 return true;
cf13d699 14977 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14978 if (sym_index >= num_syms)
74a965d8
AM
14979 error (_("%s reloc contains invalid symbol index "
14980 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14981 else
14982 saved_sym = symtab + sym_index;
015dc7e1 14983 return true;
f84ce13b 14984
cf13d699
NC
14985 case 1: /* R_MN10300_32 */
14986 case 2: /* R_MN10300_16 */
14987 if (saved_sym != NULL)
14988 {
03f7786e 14989 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14990 uint64_t value;
252b5132 14991
f84ce13b 14992 if (sym_index >= num_syms)
74a965d8
AM
14993 error (_("%s reloc contains invalid symbol index "
14994 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14995 else
f84ce13b
NC
14996 {
14997 value = reloc->r_addend + (symtab[sym_index].st_value
14998 - saved_sym->st_value);
14999
b32e566b 15000 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 15001 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 15002 else
26c527e6
AM
15003 error (_("MN10300 sym diff reloc contains invalid offset:"
15004 " %#" PRIx64 "\n"),
15005 reloc->r_offset);
f84ce13b 15006 }
252b5132 15007
cf13d699 15008 saved_sym = NULL;
015dc7e1 15009 return true;
cf13d699
NC
15010 }
15011 break;
15012 default:
15013 if (saved_sym != NULL)
071436c6 15014 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
15015 break;
15016 }
15017 break;
15018 }
6ff71e76
NC
15019
15020 case EM_RL78:
15021 {
625d49fc
AM
15022 static uint64_t saved_sym1 = 0;
15023 static uint64_t saved_sym2 = 0;
15024 static uint64_t value;
6ff71e76 15025
f84ce13b
NC
15026 if (reloc == NULL)
15027 {
15028 saved_sym1 = saved_sym2 = 0;
015dc7e1 15029 return true;
f84ce13b
NC
15030 }
15031
6ff71e76
NC
15032 switch (reloc_type)
15033 {
15034 case 0x80: /* R_RL78_SYM. */
15035 saved_sym1 = saved_sym2;
f84ce13b 15036 if (sym_index >= num_syms)
74a965d8
AM
15037 error (_("%s reloc contains invalid symbol index "
15038 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
15039 else
15040 {
15041 saved_sym2 = symtab[sym_index].st_value;
15042 saved_sym2 += reloc->r_addend;
15043 }
015dc7e1 15044 return true;
6ff71e76
NC
15045
15046 case 0x83: /* R_RL78_OPsub. */
15047 value = saved_sym1 - saved_sym2;
15048 saved_sym2 = saved_sym1 = 0;
015dc7e1 15049 return true;
6ff71e76
NC
15050 break;
15051
15052 case 0x41: /* R_RL78_ABS32. */
b32e566b 15053 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 15054 byte_put (start + reloc->r_offset, value, 4);
b32e566b 15055 else
26c527e6
AM
15056 error (_("RL78 sym diff reloc contains invalid offset: "
15057 "%#" PRIx64 "\n"),
15058 reloc->r_offset);
6ff71e76 15059 value = 0;
015dc7e1 15060 return true;
6ff71e76
NC
15061
15062 case 0x43: /* R_RL78_ABS16. */
b32e566b 15063 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 15064 byte_put (start + reloc->r_offset, value, 2);
b32e566b 15065 else
26c527e6
AM
15066 error (_("RL78 sym diff reloc contains invalid offset: "
15067 "%#" PRIx64 "\n"),
15068 reloc->r_offset);
6ff71e76 15069 value = 0;
015dc7e1 15070 return true;
6ff71e76
NC
15071
15072 default:
15073 break;
15074 }
15075 break;
15076 }
252b5132
RH
15077 }
15078
015dc7e1 15079 return false;
252b5132
RH
15080}
15081
aca88567
NC
15082/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15083 DWARF debug sections. This is a target specific test. Note - we do not
15084 go through the whole including-target-headers-multiple-times route, (as
15085 we have already done with <elf/h8.h>) because this would become very
15086 messy and even then this function would have to contain target specific
15087 information (the names of the relocs instead of their numeric values).
15088 FIXME: This is not the correct way to solve this problem. The proper way
15089 is to have target specific reloc sizing and typing functions created by
15090 the reloc-macros.h header, in the same way that it already creates the
15091 reloc naming functions. */
15092
015dc7e1 15093static bool
dda8d76d 15094is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15095{
d347c9df 15096 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15097 switch (filedata->file_header.e_machine)
aca88567 15098 {
41e92641 15099 case EM_386:
22abe556 15100 case EM_IAMCU:
41e92641 15101 return reloc_type == 1; /* R_386_32. */
aca88567
NC
15102 case EM_68K:
15103 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
15104 case EM_860:
15105 return reloc_type == 1; /* R_860_32. */
15106 case EM_960:
15107 return reloc_type == 2; /* R_960_32. */
a06ea964 15108 case EM_AARCH64:
9282b95a
JW
15109 return (reloc_type == 258
15110 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
15111 case EM_BPF:
15112 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
15113 case EM_ADAPTEVA_EPIPHANY:
15114 return reloc_type == 3;
aca88567 15115 case EM_ALPHA:
137b6b5f 15116 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
15117 case EM_ARC:
15118 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
15119 case EM_ARC_COMPACT:
15120 case EM_ARC_COMPACT2:
b5c37946
SJ
15121 case EM_ARC_COMPACT3:
15122 case EM_ARC_COMPACT3_64:
886a2506 15123 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
15124 case EM_ARM:
15125 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 15126 case EM_AVR_OLD:
aca88567
NC
15127 case EM_AVR:
15128 return reloc_type == 1;
15129 case EM_BLACKFIN:
15130 return reloc_type == 0x12; /* R_byte4_data. */
15131 case EM_CRIS:
15132 return reloc_type == 3; /* R_CRIS_32. */
15133 case EM_CR16:
15134 return reloc_type == 3; /* R_CR16_NUM32. */
15135 case EM_CRX:
15136 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
15137 case EM_CSKY:
15138 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
15139 case EM_CYGNUS_FRV:
15140 return reloc_type == 1;
41e92641
NC
15141 case EM_CYGNUS_D10V:
15142 case EM_D10V:
15143 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
15144 case EM_CYGNUS_D30V:
15145 case EM_D30V:
15146 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
15147 case EM_DLX:
15148 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
15149 case EM_CYGNUS_FR30:
15150 case EM_FR30:
15151 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
15152 case EM_FT32:
15153 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
15154 case EM_H8S:
15155 case EM_H8_300:
15156 case EM_H8_300H:
15157 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 15158 case EM_IA_64:
262cdac7
AM
15159 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15160 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15161 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15162 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
15163 case EM_IP2K_OLD:
15164 case EM_IP2K:
15165 return reloc_type == 2; /* R_IP2K_32. */
15166 case EM_IQ2000:
15167 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
15168 case EM_KVX:
15169 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
15170 case EM_LATTICEMICO32:
15171 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 15172 case EM_LOONGARCH:
15173 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 15174 case EM_M32C_OLD:
aca88567
NC
15175 case EM_M32C:
15176 return reloc_type == 3; /* R_M32C_32. */
15177 case EM_M32R:
15178 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
15179 case EM_68HC11:
15180 case EM_68HC12:
15181 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 15182 case EM_S12Z:
2849d19f
JD
15183 return reloc_type == 7 || /* R_S12Z_EXT32 */
15184 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
15185 case EM_MCORE:
15186 return reloc_type == 1; /* R_MCORE_ADDR32. */
15187 case EM_CYGNUS_MEP:
15188 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
15189 case EM_METAG:
15190 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
15191 case EM_MICROBLAZE:
15192 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
15193 case EM_MIPS:
15194 return reloc_type == 2; /* R_MIPS_32. */
15195 case EM_MMIX:
15196 return reloc_type == 4; /* R_MMIX_32. */
15197 case EM_CYGNUS_MN10200:
15198 case EM_MN10200:
15199 return reloc_type == 1; /* R_MN10200_32. */
15200 case EM_CYGNUS_MN10300:
15201 case EM_MN10300:
15202 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
15203 case EM_MOXIE:
15204 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
15205 case EM_MSP430_OLD:
15206 case EM_MSP430:
13761a11 15207 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
15208 case EM_MT:
15209 return reloc_type == 2; /* R_MT_32. */
35c08157 15210 case EM_NDS32:
81c5e376 15211 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 15212 case EM_ALTERA_NIOS2:
36591ba1 15213 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
15214 case EM_NIOS32:
15215 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
15216 case EM_OR1K:
15217 return reloc_type == 1; /* R_OR1K_32. */
aca88567 15218 case EM_PARISC:
9abca702 15219 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 15220 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 15221 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
15222 case EM_PJ:
15223 case EM_PJ_OLD:
15224 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15225 case EM_PPC64:
15226 return reloc_type == 1; /* R_PPC64_ADDR32. */
15227 case EM_PPC:
15228 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
15229 case EM_TI_PRU:
15230 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
15231 case EM_RISCV:
15232 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
15233 case EM_RL78:
15234 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
15235 case EM_RX:
15236 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
15237 case EM_S370:
15238 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
15239 case EM_S390_OLD:
15240 case EM_S390:
15241 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
15242 case EM_SCORE:
15243 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
15244 case EM_SH:
15245 return reloc_type == 1; /* R_SH_DIR32. */
15246 case EM_SPARC32PLUS:
15247 case EM_SPARCV9:
15248 case EM_SPARC:
15249 return reloc_type == 3 /* R_SPARC_32. */
15250 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
15251 case EM_SPU:
15252 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
15253 case EM_TI_C6000:
15254 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
15255 case EM_TILEGX:
15256 return reloc_type == 2; /* R_TILEGX_32. */
15257 case EM_TILEPRO:
15258 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
15259 case EM_CYGNUS_V850:
15260 case EM_V850:
15261 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
15262 case EM_V800:
15263 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
15264 case EM_VAX:
15265 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
15266 case EM_VISIUM:
15267 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
15268 case EM_WEBASSEMBLY:
15269 return reloc_type == 1; /* R_WASM32_32. */
aca88567 15270 case EM_X86_64:
8a9036a4 15271 case EM_L1OM:
7a9068fe 15272 case EM_K1OM:
aca88567 15273 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
15274 case EM_XGATE:
15275 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
15276 case EM_XSTORMY16:
15277 return reloc_type == 1; /* R_XSTROMY16_32. */
15278 case EM_XTENSA_OLD:
15279 case EM_XTENSA:
15280 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
15281 case EM_Z80:
15282 return reloc_type == 6; /* R_Z80_32. */
aca88567 15283 default:
bee0ee85
NC
15284 {
15285 static unsigned int prev_warn = 0;
15286
15287 /* Avoid repeating the same warning multiple times. */
dda8d76d 15288 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15289 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15290 filedata->file_header.e_machine);
15291 prev_warn = filedata->file_header.e_machine;
015dc7e1 15292 return false;
bee0ee85 15293 }
aca88567
NC
15294 }
15295}
15296
15297/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15298 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15299
015dc7e1 15300static bool
dda8d76d 15301is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15302{
dda8d76d 15303 switch (filedata->file_header.e_machine)
d347c9df 15304 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15305 {
41e92641 15306 case EM_386:
22abe556 15307 case EM_IAMCU:
3e0873ac 15308 return reloc_type == 2; /* R_386_PC32. */
aca88567 15309 case EM_68K:
3e0873ac 15310 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15311 case EM_AARCH64:
15312 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15313 case EM_ADAPTEVA_EPIPHANY:
15314 return reloc_type == 6;
aca88567
NC
15315 case EM_ALPHA:
15316 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15317 case EM_ARC_COMPACT:
15318 case EM_ARC_COMPACT2:
b5c37946
SJ
15319 case EM_ARC_COMPACT3:
15320 case EM_ARC_COMPACT3_64:
726c18e1 15321 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15322 case EM_ARM:
3e0873ac 15323 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15324 case EM_AVR_OLD:
15325 case EM_AVR:
15326 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15327 case EM_LOONGARCH:
15328 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15329 case EM_MICROBLAZE:
15330 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15331 case EM_OR1K:
15332 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15333 case EM_PARISC:
85acf597 15334 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15335 case EM_PPC:
15336 return reloc_type == 26; /* R_PPC_REL32. */
15337 case EM_PPC64:
3e0873ac 15338 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15339 case EM_RISCV:
15340 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15341 case EM_S390_OLD:
15342 case EM_S390:
3e0873ac 15343 return reloc_type == 5; /* R_390_PC32. */
aca88567 15344 case EM_SH:
3e0873ac 15345 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15346 case EM_SPARC32PLUS:
15347 case EM_SPARCV9:
15348 case EM_SPARC:
3e0873ac 15349 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15350 case EM_SPU:
15351 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15352 case EM_TILEGX:
15353 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15354 case EM_TILEPRO:
15355 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15356 case EM_VISIUM:
15357 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15358 case EM_X86_64:
8a9036a4 15359 case EM_L1OM:
7a9068fe 15360 case EM_K1OM:
3e0873ac 15361 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15362 case EM_VAX:
15363 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15364 case EM_XTENSA_OLD:
15365 case EM_XTENSA:
15366 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15367 case EM_KVX:
15368 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15369 default:
15370 /* Do not abort or issue an error message here. Not all targets use
15371 pc-relative 32-bit relocs in their DWARF debug information and we
15372 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15373 more helpful warning message will be generated by apply_relocations
15374 anyway, so just return. */
015dc7e1 15375 return false;
aca88567
NC
15376 }
15377}
15378
15379/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15380 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15381
015dc7e1 15382static bool
dda8d76d 15383is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15384{
dda8d76d 15385 switch (filedata->file_header.e_machine)
aca88567 15386 {
a06ea964
NC
15387 case EM_AARCH64:
15388 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15389 case EM_ARC_COMPACT3_64:
15390 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15391 case EM_ALPHA:
15392 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15393 case EM_IA_64:
262cdac7
AM
15394 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15395 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15396 case EM_LOONGARCH:
15397 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15398 case EM_PARISC:
15399 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15400 case EM_PPC64:
15401 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15402 case EM_RISCV:
15403 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15404 case EM_SPARC32PLUS:
15405 case EM_SPARCV9:
15406 case EM_SPARC:
714da62f
NC
15407 return reloc_type == 32 /* R_SPARC_64. */
15408 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15409 case EM_X86_64:
8a9036a4 15410 case EM_L1OM:
7a9068fe 15411 case EM_K1OM:
aca88567 15412 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15413 case EM_S390_OLD:
15414 case EM_S390:
aa137e4d
NC
15415 return reloc_type == 22; /* R_S390_64. */
15416 case EM_TILEGX:
15417 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15418 case EM_MIPS:
aa137e4d 15419 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15420 case EM_KVX:
15421 return reloc_type == 3; /* R_KVX_64 */
aca88567 15422 default:
015dc7e1 15423 return false;
aca88567
NC
15424 }
15425}
15426
85acf597
RH
15427/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15428 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15429
015dc7e1 15430static bool
dda8d76d 15431is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15432{
dda8d76d 15433 switch (filedata->file_header.e_machine)
85acf597 15434 {
a06ea964
NC
15435 case EM_AARCH64:
15436 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15437 case EM_ALPHA:
aa137e4d 15438 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15439 case EM_IA_64:
262cdac7
AM
15440 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15441 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15442 case EM_PARISC:
aa137e4d 15443 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15444 case EM_PPC64:
aa137e4d 15445 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15446 case EM_SPARC32PLUS:
15447 case EM_SPARCV9:
15448 case EM_SPARC:
aa137e4d 15449 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15450 case EM_X86_64:
8a9036a4 15451 case EM_L1OM:
7a9068fe 15452 case EM_K1OM:
aa137e4d 15453 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15454 case EM_S390_OLD:
15455 case EM_S390:
aa137e4d
NC
15456 return reloc_type == 23; /* R_S390_PC64. */
15457 case EM_TILEGX:
15458 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15459 default:
015dc7e1 15460 return false;
85acf597
RH
15461 }
15462}
15463
4dc3c23d
AM
15464/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15465 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15466
015dc7e1 15467static bool
dda8d76d 15468is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15469{
dda8d76d 15470 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15471 {
15472 case EM_CYGNUS_MN10200:
15473 case EM_MN10200:
15474 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15475 case EM_FT32:
15476 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15477 case EM_Z80:
15478 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15479 default:
015dc7e1 15480 return false;
4dc3c23d
AM
15481 }
15482}
15483
aca88567
NC
15484/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15485 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15486
015dc7e1 15487static bool
dda8d76d 15488is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15489{
d347c9df 15490 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15491 switch (filedata->file_header.e_machine)
4b78141a 15492 {
886a2506
NC
15493 case EM_ARC:
15494 case EM_ARC_COMPACT:
15495 case EM_ARC_COMPACT2:
b5c37946
SJ
15496 case EM_ARC_COMPACT3:
15497 case EM_ARC_COMPACT3_64:
886a2506 15498 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15499 case EM_ADAPTEVA_EPIPHANY:
15500 return reloc_type == 5;
aca88567
NC
15501 case EM_AVR_OLD:
15502 case EM_AVR:
15503 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15504 case EM_CYGNUS_D10V:
15505 case EM_D10V:
15506 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15507 case EM_FT32:
15508 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15509 case EM_H8S:
15510 case EM_H8_300:
15511 case EM_H8_300H:
aca88567
NC
15512 return reloc_type == R_H8_DIR16;
15513 case EM_IP2K_OLD:
15514 case EM_IP2K:
15515 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15516 case EM_M32C_OLD:
f4236fe4
DD
15517 case EM_M32C:
15518 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15519 case EM_CYGNUS_MN10200:
15520 case EM_MN10200:
15521 return reloc_type == 2; /* R_MN10200_16. */
15522 case EM_CYGNUS_MN10300:
15523 case EM_MN10300:
15524 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15525 case EM_KVX:
15526 return reloc_type == 1; /* R_KVX_16 */
aca88567 15527 case EM_MSP430:
dda8d76d 15528 if (uses_msp430x_relocs (filedata))
13761a11 15529 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15530 /* Fall through. */
78c8d46c 15531 case EM_MSP430_OLD:
aca88567 15532 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15533 case EM_NDS32:
81c5e376 15534 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15535 case EM_ALTERA_NIOS2:
36591ba1 15536 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15537 case EM_NIOS32:
15538 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15539 case EM_OR1K:
15540 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15541 case EM_RISCV:
15542 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15543 case EM_TI_PRU:
15544 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15545 case EM_TI_C6000:
15546 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15547 case EM_VISIUM:
15548 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15549 case EM_XGATE:
15550 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15551 case EM_Z80:
15552 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15553 default:
015dc7e1 15554 return false;
4b78141a
NC
15555 }
15556}
15557
39e07931
AS
15558/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15559 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15560
015dc7e1 15561static bool
39e07931
AS
15562is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15563{
15564 switch (filedata->file_header.e_machine)
15565 {
15566 case EM_RISCV:
15567 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15568 case EM_Z80:
15569 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15570 case EM_MICROBLAZE:
15571 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15572 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15573 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15574 default:
015dc7e1 15575 return false;
39e07931
AS
15576 }
15577}
15578
15579/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15580 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15581
015dc7e1 15582static bool
39e07931
AS
15583is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15584{
15585 switch (filedata->file_header.e_machine)
15586 {
15587 case EM_RISCV:
15588 return reloc_type == 53; /* R_RISCV_SET6. */
15589 default:
015dc7e1 15590 return false;
39e07931
AS
15591 }
15592}
15593
03336641
JW
15594/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15595 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15596
015dc7e1 15597static bool
03336641
JW
15598is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15599{
15600 /* Please keep this table alpha-sorted for ease of visual lookup. */
15601 switch (filedata->file_header.e_machine)
15602 {
76244462 15603 case EM_LOONGARCH:
15604 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15605 case EM_RISCV:
15606 return reloc_type == 35; /* R_RISCV_ADD32. */
15607 default:
015dc7e1 15608 return false;
03336641
JW
15609 }
15610}
15611
15612/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15613 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15614
015dc7e1 15615static bool
03336641
JW
15616is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15617{
15618 /* Please keep this table alpha-sorted for ease of visual lookup. */
15619 switch (filedata->file_header.e_machine)
15620 {
76244462 15621 case EM_LOONGARCH:
15622 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15623 case EM_RISCV:
15624 return reloc_type == 39; /* R_RISCV_SUB32. */
15625 default:
015dc7e1 15626 return false;
03336641
JW
15627 }
15628}
15629
15630/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15631 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15632
015dc7e1 15633static bool
03336641
JW
15634is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15635{
15636 /* Please keep this table alpha-sorted for ease of visual lookup. */
15637 switch (filedata->file_header.e_machine)
15638 {
76244462 15639 case EM_LOONGARCH:
15640 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15641 case EM_RISCV:
15642 return reloc_type == 36; /* R_RISCV_ADD64. */
15643 default:
015dc7e1 15644 return false;
03336641
JW
15645 }
15646}
15647
15648/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15649 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15650
015dc7e1 15651static bool
03336641
JW
15652is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15653{
15654 /* Please keep this table alpha-sorted for ease of visual lookup. */
15655 switch (filedata->file_header.e_machine)
15656 {
76244462 15657 case EM_LOONGARCH:
15658 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15659 case EM_RISCV:
15660 return reloc_type == 40; /* R_RISCV_SUB64. */
15661 default:
015dc7e1 15662 return false;
03336641
JW
15663 }
15664}
15665
15666/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15667 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15668
015dc7e1 15669static bool
03336641
JW
15670is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15671{
15672 /* Please keep this table alpha-sorted for ease of visual lookup. */
15673 switch (filedata->file_header.e_machine)
15674 {
76244462 15675 case EM_LOONGARCH:
15676 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15677 case EM_RISCV:
15678 return reloc_type == 34; /* R_RISCV_ADD16. */
15679 default:
015dc7e1 15680 return false;
03336641
JW
15681 }
15682}
15683
15684/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15685 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15686
015dc7e1 15687static bool
03336641
JW
15688is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15689{
15690 /* Please keep this table alpha-sorted for ease of visual lookup. */
15691 switch (filedata->file_header.e_machine)
15692 {
76244462 15693 case EM_LOONGARCH:
15694 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15695 case EM_RISCV:
15696 return reloc_type == 38; /* R_RISCV_SUB16. */
15697 default:
015dc7e1 15698 return false;
03336641
JW
15699 }
15700}
15701
15702/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15703 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15704
015dc7e1 15705static bool
03336641
JW
15706is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15707{
15708 /* Please keep this table alpha-sorted for ease of visual lookup. */
15709 switch (filedata->file_header.e_machine)
15710 {
76244462 15711 case EM_LOONGARCH:
15712 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15713 case EM_RISCV:
15714 return reloc_type == 33; /* R_RISCV_ADD8. */
15715 default:
015dc7e1 15716 return false;
03336641
JW
15717 }
15718}
15719
15720/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15721 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15722
015dc7e1 15723static bool
03336641
JW
15724is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15725{
15726 /* Please keep this table alpha-sorted for ease of visual lookup. */
15727 switch (filedata->file_header.e_machine)
15728 {
76244462 15729 case EM_LOONGARCH:
15730 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15731 case EM_RISCV:
15732 return reloc_type == 37; /* R_RISCV_SUB8. */
15733 default:
015dc7e1 15734 return false;
03336641
JW
15735 }
15736}
15737
76244462 15738/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15739 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15740
15741static bool
15742is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15743{
15744 switch (filedata->file_header.e_machine)
15745 {
15746 case EM_LOONGARCH:
15747 return reloc_type == 105; /* R_LARCH_ADD6. */
15748 default:
15749 return false;
15750 }
15751}
15752
39e07931
AS
15753/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15754 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15755
015dc7e1 15756static bool
39e07931
AS
15757is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15758{
15759 switch (filedata->file_header.e_machine)
15760 {
76244462 15761 case EM_LOONGARCH:
15762 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15763 case EM_RISCV:
15764 return reloc_type == 52; /* R_RISCV_SUB6. */
15765 default:
015dc7e1 15766 return false;
39e07931
AS
15767 }
15768}
15769
2a7b2e88
JK
15770/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15771 relocation entries (possibly formerly used for SHT_GROUP sections). */
15772
015dc7e1 15773static bool
dda8d76d 15774is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15775{
dda8d76d 15776 switch (filedata->file_header.e_machine)
2a7b2e88 15777 {
cb8f3167 15778 case EM_386: /* R_386_NONE. */
d347c9df 15779 case EM_68K: /* R_68K_NONE. */
cfb8c092 15780 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15781 case EM_ALPHA: /* R_ALPHA_NONE. */
15782 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15783 case EM_ARC: /* R_ARC_NONE. */
886a2506 15784 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15785 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15786 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15787 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15788 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15789 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15790 case EM_FT32: /* R_FT32_NONE. */
15791 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15792 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15793 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15794 case EM_L1OM: /* R_X86_64_NONE. */
15795 case EM_M32R: /* R_M32R_NONE. */
15796 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15797 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15798 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15799 case EM_NIOS32: /* R_NIOS_NONE. */
15800 case EM_OR1K: /* R_OR1K_NONE. */
15801 case EM_PARISC: /* R_PARISC_NONE. */
15802 case EM_PPC64: /* R_PPC64_NONE. */
15803 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15804 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15805 case EM_S390: /* R_390_NONE. */
15806 case EM_S390_OLD:
15807 case EM_SH: /* R_SH_NONE. */
15808 case EM_SPARC32PLUS:
15809 case EM_SPARC: /* R_SPARC_NONE. */
15810 case EM_SPARCV9:
aa137e4d
NC
15811 case EM_TILEGX: /* R_TILEGX_NONE. */
15812 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15813 case EM_TI_C6000:/* R_C6000_NONE. */
15814 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15815 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15816 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15817 return reloc_type == 0;
d347c9df 15818
a06ea964
NC
15819 case EM_AARCH64:
15820 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15821 case EM_AVR_OLD:
15822 case EM_AVR:
15823 return (reloc_type == 0 /* R_AVR_NONE. */
15824 || reloc_type == 30 /* R_AVR_DIFF8. */
15825 || reloc_type == 31 /* R_AVR_DIFF16. */
15826 || reloc_type == 32 /* R_AVR_DIFF32. */);
15827 case EM_METAG:
15828 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15829 case EM_NDS32:
81c5e376
AM
15830 return (reloc_type == 0 /* R_NDS32_NONE. */
15831 || reloc_type == 205 /* R_NDS32_DIFF8. */
15832 || reloc_type == 206 /* R_NDS32_DIFF16. */
15833 || reloc_type == 207 /* R_NDS32_DIFF32. */
15834 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15835 case EM_TI_PRU:
15836 return (reloc_type == 0 /* R_PRU_NONE. */
15837 || reloc_type == 65 /* R_PRU_DIFF8. */
15838 || reloc_type == 66 /* R_PRU_DIFF16. */
15839 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15840 case EM_XTENSA_OLD:
15841 case EM_XTENSA:
4dc3c23d
AM
15842 return (reloc_type == 0 /* R_XTENSA_NONE. */
15843 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15844 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15845 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15846 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15847 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15848 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15849 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15850 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15851 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15852 }
015dc7e1 15853 return false;
2a7b2e88
JK
15854}
15855
d1c4b12b
NC
15856/* Returns TRUE if there is a relocation against
15857 section NAME at OFFSET bytes. */
15858
015dc7e1 15859bool
31e5a3a3 15860reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15861{
15862 Elf_Internal_Rela * relocs;
15863 Elf_Internal_Rela * rp;
15864
15865 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15866 return false;
d1c4b12b
NC
15867
15868 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15869
15870 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15871 if (rp->r_offset == offset)
015dc7e1 15872 return true;
d1c4b12b 15873
015dc7e1 15874 return false;
d1c4b12b
NC
15875}
15876
cf13d699 15877/* Apply relocations to a section.
32ec8896
NC
15878 Returns TRUE upon success, FALSE otherwise.
15879 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15880 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15881 will be set to the number of relocs loaded.
15882
cf13d699 15883 Note: So far support has been added only for those relocations
32ec8896
NC
15884 which can be found in debug sections. FIXME: Add support for
15885 more relocations ? */
1b315056 15886
015dc7e1 15887static bool
be7d229a
AM
15888apply_relocations (Filedata *filedata,
15889 const Elf_Internal_Shdr *section,
15890 unsigned char *start,
15891 size_t size,
15892 void **relocs_return,
26c527e6 15893 uint64_t *num_relocs_return)
1b315056 15894{
cf13d699 15895 Elf_Internal_Shdr * relsec;
0d2a7a93 15896 unsigned char * end = start + size;
cb8f3167 15897
d1c4b12b
NC
15898 if (relocs_return != NULL)
15899 {
15900 * (Elf_Internal_Rela **) relocs_return = NULL;
15901 * num_relocs_return = 0;
15902 }
15903
dda8d76d 15904 if (filedata->file_header.e_type != ET_REL)
32ec8896 15905 /* No relocs to apply. */
015dc7e1 15906 return true;
1b315056 15907
cf13d699 15908 /* Find the reloc section associated with the section. */
dda8d76d
NC
15909 for (relsec = filedata->section_headers;
15910 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15911 ++relsec)
252b5132 15912 {
015dc7e1 15913 bool is_rela;
26c527e6 15914 uint64_t num_relocs;
2cf0635d
NC
15915 Elf_Internal_Rela * relocs;
15916 Elf_Internal_Rela * rp;
15917 Elf_Internal_Shdr * symsec;
15918 Elf_Internal_Sym * symtab;
26c527e6 15919 uint64_t num_syms;
2cf0635d 15920 Elf_Internal_Sym * sym;
252b5132 15921
41e92641 15922 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15923 || relsec->sh_info >= filedata->file_header.e_shnum
15924 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15925 || relsec->sh_size == 0
dda8d76d 15926 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15927 continue;
428409d5 15928
a788aedd
AM
15929 symsec = filedata->section_headers + relsec->sh_link;
15930 if (symsec->sh_type != SHT_SYMTAB
15931 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15932 return false;
a788aedd 15933
41e92641
NC
15934 is_rela = relsec->sh_type == SHT_RELA;
15935
15936 if (is_rela)
15937 {
dda8d76d 15938 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15939 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15940 return false;
41e92641
NC
15941 }
15942 else
15943 {
dda8d76d 15944 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15945 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15946 return false;
41e92641
NC
15947 }
15948
15949 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15950 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15951 is_rela = false;
428409d5 15952
4de91c10 15953 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15954
41e92641 15955 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15956 {
625d49fc 15957 uint64_t addend;
015dc7e1
AM
15958 unsigned int reloc_type;
15959 unsigned int reloc_size;
15960 bool reloc_inplace = false;
15961 bool reloc_subtract = false;
15962 unsigned char *rloc;
26c527e6 15963 uint64_t sym_index;
4b78141a 15964
dda8d76d 15965 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15966
dda8d76d 15967 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15968 continue;
dda8d76d 15969 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15970 continue;
dda8d76d
NC
15971 else if (is_32bit_abs_reloc (filedata, reloc_type)
15972 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15973 reloc_size = 4;
dda8d76d
NC
15974 else if (is_64bit_abs_reloc (filedata, reloc_type)
15975 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15976 reloc_size = 8;
dda8d76d 15977 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15978 reloc_size = 3;
dda8d76d 15979 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15980 reloc_size = 2;
39e07931
AS
15981 else if (is_8bit_abs_reloc (filedata, reloc_type)
15982 || is_6bit_abs_reloc (filedata, reloc_type))
15983 reloc_size = 1;
03336641
JW
15984 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15985 reloc_type))
15986 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15987 {
15988 reloc_size = 4;
015dc7e1 15989 reloc_inplace = true;
03336641
JW
15990 }
15991 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15992 reloc_type))
15993 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15994 {
15995 reloc_size = 8;
015dc7e1 15996 reloc_inplace = true;
03336641
JW
15997 }
15998 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15999 reloc_type))
16000 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16001 {
16002 reloc_size = 2;
015dc7e1 16003 reloc_inplace = true;
03336641
JW
16004 }
16005 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16006 reloc_type))
16007 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16008 {
16009 reloc_size = 1;
015dc7e1 16010 reloc_inplace = true;
03336641 16011 }
39e07931 16012 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 16013 reloc_type))
16014 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16015 {
16016 reloc_size = 1;
015dc7e1 16017 reloc_inplace = true;
39e07931 16018 }
aca88567 16019 else
4b78141a 16020 {
bee0ee85 16021 static unsigned int prev_reloc = 0;
dda8d76d 16022
bee0ee85
NC
16023 if (reloc_type != prev_reloc)
16024 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 16025 reloc_type, printable_section_name (filedata, section));
bee0ee85 16026 prev_reloc = reloc_type;
4b78141a
NC
16027 continue;
16028 }
103f02d3 16029
91d6fa6a 16030 rloc = start + rp->r_offset;
75802ccb 16031 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 16032 {
26c527e6
AM
16033 warn (_("skipping invalid relocation offset %#" PRIx64
16034 " in section %s\n"),
16035 rp->r_offset,
dda8d76d 16036 printable_section_name (filedata, section));
700dd8b7
L
16037 continue;
16038 }
103f02d3 16039
26c527e6 16040 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
16041 if (sym_index >= num_syms)
16042 {
26c527e6
AM
16043 warn (_("skipping invalid relocation symbol index %#" PRIx64
16044 " in section %s\n"),
dda8d76d 16045 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
16046 continue;
16047 }
16048 sym = symtab + sym_index;
41e92641
NC
16049
16050 /* If the reloc has a symbol associated with it,
55f25fc3
L
16051 make sure that it is of an appropriate type.
16052
16053 Relocations against symbols without type can happen.
16054 Gcc -feliminate-dwarf2-dups may generate symbols
16055 without type for debug info.
16056
16057 Icc generates relocations against function symbols
16058 instead of local labels.
16059
16060 Relocations against object symbols can happen, eg when
16061 referencing a global array. For an example of this see
16062 the _clz.o binary in libgcc.a. */
aca88567 16063 if (sym != symtab
b8871f35 16064 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 16065 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 16066 {
26c527e6 16067 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
16068 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16069 printable_section_name (filedata, relsec),
26c527e6 16070 rp - relocs);
aca88567 16071 continue;
5b18a4bc 16072 }
252b5132 16073
4dc3c23d
AM
16074 addend = 0;
16075 if (is_rela)
16076 addend += rp->r_addend;
c47320c3
AM
16077 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16078 partial_inplace. */
4dc3c23d 16079 if (!is_rela
dda8d76d 16080 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 16081 && reloc_type == 1)
dda8d76d
NC
16082 || ((filedata->file_header.e_machine == EM_PJ
16083 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 16084 && reloc_type == 1)
dda8d76d
NC
16085 || ((filedata->file_header.e_machine == EM_D30V
16086 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
16087 && reloc_type == 12)
16088 || reloc_inplace)
39e07931
AS
16089 {
16090 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16091 addend += byte_get (rloc, reloc_size) & 0x3f;
16092 else
16093 addend += byte_get (rloc, reloc_size);
16094 }
cb8f3167 16095
dda8d76d
NC
16096 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16097 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
16098 {
16099 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 16100 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 16101 addend -= 8;
91d6fa6a 16102 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
16103 reloc_size);
16104 }
39e07931 16105 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 16106 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16107 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16108 {
16109 if (reloc_subtract)
16110 addend -= sym->st_value;
16111 else
16112 addend += sym->st_value;
16113 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16114 byte_put (rloc, addend, reloc_size);
16115 }
03336641
JW
16116 else if (reloc_subtract)
16117 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 16118 else
91d6fa6a 16119 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 16120 }
252b5132 16121
5b18a4bc 16122 free (symtab);
f84ce13b
NC
16123 /* Let the target specific reloc processing code know that
16124 we have finished with these relocs. */
dda8d76d 16125 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
16126
16127 if (relocs_return)
16128 {
16129 * (Elf_Internal_Rela **) relocs_return = relocs;
16130 * num_relocs_return = num_relocs;
16131 }
16132 else
16133 free (relocs);
16134
5b18a4bc
NC
16135 break;
16136 }
32ec8896 16137
015dc7e1 16138 return true;
5b18a4bc 16139}
103f02d3 16140
cf13d699 16141#ifdef SUPPORT_DISASSEMBLY
015dc7e1 16142static bool
dda8d76d 16143disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16144{
dda8d76d 16145 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 16146
74e1a04b 16147 /* FIXME: XXX -- to be done --- XXX */
cf13d699 16148
015dc7e1 16149 return true;
cf13d699
NC
16150}
16151#endif
16152
16153/* Reads in the contents of SECTION from FILE, returning a pointer
16154 to a malloc'ed buffer or NULL if something went wrong. */
16155
16156static char *
dda8d76d 16157get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16158{
be7d229a 16159 uint64_t num_bytes = section->sh_size;
cf13d699
NC
16160
16161 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16162 {
c6b78c96 16163 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 16164 printable_section_name (filedata, section));
cf13d699
NC
16165 return NULL;
16166 }
16167
dda8d76d 16168 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 16169 _("section contents"));
cf13d699
NC
16170}
16171
1f5a3546 16172/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 16173
015dc7e1 16174static bool
45f5fe46
NC
16175uncompress_section_contents (bool is_zstd,
16176 unsigned char ** buffer,
16177 uint64_t uncompressed_size,
16178 uint64_t * size,
16179 uint64_t file_size)
0e602686 16180{
31e5a3a3
AM
16181 uint64_t compressed_size = *size;
16182 unsigned char *compressed_buffer = *buffer;
45f5fe46 16183 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
16184 z_stream strm;
16185 int rc;
16186
f9ee45c3 16187 /* Similar to bfd_section_size_insane() in the BFD library we expect an
45f5fe46
NC
16188 upper limit of ~10x compression. Any compression larger than that is
16189 thought to be due to fuzzing of the compression header. */
16190 if (uncompressed_size > file_size * 10)
16191 {
16192 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16193 uncompressed_size);
16194 goto fail;
16195 }
16196
16197 uncompressed_buffer = xmalloc (uncompressed_size);
16198
1f5a3546
FS
16199 if (is_zstd)
16200 {
16201#ifdef HAVE_ZSTD
16202 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16203 compressed_buffer, compressed_size);
16204 if (ZSTD_isError (ret))
16205 goto fail;
16206#endif
16207 }
16208 else
16209 {
16210 /* It is possible the section consists of several compressed
16211 buffers concatenated together, so we uncompress in a loop. */
16212 /* PR 18313: The state field in the z_stream structure is supposed
16213 to be invisible to the user (ie us), but some compilers will
16214 still complain about it being used without initialisation. So
16215 we first zero the entire z_stream structure and then set the fields
16216 that we need. */
16217 memset (&strm, 0, sizeof strm);
16218 strm.avail_in = compressed_size;
16219 strm.next_in = (Bytef *)compressed_buffer;
16220 strm.avail_out = uncompressed_size;
16221
16222 rc = inflateInit (&strm);
16223 while (strm.avail_in > 0)
16224 {
16225 if (rc != Z_OK)
16226 break;
16227 strm.next_out = ((Bytef *)uncompressed_buffer
16228 + (uncompressed_size - strm.avail_out));
16229 rc = inflate (&strm, Z_FINISH);
16230 if (rc != Z_STREAM_END)
16231 break;
16232 rc = inflateReset (&strm);
16233 }
16234 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16235 goto fail;
16236 }
0e602686
NC
16237
16238 *buffer = uncompressed_buffer;
16239 *size = uncompressed_size;
015dc7e1 16240 return true;
0e602686
NC
16241
16242 fail:
16243 free (uncompressed_buffer);
16244 /* Indicate decompression failure. */
16245 *buffer = NULL;
015dc7e1 16246 return false;
0e602686 16247}
dd24e3da 16248
fab62191
NC
16249static uint64_t
16250maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16251 Filedata * filedata,
16252 unsigned char ** start_ptr,
16253 bool relocate)
cf13d699 16254{
fab62191
NC
16255 uint64_t section_size = section->sh_size;
16256 unsigned char * start = * start_ptr;
16257
0e602686
NC
16258 if (decompress_dumps)
16259 {
fab62191 16260 uint64_t new_size = section_size;
31e5a3a3 16261 uint64_t uncompressed_size = 0;
1f5a3546 16262 bool is_zstd = false;
0e602686
NC
16263
16264 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16265 {
16266 Elf_Internal_Chdr chdr;
16267 unsigned int compression_header_size
fab62191
NC
16268 = get_compression_header (& chdr, start, section_size);
16269
5844b465
NC
16270 if (compression_header_size == 0)
16271 /* An error message will have already been generated
16272 by get_compression_header. */
fab62191 16273 return (uint64_t) -1;
0e602686 16274
89dbeac7 16275 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16276 ;
16277#ifdef HAVE_ZSTD
89dbeac7 16278 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16279 is_zstd = true;
16280#endif
16281 else
0e602686 16282 {
813dabb9 16283 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16284 printable_section_name (filedata, section), chdr.ch_type);
fab62191 16285 return (uint64_t) -1;
813dabb9 16286 }
fab62191 16287
813dabb9
L
16288 uncompressed_size = chdr.ch_size;
16289 start += compression_header_size;
16290 new_size -= compression_header_size;
0e602686
NC
16291 }
16292 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16293 {
16294 /* Read the zlib header. In this case, it should be "ZLIB"
16295 followed by the uncompressed section size, 8 bytes in
16296 big-endian order. */
16297 uncompressed_size = start[4]; uncompressed_size <<= 8;
16298 uncompressed_size += start[5]; uncompressed_size <<= 8;
16299 uncompressed_size += start[6]; uncompressed_size <<= 8;
16300 uncompressed_size += start[7]; uncompressed_size <<= 8;
16301 uncompressed_size += start[8]; uncompressed_size <<= 8;
16302 uncompressed_size += start[9]; uncompressed_size <<= 8;
16303 uncompressed_size += start[10]; uncompressed_size <<= 8;
16304 uncompressed_size += start[11];
16305 start += 12;
16306 new_size -= 12;
16307 }
16308
1835f746
NC
16309 if (uncompressed_size)
16310 {
1f5a3546 16311 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16312 &new_size, filedata->file_size))
fab62191 16313 section_size = new_size;
1835f746
NC
16314 else
16315 {
16316 error (_("Unable to decompress section %s\n"),
dda8d76d 16317 printable_section_name (filedata, section));
fab62191 16318 return (uint64_t) -1;
1835f746
NC
16319 }
16320 }
bc303e5d 16321 else
fab62191
NC
16322 start = * start_ptr;
16323 }
16324 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16325 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16326 {
16327 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
0e602686 16328 }
fd8008d8 16329
fab62191 16330 if (relocate)
cf13d699 16331 {
fab62191
NC
16332 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16333 return (uint64_t) -1;
16334 }
16335 else
16336 {
16337 Elf_Internal_Shdr *relsec;
cf13d699 16338
fab62191
NC
16339 /* If the section being dumped has relocations against it the user might
16340 be expecting these relocations to have been applied. Check for this
16341 case and issue a warning message in order to avoid confusion.
16342 FIXME: Maybe we ought to have an option that dumps a section with
16343 relocs applied ? */
16344 for (relsec = filedata->section_headers;
16345 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16346 ++relsec)
16347 {
16348 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16349 || relsec->sh_info >= filedata->file_header.e_shnum
16350 || filedata->section_headers + relsec->sh_info != section
16351 || relsec->sh_size == 0
16352 || relsec->sh_link >= filedata->file_header.e_shnum)
16353 continue;
16354
16355 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16356 break;
16357 }
cf13d699
NC
16358 }
16359
fab62191
NC
16360 * start_ptr = start;
16361 return section_size;
16362}
16363
16364static bool
16365dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16366{
16367 uint64_t num_bytes;
16368 unsigned char *data;
16369 unsigned char *end;
16370 unsigned char *real_start;
16371 unsigned char *start;
16372 bool some_strings_shown;
16373
16374 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16375 if (start == NULL)
16376 /* PR 21820: Do not fail if the section was empty. */
16377 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16378
16379 num_bytes = section->sh_size;
16380
16381 if (filedata->is_separate)
16382 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16383 printable_section_name (filedata, section),
16384 filedata->file_name);
16385 else
16386 printf (_("\nString dump of section '%s':\n"),
16387 printable_section_name (filedata, section));
16388
16389 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16390 if (num_bytes == (uint64_t) -1)
16391 goto error_out;
16392
cf13d699
NC
16393 data = start;
16394 end = start + num_bytes;
015dc7e1 16395 some_strings_shown = false;
cf13d699 16396
ba3265d0
NC
16397#ifdef HAVE_MBSTATE_T
16398 mbstate_t state;
16399 /* Initialise the multibyte conversion state. */
16400 memset (& state, 0, sizeof (state));
16401#endif
16402
015dc7e1 16403 bool continuing = false;
ba3265d0 16404
cf13d699
NC
16405 while (data < end)
16406 {
16407 while (!ISPRINT (* data))
16408 if (++ data >= end)
16409 break;
16410
16411 if (data < end)
16412 {
071436c6
NC
16413 size_t maxlen = end - data;
16414
ba3265d0
NC
16415 if (continuing)
16416 {
16417 printf (" ");
015dc7e1 16418 continuing = false;
ba3265d0
NC
16419 }
16420 else
16421 {
26c527e6 16422 printf (" [%6tx] ", data - start);
ba3265d0
NC
16423 }
16424
4082ef84
NC
16425 if (maxlen > 0)
16426 {
f3da8a96 16427 char c = 0;
ba3265d0
NC
16428
16429 while (maxlen)
16430 {
16431 c = *data++;
16432
16433 if (c == 0)
16434 break;
16435
16436 /* PR 25543: Treat new-lines as string-ending characters. */
16437 if (c == '\n')
16438 {
16439 printf ("\\n\n");
16440 if (*data != 0)
015dc7e1 16441 continuing = true;
ba3265d0
NC
16442 break;
16443 }
16444
16445 /* Do not print control characters directly as they can affect terminal
16446 settings. Such characters usually appear in the names generated
16447 by the assembler for local labels. */
16448 if (ISCNTRL (c))
16449 {
16450 printf ("^%c", c + 0x40);
16451 }
16452 else if (ISPRINT (c))
16453 {
16454 putchar (c);
16455 }
16456 else
16457 {
16458 size_t n;
16459#ifdef HAVE_MBSTATE_T
16460 wchar_t w;
16461#endif
16462 /* Let printf do the hard work of displaying multibyte characters. */
16463 printf ("%.1s", data - 1);
16464#ifdef HAVE_MBSTATE_T
16465 /* Try to find out how many bytes made up the character that was
16466 just printed. Advance the symbol pointer past the bytes that
16467 were displayed. */
16468 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16469#else
16470 n = 1;
16471#endif
16472 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16473 data += (n - 1);
16474 }
16475 }
16476
16477 if (c != '\n')
16478 putchar ('\n');
4082ef84
NC
16479 }
16480 else
16481 {
16482 printf (_("<corrupt>\n"));
16483 data = end;
16484 }
015dc7e1 16485 some_strings_shown = true;
cf13d699
NC
16486 }
16487 }
16488
16489 if (! some_strings_shown)
16490 printf (_(" No strings found in this section."));
16491
0e602686 16492 free (real_start);
cf13d699
NC
16493
16494 putchar ('\n');
015dc7e1 16495 return true;
f761cb13
AM
16496
16497error_out:
16498 free (real_start);
015dc7e1 16499 return false;
cf13d699
NC
16500}
16501
015dc7e1
AM
16502static bool
16503dump_section_as_bytes (Elf_Internal_Shdr *section,
16504 Filedata *filedata,
16505 bool relocate)
cf13d699 16506{
be7d229a
AM
16507 size_t bytes;
16508 uint64_t section_size;
625d49fc 16509 uint64_t addr;
be7d229a
AM
16510 unsigned char *data;
16511 unsigned char *real_start;
16512 unsigned char *start;
0e602686 16513
dda8d76d 16514 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16515 if (start == NULL)
c6b78c96 16516 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16517 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16518
0e602686 16519 section_size = section->sh_size;
cf13d699 16520
835f2fae
NC
16521 if (filedata->is_separate)
16522 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16523 printable_section_name (filedata, section),
16524 filedata->file_name);
16525 else
16526 printf (_("\nHex dump of section '%s':\n"),
16527 printable_section_name (filedata, section));
cf13d699 16528
fab62191
NC
16529 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16530 if (section_size == (uint64_t) -1)
16531 goto error_out;
cf13d699
NC
16532
16533 addr = section->sh_addr;
0e602686 16534 bytes = section_size;
cf13d699
NC
16535 data = start;
16536
16537 while (bytes)
16538 {
16539 int j;
16540 int k;
16541 int lbytes;
16542
16543 lbytes = (bytes > 16 ? 16 : bytes);
16544
26c527e6 16545 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16546
16547 for (j = 0; j < 16; j++)
16548 {
16549 if (j < lbytes)
16550 printf ("%2.2x", data[j]);
16551 else
16552 printf (" ");
16553
16554 if ((j & 3) == 3)
16555 printf (" ");
16556 }
16557
16558 for (j = 0; j < lbytes; j++)
16559 {
16560 k = data[j];
16561 if (k >= ' ' && k < 0x7f)
16562 printf ("%c", k);
16563 else
16564 printf (".");
16565 }
16566
16567 putchar ('\n');
16568
16569 data += lbytes;
16570 addr += lbytes;
16571 bytes -= lbytes;
16572 }
16573
0e602686 16574 free (real_start);
cf13d699
NC
16575
16576 putchar ('\n');
015dc7e1 16577 return true;
f761cb13
AM
16578
16579 error_out:
16580 free (real_start);
015dc7e1 16581 return false;
cf13d699
NC
16582}
16583
094e34f2 16584#ifdef ENABLE_LIBCTF
7d9813f1
NA
16585static ctf_sect_t *
16586shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16587{
b6ac461a 16588 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16589 buf->cts_size = shdr->sh_size;
16590 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16591
16592 return buf;
16593}
16594
16595/* Formatting callback function passed to ctf_dump. Returns either the pointer
16596 it is passed, or a pointer to newly-allocated storage, in which case
16597 dump_ctf() will free it when it no longer needs it. */
16598
2f6ecaed
NA
16599static char *
16600dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16601 char *s, void *arg)
7d9813f1 16602{
3e50a591 16603 const char *blanks = arg;
7d9813f1
NA
16604 char *new_s;
16605
3e50a591 16606 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16607 return s;
16608 return new_s;
16609}
16610
926c9e76
NA
16611/* Dump CTF errors/warnings. */
16612static void
139633c3 16613dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16614{
16615 ctf_next_t *it = NULL;
16616 char *errtext;
16617 int is_warning;
16618 int err;
16619
16620 /* Dump accumulated errors and warnings. */
16621 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16622 {
5e9b84f7 16623 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16624 errtext);
16625 free (errtext);
16626 }
16627 if (err != ECTF_NEXT_END)
16628 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16629}
16630
2f6ecaed
NA
16631/* Dump one CTF archive member. */
16632
80b56fad
NA
16633static void
16634dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16635 size_t member)
2f6ecaed 16636{
2f6ecaed
NA
16637 const char *things[] = {"Header", "Labels", "Data objects",
16638 "Function objects", "Variables", "Types", "Strings",
16639 ""};
16640 const char **thing;
16641 size_t i;
16642
80b56fad
NA
16643 /* Don't print out the name of the default-named archive member if it appears
16644 first in the list. The name .ctf appears everywhere, even for things that
16645 aren't really archives, so printing it out is liable to be confusing; also,
16646 the common case by far is for only one archive member to exist, and hiding
16647 it in that case seems worthwhile. */
2f6ecaed 16648
80b56fad
NA
16649 if (strcmp (name, ".ctf") != 0 || member != 0)
16650 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16651
80b56fad
NA
16652 if (ctf_parent_name (ctf) != NULL)
16653 ctf_import (ctf, parent);
2f6ecaed
NA
16654
16655 for (i = 0, thing = things; *thing[0]; thing++, i++)
16656 {
16657 ctf_dump_state_t *s = NULL;
16658 char *item;
16659
16660 printf ("\n %s:\n", *thing);
16661 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16662 (void *) " ")) != NULL)
16663 {
16664 printf ("%s\n", item);
16665 free (item);
16666 }
16667
16668 if (ctf_errno (ctf))
16669 {
16670 error (_("Iteration failed: %s, %s\n"), *thing,
16671 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16672 break;
2f6ecaed
NA
16673 }
16674 }
8b37e7b6 16675
926c9e76 16676 dump_ctf_errs (ctf);
2f6ecaed
NA
16677}
16678
015dc7e1 16679static bool
7d9813f1
NA
16680dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16681{
7d9813f1
NA
16682 Elf_Internal_Shdr * symtab_sec = NULL;
16683 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16684 void * data = NULL;
16685 void * symdata = NULL;
16686 void * strdata = NULL;
80b56fad 16687 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16688 ctf_sect_t * symsectp = NULL;
16689 ctf_sect_t * strsectp = NULL;
2f6ecaed 16690 ctf_archive_t * ctfa = NULL;
139633c3 16691 ctf_dict_t * parent = NULL;
80b56fad 16692 ctf_dict_t * fp;
7d9813f1 16693
80b56fad
NA
16694 ctf_next_t *i = NULL;
16695 const char *name;
16696 size_t member = 0;
7d9813f1 16697 int err;
015dc7e1 16698 bool ret = false;
7d9813f1
NA
16699
16700 shdr_to_ctf_sect (&ctfsect, section, filedata);
16701 data = get_section_contents (section, filedata);
16702 ctfsect.cts_data = data;
16703
616febde 16704 if (!dump_ctf_symtab_name)
3d16b64e 16705 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16706
16707 if (!dump_ctf_strtab_name)
3d16b64e 16708 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16709
16710 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16711 {
16712 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16713 {
16714 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16715 goto fail;
16716 }
16717 if ((symdata = (void *) get_data (NULL, filedata,
16718 symtab_sec->sh_offset, 1,
16719 symtab_sec->sh_size,
16720 _("symbols"))) == NULL)
16721 goto fail;
16722 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16723 symsect.cts_data = symdata;
16724 }
835f2fae 16725
df16e041 16726 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16727 {
16728 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16729 {
16730 error (_("No string table section named %s\n"),
16731 dump_ctf_strtab_name);
16732 goto fail;
16733 }
16734 if ((strdata = (void *) get_data (NULL, filedata,
16735 strtab_sec->sh_offset, 1,
16736 strtab_sec->sh_size,
16737 _("strings"))) == NULL)
16738 goto fail;
16739 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16740 strsect.cts_data = strdata;
16741 }
835f2fae 16742
2f6ecaed
NA
16743 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16744 libctf papers over the difference, so we can pretend it is always an
80b56fad 16745 archive. */
7d9813f1 16746
2f6ecaed 16747 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16748 {
926c9e76 16749 dump_ctf_errs (NULL);
7d9813f1
NA
16750 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16751 goto fail;
16752 }
16753
96c61be5
NA
16754 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16755 != ELFDATA2MSB);
16756
80b56fad
NA
16757 /* Preload the parent dict, since it will need to be imported into every
16758 child in turn. */
16759 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16760 {
926c9e76 16761 dump_ctf_errs (NULL);
2f6ecaed
NA
16762 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16763 goto fail;
7d9813f1
NA
16764 }
16765
015dc7e1 16766 ret = true;
7d9813f1 16767
835f2fae
NC
16768 if (filedata->is_separate)
16769 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16770 printable_section_name (filedata, section),
16771 filedata->file_name);
16772 else
16773 printf (_("\nDump of CTF section '%s':\n"),
16774 printable_section_name (filedata, section));
7d9813f1 16775
80b56fad
NA
16776 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16777 dump_ctf_archive_member (fp, name, parent, member++);
16778 if (err != ECTF_NEXT_END)
16779 {
16780 dump_ctf_errs (NULL);
16781 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16782 ret = false;
16783 }
7d9813f1
NA
16784
16785 fail:
139633c3 16786 ctf_dict_close (parent);
2f6ecaed 16787 ctf_close (ctfa);
7d9813f1
NA
16788 free (data);
16789 free (symdata);
16790 free (strdata);
16791 return ret;
16792}
094e34f2 16793#endif
7d9813f1 16794
42b6953b
IB
16795static bool
16796dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16797{
16798 void * data = NULL;
16799 sframe_decoder_ctx *sfd_ctx = NULL;
16800 const char *print_name = printable_section_name (filedata, section);
16801
16802 bool ret = true;
16803 size_t sf_size;
16804 int err = 0;
16805
16806 if (strcmp (print_name, "") == 0)
16807 {
16808 error (_("Section name must be provided \n"));
16809 ret = false;
16810 return ret;
16811 }
16812
16813 data = get_section_contents (section, filedata);
16814 sf_size = section->sh_size;
16815 /* Decode the contents of the section. */
16816 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16817 if (!sfd_ctx)
16818 {
16819 ret = false;
16820 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16821 goto fail;
16822 }
16823
16824 printf (_("Contents of the SFrame section %s:"), print_name);
16825 /* Dump the contents as text. */
16826 dump_sframe (sfd_ctx, section->sh_addr);
16827
16828 fail:
16829 free (data);
16830 return ret;
16831}
16832
015dc7e1 16833static bool
dda8d76d
NC
16834load_specific_debug_section (enum dwarf_section_display_enum debug,
16835 const Elf_Internal_Shdr * sec,
16836 void * data)
1007acb3 16837{
2cf0635d 16838 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16839 char buf [64];
dda8d76d 16840 Filedata * filedata = (Filedata *) data;
9abca702 16841
19e6b90e 16842 if (section->start != NULL)
dda8d76d
NC
16843 {
16844 /* If it is already loaded, do nothing. */
16845 if (streq (section->filename, filedata->file_name))
015dc7e1 16846 return true;
dda8d76d
NC
16847 free (section->start);
16848 }
1007acb3 16849
19e6b90e
L
16850 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16851 section->address = sec->sh_addr;
dda8d76d
NC
16852 section->filename = filedata->file_name;
16853 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16854 sec->sh_offset, 1,
16855 sec->sh_size, buf);
59245841
NC
16856 if (section->start == NULL)
16857 section->size = 0;
16858 else
16859 {
77115a4a 16860 unsigned char *start = section->start;
31e5a3a3
AM
16861 uint64_t size = sec->sh_size;
16862 uint64_t uncompressed_size = 0;
1f5a3546 16863 bool is_zstd = false;
77115a4a
L
16864
16865 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16866 {
16867 Elf_Internal_Chdr chdr;
d8024a91
NC
16868 unsigned int compression_header_size;
16869
f53be977
L
16870 if (size < (is_32bit_elf
16871 ? sizeof (Elf32_External_Chdr)
16872 : sizeof (Elf64_External_Chdr)))
d8024a91 16873 {
55be8fd0 16874 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16875 section->name);
015dc7e1 16876 return false;
d8024a91
NC
16877 }
16878
ebdf1ebf 16879 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16880 if (compression_header_size == 0)
16881 /* An error message will have already been generated
16882 by get_compression_header. */
015dc7e1 16883 return false;
d8024a91 16884
89dbeac7 16885 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16886 ;
16887#ifdef HAVE_ZSTD
89dbeac7 16888 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16889 is_zstd = true;
16890#endif
16891 else
813dabb9
L
16892 {
16893 warn (_("section '%s' has unsupported compress type: %d\n"),
16894 section->name, chdr.ch_type);
015dc7e1 16895 return false;
813dabb9 16896 }
dab394de 16897 uncompressed_size = chdr.ch_size;
77115a4a
L
16898 start += compression_header_size;
16899 size -= compression_header_size;
16900 }
dab394de
L
16901 else if (size > 12 && streq ((char *) start, "ZLIB"))
16902 {
16903 /* Read the zlib header. In this case, it should be "ZLIB"
16904 followed by the uncompressed section size, 8 bytes in
16905 big-endian order. */
16906 uncompressed_size = start[4]; uncompressed_size <<= 8;
16907 uncompressed_size += start[5]; uncompressed_size <<= 8;
16908 uncompressed_size += start[6]; uncompressed_size <<= 8;
16909 uncompressed_size += start[7]; uncompressed_size <<= 8;
16910 uncompressed_size += start[8]; uncompressed_size <<= 8;
16911 uncompressed_size += start[9]; uncompressed_size <<= 8;
16912 uncompressed_size += start[10]; uncompressed_size <<= 8;
16913 uncompressed_size += start[11];
16914 start += 12;
16915 size -= 12;
16916 }
16917
1835f746 16918 if (uncompressed_size)
77115a4a 16919 {
1f5a3546 16920 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16921 &size, filedata->file_size))
1835f746
NC
16922 {
16923 /* Free the compressed buffer, update the section buffer
16924 and the section size if uncompress is successful. */
16925 free (section->start);
16926 section->start = start;
16927 }
16928 else
16929 {
16930 error (_("Unable to decompress section %s\n"),
dda8d76d 16931 printable_section_name (filedata, sec));
015dc7e1 16932 return false;
1835f746 16933 }
77115a4a 16934 }
bc303e5d 16935
77115a4a 16936 section->size = size;
59245841 16937 }
4a114e3e 16938
1b315056 16939 if (section->start == NULL)
015dc7e1 16940 return false;
1b315056 16941
19e6b90e 16942 if (debug_displays [debug].relocate)
32ec8896 16943 {
dda8d76d 16944 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16945 & section->reloc_info, & section->num_relocs))
015dc7e1 16946 return false;
32ec8896 16947 }
d1c4b12b
NC
16948 else
16949 {
16950 section->reloc_info = NULL;
16951 section->num_relocs = 0;
16952 }
1007acb3 16953
015dc7e1 16954 return true;
1007acb3
L
16955}
16956
301a9420
AM
16957#if HAVE_LIBDEBUGINFOD
16958/* Return a hex string representation of the build-id. */
16959unsigned char *
16960get_build_id (void * data)
16961{
ca0e11aa 16962 Filedata * filedata = (Filedata *) data;
301a9420 16963 Elf_Internal_Shdr * shdr;
26c527e6 16964 size_t i;
301a9420 16965
55be8fd0
NC
16966 /* Iterate through notes to find note.gnu.build-id.
16967 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16968 for (i = 0, shdr = filedata->section_headers;
16969 i < filedata->file_header.e_shnum && shdr != NULL;
16970 i++, shdr++)
16971 {
16972 if (shdr->sh_type != SHT_NOTE)
16973 continue;
16974
16975 char * next;
16976 char * end;
16977 size_t data_remaining;
16978 size_t min_notesz;
16979 Elf_External_Note * enote;
16980 Elf_Internal_Note inote;
16981
625d49fc
AM
16982 uint64_t offset = shdr->sh_offset;
16983 uint64_t align = shdr->sh_addralign;
16984 uint64_t length = shdr->sh_size;
301a9420
AM
16985
16986 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16987 if (enote == NULL)
16988 continue;
16989
16990 if (align < 4)
16991 align = 4;
16992 else if (align != 4 && align != 8)
f761cb13
AM
16993 {
16994 free (enote);
16995 continue;
16996 }
301a9420
AM
16997
16998 end = (char *) enote + length;
16999 data_remaining = end - (char *) enote;
17000
17001 if (!is_ia64_vms (filedata))
17002 {
17003 min_notesz = offsetof (Elf_External_Note, name);
17004 if (data_remaining < min_notesz)
17005 {
55be8fd0
NC
17006 warn (_("\
17007malformed note encountered in section %s whilst scanning for build-id note\n"),
17008 printable_section_name (filedata, shdr));
f761cb13 17009 free (enote);
55be8fd0 17010 continue;
301a9420
AM
17011 }
17012 data_remaining -= min_notesz;
17013
17014 inote.type = BYTE_GET (enote->type);
17015 inote.namesz = BYTE_GET (enote->namesz);
17016 inote.namedata = enote->name;
17017 inote.descsz = BYTE_GET (enote->descsz);
17018 inote.descdata = ((char *) enote
17019 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17020 inote.descpos = offset + (inote.descdata - (char *) enote);
17021 next = ((char *) enote
17022 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17023 }
17024 else
17025 {
17026 Elf64_External_VMS_Note *vms_enote;
17027
17028 /* PR binutils/15191
17029 Make sure that there is enough data to read. */
17030 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17031 if (data_remaining < min_notesz)
17032 {
55be8fd0
NC
17033 warn (_("\
17034malformed note encountered in section %s whilst scanning for build-id note\n"),
17035 printable_section_name (filedata, shdr));
f761cb13 17036 free (enote);
55be8fd0 17037 continue;
301a9420
AM
17038 }
17039 data_remaining -= min_notesz;
17040
17041 vms_enote = (Elf64_External_VMS_Note *) enote;
17042 inote.type = BYTE_GET (vms_enote->type);
17043 inote.namesz = BYTE_GET (vms_enote->namesz);
17044 inote.namedata = vms_enote->name;
17045 inote.descsz = BYTE_GET (vms_enote->descsz);
17046 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17047 inote.descpos = offset + (inote.descdata - (char *) enote);
17048 next = inote.descdata + align_power (inote.descsz, 3);
17049 }
17050
17051 /* Skip malformed notes. */
17052 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17053 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17054 || (size_t) (next - inote.descdata) < inote.descsz
17055 || ((size_t) (next - inote.descdata)
17056 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17057 {
55be8fd0
NC
17058 warn (_("\
17059malformed note encountered in section %s whilst scanning for build-id note\n"),
17060 printable_section_name (filedata, shdr));
f761cb13 17061 free (enote);
301a9420
AM
17062 continue;
17063 }
17064
17065 /* Check if this is the build-id note. If so then convert the build-id
17066 bytes to a hex string. */
17067 if (inote.namesz > 0
24d127aa 17068 && startswith (inote.namedata, "GNU")
301a9420
AM
17069 && inote.type == NT_GNU_BUILD_ID)
17070 {
26c527e6 17071 size_t j;
301a9420
AM
17072 char * build_id;
17073
17074 build_id = malloc (inote.descsz * 2 + 1);
17075 if (build_id == NULL)
f761cb13
AM
17076 {
17077 free (enote);
17078 return NULL;
17079 }
301a9420
AM
17080
17081 for (j = 0; j < inote.descsz; ++j)
17082 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17083 build_id[inote.descsz * 2] = '\0';
f761cb13 17084 free (enote);
301a9420 17085
55be8fd0 17086 return (unsigned char *) build_id;
301a9420 17087 }
f761cb13 17088 free (enote);
301a9420
AM
17089 }
17090
17091 return NULL;
17092}
17093#endif /* HAVE_LIBDEBUGINFOD */
17094
657d0d47
CC
17095/* If this is not NULL, load_debug_section will only look for sections
17096 within the list of sections given here. */
32ec8896 17097static unsigned int * section_subset = NULL;
657d0d47 17098
015dc7e1 17099bool
dda8d76d 17100load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 17101{
2cf0635d
NC
17102 struct dwarf_section * section = &debug_displays [debug].section;
17103 Elf_Internal_Shdr * sec;
dda8d76d
NC
17104 Filedata * filedata = (Filedata *) data;
17105
e1dbfc17
L
17106 if (!dump_any_debugging)
17107 return false;
17108
f425ec66
NC
17109 /* Without section headers we cannot find any sections. */
17110 if (filedata->section_headers == NULL)
015dc7e1 17111 return false;
f425ec66 17112
9c1ce108
AM
17113 if (filedata->string_table == NULL
17114 && filedata->file_header.e_shstrndx != SHN_UNDEF
17115 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
17116 {
17117 Elf_Internal_Shdr * strs;
17118
17119 /* Read in the string table, so that we have section names to scan. */
17120 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17121
4dff97b2 17122 if (strs != NULL && strs->sh_size != 0)
dda8d76d 17123 {
9c1ce108
AM
17124 filedata->string_table
17125 = (char *) get_data (NULL, filedata, strs->sh_offset,
17126 1, strs->sh_size, _("string table"));
dda8d76d 17127
9c1ce108
AM
17128 filedata->string_table_length
17129 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
17130 }
17131 }
d966045b
DJ
17132
17133 /* Locate the debug section. */
dda8d76d 17134 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
17135 if (sec != NULL)
17136 section->name = section->uncompressed_name;
17137 else
17138 {
dda8d76d 17139 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
17140 if (sec != NULL)
17141 section->name = section->compressed_name;
17142 }
17143 if (sec == NULL)
015dc7e1 17144 return false;
d966045b 17145
657d0d47
CC
17146 /* If we're loading from a subset of sections, and we've loaded
17147 a section matching this name before, it's likely that it's a
17148 different one. */
17149 if (section_subset != NULL)
17150 free_debug_section (debug);
17151
dda8d76d 17152 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
17153}
17154
19e6b90e
L
17155void
17156free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 17157{
2cf0635d 17158 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 17159
19e6b90e
L
17160 if (section->start == NULL)
17161 return;
1007acb3 17162
19e6b90e
L
17163 free ((char *) section->start);
17164 section->start = NULL;
17165 section->address = 0;
17166 section->size = 0;
a788aedd 17167
9db70fc3
AM
17168 free (section->reloc_info);
17169 section->reloc_info = NULL;
17170 section->num_relocs = 0;
1007acb3
L
17171}
17172
015dc7e1 17173static bool
dda8d76d 17174display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 17175{
84714f86
AM
17176 const char *name = (section_name_valid (filedata, section)
17177 ? section_name (filedata, section) : "");
17178 const char *print_name = printable_section_name (filedata, section);
be7d229a 17179 uint64_t length;
015dc7e1 17180 bool result = true;
3f5e193b 17181 int i;
1007acb3 17182
19e6b90e
L
17183 length = section->sh_size;
17184 if (length == 0)
1007acb3 17185 {
74e1a04b 17186 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 17187 return true;
1007acb3 17188 }
5dff79d8
NC
17189 if (section->sh_type == SHT_NOBITS)
17190 {
17191 /* There is no point in dumping the contents of a debugging section
17192 which has the NOBITS type - the bits in the file will be random.
17193 This can happen when a file containing a .eh_frame section is
17194 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
17195 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17196 print_name);
015dc7e1 17197 return false;
5dff79d8 17198 }
1007acb3 17199
24d127aa 17200 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 17201 name = ".debug_info";
1007acb3 17202
19e6b90e
L
17203 /* See if we know how to display the contents of this section. */
17204 for (i = 0; i < max; i++)
d85bf2ba
NC
17205 {
17206 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17207 struct dwarf_section_display * display = debug_displays + i;
17208 struct dwarf_section * sec = & display->section;
d966045b 17209
d85bf2ba 17210 if (streq (sec->uncompressed_name, name)
24d127aa 17211 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17212 || streq (sec->compressed_name, name))
17213 {
015dc7e1 17214 bool secondary = (section != find_section (filedata, name));
1007acb3 17215
d85bf2ba
NC
17216 if (secondary)
17217 free_debug_section (id);
dda8d76d 17218
24d127aa 17219 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17220 sec->name = name;
17221 else if (streq (sec->uncompressed_name, name))
17222 sec->name = sec->uncompressed_name;
17223 else
17224 sec->name = sec->compressed_name;
657d0d47 17225
d85bf2ba
NC
17226 if (load_specific_debug_section (id, section, filedata))
17227 {
17228 /* If this debug section is part of a CU/TU set in a .dwp file,
17229 restrict load_debug_section to the sections in that set. */
17230 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17231
d85bf2ba 17232 result &= display->display (sec, filedata);
657d0d47 17233
d85bf2ba 17234 section_subset = NULL;
1007acb3 17235
44266f36 17236 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17237 free_debug_section (id);
17238 }
17239 break;
17240 }
17241 }
1007acb3 17242
19e6b90e 17243 if (i == max)
1007acb3 17244 {
74e1a04b 17245 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17246 result = false;
1007acb3
L
17247 }
17248
19e6b90e 17249 return result;
5b18a4bc 17250}
103f02d3 17251
aef1f6d0
DJ
17252/* Set DUMP_SECTS for all sections where dumps were requested
17253 based on section name. */
17254
17255static void
dda8d76d 17256initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17257{
2cf0635d 17258 struct dump_list_entry * cur;
aef1f6d0
DJ
17259
17260 for (cur = dump_sects_byname; cur; cur = cur->next)
17261 {
17262 unsigned int i;
015dc7e1 17263 bool any = false;
aef1f6d0 17264
dda8d76d 17265 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17266 if (section_name_valid (filedata, filedata->section_headers + i)
17267 && streq (section_name (filedata, filedata->section_headers + i),
17268 cur->name))
aef1f6d0 17269 {
6431e409 17270 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17271 any = true;
aef1f6d0
DJ
17272 }
17273
835f2fae
NC
17274 if (!any && !filedata->is_separate)
17275 warn (_("Section '%s' was not dumped because it does not exist\n"),
17276 cur->name);
aef1f6d0
DJ
17277 }
17278}
17279
015dc7e1 17280static bool
dda8d76d 17281process_section_contents (Filedata * filedata)
5b18a4bc 17282{
2cf0635d 17283 Elf_Internal_Shdr * section;
19e6b90e 17284 unsigned int i;
015dc7e1 17285 bool res = true;
103f02d3 17286
19e6b90e 17287 if (! do_dump)
015dc7e1 17288 return true;
103f02d3 17289
dda8d76d 17290 initialise_dumps_byname (filedata);
aef1f6d0 17291
dda8d76d 17292 for (i = 0, section = filedata->section_headers;
6431e409 17293 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17294 i++, section++)
17295 {
6431e409 17296 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17297
d6bfbc39
NC
17298 if (filedata->is_separate && ! process_links)
17299 dump &= DEBUG_DUMP;
047c3dbf 17300
8e8d0b63
NC
17301 if (dump & AUTO_DUMP)
17302 {
17303 switch (section->sh_type)
17304 {
17305 case SHT_PROGBITS:
17306 /* FIXME: There are lots of different type of section that have
17307 SHT_PROGBITS set in their header - code, debug info, etc. So
17308 we should check the section's name and interpret its contents
17309 that way, rather than just defaulting to a byte dump. */
17310#ifdef SUPPORT_DISASSEMBLY
17311 res &= disassemble_section (section, filedata);
17312#else
17313 res &= dump_section_as_bytes (section, filedata, false);
17314#endif
17315 break;
17316
17317 case SHT_DYNSYM:
17318 case SHT_SYMTAB:
17319 res &= dump_symbol_section (section, filedata);
17320 break;
17321
17322 case SHT_STRTAB:
17323 res &= dump_section_as_strings (section, filedata);
17324 break;
17325
17326 case SHT_RELA:
17327 case SHT_REL:
17328 case SHT_RELR:
17329 res &= display_relocations (section, filedata);
17330 break;
17331
17332 case SHT_NOTE:
17333 res &= process_notes_at (filedata, section, section->sh_offset,
17334 section->sh_size, section->sh_addralign);
17335 break;
17336
17337 case SHT_NULL:
17338 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17339 break;
17340
17341 case SHT_NOBITS:
17342 inform (_("Unable to display section %d - it has no contents\n"), i);
17343 break;
17344
17345 case SHT_HASH:
17346 case SHT_DYNAMIC:
17347 case SHT_GROUP:
17348 case SHT_GNU_ATTRIBUTES:
17349 /* FIXME: Implement these. */
17350 /* Fall through. */
17351 default:
17352 /* FIXME: Add Proc and OS specific section types ? */
17353 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17354 i, section->sh_type);
17355 res = false;
17356 break;
17357 }
17358 }
17359
19e6b90e 17360#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17361 if (dump & DISASS_DUMP)
17362 {
17363 if (! disassemble_section (section, filedata))
015dc7e1 17364 res = false;
dda8d76d 17365 }
19e6b90e 17366#endif
dda8d76d 17367 if (dump & HEX_DUMP)
32ec8896 17368 {
015dc7e1
AM
17369 if (! dump_section_as_bytes (section, filedata, false))
17370 res = false;
32ec8896 17371 }
103f02d3 17372
dda8d76d 17373 if (dump & RELOC_DUMP)
32ec8896 17374 {
015dc7e1
AM
17375 if (! dump_section_as_bytes (section, filedata, true))
17376 res = false;
32ec8896 17377 }
09c11c86 17378
dda8d76d 17379 if (dump & STRING_DUMP)
32ec8896 17380 {
dda8d76d 17381 if (! dump_section_as_strings (section, filedata))
015dc7e1 17382 res = false;
32ec8896 17383 }
cf13d699 17384
dda8d76d 17385 if (dump & DEBUG_DUMP)
32ec8896 17386 {
dda8d76d 17387 if (! display_debug_section (i, section, filedata))
015dc7e1 17388 res = false;
32ec8896 17389 }
7d9813f1 17390
094e34f2 17391#ifdef ENABLE_LIBCTF
7d9813f1
NA
17392 if (dump & CTF_DUMP)
17393 {
17394 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17395 res = false;
7d9813f1 17396 }
094e34f2 17397#endif
42b6953b
IB
17398 if (dump & SFRAME_DUMP)
17399 {
17400 if (! dump_section_as_sframe (section, filedata))
17401 res = false;
17402 }
5b18a4bc 17403 }
103f02d3 17404
835f2fae 17405 if (! filedata->is_separate)
0ee3043f 17406 {
835f2fae
NC
17407 /* Check to see if the user requested a
17408 dump of a section that does not exist. */
17409 for (; i < filedata->dump.num_dump_sects; i++)
17410 if (filedata->dump.dump_sects[i])
17411 {
ca0e11aa 17412 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17413 res = false;
835f2fae 17414 }
0ee3043f 17415 }
32ec8896
NC
17416
17417 return res;
5b18a4bc 17418}
103f02d3 17419
5b18a4bc 17420static void
19e6b90e 17421process_mips_fpe_exception (int mask)
5b18a4bc 17422{
19e6b90e
L
17423 if (mask)
17424 {
015dc7e1 17425 bool first = true;
32ec8896 17426
19e6b90e 17427 if (mask & OEX_FPU_INEX)
015dc7e1 17428 fputs ("INEX", stdout), first = false;
19e6b90e 17429 if (mask & OEX_FPU_UFLO)
015dc7e1 17430 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17431 if (mask & OEX_FPU_OFLO)
015dc7e1 17432 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17433 if (mask & OEX_FPU_DIV0)
015dc7e1 17434 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17435 if (mask & OEX_FPU_INVAL)
17436 printf ("%sINVAL", first ? "" : "|");
17437 }
5b18a4bc 17438 else
19e6b90e 17439 fputs ("0", stdout);
5b18a4bc 17440}
103f02d3 17441
f6f0e17b
NC
17442/* Display's the value of TAG at location P. If TAG is
17443 greater than 0 it is assumed to be an unknown tag, and
17444 a message is printed to this effect. Otherwise it is
17445 assumed that a message has already been printed.
17446
17447 If the bottom bit of TAG is set it assumed to have a
17448 string value, otherwise it is assumed to have an integer
17449 value.
17450
17451 Returns an updated P pointing to the first unread byte
17452 beyond the end of TAG's value.
17453
17454 Reads at or beyond END will not be made. */
17455
17456static unsigned char *
60abdbed 17457display_tag_value (signed int tag,
f6f0e17b
NC
17458 unsigned char * p,
17459 const unsigned char * const end)
17460{
26c527e6 17461 uint64_t val;
f6f0e17b
NC
17462
17463 if (tag > 0)
17464 printf (" Tag_unknown_%d: ", tag);
17465
17466 if (p >= end)
17467 {
4082ef84 17468 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17469 }
17470 else if (tag & 1)
17471 {
071436c6
NC
17472 /* PR 17531 file: 027-19978-0.004. */
17473 size_t maxlen = (end - p) - 1;
17474
17475 putchar ('"');
4082ef84
NC
17476 if (maxlen > 0)
17477 {
b6ac461a 17478 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17479 p += strnlen ((char *) p, maxlen) + 1;
17480 }
17481 else
17482 {
17483 printf (_("<corrupt string tag>"));
17484 p = (unsigned char *) end;
17485 }
071436c6 17486 printf ("\"\n");
f6f0e17b
NC
17487 }
17488 else
17489 {
cd30bcef 17490 READ_ULEB (val, p, end);
26c527e6 17491 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17492 }
17493
4082ef84 17494 assert (p <= end);
f6f0e17b
NC
17495 return p;
17496}
17497
53a346d8
CZ
17498/* ARC ABI attributes section. */
17499
17500static unsigned char *
17501display_arc_attribute (unsigned char * p,
17502 const unsigned char * const end)
17503{
17504 unsigned int tag;
53a346d8
CZ
17505 unsigned int val;
17506
cd30bcef 17507 READ_ULEB (tag, p, end);
53a346d8
CZ
17508
17509 switch (tag)
17510 {
17511 case Tag_ARC_PCS_config:
cd30bcef 17512 READ_ULEB (val, p, end);
53a346d8
CZ
17513 printf (" Tag_ARC_PCS_config: ");
17514 switch (val)
17515 {
17516 case 0:
17517 printf (_("Absent/Non standard\n"));
17518 break;
17519 case 1:
17520 printf (_("Bare metal/mwdt\n"));
17521 break;
17522 case 2:
17523 printf (_("Bare metal/newlib\n"));
17524 break;
17525 case 3:
17526 printf (_("Linux/uclibc\n"));
17527 break;
17528 case 4:
17529 printf (_("Linux/glibc\n"));
17530 break;
17531 default:
17532 printf (_("Unknown\n"));
17533 break;
17534 }
17535 break;
17536
17537 case Tag_ARC_CPU_base:
cd30bcef 17538 READ_ULEB (val, p, end);
53a346d8
CZ
17539 printf (" Tag_ARC_CPU_base: ");
17540 switch (val)
17541 {
17542 default:
17543 case TAG_CPU_NONE:
17544 printf (_("Absent\n"));
17545 break;
17546 case TAG_CPU_ARC6xx:
17547 printf ("ARC6xx\n");
17548 break;
17549 case TAG_CPU_ARC7xx:
17550 printf ("ARC7xx\n");
17551 break;
17552 case TAG_CPU_ARCEM:
17553 printf ("ARCEM\n");
17554 break;
17555 case TAG_CPU_ARCHS:
17556 printf ("ARCHS\n");
17557 break;
17558 }
17559 break;
17560
17561 case Tag_ARC_CPU_variation:
cd30bcef 17562 READ_ULEB (val, p, end);
53a346d8
CZ
17563 printf (" Tag_ARC_CPU_variation: ");
17564 switch (val)
17565 {
17566 default:
17567 if (val > 0 && val < 16)
53a346d8 17568 printf ("Core%d\n", val);
d8cbc93b
JL
17569 else
17570 printf ("Unknown\n");
17571 break;
17572
53a346d8
CZ
17573 case 0:
17574 printf (_("Absent\n"));
17575 break;
17576 }
17577 break;
17578
17579 case Tag_ARC_CPU_name:
17580 printf (" Tag_ARC_CPU_name: ");
17581 p = display_tag_value (-1, p, end);
17582 break;
17583
17584 case Tag_ARC_ABI_rf16:
cd30bcef 17585 READ_ULEB (val, p, end);
53a346d8
CZ
17586 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17587 break;
17588
17589 case Tag_ARC_ABI_osver:
cd30bcef 17590 READ_ULEB (val, p, end);
53a346d8
CZ
17591 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17592 break;
17593
17594 case Tag_ARC_ABI_pic:
17595 case Tag_ARC_ABI_sda:
cd30bcef 17596 READ_ULEB (val, p, end);
53a346d8
CZ
17597 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17598 : " Tag_ARC_ABI_pic: ");
17599 switch (val)
17600 {
17601 case 0:
17602 printf (_("Absent\n"));
17603 break;
17604 case 1:
17605 printf ("MWDT\n");
17606 break;
17607 case 2:
17608 printf ("GNU\n");
17609 break;
17610 default:
17611 printf (_("Unknown\n"));
17612 break;
17613 }
17614 break;
17615
17616 case Tag_ARC_ABI_tls:
cd30bcef 17617 READ_ULEB (val, p, end);
53a346d8
CZ
17618 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17619 break;
17620
17621 case Tag_ARC_ABI_enumsize:
cd30bcef 17622 READ_ULEB (val, p, end);
53a346d8
CZ
17623 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17624 _("smallest"));
17625 break;
17626
17627 case Tag_ARC_ABI_exceptions:
cd30bcef 17628 READ_ULEB (val, p, end);
53a346d8
CZ
17629 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17630 : _("default"));
17631 break;
17632
17633 case Tag_ARC_ABI_double_size:
cd30bcef 17634 READ_ULEB (val, p, end);
53a346d8
CZ
17635 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17636 break;
17637
17638 case Tag_ARC_ISA_config:
17639 printf (" Tag_ARC_ISA_config: ");
17640 p = display_tag_value (-1, p, end);
17641 break;
17642
17643 case Tag_ARC_ISA_apex:
17644 printf (" Tag_ARC_ISA_apex: ");
17645 p = display_tag_value (-1, p, end);
17646 break;
17647
17648 case Tag_ARC_ISA_mpy_option:
cd30bcef 17649 READ_ULEB (val, p, end);
53a346d8
CZ
17650 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17651 break;
17652
db1e1b45 17653 case Tag_ARC_ATR_version:
cd30bcef 17654 READ_ULEB (val, p, end);
db1e1b45 17655 printf (" Tag_ARC_ATR_version: %d\n", val);
17656 break;
17657
53a346d8
CZ
17658 default:
17659 return display_tag_value (tag & 1, p, end);
17660 }
17661
17662 return p;
17663}
17664
11c1ff18
PB
17665/* ARM EABI attributes section. */
17666typedef struct
17667{
70e99720 17668 unsigned int tag;
2cf0635d 17669 const char * name;
11c1ff18 17670 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17671 unsigned int type;
288f0ba2 17672 const char *const *table;
11c1ff18
PB
17673} arm_attr_public_tag;
17674
288f0ba2 17675static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17676 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17677 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17678 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17679 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17680static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17681static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17682 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17683static const char *const arm_attr_tag_FP_arch[] =
bca38921 17684 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17685 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17686static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17687static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17688 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17689 "NEON for ARMv8.1"};
288f0ba2 17690static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17691 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17692 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17693static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17694 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17695static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17696 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17697static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17698 {"Absolute", "PC-relative", "None"};
288f0ba2 17699static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17700 {"None", "direct", "GOT-indirect"};
288f0ba2 17701static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17702 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17703static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17704static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17705 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17706static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17707static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17708static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17709 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17710static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17711 {"Unused", "small", "int", "forced to int"};
288f0ba2 17712static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17713 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17714static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17715 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17716static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17717 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17718static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17719 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17720 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17721static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17722 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17723 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17724static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17725static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17726 {"Not Allowed", "Allowed"};
288f0ba2 17727static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17728 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17729static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17730 {"Follow architecture", "Allowed"};
288f0ba2 17731static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17732 {"Not Allowed", "Allowed"};
288f0ba2 17733static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17734 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17735 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17736static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17737static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17738 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17739 "TrustZone and Virtualization Extensions"};
288f0ba2 17740static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17741 {"Not Allowed", "Allowed"};
11c1ff18 17742
288f0ba2 17743static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17744 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17745
99db83d0
AC
17746static const char * arm_attr_tag_PAC_extension[] =
17747 {"No PAC/AUT instructions",
17748 "PAC/AUT instructions permitted in the NOP space",
17749 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17750
4b535030
AC
17751static const char * arm_attr_tag_BTI_extension[] =
17752 {"BTI instructions not permitted",
17753 "BTI instructions permitted in the NOP space",
17754 "BTI instructions permitted in the NOP and in the non-NOP space"};
17755
b81ee92f
AC
17756static const char * arm_attr_tag_BTI_use[] =
17757 {"Compiled without branch target enforcement",
17758 "Compiled with branch target enforcement"};
17759
c9fed665
AC
17760static const char * arm_attr_tag_PACRET_use[] =
17761 {"Compiled without return address signing and authentication",
17762 "Compiled with return address signing and authentication"};
17763
11c1ff18
PB
17764#define LOOKUP(id, name) \
17765 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17766static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17767{
17768 {4, "CPU_raw_name", 1, NULL},
17769 {5, "CPU_name", 1, NULL},
17770 LOOKUP(6, CPU_arch),
17771 {7, "CPU_arch_profile", 0, NULL},
17772 LOOKUP(8, ARM_ISA_use),
17773 LOOKUP(9, THUMB_ISA_use),
75375b3e 17774 LOOKUP(10, FP_arch),
11c1ff18 17775 LOOKUP(11, WMMX_arch),
f5f53991
AS
17776 LOOKUP(12, Advanced_SIMD_arch),
17777 LOOKUP(13, PCS_config),
11c1ff18
PB
17778 LOOKUP(14, ABI_PCS_R9_use),
17779 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17780 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17781 LOOKUP(17, ABI_PCS_GOT_use),
17782 LOOKUP(18, ABI_PCS_wchar_t),
17783 LOOKUP(19, ABI_FP_rounding),
17784 LOOKUP(20, ABI_FP_denormal),
17785 LOOKUP(21, ABI_FP_exceptions),
17786 LOOKUP(22, ABI_FP_user_exceptions),
17787 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17788 {24, "ABI_align_needed", 0, NULL},
17789 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17790 LOOKUP(26, ABI_enum_size),
17791 LOOKUP(27, ABI_HardFP_use),
17792 LOOKUP(28, ABI_VFP_args),
17793 LOOKUP(29, ABI_WMMX_args),
17794 LOOKUP(30, ABI_optimization_goals),
17795 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17796 {32, "compatibility", 0, NULL},
f5f53991 17797 LOOKUP(34, CPU_unaligned_access),
75375b3e 17798 LOOKUP(36, FP_HP_extension),
8e79c3df 17799 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17800 LOOKUP(42, MPextension_use),
17801 LOOKUP(44, DIV_use),
15afaa63 17802 LOOKUP(46, DSP_extension),
a7ad558c 17803 LOOKUP(48, MVE_arch),
99db83d0 17804 LOOKUP(50, PAC_extension),
4b535030 17805 LOOKUP(52, BTI_extension),
b81ee92f 17806 LOOKUP(74, BTI_use),
c9fed665 17807 LOOKUP(76, PACRET_use),
f5f53991
AS
17808 {64, "nodefaults", 0, NULL},
17809 {65, "also_compatible_with", 0, NULL},
17810 LOOKUP(66, T2EE_use),
17811 {67, "conformance", 1, NULL},
17812 LOOKUP(68, Virtualization_use),
cd21e546 17813 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17814};
17815#undef LOOKUP
17816
11c1ff18 17817static unsigned char *
f6f0e17b
NC
17818display_arm_attribute (unsigned char * p,
17819 const unsigned char * const end)
11c1ff18 17820{
70e99720 17821 unsigned int tag;
70e99720 17822 unsigned int val;
2cf0635d 17823 arm_attr_public_tag * attr;
11c1ff18 17824 unsigned i;
70e99720 17825 unsigned int type;
11c1ff18 17826
cd30bcef 17827 READ_ULEB (tag, p, end);
11c1ff18 17828 attr = NULL;
2cf0635d 17829 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17830 {
17831 if (arm_attr_public_tags[i].tag == tag)
17832 {
17833 attr = &arm_attr_public_tags[i];
17834 break;
17835 }
17836 }
17837
17838 if (attr)
17839 {
17840 printf (" Tag_%s: ", attr->name);
17841 switch (attr->type)
17842 {
17843 case 0:
17844 switch (tag)
17845 {
17846 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17847 READ_ULEB (val, p, end);
11c1ff18
PB
17848 switch (val)
17849 {
2b692964
NC
17850 case 0: printf (_("None\n")); break;
17851 case 'A': printf (_("Application\n")); break;
17852 case 'R': printf (_("Realtime\n")); break;
17853 case 'M': printf (_("Microcontroller\n")); break;
17854 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17855 default: printf ("??? (%d)\n", val); break;
17856 }
17857 break;
17858
75375b3e 17859 case 24: /* Tag_align_needed. */
cd30bcef 17860 READ_ULEB (val, p, end);
75375b3e
MGD
17861 switch (val)
17862 {
2b692964
NC
17863 case 0: printf (_("None\n")); break;
17864 case 1: printf (_("8-byte\n")); break;
17865 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17866 case 3: printf ("??? 3\n"); break;
17867 default:
17868 if (val <= 12)
dd24e3da 17869 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17870 1 << val);
17871 else
17872 printf ("??? (%d)\n", val);
17873 break;
17874 }
17875 break;
17876
17877 case 25: /* Tag_align_preserved. */
cd30bcef 17878 READ_ULEB (val, p, end);
75375b3e
MGD
17879 switch (val)
17880 {
2b692964
NC
17881 case 0: printf (_("None\n")); break;
17882 case 1: printf (_("8-byte, except leaf SP\n")); break;
17883 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17884 case 3: printf ("??? 3\n"); break;
17885 default:
17886 if (val <= 12)
dd24e3da 17887 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17888 1 << val);
17889 else
17890 printf ("??? (%d)\n", val);
17891 break;
17892 }
17893 break;
17894
11c1ff18 17895 case 32: /* Tag_compatibility. */
071436c6 17896 {
cd30bcef 17897 READ_ULEB (val, p, end);
071436c6 17898 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17899 if (p < end - 1)
17900 {
17901 size_t maxlen = (end - p) - 1;
17902
b6ac461a 17903 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17904 p += strnlen ((char *) p, maxlen) + 1;
17905 }
17906 else
17907 {
17908 printf (_("<corrupt>"));
17909 p = (unsigned char *) end;
17910 }
071436c6 17911 putchar ('\n');
071436c6 17912 }
11c1ff18
PB
17913 break;
17914
f5f53991 17915 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17916 /* PR 17531: file: 001-505008-0.01. */
17917 if (p < end)
17918 p++;
2b692964 17919 printf (_("True\n"));
f5f53991
AS
17920 break;
17921
17922 case 65: /* Tag_also_compatible_with. */
cd30bcef 17923 READ_ULEB (val, p, end);
f5f53991
AS
17924 if (val == 6 /* Tag_CPU_arch. */)
17925 {
cd30bcef 17926 READ_ULEB (val, p, end);
071436c6 17927 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17928 printf ("??? (%d)\n", val);
17929 else
17930 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17931 }
17932 else
17933 printf ("???\n");
071436c6
NC
17934 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17935 ;
f5f53991
AS
17936 break;
17937
11c1ff18 17938 default:
bee0ee85
NC
17939 printf (_("<unknown: %d>\n"), tag);
17940 break;
11c1ff18
PB
17941 }
17942 return p;
17943
17944 case 1:
f6f0e17b 17945 return display_tag_value (-1, p, end);
11c1ff18 17946 case 2:
f6f0e17b 17947 return display_tag_value (0, p, end);
11c1ff18
PB
17948
17949 default:
17950 assert (attr->type & 0x80);
cd30bcef 17951 READ_ULEB (val, p, end);
11c1ff18
PB
17952 type = attr->type & 0x7f;
17953 if (val >= type)
17954 printf ("??? (%d)\n", val);
17955 else
17956 printf ("%s\n", attr->table[val]);
17957 return p;
17958 }
17959 }
11c1ff18 17960
f6f0e17b 17961 return display_tag_value (tag, p, end);
11c1ff18
PB
17962}
17963
104d59d1 17964static unsigned char *
60bca95a 17965display_gnu_attribute (unsigned char * p,
8e8d0b63
NC
17966 unsigned char * (* display_proc_gnu_attribute)
17967 (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17968 const unsigned char * const end)
104d59d1 17969{
cd30bcef 17970 unsigned int tag;
60abdbed 17971 unsigned int val;
104d59d1 17972
cd30bcef 17973 READ_ULEB (tag, p, end);
104d59d1
JM
17974
17975 /* Tag_compatibility is the only generic GNU attribute defined at
17976 present. */
17977 if (tag == 32)
17978 {
cd30bcef 17979 READ_ULEB (val, p, end);
071436c6
NC
17980
17981 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17982 if (p == end)
17983 {
071436c6 17984 printf (_("<corrupt>\n"));
f6f0e17b
NC
17985 warn (_("corrupt vendor attribute\n"));
17986 }
17987 else
17988 {
4082ef84
NC
17989 if (p < end - 1)
17990 {
17991 size_t maxlen = (end - p) - 1;
071436c6 17992
b6ac461a 17993 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17994 p += strnlen ((char *) p, maxlen) + 1;
17995 }
17996 else
17997 {
17998 printf (_("<corrupt>"));
17999 p = (unsigned char *) end;
18000 }
071436c6 18001 putchar ('\n');
f6f0e17b 18002 }
104d59d1
JM
18003 return p;
18004 }
18005
18006 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 18007 return display_proc_gnu_attribute (p, tag, end);
104d59d1 18008
f6f0e17b 18009 return display_tag_value (tag, p, end);
104d59d1
JM
18010}
18011
85f7484a
PB
18012static unsigned char *
18013display_m68k_gnu_attribute (unsigned char * p,
18014 unsigned int tag,
18015 const unsigned char * const end)
18016{
18017 unsigned int val;
18018
18019 if (tag == Tag_GNU_M68K_ABI_FP)
18020 {
18021 printf (" Tag_GNU_M68K_ABI_FP: ");
18022 if (p == end)
18023 {
18024 printf (_("<corrupt>\n"));
18025 return p;
18026 }
18027 READ_ULEB (val, p, end);
18028
18029 if (val > 3)
18030 printf ("(%#x), ", val);
18031
18032 switch (val & 3)
18033 {
18034 case 0:
18035 printf (_("unspecified hard/soft float\n"));
18036 break;
18037 case 1:
18038 printf (_("hard float\n"));
18039 break;
18040 case 2:
18041 printf (_("soft float\n"));
18042 break;
18043 }
18044 return p;
18045 }
18046
18047 return display_tag_value (tag & 1, p, end);
18048}
18049
34c8bcba 18050static unsigned char *
f6f0e17b 18051display_power_gnu_attribute (unsigned char * p,
60abdbed 18052 unsigned int tag,
f6f0e17b 18053 const unsigned char * const end)
34c8bcba 18054{
005d79fd 18055 unsigned int val;
34c8bcba
JM
18056
18057 if (tag == Tag_GNU_Power_ABI_FP)
18058 {
34c8bcba 18059 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 18060 if (p == end)
005d79fd
AM
18061 {
18062 printf (_("<corrupt>\n"));
18063 return p;
18064 }
cd30bcef 18065 READ_ULEB (val, p, end);
60bca95a 18066
005d79fd
AM
18067 if (val > 15)
18068 printf ("(%#x), ", val);
18069
18070 switch (val & 3)
34c8bcba
JM
18071 {
18072 case 0:
005d79fd 18073 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
18074 break;
18075 case 1:
005d79fd 18076 printf (_("hard float, "));
34c8bcba
JM
18077 break;
18078 case 2:
005d79fd 18079 printf (_("soft float, "));
34c8bcba 18080 break;
3c7b9897 18081 case 3:
005d79fd 18082 printf (_("single-precision hard float, "));
3c7b9897 18083 break;
005d79fd
AM
18084 }
18085
18086 switch (val & 0xC)
18087 {
18088 case 0:
18089 printf (_("unspecified long double\n"));
18090 break;
18091 case 4:
18092 printf (_("128-bit IBM long double\n"));
18093 break;
18094 case 8:
18095 printf (_("64-bit long double\n"));
18096 break;
18097 case 12:
18098 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
18099 break;
18100 }
18101 return p;
005d79fd 18102 }
34c8bcba 18103
c6e65352
DJ
18104 if (tag == Tag_GNU_Power_ABI_Vector)
18105 {
c6e65352 18106 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 18107 if (p == end)
005d79fd
AM
18108 {
18109 printf (_("<corrupt>\n"));
18110 return p;
18111 }
cd30bcef 18112 READ_ULEB (val, p, end);
005d79fd
AM
18113
18114 if (val > 3)
18115 printf ("(%#x), ", val);
18116
18117 switch (val & 3)
c6e65352
DJ
18118 {
18119 case 0:
005d79fd 18120 printf (_("unspecified\n"));
c6e65352
DJ
18121 break;
18122 case 1:
005d79fd 18123 printf (_("generic\n"));
c6e65352
DJ
18124 break;
18125 case 2:
18126 printf ("AltiVec\n");
18127 break;
18128 case 3:
18129 printf ("SPE\n");
18130 break;
c6e65352
DJ
18131 }
18132 return p;
005d79fd 18133 }
c6e65352 18134
f82e0623
NF
18135 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18136 {
005d79fd 18137 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 18138 if (p == end)
f6f0e17b 18139 {
005d79fd 18140 printf (_("<corrupt>\n"));
f6f0e17b
NC
18141 return p;
18142 }
cd30bcef 18143 READ_ULEB (val, p, end);
0b4362b0 18144
005d79fd
AM
18145 if (val > 2)
18146 printf ("(%#x), ", val);
18147
18148 switch (val & 3)
18149 {
18150 case 0:
18151 printf (_("unspecified\n"));
18152 break;
18153 case 1:
18154 printf ("r3/r4\n");
18155 break;
18156 case 2:
18157 printf (_("memory\n"));
18158 break;
18159 case 3:
18160 printf ("???\n");
18161 break;
18162 }
f82e0623
NF
18163 return p;
18164 }
18165
f6f0e17b 18166 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
18167}
18168
643f7afb
AK
18169static unsigned char *
18170display_s390_gnu_attribute (unsigned char * p,
60abdbed 18171 unsigned int tag,
643f7afb
AK
18172 const unsigned char * const end)
18173{
cd30bcef 18174 unsigned int val;
643f7afb
AK
18175
18176 if (tag == Tag_GNU_S390_ABI_Vector)
18177 {
643f7afb 18178 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 18179 READ_ULEB (val, p, end);
643f7afb
AK
18180
18181 switch (val)
18182 {
18183 case 0:
18184 printf (_("any\n"));
18185 break;
18186 case 1:
18187 printf (_("software\n"));
18188 break;
18189 case 2:
18190 printf (_("hardware\n"));
18191 break;
18192 default:
18193 printf ("??? (%d)\n", val);
18194 break;
18195 }
18196 return p;
18197 }
18198
18199 return display_tag_value (tag & 1, p, end);
18200}
18201
9e8c70f9 18202static void
60abdbed 18203display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
18204{
18205 if (mask)
18206 {
015dc7e1 18207 bool first = true;
071436c6 18208
9e8c70f9 18209 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 18210 fputs ("mul32", stdout), first = false;
9e8c70f9 18211 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 18212 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 18213 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 18214 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 18215 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 18216 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 18217 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 18218 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 18219 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 18220 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 18221 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 18222 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 18223 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 18224 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 18225 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 18226 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 18227 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 18228 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 18229 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 18230 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 18231 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 18232 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 18233 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 18234 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 18235 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 18236 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 18237 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 18238 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 18239 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 18240 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
18241 }
18242 else
071436c6
NC
18243 fputc ('0', stdout);
18244 fputc ('\n', stdout);
9e8c70f9
DM
18245}
18246
3d68f91c 18247static void
60abdbed 18248display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
18249{
18250 if (mask)
18251 {
015dc7e1 18252 bool first = true;
071436c6 18253
3d68f91c 18254 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 18255 fputs ("fjathplus", stdout), first = false;
3d68f91c 18256 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 18257 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 18258 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 18259 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 18260 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 18261 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 18262 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 18263 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 18264 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 18265 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 18266 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 18267 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 18268 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 18269 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 18270 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 18271 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 18272 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 18273 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 18274 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 18275 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
18276 }
18277 else
071436c6
NC
18278 fputc ('0', stdout);
18279 fputc ('\n', stdout);
3d68f91c
JM
18280}
18281
9e8c70f9 18282static unsigned char *
f6f0e17b 18283display_sparc_gnu_attribute (unsigned char * p,
60abdbed 18284 unsigned int tag,
f6f0e17b 18285 const unsigned char * const end)
9e8c70f9 18286{
cd30bcef 18287 unsigned int val;
3d68f91c 18288
9e8c70f9
DM
18289 if (tag == Tag_GNU_Sparc_HWCAPS)
18290 {
cd30bcef 18291 READ_ULEB (val, p, end);
9e8c70f9 18292 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18293 display_sparc_hwcaps (val);
18294 return p;
3d68f91c
JM
18295 }
18296 if (tag == Tag_GNU_Sparc_HWCAPS2)
18297 {
cd30bcef 18298 READ_ULEB (val, p, end);
3d68f91c
JM
18299 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18300 display_sparc_hwcaps2 (val);
18301 return p;
18302 }
9e8c70f9 18303
f6f0e17b 18304 return display_tag_value (tag, p, end);
9e8c70f9
DM
18305}
18306
351cdf24 18307static void
32ec8896 18308print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18309{
18310 switch (val)
18311 {
18312 case Val_GNU_MIPS_ABI_FP_ANY:
18313 printf (_("Hard or soft float\n"));
18314 break;
18315 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18316 printf (_("Hard float (double precision)\n"));
18317 break;
18318 case Val_GNU_MIPS_ABI_FP_SINGLE:
18319 printf (_("Hard float (single precision)\n"));
18320 break;
18321 case Val_GNU_MIPS_ABI_FP_SOFT:
18322 printf (_("Soft float\n"));
18323 break;
18324 case Val_GNU_MIPS_ABI_FP_OLD_64:
18325 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18326 break;
18327 case Val_GNU_MIPS_ABI_FP_XX:
18328 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18329 break;
18330 case Val_GNU_MIPS_ABI_FP_64:
18331 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18332 break;
18333 case Val_GNU_MIPS_ABI_FP_64A:
18334 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18335 break;
3350cc01
CM
18336 case Val_GNU_MIPS_ABI_FP_NAN2008:
18337 printf (_("NaN 2008 compatibility\n"));
18338 break;
351cdf24
MF
18339 default:
18340 printf ("??? (%d)\n", val);
18341 break;
18342 }
18343}
18344
2cf19d5c 18345static unsigned char *
f6f0e17b 18346display_mips_gnu_attribute (unsigned char * p,
60abdbed 18347 unsigned int tag,
f6f0e17b 18348 const unsigned char * const end)
2cf19d5c 18349{
2cf19d5c
JM
18350 if (tag == Tag_GNU_MIPS_ABI_FP)
18351 {
32ec8896 18352 unsigned int val;
f6f0e17b 18353
2cf19d5c 18354 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18355 READ_ULEB (val, p, end);
351cdf24 18356 print_mips_fp_abi_value (val);
2cf19d5c
JM
18357 return p;
18358 }
18359
a9f58168
CF
18360 if (tag == Tag_GNU_MIPS_ABI_MSA)
18361 {
32ec8896 18362 unsigned int val;
a9f58168 18363
a9f58168 18364 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18365 READ_ULEB (val, p, end);
a9f58168
CF
18366
18367 switch (val)
18368 {
18369 case Val_GNU_MIPS_ABI_MSA_ANY:
18370 printf (_("Any MSA or not\n"));
18371 break;
18372 case Val_GNU_MIPS_ABI_MSA_128:
18373 printf (_("128-bit MSA\n"));
18374 break;
18375 default:
18376 printf ("??? (%d)\n", val);
18377 break;
18378 }
18379 return p;
18380 }
18381
f6f0e17b 18382 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18383}
18384
59e6276b 18385static unsigned char *
f6f0e17b
NC
18386display_tic6x_attribute (unsigned char * p,
18387 const unsigned char * const end)
59e6276b 18388{
60abdbed 18389 unsigned int tag;
cd30bcef 18390 unsigned int val;
59e6276b 18391
cd30bcef 18392 READ_ULEB (tag, p, end);
59e6276b
JM
18393
18394 switch (tag)
18395 {
75fa6dc1 18396 case Tag_ISA:
75fa6dc1 18397 printf (" Tag_ISA: ");
cd30bcef 18398 READ_ULEB (val, p, end);
59e6276b
JM
18399
18400 switch (val)
18401 {
75fa6dc1 18402 case C6XABI_Tag_ISA_none:
59e6276b
JM
18403 printf (_("None\n"));
18404 break;
75fa6dc1 18405 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18406 printf ("C62x\n");
18407 break;
75fa6dc1 18408 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18409 printf ("C67x\n");
18410 break;
75fa6dc1 18411 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18412 printf ("C67x+\n");
18413 break;
75fa6dc1 18414 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18415 printf ("C64x\n");
18416 break;
75fa6dc1 18417 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18418 printf ("C64x+\n");
18419 break;
75fa6dc1 18420 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18421 printf ("C674x\n");
18422 break;
18423 default:
18424 printf ("??? (%d)\n", val);
18425 break;
18426 }
18427 return p;
18428
87779176 18429 case Tag_ABI_wchar_t:
87779176 18430 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18431 READ_ULEB (val, p, end);
87779176
JM
18432 switch (val)
18433 {
18434 case 0:
18435 printf (_("Not used\n"));
18436 break;
18437 case 1:
18438 printf (_("2 bytes\n"));
18439 break;
18440 case 2:
18441 printf (_("4 bytes\n"));
18442 break;
18443 default:
18444 printf ("??? (%d)\n", val);
18445 break;
18446 }
18447 return p;
18448
18449 case Tag_ABI_stack_align_needed:
87779176 18450 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18451 READ_ULEB (val, p, end);
87779176
JM
18452 switch (val)
18453 {
18454 case 0:
18455 printf (_("8-byte\n"));
18456 break;
18457 case 1:
18458 printf (_("16-byte\n"));
18459 break;
18460 default:
18461 printf ("??? (%d)\n", val);
18462 break;
18463 }
18464 return p;
18465
18466 case Tag_ABI_stack_align_preserved:
cd30bcef 18467 READ_ULEB (val, p, end);
87779176
JM
18468 printf (" Tag_ABI_stack_align_preserved: ");
18469 switch (val)
18470 {
18471 case 0:
18472 printf (_("8-byte\n"));
18473 break;
18474 case 1:
18475 printf (_("16-byte\n"));
18476 break;
18477 default:
18478 printf ("??? (%d)\n", val);
18479 break;
18480 }
18481 return p;
18482
b5593623 18483 case Tag_ABI_DSBT:
cd30bcef 18484 READ_ULEB (val, p, end);
b5593623
JM
18485 printf (" Tag_ABI_DSBT: ");
18486 switch (val)
18487 {
18488 case 0:
18489 printf (_("DSBT addressing not used\n"));
18490 break;
18491 case 1:
18492 printf (_("DSBT addressing used\n"));
18493 break;
18494 default:
18495 printf ("??? (%d)\n", val);
18496 break;
18497 }
18498 return p;
18499
87779176 18500 case Tag_ABI_PID:
cd30bcef 18501 READ_ULEB (val, p, end);
87779176
JM
18502 printf (" Tag_ABI_PID: ");
18503 switch (val)
18504 {
18505 case 0:
18506 printf (_("Data addressing position-dependent\n"));
18507 break;
18508 case 1:
18509 printf (_("Data addressing position-independent, GOT near DP\n"));
18510 break;
18511 case 2:
18512 printf (_("Data addressing position-independent, GOT far from DP\n"));
18513 break;
18514 default:
18515 printf ("??? (%d)\n", val);
18516 break;
18517 }
18518 return p;
18519
18520 case Tag_ABI_PIC:
cd30bcef 18521 READ_ULEB (val, p, end);
87779176
JM
18522 printf (" Tag_ABI_PIC: ");
18523 switch (val)
18524 {
18525 case 0:
18526 printf (_("Code addressing position-dependent\n"));
18527 break;
18528 case 1:
18529 printf (_("Code addressing position-independent\n"));
18530 break;
18531 default:
18532 printf ("??? (%d)\n", val);
18533 break;
18534 }
18535 return p;
18536
18537 case Tag_ABI_array_object_alignment:
cd30bcef 18538 READ_ULEB (val, p, end);
87779176
JM
18539 printf (" Tag_ABI_array_object_alignment: ");
18540 switch (val)
18541 {
18542 case 0:
18543 printf (_("8-byte\n"));
18544 break;
18545 case 1:
18546 printf (_("4-byte\n"));
18547 break;
18548 case 2:
18549 printf (_("16-byte\n"));
18550 break;
18551 default:
18552 printf ("??? (%d)\n", val);
18553 break;
18554 }
18555 return p;
18556
18557 case Tag_ABI_array_object_align_expected:
cd30bcef 18558 READ_ULEB (val, p, end);
87779176
JM
18559 printf (" Tag_ABI_array_object_align_expected: ");
18560 switch (val)
18561 {
18562 case 0:
18563 printf (_("8-byte\n"));
18564 break;
18565 case 1:
18566 printf (_("4-byte\n"));
18567 break;
18568 case 2:
18569 printf (_("16-byte\n"));
18570 break;
18571 default:
18572 printf ("??? (%d)\n", val);
18573 break;
18574 }
18575 return p;
18576
3cbd1c06 18577 case Tag_ABI_compatibility:
071436c6 18578 {
cd30bcef 18579 READ_ULEB (val, p, end);
071436c6 18580 printf (" Tag_ABI_compatibility: ");
071436c6 18581 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18582 if (p < end - 1)
18583 {
18584 size_t maxlen = (end - p) - 1;
18585
b6ac461a 18586 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18587 p += strnlen ((char *) p, maxlen) + 1;
18588 }
18589 else
18590 {
18591 printf (_("<corrupt>"));
18592 p = (unsigned char *) end;
18593 }
071436c6 18594 putchar ('\n');
071436c6
NC
18595 return p;
18596 }
87779176
JM
18597
18598 case Tag_ABI_conformance:
071436c6 18599 {
4082ef84
NC
18600 printf (" Tag_ABI_conformance: \"");
18601 if (p < end - 1)
18602 {
18603 size_t maxlen = (end - p) - 1;
071436c6 18604
b6ac461a 18605 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18606 p += strnlen ((char *) p, maxlen) + 1;
18607 }
18608 else
18609 {
18610 printf (_("<corrupt>"));
18611 p = (unsigned char *) end;
18612 }
071436c6 18613 printf ("\"\n");
071436c6
NC
18614 return p;
18615 }
59e6276b
JM
18616 }
18617
f6f0e17b
NC
18618 return display_tag_value (tag, p, end);
18619}
59e6276b 18620
f6f0e17b 18621static void
60abdbed 18622display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18623{
26c527e6 18624 uint64_t addr = 0;
f6f0e17b
NC
18625 size_t bytes = end - p;
18626
feceaa59 18627 assert (end >= p);
f6f0e17b 18628 while (bytes)
87779176 18629 {
f6f0e17b
NC
18630 int j;
18631 int k;
18632 int lbytes = (bytes > 16 ? 16 : bytes);
18633
26c527e6 18634 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18635
18636 for (j = 0; j < 16; j++)
18637 {
18638 if (j < lbytes)
18639 printf ("%2.2x", p[j]);
18640 else
18641 printf (" ");
18642
18643 if ((j & 3) == 3)
18644 printf (" ");
18645 }
18646
18647 for (j = 0; j < lbytes; j++)
18648 {
18649 k = p[j];
18650 if (k >= ' ' && k < 0x7f)
18651 printf ("%c", k);
18652 else
18653 printf (".");
18654 }
18655
18656 putchar ('\n');
18657
18658 p += lbytes;
18659 bytes -= lbytes;
18660 addr += lbytes;
87779176 18661 }
59e6276b 18662
f6f0e17b 18663 putchar ('\n');
59e6276b
JM
18664}
18665
13761a11 18666static unsigned char *
b0191216 18667display_msp430_attribute (unsigned char * p,
26c527e6 18668 const unsigned char * const end)
13761a11 18669{
26c527e6
AM
18670 uint64_t val;
18671 uint64_t tag;
13761a11 18672
cd30bcef 18673 READ_ULEB (tag, p, end);
0b4362b0 18674
13761a11
NC
18675 switch (tag)
18676 {
18677 case OFBA_MSPABI_Tag_ISA:
13761a11 18678 printf (" Tag_ISA: ");
cd30bcef 18679 READ_ULEB (val, p, end);
13761a11
NC
18680 switch (val)
18681 {
18682 case 0: printf (_("None\n")); break;
18683 case 1: printf (_("MSP430\n")); break;
18684 case 2: printf (_("MSP430X\n")); break;
26c527e6 18685 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18686 }
18687 break;
18688
18689 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18690 printf (" Tag_Code_Model: ");
cd30bcef 18691 READ_ULEB (val, p, end);
13761a11
NC
18692 switch (val)
18693 {
18694 case 0: printf (_("None\n")); break;
18695 case 1: printf (_("Small\n")); break;
18696 case 2: printf (_("Large\n")); break;
26c527e6 18697 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18698 }
18699 break;
18700
18701 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18702 printf (" Tag_Data_Model: ");
cd30bcef 18703 READ_ULEB (val, p, end);
13761a11
NC
18704 switch (val)
18705 {
18706 case 0: printf (_("None\n")); break;
18707 case 1: printf (_("Small\n")); break;
18708 case 2: printf (_("Large\n")); break;
18709 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18710 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18711 }
18712 break;
18713
18714 default:
26c527e6 18715 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18716
18717 if (tag & 1)
18718 {
071436c6 18719 putchar ('"');
4082ef84
NC
18720 if (p < end - 1)
18721 {
18722 size_t maxlen = (end - p) - 1;
18723
b6ac461a 18724 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18725 p += strnlen ((char *) p, maxlen) + 1;
18726 }
18727 else
18728 {
18729 printf (_("<corrupt>"));
18730 p = (unsigned char *) end;
18731 }
071436c6 18732 printf ("\"\n");
13761a11
NC
18733 }
18734 else
18735 {
cd30bcef 18736 READ_ULEB (val, p, end);
26c527e6 18737 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18738 }
18739 break;
18740 }
18741
4082ef84 18742 assert (p <= end);
13761a11
NC
18743 return p;
18744}
18745
c0ea7c52
JL
18746static unsigned char *
18747display_msp430_gnu_attribute (unsigned char * p,
18748 unsigned int tag,
18749 const unsigned char * const end)
18750{
18751 if (tag == Tag_GNU_MSP430_Data_Region)
18752 {
26c527e6 18753 uint64_t val;
c0ea7c52 18754
c0ea7c52 18755 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18756 READ_ULEB (val, p, end);
c0ea7c52
JL
18757
18758 switch (val)
18759 {
18760 case Val_GNU_MSP430_Data_Region_Any:
18761 printf (_("Any Region\n"));
18762 break;
18763 case Val_GNU_MSP430_Data_Region_Lower:
18764 printf (_("Lower Region Only\n"));
18765 break;
18766 default:
26c527e6 18767 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18768 }
18769 return p;
18770 }
18771 return display_tag_value (tag & 1, p, end);
18772}
18773
2dc8dd17
JW
18774struct riscv_attr_tag_t {
18775 const char *name;
cd30bcef 18776 unsigned int tag;
2dc8dd17
JW
18777};
18778
18779static struct riscv_attr_tag_t riscv_attr_tag[] =
18780{
18781#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18782 T(arch),
18783 T(priv_spec),
18784 T(priv_spec_minor),
18785 T(priv_spec_revision),
18786 T(unaligned_access),
18787 T(stack_align),
18788#undef T
18789};
18790
18791static unsigned char *
18792display_riscv_attribute (unsigned char *p,
18793 const unsigned char * const end)
18794{
26c527e6
AM
18795 uint64_t val;
18796 uint64_t tag;
2dc8dd17
JW
18797 struct riscv_attr_tag_t *attr = NULL;
18798 unsigned i;
18799
cd30bcef 18800 READ_ULEB (tag, p, end);
2dc8dd17
JW
18801
18802 /* Find the name of attribute. */
18803 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18804 {
18805 if (riscv_attr_tag[i].tag == tag)
18806 {
18807 attr = &riscv_attr_tag[i];
18808 break;
18809 }
18810 }
18811
18812 if (attr)
18813 printf (" %s: ", attr->name);
18814 else
18815 return display_tag_value (tag, p, end);
18816
18817 switch (tag)
18818 {
18819 case Tag_RISCV_priv_spec:
18820 case Tag_RISCV_priv_spec_minor:
18821 case Tag_RISCV_priv_spec_revision:
cd30bcef 18822 READ_ULEB (val, p, end);
26c527e6 18823 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18824 break;
18825 case Tag_RISCV_unaligned_access:
cd30bcef 18826 READ_ULEB (val, p, end);
2dc8dd17
JW
18827 switch (val)
18828 {
18829 case 0:
18830 printf (_("No unaligned access\n"));
18831 break;
18832 case 1:
18833 printf (_("Unaligned access\n"));
18834 break;
18835 }
18836 break;
18837 case Tag_RISCV_stack_align:
cd30bcef 18838 READ_ULEB (val, p, end);
26c527e6 18839 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18840 break;
18841 case Tag_RISCV_arch:
18842 p = display_tag_value (-1, p, end);
18843 break;
18844 default:
18845 return display_tag_value (tag, p, end);
18846 }
18847
18848 return p;
18849}
18850
0861f561
CQ
18851static unsigned char *
18852display_csky_attribute (unsigned char * p,
18853 const unsigned char * const end)
18854{
26c527e6
AM
18855 uint64_t tag;
18856 uint64_t val;
0861f561
CQ
18857 READ_ULEB (tag, p, end);
18858
18859 if (tag >= Tag_CSKY_MAX)
18860 {
18861 return display_tag_value (-1, p, end);
18862 }
18863
18864 switch (tag)
18865 {
18866 case Tag_CSKY_ARCH_NAME:
18867 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18868 return display_tag_value (-1, p, end);
18869 case Tag_CSKY_CPU_NAME:
18870 printf (" Tag_CSKY_CPU_NAME:\t\t");
18871 return display_tag_value (-1, p, end);
18872
18873 case Tag_CSKY_ISA_FLAGS:
18874 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18875 return display_tag_value (0, p, end);
18876 case Tag_CSKY_ISA_EXT_FLAGS:
18877 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18878 return display_tag_value (0, p, end);
18879
18880 case Tag_CSKY_DSP_VERSION:
18881 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18882 READ_ULEB (val, p, end);
18883 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18884 printf ("DSP Extension\n");
18885 else if (val == VAL_CSKY_DSP_VERSION_2)
18886 printf ("DSP 2.0\n");
18887 break;
18888
18889 case Tag_CSKY_VDSP_VERSION:
18890 printf (" Tag_CSKY_VDSP_VERSION:\t");
18891 READ_ULEB (val, p, end);
26c527e6 18892 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18893 break;
18894
18895 case Tag_CSKY_FPU_VERSION:
18896 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18897 READ_ULEB (val, p, end);
18898 if (val == VAL_CSKY_FPU_VERSION_1)
18899 printf ("ABIV1 FPU Version 1\n");
18900 else if (val == VAL_CSKY_FPU_VERSION_2)
18901 printf ("FPU Version 2\n");
18902 break;
18903
18904 case Tag_CSKY_FPU_ABI:
18905 printf (" Tag_CSKY_FPU_ABI:\t\t");
18906 READ_ULEB (val, p, end);
18907 if (val == VAL_CSKY_FPU_ABI_HARD)
18908 printf ("Hard\n");
18909 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18910 printf ("SoftFP\n");
18911 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18912 printf ("Soft\n");
18913 break;
18914 case Tag_CSKY_FPU_ROUNDING:
18915 READ_ULEB (val, p, end);
f253158f
NC
18916 if (val == 1)
18917 {
18918 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18919 printf ("Needed\n");
18920 }
0861f561
CQ
18921 break;
18922 case Tag_CSKY_FPU_DENORMAL:
18923 READ_ULEB (val, p, end);
f253158f
NC
18924 if (val == 1)
18925 {
18926 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18927 printf ("Needed\n");
18928 }
0861f561
CQ
18929 break;
18930 case Tag_CSKY_FPU_Exception:
18931 READ_ULEB (val, p, end);
f253158f
NC
18932 if (val == 1)
18933 {
18934 printf (" Tag_CSKY_FPU_Exception:\t");
18935 printf ("Needed\n");
18936 }
0861f561
CQ
18937 break;
18938 case Tag_CSKY_FPU_NUMBER_MODULE:
18939 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18940 return display_tag_value (-1, p, end);
18941 case Tag_CSKY_FPU_HARDFP:
18942 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18943 READ_ULEB (val, p, end);
18944 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18945 printf (" Half");
18946 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18947 printf (" Single");
18948 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18949 printf (" Double");
18950 printf ("\n");
18951 break;
18952 default:
18953 return display_tag_value (tag, p, end);
18954 }
18955 return p;
18956}
18957
015dc7e1 18958static bool
dda8d76d 18959process_attributes (Filedata * filedata,
60bca95a 18960 const char * public_name,
104d59d1 18961 unsigned int proc_type,
f6f0e17b 18962 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18963 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18964{
2cf0635d 18965 Elf_Internal_Shdr * sect;
11c1ff18 18966 unsigned i;
015dc7e1 18967 bool res = true;
11c1ff18
PB
18968
18969 /* Find the section header so that we get the size. */
dda8d76d
NC
18970 for (i = 0, sect = filedata->section_headers;
18971 i < filedata->file_header.e_shnum;
11c1ff18
PB
18972 i++, sect++)
18973 {
071436c6
NC
18974 unsigned char * contents;
18975 unsigned char * p;
18976
104d59d1 18977 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18978 continue;
18979
dda8d76d 18980 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18981 sect->sh_size, _("attributes"));
60bca95a 18982 if (contents == NULL)
32ec8896 18983 {
015dc7e1 18984 res = false;
32ec8896
NC
18985 continue;
18986 }
60bca95a 18987
11c1ff18 18988 p = contents;
60abdbed
NC
18989 /* The first character is the version of the attributes.
18990 Currently only version 1, (aka 'A') is recognised here. */
18991 if (*p != 'A')
32ec8896
NC
18992 {
18993 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18994 res = false;
32ec8896 18995 }
60abdbed 18996 else
11c1ff18 18997 {
625d49fc 18998 uint64_t section_len;
071436c6
NC
18999
19000 section_len = sect->sh_size - 1;
11c1ff18 19001 p++;
60bca95a 19002
071436c6 19003 while (section_len > 0)
11c1ff18 19004 {
625d49fc 19005 uint64_t attr_len;
e9847026 19006 unsigned int namelen;
015dc7e1
AM
19007 bool public_section;
19008 bool gnu_section;
11c1ff18 19009
071436c6 19010 if (section_len <= 4)
e0a31db1
NC
19011 {
19012 error (_("Tag section ends prematurely\n"));
015dc7e1 19013 res = false;
e0a31db1
NC
19014 break;
19015 }
071436c6 19016 attr_len = byte_get (p, 4);
11c1ff18 19017 p += 4;
60bca95a 19018
071436c6 19019 if (attr_len > section_len)
11c1ff18 19020 {
071436c6
NC
19021 error (_("Bad attribute length (%u > %u)\n"),
19022 (unsigned) attr_len, (unsigned) section_len);
19023 attr_len = section_len;
015dc7e1 19024 res = false;
11c1ff18 19025 }
74e1a04b 19026 /* PR 17531: file: 001-101425-0.004 */
071436c6 19027 else if (attr_len < 5)
74e1a04b 19028 {
071436c6 19029 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 19030 res = false;
74e1a04b
NC
19031 break;
19032 }
e9847026 19033
071436c6
NC
19034 section_len -= attr_len;
19035 attr_len -= 4;
19036
19037 namelen = strnlen ((char *) p, attr_len) + 1;
19038 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
19039 {
19040 error (_("Corrupt attribute section name\n"));
015dc7e1 19041 res = false;
e9847026
NC
19042 break;
19043 }
19044
071436c6 19045 printf (_("Attribute Section: "));
b6ac461a 19046 print_symbol_name (INT_MAX, (const char *) p);
071436c6 19047 putchar ('\n');
60bca95a
NC
19048
19049 if (public_name && streq ((char *) p, public_name))
015dc7e1 19050 public_section = true;
11c1ff18 19051 else
015dc7e1 19052 public_section = false;
60bca95a
NC
19053
19054 if (streq ((char *) p, "gnu"))
015dc7e1 19055 gnu_section = true;
104d59d1 19056 else
015dc7e1 19057 gnu_section = false;
60bca95a 19058
11c1ff18 19059 p += namelen;
071436c6 19060 attr_len -= namelen;
e0a31db1 19061
071436c6 19062 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 19063 {
e0a31db1 19064 int tag;
cd30bcef 19065 unsigned int val;
625d49fc 19066 uint64_t size;
071436c6 19067 unsigned char * end;
60bca95a 19068
e0a31db1 19069 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 19070 if (attr_len < 6)
e0a31db1
NC
19071 {
19072 error (_("Unused bytes at end of section\n"));
015dc7e1 19073 res = false;
e0a31db1
NC
19074 section_len = 0;
19075 break;
19076 }
19077
19078 tag = *(p++);
11c1ff18 19079 size = byte_get (p, 4);
071436c6 19080 if (size > attr_len)
11c1ff18 19081 {
e9847026 19082 error (_("Bad subsection length (%u > %u)\n"),
071436c6 19083 (unsigned) size, (unsigned) attr_len);
015dc7e1 19084 res = false;
071436c6 19085 size = attr_len;
11c1ff18 19086 }
e0a31db1
NC
19087 /* PR binutils/17531: Safe handling of corrupt files. */
19088 if (size < 6)
19089 {
19090 error (_("Bad subsection length (%u < 6)\n"),
19091 (unsigned) size);
015dc7e1 19092 res = false;
e0a31db1
NC
19093 section_len = 0;
19094 break;
19095 }
60bca95a 19096
071436c6 19097 attr_len -= size;
11c1ff18 19098 end = p + size - 1;
071436c6 19099 assert (end <= contents + sect->sh_size);
11c1ff18 19100 p += 4;
60bca95a 19101
11c1ff18
PB
19102 switch (tag)
19103 {
19104 case 1:
2b692964 19105 printf (_("File Attributes\n"));
11c1ff18
PB
19106 break;
19107 case 2:
2b692964 19108 printf (_("Section Attributes:"));
11c1ff18
PB
19109 goto do_numlist;
19110 case 3:
2b692964 19111 printf (_("Symbol Attributes:"));
1a0670f3 19112 /* Fall through. */
11c1ff18
PB
19113 do_numlist:
19114 for (;;)
19115 {
cd30bcef 19116 READ_ULEB (val, p, end);
11c1ff18
PB
19117 if (val == 0)
19118 break;
19119 printf (" %d", val);
19120 }
19121 printf ("\n");
19122 break;
19123 default:
2b692964 19124 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 19125 public_section = false;
11c1ff18
PB
19126 break;
19127 }
60bca95a 19128
071436c6 19129 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
19130 {
19131 while (p < end)
f6f0e17b 19132 p = display_pub_attribute (p, end);
60abdbed 19133 assert (p == end);
104d59d1 19134 }
071436c6 19135 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
19136 {
19137 while (p < end)
19138 p = display_gnu_attribute (p,
f6f0e17b
NC
19139 display_proc_gnu_attribute,
19140 end);
60abdbed 19141 assert (p == end);
11c1ff18 19142 }
071436c6 19143 else if (p < end)
11c1ff18 19144 {
071436c6 19145 printf (_(" Unknown attribute:\n"));
f6f0e17b 19146 display_raw_attribute (p, end);
11c1ff18
PB
19147 p = end;
19148 }
071436c6
NC
19149 else
19150 attr_len = 0;
11c1ff18
PB
19151 }
19152 }
19153 }
d70c5fc7 19154
60bca95a 19155 free (contents);
11c1ff18 19156 }
32ec8896
NC
19157
19158 return res;
11c1ff18
PB
19159}
19160
ccb4c951
RS
19161/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19162 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
19163 and return the VMA of the next entry, or -1 if there was a problem.
19164 Does not read from DATA_END or beyond. */
ccb4c951 19165
625d49fc
AM
19166static uint64_t
19167print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 19168 unsigned char * data_end)
ccb4c951
RS
19169{
19170 printf (" ");
19171 print_vma (addr, LONG_HEX);
19172 printf (" ");
19173 if (addr < pltgot + 0xfff0)
19174 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19175 else
19176 printf ("%10s", "");
19177 printf (" ");
19178 if (data == NULL)
2b692964 19179 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
19180 else
19181 {
625d49fc 19182 uint64_t entry;
82b1b41b 19183 unsigned char * from = data + addr - pltgot;
ccb4c951 19184
82b1b41b
NC
19185 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19186 {
19187 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19188 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 19189 return (uint64_t) -1;
82b1b41b
NC
19190 }
19191 else
19192 {
19193 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19194 print_vma (entry, LONG_HEX);
19195 }
ccb4c951
RS
19196 }
19197 return addr + (is_32bit_elf ? 4 : 8);
19198}
19199
861fb55a
DJ
19200/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19201 PLTGOT. Print the Address and Initial fields of an entry at VMA
19202 ADDR and return the VMA of the next entry. */
19203
625d49fc
AM
19204static uint64_t
19205print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
19206{
19207 printf (" ");
19208 print_vma (addr, LONG_HEX);
19209 printf (" ");
19210 if (data == NULL)
2b692964 19211 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
19212 else
19213 {
625d49fc 19214 uint64_t entry;
861fb55a
DJ
19215
19216 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19217 print_vma (entry, LONG_HEX);
19218 }
19219 return addr + (is_32bit_elf ? 4 : 8);
19220}
19221
351cdf24
MF
19222static void
19223print_mips_ases (unsigned int mask)
19224{
19225 if (mask & AFL_ASE_DSP)
19226 fputs ("\n\tDSP ASE", stdout);
19227 if (mask & AFL_ASE_DSPR2)
19228 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
19229 if (mask & AFL_ASE_DSPR3)
19230 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
19231 if (mask & AFL_ASE_EVA)
19232 fputs ("\n\tEnhanced VA Scheme", stdout);
19233 if (mask & AFL_ASE_MCU)
19234 fputs ("\n\tMCU (MicroController) ASE", stdout);
19235 if (mask & AFL_ASE_MDMX)
19236 fputs ("\n\tMDMX ASE", stdout);
19237 if (mask & AFL_ASE_MIPS3D)
19238 fputs ("\n\tMIPS-3D ASE", stdout);
19239 if (mask & AFL_ASE_MT)
19240 fputs ("\n\tMT ASE", stdout);
19241 if (mask & AFL_ASE_SMARTMIPS)
19242 fputs ("\n\tSmartMIPS ASE", stdout);
19243 if (mask & AFL_ASE_VIRT)
19244 fputs ("\n\tVZ ASE", stdout);
19245 if (mask & AFL_ASE_MSA)
19246 fputs ("\n\tMSA ASE", stdout);
19247 if (mask & AFL_ASE_MIPS16)
19248 fputs ("\n\tMIPS16 ASE", stdout);
19249 if (mask & AFL_ASE_MICROMIPS)
19250 fputs ("\n\tMICROMIPS ASE", stdout);
19251 if (mask & AFL_ASE_XPA)
19252 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
19253 if (mask & AFL_ASE_MIPS16E2)
19254 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
19255 if (mask & AFL_ASE_CRC)
19256 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
19257 if (mask & AFL_ASE_GINV)
19258 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
19259 if (mask & AFL_ASE_LOONGSON_MMI)
19260 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
19261 if (mask & AFL_ASE_LOONGSON_CAM)
19262 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
19263 if (mask & AFL_ASE_LOONGSON_EXT)
19264 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
19265 if (mask & AFL_ASE_LOONGSON_EXT2)
19266 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
19267 if (mask == 0)
19268 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
19269 else if ((mask & ~AFL_ASE_MASK) != 0)
19270 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
19271}
19272
19273static void
19274print_mips_isa_ext (unsigned int isa_ext)
19275{
19276 switch (isa_ext)
19277 {
19278 case 0:
19279 fputs (_("None"), stdout);
19280 break;
19281 case AFL_EXT_XLR:
19282 fputs ("RMI XLR", stdout);
19283 break;
2c629856
N
19284 case AFL_EXT_OCTEON3:
19285 fputs ("Cavium Networks Octeon3", stdout);
19286 break;
351cdf24
MF
19287 case AFL_EXT_OCTEON2:
19288 fputs ("Cavium Networks Octeon2", stdout);
19289 break;
19290 case AFL_EXT_OCTEONP:
19291 fputs ("Cavium Networks OcteonP", stdout);
19292 break;
351cdf24
MF
19293 case AFL_EXT_OCTEON:
19294 fputs ("Cavium Networks Octeon", stdout);
19295 break;
19296 case AFL_EXT_5900:
19297 fputs ("Toshiba R5900", stdout);
19298 break;
19299 case AFL_EXT_4650:
19300 fputs ("MIPS R4650", stdout);
19301 break;
19302 case AFL_EXT_4010:
19303 fputs ("LSI R4010", stdout);
19304 break;
19305 case AFL_EXT_4100:
19306 fputs ("NEC VR4100", stdout);
19307 break;
19308 case AFL_EXT_3900:
19309 fputs ("Toshiba R3900", stdout);
19310 break;
19311 case AFL_EXT_10000:
19312 fputs ("MIPS R10000", stdout);
19313 break;
19314 case AFL_EXT_SB1:
19315 fputs ("Broadcom SB-1", stdout);
19316 break;
19317 case AFL_EXT_4111:
19318 fputs ("NEC VR4111/VR4181", stdout);
19319 break;
19320 case AFL_EXT_4120:
19321 fputs ("NEC VR4120", stdout);
19322 break;
19323 case AFL_EXT_5400:
19324 fputs ("NEC VR5400", stdout);
19325 break;
19326 case AFL_EXT_5500:
19327 fputs ("NEC VR5500", stdout);
19328 break;
19329 case AFL_EXT_LOONGSON_2E:
19330 fputs ("ST Microelectronics Loongson 2E", stdout);
19331 break;
19332 case AFL_EXT_LOONGSON_2F:
19333 fputs ("ST Microelectronics Loongson 2F", stdout);
19334 break;
38bf472a
MR
19335 case AFL_EXT_INTERAPTIV_MR2:
19336 fputs ("Imagination interAptiv MR2", stdout);
19337 break;
351cdf24 19338 default:
00ac7aa0 19339 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19340 }
19341}
19342
32ec8896 19343static signed int
351cdf24
MF
19344get_mips_reg_size (int reg_size)
19345{
19346 return (reg_size == AFL_REG_NONE) ? 0
19347 : (reg_size == AFL_REG_32) ? 32
19348 : (reg_size == AFL_REG_64) ? 64
19349 : (reg_size == AFL_REG_128) ? 128
19350 : -1;
19351}
19352
015dc7e1 19353static bool
dda8d76d 19354process_mips_specific (Filedata * filedata)
5b18a4bc 19355{
2cf0635d 19356 Elf_Internal_Dyn * entry;
351cdf24 19357 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19358 size_t liblist_offset = 0;
19359 size_t liblistno = 0;
19360 size_t conflictsno = 0;
19361 size_t options_offset = 0;
19362 size_t conflicts_offset = 0;
861fb55a
DJ
19363 size_t pltrelsz = 0;
19364 size_t pltrel = 0;
625d49fc
AM
19365 uint64_t pltgot = 0;
19366 uint64_t mips_pltgot = 0;
19367 uint64_t jmprel = 0;
19368 uint64_t local_gotno = 0;
19369 uint64_t gotsym = 0;
19370 uint64_t symtabno = 0;
015dc7e1 19371 bool res = true;
103f02d3 19372
dda8d76d 19373 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19374 display_mips_gnu_attribute))
015dc7e1 19375 res = false;
2cf19d5c 19376
dda8d76d 19377 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19378
19379 if (sect != NULL)
19380 {
19381 Elf_External_ABIFlags_v0 *abiflags_ext;
19382 Elf_Internal_ABIFlags_v0 abiflags_in;
19383
19384 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19385 {
19386 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19387 res = false;
32ec8896 19388 }
351cdf24
MF
19389 else
19390 {
dda8d76d 19391 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19392 sect->sh_size, _("MIPS ABI Flags section"));
19393 if (abiflags_ext)
19394 {
19395 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19396 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19397 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19398 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19399 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19400 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19401 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19402 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19403 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19404 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19405 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19406
19407 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19408 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19409 if (abiflags_in.isa_rev > 1)
19410 printf ("r%d", abiflags_in.isa_rev);
19411 printf ("\nGPR size: %d",
19412 get_mips_reg_size (abiflags_in.gpr_size));
19413 printf ("\nCPR1 size: %d",
19414 get_mips_reg_size (abiflags_in.cpr1_size));
19415 printf ("\nCPR2 size: %d",
19416 get_mips_reg_size (abiflags_in.cpr2_size));
19417 fputs ("\nFP ABI: ", stdout);
19418 print_mips_fp_abi_value (abiflags_in.fp_abi);
19419 fputs ("ISA Extension: ", stdout);
19420 print_mips_isa_ext (abiflags_in.isa_ext);
19421 fputs ("\nASEs:", stdout);
19422 print_mips_ases (abiflags_in.ases);
19423 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19424 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19425 fputc ('\n', stdout);
19426 free (abiflags_ext);
19427 }
19428 }
19429 }
19430
19e6b90e 19431 /* We have a lot of special sections. Thanks SGI! */
978c4450 19432 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19433 {
19434 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19435 sect = find_section (filedata, ".got");
bbdd9a68
MR
19436 if (sect != NULL)
19437 {
19438 unsigned char *data_end;
19439 unsigned char *data;
625d49fc 19440 uint64_t ent, end;
bbdd9a68
MR
19441 int addr_size;
19442
19443 pltgot = sect->sh_addr;
19444
19445 ent = pltgot;
19446 addr_size = (is_32bit_elf ? 4 : 8);
19447 end = pltgot + sect->sh_size;
19448
dda8d76d 19449 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19450 end - pltgot, 1,
19451 _("Global Offset Table data"));
19452 /* PR 12855: Null data is handled gracefully throughout. */
19453 data_end = data + (end - pltgot);
19454
19455 printf (_("\nStatic GOT:\n"));
19456 printf (_(" Canonical gp value: "));
19457 print_vma (ent + 0x7ff0, LONG_HEX);
19458 printf ("\n\n");
19459
19460 /* In a dynamic binary GOT[0] is reserved for the dynamic
19461 loader to store the lazy resolver pointer, however in
19462 a static binary it may well have been omitted and GOT
19463 reduced to a table of addresses.
19464 PR 21344: Check for the entry being fully available
19465 before fetching it. */
19466 if (data
19467 && data + ent - pltgot + addr_size <= data_end
19468 && byte_get (data + ent - pltgot, addr_size) == 0)
19469 {
19470 printf (_(" Reserved entries:\n"));
19471 printf (_(" %*s %10s %*s\n"),
19472 addr_size * 2, _("Address"), _("Access"),
19473 addr_size * 2, _("Value"));
19474 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19475 printf ("\n");
625d49fc 19476 if (ent == (uint64_t) -1)
bbdd9a68
MR
19477 goto sgot_print_fail;
19478
19479 /* Check for the MSB of GOT[1] being set, identifying a
19480 GNU object. This entry will be used by some runtime
19481 loaders, to store the module pointer. Otherwise this
19482 is an ordinary local entry.
19483 PR 21344: Check for the entry being fully available
19484 before fetching it. */
19485 if (data
19486 && data + ent - pltgot + addr_size <= data_end
19487 && (byte_get (data + ent - pltgot, addr_size)
19488 >> (addr_size * 8 - 1)) != 0)
19489 {
19490 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19491 printf ("\n");
625d49fc 19492 if (ent == (uint64_t) -1)
bbdd9a68
MR
19493 goto sgot_print_fail;
19494 }
19495 printf ("\n");
19496 }
19497
f17e9d8a 19498 if (data != NULL && ent < end)
bbdd9a68
MR
19499 {
19500 printf (_(" Local entries:\n"));
19501 printf (" %*s %10s %*s\n",
19502 addr_size * 2, _("Address"), _("Access"),
19503 addr_size * 2, _("Value"));
19504 while (ent < end)
19505 {
19506 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19507 printf ("\n");
625d49fc 19508 if (ent == (uint64_t) -1)
bbdd9a68
MR
19509 goto sgot_print_fail;
19510 }
19511 printf ("\n");
19512 }
19513
19514 sgot_print_fail:
9db70fc3 19515 free (data);
bbdd9a68
MR
19516 }
19517 return res;
19518 }
252b5132 19519
978c4450 19520 for (entry = filedata->dynamic_section;
071436c6 19521 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19522 (entry < filedata->dynamic_section + filedata->dynamic_nent
19523 && entry->d_tag != DT_NULL);
071436c6 19524 ++entry)
252b5132
RH
19525 switch (entry->d_tag)
19526 {
19527 case DT_MIPS_LIBLIST:
d93f0186 19528 liblist_offset
dda8d76d 19529 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19530 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19531 break;
19532 case DT_MIPS_LIBLISTNO:
19533 liblistno = entry->d_un.d_val;
19534 break;
19535 case DT_MIPS_OPTIONS:
dda8d76d 19536 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19537 break;
19538 case DT_MIPS_CONFLICT:
d93f0186 19539 conflicts_offset
dda8d76d 19540 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19541 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19542 break;
19543 case DT_MIPS_CONFLICTNO:
19544 conflictsno = entry->d_un.d_val;
19545 break;
ccb4c951 19546 case DT_PLTGOT:
861fb55a
DJ
19547 pltgot = entry->d_un.d_ptr;
19548 break;
ccb4c951
RS
19549 case DT_MIPS_LOCAL_GOTNO:
19550 local_gotno = entry->d_un.d_val;
19551 break;
19552 case DT_MIPS_GOTSYM:
19553 gotsym = entry->d_un.d_val;
19554 break;
19555 case DT_MIPS_SYMTABNO:
19556 symtabno = entry->d_un.d_val;
19557 break;
861fb55a
DJ
19558 case DT_MIPS_PLTGOT:
19559 mips_pltgot = entry->d_un.d_ptr;
19560 break;
19561 case DT_PLTREL:
19562 pltrel = entry->d_un.d_val;
19563 break;
19564 case DT_PLTRELSZ:
19565 pltrelsz = entry->d_un.d_val;
19566 break;
19567 case DT_JMPREL:
19568 jmprel = entry->d_un.d_ptr;
19569 break;
252b5132
RH
19570 default:
19571 break;
19572 }
19573
19574 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19575 {
2cf0635d 19576 Elf32_External_Lib * elib;
252b5132
RH
19577 size_t cnt;
19578
dda8d76d 19579 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19580 sizeof (Elf32_External_Lib),
19581 liblistno,
19582 _("liblist section data"));
a6e9f9df 19583 if (elib)
252b5132 19584 {
26c527e6
AM
19585 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19586 "\nSection '.liblist' contains %zu entries:\n",
19587 liblistno),
19588 liblistno);
2b692964 19589 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19590 stdout);
19591
19592 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19593 {
a6e9f9df 19594 Elf32_Lib liblist;
91d6fa6a 19595 time_t atime;
d5b07ef4 19596 char timebuf[128];
2cf0635d 19597 struct tm * tmp;
a6e9f9df
AM
19598
19599 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19600 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19601 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19602 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19603 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19604
91d6fa6a 19605 tmp = gmtime (&atime);
e9e44622
JJ
19606 snprintf (timebuf, sizeof (timebuf),
19607 "%04u-%02u-%02uT%02u:%02u:%02u",
19608 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19609 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19610
26c527e6 19611 printf ("%3zu: ", cnt);
84714f86 19612 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19613 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19614 else
2b692964 19615 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19616 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19617 liblist.l_version);
a6e9f9df
AM
19618
19619 if (liblist.l_flags == 0)
2b692964 19620 puts (_(" NONE"));
a6e9f9df
AM
19621 else
19622 {
19623 static const struct
252b5132 19624 {
2cf0635d 19625 const char * name;
a6e9f9df 19626 int bit;
252b5132 19627 }
a6e9f9df
AM
19628 l_flags_vals[] =
19629 {
19630 { " EXACT_MATCH", LL_EXACT_MATCH },
19631 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19632 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19633 { " EXPORTS", LL_EXPORTS },
19634 { " DELAY_LOAD", LL_DELAY_LOAD },
19635 { " DELTA", LL_DELTA }
19636 };
19637 int flags = liblist.l_flags;
19638 size_t fcnt;
19639
60bca95a 19640 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19641 if ((flags & l_flags_vals[fcnt].bit) != 0)
19642 {
19643 fputs (l_flags_vals[fcnt].name, stdout);
19644 flags ^= l_flags_vals[fcnt].bit;
19645 }
19646 if (flags != 0)
19647 printf (" %#x", (unsigned int) flags);
252b5132 19648
a6e9f9df
AM
19649 puts ("");
19650 }
252b5132 19651 }
252b5132 19652
a6e9f9df
AM
19653 free (elib);
19654 }
32ec8896 19655 else
015dc7e1 19656 res = false;
252b5132
RH
19657 }
19658
19659 if (options_offset != 0)
19660 {
2cf0635d 19661 Elf_External_Options * eopt;
252b5132
RH
19662 size_t offset;
19663 int cnt;
19664
19665 /* Find the section header so that we get the size. */
dda8d76d 19666 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19667 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19668 if (sect == NULL)
19669 {
19670 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19671 return false;
071436c6 19672 }
7fc0c668
NC
19673 /* PR 24243 */
19674 if (sect->sh_size < sizeof (* eopt))
19675 {
19676 error (_("The MIPS options section is too small.\n"));
015dc7e1 19677 return false;
7fc0c668 19678 }
252b5132 19679
dda8d76d 19680 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19681 sect->sh_size, _("options"));
a6e9f9df 19682 if (eopt)
252b5132 19683 {
fd17d1e6 19684 Elf_Internal_Options option;
76da6bbe 19685
a6e9f9df 19686 offset = cnt = 0;
82b1b41b 19687 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19688 {
2cf0635d 19689 Elf_External_Options * eoption;
fd17d1e6 19690 unsigned int optsize;
252b5132 19691
a6e9f9df 19692 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19693
fd17d1e6 19694 optsize = BYTE_GET (eoption->size);
76da6bbe 19695
82b1b41b 19696 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19697 if (optsize < sizeof (* eopt)
19698 || optsize > sect->sh_size - offset)
82b1b41b 19699 {
645f43a8 19700 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19701 optsize);
645f43a8 19702 free (eopt);
015dc7e1 19703 return false;
82b1b41b 19704 }
fd17d1e6 19705 offset += optsize;
a6e9f9df
AM
19706 ++cnt;
19707 }
252b5132 19708
d3a49aa8
AM
19709 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19710 "\nSection '%s' contains %d entries:\n",
19711 cnt),
dda8d76d 19712 printable_section_name (filedata, sect), cnt);
76da6bbe 19713
82b1b41b 19714 offset = 0;
a6e9f9df 19715 while (cnt-- > 0)
252b5132 19716 {
a6e9f9df 19717 size_t len;
fd17d1e6
AM
19718 Elf_External_Options * eoption;
19719
19720 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19721
19722 option.kind = BYTE_GET (eoption->kind);
19723 option.size = BYTE_GET (eoption->size);
19724 option.section = BYTE_GET (eoption->section);
19725 option.info = BYTE_GET (eoption->info);
a6e9f9df 19726
fd17d1e6 19727 switch (option.kind)
252b5132 19728 {
a6e9f9df
AM
19729 case ODK_NULL:
19730 /* This shouldn't happen. */
d0c4e780 19731 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19732 option.section, option.info);
a6e9f9df 19733 break;
2e6be59c 19734
a6e9f9df
AM
19735 case ODK_REGINFO:
19736 printf (" REGINFO ");
dda8d76d 19737 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19738 {
2cf0635d 19739 Elf32_External_RegInfo * ereg;
b34976b6 19740 Elf32_RegInfo reginfo;
a6e9f9df 19741
2e6be59c 19742 /* 32bit form. */
fd17d1e6
AM
19743 if (option.size < (sizeof (Elf_External_Options)
19744 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19745 {
19746 printf (_("<corrupt>\n"));
19747 error (_("Truncated MIPS REGINFO option\n"));
19748 cnt = 0;
19749 break;
19750 }
19751
fd17d1e6 19752 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19753
a6e9f9df
AM
19754 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19755 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19756 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19757 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19758 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19759 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19760
d0c4e780
AM
19761 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19762 reginfo.ri_gprmask, reginfo.ri_gp_value);
19763 printf (" "
19764 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19765 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19766 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19767 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19768 }
19769 else
19770 {
19771 /* 64 bit form. */
2cf0635d 19772 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19773 Elf64_Internal_RegInfo reginfo;
19774
fd17d1e6
AM
19775 if (option.size < (sizeof (Elf_External_Options)
19776 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19777 {
19778 printf (_("<corrupt>\n"));
19779 error (_("Truncated MIPS REGINFO option\n"));
19780 cnt = 0;
19781 break;
19782 }
19783
fd17d1e6 19784 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19785 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19786 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19787 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19788 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19789 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19790 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19791
d0c4e780
AM
19792 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19793 reginfo.ri_gprmask, reginfo.ri_gp_value);
19794 printf (" "
19795 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19796 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19797 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19798 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19799 }
fd17d1e6 19800 offset += option.size;
a6e9f9df 19801 continue;
2e6be59c 19802
a6e9f9df
AM
19803 case ODK_EXCEPTIONS:
19804 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19805 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19806 fputs (") fpe_max(", stdout);
fd17d1e6 19807 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19808 fputs (")", stdout);
19809
fd17d1e6 19810 if (option.info & OEX_PAGE0)
a6e9f9df 19811 fputs (" PAGE0", stdout);
fd17d1e6 19812 if (option.info & OEX_SMM)
a6e9f9df 19813 fputs (" SMM", stdout);
fd17d1e6 19814 if (option.info & OEX_FPDBUG)
a6e9f9df 19815 fputs (" FPDBUG", stdout);
fd17d1e6 19816 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19817 fputs (" DISMISS", stdout);
19818 break;
2e6be59c 19819
a6e9f9df
AM
19820 case ODK_PAD:
19821 fputs (" PAD ", stdout);
fd17d1e6 19822 if (option.info & OPAD_PREFIX)
a6e9f9df 19823 fputs (" PREFIX", stdout);
fd17d1e6 19824 if (option.info & OPAD_POSTFIX)
a6e9f9df 19825 fputs (" POSTFIX", stdout);
fd17d1e6 19826 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19827 fputs (" SYMBOL", stdout);
19828 break;
2e6be59c 19829
a6e9f9df
AM
19830 case ODK_HWPATCH:
19831 fputs (" HWPATCH ", stdout);
fd17d1e6 19832 if (option.info & OHW_R4KEOP)
a6e9f9df 19833 fputs (" R4KEOP", stdout);
fd17d1e6 19834 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19835 fputs (" R8KPFETCH", stdout);
fd17d1e6 19836 if (option.info & OHW_R5KEOP)
a6e9f9df 19837 fputs (" R5KEOP", stdout);
fd17d1e6 19838 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19839 fputs (" R5KCVTL", stdout);
19840 break;
2e6be59c 19841
a6e9f9df
AM
19842 case ODK_FILL:
19843 fputs (" FILL ", stdout);
19844 /* XXX Print content of info word? */
19845 break;
2e6be59c 19846
a6e9f9df
AM
19847 case ODK_TAGS:
19848 fputs (" TAGS ", stdout);
19849 /* XXX Print content of info word? */
19850 break;
2e6be59c 19851
a6e9f9df
AM
19852 case ODK_HWAND:
19853 fputs (" HWAND ", stdout);
fd17d1e6 19854 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19855 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19856 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19857 fputs (" R4KEOP_CLEAN", stdout);
19858 break;
2e6be59c 19859
a6e9f9df
AM
19860 case ODK_HWOR:
19861 fputs (" HWOR ", stdout);
fd17d1e6 19862 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19863 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19864 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19865 fputs (" R4KEOP_CLEAN", stdout);
19866 break;
2e6be59c 19867
a6e9f9df 19868 case ODK_GP_GROUP:
d0c4e780 19869 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19870 option.info & OGP_GROUP,
19871 (option.info & OGP_SELF) >> 16);
a6e9f9df 19872 break;
2e6be59c 19873
a6e9f9df 19874 case ODK_IDENT:
d0c4e780 19875 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19876 option.info & OGP_GROUP,
19877 (option.info & OGP_SELF) >> 16);
a6e9f9df 19878 break;
2e6be59c 19879
a6e9f9df
AM
19880 default:
19881 /* This shouldn't happen. */
d0c4e780 19882 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19883 option.kind, option.section, option.info);
a6e9f9df 19884 break;
252b5132 19885 }
a6e9f9df 19886
2cf0635d 19887 len = sizeof (* eopt);
fd17d1e6 19888 while (len < option.size)
82b1b41b 19889 {
fd17d1e6 19890 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19891
82b1b41b
NC
19892 if (ISPRINT (datum))
19893 printf ("%c", datum);
19894 else
19895 printf ("\\%03o", datum);
19896 len ++;
19897 }
a6e9f9df 19898 fputs ("\n", stdout);
82b1b41b 19899
fd17d1e6 19900 offset += option.size;
252b5132 19901 }
a6e9f9df 19902 free (eopt);
252b5132 19903 }
32ec8896 19904 else
015dc7e1 19905 res = false;
252b5132
RH
19906 }
19907
19908 if (conflicts_offset != 0 && conflictsno != 0)
19909 {
2cf0635d 19910 Elf32_Conflict * iconf;
252b5132
RH
19911 size_t cnt;
19912
978c4450 19913 if (filedata->dynamic_symbols == NULL)
252b5132 19914 {
591a748a 19915 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19916 return false;
252b5132
RH
19917 }
19918
7296a62a
NC
19919 /* PR 21345 - print a slightly more helpful error message
19920 if we are sure that the cmalloc will fail. */
645f43a8 19921 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19922 {
26c527e6
AM
19923 error (_("Overlarge number of conflicts detected: %zx\n"),
19924 conflictsno);
015dc7e1 19925 return false;
7296a62a
NC
19926 }
19927
3f5e193b 19928 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19929 if (iconf == NULL)
19930 {
8b73c356 19931 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19932 return false;
252b5132
RH
19933 }
19934
9ea033b2 19935 if (is_32bit_elf)
252b5132 19936 {
2cf0635d 19937 Elf32_External_Conflict * econf32;
a6e9f9df 19938
3f5e193b 19939 econf32 = (Elf32_External_Conflict *)
95099889
AM
19940 get_data (NULL, filedata, conflicts_offset,
19941 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19942 if (!econf32)
5a814d6d
AM
19943 {
19944 free (iconf);
015dc7e1 19945 return false;
5a814d6d 19946 }
252b5132
RH
19947
19948 for (cnt = 0; cnt < conflictsno; ++cnt)
19949 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19950
19951 free (econf32);
252b5132
RH
19952 }
19953 else
19954 {
2cf0635d 19955 Elf64_External_Conflict * econf64;
a6e9f9df 19956
3f5e193b 19957 econf64 = (Elf64_External_Conflict *)
95099889
AM
19958 get_data (NULL, filedata, conflicts_offset,
19959 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19960 if (!econf64)
5a814d6d
AM
19961 {
19962 free (iconf);
015dc7e1 19963 return false;
5a814d6d 19964 }
252b5132
RH
19965
19966 for (cnt = 0; cnt < conflictsno; ++cnt)
19967 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19968
19969 free (econf64);
252b5132
RH
19970 }
19971
26c527e6
AM
19972 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19973 "\nSection '.conflict' contains %zu entries:\n",
19974 conflictsno),
19975 conflictsno);
252b5132
RH
19976 puts (_(" Num: Index Value Name"));
19977
19978 for (cnt = 0; cnt < conflictsno; ++cnt)
19979 {
26c527e6 19980 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19981
978c4450 19982 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19983 printf (_("<corrupt symbol index>"));
d79b3d50 19984 else
e0a31db1
NC
19985 {
19986 Elf_Internal_Sym * psym;
19987
978c4450 19988 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19989 print_vma (psym->st_value, FULL_HEX);
19990 putchar (' ');
84714f86 19991 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19992 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19993 else
19994 printf (_("<corrupt: %14ld>"), psym->st_name);
19995 }
31104126 19996 putchar ('\n');
252b5132
RH
19997 }
19998
252b5132
RH
19999 free (iconf);
20000 }
20001
ccb4c951
RS
20002 if (pltgot != 0 && local_gotno != 0)
20003 {
625d49fc 20004 uint64_t ent, local_end, global_end;
bbeee7ea 20005 size_t i, offset;
2cf0635d 20006 unsigned char * data;
82b1b41b 20007 unsigned char * data_end;
bbeee7ea 20008 int addr_size;
ccb4c951 20009
91d6fa6a 20010 ent = pltgot;
ccb4c951
RS
20011 addr_size = (is_32bit_elf ? 4 : 8);
20012 local_end = pltgot + local_gotno * addr_size;
ccb4c951 20013
74e1a04b
NC
20014 /* PR binutils/17533 file: 012-111227-0.004 */
20015 if (symtabno < gotsym)
20016 {
26c527e6
AM
20017 error (_("The GOT symbol offset (%" PRIu64
20018 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20019 gotsym, symtabno);
015dc7e1 20020 return false;
74e1a04b 20021 }
82b1b41b 20022
74e1a04b 20023 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
20024 /* PR 17531: file: 54c91a34. */
20025 if (global_end < local_end)
20026 {
26c527e6 20027 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 20028 return false;
82b1b41b 20029 }
948f632f 20030
dda8d76d
NC
20031 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20032 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
20033 global_end - pltgot, 1,
20034 _("Global Offset Table data"));
919383ac 20035 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 20036 data_end = data + (global_end - pltgot);
59245841 20037
ccb4c951
RS
20038 printf (_("\nPrimary GOT:\n"));
20039 printf (_(" Canonical gp value: "));
20040 print_vma (pltgot + 0x7ff0, LONG_HEX);
20041 printf ("\n\n");
20042
20043 printf (_(" Reserved entries:\n"));
20044 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
20045 addr_size * 2, _("Address"), _("Access"),
20046 addr_size * 2, _("Initial"));
82b1b41b 20047 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 20048 printf (_(" Lazy resolver\n"));
625d49fc 20049 if (ent == (uint64_t) -1)
82b1b41b 20050 goto got_print_fail;
75ec1fdb 20051
c4ab9505
MR
20052 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20053 This entry will be used by some runtime loaders, to store the
20054 module pointer. Otherwise this is an ordinary local entry.
20055 PR 21344: Check for the entry being fully available before
20056 fetching it. */
20057 if (data
20058 && data + ent - pltgot + addr_size <= data_end
20059 && (byte_get (data + ent - pltgot, addr_size)
20060 >> (addr_size * 8 - 1)) != 0)
20061 {
20062 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20063 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 20064 if (ent == (uint64_t) -1)
c4ab9505 20065 goto got_print_fail;
ccb4c951
RS
20066 }
20067 printf ("\n");
20068
f17e9d8a 20069 if (data != NULL && ent < local_end)
ccb4c951
RS
20070 {
20071 printf (_(" Local entries:\n"));
cc5914eb 20072 printf (" %*s %10s %*s\n",
2b692964
NC
20073 addr_size * 2, _("Address"), _("Access"),
20074 addr_size * 2, _("Initial"));
91d6fa6a 20075 while (ent < local_end)
ccb4c951 20076 {
82b1b41b 20077 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20078 printf ("\n");
625d49fc 20079 if (ent == (uint64_t) -1)
82b1b41b 20080 goto got_print_fail;
ccb4c951
RS
20081 }
20082 printf ("\n");
20083 }
20084
f17e9d8a 20085 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
20086 {
20087 int sym_width;
20088
20089 printf (_(" Global entries:\n"));
cc5914eb 20090 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
20091 addr_size * 2, _("Address"),
20092 _("Access"),
2b692964 20093 addr_size * 2, _("Initial"),
9cf03b7e
NC
20094 addr_size * 2, _("Sym.Val."),
20095 _("Type"),
20096 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20097 _("Ndx"), _("Name"));
0b4362b0 20098
ccb4c951 20099 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 20100
ccb4c951
RS
20101 for (i = gotsym; i < symtabno; i++)
20102 {
82b1b41b 20103 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20104 printf (" ");
e0a31db1 20105
978c4450 20106 if (filedata->dynamic_symbols == NULL)
e0a31db1 20107 printf (_("<no dynamic symbols>"));
978c4450 20108 else if (i < filedata->num_dynamic_syms)
e0a31db1 20109 {
978c4450 20110 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
20111
20112 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
20113 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20114
20115 bool is_special;
20116 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20117 if (is_special)
20118 printf ("%3s ", s);
20119 else
20120 printf ("%3u ", psym->st_shndx);
e0a31db1 20121
84714f86 20122 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20123 print_symbol_name (sym_width,
84714f86 20124 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20125 else
20126 printf (_("<corrupt: %14ld>"), psym->st_name);
20127 }
ccb4c951 20128 else
26c527e6
AM
20129 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20130 i);
e0a31db1 20131
ccb4c951 20132 printf ("\n");
625d49fc 20133 if (ent == (uint64_t) -1)
82b1b41b 20134 break;
ccb4c951
RS
20135 }
20136 printf ("\n");
20137 }
20138
82b1b41b 20139 got_print_fail:
9db70fc3 20140 free (data);
ccb4c951
RS
20141 }
20142
861fb55a
DJ
20143 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20144 {
625d49fc 20145 uint64_t ent, end;
26c527e6
AM
20146 uint64_t offset, rel_offset;
20147 uint64_t count, i;
2cf0635d 20148 unsigned char * data;
861fb55a 20149 int addr_size, sym_width;
2cf0635d 20150 Elf_Internal_Rela * rels;
861fb55a 20151
dda8d76d 20152 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
20153 if (pltrel == DT_RELA)
20154 {
dda8d76d 20155 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20156 return false;
861fb55a
DJ
20157 }
20158 else
20159 {
dda8d76d 20160 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20161 return false;
861fb55a
DJ
20162 }
20163
91d6fa6a 20164 ent = mips_pltgot;
861fb55a
DJ
20165 addr_size = (is_32bit_elf ? 4 : 8);
20166 end = mips_pltgot + (2 + count) * addr_size;
20167
dda8d76d
NC
20168 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20169 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 20170 1, _("Procedure Linkage Table data"));
59245841 20171 if (data == NULL)
288f0ba2
AM
20172 {
20173 free (rels);
015dc7e1 20174 return false;
288f0ba2 20175 }
59245841 20176
9cf03b7e 20177 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
20178 printf (_(" Reserved entries:\n"));
20179 printf (_(" %*s %*s Purpose\n"),
2b692964 20180 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 20181 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20182 printf (_(" PLT lazy resolver\n"));
91d6fa6a 20183 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20184 printf (_(" Module pointer\n"));
861fb55a
DJ
20185 printf ("\n");
20186
20187 printf (_(" Entries:\n"));
cc5914eb 20188 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
20189 addr_size * 2, _("Address"),
20190 addr_size * 2, _("Initial"),
20191 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
20192 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20193 for (i = 0; i < count; i++)
20194 {
26c527e6 20195 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 20196
91d6fa6a 20197 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 20198 printf (" ");
e0a31db1 20199
978c4450 20200 if (idx >= filedata->num_dynamic_syms)
26c527e6 20201 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 20202 else
e0a31db1 20203 {
978c4450 20204 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
20205
20206 print_vma (psym->st_value, LONG_HEX);
20207 printf (" %-7s %3s ",
dda8d76d 20208 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 20209 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 20210 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20211 print_symbol_name (sym_width,
84714f86 20212 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20213 else
20214 printf (_("<corrupt: %14ld>"), psym->st_name);
20215 }
861fb55a
DJ
20216 printf ("\n");
20217 }
20218 printf ("\n");
20219
9db70fc3 20220 free (data);
861fb55a
DJ
20221 free (rels);
20222 }
20223
32ec8896 20224 return res;
252b5132
RH
20225}
20226
015dc7e1 20227static bool
dda8d76d 20228process_nds32_specific (Filedata * filedata)
35c08157
KLC
20229{
20230 Elf_Internal_Shdr *sect = NULL;
20231
dda8d76d 20232 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 20233 if (sect != NULL && sect->sh_size >= 4)
35c08157 20234 {
9c7b8e9b
AM
20235 unsigned char *buf;
20236 unsigned int flag;
35c08157
KLC
20237
20238 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
20239 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20240 _("NDS32 elf flags section"));
35c08157 20241
9c7b8e9b 20242 if (buf == NULL)
015dc7e1 20243 return false;
32ec8896 20244
9c7b8e9b
AM
20245 flag = byte_get (buf, 4);
20246 free (buf);
20247 switch (flag & 0x3)
35c08157
KLC
20248 {
20249 case 0:
20250 printf ("(VEC_SIZE):\tNo entry.\n");
20251 break;
20252 case 1:
20253 printf ("(VEC_SIZE):\t4 bytes\n");
20254 break;
20255 case 2:
20256 printf ("(VEC_SIZE):\t16 bytes\n");
20257 break;
20258 case 3:
20259 printf ("(VEC_SIZE):\treserved\n");
20260 break;
20261 }
20262 }
20263
015dc7e1 20264 return true;
35c08157
KLC
20265}
20266
015dc7e1 20267static bool
dda8d76d 20268process_gnu_liblist (Filedata * filedata)
047b2264 20269{
2cf0635d
NC
20270 Elf_Internal_Shdr * section;
20271 Elf_Internal_Shdr * string_sec;
20272 Elf32_External_Lib * elib;
20273 char * strtab;
c256ffe7 20274 size_t strtab_size;
047b2264 20275 size_t cnt;
26c527e6 20276 uint64_t num_liblist;
047b2264 20277 unsigned i;
015dc7e1 20278 bool res = true;
047b2264
JJ
20279
20280 if (! do_arch)
015dc7e1 20281 return true;
047b2264 20282
dda8d76d
NC
20283 for (i = 0, section = filedata->section_headers;
20284 i < filedata->file_header.e_shnum;
b34976b6 20285 i++, section++)
047b2264
JJ
20286 {
20287 switch (section->sh_type)
20288 {
20289 case SHT_GNU_LIBLIST:
dda8d76d 20290 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20291 break;
20292
3f5e193b 20293 elib = (Elf32_External_Lib *)
dda8d76d 20294 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20295 _("liblist section data"));
047b2264
JJ
20296
20297 if (elib == NULL)
32ec8896 20298 {
015dc7e1 20299 res = false;
32ec8896
NC
20300 break;
20301 }
047b2264 20302
dda8d76d
NC
20303 string_sec = filedata->section_headers + section->sh_link;
20304 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20305 string_sec->sh_size,
20306 _("liblist string table"));
047b2264
JJ
20307 if (strtab == NULL
20308 || section->sh_entsize != sizeof (Elf32_External_Lib))
20309 {
20310 free (elib);
2842702f 20311 free (strtab);
015dc7e1 20312 res = false;
047b2264
JJ
20313 break;
20314 }
59245841 20315 strtab_size = string_sec->sh_size;
047b2264 20316
d3a49aa8 20317 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20318 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20319 " entries:\n",
20320 "\nLibrary list section '%s' contains %" PRIu64
20321 " entries:\n",
d3a49aa8 20322 num_liblist),
dda8d76d 20323 printable_section_name (filedata, section),
d3a49aa8 20324 num_liblist);
047b2264 20325
2b692964 20326 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20327
20328 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20329 ++cnt)
20330 {
20331 Elf32_Lib liblist;
91d6fa6a 20332 time_t atime;
d5b07ef4 20333 char timebuf[128];
2cf0635d 20334 struct tm * tmp;
047b2264
JJ
20335
20336 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20337 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20338 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20339 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20340 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20341
91d6fa6a 20342 tmp = gmtime (&atime);
e9e44622
JJ
20343 snprintf (timebuf, sizeof (timebuf),
20344 "%04u-%02u-%02uT%02u:%02u:%02u",
20345 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20346 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20347
26c527e6 20348 printf ("%3zu: ", cnt);
047b2264 20349 if (do_wide)
c256ffe7 20350 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20351 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20352 else
c256ffe7 20353 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20354 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20355 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20356 liblist.l_version, liblist.l_flags);
20357 }
20358
20359 free (elib);
2842702f 20360 free (strtab);
047b2264
JJ
20361 }
20362 }
20363
32ec8896 20364 return res;
047b2264
JJ
20365}
20366
9437c45b 20367static const char *
dda8d76d 20368get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20369{
20370 static char buff[64];
103f02d3 20371
dda8d76d 20372 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20373 switch (e_type)
20374 {
57346661 20375 case NT_AUXV:
1ec5cd37 20376 return _("NT_AUXV (auxiliary vector)");
57346661 20377 case NT_PRSTATUS:
1ec5cd37 20378 return _("NT_PRSTATUS (prstatus structure)");
57346661 20379 case NT_FPREGSET:
1ec5cd37 20380 return _("NT_FPREGSET (floating point registers)");
57346661 20381 case NT_PRPSINFO:
1ec5cd37 20382 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20383 case NT_TASKSTRUCT:
1ec5cd37 20384 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20385 case NT_GDB_TDESC:
20386 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20387 case NT_PRXFPREG:
1ec5cd37 20388 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20389 case NT_PPC_VMX:
20390 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20391 case NT_PPC_VSX:
20392 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20393 case NT_PPC_TAR:
20394 return _("NT_PPC_TAR (ppc TAR register)");
20395 case NT_PPC_PPR:
20396 return _("NT_PPC_PPR (ppc PPR register)");
20397 case NT_PPC_DSCR:
20398 return _("NT_PPC_DSCR (ppc DSCR register)");
20399 case NT_PPC_EBB:
20400 return _("NT_PPC_EBB (ppc EBB registers)");
20401 case NT_PPC_PMU:
20402 return _("NT_PPC_PMU (ppc PMU registers)");
20403 case NT_PPC_TM_CGPR:
20404 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20405 case NT_PPC_TM_CFPR:
20406 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20407 case NT_PPC_TM_CVMX:
20408 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20409 case NT_PPC_TM_CVSX:
3fd21718 20410 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20411 case NT_PPC_TM_SPR:
20412 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20413 case NT_PPC_TM_CTAR:
20414 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20415 case NT_PPC_TM_CPPR:
20416 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20417 case NT_PPC_TM_CDSCR:
20418 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20419 case NT_386_TLS:
20420 return _("NT_386_TLS (x86 TLS information)");
20421 case NT_386_IOPERM:
20422 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20423 case NT_X86_XSTATE:
20424 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20425 case NT_X86_CET:
20426 return _("NT_X86_CET (x86 CET state)");
eccdc733
SC
20427 case NT_X86_SHSTK:
20428 return _("NT_X86_SHSTK (x86 SHSTK state)");
0675e188
UW
20429 case NT_S390_HIGH_GPRS:
20430 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20431 case NT_S390_TIMER:
20432 return _("NT_S390_TIMER (s390 timer register)");
20433 case NT_S390_TODCMP:
20434 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20435 case NT_S390_TODPREG:
20436 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20437 case NT_S390_CTRS:
20438 return _("NT_S390_CTRS (s390 control registers)");
20439 case NT_S390_PREFIX:
20440 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20441 case NT_S390_LAST_BREAK:
20442 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20443 case NT_S390_SYSTEM_CALL:
20444 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20445 case NT_S390_TDB:
20446 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20447 case NT_S390_VXRS_LOW:
20448 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20449 case NT_S390_VXRS_HIGH:
20450 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20451 case NT_S390_GS_CB:
20452 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20453 case NT_S390_GS_BC:
20454 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20455 case NT_ARM_VFP:
20456 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20457 case NT_ARM_TLS:
20458 return _("NT_ARM_TLS (AArch TLS registers)");
20459 case NT_ARM_HW_BREAK:
20460 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20461 case NT_ARM_HW_WATCH:
20462 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20463 case NT_ARM_SYSTEM_CALL:
20464 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20465 case NT_ARM_SVE:
20466 return _("NT_ARM_SVE (AArch SVE registers)");
20467 case NT_ARM_PAC_MASK:
20468 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20469 case NT_ARM_PACA_KEYS:
20470 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20471 case NT_ARM_PACG_KEYS:
20472 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20473 case NT_ARM_TAGGED_ADDR_CTRL:
20474 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20475 case NT_ARM_SSVE:
20476 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20477 case NT_ARM_ZA:
20478 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20479 case NT_ARM_ZT:
20480 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20481 case NT_ARM_PAC_ENABLED_KEYS:
20482 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20483 case NT_ARC_V2:
20484 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20485 case NT_RISCV_CSR:
20486 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20487 case NT_PSTATUS:
1ec5cd37 20488 return _("NT_PSTATUS (pstatus structure)");
57346661 20489 case NT_FPREGS:
1ec5cd37 20490 return _("NT_FPREGS (floating point registers)");
57346661 20491 case NT_PSINFO:
1ec5cd37 20492 return _("NT_PSINFO (psinfo structure)");
57346661 20493 case NT_LWPSTATUS:
1ec5cd37 20494 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20495 case NT_LWPSINFO:
1ec5cd37 20496 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20497 case NT_WIN32PSTATUS:
1ec5cd37 20498 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20499 case NT_SIGINFO:
20500 return _("NT_SIGINFO (siginfo_t data)");
20501 case NT_FILE:
20502 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20503 default:
20504 break;
20505 }
20506 else
20507 switch (e_type)
20508 {
20509 case NT_VERSION:
20510 return _("NT_VERSION (version)");
20511 case NT_ARCH:
20512 return _("NT_ARCH (architecture)");
9ef920e9 20513 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20514 return _("OPEN");
9ef920e9 20515 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20516 return _("func");
c8795e1f
NC
20517 case NT_GO_BUILDID:
20518 return _("GO BUILDID");
3ac925fc
LB
20519 case FDO_PACKAGING_METADATA:
20520 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20521 default:
20522 break;
20523 }
20524
e9e44622 20525 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20526 return buff;
779fe533
NC
20527}
20528
015dc7e1 20529static bool
9ece1fa9
TT
20530print_core_note (Elf_Internal_Note *pnote)
20531{
20532 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20533 uint64_t count, page_size;
9ece1fa9
TT
20534 unsigned char *descdata, *filenames, *descend;
20535
20536 if (pnote->type != NT_FILE)
04ac15ab
AS
20537 {
20538 if (do_wide)
20539 printf ("\n");
015dc7e1 20540 return true;
04ac15ab 20541 }
9ece1fa9 20542
9ece1fa9
TT
20543 if (pnote->descsz < 2 * addr_size)
20544 {
32ec8896 20545 error (_(" Malformed note - too short for header\n"));
015dc7e1 20546 return false;
9ece1fa9
TT
20547 }
20548
20549 descdata = (unsigned char *) pnote->descdata;
20550 descend = descdata + pnote->descsz;
20551
20552 if (descdata[pnote->descsz - 1] != '\0')
20553 {
32ec8896 20554 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20555 return false;
9ece1fa9
TT
20556 }
20557
20558 count = byte_get (descdata, addr_size);
20559 descdata += addr_size;
20560
20561 page_size = byte_get (descdata, addr_size);
20562 descdata += addr_size;
20563
625d49fc 20564 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20565 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20566 {
32ec8896 20567 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20568 return false;
9ece1fa9
TT
20569 }
20570
20571 printf (_(" Page size: "));
20572 print_vma (page_size, DEC);
20573 printf ("\n");
20574
20575 printf (_(" %*s%*s%*s\n"),
20576 (int) (2 + 2 * addr_size), _("Start"),
20577 (int) (4 + 2 * addr_size), _("End"),
20578 (int) (4 + 2 * addr_size), _("Page Offset"));
20579 filenames = descdata + count * 3 * addr_size;
595712bb 20580 while (count-- > 0)
9ece1fa9 20581 {
625d49fc 20582 uint64_t start, end, file_ofs;
9ece1fa9
TT
20583
20584 if (filenames == descend)
20585 {
32ec8896 20586 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20587 return false;
9ece1fa9
TT
20588 }
20589
20590 start = byte_get (descdata, addr_size);
20591 descdata += addr_size;
20592 end = byte_get (descdata, addr_size);
20593 descdata += addr_size;
20594 file_ofs = byte_get (descdata, addr_size);
20595 descdata += addr_size;
20596
20597 printf (" ");
20598 print_vma (start, FULL_HEX);
20599 printf (" ");
20600 print_vma (end, FULL_HEX);
20601 printf (" ");
20602 print_vma (file_ofs, FULL_HEX);
20603 printf ("\n %s\n", filenames);
20604
20605 filenames += 1 + strlen ((char *) filenames);
20606 }
20607
015dc7e1 20608 return true;
9ece1fa9
TT
20609}
20610
1118d252
RM
20611static const char *
20612get_gnu_elf_note_type (unsigned e_type)
20613{
1449284b 20614 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20615 switch (e_type)
20616 {
20617 case NT_GNU_ABI_TAG:
20618 return _("NT_GNU_ABI_TAG (ABI version tag)");
20619 case NT_GNU_HWCAP:
20620 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20621 case NT_GNU_BUILD_ID:
20622 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20623 case NT_GNU_GOLD_VERSION:
20624 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20625 case NT_GNU_PROPERTY_TYPE_0:
20626 return _("NT_GNU_PROPERTY_TYPE_0");
20627 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20628 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20629 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20630 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20631 default:
1449284b
NC
20632 {
20633 static char buff[64];
1118d252 20634
1449284b
NC
20635 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20636 return buff;
20637 }
20638 }
1118d252
RM
20639}
20640
a9eafb08
L
20641static void
20642decode_x86_compat_isa (unsigned int bitmask)
20643{
20644 while (bitmask)
20645 {
20646 unsigned int bit = bitmask & (- bitmask);
20647
20648 bitmask &= ~ bit;
20649 switch (bit)
20650 {
20651 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20652 printf ("i486");
20653 break;
20654 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20655 printf ("586");
20656 break;
20657 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20658 printf ("686");
20659 break;
20660 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20661 printf ("SSE");
20662 break;
20663 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20664 printf ("SSE2");
20665 break;
20666 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20667 printf ("SSE3");
20668 break;
20669 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20670 printf ("SSSE3");
20671 break;
20672 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20673 printf ("SSE4_1");
20674 break;
20675 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20676 printf ("SSE4_2");
20677 break;
20678 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20679 printf ("AVX");
20680 break;
20681 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20682 printf ("AVX2");
20683 break;
20684 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20685 printf ("AVX512F");
20686 break;
20687 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20688 printf ("AVX512CD");
20689 break;
20690 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20691 printf ("AVX512ER");
20692 break;
20693 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20694 printf ("AVX512PF");
20695 break;
20696 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20697 printf ("AVX512VL");
20698 break;
20699 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20700 printf ("AVX512DQ");
20701 break;
20702 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20703 printf ("AVX512BW");
20704 break;
65b3d26e
L
20705 default:
20706 printf (_("<unknown: %x>"), bit);
20707 break;
a9eafb08
L
20708 }
20709 if (bitmask)
20710 printf (", ");
20711 }
20712}
20713
9ef920e9 20714static void
32930e4e 20715decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20716{
0a59decb 20717 if (!bitmask)
90c745dc
L
20718 {
20719 printf (_("<None>"));
20720 return;
20721 }
90c745dc 20722
9ef920e9
NC
20723 while (bitmask)
20724 {
1fc87489 20725 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20726
20727 bitmask &= ~ bit;
20728 switch (bit)
20729 {
32930e4e 20730 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20731 printf ("CMOV");
20732 break;
32930e4e 20733 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20734 printf ("SSE");
20735 break;
32930e4e 20736 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20737 printf ("SSE2");
20738 break;
32930e4e 20739 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20740 printf ("SSE3");
20741 break;
32930e4e 20742 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20743 printf ("SSSE3");
20744 break;
32930e4e 20745 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20746 printf ("SSE4_1");
20747 break;
32930e4e 20748 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20749 printf ("SSE4_2");
20750 break;
32930e4e 20751 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20752 printf ("AVX");
20753 break;
32930e4e 20754 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20755 printf ("AVX2");
20756 break;
32930e4e 20757 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20758 printf ("FMA");
20759 break;
32930e4e 20760 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20761 printf ("AVX512F");
20762 break;
32930e4e 20763 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20764 printf ("AVX512CD");
20765 break;
32930e4e 20766 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20767 printf ("AVX512ER");
20768 break;
32930e4e 20769 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20770 printf ("AVX512PF");
20771 break;
32930e4e 20772 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20773 printf ("AVX512VL");
20774 break;
32930e4e 20775 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20776 printf ("AVX512DQ");
20777 break;
32930e4e 20778 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20779 printf ("AVX512BW");
20780 break;
32930e4e 20781 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20782 printf ("AVX512_4FMAPS");
20783 break;
32930e4e 20784 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20785 printf ("AVX512_4VNNIW");
20786 break;
32930e4e 20787 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20788 printf ("AVX512_BITALG");
20789 break;
32930e4e 20790 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20791 printf ("AVX512_IFMA");
20792 break;
32930e4e 20793 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20794 printf ("AVX512_VBMI");
20795 break;
32930e4e 20796 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20797 printf ("AVX512_VBMI2");
20798 break;
32930e4e 20799 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20800 printf ("AVX512_VNNI");
20801 break;
32930e4e 20802 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20803 printf ("AVX512_BF16");
20804 break;
65b3d26e
L
20805 default:
20806 printf (_("<unknown: %x>"), bit);
20807 break;
9ef920e9
NC
20808 }
20809 if (bitmask)
20810 printf (", ");
20811 }
20812}
20813
28cdbb18
SM
20814static const char *
20815get_amdgpu_elf_note_type (unsigned int e_type)
20816{
20817 switch (e_type)
20818 {
20819 case NT_AMDGPU_METADATA:
20820 return _("NT_AMDGPU_METADATA (code object metadata)");
20821 default:
20822 {
20823 static char buf[64];
20824 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20825 return buf;
20826 }
20827 }
20828}
20829
32930e4e
L
20830static void
20831decode_x86_isa (unsigned int bitmask)
20832{
32930e4e
L
20833 while (bitmask)
20834 {
20835 unsigned int bit = bitmask & (- bitmask);
20836
20837 bitmask &= ~ bit;
20838 switch (bit)
20839 {
b0ab0693
L
20840 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20841 printf ("x86-64-baseline");
20842 break;
32930e4e
L
20843 case GNU_PROPERTY_X86_ISA_1_V2:
20844 printf ("x86-64-v2");
20845 break;
20846 case GNU_PROPERTY_X86_ISA_1_V3:
20847 printf ("x86-64-v3");
20848 break;
20849 case GNU_PROPERTY_X86_ISA_1_V4:
20850 printf ("x86-64-v4");
20851 break;
20852 default:
20853 printf (_("<unknown: %x>"), bit);
20854 break;
20855 }
20856 if (bitmask)
20857 printf (", ");
20858 }
20859}
20860
ee2fdd6f 20861static void
a9eafb08 20862decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20863{
0a59decb 20864 if (!bitmask)
90c745dc
L
20865 {
20866 printf (_("<None>"));
20867 return;
20868 }
90c745dc 20869
ee2fdd6f
L
20870 while (bitmask)
20871 {
20872 unsigned int bit = bitmask & (- bitmask);
20873
20874 bitmask &= ~ bit;
20875 switch (bit)
20876 {
20877 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20878 printf ("IBT");
ee2fdd6f 20879 break;
48580982 20880 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20881 printf ("SHSTK");
48580982 20882 break;
279d901e
L
20883 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20884 printf ("LAM_U48");
20885 break;
20886 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20887 printf ("LAM_U57");
20888 break;
ee2fdd6f
L
20889 default:
20890 printf (_("<unknown: %x>"), bit);
20891 break;
20892 }
20893 if (bitmask)
20894 printf (", ");
20895 }
20896}
20897
a9eafb08
L
20898static void
20899decode_x86_feature_2 (unsigned int bitmask)
20900{
0a59decb 20901 if (!bitmask)
90c745dc
L
20902 {
20903 printf (_("<None>"));
20904 return;
20905 }
90c745dc 20906
a9eafb08
L
20907 while (bitmask)
20908 {
20909 unsigned int bit = bitmask & (- bitmask);
20910
20911 bitmask &= ~ bit;
20912 switch (bit)
20913 {
20914 case GNU_PROPERTY_X86_FEATURE_2_X86:
20915 printf ("x86");
20916 break;
20917 case GNU_PROPERTY_X86_FEATURE_2_X87:
20918 printf ("x87");
20919 break;
20920 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20921 printf ("MMX");
20922 break;
20923 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20924 printf ("XMM");
20925 break;
20926 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20927 printf ("YMM");
20928 break;
20929 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20930 printf ("ZMM");
20931 break;
a308b89d
L
20932 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20933 printf ("TMM");
20934 break;
32930e4e
L
20935 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20936 printf ("MASK");
20937 break;
a9eafb08
L
20938 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20939 printf ("FXSR");
20940 break;
20941 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20942 printf ("XSAVE");
20943 break;
20944 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20945 printf ("XSAVEOPT");
20946 break;
20947 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20948 printf ("XSAVEC");
20949 break;
65b3d26e
L
20950 default:
20951 printf (_("<unknown: %x>"), bit);
20952 break;
a9eafb08
L
20953 }
20954 if (bitmask)
20955 printf (", ");
20956 }
20957}
20958
cd702818
SD
20959static void
20960decode_aarch64_feature_1_and (unsigned int bitmask)
20961{
20962 while (bitmask)
20963 {
20964 unsigned int bit = bitmask & (- bitmask);
20965
20966 bitmask &= ~ bit;
20967 switch (bit)
20968 {
20969 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20970 printf ("BTI");
20971 break;
20972
20973 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20974 printf ("PAC");
20975 break;
20976
20977 default:
20978 printf (_("<unknown: %x>"), bit);
20979 break;
20980 }
20981 if (bitmask)
20982 printf (", ");
20983 }
20984}
20985
6320fd00
L
20986static void
20987decode_1_needed (unsigned int bitmask)
20988{
20989 while (bitmask)
20990 {
20991 unsigned int bit = bitmask & (- bitmask);
20992
20993 bitmask &= ~ bit;
20994 switch (bit)
20995 {
20996 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20997 printf ("indirect external access");
20998 break;
20999 default:
21000 printf (_("<unknown: %x>"), bit);
21001 break;
21002 }
21003 if (bitmask)
21004 printf (", ");
21005 }
21006}
21007
9ef920e9 21008static void
dda8d76d 21009print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
21010{
21011 unsigned char * ptr = (unsigned char *) pnote->descdata;
21012 unsigned char * ptr_end = ptr + pnote->descsz;
21013 unsigned int size = is_32bit_elf ? 4 : 8;
21014
21015 printf (_(" Properties: "));
21016
1fc87489 21017 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
21018 {
21019 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21020 return;
21021 }
21022
6ab2c4ed 21023 while (ptr < ptr_end)
9ef920e9 21024 {
1fc87489 21025 unsigned int j;
6ab2c4ed
MC
21026 unsigned int type;
21027 unsigned int datasz;
21028
21029 if ((size_t) (ptr_end - ptr) < 8)
21030 {
21031 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21032 break;
21033 }
21034
21035 type = byte_get (ptr, 4);
21036 datasz = byte_get (ptr + 4, 4);
9ef920e9 21037
1fc87489 21038 ptr += 8;
9ef920e9 21039
6ab2c4ed 21040 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 21041 {
1fc87489
L
21042 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21043 type, datasz);
9ef920e9 21044 break;
1fc87489 21045 }
9ef920e9 21046
1fc87489
L
21047 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21048 {
dda8d76d
NC
21049 if (filedata->file_header.e_machine == EM_X86_64
21050 || filedata->file_header.e_machine == EM_IAMCU
21051 || filedata->file_header.e_machine == EM_386)
1fc87489 21052 {
aa7bca9b
L
21053 unsigned int bitmask;
21054
21055 if (datasz == 4)
0a59decb 21056 bitmask = byte_get (ptr, 4);
aa7bca9b
L
21057 else
21058 bitmask = 0;
21059
1fc87489
L
21060 switch (type)
21061 {
21062 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 21063 if (datasz != 4)
aa7bca9b
L
21064 printf (_("x86 ISA used: <corrupt length: %#x> "),
21065 datasz);
1fc87489 21066 else
aa7bca9b
L
21067 {
21068 printf ("x86 ISA used: ");
21069 decode_x86_isa (bitmask);
21070 }
1fc87489 21071 goto next;
9ef920e9 21072
1fc87489 21073 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 21074 if (datasz != 4)
aa7bca9b
L
21075 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21076 datasz);
1fc87489 21077 else
aa7bca9b
L
21078 {
21079 printf ("x86 ISA needed: ");
21080 decode_x86_isa (bitmask);
21081 }
1fc87489 21082 goto next;
9ef920e9 21083
ee2fdd6f 21084 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 21085 if (datasz != 4)
aa7bca9b
L
21086 printf (_("x86 feature: <corrupt length: %#x> "),
21087 datasz);
ee2fdd6f 21088 else
aa7bca9b
L
21089 {
21090 printf ("x86 feature: ");
a9eafb08
L
21091 decode_x86_feature_1 (bitmask);
21092 }
21093 goto next;
21094
21095 case GNU_PROPERTY_X86_FEATURE_2_USED:
21096 if (datasz != 4)
21097 printf (_("x86 feature used: <corrupt length: %#x> "),
21098 datasz);
21099 else
21100 {
21101 printf ("x86 feature used: ");
21102 decode_x86_feature_2 (bitmask);
21103 }
21104 goto next;
21105
21106 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21107 if (datasz != 4)
21108 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21109 else
21110 {
21111 printf ("x86 feature needed: ");
21112 decode_x86_feature_2 (bitmask);
21113 }
21114 goto next;
21115
21116 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21117 if (datasz != 4)
21118 printf (_("x86 ISA used: <corrupt length: %#x> "),
21119 datasz);
21120 else
21121 {
21122 printf ("x86 ISA used: ");
21123 decode_x86_compat_isa (bitmask);
21124 }
21125 goto next;
21126
21127 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21128 if (datasz != 4)
21129 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21130 datasz);
21131 else
21132 {
21133 printf ("x86 ISA needed: ");
21134 decode_x86_compat_isa (bitmask);
aa7bca9b 21135 }
ee2fdd6f
L
21136 goto next;
21137
32930e4e
L
21138 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21139 if (datasz != 4)
21140 printf (_("x86 ISA used: <corrupt length: %#x> "),
21141 datasz);
21142 else
21143 {
21144 printf ("x86 ISA used: ");
21145 decode_x86_compat_2_isa (bitmask);
21146 }
21147 goto next;
21148
21149 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21150 if (datasz != 4)
21151 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21152 datasz);
21153 else
21154 {
21155 printf ("x86 ISA needed: ");
21156 decode_x86_compat_2_isa (bitmask);
21157 }
21158 goto next;
21159
1fc87489
L
21160 default:
21161 break;
21162 }
21163 }
cd702818
SD
21164 else if (filedata->file_header.e_machine == EM_AARCH64)
21165 {
21166 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21167 {
21168 printf ("AArch64 feature: ");
21169 if (datasz != 4)
21170 printf (_("<corrupt length: %#x> "), datasz);
21171 else
21172 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21173 goto next;
21174 }
21175 }
1fc87489
L
21176 }
21177 else
21178 {
21179 switch (type)
9ef920e9 21180 {
1fc87489
L
21181 case GNU_PROPERTY_STACK_SIZE:
21182 printf (_("stack size: "));
21183 if (datasz != size)
21184 printf (_("<corrupt length: %#x> "), datasz);
21185 else
26c527e6 21186 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
21187 goto next;
21188
21189 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21190 printf ("no copy on protected ");
21191 if (datasz)
21192 printf (_("<corrupt length: %#x> "), datasz);
21193 goto next;
21194
21195 default:
5a767724
L
21196 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21197 && type <= GNU_PROPERTY_UINT32_AND_HI)
21198 || (type >= GNU_PROPERTY_UINT32_OR_LO
21199 && type <= GNU_PROPERTY_UINT32_OR_HI))
21200 {
6320fd00
L
21201 switch (type)
21202 {
21203 case GNU_PROPERTY_1_NEEDED:
21204 if (datasz != 4)
21205 printf (_("1_needed: <corrupt length: %#x> "),
21206 datasz);
21207 else
21208 {
21209 unsigned int bitmask = byte_get (ptr, 4);
21210 printf ("1_needed: ");
21211 decode_1_needed (bitmask);
21212 }
21213 goto next;
21214
21215 default:
21216 break;
21217 }
5a767724
L
21218 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21219 printf (_("UINT32_AND (%#x): "), type);
21220 else
21221 printf (_("UINT32_OR (%#x): "), type);
21222 if (datasz != 4)
21223 printf (_("<corrupt length: %#x> "), datasz);
21224 else
21225 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21226 goto next;
21227 }
9ef920e9
NC
21228 break;
21229 }
9ef920e9
NC
21230 }
21231
1fc87489
L
21232 if (type < GNU_PROPERTY_LOPROC)
21233 printf (_("<unknown type %#x data: "), type);
21234 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 21235 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
21236 else
21237 printf (_("<application-specific type %#x data: "), type);
21238 for (j = 0; j < datasz; ++j)
21239 printf ("%02x ", ptr[j] & 0xff);
21240 printf (">");
21241
dc1e8a47 21242 next:
9ef920e9 21243 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
21244 if (ptr == ptr_end)
21245 break;
1fc87489 21246
6ab2c4ed
MC
21247 if (do_wide)
21248 printf (", ");
21249 else
21250 printf ("\n\t");
9ef920e9
NC
21251 }
21252
21253 printf ("\n");
21254}
21255
015dc7e1 21256static bool
dda8d76d 21257print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 21258{
1449284b 21259 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
21260 switch (pnote->type)
21261 {
21262 case NT_GNU_BUILD_ID:
21263 {
26c527e6 21264 size_t i;
664f90a3
TT
21265
21266 printf (_(" Build ID: "));
21267 for (i = 0; i < pnote->descsz; ++i)
21268 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 21269 printf ("\n");
664f90a3
TT
21270 }
21271 break;
21272
21273 case NT_GNU_ABI_TAG:
21274 {
26c527e6 21275 unsigned int os, major, minor, subminor;
664f90a3
TT
21276 const char *osname;
21277
3102e897
NC
21278 /* PR 17531: file: 030-599401-0.004. */
21279 if (pnote->descsz < 16)
21280 {
21281 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21282 break;
21283 }
21284
664f90a3
TT
21285 os = byte_get ((unsigned char *) pnote->descdata, 4);
21286 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21287 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21288 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21289
21290 switch (os)
21291 {
21292 case GNU_ABI_TAG_LINUX:
21293 osname = "Linux";
21294 break;
21295 case GNU_ABI_TAG_HURD:
21296 osname = "Hurd";
21297 break;
21298 case GNU_ABI_TAG_SOLARIS:
21299 osname = "Solaris";
21300 break;
21301 case GNU_ABI_TAG_FREEBSD:
21302 osname = "FreeBSD";
21303 break;
21304 case GNU_ABI_TAG_NETBSD:
21305 osname = "NetBSD";
21306 break;
14ae95f2
RM
21307 case GNU_ABI_TAG_SYLLABLE:
21308 osname = "Syllable";
21309 break;
21310 case GNU_ABI_TAG_NACL:
21311 osname = "NaCl";
21312 break;
664f90a3
TT
21313 default:
21314 osname = "Unknown";
21315 break;
21316 }
21317
26c527e6 21318 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21319 major, minor, subminor);
21320 }
21321 break;
926c5385
CC
21322
21323 case NT_GNU_GOLD_VERSION:
21324 {
26c527e6 21325 size_t i;
926c5385
CC
21326
21327 printf (_(" Version: "));
21328 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21329 printf ("%c", pnote->descdata[i]);
21330 printf ("\n");
21331 }
21332 break;
1449284b
NC
21333
21334 case NT_GNU_HWCAP:
21335 {
26c527e6 21336 unsigned int num_entries, mask;
1449284b
NC
21337
21338 /* Hardware capabilities information. Word 0 is the number of entries.
21339 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21340 is a series of entries, where each entry is a single byte followed
21341 by a nul terminated string. The byte gives the bit number to test
21342 if enabled in the bitmask. */
21343 printf (_(" Hardware Capabilities: "));
21344 if (pnote->descsz < 8)
21345 {
32ec8896 21346 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21347 return false;
1449284b
NC
21348 }
21349 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21350 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21351 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21352 /* FIXME: Add code to display the entries... */
21353 }
21354 break;
21355
9ef920e9 21356 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21357 print_gnu_property_note (filedata, pnote);
9ef920e9 21358 break;
9abca702 21359
1449284b
NC
21360 default:
21361 /* Handle unrecognised types. An error message should have already been
21362 created by get_gnu_elf_note_type(), so all that we need to do is to
21363 display the data. */
21364 {
26c527e6 21365 size_t i;
1449284b
NC
21366
21367 printf (_(" Description data: "));
21368 for (i = 0; i < pnote->descsz; ++i)
21369 printf ("%02x ", pnote->descdata[i] & 0xff);
21370 printf ("\n");
21371 }
21372 break;
664f90a3
TT
21373 }
21374
015dc7e1 21375 return true;
664f90a3
TT
21376}
21377
685080f2
NC
21378static const char *
21379get_v850_elf_note_type (enum v850_notes n_type)
21380{
21381 static char buff[64];
21382
21383 switch (n_type)
21384 {
21385 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21386 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21387 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21388 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21389 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21390 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21391 default:
21392 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21393 return buff;
21394 }
21395}
21396
015dc7e1 21397static bool
685080f2
NC
21398print_v850_note (Elf_Internal_Note * pnote)
21399{
21400 unsigned int val;
21401
21402 if (pnote->descsz != 4)
015dc7e1 21403 return false;
32ec8896 21404
685080f2
NC
21405 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21406
21407 if (val == 0)
21408 {
21409 printf (_("not set\n"));
015dc7e1 21410 return true;
685080f2
NC
21411 }
21412
21413 switch (pnote->type)
21414 {
21415 case V850_NOTE_ALIGNMENT:
21416 switch (val)
21417 {
015dc7e1
AM
21418 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21419 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21420 }
21421 break;
14ae95f2 21422
685080f2
NC
21423 case V850_NOTE_DATA_SIZE:
21424 switch (val)
21425 {
015dc7e1
AM
21426 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21427 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21428 }
21429 break;
14ae95f2 21430
685080f2
NC
21431 case V850_NOTE_FPU_INFO:
21432 switch (val)
21433 {
015dc7e1
AM
21434 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21435 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21436 }
21437 break;
14ae95f2 21438
685080f2
NC
21439 case V850_NOTE_MMU_INFO:
21440 case V850_NOTE_CACHE_INFO:
21441 case V850_NOTE_SIMD_INFO:
21442 if (val == EF_RH850_SIMD)
21443 {
21444 printf (_("yes\n"));
015dc7e1 21445 return true;
685080f2
NC
21446 }
21447 break;
21448
21449 default:
21450 /* An 'unknown note type' message will already have been displayed. */
21451 break;
21452 }
21453
21454 printf (_("unknown value: %x\n"), val);
015dc7e1 21455 return false;
685080f2
NC
21456}
21457
015dc7e1 21458static bool
c6056a74
SF
21459process_netbsd_elf_note (Elf_Internal_Note * pnote)
21460{
21461 unsigned int version;
21462
21463 switch (pnote->type)
21464 {
21465 case NT_NETBSD_IDENT:
b966f55f
AM
21466 if (pnote->descsz < 1)
21467 break;
c6056a74
SF
21468 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21469 if ((version / 10000) % 100)
b966f55f 21470 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21471 version, version / 100000000, (version / 1000000) % 100,
21472 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21473 'A' + (version / 10000) % 26);
c6056a74
SF
21474 else
21475 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21476 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21477 (version / 100) % 100);
015dc7e1 21478 return true;
c6056a74
SF
21479
21480 case NT_NETBSD_MARCH:
9abca702 21481 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21482 pnote->descdata);
015dc7e1 21483 return true;
c6056a74 21484
9abca702 21485 case NT_NETBSD_PAX:
b966f55f
AM
21486 if (pnote->descsz < 1)
21487 break;
9abca702
CZ
21488 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21489 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21490 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21491 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21492 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21493 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21494 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21495 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21496 return true;
c6056a74 21497 }
b966f55f
AM
21498
21499 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21500 pnote->descsz, pnote->type);
015dc7e1 21501 return false;
c6056a74
SF
21502}
21503
f4ddf30f 21504static const char *
dda8d76d 21505get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21506{
f4ddf30f
JB
21507 switch (e_type)
21508 {
21509 case NT_FREEBSD_THRMISC:
21510 return _("NT_THRMISC (thrmisc structure)");
21511 case NT_FREEBSD_PROCSTAT_PROC:
21512 return _("NT_PROCSTAT_PROC (proc data)");
21513 case NT_FREEBSD_PROCSTAT_FILES:
21514 return _("NT_PROCSTAT_FILES (files data)");
21515 case NT_FREEBSD_PROCSTAT_VMMAP:
21516 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21517 case NT_FREEBSD_PROCSTAT_GROUPS:
21518 return _("NT_PROCSTAT_GROUPS (groups data)");
21519 case NT_FREEBSD_PROCSTAT_UMASK:
21520 return _("NT_PROCSTAT_UMASK (umask data)");
21521 case NT_FREEBSD_PROCSTAT_RLIMIT:
21522 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21523 case NT_FREEBSD_PROCSTAT_OSREL:
21524 return _("NT_PROCSTAT_OSREL (osreldate data)");
21525 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21526 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21527 case NT_FREEBSD_PROCSTAT_AUXV:
21528 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21529 case NT_FREEBSD_PTLWPINFO:
21530 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21531 case NT_FREEBSD_X86_SEGBASES:
21532 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21533 }
dda8d76d 21534 return get_note_type (filedata, e_type);
f4ddf30f
JB
21535}
21536
9437c45b 21537static const char *
dda8d76d 21538get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21539{
21540 static char buff[64];
21541
540e6170
CZ
21542 switch (e_type)
21543 {
21544 case NT_NETBSDCORE_PROCINFO:
21545 /* NetBSD core "procinfo" structure. */
21546 return _("NetBSD procinfo structure");
9437c45b 21547
540e6170
CZ
21548 case NT_NETBSDCORE_AUXV:
21549 return _("NetBSD ELF auxiliary vector data");
9437c45b 21550
06d949ec
KR
21551 case NT_NETBSDCORE_LWPSTATUS:
21552 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21553
540e6170 21554 default:
06d949ec 21555 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21556 defined for NetBSD core files. If the note type is less
21557 than the start of the machine-dependent note types, we don't
21558 understand it. */
21559
21560 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21561 {
21562 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21563 return buff;
21564 }
21565 break;
9437c45b
JT
21566 }
21567
dda8d76d 21568 switch (filedata->file_header.e_machine)
9437c45b
JT
21569 {
21570 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21571 and PT_GETFPREGS == mach+2. */
21572
21573 case EM_OLD_ALPHA:
21574 case EM_ALPHA:
21575 case EM_SPARC:
21576 case EM_SPARC32PLUS:
21577 case EM_SPARCV9:
21578 switch (e_type)
21579 {
2b692964 21580 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21581 return _("PT_GETREGS (reg structure)");
2b692964 21582 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21583 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21584 default:
21585 break;
21586 }
21587 break;
21588
c0d38b0e
CZ
21589 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21590 There's also old PT___GETREGS40 == mach + 1 for old reg
21591 structure which lacks GBR. */
21592 case EM_SH:
21593 switch (e_type)
21594 {
21595 case NT_NETBSDCORE_FIRSTMACH + 1:
21596 return _("PT___GETREGS40 (old reg structure)");
21597 case NT_NETBSDCORE_FIRSTMACH + 3:
21598 return _("PT_GETREGS (reg structure)");
21599 case NT_NETBSDCORE_FIRSTMACH + 5:
21600 return _("PT_GETFPREGS (fpreg structure)");
21601 default:
21602 break;
21603 }
21604 break;
21605
9437c45b
JT
21606 /* On all other arch's, PT_GETREGS == mach+1 and
21607 PT_GETFPREGS == mach+3. */
21608 default:
21609 switch (e_type)
21610 {
2b692964 21611 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21612 return _("PT_GETREGS (reg structure)");
2b692964 21613 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21614 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21615 default:
21616 break;
21617 }
21618 }
21619
9cf03b7e 21620 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21621 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21622 return buff;
21623}
21624
98ca73af
FC
21625static const char *
21626get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21627{
21628 switch (e_type)
21629 {
21630 case NT_OPENBSD_PROCINFO:
21631 return _("OpenBSD procinfo structure");
21632 case NT_OPENBSD_AUXV:
21633 return _("OpenBSD ELF auxiliary vector data");
21634 case NT_OPENBSD_REGS:
21635 return _("OpenBSD regular registers");
21636 case NT_OPENBSD_FPREGS:
21637 return _("OpenBSD floating point registers");
21638 case NT_OPENBSD_WCOOKIE:
21639 return _("OpenBSD window cookie");
21640 }
21641
21642 return get_note_type (filedata, e_type);
21643}
21644
e263a66b
CC
21645static const char *
21646get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21647{
21648 switch (e_type)
21649 {
21650 case QNT_DEBUG_FULLPATH:
21651 return _("QNX debug fullpath");
21652 case QNT_DEBUG_RELOC:
21653 return _("QNX debug relocation");
21654 case QNT_STACK:
21655 return _("QNX stack");
21656 case QNT_GENERATOR:
21657 return _("QNX generator");
21658 case QNT_DEFAULT_LIB:
21659 return _("QNX default library");
21660 case QNT_CORE_SYSINFO:
21661 return _("QNX core sysinfo");
21662 case QNT_CORE_INFO:
21663 return _("QNX core info");
21664 case QNT_CORE_STATUS:
21665 return _("QNX core status");
21666 case QNT_CORE_GREG:
21667 return _("QNX general registers");
21668 case QNT_CORE_FPREG:
21669 return _("QNX floating point registers");
21670 case QNT_LINK_MAP:
21671 return _("QNX link map");
21672 }
21673
21674 return get_note_type (filedata, e_type);
21675}
21676
70616151
TT
21677static const char *
21678get_stapsdt_note_type (unsigned e_type)
21679{
21680 static char buff[64];
21681
21682 switch (e_type)
21683 {
21684 case NT_STAPSDT:
21685 return _("NT_STAPSDT (SystemTap probe descriptors)");
21686
21687 default:
21688 break;
21689 }
21690
21691 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21692 return buff;
21693}
21694
015dc7e1 21695static bool
c6a9fc58
TT
21696print_stapsdt_note (Elf_Internal_Note *pnote)
21697{
3ca60c57 21698 size_t len, maxlen;
26c527e6 21699 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21700 char *data = pnote->descdata;
21701 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21702 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21703 char *provider, *probe, *arg_fmt;
21704
3ca60c57
NC
21705 if (pnote->descsz < (addr_size * 3))
21706 goto stapdt_note_too_small;
21707
c6a9fc58
TT
21708 pc = byte_get ((unsigned char *) data, addr_size);
21709 data += addr_size;
3ca60c57 21710
c6a9fc58
TT
21711 base_addr = byte_get ((unsigned char *) data, addr_size);
21712 data += addr_size;
3ca60c57 21713
c6a9fc58
TT
21714 semaphore = byte_get ((unsigned char *) data, addr_size);
21715 data += addr_size;
21716
3ca60c57
NC
21717 if (data >= data_end)
21718 goto stapdt_note_too_small;
21719 maxlen = data_end - data;
21720 len = strnlen (data, maxlen);
21721 if (len < maxlen)
21722 {
21723 provider = data;
21724 data += len + 1;
21725 }
21726 else
21727 goto stapdt_note_too_small;
21728
21729 if (data >= data_end)
21730 goto stapdt_note_too_small;
21731 maxlen = data_end - data;
21732 len = strnlen (data, maxlen);
21733 if (len < maxlen)
21734 {
21735 probe = data;
21736 data += len + 1;
21737 }
21738 else
21739 goto stapdt_note_too_small;
9abca702 21740
3ca60c57
NC
21741 if (data >= data_end)
21742 goto stapdt_note_too_small;
21743 maxlen = data_end - data;
21744 len = strnlen (data, maxlen);
21745 if (len < maxlen)
21746 {
21747 arg_fmt = data;
21748 data += len + 1;
21749 }
21750 else
21751 goto stapdt_note_too_small;
c6a9fc58
TT
21752
21753 printf (_(" Provider: %s\n"), provider);
21754 printf (_(" Name: %s\n"), probe);
21755 printf (_(" Location: "));
21756 print_vma (pc, FULL_HEX);
21757 printf (_(", Base: "));
21758 print_vma (base_addr, FULL_HEX);
21759 printf (_(", Semaphore: "));
21760 print_vma (semaphore, FULL_HEX);
9cf03b7e 21761 printf ("\n");
c6a9fc58
TT
21762 printf (_(" Arguments: %s\n"), arg_fmt);
21763
21764 return data == data_end;
3ca60c57
NC
21765
21766 stapdt_note_too_small:
21767 printf (_(" <corrupt - note is too small>\n"));
21768 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21769 return false;
c6a9fc58
TT
21770}
21771
e5382207
LB
21772static bool
21773print_fdo_note (Elf_Internal_Note * pnote)
21774{
21775 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21776 {
21777 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21778 return true;
21779 }
21780 return false;
21781}
21782
00e98fc7
TG
21783static const char *
21784get_ia64_vms_note_type (unsigned e_type)
21785{
21786 static char buff[64];
21787
21788 switch (e_type)
21789 {
21790 case NT_VMS_MHD:
21791 return _("NT_VMS_MHD (module header)");
21792 case NT_VMS_LNM:
21793 return _("NT_VMS_LNM (language name)");
21794 case NT_VMS_SRC:
21795 return _("NT_VMS_SRC (source files)");
21796 case NT_VMS_TITLE:
9cf03b7e 21797 return "NT_VMS_TITLE";
00e98fc7
TG
21798 case NT_VMS_EIDC:
21799 return _("NT_VMS_EIDC (consistency check)");
21800 case NT_VMS_FPMODE:
21801 return _("NT_VMS_FPMODE (FP mode)");
21802 case NT_VMS_LINKTIME:
9cf03b7e 21803 return "NT_VMS_LINKTIME";
00e98fc7
TG
21804 case NT_VMS_IMGNAM:
21805 return _("NT_VMS_IMGNAM (image name)");
21806 case NT_VMS_IMGID:
21807 return _("NT_VMS_IMGID (image id)");
21808 case NT_VMS_LINKID:
21809 return _("NT_VMS_LINKID (link id)");
21810 case NT_VMS_IMGBID:
21811 return _("NT_VMS_IMGBID (build id)");
21812 case NT_VMS_GSTNAM:
21813 return _("NT_VMS_GSTNAM (sym table name)");
21814 case NT_VMS_ORIG_DYN:
9cf03b7e 21815 return "NT_VMS_ORIG_DYN";
00e98fc7 21816 case NT_VMS_PATCHTIME:
9cf03b7e 21817 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21818 default:
21819 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21820 return buff;
21821 }
21822}
21823
015dc7e1 21824static bool
00e98fc7
TG
21825print_ia64_vms_note (Elf_Internal_Note * pnote)
21826{
26c527e6 21827 unsigned int maxlen = pnote->descsz;
8d18bf79 21828
26c527e6 21829 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21830 goto desc_size_fail;
21831
00e98fc7
TG
21832 switch (pnote->type)
21833 {
21834 case NT_VMS_MHD:
8d18bf79
NC
21835 if (maxlen <= 36)
21836 goto desc_size_fail;
21837
26c527e6 21838 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21839
21840 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21841 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21842 if (l + 34 < maxlen)
21843 {
21844 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21845 if (l + 35 < maxlen)
21846 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21847 else
21848 printf (_(" Module version : <missing>\n"));
21849 }
00e98fc7 21850 else
8d18bf79
NC
21851 {
21852 printf (_(" Module name : <missing>\n"));
21853 printf (_(" Module version : <missing>\n"));
21854 }
00e98fc7 21855 break;
8d18bf79 21856
00e98fc7 21857 case NT_VMS_LNM:
8d18bf79 21858 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21859 break;
8d18bf79 21860
00e98fc7 21861 case NT_VMS_FPMODE:
9cf03b7e 21862 printf (_(" Floating Point mode: "));
8d18bf79
NC
21863 if (maxlen < 8)
21864 goto desc_size_fail;
21865 /* FIXME: Generate an error if descsz > 8 ? */
21866
b8281767 21867 printf ("0x%016" PRIx64 "\n",
625d49fc 21868 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21869 break;
8d18bf79 21870
00e98fc7
TG
21871 case NT_VMS_LINKTIME:
21872 printf (_(" Link time: "));
8d18bf79
NC
21873 if (maxlen < 8)
21874 goto desc_size_fail;
21875 /* FIXME: Generate an error if descsz > 8 ? */
21876
0e3c1eeb 21877 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21878 printf ("\n");
21879 break;
8d18bf79 21880
00e98fc7
TG
21881 case NT_VMS_PATCHTIME:
21882 printf (_(" Patch time: "));
8d18bf79
NC
21883 if (maxlen < 8)
21884 goto desc_size_fail;
21885 /* FIXME: Generate an error if descsz > 8 ? */
21886
0e3c1eeb 21887 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21888 printf ("\n");
21889 break;
8d18bf79 21890
00e98fc7 21891 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21892 if (maxlen < 34)
21893 goto desc_size_fail;
21894
00e98fc7 21895 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21896 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21897 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21898 printf (_(" Last modified : "));
0e3c1eeb 21899 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21900 printf (_("\n Link flags : "));
b8281767 21901 printf ("0x%016" PRIx64 "\n",
625d49fc 21902 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21903 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21904 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21905 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21906 break;
8d18bf79 21907
00e98fc7 21908 case NT_VMS_IMGNAM:
8d18bf79 21909 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21910 break;
8d18bf79 21911
00e98fc7 21912 case NT_VMS_GSTNAM:
8d18bf79 21913 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21914 break;
8d18bf79 21915
00e98fc7 21916 case NT_VMS_IMGID:
8d18bf79 21917 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21918 break;
8d18bf79 21919
00e98fc7 21920 case NT_VMS_LINKID:
8d18bf79 21921 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21922 break;
8d18bf79 21923
00e98fc7 21924 default:
015dc7e1 21925 return false;
00e98fc7 21926 }
8d18bf79 21927
015dc7e1 21928 return true;
8d18bf79
NC
21929
21930 desc_size_fail:
21931 printf (_(" <corrupt - data size is too small>\n"));
21932 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21933 return false;
00e98fc7
TG
21934}
21935
fd486f32
AM
21936struct build_attr_cache {
21937 Filedata *filedata;
21938 char *strtab;
26c527e6 21939 uint64_t strtablen;
fd486f32 21940 Elf_Internal_Sym *symtab;
26c527e6 21941 uint64_t nsyms;
fd486f32
AM
21942} ba_cache;
21943
6f156d7a
NC
21944/* Find the symbol associated with a build attribute that is attached
21945 to address OFFSET. If PNAME is non-NULL then store the name of
21946 the symbol (if found) in the provided pointer, Returns NULL if a
21947 symbol could not be found. */
c799a79d 21948
6f156d7a 21949static Elf_Internal_Sym *
015dc7e1 21950get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21951 uint64_t offset,
015dc7e1
AM
21952 bool is_open_attr,
21953 const char **pname)
9ef920e9 21954{
fd486f32
AM
21955 Elf_Internal_Sym *saved_sym = NULL;
21956 Elf_Internal_Sym *sym;
9ef920e9 21957
dda8d76d 21958 if (filedata->section_headers != NULL
fd486f32 21959 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21960 {
c799a79d 21961 Elf_Internal_Shdr * symsec;
9ef920e9 21962
fd486f32
AM
21963 free (ba_cache.strtab);
21964 ba_cache.strtab = NULL;
21965 free (ba_cache.symtab);
21966 ba_cache.symtab = NULL;
21967
c799a79d 21968 /* Load the symbol and string sections. */
dda8d76d
NC
21969 for (symsec = filedata->section_headers;
21970 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21971 symsec ++)
9ef920e9 21972 {
28d13567
AM
21973 if (symsec->sh_type == SHT_SYMTAB
21974 && get_symtab (filedata, symsec,
21975 &ba_cache.symtab, &ba_cache.nsyms,
21976 &ba_cache.strtab, &ba_cache.strtablen))
21977 break;
9ef920e9 21978 }
fd486f32 21979 ba_cache.filedata = filedata;
9ef920e9
NC
21980 }
21981
fd486f32 21982 if (ba_cache.symtab == NULL)
6f156d7a 21983 return NULL;
9ef920e9 21984
c799a79d 21985 /* Find a symbol whose value matches offset. */
fd486f32 21986 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21987 if (sym->st_value == offset)
21988 {
fd486f32 21989 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21990 /* Huh ? This should not happen. */
21991 continue;
9ef920e9 21992
fd486f32 21993 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21994 continue;
9ef920e9 21995
9b9b1092 21996 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21997 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21998 if (ba_cache.strtab[sym->st_name] == '$'
21999 && ba_cache.strtab[sym->st_name + 1] != 0
22000 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
22001 continue;
22002
c799a79d
NC
22003 if (is_open_attr)
22004 {
22005 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22006 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22007 FUNC symbols entirely. */
22008 switch (ELF_ST_TYPE (sym->st_info))
22009 {
c799a79d 22010 case STT_OBJECT:
6f156d7a 22011 case STT_FILE:
c799a79d 22012 saved_sym = sym;
6f156d7a
NC
22013 if (sym->st_size)
22014 {
22015 /* If the symbol has a size associated
22016 with it then we can stop searching. */
fd486f32 22017 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 22018 }
c799a79d 22019 continue;
9ef920e9 22020
c799a79d
NC
22021 case STT_FUNC:
22022 /* Ignore function symbols. */
22023 continue;
22024
22025 default:
22026 break;
22027 }
22028
22029 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 22030 {
c799a79d
NC
22031 case STB_GLOBAL:
22032 if (saved_sym == NULL
22033 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22034 saved_sym = sym;
22035 break;
c871dade 22036
c799a79d
NC
22037 case STB_LOCAL:
22038 if (saved_sym == NULL)
22039 saved_sym = sym;
22040 break;
22041
22042 default:
9ef920e9
NC
22043 break;
22044 }
22045 }
c799a79d
NC
22046 else
22047 {
22048 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22049 continue;
22050
22051 saved_sym = sym;
22052 break;
22053 }
22054 }
22055
6f156d7a 22056 if (saved_sym && pname)
fd486f32 22057 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
22058
22059 return saved_sym;
c799a79d
NC
22060}
22061
d20e98ab
NC
22062/* Returns true iff addr1 and addr2 are in the same section. */
22063
015dc7e1 22064static bool
26c527e6 22065same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
22066{
22067 Elf_Internal_Shdr * a1;
22068 Elf_Internal_Shdr * a2;
22069
22070 a1 = find_section_by_address (filedata, addr1);
22071 a2 = find_section_by_address (filedata, addr2);
9abca702 22072
d20e98ab
NC
22073 return a1 == a2 && a1 != NULL;
22074}
22075
015dc7e1 22076static bool
dda8d76d
NC
22077print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22078 Filedata * filedata)
c799a79d 22079{
26c527e6
AM
22080 static uint64_t global_offset = 0;
22081 static uint64_t global_end = 0;
22082 static uint64_t func_offset = 0;
22083 static uint64_t func_end = 0;
c871dade 22084
015dc7e1
AM
22085 Elf_Internal_Sym *sym;
22086 const char *name;
26c527e6
AM
22087 uint64_t start;
22088 uint64_t end;
015dc7e1 22089 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
22090
22091 switch (pnote->descsz)
c799a79d 22092 {
6f156d7a
NC
22093 case 0:
22094 /* A zero-length description means that the range of
22095 the previous note of the same type should be used. */
c799a79d 22096 if (is_open_attr)
c871dade 22097 {
6f156d7a 22098 if (global_end > global_offset)
26c527e6
AM
22099 printf (_(" Applies to region from %#" PRIx64
22100 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 22101 else
26c527e6
AM
22102 printf (_(" Applies to region from %#" PRIx64
22103 "\n"), global_offset);
c799a79d
NC
22104 }
22105 else
22106 {
6f156d7a 22107 if (func_end > func_offset)
26c527e6
AM
22108 printf (_(" Applies to region from %#" PRIx64
22109 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 22110 else
26c527e6
AM
22111 printf (_(" Applies to region from %#" PRIx64
22112 "\n"), func_offset);
c871dade 22113 }
015dc7e1 22114 return true;
9ef920e9 22115
6f156d7a
NC
22116 case 4:
22117 start = byte_get ((unsigned char *) pnote->descdata, 4);
22118 end = 0;
22119 break;
22120
22121 case 8:
c74147bb
NC
22122 start = byte_get ((unsigned char *) pnote->descdata, 4);
22123 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
22124 break;
22125
22126 case 16:
22127 start = byte_get ((unsigned char *) pnote->descdata, 8);
22128 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22129 break;
9abca702 22130
6f156d7a 22131 default:
c799a79d
NC
22132 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22133 printf (_(" <invalid descsz>"));
015dc7e1 22134 return false;
c799a79d
NC
22135 }
22136
6f156d7a
NC
22137 name = NULL;
22138 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
22139 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22140 in order to avoid them being confused with the start address of the
22141 first function in the file... */
22142 if (sym == NULL && is_open_attr)
22143 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22144 & name);
6f156d7a
NC
22145
22146 if (end == 0 && sym != NULL && sym->st_size > 0)
22147 end = start + sym->st_size;
c799a79d
NC
22148
22149 if (is_open_attr)
22150 {
d20e98ab
NC
22151 /* FIXME: Need to properly allow for section alignment.
22152 16 is just the alignment used on x86_64. */
22153 if (global_end > 0
22154 && start > BFD_ALIGN (global_end, 16)
22155 /* Build notes are not guaranteed to be organised in order of
22156 increasing address, but we should find the all of the notes
22157 for one section in the same place. */
22158 && same_section (filedata, start, global_end))
26c527e6
AM
22159 warn (_("Gap in build notes detected from %#" PRIx64
22160 " to %#" PRIx64 "\n"),
6f156d7a
NC
22161 global_end + 1, start - 1);
22162
26c527e6 22163 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22164 global_offset = start;
22165
22166 if (end)
22167 {
26c527e6 22168 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22169 global_end = end;
22170 }
c799a79d
NC
22171 }
22172 else
22173 {
26c527e6 22174 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22175 func_offset = start;
22176
22177 if (end)
22178 {
26c527e6 22179 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22180 func_end = end;
22181 }
c799a79d
NC
22182 }
22183
6f156d7a
NC
22184 if (sym && name)
22185 printf (_(" (%s)"), name);
22186
22187 printf ("\n");
015dc7e1 22188 return true;
9ef920e9
NC
22189}
22190
015dc7e1 22191static bool
9ef920e9
NC
22192print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22193{
1d15e434
NC
22194 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22195 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22196 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
22197 char name_type;
22198 char name_attribute;
1d15e434 22199 const char * expected_types;
9ef920e9
NC
22200 const char * name = pnote->namedata;
22201 const char * text;
88305e1b 22202 signed int left;
9ef920e9
NC
22203
22204 if (name == NULL || pnote->namesz < 2)
22205 {
22206 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22207 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22208 return false;
9ef920e9
NC
22209 }
22210
6f156d7a
NC
22211 if (do_wide)
22212 left = 28;
22213 else
22214 left = 20;
88305e1b
NC
22215
22216 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22217 if (name[0] == 'G' && name[1] == 'A')
22218 {
6f156d7a
NC
22219 if (pnote->namesz < 4)
22220 {
22221 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22222 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22223 return false;
6f156d7a
NC
22224 }
22225
88305e1b
NC
22226 printf ("GA");
22227 name += 2;
22228 left -= 2;
22229 }
22230
9ef920e9
NC
22231 switch ((name_type = * name))
22232 {
22233 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22234 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22235 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22236 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22237 printf ("%c", * name);
88305e1b 22238 left --;
9ef920e9
NC
22239 break;
22240 default:
22241 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 22242 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 22243 return false;
9ef920e9
NC
22244 }
22245
9ef920e9
NC
22246 ++ name;
22247 text = NULL;
22248
22249 switch ((name_attribute = * name))
22250 {
22251 case GNU_BUILD_ATTRIBUTE_VERSION:
22252 text = _("<version>");
1d15e434 22253 expected_types = string_expected;
9ef920e9
NC
22254 ++ name;
22255 break;
22256 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22257 text = _("<stack prot>");
75d7d298 22258 expected_types = "!+*";
9ef920e9
NC
22259 ++ name;
22260 break;
22261 case GNU_BUILD_ATTRIBUTE_RELRO:
22262 text = _("<relro>");
1d15e434 22263 expected_types = bool_expected;
9ef920e9
NC
22264 ++ name;
22265 break;
22266 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22267 text = _("<stack size>");
1d15e434 22268 expected_types = number_expected;
9ef920e9
NC
22269 ++ name;
22270 break;
22271 case GNU_BUILD_ATTRIBUTE_TOOL:
22272 text = _("<tool>");
1d15e434 22273 expected_types = string_expected;
9ef920e9
NC
22274 ++ name;
22275 break;
22276 case GNU_BUILD_ATTRIBUTE_ABI:
22277 text = _("<ABI>");
22278 expected_types = "$*";
22279 ++ name;
22280 break;
22281 case GNU_BUILD_ATTRIBUTE_PIC:
22282 text = _("<PIC>");
1d15e434 22283 expected_types = number_expected;
9ef920e9
NC
22284 ++ name;
22285 break;
a8be5506
NC
22286 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22287 text = _("<short enum>");
1d15e434 22288 expected_types = bool_expected;
a8be5506
NC
22289 ++ name;
22290 break;
9ef920e9
NC
22291 default:
22292 if (ISPRINT (* name))
22293 {
22294 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22295
22296 if (len > left && ! do_wide)
22297 len = left;
75d7d298 22298 printf ("%.*s:", len, name);
9ef920e9 22299 left -= len;
0dd6ae21 22300 name += len;
9ef920e9
NC
22301 }
22302 else
22303 {
3e6b6445 22304 static char tmpbuf [128];
88305e1b 22305
3e6b6445
NC
22306 error (_("unrecognised byte in name field: %d\n"), * name);
22307 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22308 text = tmpbuf;
22309 name ++;
9ef920e9
NC
22310 }
22311 expected_types = "*$!+";
22312 break;
22313 }
22314
22315 if (text)
88305e1b 22316 left -= printf ("%s", text);
9ef920e9
NC
22317
22318 if (strchr (expected_types, name_type) == NULL)
75d7d298 22319 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22320
26c527e6 22321 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22322 {
26c527e6
AM
22323 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22324 pnote->namesz,
22325 name - pnote->namedata);
015dc7e1 22326 return false;
9ef920e9
NC
22327 }
22328
22329 if (left < 1 && ! do_wide)
015dc7e1 22330 return true;
9ef920e9
NC
22331
22332 switch (name_type)
22333 {
22334 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22335 {
26c527e6
AM
22336 unsigned int bytes;
22337 uint64_t val = 0;
22338 unsigned int shift = 0;
22339 char *decoded = NULL;
ddef72cd 22340
b06b2c92
NC
22341 bytes = pnote->namesz - (name - pnote->namedata);
22342 if (bytes > 0)
22343 /* The -1 is because the name field is always 0 terminated, and we
22344 want to be able to ensure that the shift in the while loop below
22345 will not overflow. */
22346 -- bytes;
22347
ddef72cd
NC
22348 if (bytes > sizeof (val))
22349 {
3e6b6445
NC
22350 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22351 bytes);
22352 bytes = sizeof (val);
ddef72cd 22353 }
3e6b6445
NC
22354 /* We do not bother to warn if bytes == 0 as this can
22355 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22356
22357 while (bytes --)
22358 {
26c527e6 22359 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22360
22361 val |= byte << shift;
9ef920e9
NC
22362 shift += 8;
22363 }
22364
75d7d298 22365 switch (name_attribute)
9ef920e9 22366 {
75d7d298 22367 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22368 switch (val)
22369 {
75d7d298
NC
22370 case 0: decoded = "static"; break;
22371 case 1: decoded = "pic"; break;
22372 case 2: decoded = "PIC"; break;
22373 case 3: decoded = "pie"; break;
22374 case 4: decoded = "PIE"; break;
22375 default: break;
9ef920e9 22376 }
75d7d298
NC
22377 break;
22378 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22379 switch (val)
9ef920e9 22380 {
75d7d298
NC
22381 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22382 case 0: decoded = "off"; break;
22383 case 1: decoded = "on"; break;
22384 case 2: decoded = "all"; break;
22385 case 3: decoded = "strong"; break;
22386 case 4: decoded = "explicit"; break;
22387 default: break;
9ef920e9 22388 }
75d7d298
NC
22389 break;
22390 default:
22391 break;
9ef920e9
NC
22392 }
22393
75d7d298 22394 if (decoded != NULL)
3e6b6445 22395 {
b6ac461a 22396 print_symbol_name (-left, decoded);
3e6b6445
NC
22397 left = 0;
22398 }
22399 else if (val == 0)
22400 {
22401 printf ("0x0");
22402 left -= 3;
22403 }
9ef920e9 22404 else
75d7d298
NC
22405 {
22406 if (do_wide)
26c527e6 22407 left -= printf ("0x%" PRIx64, val);
75d7d298 22408 else
26c527e6 22409 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22410 }
9ef920e9
NC
22411 }
22412 break;
22413 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22414 left -= print_symbol_name (- left, name);
9ef920e9
NC
22415 break;
22416 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22417 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22418 break;
22419 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22420 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22421 break;
22422 }
22423
22424 if (do_wide && left > 0)
22425 printf ("%-*s", left, " ");
9abca702 22426
015dc7e1 22427 return true;
9ef920e9
NC
22428}
22429
2952f10c
SM
22430/* Print the contents of PNOTE as hex. */
22431
22432static void
22433print_note_contents_hex (Elf_Internal_Note *pnote)
22434{
22435 if (pnote->descsz)
22436 {
26c527e6 22437 size_t i;
2952f10c
SM
22438
22439 printf (_(" description data: "));
22440 for (i = 0; i < pnote->descsz; i++)
22441 printf ("%02x ", pnote->descdata[i] & 0xff);
22442 if (!do_wide)
22443 printf ("\n");
22444 }
22445
22446 if (do_wide)
22447 printf ("\n");
22448}
22449
22450#if defined HAVE_MSGPACK
22451
22452static void
22453print_indents (int n)
22454{
22455 printf (" ");
22456
22457 for (int i = 0; i < n; i++)
22458 printf (" ");
22459}
22460
22461/* Print OBJ in human-readable form. */
22462
22463static void
22464dump_msgpack_obj (const msgpack_object *obj, int indent)
22465{
22466 switch (obj->type)
22467 {
22468 case MSGPACK_OBJECT_NIL:
22469 printf ("(nil)");
22470 break;
22471
22472 case MSGPACK_OBJECT_BOOLEAN:
22473 printf ("%s", obj->via.boolean ? "true" : "false");
22474 break;
22475
22476 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22477 printf ("%" PRIu64, obj->via.u64);
22478 break;
22479
22480 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22481 printf ("%" PRIi64, obj->via.i64);
22482 break;
22483
22484 case MSGPACK_OBJECT_FLOAT32:
22485 case MSGPACK_OBJECT_FLOAT64:
22486 printf ("%f", obj->via.f64);
22487 break;
22488
22489 case MSGPACK_OBJECT_STR:
22490 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22491 break;
22492
22493 case MSGPACK_OBJECT_ARRAY:
22494 {
22495 const msgpack_object_array *array = &obj->via.array;
22496
22497 printf ("[\n");
22498 ++indent;
22499
22500 for (uint32_t i = 0; i < array->size; ++i)
22501 {
22502 const msgpack_object *item = &array->ptr[i];
22503
22504 print_indents (indent);
22505 dump_msgpack_obj (item, indent);
22506 printf (",\n");
22507 }
22508
22509 --indent;
22510 print_indents (indent);
22511 printf ("]");
22512 break;
22513 }
22514 break;
22515
22516 case MSGPACK_OBJECT_MAP:
22517 {
22518 const msgpack_object_map *map = &obj->via.map;
22519
22520 printf ("{\n");
22521 ++indent;
22522
22523 for (uint32_t i = 0; i < map->size; ++i)
22524 {
22525 const msgpack_object_kv *kv = &map->ptr[i];
22526 const msgpack_object *key = &kv->key;
22527 const msgpack_object *val = &kv->val;
22528
22529 print_indents (indent);
22530 dump_msgpack_obj (key, indent);
22531 printf (": ");
22532 dump_msgpack_obj (val, indent);
22533
22534 printf (",\n");
22535 }
22536
22537 --indent;
22538 print_indents (indent);
22539 printf ("}");
22540
22541 break;
22542 }
22543
22544 case MSGPACK_OBJECT_BIN:
22545 printf ("(bin)");
22546 break;
22547
22548 case MSGPACK_OBJECT_EXT:
22549 printf ("(ext)");
22550 break;
22551 }
22552}
22553
22554static void
22555dump_msgpack (const msgpack_unpacked *msg)
22556{
22557 print_indents (0);
22558 dump_msgpack_obj (&msg->data, 0);
22559 printf ("\n");
22560}
22561
22562#endif /* defined HAVE_MSGPACK */
22563
22564static bool
22565print_amdgpu_note (Elf_Internal_Note *pnote)
22566{
22567#if defined HAVE_MSGPACK
22568 /* If msgpack is available, decode and dump the note's content. */
22569 bool ret;
22570 msgpack_unpacked msg;
22571 msgpack_unpack_return msgpack_ret;
22572
22573 assert (pnote->type == NT_AMDGPU_METADATA);
22574
22575 msgpack_unpacked_init (&msg);
22576 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22577 NULL);
22578
22579 switch (msgpack_ret)
22580 {
22581 case MSGPACK_UNPACK_SUCCESS:
22582 dump_msgpack (&msg);
22583 ret = true;
22584 break;
22585
22586 default:
22587 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22588 ret = false;
22589 break;
22590 }
22591
22592 msgpack_unpacked_destroy (&msg);
22593 return ret;
22594#else
22595 /* msgpack is not available, dump contents as hex. */
22596 print_note_contents_hex (pnote);
22597 return true;
22598#endif
22599}
22600
e263a66b
CC
22601static bool
22602print_qnx_note (Elf_Internal_Note *pnote)
22603{
22604 switch (pnote->type)
22605 {
22606 case QNT_STACK:
22607 if (pnote->descsz != 12)
22608 goto desc_size_fail;
22609
22610 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22611 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22612 printf (_(" Stack allocated: %" PRIx32 "\n"),
22613 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22614 printf (_(" Executable: %s\n"),
22615 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22616 break;
22617
22618 default:
22619 print_note_contents_hex(pnote);
22620 }
22621 return true;
22622
22623desc_size_fail:
22624 printf (_(" <corrupt - data size is too small>\n"));
22625 error (_("corrupt QNX note: data size is too small\n"));
22626 return false;
22627}
22628
22629
6d118b09
NC
22630/* Note that by the ELF standard, the name field is already null byte
22631 terminated, and namesz includes the terminating null byte.
22632 I.E. the value of namesz for the name "FSF" is 4.
22633
e3c8793a 22634 If the value of namesz is zero, there is no name present. */
9ef920e9 22635
015dc7e1 22636static bool
9ef920e9 22637process_note (Elf_Internal_Note * pnote,
dda8d76d 22638 Filedata * filedata)
779fe533 22639{
2cf0635d
NC
22640 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22641 const char * nt;
9437c45b
JT
22642
22643 if (pnote->namesz == 0)
1ec5cd37
NC
22644 /* If there is no note name, then use the default set of
22645 note type strings. */
dda8d76d 22646 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22647
24d127aa 22648 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22649 /* GNU-specific object file notes. */
22650 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22651
28cdbb18
SM
22652 else if (startswith (pnote->namedata, "AMDGPU"))
22653 /* AMDGPU-specific object file notes. */
22654 nt = get_amdgpu_elf_note_type (pnote->type);
22655
24d127aa 22656 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22657 /* FreeBSD-specific core file notes. */
dda8d76d 22658 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22659
24d127aa 22660 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22661 /* NetBSD-specific core file notes. */
dda8d76d 22662 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22663
24d127aa 22664 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22665 /* NetBSD-specific core file notes. */
22666 return process_netbsd_elf_note (pnote);
22667
24d127aa 22668 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22669 /* NetBSD-specific core file notes. */
22670 return process_netbsd_elf_note (pnote);
22671
98ca73af
FC
22672 else if (startswith (pnote->namedata, "OpenBSD"))
22673 /* OpenBSD-specific core file notes. */
22674 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22675
e263a66b
CC
22676 else if (startswith (pnote->namedata, "QNX"))
22677 /* QNX-specific core file notes. */
22678 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22679
e9b095a5 22680 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22681 {
22682 /* SPU-specific core file notes. */
22683 nt = pnote->namedata + 4;
22684 name = "SPU";
22685 }
22686
24d127aa 22687 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22688 /* VMS/ia64-specific file notes. */
22689 nt = get_ia64_vms_note_type (pnote->type);
22690
24d127aa 22691 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22692 nt = get_stapsdt_note_type (pnote->type);
22693
9437c45b 22694 else
1ec5cd37
NC
22695 /* Don't recognize this note name; just use the default set of
22696 note type strings. */
dda8d76d 22697 nt = get_note_type (filedata, pnote->type);
9437c45b 22698
1449284b 22699 printf (" ");
9ef920e9 22700
24d127aa 22701 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22702 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22703 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22704 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22705 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22706 print_gnu_build_attribute_name (pnote);
22707 else
b6ac461a 22708 print_symbol_name (-20, name);
9ef920e9
NC
22709
22710 if (do_wide)
22711 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22712 else
22713 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22714
24d127aa 22715 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22716 return print_ia64_vms_note (pnote);
24d127aa 22717 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22718 return print_gnu_note (filedata, pnote);
24d127aa 22719 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22720 return print_stapsdt_note (pnote);
24d127aa 22721 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22722 return print_core_note (pnote);
e5382207
LB
22723 else if (startswith (pnote->namedata, "FDO"))
22724 return print_fdo_note (pnote);
24d127aa 22725 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22726 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22727 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22728 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22729 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22730 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22731 else if (startswith (pnote->namedata, "AMDGPU")
22732 && pnote->type == NT_AMDGPU_METADATA)
22733 return print_amdgpu_note (pnote);
e263a66b
CC
22734 else if (startswith (pnote->namedata, "QNX"))
22735 return print_qnx_note (pnote);
779fe533 22736
2952f10c 22737 print_note_contents_hex (pnote);
015dc7e1 22738 return true;
1449284b 22739}
6d118b09 22740
015dc7e1 22741static bool
dda8d76d
NC
22742process_notes_at (Filedata * filedata,
22743 Elf_Internal_Shdr * section,
625d49fc
AM
22744 uint64_t offset,
22745 uint64_t length,
22746 uint64_t align)
779fe533 22747{
015dc7e1
AM
22748 Elf_External_Note *pnotes;
22749 Elf_External_Note *external;
22750 char *end;
22751 bool res = true;
103f02d3 22752
779fe533 22753 if (length <= 0)
015dc7e1 22754 return false;
103f02d3 22755
1449284b
NC
22756 if (section)
22757 {
dda8d76d 22758 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22759 if (pnotes)
32ec8896 22760 {
dda8d76d 22761 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22762 {
22763 free (pnotes);
015dc7e1 22764 return false;
f761cb13 22765 }
32ec8896 22766 }
1449284b
NC
22767 }
22768 else
82ed9683 22769 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22770 _("notes"));
4dff97b2 22771
dd24e3da 22772 if (pnotes == NULL)
015dc7e1 22773 return false;
779fe533 22774
103f02d3 22775 external = pnotes;
103f02d3 22776
ca0e11aa
NC
22777 if (filedata->is_separate)
22778 printf (_("In linked file '%s': "), filedata->file_name);
22779 else
22780 printf ("\n");
1449284b 22781 if (section)
ca0e11aa 22782 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22783 else
26c527e6
AM
22784 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22785 " with length 0x%08" PRIx64 ":\n"),
22786 offset, length);
1449284b 22787
82ed9683
L
22788 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22789 specifies that notes should be aligned to 4 bytes in 32-bit
22790 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22791 we also support 4 byte alignment in 64-bit objects. If section
22792 alignment is less than 4, we treate alignment as 4 bytes. */
22793 if (align < 4)
22794 align = 4;
22795 else if (align != 4 && align != 8)
22796 {
26c527e6
AM
22797 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22798 align);
a788aedd 22799 free (pnotes);
015dc7e1 22800 return false;
82ed9683
L
22801 }
22802
dbe15e4e 22803 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22804
c8071705
NC
22805 end = (char *) pnotes + length;
22806 while ((char *) external < end)
779fe533 22807 {
b34976b6 22808 Elf_Internal_Note inote;
15b42fb0 22809 size_t min_notesz;
4dff97b2 22810 char * next;
2cf0635d 22811 char * temp = NULL;
c8071705 22812 size_t data_remaining = end - (char *) external;
6d118b09 22813
dda8d76d 22814 if (!is_ia64_vms (filedata))
15b42fb0 22815 {
9dd3a467
NC
22816 /* PR binutils/15191
22817 Make sure that there is enough data to read. */
15b42fb0
AM
22818 min_notesz = offsetof (Elf_External_Note, name);
22819 if (data_remaining < min_notesz)
9dd3a467 22820 {
26c527e6 22821 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22822 "not enough for a full note\n",
26c527e6 22823 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22824 "not enough for a full note\n",
22825 data_remaining),
26c527e6 22826 data_remaining);
9dd3a467
NC
22827 break;
22828 }
5396a86e
AM
22829 data_remaining -= min_notesz;
22830
15b42fb0
AM
22831 inote.type = BYTE_GET (external->type);
22832 inote.namesz = BYTE_GET (external->namesz);
22833 inote.namedata = external->name;
22834 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22835 inote.descdata = ((char *) external
4dff97b2 22836 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22837 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22838 next = ((char *) external
4dff97b2 22839 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22840 }
00e98fc7 22841 else
15b42fb0
AM
22842 {
22843 Elf64_External_VMS_Note *vms_external;
00e98fc7 22844
9dd3a467
NC
22845 /* PR binutils/15191
22846 Make sure that there is enough data to read. */
15b42fb0
AM
22847 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22848 if (data_remaining < min_notesz)
9dd3a467 22849 {
26c527e6 22850 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22851 "not enough for a full note\n",
26c527e6 22852 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22853 "not enough for a full note\n",
22854 data_remaining),
26c527e6 22855 data_remaining);
9dd3a467
NC
22856 break;
22857 }
5396a86e 22858 data_remaining -= min_notesz;
3e55a963 22859
15b42fb0
AM
22860 vms_external = (Elf64_External_VMS_Note *) external;
22861 inote.type = BYTE_GET (vms_external->type);
22862 inote.namesz = BYTE_GET (vms_external->namesz);
22863 inote.namedata = vms_external->name;
22864 inote.descsz = BYTE_GET (vms_external->descsz);
22865 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22866 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22867 next = inote.descdata + align_power (inote.descsz, 3);
22868 }
22869
5396a86e
AM
22870 /* PR 17531: file: 3443835e. */
22871 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22872 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22873 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22874 || (size_t) (next - inote.descdata) < inote.descsz
22875 || ((size_t) (next - inote.descdata)
22876 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22877 {
26c527e6
AM
22878 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22879 (char *) external - (char *) pnotes);
22880 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22881 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22882 break;
22883 }
22884
15b42fb0 22885 external = (Elf_External_Note *) next;
dd24e3da 22886
6d118b09
NC
22887 /* Verify that name is null terminated. It appears that at least
22888 one version of Linux (RedHat 6.0) generates corefiles that don't
22889 comply with the ELF spec by failing to include the null byte in
22890 namesz. */
18344509 22891 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22892 {
5396a86e 22893 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22894 {
5396a86e
AM
22895 temp = (char *) malloc (inote.namesz + 1);
22896 if (temp == NULL)
22897 {
22898 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22899 res = false;
5396a86e
AM
22900 break;
22901 }
76da6bbe 22902
5396a86e
AM
22903 memcpy (temp, inote.namedata, inote.namesz);
22904 inote.namedata = temp;
22905 }
22906 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22907 }
22908
dda8d76d 22909 if (! process_note (& inote, filedata))
015dc7e1 22910 res = false;
103f02d3 22911
9db70fc3
AM
22912 free (temp);
22913 temp = NULL;
779fe533
NC
22914 }
22915
22916 free (pnotes);
103f02d3 22917
779fe533
NC
22918 return res;
22919}
22920
015dc7e1 22921static bool
dda8d76d 22922process_corefile_note_segments (Filedata * filedata)
779fe533 22923{
015dc7e1 22924 Elf_Internal_Phdr *segment;
b34976b6 22925 unsigned int i;
015dc7e1 22926 bool res = true;
103f02d3 22927
dda8d76d 22928 if (! get_program_headers (filedata))
015dc7e1 22929 return true;
103f02d3 22930
dda8d76d
NC
22931 for (i = 0, segment = filedata->program_headers;
22932 i < filedata->file_header.e_phnum;
b34976b6 22933 i++, segment++)
779fe533
NC
22934 {
22935 if (segment->p_type == PT_NOTE)
625d49fc
AM
22936 if (! process_notes_at (filedata, NULL, segment->p_offset,
22937 segment->p_filesz, segment->p_align))
015dc7e1 22938 res = false;
779fe533 22939 }
103f02d3 22940
779fe533
NC
22941 return res;
22942}
22943
015dc7e1 22944static bool
625d49fc 22945process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22946{
22947 Elf_External_Note * pnotes;
22948 Elf_External_Note * external;
c8071705 22949 char * end;
015dc7e1 22950 bool res = true;
685080f2
NC
22951
22952 if (length <= 0)
015dc7e1 22953 return false;
685080f2 22954
dda8d76d 22955 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22956 _("v850 notes"));
22957 if (pnotes == NULL)
015dc7e1 22958 return false;
685080f2
NC
22959
22960 external = pnotes;
c8071705 22961 end = (char*) pnotes + length;
685080f2 22962
26c527e6
AM
22963 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22964 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22965 offset, length);
685080f2 22966
c8071705 22967 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22968 {
22969 Elf_External_Note * next;
22970 Elf_Internal_Note inote;
22971
22972 inote.type = BYTE_GET (external->type);
22973 inote.namesz = BYTE_GET (external->namesz);
22974 inote.namedata = external->name;
22975 inote.descsz = BYTE_GET (external->descsz);
22976 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22977 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22978
c8071705
NC
22979 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22980 {
22981 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22982 inote.descdata = inote.namedata;
22983 inote.namesz = 0;
22984 }
22985
685080f2
NC
22986 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22987
c8071705 22988 if ( ((char *) next > end)
685080f2
NC
22989 || ((char *) next < (char *) pnotes))
22990 {
26c527e6
AM
22991 warn (_("corrupt descsz found in note at offset %#tx\n"),
22992 (char *) external - (char *) pnotes);
22993 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22994 inote.type, inote.namesz, inote.descsz);
22995 break;
22996 }
22997
22998 external = next;
22999
23000 /* Prevent out-of-bounds indexing. */
c8071705 23001 if ( inote.namedata + inote.namesz > end
685080f2
NC
23002 || inote.namedata + inote.namesz < inote.namedata)
23003 {
26c527e6
AM
23004 warn (_("corrupt namesz found in note at offset %#zx\n"),
23005 (char *) external - (char *) pnotes);
23006 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
23007 inote.type, inote.namesz, inote.descsz);
23008 break;
23009 }
23010
23011 printf (" %s: ", get_v850_elf_note_type (inote.type));
23012
23013 if (! print_v850_note (& inote))
23014 {
015dc7e1 23015 res = false;
26c527e6 23016 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
23017 inote.namesz, inote.descsz);
23018 }
23019 }
23020
23021 free (pnotes);
23022
23023 return res;
23024}
23025
015dc7e1 23026static bool
dda8d76d 23027process_note_sections (Filedata * filedata)
1ec5cd37 23028{
015dc7e1 23029 Elf_Internal_Shdr *section;
26c527e6 23030 size_t i;
32ec8896 23031 unsigned int n = 0;
015dc7e1 23032 bool res = true;
1ec5cd37 23033
dda8d76d
NC
23034 for (i = 0, section = filedata->section_headers;
23035 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 23036 i++, section++)
685080f2
NC
23037 {
23038 if (section->sh_type == SHT_NOTE)
23039 {
625d49fc
AM
23040 if (! process_notes_at (filedata, section, section->sh_offset,
23041 section->sh_size, section->sh_addralign))
015dc7e1 23042 res = false;
685080f2
NC
23043 n++;
23044 }
23045
dda8d76d
NC
23046 if (( filedata->file_header.e_machine == EM_V800
23047 || filedata->file_header.e_machine == EM_V850
23048 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
23049 && section->sh_type == SHT_RENESAS_INFO)
23050 {
625d49fc
AM
23051 if (! process_v850_notes (filedata, section->sh_offset,
23052 section->sh_size))
015dc7e1 23053 res = false;
685080f2
NC
23054 n++;
23055 }
23056 }
df565f32
NC
23057
23058 if (n == 0)
23059 /* Try processing NOTE segments instead. */
dda8d76d 23060 return process_corefile_note_segments (filedata);
1ec5cd37
NC
23061
23062 return res;
23063}
23064
015dc7e1 23065static bool
dda8d76d 23066process_notes (Filedata * filedata)
779fe533
NC
23067{
23068 /* If we have not been asked to display the notes then do nothing. */
23069 if (! do_notes)
015dc7e1 23070 return true;
103f02d3 23071
dda8d76d
NC
23072 if (filedata->file_header.e_type != ET_CORE)
23073 return process_note_sections (filedata);
103f02d3 23074
779fe533 23075 /* No program headers means no NOTE segment. */
dda8d76d
NC
23076 if (filedata->file_header.e_phnum > 0)
23077 return process_corefile_note_segments (filedata);
779fe533 23078
ca0e11aa
NC
23079 if (filedata->is_separate)
23080 printf (_("No notes found in linked file '%s'.\n"),
23081 filedata->file_name);
23082 else
23083 printf (_("No notes found file.\n"));
23084
015dc7e1 23085 return true;
779fe533
NC
23086}
23087
60abdbed
NC
23088static unsigned char *
23089display_public_gnu_attributes (unsigned char * start,
23090 const unsigned char * const end)
23091{
23092 printf (_(" Unknown GNU attribute: %s\n"), start);
23093
23094 start += strnlen ((char *) start, end - start);
23095 display_raw_attribute (start, end);
23096
23097 return (unsigned char *) end;
23098}
23099
23100static unsigned char *
23101display_generic_attribute (unsigned char * start,
23102 unsigned int tag,
23103 const unsigned char * const end)
23104{
23105 if (tag == 0)
23106 return (unsigned char *) end;
23107
23108 return display_tag_value (tag, start, end);
23109}
23110
015dc7e1 23111static bool
dda8d76d 23112process_arch_specific (Filedata * filedata)
252b5132 23113{
a952a375 23114 if (! do_arch)
015dc7e1 23115 return true;
a952a375 23116
dda8d76d 23117 switch (filedata->file_header.e_machine)
252b5132 23118 {
53a346d8
CZ
23119 case EM_ARC:
23120 case EM_ARC_COMPACT:
23121 case EM_ARC_COMPACT2:
b5c37946
SJ
23122 case EM_ARC_COMPACT3:
23123 case EM_ARC_COMPACT3_64:
dda8d76d 23124 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
23125 display_arc_attribute,
23126 display_generic_attribute);
11c1ff18 23127 case EM_ARM:
dda8d76d 23128 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
23129 display_arm_attribute,
23130 display_generic_attribute);
23131
252b5132 23132 case EM_MIPS:
4fe85591 23133 case EM_MIPS_RS3_LE:
dda8d76d 23134 return process_mips_specific (filedata);
60abdbed
NC
23135
23136 case EM_MSP430:
dda8d76d 23137 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 23138 display_msp430_attribute,
c0ea7c52 23139 display_msp430_gnu_attribute);
60abdbed 23140
2dc8dd17
JW
23141 case EM_RISCV:
23142 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23143 display_riscv_attribute,
23144 display_generic_attribute);
23145
35c08157 23146 case EM_NDS32:
dda8d76d 23147 return process_nds32_specific (filedata);
60abdbed 23148
85f7484a
PB
23149 case EM_68K:
23150 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23151 display_m68k_gnu_attribute);
23152
34c8bcba 23153 case EM_PPC:
b82317dd 23154 case EM_PPC64:
dda8d76d 23155 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23156 display_power_gnu_attribute);
23157
643f7afb
AK
23158 case EM_S390:
23159 case EM_S390_OLD:
dda8d76d 23160 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23161 display_s390_gnu_attribute);
23162
9e8c70f9
DM
23163 case EM_SPARC:
23164 case EM_SPARC32PLUS:
23165 case EM_SPARCV9:
dda8d76d 23166 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23167 display_sparc_gnu_attribute);
23168
59e6276b 23169 case EM_TI_C6000:
dda8d76d 23170 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
23171 display_tic6x_attribute,
23172 display_generic_attribute);
23173
0861f561
CQ
23174 case EM_CSKY:
23175 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23176 display_csky_attribute, NULL);
23177
252b5132 23178 default:
dda8d76d 23179 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
23180 display_public_gnu_attributes,
23181 display_generic_attribute);
252b5132 23182 }
252b5132
RH
23183}
23184
015dc7e1 23185static bool
dda8d76d 23186get_file_header (Filedata * filedata)
252b5132 23187{
9ea033b2 23188 /* Read in the identity array. */
dda8d76d 23189 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23190 return false;
252b5132 23191
9ea033b2 23192 /* Determine how to read the rest of the header. */
dda8d76d 23193 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 23194 {
1a0670f3
AM
23195 default:
23196 case ELFDATANONE:
adab8cdc
AO
23197 case ELFDATA2LSB:
23198 byte_get = byte_get_little_endian;
23199 byte_put = byte_put_little_endian;
23200 break;
23201 case ELFDATA2MSB:
23202 byte_get = byte_get_big_endian;
23203 byte_put = byte_put_big_endian;
23204 break;
9ea033b2
NC
23205 }
23206
23207 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 23208 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
23209
23210 /* Read in the rest of the header. */
23211 if (is_32bit_elf)
23212 {
23213 Elf32_External_Ehdr ehdr32;
252b5132 23214
dda8d76d 23215 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23216 return false;
103f02d3 23217
dda8d76d
NC
23218 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23219 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23220 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23221 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23222 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23223 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23224 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23225 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23226 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23227 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23228 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23229 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23230 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 23231 }
252b5132 23232 else
9ea033b2
NC
23233 {
23234 Elf64_External_Ehdr ehdr64;
a952a375 23235
dda8d76d 23236 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23237 return false;
103f02d3 23238
dda8d76d
NC
23239 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23240 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23241 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23242 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23243 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23244 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23245 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23246 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23247 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23248 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23249 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23250 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23251 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 23252 }
252b5132 23253
015dc7e1 23254 return true;
252b5132
RH
23255}
23256
13acb58d
AM
23257static void
23258free_filedata (Filedata *filedata)
23259{
23260 free (filedata->program_interpreter);
13acb58d 23261 free (filedata->program_headers);
13acb58d 23262 free (filedata->section_headers);
13acb58d 23263 free (filedata->string_table);
13acb58d 23264 free (filedata->dump.dump_sects);
13acb58d 23265 free (filedata->dynamic_strings);
13acb58d 23266 free (filedata->dynamic_symbols);
13acb58d 23267 free (filedata->dynamic_syminfo);
13acb58d 23268 free (filedata->dynamic_section);
13acb58d
AM
23269
23270 while (filedata->symtab_shndx_list != NULL)
23271 {
23272 elf_section_list *next = filedata->symtab_shndx_list->next;
23273 free (filedata->symtab_shndx_list);
23274 filedata->symtab_shndx_list = next;
23275 }
23276
23277 free (filedata->section_headers_groups);
13acb58d
AM
23278
23279 if (filedata->section_groups)
23280 {
23281 size_t i;
23282 struct group_list * g;
23283 struct group_list * next;
23284
23285 for (i = 0; i < filedata->group_count; i++)
23286 {
23287 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23288 {
23289 next = g->next;
23290 free (g);
23291 }
23292 }
23293
23294 free (filedata->section_groups);
13acb58d 23295 }
066f8fbe
AM
23296 memset (&filedata->section_headers, 0,
23297 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23298}
23299
dda8d76d
NC
23300static void
23301close_file (Filedata * filedata)
23302{
23303 if (filedata)
23304 {
23305 if (filedata->handle)
23306 fclose (filedata->handle);
23307 free (filedata);
23308 }
23309}
23310
23311void
23312close_debug_file (void * data)
23313{
13acb58d 23314 free_filedata ((Filedata *) data);
dda8d76d
NC
23315 close_file ((Filedata *) data);
23316}
23317
23318static Filedata *
015dc7e1 23319open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23320{
23321 struct stat statbuf;
23322 Filedata * filedata = NULL;
23323
23324 if (stat (pathname, & statbuf) < 0
23325 || ! S_ISREG (statbuf.st_mode))
23326 goto fail;
23327
23328 filedata = calloc (1, sizeof * filedata);
23329 if (filedata == NULL)
23330 goto fail;
23331
23332 filedata->handle = fopen (pathname, "rb");
23333 if (filedata->handle == NULL)
23334 goto fail;
23335
be7d229a 23336 filedata->file_size = statbuf.st_size;
dda8d76d 23337 filedata->file_name = pathname;
ca0e11aa 23338 filedata->is_separate = is_separate;
dda8d76d
NC
23339
23340 if (! get_file_header (filedata))
23341 goto fail;
23342
4de91c10
AM
23343 if (!get_section_headers (filedata, false))
23344 goto fail;
dda8d76d
NC
23345
23346 return filedata;
23347
23348 fail:
23349 if (filedata)
23350 {
23351 if (filedata->handle)
23352 fclose (filedata->handle);
23353 free (filedata);
23354 }
23355 return NULL;
23356}
23357
23358void *
23359open_debug_file (const char * pathname)
23360{
015dc7e1 23361 return open_file (pathname, true);
dda8d76d
NC
23362}
23363
835f2fae
NC
23364static void
23365initialise_dump_sects (Filedata * filedata)
23366{
23367 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23368 Note we do this even if cmdline_dump_sects is empty because we
23369 must make sure that the dump_sets array is zeroed out before each
23370 object file is processed. */
23371 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23372 memset (filedata->dump.dump_sects, 0,
23373 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23374
23375 if (cmdline.num_dump_sects > 0)
23376 {
23377 if (filedata->dump.num_dump_sects == 0)
23378 /* A sneaky way of allocating the dump_sects array. */
23379 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23380
23381 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23382 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23383 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23384 }
23385}
23386
94585d6d
NC
23387static bool
23388might_need_separate_debug_info (Filedata * filedata)
23389{
23390 /* Debuginfo files do not need further separate file loading. */
23391 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23392 return false;
23393
23394 /* Since do_follow_links might be enabled by default, only treat it as an
23395 indication that separate files should be loaded if setting it was a
23396 deliberate user action. */
23397 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23398 return true;
23399
23400 if (process_links || do_syms || do_unwind
23401 || dump_any_debugging || do_dump || do_debugging)
23402 return true;
23403
23404 return false;
23405}
23406
fb52b2f4
NC
23407/* Process one ELF object file according to the command line options.
23408 This file may actually be stored in an archive. The file is
32ec8896
NC
23409 positioned at the start of the ELF object. Returns TRUE if no
23410 problems were encountered, FALSE otherwise. */
fb52b2f4 23411
015dc7e1 23412static bool
dda8d76d 23413process_object (Filedata * filedata)
252b5132 23414{
015dc7e1 23415 bool have_separate_files;
252b5132 23416 unsigned int i;
015dc7e1 23417 bool res;
252b5132 23418
dda8d76d 23419 if (! get_file_header (filedata))
252b5132 23420 {
dda8d76d 23421 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23422 return false;
252b5132
RH
23423 }
23424
23425 /* Initialise per file variables. */
978c4450
AM
23426 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23427 filedata->version_info[i] = 0;
252b5132 23428
978c4450
AM
23429 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23430 filedata->dynamic_info[i] = 0;
23431 filedata->dynamic_info_DT_GNU_HASH = 0;
23432 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23433
23434 /* Process the file. */
23435 if (show_name)
dda8d76d 23436 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23437
835f2fae 23438 initialise_dump_sects (filedata);
d70c5fc7 23439
4de91c10
AM
23440 /* There may be some extensions in the first section header. Don't
23441 bomb if we can't read it. */
23442 get_section_headers (filedata, true);
23443
dda8d76d 23444 if (! process_file_header (filedata))
4de91c10
AM
23445 {
23446 res = false;
23447 goto out;
23448 }
252b5132 23449
e331b18d
AM
23450 /* Throw away the single section header read above, so that we
23451 re-read the entire set. */
23452 free (filedata->section_headers);
23453 filedata->section_headers = NULL;
23454
dda8d76d 23455 if (! process_section_headers (filedata))
2f62977e 23456 {
32ec8896 23457 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23458 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23459
2f62977e 23460 if (! do_using_dynamic)
015dc7e1 23461 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23462 }
252b5132 23463
dda8d76d 23464 if (! process_section_groups (filedata))
32ec8896 23465 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23466 do_unwind = false;
d1f5c6e3 23467
93df3340
AM
23468 process_program_headers (filedata);
23469
23470 res = process_dynamic_section (filedata);
252b5132 23471
dda8d76d 23472 if (! process_relocs (filedata))
015dc7e1 23473 res = false;
252b5132 23474
dda8d76d 23475 if (! process_unwind (filedata))
015dc7e1 23476 res = false;
4d6ed7c8 23477
dda8d76d 23478 if (! process_symbol_table (filedata))
015dc7e1 23479 res = false;
252b5132 23480
0f03783c 23481 if (! process_lto_symbol_tables (filedata))
015dc7e1 23482 res = false;
b9e920ec 23483
dda8d76d 23484 if (! process_syminfo (filedata))
015dc7e1 23485 res = false;
252b5132 23486
dda8d76d 23487 if (! process_version_sections (filedata))
015dc7e1 23488 res = false;
252b5132 23489
94585d6d 23490 if (might_need_separate_debug_info (filedata))
24841daa 23491 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23492 else
015dc7e1 23493 have_separate_files = false;
dda8d76d
NC
23494
23495 if (! process_section_contents (filedata))
015dc7e1 23496 res = false;
f5842774 23497
24841daa 23498 if (have_separate_files)
dda8d76d 23499 {
24841daa
NC
23500 separate_info * d;
23501
23502 for (d = first_separate_info; d != NULL; d = d->next)
23503 {
835f2fae
NC
23504 initialise_dump_sects (d->handle);
23505
ca0e11aa 23506 if (process_links && ! process_file_header (d->handle))
015dc7e1 23507 res = false;
ca0e11aa 23508 else if (! process_section_headers (d->handle))
015dc7e1 23509 res = false;
d6bfbc39 23510 else if (! process_section_contents (d->handle))
015dc7e1 23511 res = false;
ca0e11aa
NC
23512 else if (process_links)
23513 {
ca0e11aa 23514 if (! process_section_groups (d->handle))
015dc7e1 23515 res = false;
93df3340 23516 process_program_headers (d->handle);
ca0e11aa 23517 if (! process_dynamic_section (d->handle))
015dc7e1 23518 res = false;
ca0e11aa 23519 if (! process_relocs (d->handle))
015dc7e1 23520 res = false;
ca0e11aa 23521 if (! process_unwind (d->handle))
015dc7e1 23522 res = false;
ca0e11aa 23523 if (! process_symbol_table (d->handle))
015dc7e1 23524 res = false;
ca0e11aa 23525 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23526 res = false;
ca0e11aa 23527 if (! process_syminfo (d->handle))
015dc7e1 23528 res = false;
ca0e11aa 23529 if (! process_version_sections (d->handle))
015dc7e1 23530 res = false;
ca0e11aa 23531 if (! process_notes (d->handle))
015dc7e1 23532 res = false;
ca0e11aa 23533 }
24841daa
NC
23534 }
23535
23536 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23537 }
23538
23539 if (! process_notes (filedata))
015dc7e1 23540 res = false;
103f02d3 23541
dda8d76d 23542 if (! process_gnu_liblist (filedata))
015dc7e1 23543 res = false;
047b2264 23544
dda8d76d 23545 if (! process_arch_specific (filedata))
015dc7e1 23546 res = false;
252b5132 23547
4de91c10 23548 out:
13acb58d 23549 free_filedata (filedata);
e4b17d5c 23550
19e6b90e 23551 free_debug_memory ();
18bd398b 23552
32ec8896 23553 return res;
252b5132
RH
23554}
23555
2cf0635d 23556/* Process an ELF archive.
32ec8896
NC
23557 On entry the file is positioned just after the ARMAG string.
23558 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23559
015dc7e1
AM
23560static bool
23561process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23562{
23563 struct archive_info arch;
23564 struct archive_info nested_arch;
23565 size_t got;
015dc7e1 23566 bool ret = true;
2cf0635d 23567
015dc7e1 23568 show_name = true;
2cf0635d
NC
23569
23570 /* The ARCH structure is used to hold information about this archive. */
23571 arch.file_name = NULL;
23572 arch.file = NULL;
23573 arch.index_array = NULL;
23574 arch.sym_table = NULL;
23575 arch.longnames = NULL;
23576
23577 /* The NESTED_ARCH structure is used as a single-item cache of information
23578 about a nested archive (when members of a thin archive reside within
23579 another regular archive file). */
23580 nested_arch.file_name = NULL;
23581 nested_arch.file = NULL;
23582 nested_arch.index_array = NULL;
23583 nested_arch.sym_table = NULL;
23584 nested_arch.longnames = NULL;
23585
dda8d76d 23586 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23587 filedata->file_size, is_thin_archive,
23588 do_archive_index) != 0)
2cf0635d 23589 {
015dc7e1 23590 ret = false;
2cf0635d 23591 goto out;
4145f1d5 23592 }
fb52b2f4 23593
4145f1d5
NC
23594 if (do_archive_index)
23595 {
2cf0635d 23596 if (arch.sym_table == NULL)
1cb7d8b1
AM
23597 error (_("%s: unable to dump the index as none was found\n"),
23598 filedata->file_name);
4145f1d5
NC
23599 else
23600 {
26c527e6
AM
23601 uint64_t i, l;
23602 uint64_t current_pos;
4145f1d5 23603
26c527e6
AM
23604 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23605 " %#" PRIx64 " bytes in the symbol table)\n"),
23606 filedata->file_name, arch.index_num,
1cb7d8b1 23607 arch.sym_size);
dda8d76d
NC
23608
23609 current_pos = ftell (filedata->handle);
4145f1d5 23610
2cf0635d 23611 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23612 {
1cb7d8b1
AM
23613 if (i == 0
23614 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23615 {
23616 char * member_name
23617 = get_archive_member_name_at (&arch, arch.index_array[i],
23618 &nested_arch);
2cf0635d 23619
1cb7d8b1
AM
23620 if (member_name != NULL)
23621 {
23622 char * qualified_name
23623 = make_qualified_name (&arch, &nested_arch,
23624 member_name);
2cf0635d 23625
1cb7d8b1
AM
23626 if (qualified_name != NULL)
23627 {
23628 printf (_("Contents of binary %s at offset "),
23629 qualified_name);
c2a7d3f5
NC
23630 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23631 putchar ('\n');
1cb7d8b1
AM
23632 free (qualified_name);
23633 }
fd486f32 23634 free (member_name);
4145f1d5
NC
23635 }
23636 }
2cf0635d
NC
23637
23638 if (l >= arch.sym_size)
4145f1d5 23639 {
1cb7d8b1
AM
23640 error (_("%s: end of the symbol table reached "
23641 "before the end of the index\n"),
dda8d76d 23642 filedata->file_name);
015dc7e1 23643 ret = false;
cb8f3167 23644 break;
4145f1d5 23645 }
591f7597 23646 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23647 printf ("\t%.*s\n",
23648 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23649 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23650 }
23651
67ce483b 23652 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23653 l = (l + 7) & ~ 7;
23654 else
23655 l += l & 1;
23656
2cf0635d 23657 if (l < arch.sym_size)
32ec8896 23658 {
26c527e6 23659 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23660 "but without corresponding entries in "
23661 "the index table\n",
26c527e6 23662 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23663 "but without corresponding entries in "
23664 "the index table\n",
23665 arch.sym_size - l),
dda8d76d 23666 filedata->file_name, arch.sym_size - l);
015dc7e1 23667 ret = false;
32ec8896 23668 }
4145f1d5 23669
63cf857e 23670 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23671 {
1cb7d8b1
AM
23672 error (_("%s: failed to seek back to start of object files "
23673 "in the archive\n"),
dda8d76d 23674 filedata->file_name);
015dc7e1 23675 ret = false;
2cf0635d 23676 goto out;
4145f1d5 23677 }
fb52b2f4 23678 }
4145f1d5
NC
23679
23680 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23681 && !do_segments && !do_header && !do_dump && !do_version
23682 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23683 && !do_section_groups && !do_dyn_syms)
2cf0635d 23684 {
015dc7e1 23685 ret = true; /* Archive index only. */
2cf0635d
NC
23686 goto out;
23687 }
fb52b2f4
NC
23688 }
23689
fb52b2f4
NC
23690 while (1)
23691 {
2cf0635d
NC
23692 char * name;
23693 size_t namelen;
23694 char * qualified_name;
23695
23696 /* Read the next archive header. */
63cf857e 23697 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23698 {
23699 error (_("%s: failed to seek to next archive header\n"),
23700 arch.file_name);
015dc7e1 23701 ret = false;
1cb7d8b1
AM
23702 break;
23703 }
dda8d76d 23704 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23705 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23706 {
23707 if (got == 0)
2cf0635d 23708 break;
28e817cc
NC
23709 /* PR 24049 - we cannot use filedata->file_name as this will
23710 have already been freed. */
23711 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23712
015dc7e1 23713 ret = false;
1cb7d8b1
AM
23714 break;
23715 }
2cf0635d 23716 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23717 {
23718 error (_("%s: did not find a valid archive header\n"),
23719 arch.file_name);
015dc7e1 23720 ret = false;
1cb7d8b1
AM
23721 break;
23722 }
2cf0635d
NC
23723
23724 arch.next_arhdr_offset += sizeof arch.arhdr;
23725
978c4450 23726 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23727
23728 name = get_archive_member_name (&arch, &nested_arch);
23729 if (name == NULL)
fb52b2f4 23730 {
28e817cc 23731 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23732 ret = false;
d989285c 23733 break;
fb52b2f4 23734 }
2cf0635d 23735 namelen = strlen (name);
fb52b2f4 23736
2cf0635d
NC
23737 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23738 if (qualified_name == NULL)
fb52b2f4 23739 {
28e817cc 23740 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23741 free (name);
015dc7e1 23742 ret = false;
d989285c 23743 break;
fb52b2f4
NC
23744 }
23745
2cf0635d 23746 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23747 {
23748 /* This is a proxy for an external member of a thin archive. */
23749 Filedata * member_filedata;
23750 char * member_file_name = adjust_relative_path
dda8d76d 23751 (filedata->file_name, name, namelen);
32ec8896 23752
fd486f32 23753 free (name);
1cb7d8b1
AM
23754 if (member_file_name == NULL)
23755 {
fd486f32 23756 free (qualified_name);
015dc7e1 23757 ret = false;
1cb7d8b1
AM
23758 break;
23759 }
2cf0635d 23760
015dc7e1 23761 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23762 if (member_filedata == NULL)
23763 {
23764 error (_("Input file '%s' is not readable.\n"), member_file_name);
23765 free (member_file_name);
fd486f32 23766 free (qualified_name);
015dc7e1 23767 ret = false;
1cb7d8b1
AM
23768 break;
23769 }
2cf0635d 23770
978c4450 23771 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23772 member_filedata->file_name = qualified_name;
2cf0635d 23773
75a2da57
AH
23774 /* The call to process_object() expects the file to be at the beginning. */
23775 rewind (member_filedata->handle);
23776
1cb7d8b1 23777 if (! process_object (member_filedata))
015dc7e1 23778 ret = false;
2cf0635d 23779
1cb7d8b1
AM
23780 close_file (member_filedata);
23781 free (member_file_name);
1cb7d8b1 23782 }
2cf0635d 23783 else if (is_thin_archive)
1cb7d8b1
AM
23784 {
23785 Filedata thin_filedata;
eb02c04d 23786
1cb7d8b1 23787 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23788
a043396b
NC
23789 /* PR 15140: Allow for corrupt thin archives. */
23790 if (nested_arch.file == NULL)
23791 {
23792 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23793 qualified_name, name);
fd486f32
AM
23794 free (qualified_name);
23795 free (name);
015dc7e1 23796 ret = false;
a043396b
NC
23797 break;
23798 }
fd486f32 23799 free (name);
a043396b 23800
1cb7d8b1 23801 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23802 filedata->archive_file_offset
23803 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23804
1cb7d8b1
AM
23805 /* The nested archive file will have been opened and setup by
23806 get_archive_member_name. */
63cf857e
AM
23807 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23808 SEEK_SET) != 0)
1cb7d8b1
AM
23809 {
23810 error (_("%s: failed to seek to archive member.\n"),
23811 nested_arch.file_name);
fd486f32 23812 free (qualified_name);
015dc7e1 23813 ret = false;
1cb7d8b1
AM
23814 break;
23815 }
2cf0635d 23816
dda8d76d
NC
23817 thin_filedata.handle = nested_arch.file;
23818 thin_filedata.file_name = qualified_name;
9abca702 23819
1cb7d8b1 23820 if (! process_object (& thin_filedata))
015dc7e1 23821 ret = false;
1cb7d8b1 23822 }
2cf0635d 23823 else
1cb7d8b1 23824 {
fd486f32 23825 free (name);
978c4450 23826 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23827 filedata->file_name = qualified_name;
1cb7d8b1 23828 if (! process_object (filedata))
015dc7e1 23829 ret = false;
237877b8 23830 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23831 /* Stop looping with "negative" archive_file_size. */
978c4450 23832 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23833 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23834 }
fb52b2f4 23835
2cf0635d 23836 free (qualified_name);
fb52b2f4
NC
23837 }
23838
4145f1d5 23839 out:
2cf0635d
NC
23840 if (nested_arch.file != NULL)
23841 fclose (nested_arch.file);
23842 release_archive (&nested_arch);
23843 release_archive (&arch);
fb52b2f4 23844
d989285c 23845 return ret;
fb52b2f4
NC
23846}
23847
015dc7e1 23848static bool
2cf0635d 23849process_file (char * file_name)
fb52b2f4 23850{
dda8d76d 23851 Filedata * filedata = NULL;
fb52b2f4
NC
23852 struct stat statbuf;
23853 char armag[SARMAG];
015dc7e1 23854 bool ret = true;
fb52b2f4
NC
23855
23856 if (stat (file_name, &statbuf) < 0)
23857 {
f24ddbdd
NC
23858 if (errno == ENOENT)
23859 error (_("'%s': No such file\n"), file_name);
23860 else
23861 error (_("Could not locate '%s'. System error message: %s\n"),
23862 file_name, strerror (errno));
015dc7e1 23863 return false;
f24ddbdd
NC
23864 }
23865
23866 if (! S_ISREG (statbuf.st_mode))
23867 {
23868 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23869 return false;
fb52b2f4
NC
23870 }
23871
dda8d76d
NC
23872 filedata = calloc (1, sizeof * filedata);
23873 if (filedata == NULL)
23874 {
23875 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23876 return false;
dda8d76d
NC
23877 }
23878
23879 filedata->file_name = file_name;
23880 filedata->handle = fopen (file_name, "rb");
23881 if (filedata->handle == NULL)
fb52b2f4 23882 {
f24ddbdd 23883 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23884 free (filedata);
015dc7e1 23885 return false;
fb52b2f4
NC
23886 }
23887
dda8d76d 23888 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23889 {
4145f1d5 23890 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23891 fclose (filedata->handle);
23892 free (filedata);
015dc7e1 23893 return false;
fb52b2f4
NC
23894 }
23895
be7d229a 23896 filedata->file_size = statbuf.st_size;
015dc7e1 23897 filedata->is_separate = false;
f54498b4 23898
fb52b2f4 23899 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23900 {
015dc7e1
AM
23901 if (! process_archive (filedata, false))
23902 ret = false;
32ec8896 23903 }
2cf0635d 23904 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23905 {
015dc7e1
AM
23906 if ( ! process_archive (filedata, true))
23907 ret = false;
32ec8896 23908 }
fb52b2f4
NC
23909 else
23910 {
1b513401 23911 if (do_archive_index && !check_all)
4145f1d5
NC
23912 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23913 file_name);
23914
dda8d76d 23915 rewind (filedata->handle);
978c4450 23916 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23917
dda8d76d 23918 if (! process_object (filedata))
015dc7e1 23919 ret = false;
fb52b2f4
NC
23920 }
23921
dda8d76d 23922 fclose (filedata->handle);
8fb879cd
AM
23923 free (filedata->section_headers);
23924 free (filedata->program_headers);
23925 free (filedata->string_table);
6431e409 23926 free (filedata->dump.dump_sects);
dda8d76d 23927 free (filedata);
32ec8896 23928
fd486f32 23929 free (ba_cache.strtab);
1bd6175a 23930 ba_cache.strtab = NULL;
fd486f32 23931 free (ba_cache.symtab);
1bd6175a 23932 ba_cache.symtab = NULL;
fd486f32
AM
23933 ba_cache.filedata = NULL;
23934
fb52b2f4
NC
23935 return ret;
23936}
23937
252b5132
RH
23938#ifdef SUPPORT_DISASSEMBLY
23939/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23940 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23941 symbols. */
252b5132
RH
23942
23943void
2cf0635d 23944print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23945{
23946 fprintf (outfile,"0x%8.8x", addr);
23947}
23948
e3c8793a 23949/* Needed by the i386 disassembler. */
dda8d76d 23950
252b5132
RH
23951void
23952db_task_printsym (unsigned int addr)
23953{
23954 print_address (addr, stderr);
23955}
23956#endif
23957
23958int
2cf0635d 23959main (int argc, char ** argv)
252b5132 23960{
ff78d6d6
L
23961 int err;
23962
87b9f255 23963#ifdef HAVE_LC_MESSAGES
252b5132 23964 setlocale (LC_MESSAGES, "");
3882b010 23965#endif
3882b010 23966 setlocale (LC_CTYPE, "");
252b5132
RH
23967 bindtextdomain (PACKAGE, LOCALEDIR);
23968 textdomain (PACKAGE);
23969
869b9d07
MM
23970 expandargv (&argc, &argv);
23971
dda8d76d 23972 parse_args (& cmdline, argc, argv);
59f14fc0 23973
18bd398b 23974 if (optind < (argc - 1))
1b513401
NC
23975 /* When displaying information for more than one file,
23976 prefix the information with the file name. */
015dc7e1 23977 show_name = true;
5656ba2c
L
23978 else if (optind >= argc)
23979 {
1b513401 23980 /* Ensure that the warning is always displayed. */
015dc7e1 23981 do_checks = true;
1b513401 23982
5656ba2c
L
23983 warn (_("Nothing to do.\n"));
23984 usage (stderr);
23985 }
18bd398b 23986
015dc7e1 23987 err = false;
252b5132 23988 while (optind < argc)
32ec8896 23989 if (! process_file (argv[optind++]))
015dc7e1 23990 err = true;
252b5132 23991
9db70fc3 23992 free (cmdline.dump_sects);
252b5132 23993
7d9813f1
NA
23994 free (dump_ctf_symtab_name);
23995 free (dump_ctf_strtab_name);
23996 free (dump_ctf_parent_name);
23997
32ec8896 23998 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23999}