]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
x86/testsuite: Refine AVX10.2 rounding testcases
[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 *
d565a958
SN
1539get_symbol_at (Filedata * filedata,
1540 Elf_Internal_Sym * symtab,
fcf8f323
NC
1541 uint64_t nsyms,
1542 char * strtab,
fcf8f323
NC
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
1551 /* FIXME: Since this function is likely to be called repeatedly with
1552 slightly increasing addresses each time, we could speed things up by
1553 caching the last returned value and starting our search from there. */
1554 while (beg < end)
1555 {
1556 Elf_Internal_Sym * sym;
1557 uint64_t value;
1558
1559 sym = beg + (end - beg) / 2;
1560
1561 value = sym->st_value;
1562
d41629d3 1563 if (where >= value
fcf8f323
NC
1564 && where - value < dist)
1565 {
1566 best = sym;
1567 dist = where - value;
1568 if (dist == 0)
1569 break;
1570 }
1571
1572 if (where < value)
1573 end = sym;
1574 else
1575 beg = sym + 1;
1576 }
1577
d565a958
SN
1578 const char *name;
1579
1580 /* If there is a section start closer than the found symbol then
1581 use that for symbolizing the address. */
1582 Elf_Internal_Shdr *sec = find_section_by_address (filedata, where);
1583 if (sec != NULL
1584 && where - sec->sh_addr < dist
1585 && section_name_valid (filedata, sec))
1586 {
1587 name = section_name (filedata, sec);
1588 dist = where - sec->sh_addr;
1589 }
1590 else if (best != NULL)
1591 name = strtab + best->st_name;
1592 else
fcf8f323
NC
1593 return NULL;
1594
fcf8f323
NC
1595 if (offset_return != NULL)
1596 * offset_return = dist;
1597
d565a958 1598 return name;
fcf8f323
NC
1599}
1600
1601static void
d565a958
SN
1602print_relr_addr_and_sym (Filedata * filedata,
1603 Elf_Internal_Sym * symtab,
fcf8f323
NC
1604 uint64_t nsyms,
1605 char * strtab,
fcf8f323
NC
1606 uint64_t where)
1607{
1608 const char * symname = NULL;
1609 uint64_t offset = 0;
1610
1611 print_vma (where, ZERO_HEX);
1612 printf (" ");
1613
d565a958 1614 symname = get_symbol_at (filedata, symtab, nsyms, strtab, where, & offset);
fcf8f323
NC
1615
1616 if (symname == NULL)
1617 printf ("<no sym>");
1618 else if (offset == 0)
1619 print_symbol_name (38, symname);
1620 else
1621 {
1622 print_symbol_name (28, symname);
1623 printf (" + ");
1624 print_vma (offset, PREFIX_HEX);
1625 }
1626}
1627
d41629d3
SN
1628/* See bfd_is_aarch64_special_symbol_name. */
1629
1630static bool
1631is_aarch64_special_symbol_name (const char *name)
1632{
1633 if (!name || name[0] != '$')
1634 return false;
1635 if (name[1] == 'x' || name[1] == 'd')
1636 /* Map. */;
1637 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
1638 /* Tag. */;
1639 else
1640 return false;
1641 return name[2] == 0 || name[2] == '.';
1642}
1643
1644static bool
1645is_special_symbol_name (Filedata * filedata, const char * s)
1646{
1647 switch (filedata->file_header.e_machine)
1648 {
1649 case EM_AARCH64:
1650 return is_aarch64_special_symbol_name (s);
1651
1652 default:
1653 return false;
1654 }
1655}
1656
1657/* Allows selecting the best symbol from a set for displaying addresses.
1658 BEST is the current best or NULL if there are no good symbols yet.
1659 SYM is the next symbol to consider, if it is better than BEST then
1660 return SYM else return BEST. */
1661
1662static Elf_Internal_Sym *
1663select_display_sym (Filedata * filedata,
1664 char * strtab,
1665 uint64_t strtablen,
1666 Elf_Internal_Sym * best,
1667 Elf_Internal_Sym * sym)
1668{
1669 /* Ignore empty or invalid syms. */
1670 if (sym->st_name == 0)
1671 return best;
1672 if (sym->st_name >= strtablen)
1673 return best;
1674 /* Ignore undefined or TLS syms. */
1675 if (sym->st_shndx == SHN_UNDEF)
1676 return best;
1677 if (ELF_ST_TYPE (sym->st_info) == STT_TLS)
1678 return best;
1679
1680 char *s = strtab + sym->st_name;
1681
1682 /* Don't display special symbols. */
1683 if (is_special_symbol_name (filedata, s))
1684 return best;
1685
1686 /* Here SYM is good for display. */
1687
1688 if (best == NULL)
1689 return sym;
1690
1691 char *sbest = strtab + best->st_name;
1692
1693 /* Prefer non-local symbols. */
1694 if (ELF_ST_BIND (sym->st_info) == STB_LOCAL
1695 && ELF_ST_BIND (best->st_info) != STB_LOCAL)
1696 return best;
1697 if (ELF_ST_BIND (sym->st_info) != STB_LOCAL
1698 && ELF_ST_BIND (best->st_info) == STB_LOCAL)
1699 return sym;
1700
1701 /* Select based on lexicographic order. */
1702 return strcmp (s, sbest) < 0 ? sym : best;
1703}
1704
1705/* Filter the sorted SYMTAB symbol array in-place to select at most one
1706 symbol for an address and drop symbols that are not good to display.
1707 Returns the new array length. */
1708
1709static uint64_t
1710filter_display_syms (Filedata * filedata,
1711 Elf_Internal_Sym * symtab,
1712 uint64_t nsyms,
1713 char * strtab,
1714 uint64_t strtablen)
1715{
1716 Elf_Internal_Sym *r = symtab;
1717 Elf_Internal_Sym *w = symtab;
1718 Elf_Internal_Sym *best = NULL;
1719 Elf_Internal_Sym *end = symtab + nsyms;
1720 while (r < end)
1721 {
1722 /* Select the best symbol for an address. */
1723 while (r < end
1724 && (best == NULL || best->st_value == r->st_value))
1725 {
1726 best = select_display_sym (filedata, strtab, strtablen, best, r);
1727 r++;
1728 }
1729 if (best != NULL)
1730 {
1731 *w = *best;
1732 w++;
1733 best = NULL;
1734 }
1735 }
1736 return w - symtab;
1737}
1738
fcf8f323
NC
1739static /* signed */ int
1740symcmp (const void *p, const void *q)
1741{
1742 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1743 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1744
1745 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1746}
1747
3b3e2090
NC
1748static uint64_t
1749count_relr_relocations (Filedata * filedata,
1750 Elf_Internal_Shdr * section)
1751{
1752 uint64_t * relrs;
1753 uint64_t nentries;
1754 uint64_t i;
1755 uint64_t count;
1756 int entsize;
1757
1758 if (section == NULL
1759 || section->sh_type != SHT_RELR
1760 || section->sh_size == 0)
1761 return 0;
1762
1763 entsize = section->sh_entsize;
1764 if (entsize == 0)
1765 entsize = is_32bit_elf
1766 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1767 else if (entsize != sizeof (Elf32_External_Relr)
1768 && entsize != sizeof (Elf64_External_Relr))
1769 return 0;
1770
1771 nentries = section->sh_size / entsize;
1772 if (nentries == 0)
1773 return 0;
1774
1775 /* FIXME: This call to get_data duplicates one that follows in
1776 dump_relr_relocations(). They could be combined into just
1777 one call. */
1778 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1779 section->sh_size, _("RELR relocation data"));
1780 if (relrs == NULL)
1781 return 0;
1782
1783 for (count = i = 0; i < nentries; i++)
1784 {
1785 uint64_t entry;
1786
1787 if (entsize == sizeof (Elf32_External_Relr))
1788 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1789 else
1790 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1791
1792 if ((entry & 1) == 0)
1793 {
1794 ++ count;
1795 }
1796 else
1797 {
1798 if (entry == 1)
1799 continue;
1800
1801 for (; entry >>= 1;)
1802 if ((entry & 1) == 1)
1803 ++ count;
1804 }
1805 }
1806
1807 free (relrs);
1808 return count;
1809}
1810
fcf8f323
NC
1811static bool
1812dump_relr_relocations (Filedata * filedata,
1813 Elf_Internal_Shdr * section,
1814 Elf_Internal_Sym * symtab,
1815 uint64_t nsyms,
1816 char * strtab,
1817 uint64_t strtablen)
1818{
1819 uint64_t * relrs;
1820 uint64_t nentries, i;
1821 uint64_t relr_size = section->sh_size;
1822 int relr_entsize = section->sh_entsize;
1823 uint64_t relr_offset = section->sh_offset;
1824 uint64_t where = 0;
1825 int num_bits_in_entry;
1826
fcf8f323 1827 if (relr_entsize == 0)
3b3e2090
NC
1828 relr_entsize = is_32bit_elf
1829 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
fcf8f323
NC
1830
1831 nentries = relr_size / relr_entsize;
1832
3b3e2090
NC
1833 if (nentries == 0)
1834 return true;
1835
fcf8f323
NC
1836 if (relr_entsize == sizeof (Elf32_External_Relr))
1837 num_bits_in_entry = 31;
1838 else if (relr_entsize == sizeof (Elf64_External_Relr))
1839 num_bits_in_entry = 63;
1840 else
1841 {
1842 warn (_("Unexpected entsize for RELR section\n"));
1843 return false;
1844 }
fcf8f323 1845
3b3e2090
NC
1846 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1847 if (relrs == NULL)
1848 return false;
1849
d41629d3
SN
1850 /* Paranoia. */
1851 if (strtab == NULL)
1852 strtablen = 0;
1853 if (symtab == NULL)
1854 nsyms = 0;
1855
3b3e2090
NC
1856 if (symtab != NULL)
1857 {
1858 /* Symbol tables are not sorted on address, but we want a quick lookup
1859 for the symbol associated with each address computed below, so sort
d41629d3
SN
1860 the table then filter out unwanted entries. FIXME: This assumes that
1861 the symbol table will not be used later on for some other purpose. */
3b3e2090 1862 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
d41629d3 1863 nsyms = filter_display_syms (filedata, symtab, nsyms, strtab, strtablen);
3b3e2090
NC
1864 }
1865
1866 if (relr_entsize == sizeof (Elf32_External_Relr))
21061c38 1867 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323 1868 else
21061c38 1869 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323
NC
1870
1871 for (i = 0; i < nentries; i++)
1872 {
1873 uint64_t entry;
1874
3b3e2090 1875 if (relr_entsize == sizeof (Elf32_External_Relr))
fcf8f323
NC
1876 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1877 else
1878 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1879
1880 /* We assume that there will never be more than 9999 entries. */
1881 printf (_("%04u: "), (unsigned int) i);
1882 print_vma (entry, ZERO_HEX);
1883 printf (" ");
1884
1885 if ((entry & 1) == 0)
1886 {
1887 where = entry;
d565a958 1888 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, where);
fcf8f323
NC
1889 printf ("\n");
1890 where += relr_entsize;
1891 }
1892 else
1893 {
1894 bool first = true;
1895 int j;
1896
1897 /* The least significant bit is ignored. */
1898 if (entry == 1)
3b3e2090
NC
1899 /* This can actually happen when the linker is allowed to shrink
1900 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1901 continue;
fcf8f323
NC
1902 else if (i == 0)
1903 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1904
1905 for (j = 0; entry >>= 1; j++)
1906 if ((entry & 1) == 1)
1907 {
1908 uint64_t addr = where + (j * relr_entsize);
1909
1910 if (first)
1911 {
d565a958 1912 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
fcf8f323
NC
1913 first = false;
1914 }
1915 else
1916 {
1917 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
d565a958 1918 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
fcf8f323
NC
1919 }
1920 }
1921
1922 printf ("\n");
1923 where += num_bits_in_entry * relr_entsize;
1924 }
1925 }
1926
1927 free (relrs);
1928 return true;
1929}
1930
d3ba0551
AM
1931/* Display the contents of the relocation data found at the specified
1932 offset. */
ee42cf8c 1933
015dc7e1 1934static bool
fcf8f323
NC
1935dump_relocations (Filedata * filedata,
1936 uint64_t rel_offset,
1937 uint64_t rel_size,
1938 Elf_Internal_Sym * symtab,
1939 uint64_t nsyms,
1940 char * strtab,
1941 uint64_t strtablen,
1942 relocation_type rel_type,
1943 bool is_dynsym)
26c527e6
AM
1944{
1945 size_t i;
2cf0635d 1946 Elf_Internal_Rela * rels;
015dc7e1 1947 bool res = true;
103f02d3 1948
a7fd1186
FS
1949 if (rel_type == reltype_unknown)
1950 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1951
a7fd1186 1952 if (rel_type == reltype_rela)
4d6ed7c8 1953 {
dda8d76d 1954 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1955 return false;
4d6ed7c8 1956 }
a7fd1186 1957 else if (rel_type == reltype_rel)
4d6ed7c8 1958 {
dda8d76d 1959 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1960 return false;
252b5132 1961 }
a7fd1186
FS
1962 else if (rel_type == reltype_relr)
1963 {
fcf8f323
NC
1964 /* This should have been handled by display_relocations(). */
1965 return false;
a7fd1186 1966 }
252b5132 1967
410f7a12
L
1968 if (is_32bit_elf)
1969 {
a7fd1186 1970 if (rel_type == reltype_rela)
2c71103e
NC
1971 {
1972 if (do_wide)
1973 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1974 else
1975 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1976 }
410f7a12 1977 else
2c71103e
NC
1978 {
1979 if (do_wide)
1980 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1981 else
1982 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1983 }
410f7a12 1984 }
252b5132 1985 else
410f7a12 1986 {
a7fd1186 1987 if (rel_type == reltype_rela)
2c71103e
NC
1988 {
1989 if (do_wide)
8beeaeb7 1990 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1991 else
1992 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1993 }
410f7a12 1994 else
2c71103e
NC
1995 {
1996 if (do_wide)
8beeaeb7 1997 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1998 else
1999 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
2000 }
410f7a12 2001 }
252b5132
RH
2002
2003 for (i = 0; i < rel_size; i++)
2004 {
2cf0635d 2005 const char * rtype;
625d49fc
AM
2006 uint64_t offset;
2007 uint64_t inf;
2008 uint64_t symtab_index;
2009 uint64_t type;
103f02d3 2010
b34976b6 2011 offset = rels[i].r_offset;
91d6fa6a 2012 inf = rels[i].r_info;
103f02d3 2013
dda8d76d 2014 type = get_reloc_type (filedata, inf);
91d6fa6a 2015 symtab_index = get_reloc_symindex (inf);
252b5132 2016
410f7a12
L
2017 if (is_32bit_elf)
2018 {
39dbeff8
AM
2019 printf ("%8.8lx %8.8lx ",
2020 (unsigned long) offset & 0xffffffff,
91d6fa6a 2021 (unsigned long) inf & 0xffffffff);
410f7a12
L
2022 }
2023 else
2024 {
39dbeff8 2025 printf (do_wide
b8281767
AM
2026 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
2027 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 2028 offset, inf);
410f7a12 2029 }
103f02d3 2030
dda8d76d 2031 switch (filedata->file_header.e_machine)
252b5132
RH
2032 {
2033 default:
2034 rtype = NULL;
2035 break;
2036
a06ea964
NC
2037 case EM_AARCH64:
2038 rtype = elf_aarch64_reloc_type (type);
2039 break;
2040
2b0337b0 2041 case EM_M32R:
252b5132 2042 case EM_CYGNUS_M32R:
9ea033b2 2043 rtype = elf_m32r_reloc_type (type);
252b5132
RH
2044 break;
2045
2046 case EM_386:
22abe556 2047 case EM_IAMCU:
9ea033b2 2048 rtype = elf_i386_reloc_type (type);
252b5132
RH
2049 break;
2050
ba2685cc
AM
2051 case EM_68HC11:
2052 case EM_68HC12:
2053 rtype = elf_m68hc11_reloc_type (type);
2054 break;
75751cd9 2055
7b4ae824
JD
2056 case EM_S12Z:
2057 rtype = elf_s12z_reloc_type (type);
2058 break;
2059
252b5132 2060 case EM_68K:
9ea033b2 2061 rtype = elf_m68k_reloc_type (type);
252b5132
RH
2062 break;
2063
f954747f
AM
2064 case EM_960:
2065 rtype = elf_i960_reloc_type (type);
2066 break;
2067
adde6300 2068 case EM_AVR:
2b0337b0 2069 case EM_AVR_OLD:
adde6300
AM
2070 rtype = elf_avr_reloc_type (type);
2071 break;
2072
9ea033b2
NC
2073 case EM_OLD_SPARCV9:
2074 case EM_SPARC32PLUS:
2075 case EM_SPARCV9:
252b5132 2076 case EM_SPARC:
9ea033b2 2077 rtype = elf_sparc_reloc_type (type);
252b5132
RH
2078 break;
2079
e9f53129
AM
2080 case EM_SPU:
2081 rtype = elf_spu_reloc_type (type);
2082 break;
2083
708e2187
NC
2084 case EM_V800:
2085 rtype = v800_reloc_type (type);
2086 break;
2b0337b0 2087 case EM_V850:
252b5132 2088 case EM_CYGNUS_V850:
9ea033b2 2089 rtype = v850_reloc_type (type);
252b5132
RH
2090 break;
2091
2b0337b0 2092 case EM_D10V:
252b5132 2093 case EM_CYGNUS_D10V:
9ea033b2 2094 rtype = elf_d10v_reloc_type (type);
252b5132
RH
2095 break;
2096
2b0337b0 2097 case EM_D30V:
252b5132 2098 case EM_CYGNUS_D30V:
9ea033b2 2099 rtype = elf_d30v_reloc_type (type);
252b5132
RH
2100 break;
2101
d172d4ba
NC
2102 case EM_DLX:
2103 rtype = elf_dlx_reloc_type (type);
2104 break;
2105
252b5132 2106 case EM_SH:
9ea033b2 2107 rtype = elf_sh_reloc_type (type);
252b5132
RH
2108 break;
2109
2b0337b0 2110 case EM_MN10300:
252b5132 2111 case EM_CYGNUS_MN10300:
9ea033b2 2112 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
2113 break;
2114
2b0337b0 2115 case EM_MN10200:
252b5132 2116 case EM_CYGNUS_MN10200:
9ea033b2 2117 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
2118 break;
2119
2b0337b0 2120 case EM_FR30:
252b5132 2121 case EM_CYGNUS_FR30:
9ea033b2 2122 rtype = elf_fr30_reloc_type (type);
252b5132
RH
2123 break;
2124
ba2685cc
AM
2125 case EM_CYGNUS_FRV:
2126 rtype = elf_frv_reloc_type (type);
2127 break;
5c70f934 2128
b8891f8d
AJ
2129 case EM_CSKY:
2130 rtype = elf_csky_reloc_type (type);
2131 break;
2132
3f8107ab
AM
2133 case EM_FT32:
2134 rtype = elf_ft32_reloc_type (type);
2135 break;
2136
252b5132 2137 case EM_MCORE:
9ea033b2 2138 rtype = elf_mcore_reloc_type (type);
252b5132
RH
2139 break;
2140
3c3bdf30
NC
2141 case EM_MMIX:
2142 rtype = elf_mmix_reloc_type (type);
2143 break;
2144
5506d11a
AM
2145 case EM_MOXIE:
2146 rtype = elf_moxie_reloc_type (type);
2147 break;
2148
2469cfa2 2149 case EM_MSP430:
dda8d76d 2150 if (uses_msp430x_relocs (filedata))
13761a11
NC
2151 {
2152 rtype = elf_msp430x_reloc_type (type);
2153 break;
2154 }
1a0670f3 2155 /* Fall through. */
2469cfa2
NC
2156 case EM_MSP430_OLD:
2157 rtype = elf_msp430_reloc_type (type);
2158 break;
2159
35c08157
KLC
2160 case EM_NDS32:
2161 rtype = elf_nds32_reloc_type (type);
2162 break;
2163
252b5132 2164 case EM_PPC:
9ea033b2 2165 rtype = elf_ppc_reloc_type (type);
252b5132
RH
2166 break;
2167
c833c019
AM
2168 case EM_PPC64:
2169 rtype = elf_ppc64_reloc_type (type);
2170 break;
2171
252b5132 2172 case EM_MIPS:
4fe85591 2173 case EM_MIPS_RS3_LE:
9ea033b2 2174 rtype = elf_mips_reloc_type (type);
252b5132
RH
2175 break;
2176
e23eba97
NC
2177 case EM_RISCV:
2178 rtype = elf_riscv_reloc_type (type);
2179 break;
2180
252b5132 2181 case EM_ALPHA:
9ea033b2 2182 rtype = elf_alpha_reloc_type (type);
252b5132
RH
2183 break;
2184
2185 case EM_ARM:
9ea033b2 2186 rtype = elf_arm_reloc_type (type);
252b5132
RH
2187 break;
2188
584da044 2189 case EM_ARC:
886a2506
NC
2190 case EM_ARC_COMPACT:
2191 case EM_ARC_COMPACT2:
b5c37946
SJ
2192 case EM_ARC_COMPACT3:
2193 case EM_ARC_COMPACT3_64:
9ea033b2 2194 rtype = elf_arc_reloc_type (type);
252b5132
RH
2195 break;
2196
2197 case EM_PARISC:
69e617ca 2198 rtype = elf_hppa_reloc_type (type);
252b5132 2199 break;
7d466069 2200
b8720f9d
JL
2201 case EM_H8_300:
2202 case EM_H8_300H:
2203 case EM_H8S:
2204 rtype = elf_h8_reloc_type (type);
2205 break;
2206
73589c9d
CS
2207 case EM_OR1K:
2208 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
2209 break;
2210
7d466069 2211 case EM_PJ:
2b0337b0 2212 case EM_PJ_OLD:
7d466069
ILT
2213 rtype = elf_pj_reloc_type (type);
2214 break;
800eeca4
JW
2215 case EM_IA_64:
2216 rtype = elf_ia64_reloc_type (type);
2217 break;
1b61cf92 2218
6e712424
PI
2219 case EM_KVX:
2220 rtype = elf_kvx_reloc_type (type);
2221 break;
2222
1b61cf92
HPN
2223 case EM_CRIS:
2224 rtype = elf_cris_reloc_type (type);
2225 break;
535c37ff 2226
f954747f
AM
2227 case EM_860:
2228 rtype = elf_i860_reloc_type (type);
2229 break;
2230
bcedfee6 2231 case EM_X86_64:
8a9036a4 2232 case EM_L1OM:
7a9068fe 2233 case EM_K1OM:
bcedfee6
NC
2234 rtype = elf_x86_64_reloc_type (type);
2235 break;
a85d7ed0 2236
f954747f
AM
2237 case EM_S370:
2238 rtype = i370_reloc_type (type);
2239 break;
2240
53c7db4b
KH
2241 case EM_S390_OLD:
2242 case EM_S390:
2243 rtype = elf_s390_reloc_type (type);
2244 break;
93fbbb04 2245
1c0d3aa6
NC
2246 case EM_SCORE:
2247 rtype = elf_score_reloc_type (type);
2248 break;
2249
93fbbb04
GK
2250 case EM_XSTORMY16:
2251 rtype = elf_xstormy16_reloc_type (type);
2252 break;
179d3252 2253
1fe1f39c
NC
2254 case EM_CRX:
2255 rtype = elf_crx_reloc_type (type);
2256 break;
2257
179d3252
JT
2258 case EM_VAX:
2259 rtype = elf_vax_reloc_type (type);
2260 break;
1e4cf259 2261
619ed720
EB
2262 case EM_VISIUM:
2263 rtype = elf_visium_reloc_type (type);
2264 break;
2265
aca4efc7
JM
2266 case EM_BPF:
2267 rtype = elf_bpf_reloc_type (type);
2268 break;
2269
cfb8c092
NC
2270 case EM_ADAPTEVA_EPIPHANY:
2271 rtype = elf_epiphany_reloc_type (type);
2272 break;
2273
1e4cf259
NC
2274 case EM_IP2K:
2275 case EM_IP2K_OLD:
2276 rtype = elf_ip2k_reloc_type (type);
2277 break;
3b36097d
SC
2278
2279 case EM_IQ2000:
2280 rtype = elf_iq2000_reloc_type (type);
2281 break;
88da6820
NC
2282
2283 case EM_XTENSA_OLD:
2284 case EM_XTENSA:
2285 rtype = elf_xtensa_reloc_type (type);
2286 break;
a34e3ecb 2287
84e94c90
NC
2288 case EM_LATTICEMICO32:
2289 rtype = elf_lm32_reloc_type (type);
2290 break;
2291
ff7eeb89 2292 case EM_M32C_OLD:
49f58d10
JB
2293 case EM_M32C:
2294 rtype = elf_m32c_reloc_type (type);
2295 break;
2296
d031aafb
NS
2297 case EM_MT:
2298 rtype = elf_mt_reloc_type (type);
a34e3ecb 2299 break;
1d65ded4
CM
2300
2301 case EM_BLACKFIN:
2302 rtype = elf_bfin_reloc_type (type);
2303 break;
15ab5209
DB
2304
2305 case EM_CYGNUS_MEP:
2306 rtype = elf_mep_reloc_type (type);
2307 break;
60bca95a
NC
2308
2309 case EM_CR16:
2310 rtype = elf_cr16_reloc_type (type);
2311 break;
dd24e3da 2312
7ba29e2a
NC
2313 case EM_MICROBLAZE:
2314 case EM_MICROBLAZE_OLD:
2315 rtype = elf_microblaze_reloc_type (type);
2316 break;
c7927a3c 2317
99c513f6
DD
2318 case EM_RL78:
2319 rtype = elf_rl78_reloc_type (type);
2320 break;
2321
c7927a3c
NC
2322 case EM_RX:
2323 rtype = elf_rx_reloc_type (type);
2324 break;
c29aca4a 2325
a3c62988
NC
2326 case EM_METAG:
2327 rtype = elf_metag_reloc_type (type);
2328 break;
2329
40b36596
JM
2330 case EM_TI_C6000:
2331 rtype = elf_tic6x_reloc_type (type);
2332 break;
aa137e4d
NC
2333
2334 case EM_TILEGX:
2335 rtype = elf_tilegx_reloc_type (type);
2336 break;
2337
2338 case EM_TILEPRO:
2339 rtype = elf_tilepro_reloc_type (type);
2340 break;
f6c1a2d5 2341
f96bd6c2
PC
2342 case EM_WEBASSEMBLY:
2343 rtype = elf_wasm32_reloc_type (type);
2344 break;
2345
f6c1a2d5
NC
2346 case EM_XGATE:
2347 rtype = elf_xgate_reloc_type (type);
2348 break;
36591ba1
SL
2349
2350 case EM_ALTERA_NIOS2:
2351 rtype = elf_nios2_reloc_type (type);
2352 break;
2b100bb5
DD
2353
2354 case EM_TI_PRU:
2355 rtype = elf_pru_reloc_type (type);
2356 break;
fe944acf
FT
2357
2358 case EM_NFP:
2359 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2360 rtype = elf_nfp3200_reloc_type (type);
2361 else
2362 rtype = elf_nfp_reloc_type (type);
2363 break;
6655dba2
SB
2364
2365 case EM_Z80:
2366 rtype = elf_z80_reloc_type (type);
2367 break;
e9a0721f 2368
2369 case EM_LOONGARCH:
2370 rtype = elf_loongarch_reloc_type (type);
2371 break;
2372
0c857ef4
SM
2373 case EM_AMDGPU:
2374 rtype = elf_amdgpu_reloc_type (type);
2375 break;
252b5132
RH
2376 }
2377
2378 if (rtype == NULL)
39dbeff8 2379 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2380 else
5c144731 2381 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2382
dda8d76d 2383 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2384 && rtype != NULL
7ace3541 2385 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2386 && rel_type == reltype_rela)
7ace3541
RH
2387 {
2388 switch (rels[i].r_addend)
2389 {
2390 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2391 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2392 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2393 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2394 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2395 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2396 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2397 default: rtype = NULL;
2398 }
32ec8896 2399
7ace3541
RH
2400 if (rtype)
2401 printf (" (%s)", rtype);
2402 else
2403 {
2404 putchar (' ');
26c527e6
AM
2405 printf (_("<unknown addend: %" PRIx64 ">"),
2406 rels[i].r_addend);
015dc7e1 2407 res = false;
7ace3541
RH
2408 }
2409 }
2410 else if (symtab_index)
252b5132 2411 {
af3fc3bc 2412 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2413 {
27a45f42
AS
2414 error (_(" bad symbol index: %08lx in reloc\n"),
2415 (unsigned long) symtab_index);
015dc7e1 2416 res = false;
32ec8896 2417 }
af3fc3bc 2418 else
19936277 2419 {
2cf0635d 2420 Elf_Internal_Sym * psym;
bb4d2ac2
L
2421 const char * version_string;
2422 enum versioned_symbol_info sym_info;
2423 unsigned short vna_other;
19936277 2424
af3fc3bc 2425 psym = symtab + symtab_index;
103f02d3 2426
bb4d2ac2 2427 version_string
dda8d76d 2428 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2429 strtab, strtablen,
2430 symtab_index,
2431 psym,
2432 &sym_info,
2433 &vna_other);
2434
af3fc3bc 2435 printf (" ");
171191ba 2436
d8045f23
NC
2437 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2438 {
2439 const char * name;
2440 unsigned int len;
2441 unsigned int width = is_32bit_elf ? 8 : 14;
2442
2443 /* Relocations against GNU_IFUNC symbols do not use the value
2444 of the symbol as the address to relocate against. Instead
2445 they invoke the function named by the symbol and use its
2446 result as the address for relocation.
2447
2448 To indicate this to the user, do not display the value of
2449 the symbol in the "Symbols's Value" field. Instead show
2450 its name followed by () as a hint that the symbol is
2451 invoked. */
2452
2453 if (strtab == NULL
2454 || psym->st_name == 0
2455 || psym->st_name >= strtablen)
2456 name = "??";
2457 else
2458 name = strtab + psym->st_name;
2459
b6ac461a 2460 len = print_symbol_name (width, name);
bb4d2ac2
L
2461 if (version_string)
2462 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2463 version_string);
d8045f23
NC
2464 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2465 }
2466 else
2467 {
2468 print_vma (psym->st_value, LONG_HEX);
171191ba 2469
d8045f23
NC
2470 printf (is_32bit_elf ? " " : " ");
2471 }
103f02d3 2472
af3fc3bc 2473 if (psym->st_name == 0)
f1ef08cb 2474 {
2cf0635d 2475 const char * sec_name = "<null>";
f1ef08cb
AM
2476
2477 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2478 sec_name = printable_section_name_from_index
2479 (filedata, psym->st_shndx, NULL);
2480
2481 print_symbol_name (22, sec_name);
f1ef08cb 2482 }
af3fc3bc 2483 else if (strtab == NULL)
d79b3d50 2484 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2485 else if (psym->st_name >= strtablen)
32ec8896 2486 {
27a45f42
AS
2487 error (_("<corrupt string table index: %3ld>\n"),
2488 psym->st_name);
015dc7e1 2489 res = false;
32ec8896 2490 }
af3fc3bc 2491 else
bb4d2ac2 2492 {
b6ac461a 2493 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2494 if (version_string)
2495 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2496 version_string);
2497 }
103f02d3 2498
a7fd1186 2499 if (rel_type == reltype_rela)
171191ba 2500 {
625d49fc 2501 uint64_t off = rels[i].r_addend;
171191ba 2502
625d49fc
AM
2503 if ((int64_t) off < 0)
2504 printf (" - %" PRIx64, -off);
171191ba 2505 else
625d49fc 2506 printf (" + %" PRIx64, off);
171191ba 2507 }
19936277 2508 }
252b5132 2509 }
a7fd1186 2510 else if (rel_type == reltype_rela)
f7a99963 2511 {
625d49fc 2512 uint64_t off = rels[i].r_addend;
e04d7088
L
2513
2514 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2515 if ((int64_t) off < 0)
2516 printf ("-%" PRIx64, -off);
e04d7088 2517 else
625d49fc 2518 printf ("%" PRIx64, off);
f7a99963 2519 }
252b5132 2520
dda8d76d 2521 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2522 && rtype != NULL
2523 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2524 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2525
252b5132 2526 putchar ('\n');
2c71103e 2527
dda8d76d 2528 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2529 {
625d49fc
AM
2530 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2531 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2532 const char * rtype2 = elf_mips_reloc_type (type2);
2533 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2534
2c71103e
NC
2535 printf (" Type2: ");
2536
2537 if (rtype2 == NULL)
39dbeff8
AM
2538 printf (_("unrecognized: %-7lx"),
2539 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2540 else
2541 printf ("%-17.17s", rtype2);
2542
18bd398b 2543 printf ("\n Type3: ");
2c71103e
NC
2544
2545 if (rtype3 == NULL)
39dbeff8
AM
2546 printf (_("unrecognized: %-7lx"),
2547 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2548 else
2549 printf ("%-17.17s", rtype3);
2550
53c7db4b 2551 putchar ('\n');
2c71103e 2552 }
252b5132
RH
2553 }
2554
c8286bd1 2555 free (rels);
32ec8896
NC
2556
2557 return res;
252b5132
RH
2558}
2559
37c18eed
SD
2560static const char *
2561get_aarch64_dynamic_type (unsigned long type)
2562{
2563 switch (type)
2564 {
2565 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2566 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2567 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2568 default:
2569 return NULL;
2570 }
2571}
2572
252b5132 2573static const char *
d3ba0551 2574get_mips_dynamic_type (unsigned long type)
252b5132
RH
2575{
2576 switch (type)
2577 {
2578 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2579 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2580 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2581 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2582 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2583 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2584 case DT_MIPS_MSYM: return "MIPS_MSYM";
2585 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2586 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2587 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2588 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2589 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2590 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2591 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2592 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2593 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2594 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2595 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2596 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2597 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2598 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2599 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2600 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2601 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2602 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2603 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2604 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2605 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2606 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2607 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2608 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2609 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2610 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2611 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2612 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2613 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2614 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2615 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2616 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2617 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2618 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2619 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2620 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2621 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2622 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2623 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2624 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2625 default:
2626 return NULL;
2627 }
2628}
2629
9a097730 2630static const char *
d3ba0551 2631get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2632{
2633 switch (type)
2634 {
2635 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2636 default:
2637 return NULL;
2638 }
103f02d3
UD
2639}
2640
7490d522
AM
2641static const char *
2642get_ppc_dynamic_type (unsigned long type)
2643{
2644 switch (type)
2645 {
a7f2871e 2646 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2647 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2648 default:
2649 return NULL;
2650 }
2651}
2652
f1cb7e17 2653static const char *
d3ba0551 2654get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2655{
2656 switch (type)
2657 {
a7f2871e
AM
2658 case DT_PPC64_GLINK: return "PPC64_GLINK";
2659 case DT_PPC64_OPD: return "PPC64_OPD";
2660 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2661 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2662 default:
2663 return NULL;
2664 }
2665}
2666
103f02d3 2667static const char *
d3ba0551 2668get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2669{
2670 switch (type)
2671 {
2672 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2673 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2674 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2675 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2676 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2677 case DT_HP_PREINIT: return "HP_PREINIT";
2678 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2679 case DT_HP_NEEDED: return "HP_NEEDED";
2680 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2681 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2682 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2683 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2684 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2685 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2686 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2687 case DT_HP_FILTERED: return "HP_FILTERED";
2688 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2689 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2690 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2691 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2692 case DT_PLT: return "PLT";
2693 case DT_PLT_SIZE: return "PLT_SIZE";
2694 case DT_DLT: return "DLT";
2695 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2696 default:
2697 return NULL;
2698 }
2699}
9a097730 2700
ecc51f48 2701static const char *
d3ba0551 2702get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2703{
2704 switch (type)
2705 {
148b93f2
NC
2706 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2707 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2708 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2709 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2710 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2711 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2712 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2713 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2714 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2715 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2716 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2717 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2718 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2719 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2720 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2721 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2722 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2723 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2724 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2725 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2726 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2727 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2728 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2729 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2730 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2731 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2732 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2733 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2734 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2735 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2736 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2737 default:
2738 return NULL;
2739 }
2740}
2741
fd85a6a1
NC
2742static const char *
2743get_solaris_section_type (unsigned long type)
2744{
2745 switch (type)
2746 {
2747 case 0x6fffffee: return "SUNW_ancillary";
2748 case 0x6fffffef: return "SUNW_capchain";
2749 case 0x6ffffff0: return "SUNW_capinfo";
2750 case 0x6ffffff1: return "SUNW_symsort";
2751 case 0x6ffffff2: return "SUNW_tlssort";
2752 case 0x6ffffff3: return "SUNW_LDYNSYM";
2753 case 0x6ffffff4: return "SUNW_dof";
2754 case 0x6ffffff5: return "SUNW_cap";
2755 case 0x6ffffff6: return "SUNW_SIGNATURE";
2756 case 0x6ffffff7: return "SUNW_ANNOTATE";
2757 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2758 case 0x6ffffff9: return "SUNW_DEBUG";
2759 case 0x6ffffffa: return "SUNW_move";
2760 case 0x6ffffffb: return "SUNW_COMDAT";
2761 case 0x6ffffffc: return "SUNW_syminfo";
2762 case 0x6ffffffd: return "SUNW_verdef";
2763 case 0x6ffffffe: return "SUNW_verneed";
2764 case 0x6fffffff: return "SUNW_versym";
2765 case 0x70000000: return "SPARC_GOTDATA";
2766 default: return NULL;
2767 }
2768}
2769
fabcb361
RH
2770static const char *
2771get_alpha_dynamic_type (unsigned long type)
2772{
2773 switch (type)
2774 {
2775 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2776 default: return NULL;
fabcb361
RH
2777 }
2778}
2779
1c0d3aa6
NC
2780static const char *
2781get_score_dynamic_type (unsigned long type)
2782{
2783 switch (type)
2784 {
2785 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2786 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2787 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2788 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2789 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2790 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2791 default: return NULL;
1c0d3aa6
NC
2792 }
2793}
2794
40b36596
JM
2795static const char *
2796get_tic6x_dynamic_type (unsigned long type)
2797{
2798 switch (type)
2799 {
2800 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2801 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2802 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2803 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2804 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2805 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2806 default: return NULL;
40b36596
JM
2807 }
2808}
1c0d3aa6 2809
36591ba1
SL
2810static const char *
2811get_nios2_dynamic_type (unsigned long type)
2812{
2813 switch (type)
2814 {
2815 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2816 default: return NULL;
36591ba1
SL
2817 }
2818}
2819
fd85a6a1
NC
2820static const char *
2821get_solaris_dynamic_type (unsigned long type)
2822{
2823 switch (type)
2824 {
2825 case 0x6000000d: return "SUNW_AUXILIARY";
2826 case 0x6000000e: return "SUNW_RTLDINF";
2827 case 0x6000000f: return "SUNW_FILTER";
2828 case 0x60000010: return "SUNW_CAP";
2829 case 0x60000011: return "SUNW_SYMTAB";
2830 case 0x60000012: return "SUNW_SYMSZ";
2831 case 0x60000013: return "SUNW_SORTENT";
2832 case 0x60000014: return "SUNW_SYMSORT";
2833 case 0x60000015: return "SUNW_SYMSORTSZ";
2834 case 0x60000016: return "SUNW_TLSSORT";
2835 case 0x60000017: return "SUNW_TLSSORTSZ";
2836 case 0x60000018: return "SUNW_CAPINFO";
2837 case 0x60000019: return "SUNW_STRPAD";
2838 case 0x6000001a: return "SUNW_CAPCHAIN";
2839 case 0x6000001b: return "SUNW_LDMACH";
2840 case 0x6000001d: return "SUNW_CAPCHAINENT";
2841 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2842 case 0x60000021: return "SUNW_PARENT";
2843 case 0x60000023: return "SUNW_ASLR";
2844 case 0x60000025: return "SUNW_RELAX";
2845 case 0x60000029: return "SUNW_NXHEAP";
2846 case 0x6000002b: return "SUNW_NXSTACK";
2847
2848 case 0x70000001: return "SPARC_REGISTER";
2849 case 0x7ffffffd: return "AUXILIARY";
2850 case 0x7ffffffe: return "USED";
2851 case 0x7fffffff: return "FILTER";
2852
15f205b1 2853 default: return NULL;
fd85a6a1
NC
2854 }
2855}
2856
8155b853
NC
2857static const char *
2858get_riscv_dynamic_type (unsigned long type)
2859{
2860 switch (type)
2861 {
2862 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2863 default:
2864 return NULL;
2865 }
2866}
2867
832ca732
L
2868static const char *
2869get_x86_64_dynamic_type (unsigned long type)
2870{
2871 switch (type)
2872 {
2873 case DT_X86_64_PLT:
2874 return "DT_X86_64_PLT";
2875 case DT_X86_64_PLTSZ:
2876 return "DT_X86_64_PLTSZ";
2877 case DT_X86_64_PLTENT:
2878 return "DT_X86_64_PLTENT";
2879 default:
2880 return NULL;
2881 }
2882}
2883
252b5132 2884static const char *
dda8d76d 2885get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2886{
e9e44622 2887 static char buff[64];
252b5132
RH
2888
2889 switch (type)
2890 {
2891 case DT_NULL: return "NULL";
2892 case DT_NEEDED: return "NEEDED";
2893 case DT_PLTRELSZ: return "PLTRELSZ";
2894 case DT_PLTGOT: return "PLTGOT";
2895 case DT_HASH: return "HASH";
2896 case DT_STRTAB: return "STRTAB";
2897 case DT_SYMTAB: return "SYMTAB";
2898 case DT_RELA: return "RELA";
2899 case DT_RELASZ: return "RELASZ";
2900 case DT_RELAENT: return "RELAENT";
2901 case DT_STRSZ: return "STRSZ";
2902 case DT_SYMENT: return "SYMENT";
2903 case DT_INIT: return "INIT";
2904 case DT_FINI: return "FINI";
2905 case DT_SONAME: return "SONAME";
2906 case DT_RPATH: return "RPATH";
2907 case DT_SYMBOLIC: return "SYMBOLIC";
2908 case DT_REL: return "REL";
2909 case DT_RELSZ: return "RELSZ";
2910 case DT_RELENT: return "RELENT";
dd207c13
FS
2911 case DT_RELR: return "RELR";
2912 case DT_RELRSZ: return "RELRSZ";
2913 case DT_RELRENT: return "RELRENT";
252b5132
RH
2914 case DT_PLTREL: return "PLTREL";
2915 case DT_DEBUG: return "DEBUG";
2916 case DT_TEXTREL: return "TEXTREL";
2917 case DT_JMPREL: return "JMPREL";
2918 case DT_BIND_NOW: return "BIND_NOW";
2919 case DT_INIT_ARRAY: return "INIT_ARRAY";
2920 case DT_FINI_ARRAY: return "FINI_ARRAY";
2921 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2922 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2923 case DT_RUNPATH: return "RUNPATH";
2924 case DT_FLAGS: return "FLAGS";
2d0e6f43 2925
d1133906
NC
2926 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2927 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2928 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2929
05107a46 2930 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2931 case DT_PLTPADSZ: return "PLTPADSZ";
2932 case DT_MOVEENT: return "MOVEENT";
2933 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2934 case DT_FEATURE: return "FEATURE";
252b5132
RH
2935 case DT_POSFLAG_1: return "POSFLAG_1";
2936 case DT_SYMINSZ: return "SYMINSZ";
2937 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2938
252b5132 2939 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2940 case DT_CONFIG: return "CONFIG";
2941 case DT_DEPAUDIT: return "DEPAUDIT";
2942 case DT_AUDIT: return "AUDIT";
2943 case DT_PLTPAD: return "PLTPAD";
2944 case DT_MOVETAB: return "MOVETAB";
252b5132 2945 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2946
252b5132 2947 case DT_VERSYM: return "VERSYM";
103f02d3 2948
67a4f2b7
AO
2949 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2950 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2951 case DT_RELACOUNT: return "RELACOUNT";
2952 case DT_RELCOUNT: return "RELCOUNT";
2953 case DT_FLAGS_1: return "FLAGS_1";
2954 case DT_VERDEF: return "VERDEF";
2955 case DT_VERDEFNUM: return "VERDEFNUM";
2956 case DT_VERNEED: return "VERNEED";
2957 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2958
019148e4 2959 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2960 case DT_USED: return "USED";
2961 case DT_FILTER: return "FILTER";
103f02d3 2962
047b2264
JJ
2963 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2964 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2965 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2966 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2967 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2968 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2969 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2970
252b5132
RH
2971 default:
2972 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2973 {
2cf0635d 2974 const char * result;
103f02d3 2975
dda8d76d 2976 switch (filedata->file_header.e_machine)
252b5132 2977 {
37c18eed
SD
2978 case EM_AARCH64:
2979 result = get_aarch64_dynamic_type (type);
2980 break;
252b5132 2981 case EM_MIPS:
4fe85591 2982 case EM_MIPS_RS3_LE:
252b5132
RH
2983 result = get_mips_dynamic_type (type);
2984 break;
9a097730
RH
2985 case EM_SPARCV9:
2986 result = get_sparc64_dynamic_type (type);
2987 break;
7490d522
AM
2988 case EM_PPC:
2989 result = get_ppc_dynamic_type (type);
2990 break;
f1cb7e17
AM
2991 case EM_PPC64:
2992 result = get_ppc64_dynamic_type (type);
2993 break;
ecc51f48
NC
2994 case EM_IA_64:
2995 result = get_ia64_dynamic_type (type);
2996 break;
fabcb361
RH
2997 case EM_ALPHA:
2998 result = get_alpha_dynamic_type (type);
2999 break;
1c0d3aa6
NC
3000 case EM_SCORE:
3001 result = get_score_dynamic_type (type);
3002 break;
40b36596
JM
3003 case EM_TI_C6000:
3004 result = get_tic6x_dynamic_type (type);
3005 break;
36591ba1
SL
3006 case EM_ALTERA_NIOS2:
3007 result = get_nios2_dynamic_type (type);
3008 break;
8155b853
NC
3009 case EM_RISCV:
3010 result = get_riscv_dynamic_type (type);
3011 break;
832ca732
L
3012 case EM_X86_64:
3013 result = get_x86_64_dynamic_type (type);
3014 break;
252b5132 3015 default:
dda8d76d 3016 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
3017 result = get_solaris_dynamic_type (type);
3018 else
3019 result = NULL;
252b5132
RH
3020 break;
3021 }
3022
3023 if (result != NULL)
3024 return result;
3025
e9e44622 3026 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 3027 }
eec8f817 3028 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 3029 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 3030 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 3031 {
2cf0635d 3032 const char * result;
103f02d3 3033
dda8d76d 3034 switch (filedata->file_header.e_machine)
103f02d3
UD
3035 {
3036 case EM_PARISC:
3037 result = get_parisc_dynamic_type (type);
3038 break;
148b93f2
NC
3039 case EM_IA_64:
3040 result = get_ia64_dynamic_type (type);
3041 break;
103f02d3 3042 default:
dda8d76d 3043 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
3044 result = get_solaris_dynamic_type (type);
3045 else
3046 result = NULL;
103f02d3
UD
3047 break;
3048 }
3049
3050 if (result != NULL)
3051 return result;
3052
e9e44622
JJ
3053 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
3054 type);
103f02d3 3055 }
252b5132 3056 else
e9e44622 3057 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 3058
252b5132
RH
3059 return buff;
3060 }
3061}
3062
93df3340
AM
3063static bool get_program_headers (Filedata *);
3064static bool get_dynamic_section (Filedata *);
3065
3066static void
3067locate_dynamic_section (Filedata *filedata)
3068{
26c527e6 3069 uint64_t dynamic_addr = 0;
be7d229a 3070 uint64_t dynamic_size = 0;
93df3340
AM
3071
3072 if (filedata->file_header.e_phnum != 0
3073 && get_program_headers (filedata))
3074 {
3075 Elf_Internal_Phdr *segment;
3076 unsigned int i;
3077
3078 for (i = 0, segment = filedata->program_headers;
3079 i < filedata->file_header.e_phnum;
3080 i++, segment++)
3081 {
3082 if (segment->p_type == PT_DYNAMIC)
3083 {
3084 dynamic_addr = segment->p_offset;
3085 dynamic_size = segment->p_filesz;
3086
3087 if (filedata->section_headers != NULL)
3088 {
3089 Elf_Internal_Shdr *sec;
3090
3091 sec = find_section (filedata, ".dynamic");
3092 if (sec != NULL)
3093 {
3094 if (sec->sh_size == 0
3095 || sec->sh_type == SHT_NOBITS)
3096 {
3097 dynamic_addr = 0;
3098 dynamic_size = 0;
3099 }
3100 else
3101 {
3102 dynamic_addr = sec->sh_offset;
3103 dynamic_size = sec->sh_size;
3104 }
3105 }
3106 }
3107
3108 if (dynamic_addr > filedata->file_size
3109 || (dynamic_size > filedata->file_size - dynamic_addr))
3110 {
3111 dynamic_addr = 0;
3112 dynamic_size = 0;
3113 }
3114 break;
3115 }
3116 }
3117 }
3118 filedata->dynamic_addr = dynamic_addr;
3119 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
3120}
3121
3122static bool
3123is_pie (Filedata *filedata)
3124{
3125 Elf_Internal_Dyn *entry;
3126
3127 if (filedata->dynamic_size == 0)
3128 locate_dynamic_section (filedata);
3129 if (filedata->dynamic_size <= 1)
3130 return false;
3131
3132 if (!get_dynamic_section (filedata))
3133 return false;
3134
3135 for (entry = filedata->dynamic_section;
3136 entry < filedata->dynamic_section + filedata->dynamic_nent;
3137 entry++)
3138 {
3139 if (entry->d_tag == DT_FLAGS_1)
3140 {
3141 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3142 return true;
3143 break;
3144 }
3145 }
3146 return false;
3147}
3148
252b5132 3149static char *
93df3340 3150get_file_type (Filedata *filedata)
252b5132 3151{
93df3340 3152 unsigned e_type = filedata->file_header.e_type;
89246a0e 3153 static char buff[64];
252b5132
RH
3154
3155 switch (e_type)
3156 {
32ec8896
NC
3157 case ET_NONE: return _("NONE (None)");
3158 case ET_REL: return _("REL (Relocatable file)");
3159 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
3160 case ET_DYN:
3161 if (is_pie (filedata))
3162 return _("DYN (Position-Independent Executable file)");
3163 else
3164 return _("DYN (Shared object file)");
32ec8896 3165 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
3166
3167 default:
3168 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 3169 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 3170 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 3171 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 3172 else
e9e44622 3173 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
3174 return buff;
3175 }
3176}
3177
3178static char *
d3ba0551 3179get_machine_name (unsigned e_machine)
252b5132 3180{
b34976b6 3181 static char buff[64]; /* XXX */
252b5132
RH
3182
3183 switch (e_machine)
3184 {
55e22ca8
NC
3185 /* Please keep this switch table sorted by increasing EM_ value. */
3186 /* 0 */
c45021f2
NC
3187 case EM_NONE: return _("None");
3188 case EM_M32: return "WE32100";
3189 case EM_SPARC: return "Sparc";
3190 case EM_386: return "Intel 80386";
3191 case EM_68K: return "MC68000";
3192 case EM_88K: return "MC88000";
22abe556 3193 case EM_IAMCU: return "Intel MCU";
fb70ec17 3194 case EM_860: return "Intel 80860";
c45021f2
NC
3195 case EM_MIPS: return "MIPS R3000";
3196 case EM_S370: return "IBM System/370";
55e22ca8 3197 /* 10 */
7036c0e1 3198 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 3199 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 3200 case EM_PARISC: return "HPPA";
55e22ca8 3201 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 3202 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 3203 case EM_960: return "Intel 80960";
c45021f2 3204 case EM_PPC: return "PowerPC";
55e22ca8 3205 /* 20 */
285d1771 3206 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
3207 case EM_S390_OLD:
3208 case EM_S390: return "IBM S/390";
3209 case EM_SPU: return "SPU";
3210 /* 30 */
3211 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
3212 case EM_FR20: return "Fujitsu FR20";
3213 case EM_RH32: return "TRW RH32";
b34976b6 3214 case EM_MCORE: return "MCORE";
55e22ca8 3215 /* 40 */
7036c0e1
AJ
3216 case EM_ARM: return "ARM";
3217 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 3218 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
3219 case EM_SPARCV9: return "Sparc v9";
3220 case EM_TRICORE: return "Siemens Tricore";
584da044 3221 case EM_ARC: return "ARC";
c2dcd04e
NC
3222 case EM_H8_300: return "Renesas H8/300";
3223 case EM_H8_300H: return "Renesas H8/300H";
3224 case EM_H8S: return "Renesas H8S";
3225 case EM_H8_500: return "Renesas H8/500";
55e22ca8 3226 /* 50 */
30800947 3227 case EM_IA_64: return "Intel IA-64";
252b5132
RH
3228 case EM_MIPS_X: return "Stanford MIPS-X";
3229 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 3230 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
3231 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3232 case EM_PCP: return "Siemens PCP";
3233 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 3234 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
3235 case EM_STARCORE: return "Motorola Star*Core processor";
3236 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 3237 /* 60 */
7036c0e1
AJ
3238 case EM_ST100: return "STMicroelectronics ST100 processor";
3239 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 3240 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
3241 case EM_PDSP: return "Sony DSP processor";
3242 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3243 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
3244 case EM_FX66: return "Siemens FX66 microcontroller";
3245 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3246 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3247 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 3248 /* 70 */
7036c0e1
AJ
3249 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3250 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3251 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3252 case EM_SVX: return "Silicon Graphics SVx";
3253 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3254 case EM_VAX: return "Digital VAX";
1b61cf92 3255 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
3256 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3257 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3258 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 3259 /* 80 */
b34976b6 3260 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 3261 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 3262 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
3263 case EM_AVR_OLD:
3264 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3265 case EM_CYGNUS_FR30:
3266 case EM_FR30: return "Fujitsu FR30";
3267 case EM_CYGNUS_D10V:
3268 case EM_D10V: return "d10v";
3269 case EM_CYGNUS_D30V:
3270 case EM_D30V: return "d30v";
3271 case EM_CYGNUS_V850:
3272 case EM_V850: return "Renesas V850";
3273 case EM_CYGNUS_M32R:
3274 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3275 case EM_CYGNUS_MN10300:
3276 case EM_MN10300: return "mn10300";
3277 /* 90 */
3278 case EM_CYGNUS_MN10200:
3279 case EM_MN10200: return "mn10200";
3280 case EM_PJ: return "picoJava";
73589c9d 3281 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 3282 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
3283 case EM_XTENSA_OLD:
3284 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
3285 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3286 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3287 case EM_NS32K: return "National Semiconductor 32000 series";
3288 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
3289 case EM_SNP1K: return "Trebia SNP 1000 processor";
3290 /* 100 */
9abca702 3291 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
3292 case EM_IP2K_OLD:
3293 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
3294 case EM_MAX: return "MAX Processor";
3295 case EM_CR: return "National Semiconductor CompactRISC";
3296 case EM_F2MC16: return "Fujitsu F2MC16";
3297 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 3298 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
3299 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3300 case EM_SEP: return "Sharp embedded microprocessor";
3301 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 3302 /* 110 */
11636f9e
JM
3303 case EM_UNICORE: return "Unicore";
3304 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3305 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 3306 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
3307 case EM_CRX: return "National Semiconductor CRX microprocessor";
3308 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 3309 case EM_C166:
d70c5fc7 3310 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
3311 case EM_M16C: return "Renesas M16C series microprocessors";
3312 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3313 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
3314 /* 120 */
3315 case EM_M32C: return "Renesas M32c";
3316 /* 130 */
11636f9e
JM
3317 case EM_TSK3000: return "Altium TSK3000 core";
3318 case EM_RS08: return "Freescale RS08 embedded processor";
3319 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 3320 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
3321 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3322 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 3323 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 3324 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 3325 /* 140 */
11636f9e
JM
3326 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3327 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3328 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
3329 case EM_TI_PRU: return "TI PRU I/O processor";
3330 /* 160 */
11636f9e
JM
3331 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3332 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3333 case EM_R32C: return "Renesas R32C series microprocessors";
3334 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3335 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3336 case EM_8051: return "Intel 8051 and variants";
3337 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3338 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3339 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3340 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 3341 /* 170 */
11636f9e
JM
3342 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3343 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3344 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3345 case EM_RX: return "Renesas RX";
a3c62988 3346 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3347 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3348 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3349 case EM_CR16:
3350 case EM_MICROBLAZE:
3351 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3352 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3353 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3354 /* 180 */
3355 case EM_L1OM: return "Intel L1OM";
3356 case EM_K1OM: return "Intel K1OM";
3357 case EM_INTEL182: return "Intel (reserved)";
3358 case EM_AARCH64: return "AArch64";
3359 case EM_ARM184: return "ARM (reserved)";
3360 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3361 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3362 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3363 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3364 /* 190 */
11636f9e 3365 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3366 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3367 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3368 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3369 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3370 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3371 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3372 case EM_RL78: return "Renesas RL78";
6d913794 3373 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3374 case EM_78K0R: return "Renesas 78K0R";
3375 /* 200 */
6d913794 3376 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3377 case EM_BA1: return "Beyond BA1 CPU architecture";
3378 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3379 case EM_XCORE: return "XMOS xCORE processor family";
3380 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3381 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3382 /* 210 */
6d913794
NC
3383 case EM_KM32: return "KM211 KM32 32-bit processor";
3384 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3385 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3386 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3387 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3388 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3389 case EM_COGE: return "Cognitive Smart Memory Processor";
3390 case EM_COOL: return "Bluechip Systems CoolEngine";
3391 case EM_NORC: return "Nanoradio Optimized RISC";
3392 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3393 /* 220 */
15f205b1 3394 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3395 case EM_VISIUM: return "CDS VISIUMcore processor";
3396 case EM_FT32: return "FTDI Chip FT32";
3397 case EM_MOXIE: return "Moxie";
3398 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3399 /* 230 (all reserved) */
3400 /* 240 */
55e22ca8
NC
3401 case EM_RISCV: return "RISC-V";
3402 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3403 case EM_CEVA: return "CEVA Processor Architecture Family";
3404 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3405 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3406 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3407 case EM_IMG1: return "Imagination Technologies";
3408 /* 250 */
fe944acf 3409 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3410 case EM_VE: return "NEC Vector Engine";
3411 case EM_CSKY: return "C-SKY";
b5c37946 3412 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3413 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3414 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3415 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3416 case EM_65816: return "WDC 65816/65C816";
01a8c731 3417 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3418 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3419
3420 /* Large numbers... */
3421 case EM_MT: return "Morpho Techologies MT processor";
3422 case EM_ALPHA: return "Alpha";
3423 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3424 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3425 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3426 case EM_IQ2000: return "Vitesse IQ2000";
3427 case EM_M32C_OLD:
3428 case EM_NIOS32: return "Altera Nios";
3429 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3430 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3431 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3432 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3433
252b5132 3434 default:
35d9dd2f 3435 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3436 return buff;
3437 }
3438}
3439
f8c4789c
AM
3440static char *
3441decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3442{
3443 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3444 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3445 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3446 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3447 architectures.
3448
3449 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3450 but also sets a specific architecture type in the e_flags field.
3451
3452 However, when decoding the flags we don't worry if we see an
3453 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3454 ARCEM architecture type. */
3455
3456 switch (e_flags & EF_ARC_MACH_MSK)
3457 {
3458 /* We only expect these to occur for EM_ARC_COMPACT2. */
3459 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3460 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3461 break;
3462 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3463 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3464 break;
3465
3466 /* We only expect these to occur for EM_ARC_COMPACT. */
3467 case E_ARC_MACH_ARC600:
f8c4789c 3468 out = stpcpy (out, ", ARC600");
a9522a21
AB
3469 break;
3470 case E_ARC_MACH_ARC601:
f8c4789c 3471 out = stpcpy (out, ", ARC601");
a9522a21
AB
3472 break;
3473 case E_ARC_MACH_ARC700:
f8c4789c 3474 out = stpcpy (out, ", ARC700");
a9522a21
AB
3475 break;
3476
3477 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3478 new ELF with new architecture being read by an old version of
3479 readelf, or (c) An ELF built with non-GNU compiler that does not
3480 set the architecture in the e_flags. */
3481 default:
3482 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3483 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3484 else
f8c4789c 3485 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3486 break;
3487 }
3488
3489 switch (e_flags & EF_ARC_OSABI_MSK)
3490 {
3491 case E_ARC_OSABI_ORIG:
f8c4789c 3492 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3493 break;
3494 case E_ARC_OSABI_V2:
f8c4789c 3495 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3496 break;
3497 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3498 case E_ARC_OSABI_V3:
f8c4789c 3499 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3500 break;
53a346d8 3501 case E_ARC_OSABI_V4:
f8c4789c 3502 out = stpcpy (out, ", v4 ABI");
53a346d8 3503 break;
a9522a21 3504 default:
f8c4789c 3505 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3506 break;
3507 }
f8c4789c 3508 return out;
a9522a21
AB
3509}
3510
f8c4789c
AM
3511static char *
3512decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3513{
3514 unsigned eabi;
015dc7e1 3515 bool unknown = false;
f3485b74
NC
3516
3517 eabi = EF_ARM_EABI_VERSION (e_flags);
3518 e_flags &= ~ EF_ARM_EABIMASK;
3519
3520 /* Handle "generic" ARM flags. */
3521 if (e_flags & EF_ARM_RELEXEC)
3522 {
f8c4789c 3523 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3524 e_flags &= ~ EF_ARM_RELEXEC;
3525 }
76da6bbe 3526
18a20338
CL
3527 if (e_flags & EF_ARM_PIC)
3528 {
f8c4789c 3529 out = stpcpy (out, ", position independent");
18a20338
CL
3530 e_flags &= ~ EF_ARM_PIC;
3531 }
3532
f3485b74
NC
3533 /* Now handle EABI specific flags. */
3534 switch (eabi)
3535 {
3536 default:
f8c4789c 3537 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3538 if (e_flags)
015dc7e1 3539 unknown = true;
f3485b74
NC
3540 break;
3541
3542 case EF_ARM_EABI_VER1:
f8c4789c 3543 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3544 while (e_flags)
3545 {
3546 unsigned flag;
76da6bbe 3547
f3485b74
NC
3548 /* Process flags one bit at a time. */
3549 flag = e_flags & - e_flags;
3550 e_flags &= ~ flag;
76da6bbe 3551
f3485b74
NC
3552 switch (flag)
3553 {
a5bcd848 3554 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3555 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3556 break;
76da6bbe 3557
f3485b74 3558 default:
015dc7e1 3559 unknown = true;
f3485b74
NC
3560 break;
3561 }
3562 }
3563 break;
76da6bbe 3564
a5bcd848 3565 case EF_ARM_EABI_VER2:
f8c4789c 3566 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3567 while (e_flags)
3568 {
3569 unsigned flag;
3570
3571 /* Process flags one bit at a time. */
3572 flag = e_flags & - e_flags;
3573 e_flags &= ~ flag;
3574
3575 switch (flag)
3576 {
3577 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3578 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3579 break;
3580
3581 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3582 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3583 break;
3584
3585 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3586 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3587 break;
3588
3589 default:
015dc7e1 3590 unknown = true;
a5bcd848
PB
3591 break;
3592 }
3593 }
3594 break;
3595
d507cf36 3596 case EF_ARM_EABI_VER3:
f8c4789c 3597 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3598 break;
3599
3600 case EF_ARM_EABI_VER4:
f8c4789c 3601 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3602 while (e_flags)
3603 {
3604 unsigned flag;
3605
3606 /* Process flags one bit at a time. */
3607 flag = e_flags & - e_flags;
3608 e_flags &= ~ flag;
3609
3610 switch (flag)
3611 {
3612 case EF_ARM_BE8:
f8c4789c 3613 out = stpcpy (out, ", BE8");
3bfcb652
NC
3614 break;
3615
3616 case EF_ARM_LE8:
f8c4789c 3617 out = stpcpy (out, ", LE8");
3bfcb652
NC
3618 break;
3619
3620 default:
015dc7e1 3621 unknown = true;
3bfcb652
NC
3622 break;
3623 }
3bfcb652
NC
3624 }
3625 break;
3a4a14e9
PB
3626
3627 case EF_ARM_EABI_VER5:
f8c4789c 3628 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3629 while (e_flags)
3630 {
3631 unsigned flag;
3632
3633 /* Process flags one bit at a time. */
3634 flag = e_flags & - e_flags;
3635 e_flags &= ~ flag;
3636
3637 switch (flag)
3638 {
3639 case EF_ARM_BE8:
f8c4789c 3640 out = stpcpy (out, ", BE8");
d507cf36
PB
3641 break;
3642
3643 case EF_ARM_LE8:
f8c4789c 3644 out = stpcpy (out, ", LE8");
d507cf36
PB
3645 break;
3646
3bfcb652 3647 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3648 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3649 break;
3650
3651 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3652 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3653 break;
3654
d507cf36 3655 default:
015dc7e1 3656 unknown = true;
d507cf36
PB
3657 break;
3658 }
3659 }
3660 break;
3661
f3485b74 3662 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3663 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3664 while (e_flags)
3665 {
3666 unsigned flag;
76da6bbe 3667
f3485b74
NC
3668 /* Process flags one bit at a time. */
3669 flag = e_flags & - e_flags;
3670 e_flags &= ~ flag;
76da6bbe 3671
f3485b74
NC
3672 switch (flag)
3673 {
a5bcd848 3674 case EF_ARM_INTERWORK:
f8c4789c 3675 out = stpcpy (out, ", interworking enabled");
f3485b74 3676 break;
76da6bbe 3677
a5bcd848 3678 case EF_ARM_APCS_26:
f8c4789c 3679 out = stpcpy (out, ", uses APCS/26");
f3485b74 3680 break;
76da6bbe 3681
a5bcd848 3682 case EF_ARM_APCS_FLOAT:
f8c4789c 3683 out = stpcpy (out, ", uses APCS/float");
f3485b74 3684 break;
76da6bbe 3685
a5bcd848 3686 case EF_ARM_PIC:
f8c4789c 3687 out = stpcpy (out, ", position independent");
f3485b74 3688 break;
76da6bbe 3689
a5bcd848 3690 case EF_ARM_ALIGN8:
f8c4789c 3691 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3692 break;
76da6bbe 3693
a5bcd848 3694 case EF_ARM_NEW_ABI:
f8c4789c 3695 out = stpcpy (out, ", uses new ABI");
f3485b74 3696 break;
76da6bbe 3697
a5bcd848 3698 case EF_ARM_OLD_ABI:
f8c4789c 3699 out = stpcpy (out, ", uses old ABI");
f3485b74 3700 break;
76da6bbe 3701
a5bcd848 3702 case EF_ARM_SOFT_FLOAT:
f8c4789c 3703 out = stpcpy (out, ", software FP");
f3485b74 3704 break;
76da6bbe 3705
90e01f86 3706 case EF_ARM_VFP_FLOAT:
f8c4789c 3707 out = stpcpy (out, ", VFP");
90e01f86
ILT
3708 break;
3709
f3485b74 3710 default:
015dc7e1 3711 unknown = true;
f3485b74
NC
3712 break;
3713 }
3714 }
3715 }
f3485b74
NC
3716
3717 if (unknown)
f8c4789c
AM
3718 out = stpcpy (out,_(", <unknown>"));
3719 return out;
f3485b74
NC
3720}
3721
f8c4789c
AM
3722static char *
3723decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3724{
343433df
AB
3725 switch (e_flags & EF_AVR_MACH)
3726 {
3727 case E_AVR_MACH_AVR1:
f8c4789c 3728 out = stpcpy (out, ", avr:1");
343433df
AB
3729 break;
3730 case E_AVR_MACH_AVR2:
f8c4789c 3731 out = stpcpy (out, ", avr:2");
343433df
AB
3732 break;
3733 case E_AVR_MACH_AVR25:
f8c4789c 3734 out = stpcpy (out, ", avr:25");
343433df
AB
3735 break;
3736 case E_AVR_MACH_AVR3:
f8c4789c 3737 out = stpcpy (out, ", avr:3");
343433df
AB
3738 break;
3739 case E_AVR_MACH_AVR31:
f8c4789c 3740 out = stpcpy (out, ", avr:31");
343433df
AB
3741 break;
3742 case E_AVR_MACH_AVR35:
f8c4789c 3743 out = stpcpy (out, ", avr:35");
343433df
AB
3744 break;
3745 case E_AVR_MACH_AVR4:
f8c4789c 3746 out = stpcpy (out, ", avr:4");
343433df
AB
3747 break;
3748 case E_AVR_MACH_AVR5:
f8c4789c 3749 out = stpcpy (out, ", avr:5");
343433df
AB
3750 break;
3751 case E_AVR_MACH_AVR51:
f8c4789c 3752 out = stpcpy (out, ", avr:51");
343433df
AB
3753 break;
3754 case E_AVR_MACH_AVR6:
f8c4789c 3755 out = stpcpy (out, ", avr:6");
343433df
AB
3756 break;
3757 case E_AVR_MACH_AVRTINY:
f8c4789c 3758 out = stpcpy (out, ", avr:100");
343433df
AB
3759 break;
3760 case E_AVR_MACH_XMEGA1:
f8c4789c 3761 out = stpcpy (out, ", avr:101");
343433df
AB
3762 break;
3763 case E_AVR_MACH_XMEGA2:
f8c4789c 3764 out = stpcpy (out, ", avr:102");
343433df
AB
3765 break;
3766 case E_AVR_MACH_XMEGA3:
f8c4789c 3767 out = stpcpy (out, ", avr:103");
343433df
AB
3768 break;
3769 case E_AVR_MACH_XMEGA4:
f8c4789c 3770 out = stpcpy (out, ", avr:104");
343433df
AB
3771 break;
3772 case E_AVR_MACH_XMEGA5:
f8c4789c 3773 out = stpcpy (out, ", avr:105");
343433df
AB
3774 break;
3775 case E_AVR_MACH_XMEGA6:
f8c4789c 3776 out = stpcpy (out, ", avr:106");
343433df
AB
3777 break;
3778 case E_AVR_MACH_XMEGA7:
f8c4789c 3779 out = stpcpy (out, ", avr:107");
343433df
AB
3780 break;
3781 default:
f8c4789c 3782 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3783 break;
3784 }
3785
343433df 3786 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3787 out = stpcpy (out, ", link-relax");
3788 return out;
343433df
AB
3789}
3790
f8c4789c
AM
3791static char *
3792decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3793{
3794 if (e_flags & EF_BFIN_PIC)
3795 out = stpcpy (out, ", PIC");
3796
3797 if (e_flags & EF_BFIN_FDPIC)
3798 out = stpcpy (out, ", FDPIC");
3799
3800 if (e_flags & EF_BFIN_CODE_IN_L1)
3801 out = stpcpy (out, ", code in L1");
3802
3803 if (e_flags & EF_BFIN_DATA_IN_L1)
3804 out = stpcpy (out, ", data in L1");
3805 return out;
3806}
3807
3808static char *
3809decode_FRV_machine_flags (char *out, unsigned e_flags)
3810{
3811 switch (e_flags & EF_FRV_CPU_MASK)
3812 {
3813 case EF_FRV_CPU_GENERIC:
3814 break;
3815
3816 default:
3817 out = stpcpy (out, ", fr???");
3818 break;
3819
3820 case EF_FRV_CPU_FR300:
3821 out = stpcpy (out, ", fr300");
3822 break;
3823
3824 case EF_FRV_CPU_FR400:
3825 out = stpcpy (out, ", fr400");
3826 break;
3827 case EF_FRV_CPU_FR405:
3828 out = stpcpy (out, ", fr405");
3829 break;
3830
3831 case EF_FRV_CPU_FR450:
3832 out = stpcpy (out, ", fr450");
3833 break;
3834
3835 case EF_FRV_CPU_FR500:
3836 out = stpcpy (out, ", fr500");
3837 break;
3838 case EF_FRV_CPU_FR550:
3839 out = stpcpy (out, ", fr550");
3840 break;
3841
3842 case EF_FRV_CPU_SIMPLE:
3843 out = stpcpy (out, ", simple");
3844 break;
3845 case EF_FRV_CPU_TOMCAT:
3846 out = stpcpy (out, ", tomcat");
3847 break;
3848 }
3849 return out;
3850}
3851
3852static char *
3853decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3854{
3855 if ((e_flags & EF_IA_64_ABI64))
3856 out = stpcpy (out, ", 64-bit");
3857 else
3858 out = stpcpy (out, ", 32-bit");
3859 if ((e_flags & EF_IA_64_REDUCEDFP))
3860 out = stpcpy (out, ", reduced fp model");
3861 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3862 out = stpcpy (out, ", no function descriptors, constant gp");
3863 else if ((e_flags & EF_IA_64_CONS_GP))
3864 out = stpcpy (out, ", constant gp");
3865 if ((e_flags & EF_IA_64_ABSOLUTE))
3866 out = stpcpy (out, ", absolute");
3867 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3868 {
3869 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3870 out = stpcpy (out, ", vms_linkages");
3871 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3872 {
3873 case EF_IA_64_VMS_COMCOD_SUCCESS:
3874 break;
3875 case EF_IA_64_VMS_COMCOD_WARNING:
3876 out = stpcpy (out, ", warning");
3877 break;
3878 case EF_IA_64_VMS_COMCOD_ERROR:
3879 out = stpcpy (out, ", error");
3880 break;
3881 case EF_IA_64_VMS_COMCOD_ABORT:
3882 out = stpcpy (out, ", abort");
3883 break;
3884 default:
3885 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3886 e_flags & EF_IA_64_VMS_COMCOD);
3887 out = stpcpy (out, ", <unknown>");
3888 }
3889 }
3890 return out;
3891}
3892
3893static char *
3894decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3895{
3896 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3897 out = stpcpy (out, ", SOFT-FLOAT");
3898 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3899 out = stpcpy (out, ", SINGLE-FLOAT");
3900 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3901 out = stpcpy (out, ", DOUBLE-FLOAT");
3902
3903 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3904 out = stpcpy (out, ", OBJ-v0");
3905 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3906 out = stpcpy (out, ", OBJ-v1");
3907 return out;
3908}
3909
3910static char *
3911decode_M68K_machine_flags (char *out, unsigned int e_flags)
3912{
3913 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3914 out = stpcpy (out, ", m68000");
3915 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3916 out = stpcpy (out, ", cpu32");
3917 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3918 out = stpcpy (out, ", fido_a");
3919 else
3920 {
3921 char const *isa = _("unknown");
3922 char const *mac = _("unknown mac");
3923 char const *additional = NULL;
3924
3925 switch (e_flags & EF_M68K_CF_ISA_MASK)
3926 {
3927 case EF_M68K_CF_ISA_A_NODIV:
3928 isa = "A";
3929 additional = ", nodiv";
3930 break;
3931 case EF_M68K_CF_ISA_A:
3932 isa = "A";
3933 break;
3934 case EF_M68K_CF_ISA_A_PLUS:
3935 isa = "A+";
3936 break;
3937 case EF_M68K_CF_ISA_B_NOUSP:
3938 isa = "B";
3939 additional = ", nousp";
3940 break;
3941 case EF_M68K_CF_ISA_B:
3942 isa = "B";
3943 break;
3944 case EF_M68K_CF_ISA_C:
3945 isa = "C";
3946 break;
3947 case EF_M68K_CF_ISA_C_NODIV:
3948 isa = "C";
3949 additional = ", nodiv";
3950 break;
3951 }
3952 out = stpcpy (out, ", cf, isa ");
3953 out = stpcpy (out, isa);
3954 if (additional)
3955 out = stpcpy (out, additional);
3956 if (e_flags & EF_M68K_CF_FLOAT)
3957 out = stpcpy (out, ", float");
3958 switch (e_flags & EF_M68K_CF_MAC_MASK)
3959 {
3960 case 0:
3961 mac = NULL;
3962 break;
3963 case EF_M68K_CF_MAC:
3964 mac = "mac";
3965 break;
3966 case EF_M68K_CF_EMAC:
3967 mac = "emac";
3968 break;
3969 case EF_M68K_CF_EMAC_B:
3970 mac = "emac_b";
3971 break;
3972 }
3973 if (mac)
3974 {
3975 out = stpcpy (out, ", ");
3976 out = stpcpy (out, mac);
3977 }
3978 }
3979 return out;
3980}
3981
3982static char *
3983decode_MeP_machine_flags (char *out, unsigned int e_flags)
3984{
3985 switch (e_flags & EF_MEP_CPU_MASK)
3986 {
3987 case EF_MEP_CPU_MEP:
3988 out = stpcpy (out, ", generic MeP");
3989 break;
3990 case EF_MEP_CPU_C2:
3991 out = stpcpy (out, ", MeP C2");
3992 break;
3993 case EF_MEP_CPU_C3:
3994 out = stpcpy (out, ", MeP C3");
3995 break;
3996 case EF_MEP_CPU_C4:
3997 out = stpcpy (out, ", MeP C4");
3998 break;
3999 case EF_MEP_CPU_C5:
4000 out = stpcpy (out, ", MeP C5");
4001 break;
4002 case EF_MEP_CPU_H1:
4003 out = stpcpy (out, ", MeP H1");
4004 break;
4005 default:
4006 out = stpcpy (out, _(", <unknown MeP cpu type>"));
4007 break;
4008 }
4009
4010 switch (e_flags & EF_MEP_COP_MASK)
4011 {
4012 case EF_MEP_COP_NONE:
4013 break;
4014 case EF_MEP_COP_AVC:
4015 out = stpcpy (out, ", AVC coprocessor");
4016 break;
4017 case EF_MEP_COP_AVC2:
4018 out = stpcpy (out, ", AVC2 coprocessor");
4019 break;
4020 case EF_MEP_COP_FMAX:
4021 out = stpcpy (out, ", FMAX coprocessor");
4022 break;
4023 case EF_MEP_COP_IVC2:
4024 out = stpcpy (out, ", IVC2 coprocessor");
4025 break;
4026 default:
4027 out = stpcpy (out, _("<unknown MeP copro type>"));
4028 break;
4029 }
4030
4031 if (e_flags & EF_MEP_LIBRARY)
4032 out = stpcpy (out, ", Built for Library");
4033
4034 if (e_flags & EF_MEP_INDEX_MASK)
4035 out += sprintf (out, ", Configuration Index: %#x",
4036 e_flags & EF_MEP_INDEX_MASK);
4037
4038 if (e_flags & ~ EF_MEP_ALL_FLAGS)
4039 out += sprintf (out, _(", unknown flags bits: %#x"),
4040 e_flags & ~ EF_MEP_ALL_FLAGS);
4041 return out;
4042}
4043
4044static char *
4045decode_MIPS_machine_flags (char *out, unsigned int e_flags)
4046{
4047 if (e_flags & EF_MIPS_NOREORDER)
4048 out = stpcpy (out, ", noreorder");
4049
4050 if (e_flags & EF_MIPS_PIC)
4051 out = stpcpy (out, ", pic");
4052
4053 if (e_flags & EF_MIPS_CPIC)
4054 out = stpcpy (out, ", cpic");
4055
4056 if (e_flags & EF_MIPS_UCODE)
4057 out = stpcpy (out, ", ugen_reserved");
4058
4059 if (e_flags & EF_MIPS_ABI2)
4060 out = stpcpy (out, ", abi2");
4061
4062 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4063 out = stpcpy (out, ", odk first");
4064
4065 if (e_flags & EF_MIPS_32BITMODE)
4066 out = stpcpy (out, ", 32bitmode");
4067
4068 if (e_flags & EF_MIPS_NAN2008)
4069 out = stpcpy (out, ", nan2008");
4070
4071 if (e_flags & EF_MIPS_FP64)
4072 out = stpcpy (out, ", fp64");
4073
4074 switch ((e_flags & EF_MIPS_MACH))
4075 {
d173146d 4076 case EF_MIPS_MACH_3900:
f8c4789c
AM
4077 out = stpcpy (out, ", 3900");
4078 break;
d173146d 4079 case EF_MIPS_MACH_4010:
f8c4789c
AM
4080 out = stpcpy (out, ", 4010");
4081 break;
d173146d 4082 case EF_MIPS_MACH_4100:
f8c4789c
AM
4083 out = stpcpy (out, ", 4100");
4084 break;
d173146d 4085 case EF_MIPS_MACH_4111:
f8c4789c
AM
4086 out = stpcpy (out, ", 4111");
4087 break;
d173146d 4088 case EF_MIPS_MACH_4120:
f8c4789c
AM
4089 out = stpcpy (out, ", 4120");
4090 break;
d173146d 4091 case EF_MIPS_MACH_4650:
f8c4789c
AM
4092 out = stpcpy (out, ", 4650");
4093 break;
d173146d 4094 case EF_MIPS_MACH_5400:
f8c4789c
AM
4095 out = stpcpy (out, ", 5400");
4096 break;
d173146d 4097 case EF_MIPS_MACH_5500:
f8c4789c
AM
4098 out = stpcpy (out, ", 5500");
4099 break;
d173146d 4100 case EF_MIPS_MACH_5900:
f8c4789c
AM
4101 out = stpcpy (out, ", 5900");
4102 break;
d173146d 4103 case EF_MIPS_MACH_SB1:
f8c4789c
AM
4104 out = stpcpy (out, ", sb1");
4105 break;
d173146d 4106 case EF_MIPS_MACH_9000:
f8c4789c
AM
4107 out = stpcpy (out, ", 9000");
4108 break;
d173146d 4109 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
4110 out = stpcpy (out, ", loongson-2e");
4111 break;
d173146d 4112 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
4113 out = stpcpy (out, ", loongson-2f");
4114 break;
d173146d 4115 case EF_MIPS_MACH_GS464:
f8c4789c
AM
4116 out = stpcpy (out, ", gs464");
4117 break;
d173146d 4118 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
4119 out = stpcpy (out, ", gs464e");
4120 break;
d173146d 4121 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
4122 out = stpcpy (out, ", gs264e");
4123 break;
d173146d 4124 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
4125 out = stpcpy (out, ", octeon");
4126 break;
d173146d 4127 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
4128 out = stpcpy (out, ", octeon2");
4129 break;
d173146d 4130 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
4131 out = stpcpy (out, ", octeon3");
4132 break;
d173146d 4133 case EF_MIPS_MACH_XLR:
f8c4789c
AM
4134 out = stpcpy (out, ", xlr");
4135 break;
d173146d 4136 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
4137 out = stpcpy (out, ", interaptiv-mr2");
4138 break;
d173146d 4139 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
4140 out = stpcpy (out, ", allegrex");
4141 break;
4142 case 0:
4143 /* We simply ignore the field in this case to avoid confusion:
4144 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4145 extension. */
4146 break;
4147 default:
4148 out = stpcpy (out, _(", unknown CPU"));
4149 break;
4150 }
4151
4152 switch ((e_flags & EF_MIPS_ABI))
4153 {
d173146d 4154 case EF_MIPS_ABI_O32:
f8c4789c
AM
4155 out = stpcpy (out, ", o32");
4156 break;
d173146d 4157 case EF_MIPS_ABI_O64:
f8c4789c
AM
4158 out = stpcpy (out, ", o64");
4159 break;
d173146d 4160 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
4161 out = stpcpy (out, ", eabi32");
4162 break;
d173146d 4163 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
4164 out = stpcpy (out, ", eabi64");
4165 break;
4166 case 0:
4167 /* We simply ignore the field in this case to avoid confusion:
4168 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4169 This means it is likely to be an o32 file, but not for
4170 sure. */
4171 break;
4172 default:
4173 out = stpcpy (out, _(", unknown ABI"));
4174 break;
4175 }
4176
4177 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4178 out = stpcpy (out, ", mdmx");
4179
4180 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4181 out = stpcpy (out, ", mips16");
4182
4183 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4184 out = stpcpy (out, ", micromips");
4185
4186 switch ((e_flags & EF_MIPS_ARCH))
4187 {
d173146d 4188 case EF_MIPS_ARCH_1:
f8c4789c
AM
4189 out = stpcpy (out, ", mips1");
4190 break;
d173146d 4191 case EF_MIPS_ARCH_2:
f8c4789c
AM
4192 out = stpcpy (out, ", mips2");
4193 break;
d173146d 4194 case EF_MIPS_ARCH_3:
f8c4789c
AM
4195 out = stpcpy (out, ", mips3");
4196 break;
d173146d 4197 case EF_MIPS_ARCH_4:
f8c4789c
AM
4198 out = stpcpy (out, ", mips4");
4199 break;
d173146d 4200 case EF_MIPS_ARCH_5:
f8c4789c
AM
4201 out = stpcpy (out, ", mips5");
4202 break;
d173146d 4203 case EF_MIPS_ARCH_32:
f8c4789c
AM
4204 out = stpcpy (out, ", mips32");
4205 break;
d173146d 4206 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
4207 out = stpcpy (out, ", mips32r2");
4208 break;
d173146d 4209 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
4210 out = stpcpy (out, ", mips32r6");
4211 break;
d173146d 4212 case EF_MIPS_ARCH_64:
f8c4789c
AM
4213 out = stpcpy (out, ", mips64");
4214 break;
d173146d 4215 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
4216 out = stpcpy (out, ", mips64r2");
4217 break;
d173146d 4218 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
4219 out = stpcpy (out, ", mips64r6");
4220 break;
4221 default:
4222 out = stpcpy (out, _(", unknown ISA"));
4223 break;
4224 }
4225 return out;
4226}
4227
4228static char *
4229decode_MSP430_machine_flags (char *out, unsigned e_flags)
4230{
4231 out = stpcpy (out, _(": architecture variant: "));
4232 switch (e_flags & EF_MSP430_MACH)
4233 {
4234 case E_MSP430_MACH_MSP430x11:
4235 out = stpcpy (out, "MSP430x11");
4236 break;
4237 case E_MSP430_MACH_MSP430x11x1:
4238 out = stpcpy (out, "MSP430x11x1 ");
4239 break;
4240 case E_MSP430_MACH_MSP430x12:
4241 out = stpcpy (out, "MSP430x12");
4242 break;
4243 case E_MSP430_MACH_MSP430x13:
4244 out = stpcpy (out, "MSP430x13");
4245 break;
4246 case E_MSP430_MACH_MSP430x14:
4247 out = stpcpy (out, "MSP430x14");
4248 break;
4249 case E_MSP430_MACH_MSP430x15:
4250 out = stpcpy (out, "MSP430x15");
4251 break;
4252 case E_MSP430_MACH_MSP430x16:
4253 out = stpcpy (out, "MSP430x16");
4254 break;
4255 case E_MSP430_MACH_MSP430x31:
4256 out = stpcpy (out, "MSP430x31");
4257 break;
4258 case E_MSP430_MACH_MSP430x32:
4259 out = stpcpy (out, "MSP430x32");
4260 break;
4261 case E_MSP430_MACH_MSP430x33:
4262 out = stpcpy (out, "MSP430x33");
4263 break;
4264 case E_MSP430_MACH_MSP430x41:
4265 out = stpcpy (out, "MSP430x41");
4266 break;
4267 case E_MSP430_MACH_MSP430x42:
4268 out = stpcpy (out, "MSP430x42");
4269 break;
4270 case E_MSP430_MACH_MSP430x43:
4271 out = stpcpy (out, "MSP430x43");
4272 break;
4273 case E_MSP430_MACH_MSP430x44:
4274 out = stpcpy (out, "MSP430x44");
4275 break;
4276 case E_MSP430_MACH_MSP430X :
4277 out = stpcpy (out, "MSP430X");
4278 break;
4279 default:
4280 out = stpcpy (out, _(": unknown"));
4281 break;
4282 }
4283
4284 if (e_flags & ~ EF_MSP430_MACH)
4285 out = stpcpy (out, _(": unknown extra flag bits also present"));
4286 return out;
4287}
4288
4289static char *
4290decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
4291{
4292 unsigned abi;
4293 unsigned arch;
4294 unsigned config;
4295 unsigned version;
015dc7e1 4296 bool has_fpu = false;
35c08157
KLC
4297
4298 static const char *ABI_STRINGS[] =
4299 {
4300 "ABI v0", /* use r5 as return register; only used in N1213HC */
4301 "ABI v1", /* use r0 as return register */
4302 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4303 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
4304 "AABI",
4305 "ABI2 FP+"
35c08157
KLC
4306 };
4307 static const char *VER_STRINGS[] =
4308 {
4309 "Andes ELF V1.3 or older",
4310 "Andes ELF V1.3.1",
4311 "Andes ELF V1.4"
4312 };
4313 static const char *ARCH_STRINGS[] =
4314 {
4315 "",
4316 "Andes Star v1.0",
4317 "Andes Star v2.0",
4318 "Andes Star v3.0",
4319 "Andes Star v3.0m"
4320 };
4321
4322 abi = EF_NDS_ABI & e_flags;
4323 arch = EF_NDS_ARCH & e_flags;
4324 config = EF_NDS_INST & e_flags;
4325 version = EF_NDS32_ELF_VERSION & e_flags;
4326
35c08157
KLC
4327 switch (abi)
4328 {
4329 case E_NDS_ABI_V0:
4330 case E_NDS_ABI_V1:
4331 case E_NDS_ABI_V2:
4332 case E_NDS_ABI_V2FP:
4333 case E_NDS_ABI_AABI:
40c7a7cb 4334 case E_NDS_ABI_V2FP_PLUS:
35c08157 4335 /* In case there are holes in the array. */
f8c4789c 4336 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
4337 break;
4338
4339 default:
f8c4789c 4340 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4341 break;
4342 }
4343
4344 switch (version)
4345 {
4346 case E_NDS32_ELF_VER_1_2:
4347 case E_NDS32_ELF_VER_1_3:
4348 case E_NDS32_ELF_VER_1_4:
f8c4789c 4349 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4350 break;
4351
4352 default:
f8c4789c 4353 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4354 break;
4355 }
4356
4357 if (E_NDS_ABI_V0 == abi)
4358 {
4359 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4360 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4361 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4362 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4363 return out;
35c08157
KLC
4364 }
4365
4366 switch (arch)
4367 {
4368 case E_NDS_ARCH_STAR_V1_0:
4369 case E_NDS_ARCH_STAR_V2_0:
4370 case E_NDS_ARCH_STAR_V3_0:
4371 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4372 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4373 break;
4374
4375 default:
f8c4789c 4376 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4377 /* ARCH version determines how the e_flags are interpreted.
4378 If it is unknown, we cannot proceed. */
f8c4789c 4379 return out;
35c08157
KLC
4380 }
4381
4382 /* Newer ABI; Now handle architecture specific flags. */
4383 if (arch == E_NDS_ARCH_STAR_V1_0)
4384 {
4385 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4386 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4387
4388 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4389 out = stpcpy (out, ", MAC");
35c08157
KLC
4390
4391 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4392 out = stpcpy (out, ", DIV");
35c08157
KLC
4393
4394 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4395 out = stpcpy (out, ", 16b");
35c08157
KLC
4396 }
4397 else
4398 {
4399 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4400 {
4401 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4402 out = stpcpy (out, ", [B8]");
35c08157 4403 else
f8c4789c 4404 out = stpcpy (out, ", EX9");
35c08157
KLC
4405 }
4406
4407 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4408 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4409
4410 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4411 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4412
4413 if (config & E_NDS32_HAS_16BIT_INST)
4414 {
4415 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4416 out = stpcpy (out, ", 16b");
35c08157 4417 else
f8c4789c 4418 out = stpcpy (out, ", IFC");
35c08157
KLC
4419 }
4420 }
4421
4422 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4423 out = stpcpy (out, ", PERF1");
35c08157
KLC
4424
4425 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4426 out = stpcpy (out, ", PERF2");
35c08157
KLC
4427
4428 if (config & E_NDS32_HAS_FPU_INST)
4429 {
015dc7e1 4430 has_fpu = true;
f8c4789c 4431 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4432 }
4433
4434 if (config & E_NDS32_HAS_FPU_DP_INST)
4435 {
015dc7e1 4436 has_fpu = true;
f8c4789c 4437 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4438 }
4439
4440 if (config & E_NDS32_HAS_FPU_MAC_INST)
4441 {
015dc7e1 4442 has_fpu = true;
f8c4789c 4443 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4444 }
4445
4446 if (has_fpu)
4447 {
4448 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4449 {
4450 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4451 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4452 break;
4453 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4454 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4455 break;
4456 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4457 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4458 break;
4459 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4460 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4461 break;
4462 }
4463 }
4464
4465 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4466 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4467
4468 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4469 out = stpcpy (out, ", STR");
35c08157
KLC
4470
4471 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4472 out = stpcpy (out, ", 16REG");
35c08157
KLC
4473
4474 if (config & E_NDS32_HAS_VIDEO_INST)
4475 {
4476 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4477 out = stpcpy (out, ", VIDEO");
35c08157 4478 else
f8c4789c 4479 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4480 }
4481
4482 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4483 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4484
4485 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4486 out = stpcpy (out, ", L2C");
4487
4488 return out;
35c08157
KLC
4489}
4490
f8c4789c
AM
4491static char *
4492decode_PARISC_machine_flags (char *out, unsigned e_flags)
4493{
4494 switch (e_flags & EF_PARISC_ARCH)
4495 {
4496 case EFA_PARISC_1_0:
4497 out = stpcpy (out, ", PA-RISC 1.0");
4498 break;
4499 case EFA_PARISC_1_1:
4500 out = stpcpy (out, ", PA-RISC 1.1");
4501 break;
4502 case EFA_PARISC_2_0:
4503 out = stpcpy (out, ", PA-RISC 2.0");
4504 break;
4505 default:
4506 break;
4507 }
4508 if (e_flags & EF_PARISC_TRAPNIL)
4509 out = stpcpy (out, ", trapnil");
4510 if (e_flags & EF_PARISC_EXT)
4511 out = stpcpy (out, ", ext");
4512 if (e_flags & EF_PARISC_LSB)
4513 out = stpcpy (out, ", lsb");
4514 if (e_flags & EF_PARISC_WIDE)
4515 out = stpcpy (out, ", wide");
4516 if (e_flags & EF_PARISC_NO_KABP)
4517 out = stpcpy (out, ", no kabp");
4518 if (e_flags & EF_PARISC_LAZYSWAP)
4519 out = stpcpy (out, ", lazyswap");
4520 return out;
4521}
4522
4523static char *
4524decode_RISCV_machine_flags (char *out, unsigned e_flags)
4525{
4526 if (e_flags & EF_RISCV_RVC)
4527 out = stpcpy (out, ", RVC");
4528
4529 if (e_flags & EF_RISCV_RVE)
4530 out = stpcpy (out, ", RVE");
4531
4532 if (e_flags & EF_RISCV_TSO)
4533 out = stpcpy (out, ", TSO");
4534
4535 switch (e_flags & EF_RISCV_FLOAT_ABI)
4536 {
4537 case EF_RISCV_FLOAT_ABI_SOFT:
4538 out = stpcpy (out, ", soft-float ABI");
4539 break;
4540
4541 case EF_RISCV_FLOAT_ABI_SINGLE:
4542 out = stpcpy (out, ", single-float ABI");
4543 break;
4544
4545 case EF_RISCV_FLOAT_ABI_DOUBLE:
4546 out = stpcpy (out, ", double-float ABI");
4547 break;
4548
4549 case EF_RISCV_FLOAT_ABI_QUAD:
4550 out = stpcpy (out, ", quad-float ABI");
4551 break;
4552 }
4553 return out;
4554}
4555
4556static char *
4557decode_RL78_machine_flags (char *out, unsigned e_flags)
4558{
4559 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4560 {
4561 case E_FLAG_RL78_ANY_CPU:
4562 break;
4563 case E_FLAG_RL78_G10:
4564 out = stpcpy (out, ", G10");
4565 break;
4566 case E_FLAG_RL78_G13:
4567 out = stpcpy (out, ", G13");
4568 break;
4569 case E_FLAG_RL78_G14:
4570 out = stpcpy (out, ", G14");
4571 break;
4572 }
4573 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4574 out = stpcpy (out, ", 64-bit doubles");
4575 return out;
4576}
4577
4578static char *
4579decode_RX_machine_flags (char *out, unsigned e_flags)
4580{
4581 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4582 out = stpcpy (out, ", 64-bit doubles");
4583 if (e_flags & E_FLAG_RX_DSP)
4584 out = stpcpy (out, ", dsp");
4585 if (e_flags & E_FLAG_RX_PID)
4586 out = stpcpy (out, ", pid");
4587 if (e_flags & E_FLAG_RX_ABI)
4588 out = stpcpy (out, ", RX ABI");
4589 if (e_flags & E_FLAG_RX_SINSNS_SET)
4590 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4591 ? ", uses String instructions"
4592 : ", bans String instructions"));
4593 if (e_flags & E_FLAG_RX_V2)
4594 out = stpcpy (out, ", V2");
4595 if (e_flags & E_FLAG_RX_V3)
4596 out = stpcpy (out, ", V3");
4597 return out;
4598}
4599
4600static char *
4601decode_SH_machine_flags (char *out, unsigned e_flags)
4602{
4603 switch ((e_flags & EF_SH_MACH_MASK))
4604 {
4605 case EF_SH1:
4606 out = stpcpy (out, ", sh1");
4607 break;
4608 case EF_SH2:
4609 out = stpcpy (out, ", sh2");
4610 break;
4611 case EF_SH3:
4612 out = stpcpy (out, ", sh3");
4613 break;
4614 case EF_SH_DSP:
4615 out = stpcpy (out, ", sh-dsp");
4616 break;
4617 case EF_SH3_DSP:
4618 out = stpcpy (out, ", sh3-dsp");
4619 break;
4620 case EF_SH4AL_DSP:
4621 out = stpcpy (out, ", sh4al-dsp");
4622 break;
4623 case EF_SH3E:
4624 out = stpcpy (out, ", sh3e");
4625 break;
4626 case EF_SH4:
4627 out = stpcpy (out, ", sh4");
4628 break;
4629 case EF_SH5:
4630 out = stpcpy (out, ", sh5");
4631 break;
4632 case EF_SH2E:
4633 out = stpcpy (out, ", sh2e");
4634 break;
4635 case EF_SH4A:
4636 out = stpcpy (out, ", sh4a");
4637 break;
4638 case EF_SH2A:
4639 out = stpcpy (out, ", sh2a");
4640 break;
4641 case EF_SH4_NOFPU:
4642 out = stpcpy (out, ", sh4-nofpu");
4643 break;
4644 case EF_SH4A_NOFPU:
4645 out = stpcpy (out, ", sh4a-nofpu");
4646 break;
4647 case EF_SH2A_NOFPU:
4648 out = stpcpy (out, ", sh2a-nofpu");
4649 break;
4650 case EF_SH3_NOMMU:
4651 out = stpcpy (out, ", sh3-nommu");
4652 break;
4653 case EF_SH4_NOMMU_NOFPU:
4654 out = stpcpy (out, ", sh4-nommu-nofpu");
4655 break;
4656 case EF_SH2A_SH4_NOFPU:
4657 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4658 break;
4659 case EF_SH2A_SH3_NOFPU:
4660 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4661 break;
4662 case EF_SH2A_SH4:
4663 out = stpcpy (out, ", sh2a-or-sh4");
4664 break;
4665 case EF_SH2A_SH3E:
4666 out = stpcpy (out, ", sh2a-or-sh3e");
4667 break;
4668 default:
4669 out = stpcpy (out, _(", unknown ISA"));
4670 break;
4671 }
4672
4673 if (e_flags & EF_SH_PIC)
4674 out = stpcpy (out, ", pic");
4675
4676 if (e_flags & EF_SH_FDPIC)
4677 out = stpcpy (out, ", fdpic");
4678 return out;
4679}
4680
4681static char *
4682decode_SPARC_machine_flags (char *out, unsigned e_flags)
4683{
4684 if (e_flags & EF_SPARC_32PLUS)
4685 out = stpcpy (out, ", v8+");
4686
4687 if (e_flags & EF_SPARC_SUN_US1)
4688 out = stpcpy (out, ", ultrasparcI");
4689
4690 if (e_flags & EF_SPARC_SUN_US3)
4691 out = stpcpy (out, ", ultrasparcIII");
4692
4693 if (e_flags & EF_SPARC_HAL_R1)
4694 out = stpcpy (out, ", halr1");
4695
4696 if (e_flags & EF_SPARC_LEDATA)
4697 out = stpcpy (out, ", ledata");
4698
4699 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4700 out = stpcpy (out, ", tso");
4701
4702 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4703 out = stpcpy (out, ", pso");
4704
4705 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4706 out = stpcpy (out, ", rmo");
4707 return out;
4708}
4709
4710static char *
4711decode_V800_machine_flags (char *out, unsigned int e_flags)
4712{
4713 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4714 out = stpcpy (out, ", RH850 ABI");
4715
4716 if (e_flags & EF_V800_850E3)
4717 out = stpcpy (out, ", V3 architecture");
4718
4719 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4720 out = stpcpy (out, ", FPU not used");
4721
4722 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4723 out = stpcpy (out, ", regmode: COMMON");
4724
4725 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4726 out = stpcpy (out, ", r4 not used");
4727
4728 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4729 out = stpcpy (out, ", r30 not used");
4730
4731 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4732 out = stpcpy (out, ", r5 not used");
4733
4734 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4735 out = stpcpy (out, ", r2 not used");
4736
4737 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4738 {
4739 switch (e_flags & - e_flags)
4740 {
4741 case EF_RH850_FPU_DOUBLE:
4742 out = stpcpy (out, ", double precision FPU");
4743 break;
4744 case EF_RH850_FPU_SINGLE:
4745 out = stpcpy (out, ", single precision FPU");
4746 break;
4747 case EF_RH850_REGMODE22:
4748 out = stpcpy (out, ", regmode:22");
4749 break;
4750 case EF_RH850_REGMODE32:
4751 out = stpcpy (out, ", regmode:23");
4752 break;
4753 case EF_RH850_GP_FIX:
4754 out = stpcpy (out, ", r4 fixed");
4755 break;
4756 case EF_RH850_GP_NOFIX:
4757 out = stpcpy (out, ", r4 free");
4758 break;
4759 case EF_RH850_EP_FIX:
4760 out = stpcpy (out, ", r30 fixed");
4761 break;
4762 case EF_RH850_EP_NOFIX:
4763 out = stpcpy (out, ", r30 free");
4764 break;
4765 case EF_RH850_TP_FIX:
4766 out = stpcpy (out, ", r5 fixed");
4767 break;
4768 case EF_RH850_TP_NOFIX:
4769 out = stpcpy (out, ", r5 free");
4770 break;
4771 case EF_RH850_REG2_RESERVE:
4772 out = stpcpy (out, ", r2 fixed");
4773 break;
4774 case EF_RH850_REG2_NORESERVE:
4775 out = stpcpy (out, ", r2 free");
4776 break;
4777 default:
4778 break;
4779 }
4780 }
4781 return out;
4782}
4783
4784static char *
4785decode_V850_machine_flags (char *out, unsigned int e_flags)
4786{
4787 switch (e_flags & EF_V850_ARCH)
4788 {
4789 case E_V850E3V5_ARCH:
4790 out = stpcpy (out, ", v850e3v5");
4791 break;
4792 case E_V850E2V3_ARCH:
4793 out = stpcpy (out, ", v850e2v3");
4794 break;
4795 case E_V850E2_ARCH:
4796 out = stpcpy (out, ", v850e2");
4797 break;
4798 case E_V850E1_ARCH:
4799 out = stpcpy (out, ", v850e1");
4800 break;
4801 case E_V850E_ARCH:
4802 out = stpcpy (out, ", v850e");
4803 break;
4804 case E_V850_ARCH:
4805 out = stpcpy (out, ", v850");
4806 break;
4807 default:
4808 out = stpcpy (out, _(", unknown v850 architecture variant"));
4809 break;
4810 }
4811 return out;
4812}
4813
4814static char *
4815decode_Z80_machine_flags (char *out, unsigned int e_flags)
4816{
4817 switch (e_flags & EF_Z80_MACH_MSK)
4818 {
4819 case EF_Z80_MACH_Z80:
4820 out = stpcpy (out, ", Z80");
4821 break;
4822 case EF_Z80_MACH_Z180:
4823 out = stpcpy (out, ", Z180");
4824 break;
4825 case EF_Z80_MACH_R800:
4826 out = stpcpy (out, ", R800");
4827 break;
4828 case EF_Z80_MACH_EZ80_Z80:
4829 out = stpcpy (out, ", EZ80");
4830 break;
4831 case EF_Z80_MACH_EZ80_ADL:
4832 out = stpcpy (out, ", EZ80, ADL");
4833 break;
4834 case EF_Z80_MACH_GBZ80:
4835 out = stpcpy (out, ", GBZ80");
4836 break;
4837 case EF_Z80_MACH_Z80N:
4838 out = stpcpy (out, ", Z80N");
4839 break;
4840 default:
4841 out = stpcpy (out, _(", unknown"));
4842 break;
4843 }
4844 return out;
4845}
4846
4847static char *
4848decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4849{
4850 unsigned char *e_ident = filedata->file_header.e_ident;
4851 unsigned char osabi = e_ident[EI_OSABI];
4852 unsigned char abiversion = e_ident[EI_ABIVERSION];
4853 unsigned int mach;
4854
4855 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4856 it has been deprecated for a while.
4857
4858 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4859 of writing, they use the same flags as HSA v3, so the code below uses that
4860 assumption. */
4861 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4862 return out;
c077c580
SM
4863
4864 mach = e_flags & EF_AMDGPU_MACH;
4865 switch (mach)
4866 {
4867#define AMDGPU_CASE(code, string) \
f8c4789c 4868 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4869 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4870 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4871 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4872 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4873 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4874 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4875 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4876 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4877 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4878 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4879 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4880 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4881 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4882 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4883 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4884 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4885 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4886 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4887 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4888 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4889 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4890 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4891 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4892 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4893 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4894 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4895 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4896 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4897 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4898 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4899 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4900 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4901 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4902 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4903 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4904 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4905 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4906 default:
f8c4789c 4907 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4908 break;
4909#undef AMDGPU_CASE
4910 }
4911
c077c580
SM
4912 e_flags &= ~EF_AMDGPU_MACH;
4913
4914 if ((osabi == ELFOSABI_AMDGPU_HSA
4915 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4916 || osabi != ELFOSABI_AMDGPU_HSA)
4917 {
4918 /* For HSA v3 and other OS ABIs. */
4919 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4920 {
f8c4789c 4921 out = stpcpy (out, ", xnack on");
c077c580
SM
4922 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4923 }
4924
4925 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4926 {
f8c4789c 4927 out = stpcpy (out, ", sramecc on");
c077c580
SM
4928 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4929 }
4930 }
4931 else
4932 {
4933 /* For HSA v4+. */
4934 int xnack, sramecc;
4935
4936 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4937 switch (xnack)
4938 {
4939 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4940 break;
4941
4942 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4943 out = stpcpy (out, ", xnack any");
c077c580
SM
4944 break;
4945
4946 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4947 out = stpcpy (out, ", xnack off");
c077c580
SM
4948 break;
4949
4950 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4951 out = stpcpy (out, ", xnack on");
c077c580
SM
4952 break;
4953
4954 default:
f8c4789c 4955 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4956 break;
4957 }
4958
c077c580
SM
4959 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4960
4961 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4962 switch (sramecc)
4963 {
4964 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4965 break;
4966
4967 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4968 out = stpcpy (out, ", sramecc any");
c077c580
SM
4969 break;
4970
4971 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4972 out = stpcpy (out, ", sramecc off");
c077c580
SM
4973 break;
4974
4975 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4976 out = stpcpy (out, ", sramecc on");
c077c580
SM
4977 break;
4978
4979 default:
f8c4789c 4980 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4981 break;
4982 }
4983
c077c580
SM
4984 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4985 }
4986
4987 if (e_flags != 0)
f8c4789c
AM
4988 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4989 return out;
c077c580
SM
4990}
4991
252b5132 4992static char *
dda8d76d 4993get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4994{
b34976b6 4995 static char buf[1024];
f8c4789c 4996 char *out = buf;
252b5132
RH
4997
4998 buf[0] = '\0';
76da6bbe 4999
252b5132
RH
5000 if (e_flags)
5001 {
5002 switch (e_machine)
5003 {
5004 default:
5005 break;
5006
b5c37946 5007 case EM_ARC_COMPACT3:
f8c4789c 5008 out = stpcpy (out, ", HS5x");
b5c37946
SJ
5009 break;
5010
5011 case EM_ARC_COMPACT3_64:
f8c4789c 5012 out = stpcpy (out, ", HS6x");
b5c37946
SJ
5013 break;
5014
886a2506 5015 case EM_ARC_COMPACT2:
886a2506 5016 case EM_ARC_COMPACT:
f8c4789c
AM
5017 out = decode_ARC_machine_flags (out, e_flags, e_machine);
5018 break;
886a2506 5019
f3485b74 5020 case EM_ARM:
f8c4789c 5021 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 5022 break;
76da6bbe 5023
f8c4789c
AM
5024 case EM_AVR:
5025 out = decode_AVR_machine_flags (out, e_flags);
5026 break;
343433df 5027
781303ce 5028 case EM_BLACKFIN:
f8c4789c 5029 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
5030 break;
5031
ec2dfb42 5032 case EM_CYGNUS_FRV:
f8c4789c 5033 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 5034 break;
ec2dfb42 5035
53c7db4b 5036 case EM_68K:
f8c4789c 5037 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 5038 break;
33c63f9d 5039
c077c580 5040 case EM_AMDGPU:
f8c4789c 5041 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
5042 break;
5043
153a2776 5044 case EM_CYGNUS_MEP:
f8c4789c 5045 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
5046 break;
5047
252b5132
RH
5048 case EM_PPC:
5049 if (e_flags & EF_PPC_EMB)
f8c4789c 5050 out = stpcpy (out, ", emb");
252b5132
RH
5051
5052 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 5053 out = stpcpy (out, _(", relocatable"));
252b5132
RH
5054
5055 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 5056 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
5057 break;
5058
ee67d69a
AM
5059 case EM_PPC64:
5060 if (e_flags & EF_PPC64_ABI)
f8c4789c 5061 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
5062 break;
5063
708e2187 5064 case EM_V800:
f8c4789c 5065 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
5066 break;
5067
2b0337b0 5068 case EM_V850:
252b5132 5069 case EM_CYGNUS_V850:
f8c4789c 5070 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
5071 break;
5072
2b0337b0 5073 case EM_M32R:
252b5132
RH
5074 case EM_CYGNUS_M32R:
5075 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 5076 out = stpcpy (out, ", m32r");
252b5132
RH
5077 break;
5078
5079 case EM_MIPS:
4fe85591 5080 case EM_MIPS_RS3_LE:
f8c4789c 5081 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 5082 break;
351b4b40 5083
35c08157 5084 case EM_NDS32:
f8c4789c 5085 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
5086 break;
5087
fe944acf
FT
5088 case EM_NFP:
5089 switch (EF_NFP_MACH (e_flags))
5090 {
5091 case E_NFP_MACH_3200:
f8c4789c 5092 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
5093 break;
5094 case E_NFP_MACH_6000:
f8c4789c 5095 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
5096 break;
5097 }
5098 break;
5099
e23eba97 5100 case EM_RISCV:
f8c4789c 5101 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
5102 break;
5103
ccde1100 5104 case EM_SH:
f8c4789c 5105 out = decode_SH_machine_flags (out, e_flags);
ccde1100 5106 break;
948f632f 5107
f8c4789c
AM
5108 case EM_OR1K:
5109 if (e_flags & EF_OR1K_NODELAY)
5110 out = stpcpy (out, ", no delay");
5111 break;
57346661 5112
f8c4789c
AM
5113 case EM_BPF:
5114 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
5115 break;
b5c37946 5116
351b4b40 5117 case EM_SPARCV9:
f8c4789c 5118 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 5119 break;
7d466069 5120
103f02d3 5121 case EM_PARISC:
f8c4789c 5122 out = decode_PARISC_machine_flags (out, e_flags);
30800947 5123 break;
76da6bbe 5124
7d466069 5125 case EM_PJ:
2b0337b0 5126 case EM_PJ_OLD:
7d466069 5127 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 5128 out = stpcpy (out, ", new calling convention");
7d466069
ILT
5129
5130 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 5131 out = stpcpy (out, ", gnu calling convention");
7d466069 5132 break;
4d6ed7c8
NC
5133
5134 case EM_IA_64:
f8c4789c 5135 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 5136 break;
179d3252
JT
5137
5138 case EM_VAX:
5139 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 5140 out = stpcpy (out, ", non-PIC");
179d3252 5141 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 5142 out = stpcpy (out, ", D-Float");
179d3252 5143 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 5144 out = stpcpy (out, ", G-Float");
179d3252 5145 break;
c7927a3c 5146
f8c4789c 5147 case EM_VISIUM:
619ed720 5148 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 5149 out = stpcpy (out, ", mcm");
619ed720 5150 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 5151 out = stpcpy (out, ", mcm24");
619ed720 5152 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 5153 out = stpcpy (out, ", gr6");
619ed720
EB
5154 break;
5155
4046d87a 5156 case EM_RL78:
f8c4789c 5157 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 5158 break;
0b4362b0 5159
c7927a3c 5160 case EM_RX:
f8c4789c 5161 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 5162 break;
55786da2
AK
5163
5164 case EM_S390:
5165 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 5166 out = stpcpy (out, ", highgprs");
d4cb0ea0 5167 break;
40b36596
JM
5168
5169 case EM_TI_C6000:
5170 if ((e_flags & EF_C6000_REL))
f8c4789c 5171 out = stpcpy (out, ", relocatable module");
d4cb0ea0 5172 break;
13761a11 5173
6e712424
PI
5174 case EM_KVX:
5175 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5176 strcat (buf, ", Kalray VLIW kv3-1");
5177 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5178 strcat (buf, ", Kalray VLIW kv3-2");
5179 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5180 strcat (buf, ", Kalray VLIW kv4-1");
5181 else
5182 strcat (buf, ", unknown KVX MPPA");
5183 break;
5184
13761a11 5185 case EM_MSP430:
f8c4789c 5186 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
5187 break;
5188
5189 case EM_Z80:
f8c4789c 5190 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 5191 break;
c4a7e6b5 5192
f8c4789c
AM
5193 case EM_LOONGARCH:
5194 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 5195 break;
252b5132
RH
5196 }
5197 }
5198
5199 return buf;
5200}
5201
252b5132 5202static const char *
dda8d76d 5203get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
5204{
5205 static char buff[32];
5206
5207 switch (osabi)
5208 {
5209 case ELFOSABI_NONE: return "UNIX - System V";
5210 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5211 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 5212 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
5213 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5214 case ELFOSABI_AIX: return "UNIX - AIX";
5215 case ELFOSABI_IRIX: return "UNIX - IRIX";
5216 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5217 case ELFOSABI_TRU64: return "UNIX - TRU64";
5218 case ELFOSABI_MODESTO: return "Novell - Modesto";
5219 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5220 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5221 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 5222 case ELFOSABI_AROS: return "AROS";
11636f9e 5223 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
5224 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5225 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
08b0f198 5226 case ELFOSABI_CUDA: return "CUDA";
d3ba0551 5227 default:
40b36596 5228 if (osabi >= 64)
dda8d76d 5229 switch (filedata->file_header.e_machine)
40b36596 5230 {
37870be8
SM
5231 case EM_AMDGPU:
5232 switch (osabi)
5233 {
5234 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5235 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5236 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5237 default:
5238 break;
5239 }
5240 break;
5241
40b36596
JM
5242 case EM_ARM:
5243 switch (osabi)
5244 {
5245 case ELFOSABI_ARM: return "ARM";
18a20338 5246 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
5247 default:
5248 break;
5249 }
5250 break;
5251
5252 case EM_MSP430:
5253 case EM_MSP430_OLD:
619ed720 5254 case EM_VISIUM:
40b36596
JM
5255 switch (osabi)
5256 {
5257 case ELFOSABI_STANDALONE: return _("Standalone App");
5258 default:
5259 break;
5260 }
5261 break;
5262
5263 case EM_TI_C6000:
5264 switch (osabi)
5265 {
5266 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5267 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5268 default:
5269 break;
5270 }
5271 break;
5272
5273 default:
5274 break;
5275 }
e9e44622 5276 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
5277 return buff;
5278 }
5279}
5280
a06ea964
NC
5281static const char *
5282get_aarch64_segment_type (unsigned long type)
5283{
5284 switch (type)
5285 {
08b0f198 5286 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 5287 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
08b0f198 5288 default: return NULL;
a06ea964 5289 }
a06ea964
NC
5290}
5291
b294bdf8
MM
5292static const char *
5293get_arm_segment_type (unsigned long type)
5294{
5295 switch (type)
5296 {
08b0f198
NC
5297 case PT_ARM_ARCHEXT: return "ARM_ARCHEXT";
5298 case PT_ARM_EXIDX: return "ARM_EXIDX";
5299 default: return NULL;
b294bdf8 5300 }
b294bdf8
MM
5301}
5302
b4cbbe8f
AK
5303static const char *
5304get_s390_segment_type (unsigned long type)
5305{
5306 switch (type)
5307 {
5308 case PT_S390_PGSTE: return "S390_PGSTE";
5309 default: return NULL;
5310 }
5311}
5312
d3ba0551
AM
5313static const char *
5314get_mips_segment_type (unsigned long type)
252b5132
RH
5315{
5316 switch (type)
5317 {
32ec8896
NC
5318 case PT_MIPS_REGINFO: return "REGINFO";
5319 case PT_MIPS_RTPROC: return "RTPROC";
5320 case PT_MIPS_OPTIONS: return "OPTIONS";
5321 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5322 default: return NULL;
252b5132 5323 }
252b5132
RH
5324}
5325
103f02d3 5326static const char *
d3ba0551 5327get_parisc_segment_type (unsigned long type)
103f02d3
UD
5328{
5329 switch (type)
5330 {
103f02d3
UD
5331 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5332 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 5333 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 5334 default: return NULL;
103f02d3 5335 }
103f02d3
UD
5336}
5337
4d6ed7c8 5338static const char *
d3ba0551 5339get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
5340{
5341 switch (type)
5342 {
5343 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5344 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5345 default: return NULL;
4d6ed7c8 5346 }
4d6ed7c8
NC
5347}
5348
40b36596
JM
5349static const char *
5350get_tic6x_segment_type (unsigned long type)
5351{
5352 switch (type)
5353 {
32ec8896
NC
5354 case PT_C6000_PHATTR: return "C6000_PHATTR";
5355 default: return NULL;
40b36596 5356 }
40b36596
JM
5357}
5358
fbc95f1e
KC
5359static const char *
5360get_riscv_segment_type (unsigned long type)
5361{
5362 switch (type)
5363 {
5364 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5365 default: return NULL;
5366 }
5367}
5368
df3a023b
AM
5369static const char *
5370get_hpux_segment_type (unsigned long type, unsigned e_machine)
5371{
5372 if (e_machine == EM_PARISC)
5373 switch (type)
5374 {
5375 case PT_HP_TLS: return "HP_TLS";
5376 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5377 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5378 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5379 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5380 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5381 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5382 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5383 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5384 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5385 case PT_HP_PARALLEL: return "HP_PARALLEL";
5386 case PT_HP_FASTBIND: return "HP_FASTBIND";
5387 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5388 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5389 case PT_HP_STACK: return "HP_STACK";
5390 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
08b0f198
NC
5391 default:
5392 break;
df3a023b
AM
5393 }
5394
5395 if (e_machine == EM_IA_64)
5396 switch (type)
5397 {
08b0f198 5398 case PT_HP_TLS: return "HP_TLS";
df3a023b
AM
5399 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5400 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5401 case PT_IA_64_HP_STACK: return "HP_STACK";
08b0f198
NC
5402 default:
5403 break;
df3a023b
AM
5404 }
5405
5406 return NULL;
5407}
5408
5522f910
NC
5409static const char *
5410get_solaris_segment_type (unsigned long type)
5411{
5412 switch (type)
5413 {
08b0f198
NC
5414 case PT_SUNW_UNWIND: return "SUNW_UNWIND";
5415 case PT_SUNW_EH_FRAME: return "SUNW_EH_FRAME";
5416 case PT_SUNWBSS: return "SUNW_BSS";
5417 case PT_SUNWSTACK: return "SUNW_STACK";
5418 case PT_SUNWDTRACE: return "SUNW_DTRACE";
5419 case PT_SUNWCAP: return "SUNW_CAP";
5420 default: return NULL;
5421 }
5422}
5423
5424static const char *
5425get_os_specific_segment_type (Filedata * filedata, unsigned long p_type)
5426{
5427 static char buff[32];
5428 const char * result = NULL;
5429
5430 switch (filedata->file_header.e_ident[EI_OSABI])
5431 {
5432 case ELFOSABI_GNU:
5433 case ELFOSABI_FREEBSD:
5434 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5435 {
5436 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5437 result = buff;
5438 }
5439 break;
5440
5441 case ELFOSABI_HPUX:
5442 result = get_hpux_segment_type (p_type,
5443 filedata->file_header.e_machine);
5444 break;
5445
5446 case ELFOSABI_SOLARIS:
5447 result = get_solaris_segment_type (p_type);
5448 break;
5449
5450 default:
5451 break;
5452 }
5453
5454 if (result != NULL)
5455 return result;
5456
5457 switch (p_type)
5458 {
5459 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5460 case PT_GNU_STACK: return "GNU_STACK";
5461 case PT_GNU_RELRO: return "GNU_RELRO";
5462 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5463 case PT_GNU_SFRAME: return "GNU_SFRAME";
5464
5465 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5466 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5467 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5468 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5469 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5470 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5471
5472 default:
5473 break;
5522f910 5474 }
08b0f198
NC
5475
5476 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5477 return buff;
5522f910
NC
5478}
5479
08b0f198
NC
5480static const char *
5481get_processor_specific_segment_type (Filedata * filedata, unsigned long p_type)
5482{
5483 static char buff[32];
5484 const char * result = NULL;
5485
5486 switch (filedata->file_header.e_machine)
5487 {
5488 case EM_AARCH64:
5489 result = get_aarch64_segment_type (p_type);
5490 break;
5491
5492 case EM_ARM:
5493 result = get_arm_segment_type (p_type);
5494 break;
5495
5496 case EM_MIPS:
5497 case EM_MIPS_RS3_LE:
5498 result = get_mips_segment_type (p_type);
5499 break;
5500
5501 case EM_PARISC:
5502 result = get_parisc_segment_type (p_type);
5503 break;
5504
5505 case EM_IA_64:
5506 result = get_ia64_segment_type (p_type);
5507 break;
5508
5509 case EM_TI_C6000:
5510 result = get_tic6x_segment_type (p_type);
5511 break;
5512
5513 case EM_S390:
5514 case EM_S390_OLD:
5515 result = get_s390_segment_type (p_type);
5516 break;
5517
5518 case EM_RISCV:
5519 result = get_riscv_segment_type (p_type);
5520 break;
5521
5522 default:
5523 result = NULL;
5524 break;
5525 }
5526
5527 if (result != NULL)
5528 return result;
5529
5530 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5531 return buff;
5532}
5533
252b5132 5534static const char *
dda8d76d 5535get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5536{
b34976b6 5537 static char buff[32];
252b5132
RH
5538
5539 switch (p_type)
5540 {
b34976b6
AM
5541 case PT_NULL: return "NULL";
5542 case PT_LOAD: return "LOAD";
252b5132 5543 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5544 case PT_INTERP: return "INTERP";
5545 case PT_NOTE: return "NOTE";
5546 case PT_SHLIB: return "SHLIB";
5547 case PT_PHDR: return "PHDR";
13ae64f3 5548 case PT_TLS: return "TLS";
08b0f198
NC
5549 case PT_NUM: return "NUM";
5550 }
103f02d3 5551
08b0f198
NC
5552 if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5553 return get_os_specific_segment_type (filedata, p_type);
103f02d3 5554
08b0f198
NC
5555 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5556 return get_processor_specific_segment_type (filedata, p_type);
252b5132 5557
08b0f198
NC
5558 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5559 return buff;
252b5132
RH
5560}
5561
53a346d8
CZ
5562static const char *
5563get_arc_section_type_name (unsigned int sh_type)
5564{
5565 switch (sh_type)
5566 {
5567 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5568 default:
5569 break;
5570 }
5571 return NULL;
5572}
5573
252b5132 5574static const char *
d3ba0551 5575get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5576{
5577 switch (sh_type)
5578 {
b34976b6
AM
5579 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5580 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5581 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5582 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5583 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5584 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5585 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5586 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5587 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5588 case SHT_MIPS_RELD: return "MIPS_RELD";
5589 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5590 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5591 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5592 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5593 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5594 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5595 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5596 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5597 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5598 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5599 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5600 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5601 case SHT_MIPS_LINE: return "MIPS_LINE";
5602 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5603 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5604 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5605 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5606 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5607 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5608 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5609 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5610 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5611 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5612 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5613 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5614 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5615 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5616 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5617 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5618 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5619 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5620 default:
5621 break;
5622 }
5623 return NULL;
5624}
5625
103f02d3 5626static const char *
d3ba0551 5627get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5628{
5629 switch (sh_type)
5630 {
5631 case SHT_PARISC_EXT: return "PARISC_EXT";
5632 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5633 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817 5634 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
08b0f198 5635 case SHT_PARISC_DLKM: return "PARISC_DLKM";
eec8f817
DA
5636 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5637 case SHT_PARISC_STUBS: return "PARISC_STUBS";
32ec8896 5638 default: return NULL;
103f02d3 5639 }
103f02d3
UD
5640}
5641
4d6ed7c8 5642static const char *
dda8d76d 5643get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5644{
18bd398b 5645 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5646 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5647 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5648
4d6ed7c8
NC
5649 switch (sh_type)
5650 {
148b93f2
NC
5651 case SHT_IA_64_EXT: return "IA_64_EXT";
5652 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5653 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
08b0f198
NC
5654 default:
5655 break;
5656 }
5657 return NULL;
5658}
5659
5660static const char *
5661get_vms_section_type_name (unsigned int sh_type)
5662{
5663 switch (sh_type)
5664 {
148b93f2
NC
5665 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5666 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5667 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5668 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5669 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5670 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5671 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5672 default:
5673 break;
5674 }
5675 return NULL;
5676}
5677
d2b2c203
DJ
5678static const char *
5679get_x86_64_section_type_name (unsigned int sh_type)
5680{
5681 switch (sh_type)
5682 {
5683 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5684 default: return NULL;
d2b2c203 5685 }
d2b2c203
DJ
5686}
5687
a06ea964
NC
5688static const char *
5689get_aarch64_section_type_name (unsigned int sh_type)
5690{
5691 switch (sh_type)
5692 {
08b0f198
NC
5693 case SHT_AARCH64_ATTRIBUTES:
5694 return "AARCH64_ATTRIBUTES";
5695 case SHT_AARCH64_AUTH_RELR:
5696 return "AARCH64_AUTH_RELR";
5697 case SHT_AARCH64_MEMTAG_GLOBALS_STATIC:
5698 return "AARCH64_MEMTAG_GLOBALS_STATIC";
5699 case SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC:
5700 return "AARCH64_MEMTAG_GLOBALS_DYNAMIC";
5701 default:
5702 return NULL;
a06ea964 5703 }
a06ea964
NC
5704}
5705
40a18ebd
NC
5706static const char *
5707get_arm_section_type_name (unsigned int sh_type)
5708{
5709 switch (sh_type)
5710 {
7f6fed87
NC
5711 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5712 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5713 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5714 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5715 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5716 default: return NULL;
40a18ebd 5717 }
40a18ebd
NC
5718}
5719
40b36596
JM
5720static const char *
5721get_tic6x_section_type_name (unsigned int sh_type)
5722{
5723 switch (sh_type)
5724 {
32ec8896
NC
5725 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5726 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5727 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5728 case SHT_TI_ICODE: return "TI_ICODE";
5729 case SHT_TI_XREF: return "TI_XREF";
5730 case SHT_TI_HANDLER: return "TI_HANDLER";
5731 case SHT_TI_INITINFO: return "TI_INITINFO";
5732 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5733 default: return NULL;
40b36596 5734 }
40b36596
JM
5735}
5736
13761a11 5737static const char *
b0191216 5738get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5739{
5740 switch (sh_type)
5741 {
32ec8896
NC
5742 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5743 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5744 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5745 default: return NULL;
13761a11
NC
5746 }
5747}
5748
fe944acf
FT
5749static const char *
5750get_nfp_section_type_name (unsigned int sh_type)
5751{
5752 switch (sh_type)
5753 {
5754 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5755 case SHT_NFP_INITREG: return "NFP_INITREG";
5756 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5757 default: return NULL;
5758 }
5759}
5760
685080f2
NC
5761static const char *
5762get_v850_section_type_name (unsigned int sh_type)
5763{
5764 switch (sh_type)
5765 {
32ec8896
NC
5766 case SHT_V850_SCOMMON: return "V850 Small Common";
5767 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5768 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5769 case SHT_RENESAS_IOP: return "RENESAS IOP";
5770 case SHT_RENESAS_INFO: return "RENESAS INFO";
5771 default: return NULL;
685080f2
NC
5772 }
5773}
5774
2dc8dd17
JW
5775static const char *
5776get_riscv_section_type_name (unsigned int sh_type)
5777{
5778 switch (sh_type)
5779 {
5780 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5781 default: return NULL;
5782 }
5783}
5784
0861f561
CQ
5785static const char *
5786get_csky_section_type_name (unsigned int sh_type)
5787{
5788 switch (sh_type)
5789 {
5790 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5791 default: return NULL;
5792 }
5793}
5794
252b5132 5795static const char *
08b0f198
NC
5796get_powerpc_section_type_name (unsigned int sh_type)
5797{
5798 switch (sh_type)
5799 {
5800 case SHT_ORDERED: return "ORDERED";
5801 default: return NULL;
5802 }
5803}
5804
5805static const char *
5806get_alpha_section_type_name (unsigned int sh_type)
5807{
5808 switch (sh_type)
5809 {
5810 case SHT_ALPHA_DEBUG: return "DEBUG";
5811 case SHT_ALPHA_REGINFO: return "REGINFO";
5812 default: return NULL;
5813 }
5814}
5815
5816static const char *
5817get_processor_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5818{
5819 static char buff[32];
5820 const char * result = NULL;
5821
5822 switch (filedata->file_header.e_machine)
5823 {
5824 case EM_AARCH64:
5825 result = get_aarch64_section_type_name (sh_type);
5826 break;
5827
5828 case EM_ALPHA:
5829 result = get_alpha_section_type_name (sh_type);
5830 break;
5831
5832 case EM_ARC:
5833 case EM_ARC_COMPACT:
5834 case EM_ARC_COMPACT2:
5835 case EM_ARC_COMPACT3:
5836 case EM_ARC_COMPACT3_64:
5837 result = get_arc_section_type_name (sh_type);
5838 break;
5839
5840 case EM_ARM:
5841 result = get_arm_section_type_name (sh_type);
5842 break;
5843
5844 case EM_CSKY:
5845 result = get_csky_section_type_name (sh_type);
5846 break;
5847
5848 case EM_IA_64:
5849 result = get_ia64_section_type_name (filedata, sh_type);
5850 break;
5851
5852 case EM_MIPS:
5853 case EM_MIPS_RS3_LE:
5854 result = get_mips_section_type_name (sh_type);
5855 break;
5856
5857 case EM_MSP430:
5858 result = get_msp430_section_type_name (sh_type);
5859 break;
5860
5861 case EM_NFP:
5862 result = get_nfp_section_type_name (sh_type);
5863 break;
5864
5865 case EM_PARISC:
5866 result = get_parisc_section_type_name (sh_type);
5867 break;
5868
5869 case EM_PPC64:
5870 case EM_PPC:
5871 return get_powerpc_section_type_name (sh_type);
5872 break;
5873
5874 case EM_RISCV:
5875 result = get_riscv_section_type_name (sh_type);
5876 break;
5877
5878 case EM_TI_C6000:
5879 result = get_tic6x_section_type_name (sh_type);
5880 break;
5881
5882 case EM_V800:
5883 case EM_V850:
5884 case EM_CYGNUS_V850:
5885 result = get_v850_section_type_name (sh_type);
5886 break;
5887
5888 case EM_X86_64:
5889 case EM_L1OM:
5890 case EM_K1OM:
5891 result = get_x86_64_section_type_name (sh_type);
5892 break;
5893
5894 default:
5895 break;
5896 }
5897
5898 if (result != NULL)
5899 return result;
5900
5901 switch (sh_type)
5902 {
5903 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5904 case 0x7ffffffd: return "AUXILIARY";
5905 case 0x7fffffff: return "FILTER";
5906 default:
5907 break;
5908 }
5909
5910 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5911 return buff;
5912}
5913
5914static const char *
5915get_os_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5916{
5917 static char buff[32];
5918 const char * result = NULL;
5919
5920 switch (filedata->file_header.e_machine)
5921 {
5922 case EM_IA_64:
5923 result = get_vms_section_type_name (sh_type);
5924 break;
5925 default:
5926 break;
5927 }
5928
5929 if (result != NULL)
5930 return result;
5931
5932 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5933 result = get_solaris_section_type (sh_type);
5934
5935 if (result != NULL)
5936 return result;
5937
5938 switch (sh_type)
5939 {
5940 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
5941 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5942 case SHT_GNU_HASH: return "GNU_HASH";
5943 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5944
5945 case SHT_SUNW_move: return "SUNW_MOVE";
5946 case SHT_SUNW_COMDAT: return "SUNW_COMDAT";
5947 case SHT_SUNW_syminfo: return "SUNW_SYMINFO";
5948 case SHT_GNU_verdef: return "VERDEF";
5949 case SHT_GNU_verneed: return "VERNEED";
5950 case SHT_GNU_versym: return "VERSYM";
5951
5952 case SHT_LLVM_ODRTAB: return "LLVM_ODRTAB";
5953 case SHT_LLVM_LINKER_OPTIONS: return "LLVM_LINKER_OPTIONS";
5954 case SHT_LLVM_ADDRSIG: return "LLVM_ADDRSIG";
5955 case SHT_LLVM_DEPENDENT_LIBRARIES: return "LLVM_DEPENDENT_LIBRARIES";
5956 case SHT_LLVM_SYMPART: return "LLVM_SYMPART";
5957 case SHT_LLVM_PART_EHDR: return "LLVM_PART_EHDR";
5958 case SHT_LLVM_PART_PHDR: return "LLVM_PART_PHDR";
5959 case SHT_LLVM_BB_ADDR_MAP_V0: return "LLVM_BB_ADDR_MAP_V0";
5960 case SHT_LLVM_CALL_GRAPH_PROFILE: return "LLVM_CALL_GRAPH_PROFILE";
5961 case SHT_LLVM_BB_ADDR_MAP: return "LLVM_BB_ADDR_MAP";
5962 case SHT_LLVM_OFFLOADING: return "LLVM_OFFLOADING";
5963 case SHT_LLVM_LTO: return "LLVM_LTO";
5964
5965 case SHT_ANDROID_REL: return "ANDROID_REL";
5966 case SHT_ANDROID_RELA: return "ANDROID_RELA";
5967 case SHT_ANDROID_RELR: return "ANDROID_RELR";
5968
5969 case SHT_CHECKSUM: return "CHECKSUM";
5970
5971 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5972 case 0x6ffffff0: return "VERSYM";
5973
5974 default:
5975 break;
5976 }
5977
5978 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
5979 return buff;
5980}
5981
5982static const char *
5983get_user_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5984{
b34976b6 5985 static char buff[32];
9fb71ee4 5986 const char * result;
252b5132 5987
08b0f198
NC
5988 switch (filedata->file_header.e_machine)
5989 {
5990 case EM_V800:
5991 case EM_V850:
5992 case EM_CYGNUS_V850:
5993 result = get_v850_section_type_name (sh_type);
5994 break;
5995
5996 default:
5997 result = NULL;
5998 break;
5999 }
6000
6001 if (result != NULL)
6002 return result;
6003
6004 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
6005 return buff;
6006}
6007
6008static const char *
6009get_section_type_name (Filedata * filedata,
6010 unsigned int sh_type)
6011{
252b5132
RH
6012 switch (sh_type)
6013 {
6014 case SHT_NULL: return "NULL";
6015 case SHT_PROGBITS: return "PROGBITS";
6016 case SHT_SYMTAB: return "SYMTAB";
6017 case SHT_STRTAB: return "STRTAB";
6018 case SHT_RELA: return "RELA";
6019 case SHT_HASH: return "HASH";
6020 case SHT_DYNAMIC: return "DYNAMIC";
6021 case SHT_NOTE: return "NOTE";
6022 case SHT_NOBITS: return "NOBITS";
6023 case SHT_REL: return "REL";
6024 case SHT_SHLIB: return "SHLIB";
6025 case SHT_DYNSYM: return "DYNSYM";
8e8d0b63 6026 /* 12 and 13 are not defined. */
d1133906
NC
6027 case SHT_INIT_ARRAY: return "INIT_ARRAY";
6028 case SHT_FINI_ARRAY: return "FINI_ARRAY";
6029 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586 6030 case SHT_GROUP: return "GROUP";
67ce483b 6031 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
8e8d0b63
NC
6032 case SHT_RELR: return "RELR";
6033 /* End of generic section types. */
6034
252b5132 6035 default:
08b0f198
NC
6036 break;
6037 }
148b93f2 6038
08b0f198
NC
6039 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
6040 return get_processor_specific_section_type_name (filedata, sh_type);
148b93f2 6041
08b0f198
NC
6042 if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
6043 return get_os_specific_section_type_name (filedata, sh_type);
685080f2 6044
08b0f198
NC
6045 if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
6046 return get_user_specific_section_type_name (filedata, sh_type);
9fb71ee4 6047
08b0f198 6048 static char buff[32];
103f02d3 6049
08b0f198
NC
6050 /* This message is probably going to be displayed in a 15
6051 character wide field, so put the hex value first. */
6052 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
6053 return buff;
252b5132
RH
6054}
6055
79bc120c
NC
6056enum long_option_values
6057{
6058 OPTION_DEBUG_DUMP = 512,
6059 OPTION_DYN_SYMS,
0f03783c 6060 OPTION_LTO_SYMS,
79bc120c
NC
6061 OPTION_DWARF_DEPTH,
6062 OPTION_DWARF_START,
6063 OPTION_DWARF_CHECK,
6064 OPTION_CTF_DUMP,
6065 OPTION_CTF_PARENT,
6066 OPTION_CTF_SYMBOLS,
6067 OPTION_CTF_STRINGS,
42b6953b 6068 OPTION_SFRAME_DUMP,
79bc120c
NC
6069 OPTION_WITH_SYMBOL_VERSIONS,
6070 OPTION_RECURSE_LIMIT,
6071 OPTION_NO_RECURSE_LIMIT,
047c3dbf 6072 OPTION_NO_DEMANGLING,
b6ac461a 6073 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 6074 OPTION_SYM_BASE
79bc120c 6075};
2979dc34 6076
85b1c36d 6077static struct option options[] =
252b5132 6078{
79bc120c
NC
6079 /* Note - This table is alpha-sorted on the 'val'
6080 field in order to make adding new options easier. */
6081 {"arch-specific", no_argument, 0, 'A'},
b34976b6 6082 {"all", no_argument, 0, 'a'},
79bc120c
NC
6083 {"demangle", optional_argument, 0, 'C'},
6084 {"archive-index", no_argument, 0, 'c'},
6085 {"use-dynamic", no_argument, 0, 'D'},
6086 {"dynamic", no_argument, 0, 'd'},
b34976b6 6087 {"headers", no_argument, 0, 'e'},
79bc120c
NC
6088 {"section-groups", no_argument, 0, 'g'},
6089 {"help", no_argument, 0, 'H'},
6090 {"file-header", no_argument, 0, 'h'},
b34976b6 6091 {"histogram", no_argument, 0, 'I'},
8e8d0b63 6092 {"display-section", required_argument, 0, 'j'},
79bc120c
NC
6093 {"lint", no_argument, 0, 'L'},
6094 {"enable-checks", no_argument, 0, 'L'},
6095 {"program-headers", no_argument, 0, 'l'},
b34976b6 6096 {"segments", no_argument, 0, 'l'},
595cf52e 6097 {"full-section-name",no_argument, 0, 'N'},
79bc120c 6098 {"notes", no_argument, 0, 'n'},
ca0e11aa 6099 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
6100 {"string-dump", required_argument, 0, 'p'},
6101 {"relocated-dump", required_argument, 0, 'R'},
6102 {"relocs", no_argument, 0, 'r'},
6103 {"section-headers", no_argument, 0, 'S'},
6104 {"sections", no_argument, 0, 'S'},
b34976b6
AM
6105 {"symbols", no_argument, 0, 's'},
6106 {"syms", no_argument, 0, 's'},
79bc120c
NC
6107 {"silent-truncation",no_argument, 0, 'T'},
6108 {"section-details", no_argument, 0, 't'},
b3aa80b4 6109 {"unicode", required_argument, NULL, 'U'},
09c11c86 6110 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
6111 {"version-info", no_argument, 0, 'V'},
6112 {"version", no_argument, 0, 'v'},
6113 {"wide", no_argument, 0, 'W'},
b6ac461a 6114 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 6115 {"hex-dump", required_argument, 0, 'x'},
0e602686 6116 {"decompress", no_argument, 0, 'z'},
252b5132 6117
79bc120c 6118 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 6119 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
6120 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
6121 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6122 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6123 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 6124 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 6125 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
6126 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
6127 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 6128 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 6129#ifdef ENABLE_LIBCTF
d344b407 6130 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
6131 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
6132 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
6133 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 6134#endif
42b6953b 6135 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 6136 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 6137
b34976b6 6138 {0, no_argument, 0, 0}
252b5132
RH
6139};
6140
6141static void
2cf0635d 6142usage (FILE * stream)
252b5132 6143{
92f01d61
JM
6144 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
6145 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
6146 fprintf (stream, _(" Options are:\n"));
6147 fprintf (stream, _("\
6148 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
6149 fprintf (stream, _("\
6150 -h --file-header Display the ELF file header\n"));
6151 fprintf (stream, _("\
6152 -l --program-headers Display the program headers\n"));
6153 fprintf (stream, _("\
6154 --segments An alias for --program-headers\n"));
6155 fprintf (stream, _("\
6156 -S --section-headers Display the sections' header\n"));
6157 fprintf (stream, _("\
6158 --sections An alias for --section-headers\n"));
6159 fprintf (stream, _("\
6160 -g --section-groups Display the section groups\n"));
6161 fprintf (stream, _("\
6162 -t --section-details Display the section details\n"));
6163 fprintf (stream, _("\
6164 -e --headers Equivalent to: -h -l -S\n"));
6165 fprintf (stream, _("\
6166 -s --syms Display the symbol table\n"));
6167 fprintf (stream, _("\
6168 --symbols An alias for --syms\n"));
6169 fprintf (stream, _("\
6170 --dyn-syms Display the dynamic symbol table\n"));
6171 fprintf (stream, _("\
6172 --lto-syms Display LTO symbol tables\n"));
6173 fprintf (stream, _("\
047c3dbf
NL
6174 --sym-base=[0|8|10|16] \n\
6175 Force base for symbol sizes. The options are \n\
d6249f5f
AM
6176 mixed (the default), octal, decimal, hexadecimal.\n"));
6177 fprintf (stream, _("\
0d646226
AM
6178 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
6179 display_demangler_styles (stream, _("\
6180 STYLE can be "));
d6249f5f
AM
6181 fprintf (stream, _("\
6182 --no-demangle Do not demangle low-level symbol names. (default)\n"));
6183 fprintf (stream, _("\
6184 --recurse-limit Enable a demangling recursion limit. (default)\n"));
6185 fprintf (stream, _("\
6186 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
6187 fprintf (stream, _("\
6188 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
6189 Display unicode characters as determined by the current locale\n\
6190 (default), escape sequences, \"<hex sequences>\", highlighted\n\
6191 escape sequences, or treat them as invalid and display as\n\
6192 \"{hex sequences}\"\n"));
d6249f5f 6193 fprintf (stream, _("\
b6ac461a
NC
6194 -X --extra-sym-info Display extra information when showing symbols\n"));
6195 fprintf (stream, _("\
6196 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
6197 fprintf (stream, _("\
6198 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
6199 fprintf (stream, _("\
6200 -r --relocs Display the relocations (if present)\n"));
6201 fprintf (stream, _("\
6202 -u --unwind Display the unwind info (if present)\n"));
6203 fprintf (stream, _("\
6204 -d --dynamic Display the dynamic section (if present)\n"));
6205 fprintf (stream, _("\
6206 -V --version-info Display the version sections (if present)\n"));
6207 fprintf (stream, _("\
6208 -A --arch-specific Display architecture specific information (if any)\n"));
6209 fprintf (stream, _("\
6210 -c --archive-index Display the symbol/file index in an archive\n"));
6211 fprintf (stream, _("\
6212 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
6213 fprintf (stream, _("\
6214 -L --lint|--enable-checks\n\
6215 Display warning messages for possible problems\n"));
6216 fprintf (stream, _("\
09c11c86 6217 -x --hex-dump=<number|name>\n\
d6249f5f
AM
6218 Dump the contents of section <number|name> as bytes\n"));
6219 fprintf (stream, _("\
09c11c86 6220 -p --string-dump=<number|name>\n\
d6249f5f
AM
6221 Dump the contents of section <number|name> as strings\n"));
6222 fprintf (stream, _("\
cf13d699 6223 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
6224 Dump the relocated contents of section <number|name>\n"));
6225 fprintf (stream, _("\
6226 -z --decompress Decompress section before dumping it\n"));
8e8d0b63
NC
6227 fprintf (stream, _("\n\
6228 -j --display-section=<name|number>\n\
6229 Display the contents of the indicated section. Can be repeated\n"));
d6249f5f
AM
6230 fprintf (stream, _("\
6231 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
6232 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
6233 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
6234 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
6235 U/=trace_info]\n\
6236 Display the contents of DWARF debug sections\n"));
6237 fprintf (stream, _("\
6238 -wk --debug-dump=links Display the contents of sections that link to separate\n\
6239 debuginfo files\n"));
6240 fprintf (stream, _("\
6241 -P --process-links Display the contents of non-debug sections in separate\n\
6242 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
6243#if DEFAULT_FOR_FOLLOW_LINKS
6244 fprintf (stream, _("\
d6249f5f
AM
6245 -wK --debug-dump=follow-links\n\
6246 Follow links to separate debug info files (default)\n"));
6247 fprintf (stream, _("\
6248 -wN --debug-dump=no-follow-links\n\
6249 Do not follow links to separate debug info files\n"));
c46b7066
NC
6250#else
6251 fprintf (stream, _("\
d6249f5f
AM
6252 -wK --debug-dump=follow-links\n\
6253 Follow links to separate debug info files\n"));
6254 fprintf (stream, _("\
6255 -wN --debug-dump=no-follow-links\n\
6256 Do not follow links to separate debug info files\n\
6257 (default)\n"));
bed566bb
NC
6258#endif
6259#if HAVE_LIBDEBUGINFOD
6260 fprintf (stream, _("\
6261 -wD --debug-dump=use-debuginfod\n\
6262 When following links, also query debuginfod servers (default)\n"));
6263 fprintf (stream, _("\
6264 -wE --debug-dump=do-not-use-debuginfod\n\
6265 When following links, do not query debuginfod servers\n"));
c46b7066 6266#endif
fd2f0033 6267 fprintf (stream, _("\
d6249f5f
AM
6268 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6269 fprintf (stream, _("\
6270 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 6271#ifdef ENABLE_LIBCTF
7d9813f1 6272 fprintf (stream, _("\
d6249f5f
AM
6273 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6274 fprintf (stream, _("\
80b56fad 6275 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 6276 fprintf (stream, _("\
7d9813f1 6277 --ctf-symbols=<number|name>\n\
d6249f5f
AM
6278 Use section <number|name> as the CTF external symtab\n"));
6279 fprintf (stream, _("\
7d9813f1 6280 --ctf-strings=<number|name>\n\
d6249f5f 6281 Use section <number|name> as the CTF external strtab\n"));
094e34f2 6282#endif
42b6953b
IB
6283 fprintf (stream, _("\
6284 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 6285
252b5132 6286#ifdef SUPPORT_DISASSEMBLY
92f01d61 6287 fprintf (stream, _("\
09c11c86
NC
6288 -i --instruction-dump=<number|name>\n\
6289 Disassemble the contents of section <number|name>\n"));
252b5132 6290#endif
92f01d61 6291 fprintf (stream, _("\
d6249f5f
AM
6292 -I --histogram Display histogram of bucket list lengths\n"));
6293 fprintf (stream, _("\
6294 -W --wide Allow output width to exceed 80 characters\n"));
6295 fprintf (stream, _("\
6296 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6297 fprintf (stream, _("\
6298 @<file> Read options from <file>\n"));
6299 fprintf (stream, _("\
6300 -H --help Display this information\n"));
6301 fprintf (stream, _("\
8b53311e 6302 -v --version Display the version number of readelf\n"));
1118d252 6303
92f01d61
JM
6304 if (REPORT_BUGS_TO[0] && stream == stdout)
6305 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 6306
92f01d61 6307 exit (stream == stdout ? 0 : 1);
252b5132
RH
6308}
6309
18bd398b
NC
6310/* Record the fact that the user wants the contents of section number
6311 SECTION to be displayed using the method(s) encoded as flags bits
6312 in TYPE. Note, TYPE can be zero if we are creating the array for
6313 the first time. */
6314
252b5132 6315static void
6431e409
AM
6316request_dump_bynumber (struct dump_data *dumpdata,
6317 unsigned int section, dump_type type)
252b5132 6318{
6431e409 6319 if (section >= dumpdata->num_dump_sects)
252b5132 6320 {
2cf0635d 6321 dump_type * new_dump_sects;
252b5132 6322
3f5e193b 6323 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 6324 sizeof (* new_dump_sects));
252b5132
RH
6325
6326 if (new_dump_sects == NULL)
591a748a 6327 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
6328 else
6329 {
6431e409 6330 if (dumpdata->dump_sects)
21b65bac
NC
6331 {
6332 /* Copy current flag settings. */
6431e409
AM
6333 memcpy (new_dump_sects, dumpdata->dump_sects,
6334 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 6335
6431e409 6336 free (dumpdata->dump_sects);
21b65bac 6337 }
252b5132 6338
6431e409
AM
6339 dumpdata->dump_sects = new_dump_sects;
6340 dumpdata->num_dump_sects = section + 1;
252b5132
RH
6341 }
6342 }
6343
6431e409
AM
6344 if (dumpdata->dump_sects)
6345 dumpdata->dump_sects[section] |= type;
252b5132
RH
6346}
6347
aef1f6d0
DJ
6348/* Request a dump by section name. */
6349
6350static void
2cf0635d 6351request_dump_byname (const char * section, dump_type type)
aef1f6d0 6352{
2cf0635d 6353 struct dump_list_entry * new_request;
aef1f6d0 6354
3f5e193b
NC
6355 new_request = (struct dump_list_entry *)
6356 malloc (sizeof (struct dump_list_entry));
aef1f6d0 6357 if (!new_request)
591a748a 6358 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6359
6360 new_request->name = strdup (section);
6361 if (!new_request->name)
591a748a 6362 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6363
6364 new_request->type = type;
6365
6366 new_request->next = dump_sects_byname;
6367 dump_sects_byname = new_request;
6368}
6369
cf13d699 6370static inline void
6431e409 6371request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
6372{
6373 int section;
6374 char * cp;
6375
015dc7e1 6376 do_dump = true;
cf13d699
NC
6377 section = strtoul (optarg, & cp, 0);
6378
6379 if (! *cp && section >= 0)
6431e409 6380 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
6381 else
6382 request_dump_byname (optarg, type);
6383}
6384
252b5132 6385static void
6431e409 6386parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
6387{
6388 int c;
6389
6390 if (argc < 2)
92f01d61 6391 usage (stderr);
252b5132
RH
6392
6393 while ((c = getopt_long
8e8d0b63 6394 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 6395 {
252b5132
RH
6396 switch (c)
6397 {
6398 case 0:
6399 /* Long options. */
6400 break;
6401 case 'H':
92f01d61 6402 usage (stdout);
252b5132
RH
6403 break;
6404
6405 case 'a':
015dc7e1
AM
6406 do_syms = true;
6407 do_reloc = true;
6408 do_unwind = true;
6409 do_dynamic = true;
6410 do_header = true;
6411 do_sections = true;
6412 do_section_groups = true;
6413 do_segments = true;
6414 do_version = true;
6415 do_histogram = true;
6416 do_arch = true;
6417 do_notes = true;
252b5132 6418 break;
79bc120c 6419
f5842774 6420 case 'g':
015dc7e1 6421 do_section_groups = true;
f5842774 6422 break;
5477e8a0 6423 case 't':
595cf52e 6424 case 'N':
015dc7e1
AM
6425 do_sections = true;
6426 do_section_details = true;
595cf52e 6427 break;
252b5132 6428 case 'e':
015dc7e1
AM
6429 do_header = true;
6430 do_sections = true;
6431 do_segments = true;
252b5132 6432 break;
a952a375 6433 case 'A':
015dc7e1 6434 do_arch = true;
a952a375 6435 break;
252b5132 6436 case 'D':
015dc7e1 6437 do_using_dynamic = true;
252b5132
RH
6438 break;
6439 case 'r':
015dc7e1 6440 do_reloc = true;
252b5132 6441 break;
4d6ed7c8 6442 case 'u':
015dc7e1 6443 do_unwind = true;
4d6ed7c8 6444 break;
252b5132 6445 case 'h':
015dc7e1 6446 do_header = true;
252b5132
RH
6447 break;
6448 case 'l':
015dc7e1 6449 do_segments = true;
252b5132
RH
6450 break;
6451 case 's':
015dc7e1 6452 do_syms = true;
252b5132
RH
6453 break;
6454 case 'S':
015dc7e1 6455 do_sections = true;
252b5132
RH
6456 break;
6457 case 'd':
015dc7e1 6458 do_dynamic = true;
252b5132 6459 break;
a952a375 6460 case 'I':
015dc7e1 6461 do_histogram = true;
a952a375 6462 break;
779fe533 6463 case 'n':
015dc7e1 6464 do_notes = true;
779fe533 6465 break;
4145f1d5 6466 case 'c':
015dc7e1 6467 do_archive_index = true;
4145f1d5 6468 break;
1b513401 6469 case 'L':
015dc7e1 6470 do_checks = true;
1b513401 6471 break;
ca0e11aa 6472 case 'P':
015dc7e1
AM
6473 process_links = true;
6474 do_follow_links = true;
e1dbfc17 6475 dump_any_debugging = true;
ca0e11aa 6476 break;
8e8d0b63
NC
6477 case 'j':
6478 request_dump (dumpdata, AUTO_DUMP);
6479 break;
252b5132 6480 case 'x':
6431e409 6481 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 6482 break;
09c11c86 6483 case 'p':
6431e409 6484 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
6485 break;
6486 case 'R':
6431e409 6487 request_dump (dumpdata, RELOC_DUMP);
09c11c86 6488 break;
0e602686 6489 case 'z':
015dc7e1 6490 decompress_dumps = true;
0e602686 6491 break;
252b5132 6492 case 'w':
0f03783c 6493 if (optarg == NULL)
613ff48b 6494 {
015dc7e1 6495 do_debugging = true;
94585d6d
NC
6496 do_dump = true;
6497 dump_any_debugging = true;
613ff48b
CC
6498 dwarf_select_sections_all ();
6499 }
252b5132
RH
6500 else
6501 {
015dc7e1 6502 do_debugging = false;
94585d6d
NC
6503 if (dwarf_select_sections_by_letters (optarg))
6504 {
6505 do_dump = true;
6506 dump_any_debugging = true;
6507 }
252b5132
RH
6508 }
6509 break;
2979dc34 6510 case OPTION_DEBUG_DUMP:
0f03783c 6511 if (optarg == NULL)
d6249f5f 6512 {
94585d6d 6513 do_dump = true;
d6249f5f 6514 do_debugging = true;
94585d6d 6515 dump_any_debugging = true;
d6249f5f
AM
6516 dwarf_select_sections_all ();
6517 }
2979dc34
JJ
6518 else
6519 {
015dc7e1 6520 do_debugging = false;
94585d6d
NC
6521 if (dwarf_select_sections_by_names (optarg))
6522 {
6523 do_dump = true;
6524 dump_any_debugging = true;
6525 }
2979dc34
JJ
6526 }
6527 break;
fd2f0033
TT
6528 case OPTION_DWARF_DEPTH:
6529 {
6530 char *cp;
6531
6532 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6533 }
6534 break;
6535 case OPTION_DWARF_START:
6536 {
6537 char *cp;
6538
6539 dwarf_start_die = strtoul (optarg, & cp, 0);
6540 }
6541 break;
4723351a 6542 case OPTION_DWARF_CHECK:
015dc7e1 6543 dwarf_check = true;
4723351a 6544 break;
7d9813f1 6545 case OPTION_CTF_DUMP:
015dc7e1 6546 do_ctf = true;
6431e409 6547 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6548 break;
6549 case OPTION_CTF_SYMBOLS:
df16e041 6550 free (dump_ctf_symtab_name);
7d9813f1
NA
6551 dump_ctf_symtab_name = strdup (optarg);
6552 break;
6553 case OPTION_CTF_STRINGS:
df16e041 6554 free (dump_ctf_strtab_name);
7d9813f1
NA
6555 dump_ctf_strtab_name = strdup (optarg);
6556 break;
6557 case OPTION_CTF_PARENT:
df16e041 6558 free (dump_ctf_parent_name);
7d9813f1
NA
6559 dump_ctf_parent_name = strdup (optarg);
6560 break;
42b6953b
IB
6561 case OPTION_SFRAME_DUMP:
6562 do_sframe = true;
6563 /* Providing section name is optional. request_dump (), however,
6564 thrives on non NULL optarg. Handle it explicitly here. */
6565 if (optarg != NULL)
6566 request_dump (dumpdata, SFRAME_DUMP);
6567 else
6568 {
6569 do_dump = true;
6570 const char *sframe_sec_name = strdup (".sframe");
6571 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6572 }
6573 break;
2c610e4b 6574 case OPTION_DYN_SYMS:
015dc7e1 6575 do_dyn_syms = true;
2c610e4b 6576 break;
0f03783c 6577 case OPTION_LTO_SYMS:
015dc7e1 6578 do_lto_syms = true;
0f03783c 6579 break;
b6ac461a
NC
6580 case 'X':
6581 extra_sym_info = true;
6582 break;
6583 case OPTION_NO_EXTRA_SYM_INFO:
6584 extra_sym_info = false;
6585 break;
6586
252b5132
RH
6587#ifdef SUPPORT_DISASSEMBLY
6588 case 'i':
6431e409 6589 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6590 break;
252b5132
RH
6591#endif
6592 case 'v':
6593 print_version (program_name);
6594 break;
6595 case 'V':
015dc7e1 6596 do_version = true;
252b5132 6597 break;
d974e256 6598 case 'W':
015dc7e1 6599 do_wide = true;
d974e256 6600 break;
0942c7ab 6601 case 'T':
015dc7e1 6602 do_not_show_symbol_truncation = true;
0942c7ab 6603 break;
79bc120c 6604 case 'C':
015dc7e1 6605 do_demangle = true;
79bc120c
NC
6606 if (optarg != NULL)
6607 {
6608 enum demangling_styles style;
6609
6610 style = cplus_demangle_name_to_style (optarg);
6611 if (style == unknown_demangling)
6612 error (_("unknown demangling style `%s'"), optarg);
6613
6614 cplus_demangle_set_style (style);
6615 }
6616 break;
6617 case OPTION_NO_DEMANGLING:
015dc7e1 6618 do_demangle = false;
79bc120c
NC
6619 break;
6620 case OPTION_RECURSE_LIMIT:
6621 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6622 break;
6623 case OPTION_NO_RECURSE_LIMIT:
6624 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6625 break;
6626 case OPTION_WITH_SYMBOL_VERSIONS:
6627 /* Ignored for backward compatibility. */
6628 break;
b9e920ec 6629
b3aa80b4
NC
6630 case 'U':
6631 if (optarg == NULL)
6632 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6633 else if (streq (optarg, "default") || streq (optarg, "d"))
6634 unicode_display = unicode_default;
6635 else if (streq (optarg, "locale") || streq (optarg, "l"))
6636 unicode_display = unicode_locale;
6637 else if (streq (optarg, "escape") || streq (optarg, "e"))
6638 unicode_display = unicode_escape;
6639 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6640 unicode_display = unicode_invalid;
6641 else if (streq (optarg, "hex") || streq (optarg, "x"))
6642 unicode_display = unicode_hex;
6643 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6644 unicode_display = unicode_highlight;
6645 else
6646 error (_("invalid argument to -U/--unicode: %s"), optarg);
6647 break;
6648
047c3dbf
NL
6649 case OPTION_SYM_BASE:
6650 sym_base = 0;
6651 if (optarg != NULL)
6652 {
6653 sym_base = strtoul (optarg, NULL, 0);
6654 switch (sym_base)
6655 {
6656 case 0:
6657 case 8:
6658 case 10:
6659 case 16:
6660 break;
6661
6662 default:
6663 sym_base = 0;
6664 break;
6665 }
6666 }
6667 break;
6668
252b5132 6669 default:
252b5132
RH
6670 /* xgettext:c-format */
6671 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6672 /* Fall through. */
252b5132 6673 case '?':
92f01d61 6674 usage (stderr);
252b5132
RH
6675 }
6676 }
6677
4d6ed7c8 6678 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6679 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6680 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6681 && !do_section_groups && !do_archive_index
0f03783c 6682 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6683 {
6684 if (do_checks)
6685 {
015dc7e1
AM
6686 check_all = true;
6687 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6688 do_segments = do_header = do_dump = do_version = true;
6689 do_histogram = do_debugging = do_arch = do_notes = true;
6690 do_section_groups = do_archive_index = do_dyn_syms = true;
6691 do_lto_syms = true;
1b513401
NC
6692 }
6693 else
6694 usage (stderr);
6695 }
252b5132
RH
6696}
6697
6698static const char *
d3ba0551 6699get_elf_class (unsigned int elf_class)
252b5132 6700{
b34976b6 6701 static char buff[32];
103f02d3 6702
252b5132
RH
6703 switch (elf_class)
6704 {
6705 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6706 case ELFCLASS32: return "ELF32";
6707 case ELFCLASS64: return "ELF64";
ab5e7794 6708 default:
e9e44622 6709 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6710 return buff;
252b5132
RH
6711 }
6712}
6713
6714static const char *
d3ba0551 6715get_data_encoding (unsigned int encoding)
252b5132 6716{
b34976b6 6717 static char buff[32];
103f02d3 6718
252b5132
RH
6719 switch (encoding)
6720 {
6721 case ELFDATANONE: return _("none");
33c63f9d
CM
6722 case ELFDATA2LSB: return _("2's complement, little endian");
6723 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6724 default:
e9e44622 6725 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6726 return buff;
252b5132
RH
6727 }
6728}
6729
521f7268
NC
6730static bool
6731check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6732{
6733 if (header->e_ident[EI_MAG0] == ELFMAG0
6734 && header->e_ident[EI_MAG1] == ELFMAG1
6735 && header->e_ident[EI_MAG2] == ELFMAG2
6736 && header->e_ident[EI_MAG3] == ELFMAG3)
6737 return true;
6738
6739 /* Some compilers produce object files that are not in the ELF file format.
6740 As an aid to users of readelf, try to identify these cases and suggest
6741 alternative tools.
6742
6743 FIXME: It is not clear if all four bytes are used as constant magic
6744 valus by all compilers. It may be necessary to recode this function if
6745 different tools use different length sequences. */
6746
6747 static struct
6748 {
6749 unsigned char magic[4];
6750 const char * obj_message;
6751 const char * ar_message;
6752 }
6753 known_magic[] =
6754 {
6755 { { 'B', 'C', 0xc0, 0xde },
6756 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6757 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6758 },
6759 { { 'g', 'o', ' ', 'o' },
6760 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6761 NULL
6762 }
6763 };
6764 int i;
6765
6766 for (i = ARRAY_SIZE (known_magic); i--;)
6767 {
6768 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6769 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6770 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6771 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6772 {
6773 /* Some compiler's analyzer tools do not handle archives,
6774 so we provide two different kinds of error message. */
6775 if (filedata->archive_file_size > 0
6776 && known_magic[i].ar_message != NULL)
b3ea2010 6777 error ("%s", known_magic[i].ar_message);
521f7268 6778 else
b3ea2010 6779 error ("%s", known_magic[i].obj_message);
521f7268
NC
6780 return false;
6781 }
6782 }
6783
6784 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6785 return false;
6786}
6787
dda8d76d 6788/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6789
015dc7e1 6790static bool
dda8d76d 6791process_file_header (Filedata * filedata)
252b5132 6792{
dda8d76d
NC
6793 Elf_Internal_Ehdr * header = & filedata->file_header;
6794
521f7268
NC
6795 if (! check_magic_number (filedata, header))
6796 return false;
252b5132 6797
ca0e11aa
NC
6798 if (! filedata->is_separate)
6799 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6800
252b5132
RH
6801 if (do_header)
6802 {
32ec8896 6803 unsigned i;
252b5132 6804
ca0e11aa
NC
6805 if (filedata->is_separate)
6806 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6807 else
6808 printf (_("ELF Header:\n"));
252b5132 6809 printf (_(" Magic: "));
b34976b6 6810 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6811 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6812 printf ("\n");
6813 printf (_(" Class: %s\n"),
dda8d76d 6814 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6815 printf (_(" Data: %s\n"),
dda8d76d 6816 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6817 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6818 header->e_ident[EI_VERSION],
6819 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6820 ? _(" (current)")
dda8d76d 6821 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6822 ? _(" <unknown>")
789be9f7 6823 : "")));
252b5132 6824 printf (_(" OS/ABI: %s\n"),
dda8d76d 6825 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6826 printf (_(" ABI Version: %d\n"),
dda8d76d 6827 header->e_ident[EI_ABIVERSION]);
252b5132 6828 printf (_(" Type: %s\n"),
93df3340 6829 get_file_type (filedata));
252b5132 6830 printf (_(" Machine: %s\n"),
dda8d76d 6831 get_machine_name (header->e_machine));
252b5132 6832 printf (_(" Version: 0x%lx\n"),
e8a64888 6833 header->e_version);
76da6bbe 6834
f7a99963 6835 printf (_(" Entry point address: "));
e8a64888 6836 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6837 printf (_("\n Start of program headers: "));
e8a64888 6838 print_vma (header->e_phoff, DEC);
f7a99963 6839 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6840 print_vma (header->e_shoff, DEC);
f7a99963 6841 printf (_(" (bytes into file)\n"));
76da6bbe 6842
252b5132 6843 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6844 header->e_flags,
dda8d76d 6845 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6846 printf (_(" Size of this header: %u (bytes)\n"),
6847 header->e_ehsize);
6848 printf (_(" Size of program headers: %u (bytes)\n"),
6849 header->e_phentsize);
6850 printf (_(" Number of program headers: %u"),
6851 header->e_phnum);
dda8d76d
NC
6852 if (filedata->section_headers != NULL
6853 && header->e_phnum == PN_XNUM
6854 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6855 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6856 putc ('\n', stdout);
e8a64888
AM
6857 printf (_(" Size of section headers: %u (bytes)\n"),
6858 header->e_shentsize);
6859 printf (_(" Number of section headers: %u"),
6860 header->e_shnum);
dda8d76d 6861 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6862 {
6863 header->e_shnum = filedata->section_headers[0].sh_size;
6864 printf (" (%u)", header->e_shnum);
6865 }
560f3c1c 6866 putc ('\n', stdout);
e8a64888
AM
6867 printf (_(" Section header string table index: %u"),
6868 header->e_shstrndx);
dda8d76d
NC
6869 if (filedata->section_headers != NULL
6870 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6871 {
6872 header->e_shstrndx = filedata->section_headers[0].sh_link;
6873 printf (" (%u)", header->e_shstrndx);
6874 }
6875 if (header->e_shstrndx != SHN_UNDEF
6876 && header->e_shstrndx >= header->e_shnum)
6877 {
6878 header->e_shstrndx = SHN_UNDEF;
6879 printf (_(" <corrupt: out of range>"));
6880 }
560f3c1c
AM
6881 putc ('\n', stdout);
6882 }
6883
dda8d76d 6884 if (filedata->section_headers != NULL)
560f3c1c 6885 {
dda8d76d
NC
6886 if (header->e_phnum == PN_XNUM
6887 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6888 {
6889 /* Throw away any cached read of PN_XNUM headers. */
6890 free (filedata->program_headers);
6891 filedata->program_headers = NULL;
6892 header->e_phnum = filedata->section_headers[0].sh_info;
6893 }
dda8d76d
NC
6894 if (header->e_shnum == SHN_UNDEF)
6895 header->e_shnum = filedata->section_headers[0].sh_size;
6896 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6897 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6898 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6899 header->e_shstrndx = SHN_UNDEF;
252b5132 6900 }
103f02d3 6901
015dc7e1 6902 return true;
9ea033b2
NC
6903}
6904
dda8d76d
NC
6905/* Read in the program headers from FILEDATA and store them in PHEADERS.
6906 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6907
015dc7e1 6908static bool
dda8d76d 6909get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6910{
2cf0635d
NC
6911 Elf32_External_Phdr * phdrs;
6912 Elf32_External_Phdr * external;
6913 Elf_Internal_Phdr * internal;
b34976b6 6914 unsigned int i;
dda8d76d
NC
6915 unsigned int size = filedata->file_header.e_phentsize;
6916 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6917
6918 /* PR binutils/17531: Cope with unexpected section header sizes. */
6919 if (size == 0 || num == 0)
015dc7e1 6920 return false;
e0a31db1
NC
6921 if (size < sizeof * phdrs)
6922 {
6923 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6924 return false;
e0a31db1
NC
6925 }
6926 if (size > sizeof * phdrs)
6927 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6928
dda8d76d 6929 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6930 size, num, _("program headers"));
6931 if (phdrs == NULL)
015dc7e1 6932 return false;
9ea033b2 6933
91d6fa6a 6934 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6935 i < filedata->file_header.e_phnum;
b34976b6 6936 i++, internal++, external++)
252b5132 6937 {
9ea033b2
NC
6938 internal->p_type = BYTE_GET (external->p_type);
6939 internal->p_offset = BYTE_GET (external->p_offset);
6940 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6941 internal->p_paddr = BYTE_GET (external->p_paddr);
6942 internal->p_filesz = BYTE_GET (external->p_filesz);
6943 internal->p_memsz = BYTE_GET (external->p_memsz);
6944 internal->p_flags = BYTE_GET (external->p_flags);
6945 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6946 }
6947
9ea033b2 6948 free (phdrs);
015dc7e1 6949 return true;
252b5132
RH
6950}
6951
dda8d76d
NC
6952/* Read in the program headers from FILEDATA and store them in PHEADERS.
6953 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6954
015dc7e1 6955static bool
dda8d76d 6956get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6957{
2cf0635d
NC
6958 Elf64_External_Phdr * phdrs;
6959 Elf64_External_Phdr * external;
6960 Elf_Internal_Phdr * internal;
b34976b6 6961 unsigned int i;
dda8d76d
NC
6962 unsigned int size = filedata->file_header.e_phentsize;
6963 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6964
6965 /* PR binutils/17531: Cope with unexpected section header sizes. */
6966 if (size == 0 || num == 0)
015dc7e1 6967 return false;
e0a31db1
NC
6968 if (size < sizeof * phdrs)
6969 {
6970 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6971 return false;
e0a31db1
NC
6972 }
6973 if (size > sizeof * phdrs)
6974 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6975
dda8d76d 6976 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6977 size, num, _("program headers"));
a6e9f9df 6978 if (!phdrs)
015dc7e1 6979 return false;
9ea033b2 6980
91d6fa6a 6981 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6982 i < filedata->file_header.e_phnum;
b34976b6 6983 i++, internal++, external++)
9ea033b2
NC
6984 {
6985 internal->p_type = BYTE_GET (external->p_type);
6986 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6987 internal->p_offset = BYTE_GET (external->p_offset);
6988 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6989 internal->p_paddr = BYTE_GET (external->p_paddr);
6990 internal->p_filesz = BYTE_GET (external->p_filesz);
6991 internal->p_memsz = BYTE_GET (external->p_memsz);
6992 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6993 }
6994
6995 free (phdrs);
015dc7e1 6996 return true;
9ea033b2 6997}
252b5132 6998
32ec8896 6999/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 7000
015dc7e1 7001static bool
dda8d76d 7002get_program_headers (Filedata * filedata)
d93f0186 7003{
2cf0635d 7004 Elf_Internal_Phdr * phdrs;
d93f0186
NC
7005
7006 /* Check cache of prior read. */
dda8d76d 7007 if (filedata->program_headers != NULL)
015dc7e1 7008 return true;
d93f0186 7009
82156ab7
NC
7010 /* Be kind to memory checkers by looking for
7011 e_phnum values which we know must be invalid. */
dda8d76d 7012 if (filedata->file_header.e_phnum
82156ab7 7013 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 7014 >= filedata->file_size)
82156ab7
NC
7015 {
7016 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 7017 filedata->file_header.e_phnum);
015dc7e1 7018 return false;
82156ab7 7019 }
d93f0186 7020
dda8d76d 7021 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 7022 sizeof (Elf_Internal_Phdr));
d93f0186
NC
7023 if (phdrs == NULL)
7024 {
8b73c356 7025 error (_("Out of memory reading %u program headers\n"),
dda8d76d 7026 filedata->file_header.e_phnum);
015dc7e1 7027 return false;
d93f0186
NC
7028 }
7029
7030 if (is_32bit_elf
dda8d76d
NC
7031 ? get_32bit_program_headers (filedata, phdrs)
7032 : get_64bit_program_headers (filedata, phdrs))
d93f0186 7033 {
dda8d76d 7034 filedata->program_headers = phdrs;
015dc7e1 7035 return true;
d93f0186
NC
7036 }
7037
7038 free (phdrs);
015dc7e1 7039 return false;
d93f0186
NC
7040}
7041
93df3340 7042/* Print program header info and locate dynamic section. */
2f62977e 7043
93df3340 7044static void
dda8d76d 7045process_program_headers (Filedata * filedata)
252b5132 7046{
2cf0635d 7047 Elf_Internal_Phdr * segment;
b34976b6 7048 unsigned int i;
1a9ccd70 7049 Elf_Internal_Phdr * previous_load = NULL;
252b5132 7050
dda8d76d 7051 if (filedata->file_header.e_phnum == 0)
252b5132 7052 {
82f2dbf7 7053 /* PR binutils/12467. */
dda8d76d 7054 if (filedata->file_header.e_phoff != 0)
93df3340
AM
7055 warn (_("possibly corrupt ELF header - it has a non-zero program"
7056 " header offset, but no program headers\n"));
82f2dbf7 7057 else if (do_segments)
ca0e11aa
NC
7058 {
7059 if (filedata->is_separate)
7060 printf (_("\nThere are no program headers in linked file '%s'.\n"),
7061 filedata->file_name);
7062 else
7063 printf (_("\nThere are no program headers in this file.\n"));
7064 }
93df3340 7065 goto no_headers;
252b5132
RH
7066 }
7067
7068 if (do_segments && !do_header)
7069 {
ca0e11aa
NC
7070 if (filedata->is_separate)
7071 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 7072 filedata->file_name, get_file_type (filedata));
ca0e11aa 7073 else
93df3340 7074 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 7075 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 7076 filedata->file_header.e_entry);
b8281767
AM
7077 printf (ngettext ("There is %d program header,"
7078 " starting at offset %" PRIu64 "\n",
7079 "There are %d program headers,"
7080 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
7081 filedata->file_header.e_phnum),
7082 filedata->file_header.e_phnum,
625d49fc 7083 filedata->file_header.e_phoff);
252b5132
RH
7084 }
7085
dda8d76d 7086 if (! get_program_headers (filedata))
93df3340 7087 goto no_headers;
103f02d3 7088
252b5132
RH
7089 if (do_segments)
7090 {
dda8d76d 7091 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
7092 printf (_("\nProgram Headers:\n"));
7093 else
7094 printf (_("\nProgram Headers:\n"));
76da6bbe 7095
f7a99963
NC
7096 if (is_32bit_elf)
7097 printf
7098 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
7099 else if (do_wide)
7100 printf
7101 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
7102 else
7103 {
7104 printf
7105 (_(" Type Offset VirtAddr PhysAddr\n"));
7106 printf
7107 (_(" FileSiz MemSiz Flags Align\n"));
7108 }
252b5132
RH
7109 }
7110
26c527e6 7111 uint64_t dynamic_addr = 0;
be7d229a 7112 uint64_t dynamic_size = 0;
dda8d76d
NC
7113 for (i = 0, segment = filedata->program_headers;
7114 i < filedata->file_header.e_phnum;
b34976b6 7115 i++, segment++)
252b5132
RH
7116 {
7117 if (do_segments)
7118 {
dda8d76d 7119 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
7120
7121 if (is_32bit_elf)
7122 {
7123 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7124 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
7125 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
7126 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
7127 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
7128 printf ("%c%c%c ",
7129 (segment->p_flags & PF_R ? 'R' : ' '),
7130 (segment->p_flags & PF_W ? 'W' : ' '),
7131 (segment->p_flags & PF_X ? 'E' : ' '));
7132 printf ("%#lx", (unsigned long) segment->p_align);
7133 }
d974e256
JJ
7134 else if (do_wide)
7135 {
7136 if ((unsigned long) segment->p_offset == segment->p_offset)
7137 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7138 else
7139 {
7140 print_vma (segment->p_offset, FULL_HEX);
7141 putchar (' ');
7142 }
7143
7144 print_vma (segment->p_vaddr, FULL_HEX);
7145 putchar (' ');
7146 print_vma (segment->p_paddr, FULL_HEX);
7147 putchar (' ');
7148
7149 if ((unsigned long) segment->p_filesz == segment->p_filesz)
7150 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
7151 else
7152 {
7153 print_vma (segment->p_filesz, FULL_HEX);
7154 putchar (' ');
7155 }
7156
7157 if ((unsigned long) segment->p_memsz == segment->p_memsz)
7158 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
7159 else
7160 {
f48e6c45 7161 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
7162 }
7163
7164 printf (" %c%c%c ",
7165 (segment->p_flags & PF_R ? 'R' : ' '),
7166 (segment->p_flags & PF_W ? 'W' : ' '),
7167 (segment->p_flags & PF_X ? 'E' : ' '));
7168
7169 if ((unsigned long) segment->p_align == segment->p_align)
7170 printf ("%#lx", (unsigned long) segment->p_align);
7171 else
7172 {
7173 print_vma (segment->p_align, PREFIX_HEX);
7174 }
7175 }
f7a99963
NC
7176 else
7177 {
7178 print_vma (segment->p_offset, FULL_HEX);
7179 putchar (' ');
7180 print_vma (segment->p_vaddr, FULL_HEX);
7181 putchar (' ');
7182 print_vma (segment->p_paddr, FULL_HEX);
7183 printf ("\n ");
7184 print_vma (segment->p_filesz, FULL_HEX);
7185 putchar (' ');
7186 print_vma (segment->p_memsz, FULL_HEX);
7187 printf (" %c%c%c ",
7188 (segment->p_flags & PF_R ? 'R' : ' '),
7189 (segment->p_flags & PF_W ? 'W' : ' '),
7190 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 7191 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 7192 }
252b5132 7193
1a9ccd70
NC
7194 putc ('\n', stdout);
7195 }
f54498b4 7196
252b5132
RH
7197 switch (segment->p_type)
7198 {
1a9ccd70 7199 case PT_LOAD:
502d895c
NC
7200#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
7201 required by the ELF standard, several programs, including the Linux
7202 kernel, make use of non-ordered segments. */
1a9ccd70
NC
7203 if (previous_load
7204 && previous_load->p_vaddr > segment->p_vaddr)
7205 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 7206#endif
1a9ccd70
NC
7207 if (segment->p_memsz < segment->p_filesz)
7208 error (_("the segment's file size is larger than its memory size\n"));
7209 previous_load = segment;
7210 break;
7211
7212 case PT_PHDR:
7213 /* PR 20815 - Verify that the program header is loaded into memory. */
7214 if (i > 0 && previous_load != NULL)
7215 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 7216 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
7217 {
7218 unsigned int j;
7219
dda8d76d 7220 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
7221 {
7222 Elf_Internal_Phdr *load = filedata->program_headers + j;
7223 if (load->p_type == PT_LOAD
7224 && load->p_offset <= segment->p_offset
7225 && (load->p_offset + load->p_filesz
7226 >= segment->p_offset + segment->p_filesz)
7227 && load->p_vaddr <= segment->p_vaddr
7228 && (load->p_vaddr + load->p_filesz
7229 >= segment->p_vaddr + segment->p_filesz))
7230 break;
7231 }
dda8d76d 7232 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
7233 error (_("the PHDR segment is not covered by a LOAD segment\n"));
7234 }
7235 break;
7236
252b5132 7237 case PT_DYNAMIC:
93df3340 7238 if (dynamic_addr)
252b5132
RH
7239 error (_("more than one dynamic segment\n"));
7240
20737c13
AM
7241 /* By default, assume that the .dynamic section is the first
7242 section in the DYNAMIC segment. */
93df3340
AM
7243 dynamic_addr = segment->p_offset;
7244 dynamic_size = segment->p_filesz;
20737c13 7245
b2d38a17
NC
7246 /* Try to locate the .dynamic section. If there is
7247 a section header table, we can easily locate it. */
dda8d76d 7248 if (filedata->section_headers != NULL)
b2d38a17 7249 {
2cf0635d 7250 Elf_Internal_Shdr * sec;
b2d38a17 7251
dda8d76d 7252 sec = find_section (filedata, ".dynamic");
89fac5e3 7253 if (sec == NULL || sec->sh_size == 0)
b2d38a17 7254 {
93df3340
AM
7255 /* A corresponding .dynamic section is expected, but on
7256 IA-64/OpenVMS it is OK for it to be missing. */
7257 if (!is_ia64_vms (filedata))
7258 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
7259 break;
7260 }
7261
42bb2e33 7262 if (sec->sh_type == SHT_NOBITS)
20737c13 7263 {
93df3340
AM
7264 dynamic_addr = 0;
7265 dynamic_size = 0;
20737c13
AM
7266 break;
7267 }
42bb2e33 7268
93df3340
AM
7269 dynamic_addr = sec->sh_offset;
7270 dynamic_size = sec->sh_size;
b2d38a17 7271
8ac10c5b
L
7272 /* The PT_DYNAMIC segment, which is used by the run-time
7273 loader, should exactly match the .dynamic section. */
7274 if (do_checks
93df3340
AM
7275 && (dynamic_addr != segment->p_offset
7276 || dynamic_size != segment->p_filesz))
8ac10c5b
L
7277 warn (_("\
7278the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 7279 }
39e224f6
MW
7280
7281 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7282 segment. Check this after matching against the section headers
7283 so we don't warn on debuginfo file (which have NOBITS .dynamic
7284 sections). */
93df3340
AM
7285 if (dynamic_addr > filedata->file_size
7286 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
7287 {
7288 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
7289 dynamic_addr = 0;
7290 dynamic_size = 0;
39e224f6 7291 }
252b5132
RH
7292 break;
7293
7294 case PT_INTERP:
13acb58d
AM
7295 if (segment->p_offset >= filedata->file_size
7296 || segment->p_filesz > filedata->file_size - segment->p_offset
7297 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
7298 || fseek64 (filedata->handle,
7299 filedata->archive_file_offset + segment->p_offset,
7300 SEEK_SET))
252b5132
RH
7301 error (_("Unable to find program interpreter name\n"));
7302 else
7303 {
13acb58d
AM
7304 size_t len = segment->p_filesz;
7305 free (filedata->program_interpreter);
7306 filedata->program_interpreter = xmalloc (len + 1);
7307 len = fread (filedata->program_interpreter, 1, len,
7308 filedata->handle);
7309 filedata->program_interpreter[len] = 0;
252b5132
RH
7310
7311 if (do_segments)
f54498b4 7312 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 7313 filedata->program_interpreter);
252b5132
RH
7314 }
7315 break;
7316 }
252b5132
RH
7317 }
7318
dda8d76d
NC
7319 if (do_segments
7320 && filedata->section_headers != NULL
7321 && filedata->string_table != NULL)
252b5132
RH
7322 {
7323 printf (_("\n Section to Segment mapping:\n"));
7324 printf (_(" Segment Sections...\n"));
7325
dda8d76d 7326 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 7327 {
9ad5cbcf 7328 unsigned int j;
2cf0635d 7329 Elf_Internal_Shdr * section;
252b5132 7330
dda8d76d
NC
7331 segment = filedata->program_headers + i;
7332 section = filedata->section_headers + 1;
252b5132
RH
7333
7334 printf (" %2.2d ", i);
7335
dda8d76d 7336 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 7337 {
f4638467
AM
7338 if (!ELF_TBSS_SPECIAL (section, segment)
7339 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 7340 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
7341 }
7342
7343 putc ('\n',stdout);
7344 }
7345 }
7346
93df3340
AM
7347 filedata->dynamic_addr = dynamic_addr;
7348 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7349 return;
7350
7351 no_headers:
7352 filedata->dynamic_addr = 0;
7353 filedata->dynamic_size = 1;
252b5132
RH
7354}
7355
7356
d93f0186
NC
7357/* Find the file offset corresponding to VMA by using the program headers. */
7358
26c527e6 7359static int64_t
625d49fc 7360offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 7361{
2cf0635d 7362 Elf_Internal_Phdr * seg;
d93f0186 7363
dda8d76d 7364 if (! get_program_headers (filedata))
d93f0186
NC
7365 {
7366 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7367 return (long) vma;
7368 }
7369
dda8d76d
NC
7370 for (seg = filedata->program_headers;
7371 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
7372 ++seg)
7373 {
7374 if (seg->p_type != PT_LOAD)
7375 continue;
7376
7377 if (vma >= (seg->p_vaddr & -seg->p_align)
7378 && vma + size <= seg->p_vaddr + seg->p_filesz)
7379 return vma - seg->p_vaddr + seg->p_offset;
7380 }
7381
26c527e6
AM
7382 warn (_("Virtual address %#" PRIx64
7383 " not located in any PT_LOAD segment.\n"), vma);
7384 return vma;
d93f0186
NC
7385}
7386
7387
dda8d76d
NC
7388/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7389 If PROBE is true, this is just a probe and we do not generate any error
7390 messages if the load fails. */
049b0c3a 7391
015dc7e1
AM
7392static bool
7393get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 7394{
2cf0635d
NC
7395 Elf32_External_Shdr * shdrs;
7396 Elf_Internal_Shdr * internal;
dda8d76d
NC
7397 unsigned int i;
7398 unsigned int size = filedata->file_header.e_shentsize;
7399 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7400
7401 /* PR binutils/17531: Cope with unexpected section header sizes. */
7402 if (size == 0 || num == 0)
015dc7e1 7403 return false;
907b52f4
NC
7404
7405 /* The section header cannot be at the start of the file - that is
7406 where the ELF file header is located. A file with absolutely no
7407 sections in it will use a shoff of 0. */
7408 if (filedata->file_header.e_shoff == 0)
7409 return false;
7410
049b0c3a
NC
7411 if (size < sizeof * shdrs)
7412 {
7413 if (! probe)
7414 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7415 return false;
049b0c3a
NC
7416 }
7417 if (!probe && size > sizeof * shdrs)
7418 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 7419
dda8d76d 7420 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
7421 size, num,
7422 probe ? NULL : _("section headers"));
7423 if (shdrs == NULL)
015dc7e1 7424 return false;
252b5132 7425
dda8d76d
NC
7426 filedata->section_headers = (Elf_Internal_Shdr *)
7427 cmalloc (num, sizeof (Elf_Internal_Shdr));
7428 if (filedata->section_headers == NULL)
252b5132 7429 {
049b0c3a 7430 if (!probe)
8b73c356 7431 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7432 free (shdrs);
015dc7e1 7433 return false;
252b5132
RH
7434 }
7435
dda8d76d 7436 for (i = 0, internal = filedata->section_headers;
560f3c1c 7437 i < num;
b34976b6 7438 i++, internal++)
252b5132
RH
7439 {
7440 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7441 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7442 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7443 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7444 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7445 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7446 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7447 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7448 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7449 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
7450 if (!probe && internal->sh_link > num)
7451 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7452 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7453 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
7454 }
7455
7456 free (shdrs);
015dc7e1 7457 return true;
252b5132
RH
7458}
7459
dda8d76d
NC
7460/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7461
015dc7e1
AM
7462static bool
7463get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 7464{
dda8d76d
NC
7465 Elf64_External_Shdr * shdrs;
7466 Elf_Internal_Shdr * internal;
7467 unsigned int i;
7468 unsigned int size = filedata->file_header.e_shentsize;
7469 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7470
7471 /* PR binutils/17531: Cope with unexpected section header sizes. */
7472 if (size == 0 || num == 0)
015dc7e1 7473 return false;
dda8d76d 7474
907b52f4
NC
7475 /* The section header cannot be at the start of the file - that is
7476 where the ELF file header is located. A file with absolutely no
7477 sections in it will use a shoff of 0. */
7478 if (filedata->file_header.e_shoff == 0)
7479 return false;
7480
049b0c3a
NC
7481 if (size < sizeof * shdrs)
7482 {
7483 if (! probe)
7484 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7485 return false;
049b0c3a 7486 }
dda8d76d 7487
049b0c3a
NC
7488 if (! probe && size > sizeof * shdrs)
7489 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 7490
dda8d76d
NC
7491 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7492 filedata->file_header.e_shoff,
049b0c3a
NC
7493 size, num,
7494 probe ? NULL : _("section headers"));
7495 if (shdrs == NULL)
015dc7e1 7496 return false;
9ea033b2 7497
dda8d76d
NC
7498 filedata->section_headers = (Elf_Internal_Shdr *)
7499 cmalloc (num, sizeof (Elf_Internal_Shdr));
7500 if (filedata->section_headers == NULL)
9ea033b2 7501 {
049b0c3a 7502 if (! probe)
8b73c356 7503 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7504 free (shdrs);
015dc7e1 7505 return false;
9ea033b2
NC
7506 }
7507
dda8d76d 7508 for (i = 0, internal = filedata->section_headers;
560f3c1c 7509 i < num;
b34976b6 7510 i++, internal++)
9ea033b2
NC
7511 {
7512 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7513 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7514 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7515 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7516 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7517 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7518 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7519 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7520 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7521 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7522 if (!probe && internal->sh_link > num)
7523 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7524 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7525 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7526 }
7527
7528 free (shdrs);
015dc7e1 7529 return true;
9ea033b2
NC
7530}
7531
4de91c10
AM
7532static bool
7533get_section_headers (Filedata *filedata, bool probe)
7534{
7535 if (filedata->section_headers != NULL)
7536 return true;
7537
4de91c10
AM
7538 if (is_32bit_elf)
7539 return get_32bit_section_headers (filedata, probe);
7540 else
7541 return get_64bit_section_headers (filedata, probe);
7542}
7543
252b5132 7544static Elf_Internal_Sym *
26c527e6
AM
7545get_32bit_elf_symbols (Filedata *filedata,
7546 Elf_Internal_Shdr *section,
7547 uint64_t *num_syms_return)
252b5132 7548{
26c527e6 7549 uint64_t number = 0;
dd24e3da 7550 Elf32_External_Sym * esyms = NULL;
ba5cdace 7551 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7552 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7553 Elf_Internal_Sym * psym;
b34976b6 7554 unsigned int j;
e3d39609 7555 elf_section_list * entry;
252b5132 7556
c9c1d674
EG
7557 if (section->sh_size == 0)
7558 {
7559 if (num_syms_return != NULL)
7560 * num_syms_return = 0;
7561 return NULL;
7562 }
7563
dd24e3da 7564 /* Run some sanity checks first. */
c9c1d674 7565 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7566 {
26c527e6 7567 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7568 printable_section_name (filedata, section),
26c527e6 7569 section->sh_entsize);
ba5cdace 7570 goto exit_point;
dd24e3da
NC
7571 }
7572
dda8d76d 7573 if (section->sh_size > filedata->file_size)
f54498b4 7574 {
26c527e6 7575 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7576 printable_section_name (filedata, section),
26c527e6 7577 section->sh_size);
f54498b4
NC
7578 goto exit_point;
7579 }
7580
dd24e3da
NC
7581 number = section->sh_size / section->sh_entsize;
7582
7583 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7584 {
26c527e6
AM
7585 error (_("Size (%#" PRIx64 ") of section %s "
7586 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7587 section->sh_size,
dda8d76d 7588 printable_section_name (filedata, section),
26c527e6 7589 section->sh_entsize);
ba5cdace 7590 goto exit_point;
dd24e3da
NC
7591 }
7592
dda8d76d 7593 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7594 section->sh_size, _("symbols"));
dd24e3da 7595 if (esyms == NULL)
ba5cdace 7596 goto exit_point;
252b5132 7597
e3d39609 7598 shndx = NULL;
978c4450 7599 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7600 {
26c527e6 7601 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7602 continue;
7603
7604 if (shndx != NULL)
7605 {
7606 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7607 free (shndx);
7608 }
7609
7610 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7611 entry->hdr->sh_offset,
7612 1, entry->hdr->sh_size,
7613 _("symbol table section indices"));
7614 if (shndx == NULL)
7615 goto exit_point;
7616
7617 /* PR17531: file: heap-buffer-overflow */
7618 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7619 {
26c527e6 7620 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7621 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7622 entry->hdr->sh_size,
7623 section->sh_size);
e3d39609 7624 goto exit_point;
c9c1d674 7625 }
e3d39609 7626 }
9ad5cbcf 7627
3f5e193b 7628 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7629
7630 if (isyms == NULL)
7631 {
26c527e6 7632 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7633 goto exit_point;
252b5132
RH
7634 }
7635
dd24e3da 7636 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7637 {
7638 psym->st_name = BYTE_GET (esyms[j].st_name);
7639 psym->st_value = BYTE_GET (esyms[j].st_value);
7640 psym->st_size = BYTE_GET (esyms[j].st_size);
7641 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7642 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7643 psym->st_shndx
7644 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7645 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7646 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7647 psym->st_info = BYTE_GET (esyms[j].st_info);
7648 psym->st_other = BYTE_GET (esyms[j].st_other);
7649 }
7650
dd24e3da 7651 exit_point:
e3d39609
NC
7652 free (shndx);
7653 free (esyms);
252b5132 7654
ba5cdace
NC
7655 if (num_syms_return != NULL)
7656 * num_syms_return = isyms == NULL ? 0 : number;
7657
252b5132
RH
7658 return isyms;
7659}
7660
9ea033b2 7661static Elf_Internal_Sym *
26c527e6
AM
7662get_64bit_elf_symbols (Filedata *filedata,
7663 Elf_Internal_Shdr *section,
7664 uint64_t *num_syms_return)
9ea033b2 7665{
26c527e6 7666 uint64_t number = 0;
ba5cdace
NC
7667 Elf64_External_Sym * esyms = NULL;
7668 Elf_External_Sym_Shndx * shndx = NULL;
7669 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7670 Elf_Internal_Sym * psym;
b34976b6 7671 unsigned int j;
e3d39609 7672 elf_section_list * entry;
9ea033b2 7673
c9c1d674
EG
7674 if (section->sh_size == 0)
7675 {
7676 if (num_syms_return != NULL)
7677 * num_syms_return = 0;
7678 return NULL;
7679 }
7680
dd24e3da 7681 /* Run some sanity checks first. */
c9c1d674 7682 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7683 {
26c527e6 7684 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7685 printable_section_name (filedata, section),
26c527e6 7686 section->sh_entsize);
ba5cdace 7687 goto exit_point;
dd24e3da
NC
7688 }
7689
dda8d76d 7690 if (section->sh_size > filedata->file_size)
f54498b4 7691 {
26c527e6 7692 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7693 printable_section_name (filedata, section),
26c527e6 7694 section->sh_size);
f54498b4
NC
7695 goto exit_point;
7696 }
7697
dd24e3da
NC
7698 number = section->sh_size / section->sh_entsize;
7699
7700 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7701 {
26c527e6
AM
7702 error (_("Size (%#" PRIx64 ") of section %s "
7703 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7704 section->sh_size,
dda8d76d 7705 printable_section_name (filedata, section),
26c527e6 7706 section->sh_entsize);
ba5cdace 7707 goto exit_point;
dd24e3da
NC
7708 }
7709
dda8d76d 7710 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7711 section->sh_size, _("symbols"));
a6e9f9df 7712 if (!esyms)
ba5cdace 7713 goto exit_point;
9ea033b2 7714
e3d39609 7715 shndx = NULL;
978c4450 7716 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7717 {
26c527e6 7718 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7719 continue;
7720
7721 if (shndx != NULL)
7722 {
7723 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7724 free (shndx);
c9c1d674 7725 }
e3d39609
NC
7726
7727 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7728 entry->hdr->sh_offset,
7729 1, entry->hdr->sh_size,
7730 _("symbol table section indices"));
7731 if (shndx == NULL)
7732 goto exit_point;
7733
7734 /* PR17531: file: heap-buffer-overflow */
7735 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7736 {
26c527e6 7737 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7738 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7739 entry->hdr->sh_size,
7740 section->sh_size);
e3d39609
NC
7741 goto exit_point;
7742 }
7743 }
9ad5cbcf 7744
3f5e193b 7745 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7746
7747 if (isyms == NULL)
7748 {
26c527e6 7749 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7750 goto exit_point;
9ea033b2
NC
7751 }
7752
ba5cdace 7753 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7754 {
7755 psym->st_name = BYTE_GET (esyms[j].st_name);
7756 psym->st_info = BYTE_GET (esyms[j].st_info);
7757 psym->st_other = BYTE_GET (esyms[j].st_other);
7758 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7759
4fbb74a6 7760 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7761 psym->st_shndx
7762 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7763 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7764 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7765
66543521
AM
7766 psym->st_value = BYTE_GET (esyms[j].st_value);
7767 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7768 }
7769
ba5cdace 7770 exit_point:
e3d39609
NC
7771 free (shndx);
7772 free (esyms);
ba5cdace
NC
7773
7774 if (num_syms_return != NULL)
7775 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7776
7777 return isyms;
7778}
7779
4de91c10
AM
7780static Elf_Internal_Sym *
7781get_elf_symbols (Filedata *filedata,
7782 Elf_Internal_Shdr *section,
26c527e6 7783 uint64_t *num_syms_return)
4de91c10
AM
7784{
7785 if (is_32bit_elf)
7786 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7787 else
7788 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7789}
7790
d1133906 7791static const char *
625d49fc 7792get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7793{
5477e8a0 7794 static char buff[1024];
2cf0635d 7795 char * p = buff;
32ec8896
NC
7796 unsigned int field_size = is_32bit_elf ? 8 : 16;
7797 signed int sindex;
7798 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7799 uint64_t os_flags = 0;
7800 uint64_t proc_flags = 0;
7801 uint64_t unknown_flags = 0;
148b93f2 7802 static const struct
5477e8a0 7803 {
2cf0635d 7804 const char * str;
32ec8896 7805 unsigned int len;
5477e8a0
L
7806 }
7807 flags [] =
7808 {
cfcac11d
NC
7809 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7810 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7811 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7812 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7813 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7814 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7815 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7816 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7817 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7818 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7819 /* IA-64 specific. */
7820 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7821 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7822 /* IA-64 OpenVMS specific. */
7823 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7824 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7825 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7826 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7827 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7828 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7829 /* Generic. */
cfcac11d 7830 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7831 /* SPARC specific. */
77115a4a 7832 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7833 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7834 /* ARM specific. */
7835 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7836 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7837 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7838 /* GNU specific. */
7839 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7840 /* VLE specific. */
7841 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7842 /* GNU specific. */
7843 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7844 };
7845
7846 if (do_section_details)
f8c4789c
AM
7847 p += sprintf (p, "[%*.*lx]: ",
7848 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7849
d1133906
NC
7850 while (sh_flags)
7851 {
625d49fc 7852 uint64_t flag;
d1133906
NC
7853
7854 flag = sh_flags & - sh_flags;
7855 sh_flags &= ~ flag;
76da6bbe 7856
5477e8a0 7857 if (do_section_details)
d1133906 7858 {
5477e8a0
L
7859 switch (flag)
7860 {
91d6fa6a
NC
7861 case SHF_WRITE: sindex = 0; break;
7862 case SHF_ALLOC: sindex = 1; break;
7863 case SHF_EXECINSTR: sindex = 2; break;
7864 case SHF_MERGE: sindex = 3; break;
7865 case SHF_STRINGS: sindex = 4; break;
7866 case SHF_INFO_LINK: sindex = 5; break;
7867 case SHF_LINK_ORDER: sindex = 6; break;
7868 case SHF_OS_NONCONFORMING: sindex = 7; break;
7869 case SHF_GROUP: sindex = 8; break;
7870 case SHF_TLS: sindex = 9; break;
18ae9cc1 7871 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7872 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7873
5477e8a0 7874 default:
91d6fa6a 7875 sindex = -1;
dda8d76d 7876 switch (filedata->file_header.e_machine)
148b93f2 7877 {
cfcac11d 7878 case EM_IA_64:
148b93f2 7879 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7880 sindex = 10;
148b93f2 7881 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7882 sindex = 11;
dda8d76d 7883 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7884 switch (flag)
7885 {
91d6fa6a
NC
7886 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7887 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7888 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7889 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7890 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7891 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7892 default: break;
7893 }
cfcac11d
NC
7894 break;
7895
caa83f8b 7896 case EM_386:
22abe556 7897 case EM_IAMCU:
caa83f8b 7898 case EM_X86_64:
7f502d6c 7899 case EM_L1OM:
7a9068fe 7900 case EM_K1OM:
cfcac11d
NC
7901 case EM_OLD_SPARCV9:
7902 case EM_SPARC32PLUS:
7903 case EM_SPARCV9:
7904 case EM_SPARC:
18ae9cc1 7905 if (flag == SHF_ORDERED)
91d6fa6a 7906 sindex = 19;
cfcac11d 7907 break;
ac4c9b04
MG
7908
7909 case EM_ARM:
7910 switch (flag)
7911 {
7912 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7913 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7914 case SHF_COMDEF: sindex = 23; break;
7915 default: break;
7916 }
7917 break;
83eef883
AFB
7918 case EM_PPC:
7919 if (flag == SHF_PPC_VLE)
7920 sindex = 25;
7921 break;
99fabbc9
JL
7922 default:
7923 break;
7924 }
ac4c9b04 7925
99fabbc9
JL
7926 switch (filedata->file_header.e_ident[EI_OSABI])
7927 {
7928 case ELFOSABI_GNU:
7929 case ELFOSABI_FREEBSD:
7930 if (flag == SHF_GNU_RETAIN)
7931 sindex = 26;
7932 /* Fall through */
7933 case ELFOSABI_NONE:
7934 if (flag == SHF_GNU_MBIND)
7935 /* We should not recognize SHF_GNU_MBIND for
7936 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7937 not set the EI_OSABI header byte. */
7938 sindex = 24;
7939 break;
cfcac11d
NC
7940 default:
7941 break;
148b93f2 7942 }
99fabbc9 7943 break;
5477e8a0
L
7944 }
7945
91d6fa6a 7946 if (sindex != -1)
5477e8a0 7947 {
8d5ff12c
L
7948 if (p != buff + field_size + 4)
7949 {
7950 if (size < (10 + 2))
bee0ee85
NC
7951 {
7952 warn (_("Internal error: not enough buffer room for section flag info"));
7953 return _("<unknown>");
7954 }
8d5ff12c
L
7955 size -= 2;
7956 *p++ = ',';
7957 *p++ = ' ';
7958 }
7959
91d6fa6a
NC
7960 size -= flags [sindex].len;
7961 p = stpcpy (p, flags [sindex].str);
5477e8a0 7962 }
3b22753a 7963 else if (flag & SHF_MASKOS)
8d5ff12c 7964 os_flags |= flag;
d1133906 7965 else if (flag & SHF_MASKPROC)
8d5ff12c 7966 proc_flags |= flag;
d1133906 7967 else
8d5ff12c 7968 unknown_flags |= flag;
5477e8a0
L
7969 }
7970 else
7971 {
7972 switch (flag)
7973 {
7974 case SHF_WRITE: *p = 'W'; break;
7975 case SHF_ALLOC: *p = 'A'; break;
7976 case SHF_EXECINSTR: *p = 'X'; break;
7977 case SHF_MERGE: *p = 'M'; break;
7978 case SHF_STRINGS: *p = 'S'; break;
7979 case SHF_INFO_LINK: *p = 'I'; break;
7980 case SHF_LINK_ORDER: *p = 'L'; break;
7981 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7982 case SHF_GROUP: *p = 'G'; break;
7983 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7984 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7985 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7986
7987 default:
dda8d76d
NC
7988 if ((filedata->file_header.e_machine == EM_X86_64
7989 || filedata->file_header.e_machine == EM_L1OM
7990 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7991 && flag == SHF_X86_64_LARGE)
7992 *p = 'l';
dda8d76d 7993 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7994 && flag == SHF_ARM_PURECODE)
99fabbc9 7995 *p = 'y';
dda8d76d 7996 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7997 && flag == SHF_PPC_VLE)
99fabbc9 7998 *p = 'v';
5477e8a0
L
7999 else if (flag & SHF_MASKOS)
8000 {
99fabbc9
JL
8001 switch (filedata->file_header.e_ident[EI_OSABI])
8002 {
8003 case ELFOSABI_GNU:
8004 case ELFOSABI_FREEBSD:
8005 if (flag == SHF_GNU_RETAIN)
8006 {
8007 *p = 'R';
8008 break;
8009 }
8010 /* Fall through */
8011 case ELFOSABI_NONE:
8012 if (flag == SHF_GNU_MBIND)
8013 {
8014 /* We should not recognize SHF_GNU_MBIND for
8015 ELFOSABI_NONE, but binutils as of 2019-07-23 did
8016 not set the EI_OSABI header byte. */
8017 *p = 'D';
8018 break;
8019 }
8020 /* Fall through */
8021 default:
8022 *p = 'o';
8023 sh_flags &= ~SHF_MASKOS;
8024 break;
8025 }
5477e8a0
L
8026 }
8027 else if (flag & SHF_MASKPROC)
8028 {
8029 *p = 'p';
8030 sh_flags &= ~ SHF_MASKPROC;
8031 }
8032 else
8033 *p = 'x';
8034 break;
8035 }
8036 p++;
d1133906
NC
8037 }
8038 }
76da6bbe 8039
8d5ff12c
L
8040 if (do_section_details)
8041 {
8042 if (os_flags)
8043 {
8d5ff12c
L
8044 if (p != buff + field_size + 4)
8045 {
f8c4789c 8046 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
8047 {
8048 warn (_("Internal error: not enough buffer room for section flag info"));
8049 return _("<unknown>");
8050 }
8d5ff12c
L
8051 size -= 2;
8052 *p++ = ',';
8053 *p++ = ' ';
8054 }
f8c4789c
AM
8055 size -= 5 + field_size;
8056 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
8057 (unsigned long) os_flags);
8d5ff12c
L
8058 }
8059 if (proc_flags)
8060 {
8d5ff12c
L
8061 if (p != buff + field_size + 4)
8062 {
f8c4789c 8063 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
8064 {
8065 warn (_("Internal error: not enough buffer room for section flag info"));
8066 return _("<unknown>");
8067 }
8d5ff12c
L
8068 size -= 2;
8069 *p++ = ',';
8070 *p++ = ' ';
8071 }
f8c4789c
AM
8072 size -= 7 + field_size;
8073 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
8074 (unsigned long) proc_flags);
8d5ff12c
L
8075 }
8076 if (unknown_flags)
8077 {
8d5ff12c
L
8078 if (p != buff + field_size + 4)
8079 {
f8c4789c 8080 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
8081 {
8082 warn (_("Internal error: not enough buffer room for section flag info"));
8083 return _("<unknown>");
8084 }
8d5ff12c
L
8085 size -= 2;
8086 *p++ = ',';
8087 *p++ = ' ';
8088 }
f8c4789c
AM
8089 size -= 10 + field_size;
8090 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8091 (unsigned long) unknown_flags);
8d5ff12c
L
8092 }
8093 }
8094
e9e44622 8095 *p = '\0';
d1133906
NC
8096 return buff;
8097}
8098
5844b465 8099static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
8100get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
8101 uint64_t size)
77115a4a
L
8102{
8103 if (is_32bit_elf)
8104 {
8105 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 8106
ebdf1ebf
NC
8107 if (size < sizeof (* echdr))
8108 {
8109 error (_("Compressed section is too small even for a compression header\n"));
8110 return 0;
8111 }
8112
77115a4a
L
8113 chdr->ch_type = BYTE_GET (echdr->ch_type);
8114 chdr->ch_size = BYTE_GET (echdr->ch_size);
8115 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8116 return sizeof (*echdr);
8117 }
8118 else
8119 {
8120 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 8121
ebdf1ebf
NC
8122 if (size < sizeof (* echdr))
8123 {
8124 error (_("Compressed section is too small even for a compression header\n"));
8125 return 0;
8126 }
8127
77115a4a
L
8128 chdr->ch_type = BYTE_GET (echdr->ch_type);
8129 chdr->ch_size = BYTE_GET (echdr->ch_size);
8130 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8131 return sizeof (*echdr);
8132 }
8133}
8134
015dc7e1 8135static bool
dda8d76d 8136process_section_headers (Filedata * filedata)
252b5132 8137{
2cf0635d 8138 Elf_Internal_Shdr * section;
b34976b6 8139 unsigned int i;
252b5132 8140
dda8d76d 8141 if (filedata->file_header.e_shnum == 0)
252b5132 8142 {
82f2dbf7 8143 /* PR binutils/12467. */
dda8d76d 8144 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
8145 {
8146 warn (_("possibly corrupt ELF file header - it has a non-zero"
8147 " section header offset, but no section headers\n"));
015dc7e1 8148 return false;
32ec8896 8149 }
82f2dbf7 8150 else if (do_sections)
252b5132
RH
8151 printf (_("\nThere are no sections in this file.\n"));
8152
015dc7e1 8153 return true;
252b5132
RH
8154 }
8155
8156 if (do_sections && !do_header)
ca0e11aa
NC
8157 {
8158 if (filedata->is_separate && process_links)
8159 printf (_("In linked file '%s': "), filedata->file_name);
8160 if (! filedata->is_separate || process_links)
8161 printf (ngettext ("There is %d section header, "
26c527e6 8162 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 8163 "There are %d section headers, "
26c527e6 8164 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
8165 filedata->file_header.e_shnum),
8166 filedata->file_header.e_shnum,
26c527e6 8167 filedata->file_header.e_shoff);
ca0e11aa 8168 }
252b5132 8169
4de91c10
AM
8170 if (!get_section_headers (filedata, false))
8171 return false;
252b5132
RH
8172
8173 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
8174 if (filedata->file_header.e_shstrndx != SHN_UNDEF
8175 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 8176 {
dda8d76d 8177 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 8178
c256ffe7
JJ
8179 if (section->sh_size != 0)
8180 {
dda8d76d
NC
8181 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
8182 1, section->sh_size,
8183 _("string table"));
0de14b54 8184
dda8d76d 8185 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 8186 }
252b5132
RH
8187 }
8188
8189 /* Scan the sections for the dynamic symbol table
e3c8793a 8190 and dynamic string table and debug sections. */
89fac5e3 8191 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 8192 switch (filedata->file_header.e_machine)
89fac5e3
RS
8193 {
8194 case EM_MIPS:
8195 case EM_MIPS_RS3_LE:
8196 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
8197 FDE addresses. However, the ABI also has a semi-official ILP32
8198 variant for which the normal FDE address size rules apply.
8199
8200 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
8201 section, where XX is the size of longs in bits. Unfortunately,
8202 earlier compilers provided no way of distinguishing ILP32 objects
8203 from LP64 objects, so if there's any doubt, we should assume that
8204 the official LP64 form is being used. */
d173146d 8205 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 8206 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
8207 eh_addr_size = 8;
8208 break;
0f56a26a
DD
8209
8210 case EM_H8_300:
8211 case EM_H8_300H:
dda8d76d 8212 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
8213 {
8214 case E_H8_MACH_H8300:
8215 case E_H8_MACH_H8300HN:
8216 case E_H8_MACH_H8300SN:
8217 case E_H8_MACH_H8300SXN:
8218 eh_addr_size = 2;
8219 break;
8220 case E_H8_MACH_H8300H:
8221 case E_H8_MACH_H8300S:
8222 case E_H8_MACH_H8300SX:
8223 eh_addr_size = 4;
8224 break;
8225 }
f4236fe4
DD
8226 break;
8227
ff7eeb89 8228 case EM_M32C_OLD:
f4236fe4 8229 case EM_M32C:
dda8d76d 8230 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
8231 {
8232 case EF_M32C_CPU_M16C:
8233 eh_addr_size = 2;
8234 break;
8235 }
8236 break;
89fac5e3
RS
8237 }
8238
76ca31c0
NC
8239#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
8240 do \
8241 { \
be7d229a 8242 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 8243 if (section->sh_entsize != expected_entsize) \
9dd3a467 8244 { \
f493c217 8245 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 8246 i, section->sh_entsize); \
f493c217 8247 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 8248 expected_entsize); \
9dd3a467 8249 section->sh_entsize = expected_entsize; \
76ca31c0
NC
8250 } \
8251 } \
08d8fa11 8252 while (0)
9dd3a467
NC
8253
8254#define CHECK_ENTSIZE(section, i, type) \
1b513401 8255 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
8256 sizeof (Elf64_External_##type))
8257
dda8d76d
NC
8258 for (i = 0, section = filedata->section_headers;
8259 i < filedata->file_header.e_shnum;
b34976b6 8260 i++, section++)
252b5132 8261 {
b6ac461a 8262 const char *name = printable_section_name (filedata, section);
252b5132 8263
1b513401
NC
8264 /* Run some sanity checks on the headers and
8265 possibly fill in some file data as well. */
8266 switch (section->sh_type)
252b5132 8267 {
1b513401 8268 case SHT_DYNSYM:
978c4450 8269 if (filedata->dynamic_symbols != NULL)
252b5132
RH
8270 {
8271 error (_("File contains multiple dynamic symbol tables\n"));
8272 continue;
8273 }
8274
08d8fa11 8275 CHECK_ENTSIZE (section, i, Sym);
978c4450 8276 filedata->dynamic_symbols
4de91c10 8277 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 8278 filedata->dynamic_symtab_section = section;
1b513401
NC
8279 break;
8280
8281 case SHT_STRTAB:
8282 if (streq (name, ".dynstr"))
252b5132 8283 {
1b513401
NC
8284 if (filedata->dynamic_strings != NULL)
8285 {
8286 error (_("File contains multiple dynamic string tables\n"));
8287 continue;
8288 }
8289
8290 filedata->dynamic_strings
8291 = (char *) get_data (NULL, filedata, section->sh_offset,
8292 1, section->sh_size, _("dynamic strings"));
8293 filedata->dynamic_strings_length
8294 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 8295 filedata->dynamic_strtab_section = section;
252b5132 8296 }
1b513401
NC
8297 break;
8298
8299 case SHT_SYMTAB_SHNDX:
8300 {
8301 elf_section_list * entry = xmalloc (sizeof * entry);
8302
8303 entry->hdr = section;
8304 entry->next = filedata->symtab_shndx_list;
8305 filedata->symtab_shndx_list = entry;
8306 }
8307 break;
8308
8309 case SHT_SYMTAB:
8310 CHECK_ENTSIZE (section, i, Sym);
8311 break;
8312
8313 case SHT_GROUP:
8314 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8315 break;
252b5132 8316
1b513401
NC
8317 case SHT_REL:
8318 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 8319 if (do_checks && section->sh_size == 0)
1b513401
NC
8320 warn (_("Section '%s': zero-sized relocation section\n"), name);
8321 break;
8322
8323 case SHT_RELA:
8324 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 8325 if (do_checks && section->sh_size == 0)
1b513401
NC
8326 warn (_("Section '%s': zero-sized relocation section\n"), name);
8327 break;
8328
682351b9
AM
8329 case SHT_RELR:
8330 CHECK_ENTSIZE (section, i, Relr);
8331 break;
8332
1b513401
NC
8333 case SHT_NOTE:
8334 case SHT_PROGBITS:
546cb2d8
NC
8335 /* Having a zero sized section is not illegal according to the
8336 ELF standard, but it might be an indication that something
8337 is wrong. So issue a warning if we are running in lint mode. */
8338 if (do_checks && section->sh_size == 0)
1b513401
NC
8339 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8340 break;
8341
8342 default:
8343 break;
8344 }
8345
8346 if ((do_debugging || do_debug_info || do_debug_abbrevs
8347 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8348 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
8349 || do_debug_str || do_debug_str_offsets || do_debug_loc
8350 || do_debug_ranges
1b513401 8351 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
8352 && (startswith (name, ".debug_")
8353 || startswith (name, ".zdebug_")))
252b5132 8354 {
1b315056
CS
8355 if (name[1] == 'z')
8356 name += sizeof (".zdebug_") - 1;
8357 else
8358 name += sizeof (".debug_") - 1;
252b5132
RH
8359
8360 if (do_debugging
24d127aa
ML
8361 || (do_debug_info && startswith (name, "info"))
8362 || (do_debug_info && startswith (name, "types"))
8363 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 8364 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
8365 || (do_debug_lines && startswith (name, "line."))
8366 || (do_debug_pubnames && startswith (name, "pubnames"))
8367 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8368 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8369 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8370 || (do_debug_aranges && startswith (name, "aranges"))
8371 || (do_debug_ranges && startswith (name, "ranges"))
8372 || (do_debug_ranges && startswith (name, "rnglists"))
8373 || (do_debug_frames && startswith (name, "frame"))
8374 || (do_debug_macinfo && startswith (name, "macinfo"))
8375 || (do_debug_macinfo && startswith (name, "macro"))
8376 || (do_debug_str && startswith (name, "str"))
8377 || (do_debug_links && startswith (name, "sup"))
8378 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8379 || (do_debug_loc && startswith (name, "loc"))
8380 || (do_debug_loc && startswith (name, "loclists"))
8381 || (do_debug_addr && startswith (name, "addr"))
8382 || (do_debug_cu_index && startswith (name, "cu_index"))
8383 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 8384 )
6431e409 8385 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 8386 }
a262ae96 8387 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 8388 else if ((do_debugging || do_debug_info)
24d127aa 8389 && startswith (name, ".gnu.linkonce.wi."))
6431e409 8390 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 8391 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 8392 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
1878f44b
NC
8393 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8394 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
8395 else if (do_gdb_index && (streq (name, ".gdb_index")
8396 || streq (name, ".debug_names")))
6431e409 8397 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
8398 /* Trace sections for Itanium VMS. */
8399 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8400 || do_trace_aranges)
24d127aa 8401 && startswith (name, ".trace_"))
6f875884
TG
8402 {
8403 name += sizeof (".trace_") - 1;
8404
8405 if (do_debugging
8406 || (do_trace_info && streq (name, "info"))
8407 || (do_trace_abbrevs && streq (name, "abbrev"))
8408 || (do_trace_aranges && streq (name, "aranges"))
8409 )
6431e409 8410 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 8411 }
dda8d76d 8412 else if ((do_debugging || do_debug_links)
24d127aa
ML
8413 && (startswith (name, ".gnu_debuglink")
8414 || startswith (name, ".gnu_debugaltlink")))
6431e409 8415 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
8416 }
8417
8418 if (! do_sections)
015dc7e1 8419 return true;
252b5132 8420
ca0e11aa 8421 if (filedata->is_separate && ! process_links)
015dc7e1 8422 return true;
ca0e11aa
NC
8423
8424 if (filedata->is_separate)
8425 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
8426 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
8427 printf (_("\nSection Headers:\n"));
8428 else
8429 printf (_("\nSection Header:\n"));
76da6bbe 8430
f7a99963 8431 if (is_32bit_elf)
595cf52e 8432 {
5477e8a0 8433 if (do_section_details)
595cf52e
L
8434 {
8435 printf (_(" [Nr] Name\n"));
5477e8a0 8436 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
8437 }
8438 else
8439 printf
8440 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8441 }
d974e256 8442 else if (do_wide)
595cf52e 8443 {
5477e8a0 8444 if (do_section_details)
595cf52e
L
8445 {
8446 printf (_(" [Nr] Name\n"));
5477e8a0 8447 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
8448 }
8449 else
8450 printf
8451 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8452 }
f7a99963
NC
8453 else
8454 {
5477e8a0 8455 if (do_section_details)
595cf52e
L
8456 {
8457 printf (_(" [Nr] Name\n"));
5477e8a0
L
8458 printf (_(" Type Address Offset Link\n"));
8459 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
8460 }
8461 else
8462 {
8463 printf (_(" [Nr] Name Type Address Offset\n"));
8464 printf (_(" Size EntSize Flags Link Info Align\n"));
8465 }
f7a99963 8466 }
252b5132 8467
5477e8a0
L
8468 if (do_section_details)
8469 printf (_(" Flags\n"));
8470
dda8d76d
NC
8471 for (i = 0, section = filedata->section_headers;
8472 i < filedata->file_header.e_shnum;
b34976b6 8473 i++, section++)
252b5132 8474 {
dd905818
NC
8475 /* Run some sanity checks on the section header. */
8476
8477 /* Check the sh_link field. */
8478 switch (section->sh_type)
8479 {
285e3f99 8480 case SHT_REL:
fcf8f323 8481 case SHT_RELR:
285e3f99
AM
8482 case SHT_RELA:
8483 if (section->sh_link == 0
8484 && (filedata->file_header.e_type == ET_EXEC
8485 || filedata->file_header.e_type == ET_DYN))
8486 /* A dynamic relocation section where all entries use a
8487 zero symbol index need not specify a symtab section. */
8488 break;
8489 /* Fall through. */
dd905818
NC
8490 case SHT_SYMTAB_SHNDX:
8491 case SHT_GROUP:
8492 case SHT_HASH:
8493 case SHT_GNU_HASH:
8494 case SHT_GNU_versym:
285e3f99 8495 if (section->sh_link == 0
dda8d76d
NC
8496 || section->sh_link >= filedata->file_header.e_shnum
8497 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8498 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
8499 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8500 i, section->sh_link);
8501 break;
8502
8503 case SHT_DYNAMIC:
8504 case SHT_SYMTAB:
8505 case SHT_DYNSYM:
8506 case SHT_GNU_verneed:
8507 case SHT_GNU_verdef:
8508 case SHT_GNU_LIBLIST:
285e3f99 8509 if (section->sh_link == 0
dda8d76d
NC
8510 || section->sh_link >= filedata->file_header.e_shnum
8511 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8512 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8513 i, section->sh_link);
8514 break;
8515
8516 case SHT_INIT_ARRAY:
8517 case SHT_FINI_ARRAY:
8518 case SHT_PREINIT_ARRAY:
8519 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8520 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8521 i, section->sh_link);
8522 break;
8523
8524 default:
8525 /* FIXME: Add support for target specific section types. */
8526#if 0 /* Currently we do not check other section types as there are too
8527 many special cases. Stab sections for example have a type
8528 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8529 section. */
8530 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8531 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8532 i, section->sh_link);
8533#endif
8534 break;
8535 }
8536
8537 /* Check the sh_info field. */
8538 switch (section->sh_type)
8539 {
8540 case SHT_REL:
8541 case SHT_RELA:
285e3f99
AM
8542 if (section->sh_info == 0
8543 && (filedata->file_header.e_type == ET_EXEC
8544 || filedata->file_header.e_type == ET_DYN))
8545 /* Dynamic relocations apply to segments, so they do not
8546 need to specify the section they relocate. */
8547 break;
8548 if (section->sh_info == 0
dda8d76d
NC
8549 || section->sh_info >= filedata->file_header.e_shnum
8550 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8551 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8552 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8553 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8554 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8555 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8556 /* FIXME: Are other section types valid ? */
dda8d76d 8557 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8558 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8559 i, section->sh_info);
dd905818
NC
8560 break;
8561
8562 case SHT_DYNAMIC:
8563 case SHT_HASH:
8564 case SHT_SYMTAB_SHNDX:
8565 case SHT_INIT_ARRAY:
8566 case SHT_FINI_ARRAY:
8567 case SHT_PREINIT_ARRAY:
8568 if (section->sh_info != 0)
8569 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8570 i, section->sh_info);
8571 break;
8572
8573 case SHT_GROUP:
8574 case SHT_SYMTAB:
8575 case SHT_DYNSYM:
8576 /* A symbol index - we assume that it is valid. */
8577 break;
8578
8579 default:
8580 /* FIXME: Add support for target specific section types. */
8581 if (section->sh_type == SHT_NOBITS)
8582 /* NOBITS section headers with non-zero sh_info fields can be
8583 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8584 information. The stripped sections have their headers
8585 preserved but their types set to SHT_NOBITS. So do not check
8586 this type of section. */
dd905818
NC
8587 ;
8588 else if (section->sh_flags & SHF_INFO_LINK)
8589 {
dda8d76d 8590 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8591 warn (_("[%2u]: Expected link to another section in info field"), i);
8592 }
a91e1603
L
8593 else if (section->sh_type < SHT_LOOS
8594 && (section->sh_flags & SHF_GNU_MBIND) == 0
8595 && section->sh_info != 0)
dd905818
NC
8596 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8597 i, section->sh_info);
8598 break;
8599 }
8600
3e6b6445 8601 /* Check the sh_size field. */
dda8d76d 8602 if (section->sh_size > filedata->file_size
3e6b6445
NC
8603 && section->sh_type != SHT_NOBITS
8604 && section->sh_type != SHT_NULL
8605 && section->sh_type < SHT_LOOS)
8606 warn (_("Size of section %u is larger than the entire file!\n"), i);
8607
7bfd842d 8608 printf (" [%2u] ", i);
5477e8a0 8609 if (do_section_details)
dda8d76d 8610 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8611 else
b6ac461a 8612 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8613
ea52a088 8614 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8615 get_section_type_name (filedata, section->sh_type));
0b4362b0 8616
f7a99963
NC
8617 if (is_32bit_elf)
8618 {
cfcac11d
NC
8619 const char * link_too_big = NULL;
8620
f7a99963 8621 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8622
f7a99963
NC
8623 printf ( " %6.6lx %6.6lx %2.2lx",
8624 (unsigned long) section->sh_offset,
8625 (unsigned long) section->sh_size,
8626 (unsigned long) section->sh_entsize);
d1133906 8627
5477e8a0
L
8628 if (do_section_details)
8629 fputs (" ", stdout);
8630 else
dda8d76d 8631 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8632
dda8d76d 8633 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8634 {
8635 link_too_big = "";
8636 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8637 an error but it can have special values in Solaris binaries. */
dda8d76d 8638 switch (filedata->file_header.e_machine)
cfcac11d 8639 {
caa83f8b 8640 case EM_386:
22abe556 8641 case EM_IAMCU:
caa83f8b 8642 case EM_X86_64:
7f502d6c 8643 case EM_L1OM:
7a9068fe 8644 case EM_K1OM:
cfcac11d
NC
8645 case EM_OLD_SPARCV9:
8646 case EM_SPARC32PLUS:
8647 case EM_SPARCV9:
8648 case EM_SPARC:
8649 if (section->sh_link == (SHN_BEFORE & 0xffff))
8650 link_too_big = "BEFORE";
8651 else if (section->sh_link == (SHN_AFTER & 0xffff))
8652 link_too_big = "AFTER";
8653 break;
8654 default:
8655 break;
8656 }
8657 }
8658
8659 if (do_section_details)
8660 {
8661 if (link_too_big != NULL && * link_too_big)
8662 printf ("<%s> ", link_too_big);
8663 else
8664 printf ("%2u ", section->sh_link);
8665 printf ("%3u %2lu\n", section->sh_info,
8666 (unsigned long) section->sh_addralign);
8667 }
8668 else
8669 printf ("%2u %3u %2lu\n",
8670 section->sh_link,
8671 section->sh_info,
8672 (unsigned long) section->sh_addralign);
8673
8674 if (link_too_big && ! * link_too_big)
8675 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8676 i, section->sh_link);
f7a99963 8677 }
d974e256
JJ
8678 else if (do_wide)
8679 {
8680 print_vma (section->sh_addr, LONG_HEX);
8681
8682 if ((long) section->sh_offset == section->sh_offset)
8683 printf (" %6.6lx", (unsigned long) section->sh_offset);
8684 else
8685 {
8686 putchar (' ');
8687 print_vma (section->sh_offset, LONG_HEX);
8688 }
8689
8690 if ((unsigned long) section->sh_size == section->sh_size)
8691 printf (" %6.6lx", (unsigned long) section->sh_size);
8692 else
8693 {
8694 putchar (' ');
8695 print_vma (section->sh_size, LONG_HEX);
8696 }
8697
8698 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8699 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8700 else
8701 {
8702 putchar (' ');
8703 print_vma (section->sh_entsize, LONG_HEX);
8704 }
8705
5477e8a0
L
8706 if (do_section_details)
8707 fputs (" ", stdout);
8708 else
dda8d76d 8709 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8710
72de5009 8711 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8712
8713 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8714 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8715 else
8716 {
8717 print_vma (section->sh_addralign, DEC);
8718 putchar ('\n');
8719 }
8720 }
5477e8a0 8721 else if (do_section_details)
595cf52e 8722 {
55cc53e9 8723 putchar (' ');
595cf52e
L
8724 print_vma (section->sh_addr, LONG_HEX);
8725 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8726 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8727 else
8728 {
8729 printf (" ");
8730 print_vma (section->sh_offset, LONG_HEX);
8731 }
72de5009 8732 printf (" %u\n ", section->sh_link);
595cf52e 8733 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8734 putchar (' ');
595cf52e
L
8735 print_vma (section->sh_entsize, LONG_HEX);
8736
72de5009
AM
8737 printf (" %-16u %lu\n",
8738 section->sh_info,
595cf52e
L
8739 (unsigned long) section->sh_addralign);
8740 }
f7a99963
NC
8741 else
8742 {
8743 putchar (' ');
8744 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8745 if ((long) section->sh_offset == section->sh_offset)
8746 printf (" %8.8lx", (unsigned long) section->sh_offset);
8747 else
8748 {
8749 printf (" ");
8750 print_vma (section->sh_offset, LONG_HEX);
8751 }
f7a99963
NC
8752 printf ("\n ");
8753 print_vma (section->sh_size, LONG_HEX);
8754 printf (" ");
8755 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8756
dda8d76d 8757 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8758
72de5009
AM
8759 printf (" %2u %3u %lu\n",
8760 section->sh_link,
8761 section->sh_info,
f7a99963
NC
8762 (unsigned long) section->sh_addralign);
8763 }
5477e8a0
L
8764
8765 if (do_section_details)
77115a4a 8766 {
dda8d76d 8767 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8768 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8769 {
8770 /* Minimum section size is 12 bytes for 32-bit compression
8771 header + 12 bytes for compressed data header. */
8772 unsigned char buf[24];
d8024a91 8773
77115a4a 8774 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8775 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8776 sizeof (buf), _("compression header")))
8777 {
8778 Elf_Internal_Chdr chdr;
d8024a91 8779
5844b465
NC
8780 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8781 printf (_(" [<corrupt>]\n"));
77115a4a 8782 else
5844b465 8783 {
89dbeac7 8784 if (chdr.ch_type == ch_compress_zlib)
5844b465 8785 printf (" ZLIB, ");
89dbeac7 8786 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8787 printf (" ZSTD, ");
5844b465
NC
8788 else
8789 printf (_(" [<unknown>: 0x%x], "),
8790 chdr.ch_type);
8791 print_vma (chdr.ch_size, LONG_HEX);
8792 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8793 }
77115a4a
L
8794 }
8795 }
8796 }
252b5132
RH
8797 }
8798
5477e8a0 8799 if (!do_section_details)
3dbcc61d 8800 {
9fb71ee4
NC
8801 /* The ordering of the letters shown here matches the ordering of the
8802 corresponding SHF_xxx values, and hence the order in which these
8803 letters will be displayed to the user. */
8804 printf (_("Key to Flags:\n\
8805 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8806 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8807 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8808 switch (filedata->file_header.e_ident[EI_OSABI])
8809 {
8810 case ELFOSABI_GNU:
8811 case ELFOSABI_FREEBSD:
8812 printf (_("R (retain), "));
8813 /* Fall through */
8814 case ELFOSABI_NONE:
8815 printf (_("D (mbind), "));
8816 break;
8817 default:
8818 break;
8819 }
dda8d76d
NC
8820 if (filedata->file_header.e_machine == EM_X86_64
8821 || filedata->file_header.e_machine == EM_L1OM
8822 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8823 printf (_("l (large), "));
dda8d76d 8824 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8825 printf (_("y (purecode), "));
dda8d76d 8826 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8827 printf (_("v (VLE), "));
9fb71ee4 8828 printf ("p (processor specific)\n");
0b4362b0 8829 }
d1133906 8830
015dc7e1 8831 return true;
252b5132
RH
8832}
8833
015dc7e1 8834static bool
fcf8f323
NC
8835get_symtab (Filedata * filedata,
8836 Elf_Internal_Shdr * symsec,
8837 Elf_Internal_Sym ** symtab,
8838 uint64_t * nsyms,
8839 char ** strtab,
8840 uint64_t * strtablen)
28d13567
AM
8841{
8842 *strtab = NULL;
8843 *strtablen = 0;
4de91c10 8844 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8845
8846 if (*symtab == NULL)
015dc7e1 8847 return false;
28d13567
AM
8848
8849 if (symsec->sh_link != 0)
8850 {
8851 Elf_Internal_Shdr *strsec;
8852
8853 if (symsec->sh_link >= filedata->file_header.e_shnum)
8854 {
8855 error (_("Bad sh_link in symbol table section\n"));
8856 free (*symtab);
8857 *symtab = NULL;
8858 *nsyms = 0;
015dc7e1 8859 return false;
28d13567
AM
8860 }
8861
8862 strsec = filedata->section_headers + symsec->sh_link;
8863
8864 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8865 1, strsec->sh_size, _("string table"));
8866 if (*strtab == NULL)
8867 {
8868 free (*symtab);
8869 *symtab = NULL;
8870 *nsyms = 0;
015dc7e1 8871 return false;
28d13567
AM
8872 }
8873 *strtablen = strsec->sh_size;
8874 }
015dc7e1 8875 return true;
28d13567
AM
8876}
8877
f5842774
L
8878static const char *
8879get_group_flags (unsigned int flags)
8880{
1449284b 8881 static char buff[128];
220453ec 8882
6d913794
NC
8883 if (flags == 0)
8884 return "";
8885 else if (flags == GRP_COMDAT)
8886 return "COMDAT ";
f5842774 8887
89246a0e
AM
8888 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8889 flags,
8890 flags & GRP_MASKOS ? _("<OS specific>") : "",
8891 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8892 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8893 ? _("<unknown>") : ""));
6d913794 8894
f5842774
L
8895 return buff;
8896}
8897
015dc7e1 8898static bool
dda8d76d 8899process_section_groups (Filedata * filedata)
f5842774 8900{
2cf0635d 8901 Elf_Internal_Shdr * section;
f5842774 8902 unsigned int i;
2cf0635d
NC
8903 struct group * group;
8904 Elf_Internal_Shdr * symtab_sec;
8905 Elf_Internal_Shdr * strtab_sec;
8906 Elf_Internal_Sym * symtab;
26c527e6 8907 uint64_t num_syms;
2cf0635d 8908 char * strtab;
c256ffe7 8909 size_t strtab_size;
d1f5c6e3
L
8910
8911 /* Don't process section groups unless needed. */
8912 if (!do_unwind && !do_section_groups)
015dc7e1 8913 return true;
f5842774 8914
dda8d76d 8915 if (filedata->file_header.e_shnum == 0)
f5842774
L
8916 {
8917 if (do_section_groups)
ca0e11aa
NC
8918 {
8919 if (filedata->is_separate)
8920 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8921 filedata->file_name);
8922 else
8923 printf (_("\nThere are no section groups in this file.\n"));
8924 }
015dc7e1 8925 return true;
f5842774
L
8926 }
8927
dda8d76d 8928 if (filedata->section_headers == NULL)
f5842774
L
8929 {
8930 error (_("Section headers are not available!\n"));
fa1908fd 8931 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8932 return false;
f5842774
L
8933 }
8934
978c4450
AM
8935 filedata->section_headers_groups
8936 = (struct group **) calloc (filedata->file_header.e_shnum,
8937 sizeof (struct group *));
e4b17d5c 8938
978c4450 8939 if (filedata->section_headers_groups == NULL)
e4b17d5c 8940 {
8b73c356 8941 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8942 filedata->file_header.e_shnum);
015dc7e1 8943 return false;
e4b17d5c
L
8944 }
8945
f5842774 8946 /* Scan the sections for the group section. */
978c4450 8947 filedata->group_count = 0;
dda8d76d
NC
8948 for (i = 0, section = filedata->section_headers;
8949 i < filedata->file_header.e_shnum;
f5842774 8950 i++, section++)
e4b17d5c 8951 if (section->sh_type == SHT_GROUP)
978c4450 8952 filedata->group_count++;
e4b17d5c 8953
978c4450 8954 if (filedata->group_count == 0)
d1f5c6e3
L
8955 {
8956 if (do_section_groups)
ca0e11aa
NC
8957 {
8958 if (filedata->is_separate)
8959 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8960 filedata->file_name);
8961 else
8962 printf (_("\nThere are no section groups in this file.\n"));
8963 }
d1f5c6e3 8964
015dc7e1 8965 return true;
d1f5c6e3
L
8966 }
8967
978c4450
AM
8968 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8969 sizeof (struct group));
e4b17d5c 8970
978c4450 8971 if (filedata->section_groups == NULL)
e4b17d5c 8972 {
26c527e6 8973 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8974 return false;
e4b17d5c
L
8975 }
8976
d1f5c6e3
L
8977 symtab_sec = NULL;
8978 strtab_sec = NULL;
8979 symtab = NULL;
ba5cdace 8980 num_syms = 0;
d1f5c6e3 8981 strtab = NULL;
c256ffe7 8982 strtab_size = 0;
ca0e11aa
NC
8983
8984 if (filedata->is_separate)
8985 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8986
978c4450 8987 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8988 i < filedata->file_header.e_shnum;
e4b17d5c 8989 i++, section++)
f5842774
L
8990 {
8991 if (section->sh_type == SHT_GROUP)
8992 {
dda8d76d 8993 const char * name = printable_section_name (filedata, section);
74e1a04b 8994 const char * group_name;
2cf0635d
NC
8995 unsigned char * start;
8996 unsigned char * indices;
f5842774 8997 unsigned int entry, j, size;
2cf0635d
NC
8998 Elf_Internal_Shdr * sec;
8999 Elf_Internal_Sym * sym;
f5842774
L
9000
9001 /* Get the symbol table. */
dda8d76d
NC
9002 if (section->sh_link >= filedata->file_header.e_shnum
9003 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 9004 != SHT_SYMTAB))
f5842774
L
9005 {
9006 error (_("Bad sh_link in group section `%s'\n"), name);
9007 continue;
9008 }
d1f5c6e3
L
9009
9010 if (symtab_sec != sec)
9011 {
9012 symtab_sec = sec;
9db70fc3 9013 free (symtab);
4de91c10 9014 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 9015 }
f5842774 9016
dd24e3da
NC
9017 if (symtab == NULL)
9018 {
9019 error (_("Corrupt header in group section `%s'\n"), name);
9020 continue;
9021 }
9022
ba5cdace
NC
9023 if (section->sh_info >= num_syms)
9024 {
9025 error (_("Bad sh_info in group section `%s'\n"), name);
9026 continue;
9027 }
9028
f5842774
L
9029 sym = symtab + section->sh_info;
9030
9031 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
9032 {
4fbb74a6 9033 if (sym->st_shndx == 0
dda8d76d 9034 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
9035 {
9036 error (_("Bad sh_info in group section `%s'\n"), name);
9037 continue;
9038 }
ba2685cc 9039
b6ac461a
NC
9040 group_name = printable_section_name (filedata,
9041 filedata->section_headers
9042 + sym->st_shndx);
c256ffe7 9043 strtab_sec = NULL;
9db70fc3 9044 free (strtab);
f5842774 9045 strtab = NULL;
c256ffe7 9046 strtab_size = 0;
f5842774
L
9047 }
9048 else
9049 {
9050 /* Get the string table. */
dda8d76d 9051 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
9052 {
9053 strtab_sec = NULL;
9db70fc3 9054 free (strtab);
c256ffe7
JJ
9055 strtab = NULL;
9056 strtab_size = 0;
9057 }
9058 else if (strtab_sec
dda8d76d 9059 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
9060 {
9061 strtab_sec = sec;
9db70fc3 9062 free (strtab);
071436c6 9063
dda8d76d 9064 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
9065 1, strtab_sec->sh_size,
9066 _("string table"));
c256ffe7 9067 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 9068 }
c256ffe7 9069 group_name = sym->st_name < strtab_size
2b692964 9070 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
9071 }
9072
c9c1d674
EG
9073 /* PR 17531: file: loop. */
9074 if (section->sh_entsize > section->sh_size)
9075 {
26c527e6
AM
9076 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
9077 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 9078 printable_section_name (filedata, section),
26c527e6
AM
9079 section->sh_entsize,
9080 section->sh_size);
61dd8e19 9081 continue;
c9c1d674
EG
9082 }
9083
dda8d76d 9084 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
9085 1, section->sh_size,
9086 _("section data"));
59245841
NC
9087 if (start == NULL)
9088 continue;
f5842774
L
9089
9090 indices = start;
9091 size = (section->sh_size / section->sh_entsize) - 1;
9092 entry = byte_get (indices, 4);
9093 indices += 4;
e4b17d5c
L
9094
9095 if (do_section_groups)
9096 {
2b692964 9097 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 9098 get_group_flags (entry), i, name, group_name, size);
ba2685cc 9099
e4b17d5c
L
9100 printf (_(" [Index] Name\n"));
9101 }
9102
9103 group->group_index = i;
9104
f5842774
L
9105 for (j = 0; j < size; j++)
9106 {
2cf0635d 9107 struct group_list * g;
e4b17d5c 9108
f5842774
L
9109 entry = byte_get (indices, 4);
9110 indices += 4;
9111
dda8d76d 9112 if (entry >= filedata->file_header.e_shnum)
391cb864 9113 {
57028622
NC
9114 static unsigned num_group_errors = 0;
9115
9116 if (num_group_errors ++ < 10)
9117 {
9118 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 9119 entry, i, filedata->file_header.e_shnum - 1);
57028622 9120 if (num_group_errors == 10)
67ce483b 9121 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 9122 }
391cb864
L
9123 continue;
9124 }
391cb864 9125
978c4450 9126 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 9127 {
d1f5c6e3
L
9128 if (entry)
9129 {
57028622
NC
9130 static unsigned num_errs = 0;
9131
9132 if (num_errs ++ < 10)
9133 {
9134 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
9135 entry, i,
978c4450 9136 filedata->section_headers_groups [entry]->group_index);
57028622
NC
9137 if (num_errs == 10)
9138 warn (_("Further error messages about already contained group sections suppressed\n"));
9139 }
d1f5c6e3
L
9140 continue;
9141 }
9142 else
9143 {
9144 /* Intel C/C++ compiler may put section 0 in a
32ec8896 9145 section group. We just warn it the first time
d1f5c6e3 9146 and ignore it afterwards. */
015dc7e1 9147 static bool warned = false;
d1f5c6e3
L
9148 if (!warned)
9149 {
9150 error (_("section 0 in group section [%5u]\n"),
978c4450 9151 filedata->section_headers_groups [entry]->group_index);
015dc7e1 9152 warned = true;
d1f5c6e3
L
9153 }
9154 }
e4b17d5c
L
9155 }
9156
978c4450 9157 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
9158
9159 if (do_section_groups)
9160 {
dda8d76d
NC
9161 sec = filedata->section_headers + entry;
9162 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
9163 }
9164
3f5e193b 9165 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
9166 g->section_index = entry;
9167 g->next = group->root;
9168 group->root = g;
f5842774
L
9169 }
9170
9db70fc3 9171 free (start);
e4b17d5c
L
9172
9173 group++;
f5842774
L
9174 }
9175 }
9176
9db70fc3
AM
9177 free (symtab);
9178 free (strtab);
015dc7e1 9179 return true;
f5842774
L
9180}
9181
28f997cf
TG
9182/* Data used to display dynamic fixups. */
9183
9184struct ia64_vms_dynfixup
9185{
625d49fc
AM
9186 uint64_t needed_ident; /* Library ident number. */
9187 uint64_t needed; /* Index in the dstrtab of the library name. */
9188 uint64_t fixup_needed; /* Index of the library. */
9189 uint64_t fixup_rela_cnt; /* Number of fixups. */
9190 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
9191};
9192
9193/* Data used to display dynamic relocations. */
9194
9195struct ia64_vms_dynimgrela
9196{
625d49fc
AM
9197 uint64_t img_rela_cnt; /* Number of relocations. */
9198 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
9199};
9200
9201/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
9202 library). */
9203
015dc7e1 9204static bool
dda8d76d
NC
9205dump_ia64_vms_dynamic_fixups (Filedata * filedata,
9206 struct ia64_vms_dynfixup * fixup,
9207 const char * strtab,
9208 unsigned int strtab_sz)
28f997cf 9209{
32ec8896 9210 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 9211 size_t i;
32ec8896 9212 const char * lib_name;
28f997cf 9213
978c4450
AM
9214 imfs = get_data (NULL, filedata,
9215 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 9216 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
9217 _("dynamic section image fixups"));
9218 if (!imfs)
015dc7e1 9219 return false;
28f997cf
TG
9220
9221 if (fixup->needed < strtab_sz)
9222 lib_name = strtab + fixup->needed;
9223 else
9224 {
26c527e6
AM
9225 warn (_("corrupt library name index of %#" PRIx64
9226 " found in dynamic entry"), fixup->needed);
28f997cf
TG
9227 lib_name = "???";
9228 }
736990c4 9229
26c527e6
AM
9230 printf (_("\nImage fixups for needed library #%" PRId64
9231 ": %s - ident: %" PRIx64 "\n"),
9232 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
9233 printf
9234 (_("Seg Offset Type SymVec DataType\n"));
9235
26c527e6 9236 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
9237 {
9238 unsigned int type;
9239 const char *rtype;
9240
9241 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 9242 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
9243 type = BYTE_GET (imfs [i].type);
9244 rtype = elf_ia64_reloc_type (type);
9245 if (rtype == NULL)
f493c217 9246 printf ("0x%08x ", type);
28f997cf 9247 else
f493c217 9248 printf ("%-32s ", rtype);
28f997cf
TG
9249 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
9250 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
9251 }
9252
9253 free (imfs);
015dc7e1 9254 return true;
28f997cf
TG
9255}
9256
9257/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
9258
015dc7e1 9259static bool
dda8d76d 9260dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
9261{
9262 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 9263 size_t i;
28f997cf 9264
978c4450
AM
9265 imrs = get_data (NULL, filedata,
9266 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 9267 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 9268 _("dynamic section image relocations"));
28f997cf 9269 if (!imrs)
015dc7e1 9270 return false;
28f997cf
TG
9271
9272 printf (_("\nImage relocs\n"));
9273 printf
9274 (_("Seg Offset Type Addend Seg Sym Off\n"));
9275
26c527e6 9276 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
9277 {
9278 unsigned int type;
9279 const char *rtype;
9280
9281 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 9282 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
9283 type = BYTE_GET (imrs [i].type);
9284 rtype = elf_ia64_reloc_type (type);
9285 if (rtype == NULL)
9286 printf ("0x%08x ", type);
9287 else
9288 printf ("%-31s ", rtype);
9289 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9290 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 9291 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
9292 }
9293
9294 free (imrs);
015dc7e1 9295 return true;
28f997cf
TG
9296}
9297
9298/* Display IA-64 OpenVMS dynamic relocations and fixups. */
9299
015dc7e1 9300static bool
dda8d76d 9301process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
9302{
9303 struct ia64_vms_dynfixup fixup;
9304 struct ia64_vms_dynimgrela imgrela;
9305 Elf_Internal_Dyn *entry;
625d49fc
AM
9306 uint64_t strtab_off = 0;
9307 uint64_t strtab_sz = 0;
28f997cf 9308 char *strtab = NULL;
015dc7e1 9309 bool res = true;
28f997cf
TG
9310
9311 memset (&fixup, 0, sizeof (fixup));
9312 memset (&imgrela, 0, sizeof (imgrela));
9313
9314 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
9315 for (entry = filedata->dynamic_section;
9316 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
9317 entry++)
9318 {
9319 switch (entry->d_tag)
9320 {
9321 case DT_IA_64_VMS_STRTAB_OFFSET:
9322 strtab_off = entry->d_un.d_val;
9323 break;
9324 case DT_STRSZ:
9325 strtab_sz = entry->d_un.d_val;
9326 if (strtab == NULL)
978c4450
AM
9327 strtab = get_data (NULL, filedata,
9328 filedata->dynamic_addr + strtab_off,
28f997cf 9329 1, strtab_sz, _("dynamic string section"));
736990c4
NC
9330 if (strtab == NULL)
9331 strtab_sz = 0;
28f997cf
TG
9332 break;
9333
9334 case DT_IA_64_VMS_NEEDED_IDENT:
9335 fixup.needed_ident = entry->d_un.d_val;
9336 break;
9337 case DT_NEEDED:
9338 fixup.needed = entry->d_un.d_val;
9339 break;
9340 case DT_IA_64_VMS_FIXUP_NEEDED:
9341 fixup.fixup_needed = entry->d_un.d_val;
9342 break;
9343 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9344 fixup.fixup_rela_cnt = entry->d_un.d_val;
9345 break;
9346 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9347 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 9348 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 9349 res = false;
28f997cf 9350 break;
28f997cf
TG
9351 case DT_IA_64_VMS_IMG_RELA_CNT:
9352 imgrela.img_rela_cnt = entry->d_un.d_val;
9353 break;
9354 case DT_IA_64_VMS_IMG_RELA_OFF:
9355 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 9356 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 9357 res = false;
28f997cf
TG
9358 break;
9359
9360 default:
9361 break;
9362 }
9363 }
9364
9db70fc3 9365 free (strtab);
28f997cf
TG
9366
9367 return res;
9368}
9369
85b1c36d 9370static struct
566b0d53 9371{
2cf0635d 9372 const char * name;
566b0d53
L
9373 int reloc;
9374 int size;
a7fd1186 9375 relocation_type rel_type;
32ec8896
NC
9376}
9377 dynamic_relocations [] =
566b0d53 9378{
a7fd1186
FS
9379 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9380 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9381 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9382 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
9383};
9384
8e8d0b63
NC
9385static relocation_type
9386rel_type_from_sh_type (unsigned int sh_type)
9387{
9388 switch (sh_type)
9389 {
9390 case SHT_RELA: return reltype_rela;
9391 case SHT_REL: return reltype_rel;
9392 case SHT_RELR: return reltype_relr;
9393 default: return reltype_unknown;
9394 }
9395}
9396
9397static bool
9398display_relocations (Elf_Internal_Shdr * section,
9399 Filedata * filedata)
9400{
fcf8f323
NC
9401 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9402
9403 if (rel_type == reltype_unknown)
8e8d0b63
NC
9404 return false;
9405
9406 uint64_t rel_size = section->sh_size;
9407
9408 if (rel_size == 0)
9409 return false;
9410
9411 if (filedata->is_separate)
9412 printf (_("\nIn linked file '%s' relocation section "),
9413 filedata->file_name);
9414 else
9415 printf (_("\nRelocation section "));
9416
9417 if (filedata->string_table == NULL)
9418 printf ("%d", section->sh_name);
9419 else
9420 printf ("'%s'", printable_section_name (filedata, section));
9421
9422 uint64_t num_rela = rel_size / section->sh_entsize;
9423 uint64_t rel_offset = section->sh_offset;
9424
3b3e2090
NC
9425 if (rel_type == reltype_relr)
9426 {
9427 /* Just stating the 'number of entries' in a RELR section can be
9428 misleading, since this is not the number of locations relocated, but
9429 the number of words in the compressed RELR format. So also provide
9430 the number of locations affected. */
ad43ae76
NC
9431
9432 uint64_t num_reloc = count_relr_relocations (filedata, section);
9433
9434 printf (_(" at offset %#" PRIx64), rel_offset);
9435 printf (ngettext (" contains %" PRIu64 " entry which relocates",
9436 " contains %" PRIu64 " entries which relocate",
9437 num_rela), num_rela);
9438 printf (ngettext (" %" PRIu64 " location:\n",
9439 " %" PRIu64 " locations:\n",
9440 num_reloc), num_reloc);
3b3e2090
NC
9441 }
9442 else
9443 {
9444 printf (ngettext (" at offset %#" PRIx64
9445 " contains %" PRIu64 " entry:\n",
9446 " at offset %#" PRIx64
9447 " contains %" PRIu64 " entries:\n",
9448 num_rela),
9449 rel_offset, num_rela);
9450 }
8e8d0b63 9451
fcf8f323
NC
9452 Elf_Internal_Shdr * symsec;
9453 Elf_Internal_Sym * symtab = NULL;
9454 uint64_t nsyms = 0;
9455 uint64_t strtablen = 0;
9456 char * strtab = NULL;
8e8d0b63
NC
9457
9458 if (section->sh_link == 0
9459 || section->sh_link >= filedata->file_header.e_shnum)
fcf8f323
NC
9460 {
9461 /* Symbol data not available.
9462 This can happen, especially with RELR relocs.
9463 See if there is a .symtab section present.
9464 If so then use it. */
9465 symsec = find_section_by_name (filedata, ".symtab");
9466 }
9467 else
9468 {
9469 symsec = filedata->section_headers + section->sh_link;
8e8d0b63 9470
fcf8f323
NC
9471 if (symsec->sh_type != SHT_SYMTAB
9472 && symsec->sh_type != SHT_DYNSYM)
9473 return false;
9474 }
8e8d0b63 9475
fcf8f323
NC
9476 if (symsec != NULL
9477 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
8e8d0b63
NC
9478 return false;
9479
fcf8f323
NC
9480 bool res;
9481
9482 if (rel_type == reltype_relr)
9483 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9484 else
9485 res = dump_relocations (filedata, rel_offset, rel_size,
9486 symtab, nsyms, strtab, strtablen,
9487 rel_type,
9488 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
8e8d0b63
NC
9489 free (strtab);
9490 free (symtab);
9491
9492 return res;
9493}
9494
252b5132 9495/* Process the reloc section. */
18bd398b 9496
015dc7e1 9497static bool
dda8d76d 9498process_relocs (Filedata * filedata)
252b5132 9499{
26c527e6
AM
9500 uint64_t rel_size;
9501 uint64_t rel_offset;
252b5132 9502
252b5132 9503 if (!do_reloc)
015dc7e1 9504 return true;
252b5132
RH
9505
9506 if (do_using_dynamic)
9507 {
a7fd1186 9508 relocation_type rel_type;
2cf0635d 9509 const char * name;
015dc7e1 9510 bool has_dynamic_reloc;
566b0d53 9511 unsigned int i;
0de14b54 9512
015dc7e1 9513 has_dynamic_reloc = false;
252b5132 9514
566b0d53 9515 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 9516 {
a7fd1186 9517 rel_type = dynamic_relocations [i].rel_type;
566b0d53 9518 name = dynamic_relocations [i].name;
978c4450
AM
9519 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9520 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 9521
32ec8896 9522 if (rel_size)
015dc7e1 9523 has_dynamic_reloc = true;
566b0d53 9524
a7fd1186 9525 if (rel_type == reltype_unknown)
aa903cfb 9526 {
566b0d53 9527 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 9528 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
9529 {
9530 case DT_REL:
a7fd1186 9531 rel_type = reltype_rel;
566b0d53
L
9532 break;
9533 case DT_RELA:
a7fd1186 9534 rel_type = reltype_rela;
566b0d53
L
9535 break;
9536 }
aa903cfb 9537 }
252b5132 9538
566b0d53
L
9539 if (rel_size)
9540 {
ca0e11aa
NC
9541 if (filedata->is_separate)
9542 printf
26c527e6
AM
9543 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9544 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
9545 filedata->file_name, name, rel_offset, rel_size);
9546 else
9547 printf
26c527e6
AM
9548 (_("\n'%s' relocation section at offset %#" PRIx64
9549 " contains %" PRId64 " bytes:\n"),
ca0e11aa 9550 name, rel_offset, rel_size);
252b5132 9551
dda8d76d
NC
9552 dump_relocations (filedata,
9553 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 9554 rel_size,
978c4450
AM
9555 filedata->dynamic_symbols,
9556 filedata->num_dynamic_syms,
9557 filedata->dynamic_strings,
9558 filedata->dynamic_strings_length,
a7fd1186 9559 rel_type, true /* is_dynamic */);
566b0d53 9560 }
252b5132 9561 }
566b0d53 9562
dda8d76d
NC
9563 if (is_ia64_vms (filedata))
9564 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 9565 has_dynamic_reloc = true;
28f997cf 9566
566b0d53 9567 if (! has_dynamic_reloc)
ca0e11aa
NC
9568 {
9569 if (filedata->is_separate)
9570 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9571 filedata->file_name);
9572 else
9573 printf (_("\nThere are no dynamic relocations in this file.\n"));
9574 }
252b5132
RH
9575 }
9576 else
9577 {
2cf0635d 9578 Elf_Internal_Shdr * section;
26c527e6 9579 size_t i;
015dc7e1 9580 bool found = false;
252b5132 9581
dda8d76d
NC
9582 for (i = 0, section = filedata->section_headers;
9583 i < filedata->file_header.e_shnum;
b34976b6 9584 i++, section++)
252b5132 9585 {
8e8d0b63
NC
9586 if (display_relocations (section, filedata))
9587 found = true;
252b5132
RH
9588 }
9589
9590 if (! found)
45ac8f4f
NC
9591 {
9592 /* Users sometimes forget the -D option, so try to be helpful. */
9593 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9594 {
978c4450 9595 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9596 {
ca0e11aa
NC
9597 if (filedata->is_separate)
9598 printf (_("\nThere are no static relocations in linked file '%s'."),
9599 filedata->file_name);
9600 else
9601 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9602 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9603
9604 break;
9605 }
9606 }
9607 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9608 {
9609 if (filedata->is_separate)
9610 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9611 filedata->file_name);
9612 else
9613 printf (_("\nThere are no relocations in this file.\n"));
9614 }
45ac8f4f 9615 }
252b5132
RH
9616 }
9617
015dc7e1 9618 return true;
252b5132
RH
9619}
9620
4d6ed7c8
NC
9621/* An absolute address consists of a section and an offset. If the
9622 section is NULL, the offset itself is the address, otherwise, the
9623 address equals to LOAD_ADDRESS(section) + offset. */
9624
9625struct absaddr
948f632f
DA
9626{
9627 unsigned short section;
625d49fc 9628 uint64_t offset;
948f632f 9629};
4d6ed7c8 9630
948f632f
DA
9631/* Find the nearest symbol at or below ADDR. Returns the symbol
9632 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9633
4d6ed7c8 9634static void
26c527e6
AM
9635find_symbol_for_address (Filedata *filedata,
9636 Elf_Internal_Sym *symtab,
9637 uint64_t nsyms,
9638 const char *strtab,
9639 uint64_t strtab_size,
9640 struct absaddr addr,
9641 const char **symname,
9642 uint64_t *offset)
4d6ed7c8 9643{
625d49fc 9644 uint64_t dist = 0x100000;
2cf0635d 9645 Elf_Internal_Sym * sym;
948f632f
DA
9646 Elf_Internal_Sym * beg;
9647 Elf_Internal_Sym * end;
2cf0635d 9648 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9649
0b6ae522 9650 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9651 beg = symtab;
9652 end = symtab + nsyms;
0b6ae522 9653
948f632f 9654 while (beg < end)
4d6ed7c8 9655 {
625d49fc 9656 uint64_t value;
948f632f
DA
9657
9658 sym = beg + (end - beg) / 2;
0b6ae522 9659
948f632f 9660 value = sym->st_value;
0b6ae522
DJ
9661 REMOVE_ARCH_BITS (value);
9662
948f632f 9663 if (sym->st_name != 0
4d6ed7c8 9664 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9665 && addr.offset >= value
9666 && addr.offset - value < dist)
4d6ed7c8
NC
9667 {
9668 best = sym;
0b6ae522 9669 dist = addr.offset - value;
4d6ed7c8
NC
9670 if (!dist)
9671 break;
9672 }
948f632f
DA
9673
9674 if (addr.offset < value)
9675 end = sym;
9676 else
9677 beg = sym + 1;
4d6ed7c8 9678 }
1b31d05e 9679
4d6ed7c8
NC
9680 if (best)
9681 {
57346661 9682 *symname = (best->st_name >= strtab_size
2b692964 9683 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9684 *offset = dist;
9685 return;
9686 }
1b31d05e 9687
4d6ed7c8
NC
9688 *symname = NULL;
9689 *offset = addr.offset;
9690}
9691
948f632f
DA
9692/* Process the unwind section. */
9693
9694#include "unwind-ia64.h"
9695
9696struct ia64_unw_table_entry
9697{
9698 struct absaddr start;
9699 struct absaddr end;
9700 struct absaddr info;
9701};
9702
9703struct ia64_unw_aux_info
9704{
32ec8896 9705 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9706 uint64_t table_len; /* Length of unwind table. */
32ec8896 9707 unsigned char * info; /* Unwind info. */
26c527e6 9708 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9709 uint64_t info_addr; /* Starting address of unwind info. */
9710 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9711 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9712 uint64_t nsyms; /* Number of symbols. */
32ec8896 9713 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9714 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9715 char * strtab; /* The string table. */
26c527e6 9716 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9717};
9718
015dc7e1 9719static bool
dda8d76d 9720dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9721{
2cf0635d 9722 struct ia64_unw_table_entry * tp;
26c527e6 9723 size_t j, nfuns;
4d6ed7c8 9724 int in_body;
015dc7e1 9725 bool res = true;
7036c0e1 9726
948f632f
DA
9727 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9728 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9729 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9730 aux->funtab[nfuns++] = aux->symtab[j];
9731 aux->nfuns = nfuns;
9732 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9733
4d6ed7c8
NC
9734 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9735 {
625d49fc
AM
9736 uint64_t stamp;
9737 uint64_t offset;
2cf0635d
NC
9738 const unsigned char * dp;
9739 const unsigned char * head;
53774b7e 9740 const unsigned char * end;
2cf0635d 9741 const char * procname;
4d6ed7c8 9742
dda8d76d 9743 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9744 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9745
9746 fputs ("\n<", stdout);
9747
9748 if (procname)
9749 {
9750 fputs (procname, stdout);
9751
9752 if (offset)
26c527e6 9753 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9754 }
9755
9756 fputs (">: [", stdout);
9757 print_vma (tp->start.offset, PREFIX_HEX);
9758 fputc ('-', stdout);
9759 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9760 printf ("], info at +0x%" PRIx64 "\n",
9761 tp->info.offset - aux->seg_base);
4d6ed7c8 9762
53774b7e
NC
9763 /* PR 17531: file: 86232b32. */
9764 if (aux->info == NULL)
9765 continue;
9766
97c0a079
AM
9767 offset = tp->info.offset;
9768 if (tp->info.section)
9769 {
9770 if (tp->info.section >= filedata->file_header.e_shnum)
9771 {
26c527e6
AM
9772 warn (_("Invalid section %u in table entry %td\n"),
9773 tp->info.section, tp - aux->table);
015dc7e1 9774 res = false;
97c0a079
AM
9775 continue;
9776 }
9777 offset += filedata->section_headers[tp->info.section].sh_addr;
9778 }
9779 offset -= aux->info_addr;
53774b7e 9780 /* PR 17531: file: 0997b4d1. */
90679903
AM
9781 if (offset >= aux->info_size
9782 || aux->info_size - offset < 8)
53774b7e 9783 {
26c527e6
AM
9784 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9785 tp->info.offset, tp - aux->table);
015dc7e1 9786 res = false;
53774b7e
NC
9787 continue;
9788 }
9789
97c0a079 9790 head = aux->info + offset;
a4a00738 9791 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9792
86f55779 9793 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9794 (unsigned) UNW_VER (stamp),
9795 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9796 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9797 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9798 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9799
9800 if (UNW_VER (stamp) != 1)
9801 {
2b692964 9802 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9803 continue;
9804 }
9805
9806 in_body = 0;
53774b7e
NC
9807 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9808 /* PR 17531: file: 16ceda89. */
9809 if (end > aux->info + aux->info_size)
9810 end = aux->info + aux->info_size;
9811 for (dp = head + 8; dp < end;)
b4477bc8 9812 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9813 }
948f632f
DA
9814
9815 free (aux->funtab);
32ec8896
NC
9816
9817 return res;
4d6ed7c8
NC
9818}
9819
015dc7e1 9820static bool
dda8d76d
NC
9821slurp_ia64_unwind_table (Filedata * filedata,
9822 struct ia64_unw_aux_info * aux,
9823 Elf_Internal_Shdr * sec)
4d6ed7c8 9824{
26c527e6 9825 uint64_t size, nrelas, i;
2cf0635d
NC
9826 Elf_Internal_Phdr * seg;
9827 struct ia64_unw_table_entry * tep;
9828 Elf_Internal_Shdr * relsec;
9829 Elf_Internal_Rela * rela;
9830 Elf_Internal_Rela * rp;
9831 unsigned char * table;
9832 unsigned char * tp;
9833 Elf_Internal_Sym * sym;
9834 const char * relname;
4d6ed7c8 9835
53774b7e
NC
9836 aux->table_len = 0;
9837
4d6ed7c8
NC
9838 /* First, find the starting address of the segment that includes
9839 this section: */
9840
dda8d76d 9841 if (filedata->file_header.e_phnum)
4d6ed7c8 9842 {
dda8d76d 9843 if (! get_program_headers (filedata))
015dc7e1 9844 return false;
4d6ed7c8 9845
dda8d76d
NC
9846 for (seg = filedata->program_headers;
9847 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9848 ++seg)
4d6ed7c8
NC
9849 {
9850 if (seg->p_type != PT_LOAD)
9851 continue;
9852
9853 if (sec->sh_addr >= seg->p_vaddr
9854 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9855 {
9856 aux->seg_base = seg->p_vaddr;
9857 break;
9858 }
9859 }
4d6ed7c8
NC
9860 }
9861
9862 /* Second, build the unwind table from the contents of the unwind section: */
9863 size = sec->sh_size;
dda8d76d 9864 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9865 _("unwind table"));
a6e9f9df 9866 if (!table)
015dc7e1 9867 return false;
4d6ed7c8 9868
53774b7e 9869 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9870 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9871 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9872 tep = aux->table;
53774b7e
NC
9873
9874 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9875 {
9876 tep->start.section = SHN_UNDEF;
9877 tep->end.section = SHN_UNDEF;
9878 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9879 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9880 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9881 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9882 tep->start.offset += aux->seg_base;
9883 tep->end.offset += aux->seg_base;
9884 tep->info.offset += aux->seg_base;
9885 }
9886 free (table);
9887
41e92641 9888 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9889 for (relsec = filedata->section_headers;
9890 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9891 ++relsec)
9892 {
9893 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9894 || relsec->sh_info >= filedata->file_header.e_shnum
9895 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9896 continue;
9897
dda8d76d 9898 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9899 & rela, & nrelas))
53774b7e
NC
9900 {
9901 free (aux->table);
9902 aux->table = NULL;
9903 aux->table_len = 0;
015dc7e1 9904 return false;
53774b7e 9905 }
4d6ed7c8
NC
9906
9907 for (rp = rela; rp < rela + nrelas; ++rp)
9908 {
4770fb94 9909 unsigned int sym_ndx;
726bd37d
AM
9910 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9911 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9912
82b1b41b
NC
9913 /* PR 17531: file: 9fa67536. */
9914 if (relname == NULL)
9915 {
726bd37d 9916 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9917 continue;
9918 }
948f632f 9919
24d127aa 9920 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9921 {
82b1b41b 9922 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9923 continue;
9924 }
9925
89fac5e3 9926 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9927
53774b7e
NC
9928 /* PR 17531: file: 5bc8d9bf. */
9929 if (i >= aux->table_len)
9930 {
26c527e6
AM
9931 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9932 i);
53774b7e
NC
9933 continue;
9934 }
9935
4770fb94
AM
9936 sym_ndx = get_reloc_symindex (rp->r_info);
9937 if (sym_ndx >= aux->nsyms)
9938 {
9939 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9940 sym_ndx);
9941 continue;
9942 }
9943 sym = aux->symtab + sym_ndx;
9944
53774b7e 9945 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9946 {
9947 case 0:
9948 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9949 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9950 break;
9951 case 1:
9952 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9953 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9954 break;
9955 case 2:
9956 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9957 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9958 break;
9959 default:
9960 break;
9961 }
9962 }
9963
9964 free (rela);
9965 }
9966
015dc7e1 9967 return true;
4d6ed7c8
NC
9968}
9969
015dc7e1 9970static bool
dda8d76d 9971ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9972{
2cf0635d
NC
9973 Elf_Internal_Shdr * sec;
9974 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9975 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9976 struct ia64_unw_aux_info aux;
015dc7e1 9977 bool res = true;
f1467e33 9978
4d6ed7c8
NC
9979 memset (& aux, 0, sizeof (aux));
9980
dda8d76d 9981 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9982 {
28d13567 9983 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9984 {
28d13567 9985 if (aux.symtab)
4082ef84 9986 {
28d13567
AM
9987 error (_("Multiple symbol tables encountered\n"));
9988 free (aux.symtab);
9989 aux.symtab = NULL;
4082ef84 9990 free (aux.strtab);
28d13567 9991 aux.strtab = NULL;
4082ef84 9992 }
28d13567
AM
9993 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9994 &aux.strtab, &aux.strtab_size))
015dc7e1 9995 return false;
4d6ed7c8
NC
9996 }
9997 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9998 unwcount++;
9999 }
10000
10001 if (!unwcount)
10002 printf (_("\nThere are no unwind sections in this file.\n"));
10003
10004 while (unwcount-- > 0)
10005 {
84714f86 10006 const char *suffix;
579f31ac
JJ
10007 size_t len, len2;
10008
dda8d76d
NC
10009 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
10010 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
10011 if (sec->sh_type == SHT_IA_64_UNWIND)
10012 {
10013 unwsec = sec;
10014 break;
10015 }
4082ef84
NC
10016 /* We have already counted the number of SHT_IA64_UNWIND
10017 sections so the loop above should never fail. */
10018 assert (unwsec != NULL);
579f31ac
JJ
10019
10020 unwstart = i + 1;
10021 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
10022
e4b17d5c
L
10023 if ((unwsec->sh_flags & SHF_GROUP) != 0)
10024 {
10025 /* We need to find which section group it is in. */
4082ef84 10026 struct group_list * g;
e4b17d5c 10027
978c4450
AM
10028 if (filedata->section_headers_groups == NULL
10029 || filedata->section_headers_groups[i] == NULL)
dda8d76d 10030 i = filedata->file_header.e_shnum;
4082ef84 10031 else
e4b17d5c 10032 {
978c4450 10033 g = filedata->section_headers_groups[i]->root;
18bd398b 10034
4082ef84
NC
10035 for (; g != NULL; g = g->next)
10036 {
dda8d76d 10037 sec = filedata->section_headers + g->section_index;
e4b17d5c 10038
84714f86
AM
10039 if (section_name_valid (filedata, sec)
10040 && streq (section_name (filedata, sec),
10041 ELF_STRING_ia64_unwind_info))
4082ef84
NC
10042 break;
10043 }
10044
10045 if (g == NULL)
dda8d76d 10046 i = filedata->file_header.e_shnum;
4082ef84 10047 }
e4b17d5c 10048 }
84714f86
AM
10049 else if (section_name_valid (filedata, unwsec)
10050 && startswith (section_name (filedata, unwsec),
e9b095a5 10051 ELF_STRING_ia64_unwind_once))
579f31ac 10052 {
18bd398b 10053 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 10054 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 10055 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
10056 for (i = 0, sec = filedata->section_headers;
10057 i < filedata->file_header.e_shnum;
579f31ac 10058 ++i, ++sec)
84714f86
AM
10059 if (section_name_valid (filedata, sec)
10060 && startswith (section_name (filedata, sec),
e9b095a5 10061 ELF_STRING_ia64_unwind_info_once)
84714f86 10062 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
10063 break;
10064 }
10065 else
10066 {
10067 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 10068 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
10069 len = sizeof (ELF_STRING_ia64_unwind) - 1;
10070 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
10071 suffix = "";
84714f86
AM
10072 if (section_name_valid (filedata, unwsec)
10073 && startswith (section_name (filedata, unwsec),
10074 ELF_STRING_ia64_unwind))
10075 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
10076 for (i = 0, sec = filedata->section_headers;
10077 i < filedata->file_header.e_shnum;
579f31ac 10078 ++i, ++sec)
84714f86
AM
10079 if (section_name_valid (filedata, sec)
10080 && startswith (section_name (filedata, sec),
10081 ELF_STRING_ia64_unwind_info)
10082 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
10083 break;
10084 }
10085
dda8d76d 10086 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
10087 {
10088 printf (_("\nCould not find unwind info section for "));
10089
dda8d76d 10090 if (filedata->string_table == NULL)
579f31ac
JJ
10091 printf ("%d", unwsec->sh_name);
10092 else
dda8d76d 10093 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
10094 }
10095 else
4d6ed7c8 10096 {
4d6ed7c8 10097 aux.info_addr = sec->sh_addr;
dda8d76d 10098 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
10099 sec->sh_size,
10100 _("unwind info"));
59245841 10101 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 10102
579f31ac 10103 printf (_("\nUnwind section "));
4d6ed7c8 10104
dda8d76d 10105 if (filedata->string_table == NULL)
579f31ac
JJ
10106 printf ("%d", unwsec->sh_name);
10107 else
dda8d76d 10108 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 10109
26c527e6
AM
10110 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
10111 unwsec->sh_offset,
10112 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 10113
dda8d76d 10114 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 10115 && aux.table_len > 0)
dda8d76d 10116 dump_ia64_unwind (filedata, & aux);
579f31ac 10117
9db70fc3
AM
10118 free ((char *) aux.table);
10119 free ((char *) aux.info);
579f31ac
JJ
10120 aux.table = NULL;
10121 aux.info = NULL;
10122 }
4d6ed7c8 10123 }
4d6ed7c8 10124
9db70fc3
AM
10125 free (aux.symtab);
10126 free ((char *) aux.strtab);
32ec8896
NC
10127
10128 return res;
4d6ed7c8
NC
10129}
10130
3f5e193b 10131struct hppa_unw_table_entry
32ec8896
NC
10132{
10133 struct absaddr start;
10134 struct absaddr end;
10135 unsigned int Cannot_unwind:1; /* 0 */
10136 unsigned int Millicode:1; /* 1 */
10137 unsigned int Millicode_save_sr0:1; /* 2 */
10138 unsigned int Region_description:2; /* 3..4 */
10139 unsigned int reserved1:1; /* 5 */
10140 unsigned int Entry_SR:1; /* 6 */
10141 unsigned int Entry_FR:4; /* Number saved 7..10 */
10142 unsigned int Entry_GR:5; /* Number saved 11..15 */
10143 unsigned int Args_stored:1; /* 16 */
10144 unsigned int Variable_Frame:1; /* 17 */
10145 unsigned int Separate_Package_Body:1; /* 18 */
10146 unsigned int Frame_Extension_Millicode:1; /* 19 */
10147 unsigned int Stack_Overflow_Check:1; /* 20 */
10148 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
10149 unsigned int Ada_Region:1; /* 22 */
10150 unsigned int cxx_info:1; /* 23 */
10151 unsigned int cxx_try_catch:1; /* 24 */
10152 unsigned int sched_entry_seq:1; /* 25 */
10153 unsigned int reserved2:1; /* 26 */
10154 unsigned int Save_SP:1; /* 27 */
10155 unsigned int Save_RP:1; /* 28 */
10156 unsigned int Save_MRP_in_frame:1; /* 29 */
10157 unsigned int extn_ptr_defined:1; /* 30 */
10158 unsigned int Cleanup_defined:1; /* 31 */
10159
10160 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
10161 unsigned int HP_UX_interrupt_marker:1; /* 1 */
10162 unsigned int Large_frame:1; /* 2 */
10163 unsigned int Pseudo_SP_Set:1; /* 3 */
10164 unsigned int reserved4:1; /* 4 */
10165 unsigned int Total_frame_size:27; /* 5..31 */
10166};
3f5e193b 10167
57346661 10168struct hppa_unw_aux_info
948f632f 10169{
32ec8896 10170 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 10171 uint64_t table_len; /* Length of unwind table. */
625d49fc 10172 uint64_t seg_base; /* Starting address of segment. */
32ec8896 10173 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 10174 uint64_t nsyms; /* Number of symbols. */
32ec8896 10175 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10176 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 10177 char * strtab; /* The string table. */
26c527e6 10178 uint64_t strtab_size; /* Size of string table. */
948f632f 10179};
57346661 10180
015dc7e1 10181static bool
dda8d76d 10182dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 10183{
2cf0635d 10184 struct hppa_unw_table_entry * tp;
26c527e6 10185 uint64_t j, nfuns;
015dc7e1 10186 bool res = true;
948f632f
DA
10187
10188 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10189 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10190 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10191 aux->funtab[nfuns++] = aux->symtab[j];
10192 aux->nfuns = nfuns;
10193 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 10194
57346661
AM
10195 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
10196 {
625d49fc 10197 uint64_t offset;
2cf0635d 10198 const char * procname;
57346661 10199
dda8d76d 10200 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
10201 aux->strtab_size, tp->start, &procname,
10202 &offset);
10203
10204 fputs ("\n<", stdout);
10205
10206 if (procname)
10207 {
10208 fputs (procname, stdout);
10209
10210 if (offset)
26c527e6 10211 printf ("+%" PRIx64, offset);
57346661
AM
10212 }
10213
10214 fputs (">: [", stdout);
10215 print_vma (tp->start.offset, PREFIX_HEX);
10216 fputc ('-', stdout);
10217 print_vma (tp->end.offset, PREFIX_HEX);
10218 printf ("]\n\t");
10219
18bd398b
NC
10220#define PF(_m) if (tp->_m) printf (#_m " ");
10221#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
10222 PF(Cannot_unwind);
10223 PF(Millicode);
10224 PF(Millicode_save_sr0);
18bd398b 10225 /* PV(Region_description); */
57346661
AM
10226 PF(Entry_SR);
10227 PV(Entry_FR);
10228 PV(Entry_GR);
10229 PF(Args_stored);
10230 PF(Variable_Frame);
10231 PF(Separate_Package_Body);
10232 PF(Frame_Extension_Millicode);
10233 PF(Stack_Overflow_Check);
10234 PF(Two_Instruction_SP_Increment);
10235 PF(Ada_Region);
10236 PF(cxx_info);
10237 PF(cxx_try_catch);
10238 PF(sched_entry_seq);
10239 PF(Save_SP);
10240 PF(Save_RP);
10241 PF(Save_MRP_in_frame);
10242 PF(extn_ptr_defined);
10243 PF(Cleanup_defined);
10244 PF(MPE_XL_interrupt_marker);
10245 PF(HP_UX_interrupt_marker);
10246 PF(Large_frame);
10247 PF(Pseudo_SP_Set);
10248 PV(Total_frame_size);
10249#undef PF
10250#undef PV
10251 }
10252
18bd398b 10253 printf ("\n");
948f632f
DA
10254
10255 free (aux->funtab);
32ec8896
NC
10256
10257 return res;
57346661
AM
10258}
10259
015dc7e1 10260static bool
dda8d76d
NC
10261slurp_hppa_unwind_table (Filedata * filedata,
10262 struct hppa_unw_aux_info * aux,
10263 Elf_Internal_Shdr * sec)
57346661 10264{
26c527e6 10265 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
10266 Elf_Internal_Phdr * seg;
10267 struct hppa_unw_table_entry * tep;
10268 Elf_Internal_Shdr * relsec;
10269 Elf_Internal_Rela * rela;
10270 Elf_Internal_Rela * rp;
10271 unsigned char * table;
10272 unsigned char * tp;
10273 Elf_Internal_Sym * sym;
10274 const char * relname;
57346661 10275
57346661
AM
10276 /* First, find the starting address of the segment that includes
10277 this section. */
dda8d76d 10278 if (filedata->file_header.e_phnum)
57346661 10279 {
dda8d76d 10280 if (! get_program_headers (filedata))
015dc7e1 10281 return false;
57346661 10282
dda8d76d
NC
10283 for (seg = filedata->program_headers;
10284 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
10285 ++seg)
10286 {
10287 if (seg->p_type != PT_LOAD)
10288 continue;
10289
10290 if (sec->sh_addr >= seg->p_vaddr
10291 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10292 {
10293 aux->seg_base = seg->p_vaddr;
10294 break;
10295 }
10296 }
10297 }
10298
10299 /* Second, build the unwind table from the contents of the unwind
10300 section. */
10301 size = sec->sh_size;
dda8d76d 10302 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 10303 _("unwind table"));
57346661 10304 if (!table)
015dc7e1 10305 return false;
57346661 10306
1c0751b2
DA
10307 unw_ent_size = 16;
10308 nentries = size / unw_ent_size;
10309 size = unw_ent_size * nentries;
57346661 10310
e3fdc001 10311 aux->table_len = nentries;
3f5e193b
NC
10312 tep = aux->table = (struct hppa_unw_table_entry *)
10313 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 10314
1c0751b2 10315 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
10316 {
10317 unsigned int tmp1, tmp2;
10318
10319 tep->start.section = SHN_UNDEF;
10320 tep->end.section = SHN_UNDEF;
10321
1c0751b2
DA
10322 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10323 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10324 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10325 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10326
10327 tep->start.offset += aux->seg_base;
10328 tep->end.offset += aux->seg_base;
57346661
AM
10329
10330 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10331 tep->Millicode = (tmp1 >> 30) & 0x1;
10332 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10333 tep->Region_description = (tmp1 >> 27) & 0x3;
10334 tep->reserved1 = (tmp1 >> 26) & 0x1;
10335 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10336 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10337 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10338 tep->Args_stored = (tmp1 >> 15) & 0x1;
10339 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10340 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10341 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10342 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10343 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10344 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10345 tep->cxx_info = (tmp1 >> 8) & 0x1;
10346 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10347 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10348 tep->reserved2 = (tmp1 >> 5) & 0x1;
10349 tep->Save_SP = (tmp1 >> 4) & 0x1;
10350 tep->Save_RP = (tmp1 >> 3) & 0x1;
10351 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10352 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10353 tep->Cleanup_defined = tmp1 & 0x1;
10354
10355 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10356 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10357 tep->Large_frame = (tmp2 >> 29) & 0x1;
10358 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10359 tep->reserved4 = (tmp2 >> 27) & 0x1;
10360 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
10361 }
10362 free (table);
10363
10364 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
10365 for (relsec = filedata->section_headers;
10366 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
10367 ++relsec)
10368 {
10369 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
10370 || relsec->sh_info >= filedata->file_header.e_shnum
10371 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
10372 continue;
10373
dda8d76d 10374 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 10375 & rela, & nrelas))
015dc7e1 10376 return false;
57346661
AM
10377
10378 for (rp = rela; rp < rela + nrelas; ++rp)
10379 {
4770fb94 10380 unsigned int sym_ndx;
726bd37d
AM
10381 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10382 relname = elf_hppa_reloc_type (r_type);
57346661 10383
726bd37d
AM
10384 if (relname == NULL)
10385 {
10386 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10387 continue;
10388 }
10389
57346661 10390 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 10391 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 10392 {
726bd37d 10393 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
10394 continue;
10395 }
10396
10397 i = rp->r_offset / unw_ent_size;
726bd37d
AM
10398 if (i >= aux->table_len)
10399 {
26c527e6
AM
10400 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10401 i);
726bd37d
AM
10402 continue;
10403 }
57346661 10404
4770fb94
AM
10405 sym_ndx = get_reloc_symindex (rp->r_info);
10406 if (sym_ndx >= aux->nsyms)
10407 {
10408 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10409 sym_ndx);
10410 continue;
10411 }
10412 sym = aux->symtab + sym_ndx;
10413
43f6cd05 10414 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
10415 {
10416 case 0:
10417 aux->table[i].start.section = sym->st_shndx;
1e456d54 10418 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
10419 break;
10420 case 1:
10421 aux->table[i].end.section = sym->st_shndx;
1e456d54 10422 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
10423 break;
10424 default:
10425 break;
10426 }
10427 }
10428
10429 free (rela);
10430 }
10431
015dc7e1 10432 return true;
57346661
AM
10433}
10434
015dc7e1 10435static bool
dda8d76d 10436hppa_process_unwind (Filedata * filedata)
57346661 10437{
57346661 10438 struct hppa_unw_aux_info aux;
2cf0635d 10439 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 10440 Elf_Internal_Shdr * sec;
26c527e6 10441 size_t i;
015dc7e1 10442 bool res = true;
57346661 10443
dda8d76d 10444 if (filedata->string_table == NULL)
015dc7e1 10445 return false;
1b31d05e
NC
10446
10447 memset (& aux, 0, sizeof (aux));
57346661 10448
dda8d76d 10449 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10450 {
28d13567 10451 if (sec->sh_type == SHT_SYMTAB)
57346661 10452 {
28d13567 10453 if (aux.symtab)
4082ef84 10454 {
28d13567
AM
10455 error (_("Multiple symbol tables encountered\n"));
10456 free (aux.symtab);
10457 aux.symtab = NULL;
4082ef84 10458 free (aux.strtab);
28d13567 10459 aux.strtab = NULL;
4082ef84 10460 }
28d13567
AM
10461 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10462 &aux.strtab, &aux.strtab_size))
015dc7e1 10463 return false;
57346661 10464 }
84714f86
AM
10465 else if (section_name_valid (filedata, sec)
10466 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
10467 unwsec = sec;
10468 }
10469
10470 if (!unwsec)
10471 printf (_("\nThere are no unwind sections in this file.\n"));
10472
dda8d76d 10473 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10474 {
84714f86
AM
10475 if (section_name_valid (filedata, sec)
10476 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 10477 {
26c527e6 10478 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 10479
26c527e6
AM
10480 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10481 "contains %" PRIu64 " entry:\n",
10482 "\nUnwind section '%s' at offset %#" PRIx64 " "
10483 "contains %" PRIu64 " entries:\n",
d3a49aa8 10484 num_unwind),
dda8d76d 10485 printable_section_name (filedata, sec),
26c527e6 10486 sec->sh_offset,
d3a49aa8 10487 num_unwind);
57346661 10488
dda8d76d 10489 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 10490 res = false;
66b09c7e
S
10491
10492 if (res && aux.table_len > 0)
32ec8896 10493 {
dda8d76d 10494 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 10495 res = false;
32ec8896 10496 }
57346661 10497
9db70fc3 10498 free ((char *) aux.table);
57346661
AM
10499 aux.table = NULL;
10500 }
10501 }
10502
9db70fc3
AM
10503 free (aux.symtab);
10504 free ((char *) aux.strtab);
32ec8896
NC
10505
10506 return res;
57346661
AM
10507}
10508
0b6ae522
DJ
10509struct arm_section
10510{
a734115a
NC
10511 unsigned char * data; /* The unwind data. */
10512 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10513 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 10514 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
10515 unsigned int rel_type; /* REL or RELA ? */
10516 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
10517};
10518
10519struct arm_unw_aux_info
10520{
dda8d76d 10521 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 10522 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 10523 uint64_t nsyms; /* Number of symbols. */
948f632f 10524 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10525 uint64_t nfuns; /* Number of these symbols. */
a734115a 10526 char * strtab; /* The file's string table. */
26c527e6 10527 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
10528};
10529
10530static const char *
dda8d76d
NC
10531arm_print_vma_and_name (Filedata * filedata,
10532 struct arm_unw_aux_info * aux,
625d49fc 10533 uint64_t fn,
dda8d76d 10534 struct absaddr addr)
0b6ae522
DJ
10535{
10536 const char *procname;
625d49fc 10537 uint64_t sym_offset;
0b6ae522
DJ
10538
10539 if (addr.section == SHN_UNDEF)
10540 addr.offset = fn;
10541
dda8d76d 10542 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
10543 aux->strtab_size, addr, &procname,
10544 &sym_offset);
10545
10546 print_vma (fn, PREFIX_HEX);
10547
10548 if (procname)
10549 {
10550 fputs (" <", stdout);
10551 fputs (procname, stdout);
10552
10553 if (sym_offset)
26c527e6 10554 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10555 fputc ('>', stdout);
10556 }
10557
10558 return procname;
10559}
10560
10561static void
10562arm_free_section (struct arm_section *arm_sec)
10563{
9db70fc3
AM
10564 free (arm_sec->data);
10565 free (arm_sec->rela);
0b6ae522
DJ
10566}
10567
a734115a
NC
10568/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10569 cached section and install SEC instead.
10570 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10571 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10572 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10573 relocation's offset in ADDR.
1b31d05e
NC
10574 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10575 into the string table of the symbol associated with the reloc. If no
10576 reloc was applied store -1 there.
10577 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10578
015dc7e1 10579static bool
dda8d76d
NC
10580get_unwind_section_word (Filedata * filedata,
10581 struct arm_unw_aux_info * aux,
1b31d05e
NC
10582 struct arm_section * arm_sec,
10583 Elf_Internal_Shdr * sec,
625d49fc 10584 uint64_t word_offset,
1b31d05e
NC
10585 unsigned int * wordp,
10586 struct absaddr * addr,
625d49fc 10587 uint64_t * sym_name)
0b6ae522
DJ
10588{
10589 Elf_Internal_Rela *rp;
10590 Elf_Internal_Sym *sym;
10591 const char * relname;
10592 unsigned int word;
015dc7e1 10593 bool wrapped;
0b6ae522 10594
e0a31db1 10595 if (sec == NULL || arm_sec == NULL)
015dc7e1 10596 return false;
e0a31db1 10597
0b6ae522
DJ
10598 addr->section = SHN_UNDEF;
10599 addr->offset = 0;
10600
1b31d05e 10601 if (sym_name != NULL)
625d49fc 10602 *sym_name = (uint64_t) -1;
1b31d05e 10603
a734115a 10604 /* If necessary, update the section cache. */
0b6ae522
DJ
10605 if (sec != arm_sec->sec)
10606 {
10607 Elf_Internal_Shdr *relsec;
10608
10609 arm_free_section (arm_sec);
10610
10611 arm_sec->sec = sec;
dda8d76d 10612 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10613 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10614 arm_sec->rela = NULL;
10615 arm_sec->nrelas = 0;
10616
dda8d76d
NC
10617 for (relsec = filedata->section_headers;
10618 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10619 ++relsec)
10620 {
dda8d76d
NC
10621 if (relsec->sh_info >= filedata->file_header.e_shnum
10622 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10623 /* PR 15745: Check the section type as well. */
10624 || (relsec->sh_type != SHT_REL
10625 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10626 continue;
10627
a734115a 10628 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10629 if (relsec->sh_type == SHT_REL)
10630 {
dda8d76d 10631 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10632 relsec->sh_size,
10633 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10634 return false;
0b6ae522 10635 }
1ae40aa4 10636 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10637 {
dda8d76d 10638 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10639 relsec->sh_size,
10640 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10641 return false;
0b6ae522 10642 }
1ae40aa4 10643 break;
0b6ae522
DJ
10644 }
10645
10646 arm_sec->next_rela = arm_sec->rela;
10647 }
10648
a734115a 10649 /* If there is no unwind data we can do nothing. */
0b6ae522 10650 if (arm_sec->data == NULL)
015dc7e1 10651 return false;
0b6ae522 10652
e0a31db1 10653 /* If the offset is invalid then fail. */
f32ba729
NC
10654 if (/* PR 21343 *//* PR 18879 */
10655 sec->sh_size < 4
625d49fc 10656 || word_offset > sec->sh_size - 4)
015dc7e1 10657 return false;
e0a31db1 10658
a734115a 10659 /* Get the word at the required offset. */
0b6ae522
DJ
10660 word = byte_get (arm_sec->data + word_offset, 4);
10661
0eff7165
NC
10662 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10663 if (arm_sec->rela == NULL)
10664 {
10665 * wordp = word;
015dc7e1 10666 return true;
0eff7165
NC
10667 }
10668
a734115a 10669 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10670 wrapped = false;
0b6ae522
DJ
10671 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10672 {
625d49fc 10673 uint64_t prelval, offset;
0b6ae522
DJ
10674
10675 if (rp->r_offset > word_offset && !wrapped)
10676 {
10677 rp = arm_sec->rela;
015dc7e1 10678 wrapped = true;
0b6ae522
DJ
10679 }
10680 if (rp->r_offset > word_offset)
10681 break;
10682
10683 if (rp->r_offset & 3)
10684 {
26c527e6
AM
10685 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10686 rp->r_offset);
0b6ae522
DJ
10687 continue;
10688 }
10689
10690 if (rp->r_offset < word_offset)
10691 continue;
10692
74e1a04b
NC
10693 /* PR 17531: file: 027-161405-0.004 */
10694 if (aux->symtab == NULL)
10695 continue;
10696
0b6ae522
DJ
10697 if (arm_sec->rel_type == SHT_REL)
10698 {
10699 offset = word & 0x7fffffff;
10700 if (offset & 0x40000000)
625d49fc 10701 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10702 }
a734115a 10703 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10704 offset = rp->r_addend;
a734115a 10705 else
74e1a04b
NC
10706 {
10707 error (_("Unknown section relocation type %d encountered\n"),
10708 arm_sec->rel_type);
10709 break;
10710 }
0b6ae522 10711
071436c6
NC
10712 /* PR 17531 file: 027-1241568-0.004. */
10713 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10714 {
26c527e6
AM
10715 error (_("Bad symbol index in unwind relocation "
10716 "(%" PRIu64 " > %" PRIu64 ")\n"),
10717 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10718 break;
10719 }
10720
10721 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10722 offset += sym->st_value;
10723 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10724
a734115a 10725 /* Check that we are processing the expected reloc type. */
dda8d76d 10726 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10727 {
10728 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10729 if (relname == NULL)
10730 {
10731 warn (_("Skipping unknown ARM relocation type: %d\n"),
10732 (int) ELF32_R_TYPE (rp->r_info));
10733 continue;
10734 }
a734115a
NC
10735
10736 if (streq (relname, "R_ARM_NONE"))
10737 continue;
0b4362b0 10738
a734115a
NC
10739 if (! streq (relname, "R_ARM_PREL31"))
10740 {
071436c6 10741 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10742 continue;
10743 }
10744 }
dda8d76d 10745 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10746 {
10747 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10748 if (relname == NULL)
10749 {
10750 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10751 (int) ELF32_R_TYPE (rp->r_info));
10752 continue;
10753 }
0b4362b0 10754
a734115a
NC
10755 if (streq (relname, "R_C6000_NONE"))
10756 continue;
10757
10758 if (! streq (relname, "R_C6000_PREL31"))
10759 {
071436c6 10760 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10761 continue;
10762 }
10763
10764 prelval >>= 1;
10765 }
10766 else
74e1a04b
NC
10767 {
10768 /* This function currently only supports ARM and TI unwinders. */
10769 warn (_("Only TI and ARM unwinders are currently supported\n"));
10770 break;
10771 }
fa197c1c 10772
625d49fc 10773 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10774 addr->section = sym->st_shndx;
10775 addr->offset = offset;
74e1a04b 10776
1b31d05e
NC
10777 if (sym_name)
10778 * sym_name = sym->st_name;
0b6ae522
DJ
10779 break;
10780 }
10781
10782 *wordp = word;
10783 arm_sec->next_rela = rp;
10784
015dc7e1 10785 return true;
0b6ae522
DJ
10786}
10787
a734115a
NC
10788static const char *tic6x_unwind_regnames[16] =
10789{
0b4362b0
RM
10790 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10791 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10792 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10793};
fa197c1c 10794
0b6ae522 10795static void
fa197c1c 10796decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10797{
fa197c1c
PB
10798 int i;
10799
10800 for (i = 12; mask; mask >>= 1, i--)
10801 {
10802 if (mask & 1)
10803 {
10804 fputs (tic6x_unwind_regnames[i], stdout);
10805 if (mask > 1)
10806 fputs (", ", stdout);
10807 }
10808 }
10809}
0b6ae522
DJ
10810
10811#define ADVANCE \
10812 if (remaining == 0 && more_words) \
10813 { \
10814 data_offset += 4; \
dda8d76d 10815 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10816 data_offset, & word, & addr, NULL)) \
015dc7e1 10817 return false; \
0b6ae522
DJ
10818 remaining = 4; \
10819 more_words--; \
10820 } \
10821
10822#define GET_OP(OP) \
10823 ADVANCE; \
10824 if (remaining) \
10825 { \
10826 remaining--; \
10827 (OP) = word >> 24; \
10828 word <<= 8; \
10829 } \
10830 else \
10831 { \
2b692964 10832 printf (_("[Truncated opcode]\n")); \
015dc7e1 10833 return false; \
0b6ae522 10834 } \
cc5914eb 10835 printf ("0x%02x ", OP)
0b6ae522 10836
015dc7e1 10837static bool
dda8d76d
NC
10838decode_arm_unwind_bytecode (Filedata * filedata,
10839 struct arm_unw_aux_info * aux,
948f632f
DA
10840 unsigned int word,
10841 unsigned int remaining,
10842 unsigned int more_words,
625d49fc 10843 uint64_t data_offset,
948f632f
DA
10844 Elf_Internal_Shdr * data_sec,
10845 struct arm_section * data_arm_sec)
fa197c1c
PB
10846{
10847 struct absaddr addr;
015dc7e1 10848 bool res = true;
0b6ae522
DJ
10849
10850 /* Decode the unwinding instructions. */
10851 while (1)
10852 {
10853 unsigned int op, op2;
10854
10855 ADVANCE;
10856 if (remaining == 0)
10857 break;
10858 remaining--;
10859 op = word >> 24;
10860 word <<= 8;
10861
cc5914eb 10862 printf (" 0x%02x ", op);
0b6ae522
DJ
10863
10864 if ((op & 0xc0) == 0x00)
10865 {
10866 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10867
cc5914eb 10868 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10869 }
10870 else if ((op & 0xc0) == 0x40)
10871 {
10872 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10873
cc5914eb 10874 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10875 }
10876 else if ((op & 0xf0) == 0x80)
10877 {
10878 GET_OP (op2);
10879 if (op == 0x80 && op2 == 0)
10880 printf (_("Refuse to unwind"));
10881 else
10882 {
10883 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10884 bool first = true;
0b6ae522 10885 int i;
2b692964 10886
0b6ae522
DJ
10887 printf ("pop {");
10888 for (i = 0; i < 12; i++)
10889 if (mask & (1 << i))
10890 {
10891 if (first)
015dc7e1 10892 first = false;
0b6ae522
DJ
10893 else
10894 printf (", ");
10895 printf ("r%d", 4 + i);
10896 }
10897 printf ("}");
10898 }
10899 }
10900 else if ((op & 0xf0) == 0x90)
10901 {
10902 if (op == 0x9d || op == 0x9f)
10903 printf (_(" [Reserved]"));
10904 else
cc5914eb 10905 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10906 }
10907 else if ((op & 0xf0) == 0xa0)
10908 {
10909 int end = 4 + (op & 0x07);
015dc7e1 10910 bool first = true;
0b6ae522 10911 int i;
61865e30 10912
0b6ae522
DJ
10913 printf (" pop {");
10914 for (i = 4; i <= end; i++)
10915 {
10916 if (first)
015dc7e1 10917 first = false;
0b6ae522
DJ
10918 else
10919 printf (", ");
10920 printf ("r%d", i);
10921 }
10922 if (op & 0x08)
10923 {
1b31d05e 10924 if (!first)
0b6ae522
DJ
10925 printf (", ");
10926 printf ("r14");
10927 }
10928 printf ("}");
10929 }
10930 else if (op == 0xb0)
10931 printf (_(" finish"));
10932 else if (op == 0xb1)
10933 {
10934 GET_OP (op2);
10935 if (op2 == 0 || (op2 & 0xf0) != 0)
10936 printf (_("[Spare]"));
10937 else
10938 {
10939 unsigned int mask = op2 & 0x0f;
015dc7e1 10940 bool first = true;
0b6ae522 10941 int i;
61865e30 10942
0b6ae522
DJ
10943 printf ("pop {");
10944 for (i = 0; i < 12; i++)
10945 if (mask & (1 << i))
10946 {
10947 if (first)
015dc7e1 10948 first = false;
0b6ae522
DJ
10949 else
10950 printf (", ");
10951 printf ("r%d", i);
10952 }
10953 printf ("}");
10954 }
10955 }
10956 else if (op == 0xb2)
10957 {
b115cf96 10958 unsigned char buf[9];
0b6ae522 10959 unsigned int i, len;
26c527e6 10960 uint64_t offset;
61865e30 10961
b115cf96 10962 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10963 {
10964 GET_OP (buf[i]);
10965 if ((buf[i] & 0x80) == 0)
10966 break;
10967 }
4082ef84 10968 if (i == sizeof (buf))
32ec8896 10969 {
27a45f42 10970 error (_("corrupt change to vsp\n"));
015dc7e1 10971 res = false;
32ec8896 10972 }
4082ef84
NC
10973 else
10974 {
015dc7e1 10975 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10976 assert (len == i + 1);
10977 offset = offset * 4 + 0x204;
26c527e6 10978 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10979 }
0b6ae522 10980 }
61865e30 10981 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10982 {
61865e30
NC
10983 unsigned int first, last;
10984
10985 GET_OP (op2);
10986 first = op2 >> 4;
10987 last = op2 & 0x0f;
10988 if (op == 0xc8)
10989 first = first + 16;
10990 printf ("pop {D%d", first);
10991 if (last)
10992 printf ("-D%d", first + last);
10993 printf ("}");
10994 }
09854a88
TB
10995 else if (op == 0xb4)
10996 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10997 else if (op == 0xb5)
10998 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10999 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
11000 {
11001 unsigned int count = op & 0x07;
11002
11003 printf ("pop {D8");
11004 if (count)
11005 printf ("-D%d", 8 + count);
11006 printf ("}");
11007 }
11008 else if (op >= 0xc0 && op <= 0xc5)
11009 {
11010 unsigned int count = op & 0x07;
11011
11012 printf (" pop {wR10");
11013 if (count)
11014 printf ("-wR%d", 10 + count);
11015 printf ("}");
11016 }
11017 else if (op == 0xc6)
11018 {
11019 unsigned int first, last;
11020
11021 GET_OP (op2);
11022 first = op2 >> 4;
11023 last = op2 & 0x0f;
11024 printf ("pop {wR%d", first);
11025 if (last)
11026 printf ("-wR%d", first + last);
11027 printf ("}");
11028 }
11029 else if (op == 0xc7)
11030 {
11031 GET_OP (op2);
11032 if (op2 == 0 || (op2 & 0xf0) != 0)
11033 printf (_("[Spare]"));
0b6ae522
DJ
11034 else
11035 {
61865e30 11036 unsigned int mask = op2 & 0x0f;
015dc7e1 11037 bool first = true;
61865e30
NC
11038 int i;
11039
11040 printf ("pop {");
11041 for (i = 0; i < 4; i++)
11042 if (mask & (1 << i))
11043 {
11044 if (first)
015dc7e1 11045 first = false;
61865e30
NC
11046 else
11047 printf (", ");
11048 printf ("wCGR%d", i);
11049 }
11050 printf ("}");
0b6ae522
DJ
11051 }
11052 }
61865e30 11053 else
32ec8896
NC
11054 {
11055 printf (_(" [unsupported opcode]"));
015dc7e1 11056 res = false;
32ec8896
NC
11057 }
11058
0b6ae522
DJ
11059 printf ("\n");
11060 }
32ec8896
NC
11061
11062 return res;
fa197c1c
PB
11063}
11064
015dc7e1 11065static bool
dda8d76d
NC
11066decode_tic6x_unwind_bytecode (Filedata * filedata,
11067 struct arm_unw_aux_info * aux,
948f632f
DA
11068 unsigned int word,
11069 unsigned int remaining,
11070 unsigned int more_words,
625d49fc 11071 uint64_t data_offset,
948f632f
DA
11072 Elf_Internal_Shdr * data_sec,
11073 struct arm_section * data_arm_sec)
fa197c1c
PB
11074{
11075 struct absaddr addr;
11076
11077 /* Decode the unwinding instructions. */
11078 while (1)
11079 {
11080 unsigned int op, op2;
11081
11082 ADVANCE;
11083 if (remaining == 0)
11084 break;
11085 remaining--;
11086 op = word >> 24;
11087 word <<= 8;
11088
9cf03b7e 11089 printf (" 0x%02x ", op);
fa197c1c
PB
11090
11091 if ((op & 0xc0) == 0x00)
11092 {
11093 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 11094 printf (" sp = sp + %d", offset);
fa197c1c
PB
11095 }
11096 else if ((op & 0xc0) == 0x80)
11097 {
11098 GET_OP (op2);
11099 if (op == 0x80 && op2 == 0)
11100 printf (_("Refuse to unwind"));
11101 else
11102 {
11103 unsigned int mask = ((op & 0x1f) << 8) | op2;
11104 if (op & 0x20)
11105 printf ("pop compact {");
11106 else
11107 printf ("pop {");
11108
11109 decode_tic6x_unwind_regmask (mask);
11110 printf("}");
11111 }
11112 }
11113 else if ((op & 0xf0) == 0xc0)
11114 {
11115 unsigned int reg;
11116 unsigned int nregs;
11117 unsigned int i;
11118 const char *name;
a734115a
NC
11119 struct
11120 {
32ec8896
NC
11121 unsigned int offset;
11122 unsigned int reg;
fa197c1c
PB
11123 } regpos[16];
11124
11125 /* Scan entire instruction first so that GET_OP output is not
11126 interleaved with disassembly. */
11127 nregs = 0;
11128 for (i = 0; nregs < (op & 0xf); i++)
11129 {
11130 GET_OP (op2);
11131 reg = op2 >> 4;
11132 if (reg != 0xf)
11133 {
11134 regpos[nregs].offset = i * 2;
11135 regpos[nregs].reg = reg;
11136 nregs++;
11137 }
11138
11139 reg = op2 & 0xf;
11140 if (reg != 0xf)
11141 {
11142 regpos[nregs].offset = i * 2 + 1;
11143 regpos[nregs].reg = reg;
11144 nregs++;
11145 }
11146 }
11147
11148 printf (_("pop frame {"));
18344509 11149 if (nregs == 0)
fa197c1c 11150 {
18344509
NC
11151 printf (_("*corrupt* - no registers specified"));
11152 }
11153 else
11154 {
11155 reg = nregs - 1;
11156 for (i = i * 2; i > 0; i--)
fa197c1c 11157 {
18344509
NC
11158 if (regpos[reg].offset == i - 1)
11159 {
11160 name = tic6x_unwind_regnames[regpos[reg].reg];
11161 if (reg > 0)
11162 reg--;
11163 }
11164 else
11165 name = _("[pad]");
fa197c1c 11166
18344509
NC
11167 fputs (name, stdout);
11168 if (i > 1)
11169 printf (", ");
11170 }
fa197c1c
PB
11171 }
11172
11173 printf ("}");
11174 }
11175 else if (op == 0xd0)
11176 printf (" MOV FP, SP");
11177 else if (op == 0xd1)
11178 printf (" __c6xabi_pop_rts");
11179 else if (op == 0xd2)
11180 {
11181 unsigned char buf[9];
11182 unsigned int i, len;
26c527e6 11183 uint64_t offset;
a734115a 11184
fa197c1c
PB
11185 for (i = 0; i < sizeof (buf); i++)
11186 {
11187 GET_OP (buf[i]);
11188 if ((buf[i] & 0x80) == 0)
11189 break;
11190 }
0eff7165
NC
11191 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
11192 if (i == sizeof (buf))
11193 {
0eff7165 11194 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 11195 return false;
0eff7165 11196 }
948f632f 11197
015dc7e1 11198 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
11199 assert (len == i + 1);
11200 offset = offset * 8 + 0x408;
26c527e6 11201 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
11202 }
11203 else if ((op & 0xf0) == 0xe0)
11204 {
11205 if ((op & 0x0f) == 7)
11206 printf (" RETURN");
11207 else
11208 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
11209 }
11210 else
11211 {
11212 printf (_(" [unsupported opcode]"));
11213 }
11214 putchar ('\n');
11215 }
32ec8896 11216
015dc7e1 11217 return true;
fa197c1c
PB
11218}
11219
625d49fc
AM
11220static uint64_t
11221arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 11222{
625d49fc 11223 uint64_t offset;
fa197c1c
PB
11224
11225 offset = word & 0x7fffffff;
11226 if (offset & 0x40000000)
625d49fc 11227 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 11228
dda8d76d 11229 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
11230 offset <<= 1;
11231
11232 return offset + where;
11233}
11234
015dc7e1 11235static bool
dda8d76d
NC
11236decode_arm_unwind (Filedata * filedata,
11237 struct arm_unw_aux_info * aux,
1b31d05e
NC
11238 unsigned int word,
11239 unsigned int remaining,
625d49fc 11240 uint64_t data_offset,
1b31d05e
NC
11241 Elf_Internal_Shdr * data_sec,
11242 struct arm_section * data_arm_sec)
fa197c1c
PB
11243{
11244 int per_index;
11245 unsigned int more_words = 0;
37e14bc3 11246 struct absaddr addr;
625d49fc 11247 uint64_t sym_name = (uint64_t) -1;
015dc7e1 11248 bool res = true;
fa197c1c
PB
11249
11250 if (remaining == 0)
11251 {
1b31d05e
NC
11252 /* Fetch the first word.
11253 Note - when decoding an object file the address extracted
11254 here will always be 0. So we also pass in the sym_name
11255 parameter so that we can find the symbol associated with
11256 the personality routine. */
dda8d76d 11257 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 11258 & word, & addr, & sym_name))
015dc7e1 11259 return false;
1b31d05e 11260
fa197c1c
PB
11261 remaining = 4;
11262 }
c93dbb25
CZ
11263 else
11264 {
11265 addr.section = SHN_UNDEF;
11266 addr.offset = 0;
11267 }
fa197c1c
PB
11268
11269 if ((word & 0x80000000) == 0)
11270 {
11271 /* Expand prel31 for personality routine. */
625d49fc 11272 uint64_t fn;
fa197c1c
PB
11273 const char *procname;
11274
dda8d76d 11275 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 11276 printf (_(" Personality routine: "));
1b31d05e
NC
11277 if (fn == 0
11278 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 11279 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
11280 {
11281 procname = aux->strtab + sym_name;
11282 print_vma (fn, PREFIX_HEX);
11283 if (procname)
11284 {
11285 fputs (" <", stdout);
11286 fputs (procname, stdout);
11287 fputc ('>', stdout);
11288 }
11289 }
11290 else
dda8d76d 11291 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
11292 fputc ('\n', stdout);
11293
11294 /* The GCC personality routines use the standard compact
11295 encoding, starting with one byte giving the number of
11296 words. */
11297 if (procname != NULL
24d127aa
ML
11298 && (startswith (procname, "__gcc_personality_v0")
11299 || startswith (procname, "__gxx_personality_v0")
11300 || startswith (procname, "__gcj_personality_v0")
11301 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
11302 {
11303 remaining = 0;
11304 more_words = 1;
11305 ADVANCE;
11306 if (!remaining)
11307 {
11308 printf (_(" [Truncated data]\n"));
015dc7e1 11309 return false;
fa197c1c
PB
11310 }
11311 more_words = word >> 24;
11312 word <<= 8;
11313 remaining--;
11314 per_index = -1;
11315 }
11316 else
015dc7e1 11317 return true;
fa197c1c
PB
11318 }
11319 else
11320 {
1b31d05e 11321 /* ARM EHABI Section 6.3:
0b4362b0 11322
1b31d05e 11323 An exception-handling table entry for the compact model looks like:
0b4362b0 11324
1b31d05e
NC
11325 31 30-28 27-24 23-0
11326 -- ----- ----- ----
11327 1 0 index Data for personalityRoutine[index] */
11328
dda8d76d 11329 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 11330 && (word & 0x70000000))
32ec8896
NC
11331 {
11332 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 11333 res = false;
32ec8896 11334 }
1b31d05e 11335
fa197c1c 11336 per_index = (word >> 24) & 0x7f;
1b31d05e 11337 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
11338 if (per_index == 0)
11339 {
11340 more_words = 0;
11341 word <<= 8;
11342 remaining--;
11343 }
11344 else if (per_index < 3)
11345 {
11346 more_words = (word >> 16) & 0xff;
11347 word <<= 16;
11348 remaining -= 2;
11349 }
11350 }
11351
dda8d76d 11352 switch (filedata->file_header.e_machine)
fa197c1c
PB
11353 {
11354 case EM_ARM:
11355 if (per_index < 3)
11356 {
dda8d76d 11357 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11358 data_offset, data_sec, data_arm_sec))
015dc7e1 11359 res = false;
fa197c1c
PB
11360 }
11361 else
1b31d05e
NC
11362 {
11363 warn (_("Unknown ARM compact model index encountered\n"));
11364 printf (_(" [reserved]\n"));
015dc7e1 11365 res = false;
1b31d05e 11366 }
fa197c1c
PB
11367 break;
11368
11369 case EM_TI_C6000:
11370 if (per_index < 3)
11371 {
dda8d76d 11372 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11373 data_offset, data_sec, data_arm_sec))
015dc7e1 11374 res = false;
fa197c1c
PB
11375 }
11376 else if (per_index < 5)
11377 {
11378 if (((word >> 17) & 0x7f) == 0x7f)
11379 printf (_(" Restore stack from frame pointer\n"));
11380 else
11381 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11382 printf (_(" Registers restored: "));
11383 if (per_index == 4)
11384 printf (" (compact) ");
11385 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11386 putchar ('\n');
11387 printf (_(" Return register: %s\n"),
11388 tic6x_unwind_regnames[word & 0xf]);
11389 }
11390 else
1b31d05e 11391 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
11392 break;
11393
11394 default:
74e1a04b 11395 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 11396 filedata->file_header.e_machine);
015dc7e1 11397 res = false;
fa197c1c 11398 }
0b6ae522
DJ
11399
11400 /* Decode the descriptors. Not implemented. */
32ec8896
NC
11401
11402 return res;
0b6ae522
DJ
11403}
11404
015dc7e1 11405static bool
dda8d76d
NC
11406dump_arm_unwind (Filedata * filedata,
11407 struct arm_unw_aux_info * aux,
11408 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
11409{
11410 struct arm_section exidx_arm_sec, extab_arm_sec;
11411 unsigned int i, exidx_len;
26c527e6 11412 uint64_t j, nfuns;
015dc7e1 11413 bool res = true;
0b6ae522
DJ
11414
11415 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11416 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11417 exidx_len = exidx_sec->sh_size / 8;
11418
948f632f
DA
11419 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11420 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11421 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11422 aux->funtab[nfuns++] = aux->symtab[j];
11423 aux->nfuns = nfuns;
11424 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11425
0b6ae522
DJ
11426 for (i = 0; i < exidx_len; i++)
11427 {
11428 unsigned int exidx_fn, exidx_entry;
11429 struct absaddr fn_addr, entry_addr;
625d49fc 11430 uint64_t fn;
0b6ae522
DJ
11431
11432 fputc ('\n', stdout);
11433
dda8d76d 11434 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11435 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 11436 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11437 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 11438 {
948f632f 11439 free (aux->funtab);
1b31d05e
NC
11440 arm_free_section (& exidx_arm_sec);
11441 arm_free_section (& extab_arm_sec);
015dc7e1 11442 return false;
0b6ae522
DJ
11443 }
11444
83c257ca
NC
11445 /* ARM EHABI, Section 5:
11446 An index table entry consists of 2 words.
11447 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11448 if (exidx_fn & 0x80000000)
32ec8896
NC
11449 {
11450 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 11451 res = false;
32ec8896 11452 }
83c257ca 11453
dda8d76d 11454 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 11455
dda8d76d 11456 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
11457 fputs (": ", stdout);
11458
11459 if (exidx_entry == 1)
11460 {
11461 print_vma (exidx_entry, PREFIX_HEX);
11462 fputs (" [cantunwind]\n", stdout);
11463 }
11464 else if (exidx_entry & 0x80000000)
11465 {
11466 print_vma (exidx_entry, PREFIX_HEX);
11467 fputc ('\n', stdout);
dda8d76d 11468 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
11469 }
11470 else
11471 {
625d49fc 11472 uint64_t table, table_offset = 0;
0b6ae522
DJ
11473 Elf_Internal_Shdr *table_sec;
11474
11475 fputs ("@", stdout);
dda8d76d 11476 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
11477 print_vma (table, PREFIX_HEX);
11478 printf ("\n");
11479
11480 /* Locate the matching .ARM.extab. */
11481 if (entry_addr.section != SHN_UNDEF
dda8d76d 11482 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 11483 {
dda8d76d 11484 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 11485 table_offset = entry_addr.offset;
1a915552 11486 /* PR 18879 */
625d49fc 11487 if (table_offset > table_sec->sh_size)
1a915552 11488 {
26c527e6
AM
11489 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11490 table_offset,
dda8d76d 11491 printable_section_name (filedata, table_sec));
015dc7e1 11492 res = false;
1a915552
NC
11493 continue;
11494 }
0b6ae522
DJ
11495 }
11496 else
11497 {
dda8d76d 11498 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
11499 if (table_sec != NULL)
11500 table_offset = table - table_sec->sh_addr;
11501 }
32ec8896 11502
0b6ae522
DJ
11503 if (table_sec == NULL)
11504 {
26c527e6
AM
11505 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11506 table);
015dc7e1 11507 res = false;
0b6ae522
DJ
11508 continue;
11509 }
32ec8896 11510
dda8d76d 11511 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 11512 &extab_arm_sec))
015dc7e1 11513 res = false;
0b6ae522
DJ
11514 }
11515 }
11516
11517 printf ("\n");
11518
948f632f 11519 free (aux->funtab);
0b6ae522
DJ
11520 arm_free_section (&exidx_arm_sec);
11521 arm_free_section (&extab_arm_sec);
32ec8896
NC
11522
11523 return res;
0b6ae522
DJ
11524}
11525
fa197c1c 11526/* Used for both ARM and C6X unwinding tables. */
1b31d05e 11527
015dc7e1 11528static bool
dda8d76d 11529arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
11530{
11531 struct arm_unw_aux_info aux;
11532 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 11533 Elf_Internal_Shdr *sec;
26c527e6 11534 size_t i;
fa197c1c 11535 unsigned int sec_type;
015dc7e1 11536 bool res = true;
0b6ae522 11537
dda8d76d 11538 switch (filedata->file_header.e_machine)
fa197c1c
PB
11539 {
11540 case EM_ARM:
11541 sec_type = SHT_ARM_EXIDX;
11542 break;
11543
11544 case EM_TI_C6000:
11545 sec_type = SHT_C6000_UNWIND;
11546 break;
11547
0b4362b0 11548 default:
74e1a04b 11549 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11550 filedata->file_header.e_machine);
015dc7e1 11551 return false;
fa197c1c
PB
11552 }
11553
dda8d76d 11554 if (filedata->string_table == NULL)
015dc7e1 11555 return false;
1b31d05e
NC
11556
11557 memset (& aux, 0, sizeof (aux));
dda8d76d 11558 aux.filedata = filedata;
0b6ae522 11559
dda8d76d 11560 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11561 {
28d13567 11562 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11563 {
28d13567 11564 if (aux.symtab)
74e1a04b 11565 {
28d13567
AM
11566 error (_("Multiple symbol tables encountered\n"));
11567 free (aux.symtab);
11568 aux.symtab = NULL;
74e1a04b 11569 free (aux.strtab);
28d13567 11570 aux.strtab = NULL;
74e1a04b 11571 }
28d13567
AM
11572 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11573 &aux.strtab, &aux.strtab_size))
015dc7e1 11574 return false;
0b6ae522 11575 }
fa197c1c 11576 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11577 unwsec = sec;
11578 }
11579
1b31d05e 11580 if (unwsec == NULL)
0b6ae522 11581 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11582 else
dda8d76d 11583 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11584 {
11585 if (sec->sh_type == sec_type)
11586 {
26c527e6
AM
11587 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11588 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11589 "contains %" PRIu64 " entry:\n",
11590 "\nUnwind section '%s' at offset %#" PRIx64 " "
11591 "contains %" PRIu64 " entries:\n",
d3a49aa8 11592 num_unwind),
dda8d76d 11593 printable_section_name (filedata, sec),
26c527e6 11594 sec->sh_offset,
d3a49aa8 11595 num_unwind);
0b6ae522 11596
dda8d76d 11597 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11598 res = false;
1b31d05e
NC
11599 }
11600 }
0b6ae522 11601
9db70fc3
AM
11602 free (aux.symtab);
11603 free ((char *) aux.strtab);
32ec8896
NC
11604
11605 return res;
0b6ae522
DJ
11606}
11607
3ecc00ec
NC
11608static bool
11609no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11610{
11611 printf (_("No processor specific unwind information to decode\n"));
11612 return true;
11613}
11614
015dc7e1 11615static bool
dda8d76d 11616process_unwind (Filedata * filedata)
57346661 11617{
2cf0635d
NC
11618 struct unwind_handler
11619 {
32ec8896 11620 unsigned int machtype;
015dc7e1 11621 bool (* handler)(Filedata *);
2cf0635d
NC
11622 } handlers[] =
11623 {
0b6ae522 11624 { EM_ARM, arm_process_unwind },
57346661
AM
11625 { EM_IA_64, ia64_process_unwind },
11626 { EM_PARISC, hppa_process_unwind },
fa197c1c 11627 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11628 { EM_386, no_processor_specific_unwind },
11629 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11630 { 0, NULL }
57346661
AM
11631 };
11632 int i;
11633
11634 if (!do_unwind)
015dc7e1 11635 return true;
57346661
AM
11636
11637 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11638 if (filedata->file_header.e_machine == handlers[i].machtype)
11639 return handlers[i].handler (filedata);
57346661 11640
1b31d05e 11641 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11642 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11643 return true;
57346661
AM
11644}
11645
37c18eed
SD
11646static void
11647dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11648{
11649 switch (entry->d_tag)
11650 {
11651 case DT_AARCH64_BTI_PLT:
1dbade74 11652 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11653 break;
11654 default:
11655 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11656 break;
11657 }
11658 putchar ('\n');
11659}
11660
252b5132 11661static void
978c4450 11662dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11663{
11664 switch (entry->d_tag)
11665 {
11666 case DT_MIPS_FLAGS:
11667 if (entry->d_un.d_val == 0)
4b68bca3 11668 printf (_("NONE"));
252b5132
RH
11669 else
11670 {
11671 static const char * opts[] =
11672 {
11673 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11674 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11675 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11676 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11677 "RLD_ORDER_SAFE"
11678 };
11679 unsigned int cnt;
015dc7e1 11680 bool first = true;
2b692964 11681
60bca95a 11682 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11683 if (entry->d_un.d_val & (1 << cnt))
11684 {
11685 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11686 first = false;
252b5132 11687 }
252b5132
RH
11688 }
11689 break;
103f02d3 11690
252b5132 11691 case DT_MIPS_IVERSION:
84714f86 11692 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11693 printf (_("Interface Version: %s"),
84714f86 11694 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11695 else
f493c217 11696 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11697 entry->d_un.d_ptr);
252b5132 11698 break;
103f02d3 11699
252b5132
RH
11700 case DT_MIPS_TIME_STAMP:
11701 {
d5b07ef4 11702 char timebuf[128];
2cf0635d 11703 struct tm * tmp;
91d6fa6a 11704 time_t atime = entry->d_un.d_val;
82b1b41b 11705
91d6fa6a 11706 tmp = gmtime (&atime);
82b1b41b
NC
11707 /* PR 17531: file: 6accc532. */
11708 if (tmp == NULL)
11709 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11710 else
11711 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11712 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11713 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11714 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11715 }
11716 break;
103f02d3 11717
252b5132
RH
11718 case DT_MIPS_RLD_VERSION:
11719 case DT_MIPS_LOCAL_GOTNO:
11720 case DT_MIPS_CONFLICTNO:
11721 case DT_MIPS_LIBLISTNO:
11722 case DT_MIPS_SYMTABNO:
11723 case DT_MIPS_UNREFEXTNO:
11724 case DT_MIPS_HIPAGENO:
11725 case DT_MIPS_DELTA_CLASS_NO:
11726 case DT_MIPS_DELTA_INSTANCE_NO:
11727 case DT_MIPS_DELTA_RELOC_NO:
11728 case DT_MIPS_DELTA_SYM_NO:
11729 case DT_MIPS_DELTA_CLASSSYM_NO:
11730 case DT_MIPS_COMPACT_SIZE:
c69075ac 11731 print_vma (entry->d_un.d_val, DEC);
252b5132 11732 break;
103f02d3 11733
f16a9783 11734 case DT_MIPS_XHASH:
978c4450
AM
11735 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11736 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11737 /* Falls through. */
11738
103f02d3 11739 default:
4b68bca3 11740 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11741 }
4b68bca3 11742 putchar ('\n');
103f02d3
UD
11743}
11744
103f02d3 11745static void
2cf0635d 11746dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11747{
11748 switch (entry->d_tag)
11749 {
11750 case DT_HP_DLD_FLAGS:
11751 {
11752 static struct
11753 {
26c527e6 11754 unsigned int bit;
2cf0635d 11755 const char * str;
5e220199
NC
11756 }
11757 flags[] =
11758 {
11759 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11760 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11761 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11762 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11763 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11764 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11765 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11766 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11767 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11768 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11769 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11770 { DT_HP_GST, "HP_GST" },
11771 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11772 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11773 { DT_HP_NODELETE, "HP_NODELETE" },
11774 { DT_HP_GROUP, "HP_GROUP" },
11775 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11776 };
015dc7e1 11777 bool first = true;
5e220199 11778 size_t cnt;
625d49fc 11779 uint64_t val = entry->d_un.d_val;
103f02d3 11780
60bca95a 11781 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11782 if (val & flags[cnt].bit)
30800947
NC
11783 {
11784 if (! first)
11785 putchar (' ');
11786 fputs (flags[cnt].str, stdout);
015dc7e1 11787 first = false;
30800947
NC
11788 val ^= flags[cnt].bit;
11789 }
76da6bbe 11790
103f02d3 11791 if (val != 0 || first)
f7a99963
NC
11792 {
11793 if (! first)
11794 putchar (' ');
11795 print_vma (val, HEX);
11796 }
103f02d3
UD
11797 }
11798 break;
76da6bbe 11799
252b5132 11800 default:
f7a99963
NC
11801 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11802 break;
252b5132 11803 }
35b1837e 11804 putchar ('\n');
252b5132
RH
11805}
11806
28f997cf
TG
11807/* VMS vs Unix time offset and factor. */
11808
11809#define VMS_EPOCH_OFFSET 35067168000000000LL
11810#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11811#ifndef INT64_MIN
11812#define INT64_MIN (-9223372036854775807LL - 1)
11813#endif
28f997cf
TG
11814
11815/* Display a VMS time in a human readable format. */
11816
11817static void
0e3c1eeb 11818print_vms_time (int64_t vmstime)
28f997cf 11819{
dccc31de 11820 struct tm *tm = NULL;
28f997cf
TG
11821 time_t unxtime;
11822
dccc31de
AM
11823 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11824 {
11825 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11826 unxtime = vmstime;
11827 if (unxtime == vmstime)
11828 tm = gmtime (&unxtime);
11829 }
11830 if (tm != NULL)
11831 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11832 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11833 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11834}
28f997cf 11835
ecc51f48 11836static void
2cf0635d 11837dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11838{
11839 switch (entry->d_tag)
11840 {
0de14b54 11841 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11842 /* First 3 slots reserved. */
ecc51f48
NC
11843 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11844 printf (" -- ");
11845 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11846 break;
11847
28f997cf 11848 case DT_IA_64_VMS_LINKTIME:
28f997cf 11849 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11850 break;
11851
11852 case DT_IA_64_VMS_LNKFLAGS:
11853 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11854 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11855 printf (" CALL_DEBUG");
11856 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11857 printf (" NOP0BUFS");
11858 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11859 printf (" P0IMAGE");
11860 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11861 printf (" MKTHREADS");
11862 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11863 printf (" UPCALLS");
11864 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11865 printf (" IMGSTA");
11866 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11867 printf (" INITIALIZE");
11868 if (entry->d_un.d_val & VMS_LF_MAIN)
11869 printf (" MAIN");
11870 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11871 printf (" EXE_INIT");
11872 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11873 printf (" TBK_IN_IMG");
11874 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11875 printf (" DBG_IN_IMG");
11876 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11877 printf (" TBK_IN_DSF");
11878 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11879 printf (" DBG_IN_DSF");
11880 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11881 printf (" SIGNATURES");
11882 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11883 printf (" REL_SEG_OFF");
11884 break;
11885
bdf4d63a
JJ
11886 default:
11887 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11888 break;
ecc51f48 11889 }
bdf4d63a 11890 putchar ('\n');
ecc51f48
NC
11891}
11892
015dc7e1 11893static bool
dda8d76d 11894get_32bit_dynamic_section (Filedata * filedata)
252b5132 11895{
2cf0635d
NC
11896 Elf32_External_Dyn * edyn;
11897 Elf32_External_Dyn * ext;
11898 Elf_Internal_Dyn * entry;
103f02d3 11899
978c4450
AM
11900 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11901 filedata->dynamic_addr, 1,
11902 filedata->dynamic_size,
11903 _("dynamic section"));
a6e9f9df 11904 if (!edyn)
015dc7e1 11905 return false;
103f02d3 11906
071436c6
NC
11907 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11908 might not have the luxury of section headers. Look for the DT_NULL
11909 terminator to determine the number of entries. */
978c4450
AM
11910 for (ext = edyn, filedata->dynamic_nent = 0;
11911 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11912 ext++)
11913 {
978c4450 11914 filedata->dynamic_nent++;
ba2685cc
AM
11915 if (BYTE_GET (ext->d_tag) == DT_NULL)
11916 break;
11917 }
252b5132 11918
978c4450
AM
11919 filedata->dynamic_section
11920 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11921 if (filedata->dynamic_section == NULL)
252b5132 11922 {
26c527e6
AM
11923 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11924 filedata->dynamic_nent);
9ea033b2 11925 free (edyn);
015dc7e1 11926 return false;
9ea033b2 11927 }
252b5132 11928
978c4450
AM
11929 for (ext = edyn, entry = filedata->dynamic_section;
11930 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11931 ext++, entry++)
9ea033b2 11932 {
fb514b26
AM
11933 entry->d_tag = BYTE_GET (ext->d_tag);
11934 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11935 }
11936
9ea033b2
NC
11937 free (edyn);
11938
015dc7e1 11939 return true;
9ea033b2
NC
11940}
11941
015dc7e1 11942static bool
dda8d76d 11943get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11944{
2cf0635d
NC
11945 Elf64_External_Dyn * edyn;
11946 Elf64_External_Dyn * ext;
11947 Elf_Internal_Dyn * entry;
103f02d3 11948
071436c6 11949 /* Read in the data. */
978c4450
AM
11950 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11951 filedata->dynamic_addr, 1,
11952 filedata->dynamic_size,
11953 _("dynamic section"));
a6e9f9df 11954 if (!edyn)
015dc7e1 11955 return false;
103f02d3 11956
071436c6
NC
11957 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11958 might not have the luxury of section headers. Look for the DT_NULL
11959 terminator to determine the number of entries. */
978c4450 11960 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11961 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11962 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11963 ext++)
11964 {
978c4450 11965 filedata->dynamic_nent++;
66543521 11966 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11967 break;
11968 }
252b5132 11969
978c4450
AM
11970 filedata->dynamic_section
11971 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11972 if (filedata->dynamic_section == NULL)
252b5132 11973 {
26c527e6
AM
11974 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11975 filedata->dynamic_nent);
252b5132 11976 free (edyn);
015dc7e1 11977 return false;
252b5132
RH
11978 }
11979
071436c6 11980 /* Convert from external to internal formats. */
978c4450
AM
11981 for (ext = edyn, entry = filedata->dynamic_section;
11982 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11983 ext++, entry++)
252b5132 11984 {
66543521
AM
11985 entry->d_tag = BYTE_GET (ext->d_tag);
11986 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11987 }
11988
11989 free (edyn);
11990
015dc7e1 11991 return true;
9ea033b2
NC
11992}
11993
4de91c10
AM
11994static bool
11995get_dynamic_section (Filedata *filedata)
11996{
11997 if (filedata->dynamic_section)
11998 return true;
11999
12000 if (is_32bit_elf)
12001 return get_32bit_dynamic_section (filedata);
12002 else
12003 return get_64bit_dynamic_section (filedata);
12004}
12005
e9e44622 12006static void
625d49fc 12007print_dynamic_flags (uint64_t flags)
d1133906 12008{
015dc7e1 12009 bool first = true;
13ae64f3 12010
d1133906
NC
12011 while (flags)
12012 {
625d49fc 12013 uint64_t flag;
d1133906
NC
12014
12015 flag = flags & - flags;
12016 flags &= ~ flag;
12017
e9e44622 12018 if (first)
015dc7e1 12019 first = false;
e9e44622
JJ
12020 else
12021 putc (' ', stdout);
13ae64f3 12022
d1133906
NC
12023 switch (flag)
12024 {
e9e44622
JJ
12025 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
12026 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
12027 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
12028 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
12029 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 12030 default: fputs (_("unknown"), stdout); break;
d1133906
NC
12031 }
12032 }
e9e44622 12033 puts ("");
d1133906
NC
12034}
12035
625d49fc 12036static uint64_t *
be7d229a 12037get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
12038{
12039 unsigned char * e_data;
625d49fc 12040 uint64_t * i_data;
10ca4b04 12041
be7d229a
AM
12042 /* If size_t is smaller than uint64_t, eg because you are building
12043 on a 32-bit host, then make sure that when number is cast to
12044 size_t no information is lost. */
12045 if ((size_t) number != number
12046 || ent_size * number / ent_size != number)
10ca4b04 12047 {
be7d229a 12048 error (_("Size overflow prevents reading %" PRIu64
b8281767 12049 " elements of size %u\n"),
be7d229a 12050 number, ent_size);
10ca4b04
L
12051 return NULL;
12052 }
12053
12054 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
12055 attempting to allocate memory when the read is bound to fail. */
12056 if (ent_size * number > filedata->file_size)
12057 {
b8281767 12058 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 12059 number);
10ca4b04
L
12060 return NULL;
12061 }
12062
12063 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
12064 if (e_data == NULL)
12065 {
b8281767 12066 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 12067 number);
10ca4b04
L
12068 return NULL;
12069 }
12070
12071 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
12072 {
b8281767 12073 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 12074 number * ent_size);
10ca4b04
L
12075 free (e_data);
12076 return NULL;
12077 }
12078
625d49fc 12079 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
12080 if (i_data == NULL)
12081 {
b8281767 12082 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 12083 number);
10ca4b04
L
12084 free (e_data);
12085 return NULL;
12086 }
12087
12088 while (number--)
12089 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
12090
12091 free (e_data);
12092
12093 return i_data;
12094}
12095
26c527e6 12096static uint64_t
10ca4b04
L
12097get_num_dynamic_syms (Filedata * filedata)
12098{
26c527e6 12099 uint64_t num_of_syms = 0;
10ca4b04
L
12100
12101 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
12102 return num_of_syms;
12103
978c4450 12104 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
12105 {
12106 unsigned char nb[8];
12107 unsigned char nc[8];
12108 unsigned int hash_ent_size = 4;
12109
12110 if ((filedata->file_header.e_machine == EM_ALPHA
12111 || filedata->file_header.e_machine == EM_S390
12112 || filedata->file_header.e_machine == EM_S390_OLD)
12113 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
12114 hash_ent_size = 8;
12115
63cf857e
AM
12116 if (fseek64 (filedata->handle,
12117 (filedata->archive_file_offset
12118 + offset_from_vma (filedata,
12119 filedata->dynamic_info[DT_HASH],
12120 sizeof nb + sizeof nc)),
12121 SEEK_SET))
10ca4b04
L
12122 {
12123 error (_("Unable to seek to start of dynamic information\n"));
12124 goto no_hash;
12125 }
12126
12127 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
12128 {
12129 error (_("Failed to read in number of buckets\n"));
12130 goto no_hash;
12131 }
12132
12133 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
12134 {
12135 error (_("Failed to read in number of chains\n"));
12136 goto no_hash;
12137 }
12138
978c4450
AM
12139 filedata->nbuckets = byte_get (nb, hash_ent_size);
12140 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 12141
2482f306
AM
12142 if (filedata->nbuckets != 0 && filedata->nchains != 0)
12143 {
12144 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
12145 hash_ent_size);
12146 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
12147 hash_ent_size);
001890e1 12148
2482f306
AM
12149 if (filedata->buckets != NULL && filedata->chains != NULL)
12150 num_of_syms = filedata->nchains;
12151 }
ceb9bf11 12152 no_hash:
10ca4b04
L
12153 if (num_of_syms == 0)
12154 {
9db70fc3
AM
12155 free (filedata->buckets);
12156 filedata->buckets = NULL;
12157 free (filedata->chains);
12158 filedata->chains = NULL;
978c4450 12159 filedata->nbuckets = 0;
10ca4b04
L
12160 }
12161 }
12162
978c4450 12163 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
12164 {
12165 unsigned char nb[16];
625d49fc
AM
12166 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
12167 uint64_t buckets_vma;
26c527e6 12168 uint64_t hn;
10ca4b04 12169
63cf857e
AM
12170 if (fseek64 (filedata->handle,
12171 (filedata->archive_file_offset
12172 + offset_from_vma (filedata,
12173 filedata->dynamic_info_DT_GNU_HASH,
12174 sizeof nb)),
12175 SEEK_SET))
10ca4b04
L
12176 {
12177 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12178 goto no_gnu_hash;
12179 }
12180
12181 if (fread (nb, 16, 1, filedata->handle) != 1)
12182 {
12183 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
12184 goto no_gnu_hash;
12185 }
12186
978c4450
AM
12187 filedata->ngnubuckets = byte_get (nb, 4);
12188 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 12189 bitmaskwords = byte_get (nb + 8, 4);
978c4450 12190 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
12191 if (is_32bit_elf)
12192 buckets_vma += bitmaskwords * 4;
12193 else
12194 buckets_vma += bitmaskwords * 8;
12195
63cf857e
AM
12196 if (fseek64 (filedata->handle,
12197 (filedata->archive_file_offset
12198 + offset_from_vma (filedata, buckets_vma, 4)),
12199 SEEK_SET))
10ca4b04
L
12200 {
12201 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12202 goto no_gnu_hash;
12203 }
12204
978c4450
AM
12205 filedata->gnubuckets
12206 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 12207
978c4450 12208 if (filedata->gnubuckets == NULL)
90837ea7 12209 goto no_gnu_hash;
10ca4b04 12210
978c4450
AM
12211 for (i = 0; i < filedata->ngnubuckets; i++)
12212 if (filedata->gnubuckets[i] != 0)
10ca4b04 12213 {
978c4450 12214 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 12215 goto no_gnu_hash;
10ca4b04 12216
978c4450
AM
12217 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
12218 maxchain = filedata->gnubuckets[i];
10ca4b04
L
12219 }
12220
12221 if (maxchain == 0xffffffff)
90837ea7 12222 goto no_gnu_hash;
10ca4b04 12223
978c4450 12224 maxchain -= filedata->gnusymidx;
10ca4b04 12225
63cf857e
AM
12226 if (fseek64 (filedata->handle,
12227 (filedata->archive_file_offset
12228 + offset_from_vma (filedata,
12229 buckets_vma + 4 * (filedata->ngnubuckets
12230 + maxchain),
12231 4)),
12232 SEEK_SET))
10ca4b04
L
12233 {
12234 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12235 goto no_gnu_hash;
12236 }
12237
12238 do
12239 {
12240 if (fread (nb, 4, 1, filedata->handle) != 1)
12241 {
12242 error (_("Failed to determine last chain length\n"));
10ca4b04
L
12243 goto no_gnu_hash;
12244 }
12245
12246 if (maxchain + 1 == 0)
90837ea7 12247 goto no_gnu_hash;
10ca4b04
L
12248
12249 ++maxchain;
12250 }
12251 while ((byte_get (nb, 4) & 1) == 0);
12252
63cf857e
AM
12253 if (fseek64 (filedata->handle,
12254 (filedata->archive_file_offset
12255 + offset_from_vma (filedata, (buckets_vma
12256 + 4 * filedata->ngnubuckets),
12257 4)),
12258 SEEK_SET))
10ca4b04
L
12259 {
12260 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12261 goto no_gnu_hash;
12262 }
12263
978c4450
AM
12264 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
12265 filedata->ngnuchains = maxchain;
10ca4b04 12266
978c4450 12267 if (filedata->gnuchains == NULL)
90837ea7 12268 goto no_gnu_hash;
10ca4b04 12269
978c4450 12270 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12271 {
63cf857e
AM
12272 if (fseek64 (filedata->handle,
12273 (filedata->archive_file_offset
12274 + offset_from_vma (filedata, (buckets_vma
12275 + 4 * (filedata->ngnubuckets
12276 + maxchain)), 4)),
12277 SEEK_SET))
10ca4b04
L
12278 {
12279 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12280 goto no_gnu_hash;
12281 }
12282
978c4450 12283 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
12284 if (filedata->mipsxlat == NULL)
12285 goto no_gnu_hash;
10ca4b04
L
12286 }
12287
978c4450
AM
12288 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12289 if (filedata->gnubuckets[hn] != 0)
10ca4b04 12290 {
625d49fc
AM
12291 uint64_t si = filedata->gnubuckets[hn];
12292 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
12293
12294 do
12295 {
978c4450 12296 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12297 {
c31ab5a0
AM
12298 if (off < filedata->ngnuchains
12299 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 12300 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
12301 }
12302 else
12303 {
12304 if (si >= num_of_syms)
12305 num_of_syms = si + 1;
12306 }
12307 si++;
12308 }
978c4450
AM
12309 while (off < filedata->ngnuchains
12310 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
12311 }
12312
90837ea7 12313 if (num_of_syms == 0)
10ca4b04 12314 {
90837ea7 12315 no_gnu_hash:
9db70fc3
AM
12316 free (filedata->mipsxlat);
12317 filedata->mipsxlat = NULL;
12318 free (filedata->gnuchains);
12319 filedata->gnuchains = NULL;
12320 free (filedata->gnubuckets);
12321 filedata->gnubuckets = NULL;
978c4450
AM
12322 filedata->ngnubuckets = 0;
12323 filedata->ngnuchains = 0;
10ca4b04
L
12324 }
12325 }
12326
12327 return num_of_syms;
12328}
12329
b2d38a17
NC
12330/* Parse and display the contents of the dynamic section. */
12331
015dc7e1 12332static bool
dda8d76d 12333process_dynamic_section (Filedata * filedata)
9ea033b2 12334{
2cf0635d 12335 Elf_Internal_Dyn * entry;
9ea033b2 12336
93df3340 12337 if (filedata->dynamic_size <= 1)
9ea033b2
NC
12338 {
12339 if (do_dynamic)
ca0e11aa
NC
12340 {
12341 if (filedata->is_separate)
12342 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
12343 filedata->file_name);
12344 else
12345 printf (_("\nThere is no dynamic section in this file.\n"));
12346 }
9ea033b2 12347
015dc7e1 12348 return true;
9ea033b2
NC
12349 }
12350
4de91c10
AM
12351 if (!get_dynamic_section (filedata))
12352 return false;
9ea033b2 12353
252b5132 12354 /* Find the appropriate symbol table. */
978c4450 12355 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 12356 {
26c527e6 12357 uint64_t num_of_syms;
2482f306 12358
978c4450
AM
12359 for (entry = filedata->dynamic_section;
12360 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12361 ++entry)
10ca4b04 12362 if (entry->d_tag == DT_SYMTAB)
978c4450 12363 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 12364 else if (entry->d_tag == DT_SYMENT)
978c4450 12365 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 12366 else if (entry->d_tag == DT_HASH)
978c4450 12367 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 12368 else if (entry->d_tag == DT_GNU_HASH)
978c4450 12369 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
12370 else if ((filedata->file_header.e_machine == EM_MIPS
12371 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12372 && entry->d_tag == DT_MIPS_XHASH)
12373 {
978c4450
AM
12374 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12375 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 12376 }
252b5132 12377
2482f306
AM
12378 num_of_syms = get_num_dynamic_syms (filedata);
12379
12380 if (num_of_syms != 0
12381 && filedata->dynamic_symbols == NULL
12382 && filedata->dynamic_info[DT_SYMTAB]
978c4450 12383 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
12384 {
12385 Elf_Internal_Phdr *seg;
625d49fc 12386 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 12387
2482f306
AM
12388 if (! get_program_headers (filedata))
12389 {
12390 error (_("Cannot interpret virtual addresses "
12391 "without program headers.\n"));
015dc7e1 12392 return false;
2482f306 12393 }
252b5132 12394
2482f306
AM
12395 for (seg = filedata->program_headers;
12396 seg < filedata->program_headers + filedata->file_header.e_phnum;
12397 ++seg)
12398 {
12399 if (seg->p_type != PT_LOAD)
12400 continue;
252b5132 12401
2482f306
AM
12402 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12403 {
12404 /* See PR 21379 for a reproducer. */
12405 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 12406 return false;
2482f306 12407 }
252b5132 12408
2482f306
AM
12409 if (vma >= (seg->p_vaddr & -seg->p_align)
12410 && vma < seg->p_vaddr + seg->p_filesz)
12411 {
12412 /* Since we do not know how big the symbol table is,
12413 we default to reading in up to the end of PT_LOAD
12414 segment and processing that. This is overkill, I
12415 know, but it should work. */
12416 Elf_Internal_Shdr section;
12417 section.sh_offset = (vma - seg->p_vaddr
12418 + seg->p_offset);
12419 section.sh_size = (num_of_syms
12420 * filedata->dynamic_info[DT_SYMENT]);
12421 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
12422
12423 if (do_checks
12424 && filedata->dynamic_symtab_section != NULL
12425 && ((filedata->dynamic_symtab_section->sh_offset
12426 != section.sh_offset)
12427 || (filedata->dynamic_symtab_section->sh_size
12428 != section.sh_size)
12429 || (filedata->dynamic_symtab_section->sh_entsize
12430 != section.sh_entsize)))
12431 warn (_("\
12432the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12433
2482f306
AM
12434 section.sh_name = filedata->string_table_length;
12435 filedata->dynamic_symbols
4de91c10 12436 = get_elf_symbols (filedata, &section,
2482f306
AM
12437 &filedata->num_dynamic_syms);
12438 if (filedata->dynamic_symbols == NULL
12439 || filedata->num_dynamic_syms != num_of_syms)
12440 {
12441 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 12442 return false;
2482f306
AM
12443 }
12444 break;
12445 }
12446 }
12447 }
12448 }
252b5132
RH
12449
12450 /* Similarly find a string table. */
978c4450
AM
12451 if (filedata->dynamic_strings == NULL)
12452 for (entry = filedata->dynamic_section;
12453 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
12454 ++entry)
12455 {
12456 if (entry->d_tag == DT_STRTAB)
978c4450 12457 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 12458
10ca4b04 12459 if (entry->d_tag == DT_STRSZ)
978c4450 12460 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 12461
978c4450
AM
12462 if (filedata->dynamic_info[DT_STRTAB]
12463 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 12464 {
26c527e6 12465 uint64_t offset;
be7d229a 12466 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
12467
12468 offset = offset_from_vma (filedata,
978c4450 12469 filedata->dynamic_info[DT_STRTAB],
10ca4b04 12470 str_tab_len);
8ac10c5b
L
12471 if (do_checks
12472 && filedata->dynamic_strtab_section
12473 && ((filedata->dynamic_strtab_section->sh_offset
12474 != (file_ptr) offset)
12475 || (filedata->dynamic_strtab_section->sh_size
12476 != str_tab_len)))
12477 warn (_("\
12478the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12479
978c4450
AM
12480 filedata->dynamic_strings
12481 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12482 _("dynamic string table"));
12483 if (filedata->dynamic_strings == NULL)
10ca4b04
L
12484 {
12485 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12486 break;
12487 }
e3d39609 12488
978c4450 12489 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
12490 break;
12491 }
12492 }
252b5132
RH
12493
12494 /* And find the syminfo section if available. */
978c4450 12495 if (filedata->dynamic_syminfo == NULL)
252b5132 12496 {
26c527e6 12497 uint64_t syminsz = 0;
252b5132 12498
978c4450
AM
12499 for (entry = filedata->dynamic_section;
12500 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12501 ++entry)
252b5132
RH
12502 {
12503 if (entry->d_tag == DT_SYMINENT)
12504 {
12505 /* Note: these braces are necessary to avoid a syntax
12506 error from the SunOS4 C compiler. */
049b0c3a
NC
12507 /* PR binutils/17531: A corrupt file can trigger this test.
12508 So do not use an assert, instead generate an error message. */
12509 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 12510 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 12511 (int) entry->d_un.d_val);
252b5132
RH
12512 }
12513 else if (entry->d_tag == DT_SYMINSZ)
12514 syminsz = entry->d_un.d_val;
12515 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
12516 filedata->dynamic_syminfo_offset
12517 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
12518 }
12519
978c4450 12520 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 12521 {
2cf0635d
NC
12522 Elf_External_Syminfo * extsyminfo;
12523 Elf_External_Syminfo * extsym;
12524 Elf_Internal_Syminfo * syminfo;
252b5132
RH
12525
12526 /* There is a syminfo section. Read the data. */
3f5e193b 12527 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
12528 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12529 1, syminsz, _("symbol information"));
a6e9f9df 12530 if (!extsyminfo)
015dc7e1 12531 return false;
252b5132 12532
978c4450 12533 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
12534 {
12535 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 12536 free (filedata->dynamic_syminfo);
e3d39609 12537 }
978c4450
AM
12538 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12539 if (filedata->dynamic_syminfo == NULL)
252b5132 12540 {
26c527e6
AM
12541 error (_("Out of memory allocating %" PRIu64
12542 " bytes for dynamic symbol info\n"),
12543 syminsz);
015dc7e1 12544 return false;
252b5132
RH
12545 }
12546
2482f306
AM
12547 filedata->dynamic_syminfo_nent
12548 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12549 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12550 syminfo < (filedata->dynamic_syminfo
12551 + filedata->dynamic_syminfo_nent);
86dba8ee 12552 ++syminfo, ++extsym)
252b5132 12553 {
86dba8ee
AM
12554 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12555 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12556 }
12557
12558 free (extsyminfo);
12559 }
12560 }
12561
978c4450 12562 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12563 {
f253158f 12564 if (filedata->is_separate)
26c527e6
AM
12565 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12566 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12567 filedata->dynamic_nent),
f253158f
NC
12568 filedata->file_name,
12569 filedata->dynamic_addr,
26c527e6 12570 filedata->dynamic_nent);
84a9f195 12571 else
02da71ee 12572 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12573 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12574 filedata->dynamic_nent),
84a9f195 12575 filedata->dynamic_addr,
26c527e6 12576 filedata->dynamic_nent);
ca0e11aa 12577 }
252b5132
RH
12578 if (do_dynamic)
12579 printf (_(" Tag Type Name/Value\n"));
12580
978c4450
AM
12581 for (entry = filedata->dynamic_section;
12582 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12583 entry++)
252b5132
RH
12584 {
12585 if (do_dynamic)
f7a99963 12586 {
2cf0635d 12587 const char * dtype;
e699b9ff 12588
f7a99963
NC
12589 putchar (' ');
12590 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12591 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12592 printf (" (%s)%*s", dtype,
32ec8896 12593 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12594 }
252b5132
RH
12595
12596 switch (entry->d_tag)
12597 {
d1133906
NC
12598 case DT_FLAGS:
12599 if (do_dynamic)
e9e44622 12600 print_dynamic_flags (entry->d_un.d_val);
d1133906 12601 break;
76da6bbe 12602
252b5132
RH
12603 case DT_AUXILIARY:
12604 case DT_FILTER:
019148e4
L
12605 case DT_CONFIG:
12606 case DT_DEPAUDIT:
12607 case DT_AUDIT:
252b5132
RH
12608 if (do_dynamic)
12609 {
019148e4 12610 switch (entry->d_tag)
b34976b6 12611 {
019148e4
L
12612 case DT_AUXILIARY:
12613 printf (_("Auxiliary library"));
12614 break;
12615
12616 case DT_FILTER:
12617 printf (_("Filter library"));
12618 break;
12619
b34976b6 12620 case DT_CONFIG:
019148e4
L
12621 printf (_("Configuration file"));
12622 break;
12623
12624 case DT_DEPAUDIT:
12625 printf (_("Dependency audit library"));
12626 break;
12627
12628 case DT_AUDIT:
12629 printf (_("Audit library"));
12630 break;
12631 }
252b5132 12632
84714f86 12633 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12634 printf (": [%s]\n",
84714f86 12635 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12636 else
f7a99963
NC
12637 {
12638 printf (": ");
12639 print_vma (entry->d_un.d_val, PREFIX_HEX);
12640 putchar ('\n');
12641 }
252b5132
RH
12642 }
12643 break;
12644
dcefbbbd 12645 case DT_FEATURE:
252b5132
RH
12646 if (do_dynamic)
12647 {
12648 printf (_("Flags:"));
86f55779 12649
252b5132
RH
12650 if (entry->d_un.d_val == 0)
12651 printf (_(" None\n"));
12652 else
12653 {
26c527e6 12654 uint64_t val = entry->d_un.d_val;
86f55779 12655
252b5132
RH
12656 if (val & DTF_1_PARINIT)
12657 {
12658 printf (" PARINIT");
12659 val ^= DTF_1_PARINIT;
12660 }
dcefbbbd
L
12661 if (val & DTF_1_CONFEXP)
12662 {
12663 printf (" CONFEXP");
12664 val ^= DTF_1_CONFEXP;
12665 }
252b5132 12666 if (val != 0)
26c527e6 12667 printf (" %" PRIx64, val);
252b5132
RH
12668 puts ("");
12669 }
12670 }
12671 break;
12672
12673 case DT_POSFLAG_1:
12674 if (do_dynamic)
12675 {
12676 printf (_("Flags:"));
86f55779 12677
252b5132
RH
12678 if (entry->d_un.d_val == 0)
12679 printf (_(" None\n"));
12680 else
12681 {
26c527e6 12682 uint64_t val = entry->d_un.d_val;
86f55779 12683
252b5132
RH
12684 if (val & DF_P1_LAZYLOAD)
12685 {
12686 printf (" LAZYLOAD");
12687 val ^= DF_P1_LAZYLOAD;
12688 }
12689 if (val & DF_P1_GROUPPERM)
12690 {
12691 printf (" GROUPPERM");
12692 val ^= DF_P1_GROUPPERM;
12693 }
12694 if (val != 0)
26c527e6 12695 printf (" %" PRIx64, val);
252b5132
RH
12696 puts ("");
12697 }
12698 }
12699 break;
12700
12701 case DT_FLAGS_1:
12702 if (do_dynamic)
12703 {
12704 printf (_("Flags:"));
12705 if (entry->d_un.d_val == 0)
12706 printf (_(" None\n"));
12707 else
12708 {
26c527e6 12709 uint64_t val = entry->d_un.d_val;
86f55779 12710
252b5132
RH
12711 if (val & DF_1_NOW)
12712 {
12713 printf (" NOW");
12714 val ^= DF_1_NOW;
12715 }
12716 if (val & DF_1_GLOBAL)
12717 {
12718 printf (" GLOBAL");
12719 val ^= DF_1_GLOBAL;
12720 }
12721 if (val & DF_1_GROUP)
12722 {
12723 printf (" GROUP");
12724 val ^= DF_1_GROUP;
12725 }
12726 if (val & DF_1_NODELETE)
12727 {
12728 printf (" NODELETE");
12729 val ^= DF_1_NODELETE;
12730 }
12731 if (val & DF_1_LOADFLTR)
12732 {
12733 printf (" LOADFLTR");
12734 val ^= DF_1_LOADFLTR;
12735 }
12736 if (val & DF_1_INITFIRST)
12737 {
12738 printf (" INITFIRST");
12739 val ^= DF_1_INITFIRST;
12740 }
12741 if (val & DF_1_NOOPEN)
12742 {
12743 printf (" NOOPEN");
12744 val ^= DF_1_NOOPEN;
12745 }
12746 if (val & DF_1_ORIGIN)
12747 {
12748 printf (" ORIGIN");
12749 val ^= DF_1_ORIGIN;
12750 }
12751 if (val & DF_1_DIRECT)
12752 {
12753 printf (" DIRECT");
12754 val ^= DF_1_DIRECT;
12755 }
12756 if (val & DF_1_TRANS)
12757 {
12758 printf (" TRANS");
12759 val ^= DF_1_TRANS;
12760 }
12761 if (val & DF_1_INTERPOSE)
12762 {
12763 printf (" INTERPOSE");
12764 val ^= DF_1_INTERPOSE;
12765 }
f7db6139 12766 if (val & DF_1_NODEFLIB)
dcefbbbd 12767 {
f7db6139
L
12768 printf (" NODEFLIB");
12769 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12770 }
12771 if (val & DF_1_NODUMP)
12772 {
12773 printf (" NODUMP");
12774 val ^= DF_1_NODUMP;
12775 }
34b60028 12776 if (val & DF_1_CONFALT)
dcefbbbd 12777 {
34b60028
L
12778 printf (" CONFALT");
12779 val ^= DF_1_CONFALT;
12780 }
12781 if (val & DF_1_ENDFILTEE)
12782 {
12783 printf (" ENDFILTEE");
12784 val ^= DF_1_ENDFILTEE;
12785 }
12786 if (val & DF_1_DISPRELDNE)
12787 {
12788 printf (" DISPRELDNE");
12789 val ^= DF_1_DISPRELDNE;
12790 }
12791 if (val & DF_1_DISPRELPND)
12792 {
12793 printf (" DISPRELPND");
12794 val ^= DF_1_DISPRELPND;
12795 }
12796 if (val & DF_1_NODIRECT)
12797 {
12798 printf (" NODIRECT");
12799 val ^= DF_1_NODIRECT;
12800 }
12801 if (val & DF_1_IGNMULDEF)
12802 {
12803 printf (" IGNMULDEF");
12804 val ^= DF_1_IGNMULDEF;
12805 }
12806 if (val & DF_1_NOKSYMS)
12807 {
12808 printf (" NOKSYMS");
12809 val ^= DF_1_NOKSYMS;
12810 }
12811 if (val & DF_1_NOHDR)
12812 {
12813 printf (" NOHDR");
12814 val ^= DF_1_NOHDR;
12815 }
12816 if (val & DF_1_EDITED)
12817 {
12818 printf (" EDITED");
12819 val ^= DF_1_EDITED;
12820 }
12821 if (val & DF_1_NORELOC)
12822 {
12823 printf (" NORELOC");
12824 val ^= DF_1_NORELOC;
12825 }
12826 if (val & DF_1_SYMINTPOSE)
12827 {
12828 printf (" SYMINTPOSE");
12829 val ^= DF_1_SYMINTPOSE;
12830 }
12831 if (val & DF_1_GLOBAUDIT)
12832 {
12833 printf (" GLOBAUDIT");
12834 val ^= DF_1_GLOBAUDIT;
12835 }
12836 if (val & DF_1_SINGLETON)
12837 {
12838 printf (" SINGLETON");
12839 val ^= DF_1_SINGLETON;
dcefbbbd 12840 }
5c383f02
RO
12841 if (val & DF_1_STUB)
12842 {
12843 printf (" STUB");
12844 val ^= DF_1_STUB;
12845 }
12846 if (val & DF_1_PIE)
12847 {
12848 printf (" PIE");
12849 val ^= DF_1_PIE;
12850 }
b1202ffa
L
12851 if (val & DF_1_KMOD)
12852 {
12853 printf (" KMOD");
12854 val ^= DF_1_KMOD;
12855 }
12856 if (val & DF_1_WEAKFILTER)
12857 {
12858 printf (" WEAKFILTER");
12859 val ^= DF_1_WEAKFILTER;
12860 }
12861 if (val & DF_1_NOCOMMON)
12862 {
12863 printf (" NOCOMMON");
12864 val ^= DF_1_NOCOMMON;
12865 }
252b5132 12866 if (val != 0)
26c527e6 12867 printf (" %" PRIx64, val);
252b5132
RH
12868 puts ("");
12869 }
12870 }
12871 break;
12872
12873 case DT_PLTREL:
978c4450 12874 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12875 if (do_dynamic)
dda8d76d 12876 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12877 break;
12878
12879 case DT_NULL :
12880 case DT_NEEDED :
12881 case DT_PLTGOT :
12882 case DT_HASH :
12883 case DT_STRTAB :
12884 case DT_SYMTAB :
12885 case DT_RELA :
12886 case DT_INIT :
12887 case DT_FINI :
12888 case DT_SONAME :
12889 case DT_RPATH :
12890 case DT_SYMBOLIC:
12891 case DT_REL :
a7fd1186 12892 case DT_RELR :
252b5132
RH
12893 case DT_DEBUG :
12894 case DT_TEXTREL :
12895 case DT_JMPREL :
019148e4 12896 case DT_RUNPATH :
978c4450 12897 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12898
12899 if (do_dynamic)
12900 {
84714f86 12901 const char *name;
252b5132 12902
84714f86
AM
12903 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12904 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12905 else
d79b3d50 12906 name = NULL;
252b5132
RH
12907
12908 if (name)
12909 {
12910 switch (entry->d_tag)
12911 {
12912 case DT_NEEDED:
12913 printf (_("Shared library: [%s]"), name);
12914
13acb58d
AM
12915 if (filedata->program_interpreter
12916 && streq (name, filedata->program_interpreter))
f7a99963 12917 printf (_(" program interpreter"));
252b5132
RH
12918 break;
12919
12920 case DT_SONAME:
f7a99963 12921 printf (_("Library soname: [%s]"), name);
252b5132
RH
12922 break;
12923
12924 case DT_RPATH:
f7a99963 12925 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12926 break;
12927
019148e4
L
12928 case DT_RUNPATH:
12929 printf (_("Library runpath: [%s]"), name);
12930 break;
12931
252b5132 12932 default:
f7a99963
NC
12933 print_vma (entry->d_un.d_val, PREFIX_HEX);
12934 break;
252b5132
RH
12935 }
12936 }
12937 else
f7a99963
NC
12938 print_vma (entry->d_un.d_val, PREFIX_HEX);
12939
12940 putchar ('\n');
252b5132
RH
12941 }
12942 break;
12943
12944 case DT_PLTRELSZ:
12945 case DT_RELASZ :
12946 case DT_STRSZ :
12947 case DT_RELSZ :
12948 case DT_RELAENT :
a7fd1186
FS
12949 case DT_RELRENT :
12950 case DT_RELRSZ :
252b5132
RH
12951 case DT_SYMENT :
12952 case DT_RELENT :
978c4450 12953 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12954 /* Fall through. */
252b5132
RH
12955 case DT_PLTPADSZ:
12956 case DT_MOVEENT :
12957 case DT_MOVESZ :
04d8355a 12958 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12959 case DT_INIT_ARRAYSZ:
12960 case DT_FINI_ARRAYSZ:
047b2264
JJ
12961 case DT_GNU_CONFLICTSZ:
12962 case DT_GNU_LIBLISTSZ:
252b5132 12963 if (do_dynamic)
f7a99963
NC
12964 {
12965 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12966 printf (_(" (bytes)\n"));
f7a99963 12967 }
252b5132
RH
12968 break;
12969
12970 case DT_VERDEFNUM:
12971 case DT_VERNEEDNUM:
12972 case DT_RELACOUNT:
12973 case DT_RELCOUNT:
12974 if (do_dynamic)
f7a99963
NC
12975 {
12976 print_vma (entry->d_un.d_val, UNSIGNED);
12977 putchar ('\n');
12978 }
252b5132
RH
12979 break;
12980
12981 case DT_SYMINSZ:
12982 case DT_SYMINENT:
12983 case DT_SYMINFO:
12984 case DT_USED:
12985 case DT_INIT_ARRAY:
12986 case DT_FINI_ARRAY:
12987 if (do_dynamic)
12988 {
d79b3d50 12989 if (entry->d_tag == DT_USED
84714f86 12990 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12991 {
84714f86
AM
12992 const char *name
12993 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12994
b34976b6 12995 if (*name)
252b5132
RH
12996 {
12997 printf (_("Not needed object: [%s]\n"), name);
12998 break;
12999 }
13000 }
103f02d3 13001
f7a99963
NC
13002 print_vma (entry->d_un.d_val, PREFIX_HEX);
13003 putchar ('\n');
252b5132
RH
13004 }
13005 break;
13006
13007 case DT_BIND_NOW:
13008 /* The value of this entry is ignored. */
35b1837e
AM
13009 if (do_dynamic)
13010 putchar ('\n');
252b5132 13011 break;
103f02d3 13012
047b2264
JJ
13013 case DT_GNU_PRELINKED:
13014 if (do_dynamic)
13015 {
2cf0635d 13016 struct tm * tmp;
91d6fa6a 13017 time_t atime = entry->d_un.d_val;
047b2264 13018
91d6fa6a 13019 tmp = gmtime (&atime);
071436c6
NC
13020 /* PR 17533 file: 041-1244816-0.004. */
13021 if (tmp == NULL)
26c527e6
AM
13022 printf (_("<corrupt time val: %" PRIx64),
13023 (uint64_t) atime);
071436c6
NC
13024 else
13025 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
13026 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13027 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13028
13029 }
13030 break;
13031
fdc90cb4 13032 case DT_GNU_HASH:
978c4450 13033 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
13034 if (do_dynamic)
13035 {
13036 print_vma (entry->d_un.d_val, PREFIX_HEX);
13037 putchar ('\n');
13038 }
13039 break;
13040
a5da3dee
VDM
13041 case DT_GNU_FLAGS_1:
13042 if (do_dynamic)
13043 {
13044 printf (_("Flags:"));
13045 if (entry->d_un.d_val == 0)
13046 printf (_(" None\n"));
13047 else
13048 {
26c527e6 13049 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
13050
13051 if (val & DF_GNU_1_UNIQUE)
13052 {
13053 printf (" UNIQUE");
13054 val ^= DF_GNU_1_UNIQUE;
13055 }
13056 if (val != 0)
26c527e6 13057 printf (" %" PRIx64, val);
a5da3dee
VDM
13058 puts ("");
13059 }
13060 }
13061 break;
13062
252b5132
RH
13063 default:
13064 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
13065 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
13066 = entry->d_un.d_val;
252b5132
RH
13067
13068 if (do_dynamic)
13069 {
dda8d76d 13070 switch (filedata->file_header.e_machine)
252b5132 13071 {
37c18eed
SD
13072 case EM_AARCH64:
13073 dynamic_section_aarch64_val (entry);
13074 break;
252b5132 13075 case EM_MIPS:
4fe85591 13076 case EM_MIPS_RS3_LE:
978c4450 13077 dynamic_section_mips_val (filedata, entry);
252b5132 13078 break;
103f02d3 13079 case EM_PARISC:
b2d38a17 13080 dynamic_section_parisc_val (entry);
103f02d3 13081 break;
ecc51f48 13082 case EM_IA_64:
b2d38a17 13083 dynamic_section_ia64_val (entry);
ecc51f48 13084 break;
252b5132 13085 default:
f7a99963
NC
13086 print_vma (entry->d_un.d_val, PREFIX_HEX);
13087 putchar ('\n');
252b5132
RH
13088 }
13089 }
13090 break;
13091 }
13092 }
13093
015dc7e1 13094 return true;
252b5132
RH
13095}
13096
13097static char *
d3ba0551 13098get_ver_flags (unsigned int flags)
252b5132 13099{
6d4f21f6 13100 static char buff[128];
252b5132
RH
13101
13102 buff[0] = 0;
13103
13104 if (flags == 0)
13105 return _("none");
13106
13107 if (flags & VER_FLG_BASE)
7bb1ad17 13108 strcat (buff, "BASE");
252b5132
RH
13109
13110 if (flags & VER_FLG_WEAK)
13111 {
13112 if (flags & VER_FLG_BASE)
7bb1ad17 13113 strcat (buff, " | ");
252b5132 13114
7bb1ad17 13115 strcat (buff, "WEAK");
252b5132
RH
13116 }
13117
44ec90b9
RO
13118 if (flags & VER_FLG_INFO)
13119 {
13120 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 13121 strcat (buff, " | ");
44ec90b9 13122
7bb1ad17 13123 strcat (buff, "INFO");
44ec90b9
RO
13124 }
13125
13126 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
13127 {
13128 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13129 strcat (buff, " | ");
13130
13131 strcat (buff, _("<unknown>"));
13132 }
252b5132
RH
13133
13134 return buff;
13135}
13136
13137/* Display the contents of the version sections. */
98fb390a 13138
015dc7e1 13139static bool
dda8d76d 13140process_version_sections (Filedata * filedata)
252b5132 13141{
2cf0635d 13142 Elf_Internal_Shdr * section;
b34976b6 13143 unsigned i;
015dc7e1 13144 bool found = false;
252b5132
RH
13145
13146 if (! do_version)
015dc7e1 13147 return true;
252b5132 13148
dda8d76d
NC
13149 for (i = 0, section = filedata->section_headers;
13150 i < filedata->file_header.e_shnum;
b34976b6 13151 i++, section++)
252b5132
RH
13152 {
13153 switch (section->sh_type)
13154 {
13155 case SHT_GNU_verdef:
13156 {
2cf0635d 13157 Elf_External_Verdef * edefs;
26c527e6
AM
13158 size_t idx;
13159 size_t cnt;
2cf0635d 13160 char * endbuf;
252b5132 13161
015dc7e1 13162 found = true;
252b5132 13163
ca0e11aa
NC
13164 if (filedata->is_separate)
13165 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
13166 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
13167 section->sh_info),
13168 filedata->file_name,
13169 printable_section_name (filedata, section),
13170 section->sh_info);
13171 else
13172 printf (ngettext ("\nVersion definition section '%s' "
13173 "contains %u entry:\n",
13174 "\nVersion definition section '%s' "
13175 "contains %u entries:\n",
13176 section->sh_info),
13177 printable_section_name (filedata, section),
13178 section->sh_info);
047c3dbf 13179
625d49fc 13180 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13181 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13182 section->sh_offset, section->sh_link,
b6ac461a 13183 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 13184
3f5e193b 13185 edefs = (Elf_External_Verdef *)
dda8d76d 13186 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 13187 _("version definition section"));
a6e9f9df
AM
13188 if (!edefs)
13189 break;
59245841 13190 endbuf = (char *) edefs + section->sh_size;
252b5132 13191
1445030f 13192 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 13193 {
2cf0635d
NC
13194 char * vstart;
13195 Elf_External_Verdef * edef;
b34976b6 13196 Elf_Internal_Verdef ent;
2cf0635d 13197 Elf_External_Verdaux * eaux;
b34976b6 13198 Elf_Internal_Verdaux aux;
26c527e6 13199 size_t isum;
b34976b6 13200 int j;
103f02d3 13201
252b5132 13202 vstart = ((char *) edefs) + idx;
54806181
AM
13203 if (vstart + sizeof (*edef) > endbuf)
13204 break;
252b5132
RH
13205
13206 edef = (Elf_External_Verdef *) vstart;
13207
13208 ent.vd_version = BYTE_GET (edef->vd_version);
13209 ent.vd_flags = BYTE_GET (edef->vd_flags);
13210 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
13211 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
13212 ent.vd_hash = BYTE_GET (edef->vd_hash);
13213 ent.vd_aux = BYTE_GET (edef->vd_aux);
13214 ent.vd_next = BYTE_GET (edef->vd_next);
13215
26c527e6 13216 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
13217 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
13218
13219 printf (_(" Index: %d Cnt: %d "),
13220 ent.vd_ndx, ent.vd_cnt);
13221
452bf675 13222 /* Check for overflow. */
1445030f 13223 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
13224 break;
13225
252b5132
RH
13226 vstart += ent.vd_aux;
13227
1445030f
AM
13228 if (vstart + sizeof (*eaux) > endbuf)
13229 break;
252b5132
RH
13230 eaux = (Elf_External_Verdaux *) vstart;
13231
13232 aux.vda_name = BYTE_GET (eaux->vda_name);
13233 aux.vda_next = BYTE_GET (eaux->vda_next);
13234
84714f86 13235 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 13236 printf (_("Name: %s\n"),
84714f86 13237 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
13238 else
13239 printf (_("Name index: %ld\n"), aux.vda_name);
13240
13241 isum = idx + ent.vd_aux;
13242
b34976b6 13243 for (j = 1; j < ent.vd_cnt; j++)
252b5132 13244 {
1445030f
AM
13245 if (aux.vda_next < sizeof (*eaux)
13246 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
13247 {
13248 warn (_("Invalid vda_next field of %lx\n"),
13249 aux.vda_next);
13250 j = ent.vd_cnt;
13251 break;
13252 }
dd24e3da 13253 /* Check for overflow. */
7e26601c 13254 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
13255 break;
13256
252b5132
RH
13257 isum += aux.vda_next;
13258 vstart += aux.vda_next;
13259
54806181
AM
13260 if (vstart + sizeof (*eaux) > endbuf)
13261 break;
1445030f 13262 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
13263
13264 aux.vda_name = BYTE_GET (eaux->vda_name);
13265 aux.vda_next = BYTE_GET (eaux->vda_next);
13266
84714f86 13267 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 13268 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 13269 isum, j,
84714f86 13270 get_dynamic_name (filedata, aux.vda_name));
252b5132 13271 else
26c527e6 13272 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
13273 isum, j, aux.vda_name);
13274 }
dd24e3da 13275
54806181
AM
13276 if (j < ent.vd_cnt)
13277 printf (_(" Version def aux past end of section\n"));
252b5132 13278
c9f02c3e
MR
13279 /* PR 17531:
13280 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
13281 if (ent.vd_next < sizeof (*edef)
13282 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13283 {
13284 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13285 cnt = section->sh_info;
13286 break;
13287 }
452bf675 13288 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
13289 break;
13290
252b5132
RH
13291 idx += ent.vd_next;
13292 }
dd24e3da 13293
54806181
AM
13294 if (cnt < section->sh_info)
13295 printf (_(" Version definition past end of section\n"));
252b5132
RH
13296
13297 free (edefs);
13298 }
13299 break;
103f02d3 13300
252b5132
RH
13301 case SHT_GNU_verneed:
13302 {
2cf0635d 13303 Elf_External_Verneed * eneed;
26c527e6
AM
13304 size_t idx;
13305 size_t cnt;
2cf0635d 13306 char * endbuf;
252b5132 13307
015dc7e1 13308 found = true;
252b5132 13309
ca0e11aa
NC
13310 if (filedata->is_separate)
13311 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13312 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13313 section->sh_info),
13314 filedata->file_name,
13315 printable_section_name (filedata, section),
13316 section->sh_info);
13317 else
13318 printf (ngettext ("\nVersion needs section '%s' "
13319 "contains %u entry:\n",
13320 "\nVersion needs section '%s' "
13321 "contains %u entries:\n",
13322 section->sh_info),
13323 printable_section_name (filedata, section),
13324 section->sh_info);
047c3dbf 13325
625d49fc 13326 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13327 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13328 section->sh_offset, section->sh_link,
b6ac461a 13329 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 13330
dda8d76d 13331 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
13332 section->sh_offset, 1,
13333 section->sh_size,
9cf03b7e 13334 _("Version Needs section"));
a6e9f9df
AM
13335 if (!eneed)
13336 break;
59245841 13337 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
13338
13339 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13340 {
2cf0635d 13341 Elf_External_Verneed * entry;
b34976b6 13342 Elf_Internal_Verneed ent;
26c527e6 13343 size_t isum;
b34976b6 13344 int j;
2cf0635d 13345 char * vstart;
252b5132
RH
13346
13347 vstart = ((char *) eneed) + idx;
54806181
AM
13348 if (vstart + sizeof (*entry) > endbuf)
13349 break;
252b5132
RH
13350
13351 entry = (Elf_External_Verneed *) vstart;
13352
13353 ent.vn_version = BYTE_GET (entry->vn_version);
13354 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13355 ent.vn_file = BYTE_GET (entry->vn_file);
13356 ent.vn_aux = BYTE_GET (entry->vn_aux);
13357 ent.vn_next = BYTE_GET (entry->vn_next);
13358
26c527e6 13359 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 13360
84714f86 13361 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 13362 printf (_(" File: %s"),
84714f86 13363 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
13364 else
13365 printf (_(" File: %lx"), ent.vn_file);
13366
13367 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13368
dd24e3da 13369 /* Check for overflow. */
7e26601c 13370 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 13371 break;
252b5132
RH
13372 vstart += ent.vn_aux;
13373
13374 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13375 {
2cf0635d 13376 Elf_External_Vernaux * eaux;
b34976b6 13377 Elf_Internal_Vernaux aux;
252b5132 13378
54806181
AM
13379 if (vstart + sizeof (*eaux) > endbuf)
13380 break;
252b5132
RH
13381 eaux = (Elf_External_Vernaux *) vstart;
13382
13383 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13384 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13385 aux.vna_other = BYTE_GET (eaux->vna_other);
13386 aux.vna_name = BYTE_GET (eaux->vna_name);
13387 aux.vna_next = BYTE_GET (eaux->vna_next);
13388
84714f86 13389 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 13390 printf (_(" %#06zx: Name: %s"),
84714f86 13391 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 13392 else
26c527e6 13393 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
13394 isum, aux.vna_name);
13395
13396 printf (_(" Flags: %s Version: %d\n"),
13397 get_ver_flags (aux.vna_flags), aux.vna_other);
13398
1445030f
AM
13399 if (aux.vna_next < sizeof (*eaux)
13400 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
13401 {
13402 warn (_("Invalid vna_next field of %lx\n"),
13403 aux.vna_next);
13404 j = ent.vn_cnt;
13405 break;
13406 }
1445030f
AM
13407 /* Check for overflow. */
13408 if (aux.vna_next > (size_t) (endbuf - vstart))
13409 break;
252b5132
RH
13410 isum += aux.vna_next;
13411 vstart += aux.vna_next;
13412 }
9cf03b7e 13413
54806181 13414 if (j < ent.vn_cnt)
f9a6a8f0 13415 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 13416
1445030f
AM
13417 if (ent.vn_next < sizeof (*entry)
13418 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 13419 {
452bf675 13420 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
13421 cnt = section->sh_info;
13422 break;
13423 }
1445030f
AM
13424 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13425 break;
252b5132
RH
13426 idx += ent.vn_next;
13427 }
9cf03b7e 13428
54806181 13429 if (cnt < section->sh_info)
9cf03b7e 13430 warn (_("Missing Version Needs information\n"));
103f02d3 13431
252b5132
RH
13432 free (eneed);
13433 }
13434 break;
13435
13436 case SHT_GNU_versym:
13437 {
2cf0635d 13438 Elf_Internal_Shdr * link_section;
26c527e6 13439 uint64_t total;
8b73c356 13440 unsigned int cnt;
2cf0635d
NC
13441 unsigned char * edata;
13442 unsigned short * data;
13443 char * strtab;
13444 Elf_Internal_Sym * symbols;
13445 Elf_Internal_Shdr * string_sec;
26c527e6
AM
13446 uint64_t num_syms;
13447 uint64_t off;
252b5132 13448
dda8d76d 13449 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13450 break;
13451
dda8d76d 13452 link_section = filedata->section_headers + section->sh_link;
08d8fa11 13453 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 13454
dda8d76d 13455 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13456 break;
13457
015dc7e1 13458 found = true;
252b5132 13459
4de91c10 13460 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
13461 if (symbols == NULL)
13462 break;
252b5132 13463
dda8d76d 13464 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 13465
dda8d76d 13466 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
13467 string_sec->sh_size,
13468 _("version string table"));
a6e9f9df 13469 if (!strtab)
0429c154
MS
13470 {
13471 free (symbols);
13472 break;
13473 }
252b5132 13474
ca0e11aa 13475 if (filedata->is_separate)
26c527e6
AM
13476 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13477 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13478 total),
13479 filedata->file_name,
13480 printable_section_name (filedata, section),
26c527e6 13481 total);
ca0e11aa
NC
13482 else
13483 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 13484 "contains %" PRIu64 " entry:\n",
ca0e11aa 13485 "\nVersion symbols section '%s' "
26c527e6 13486 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13487 total),
13488 printable_section_name (filedata, section),
26c527e6 13489 total);
252b5132 13490
625d49fc 13491 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13492 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13493 section->sh_offset, section->sh_link,
dda8d76d 13494 printable_section_name (filedata, link_section));
252b5132 13495
dda8d76d 13496 off = offset_from_vma (filedata,
978c4450 13497 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 13498 total * sizeof (short));
95099889
AM
13499 edata = (unsigned char *) get_data (NULL, filedata, off,
13500 sizeof (short), total,
13501 _("version symbol data"));
a6e9f9df
AM
13502 if (!edata)
13503 {
13504 free (strtab);
0429c154 13505 free (symbols);
a6e9f9df
AM
13506 break;
13507 }
252b5132 13508
3f5e193b 13509 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
13510
13511 for (cnt = total; cnt --;)
b34976b6
AM
13512 data[cnt] = byte_get (edata + cnt * sizeof (short),
13513 sizeof (short));
252b5132
RH
13514
13515 free (edata);
13516
13517 for (cnt = 0; cnt < total; cnt += 4)
13518 {
13519 int j, nn;
ab273396
AM
13520 char *name;
13521 char *invalid = _("*invalid*");
252b5132
RH
13522
13523 printf (" %03x:", cnt);
13524
13525 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 13526 switch (data[cnt + j])
252b5132
RH
13527 {
13528 case 0:
13529 fputs (_(" 0 (*local*) "), stdout);
13530 break;
13531
13532 case 1:
13533 fputs (_(" 1 (*global*) "), stdout);
13534 break;
13535
13536 default:
c244d050
NC
13537 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13538 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 13539
dd24e3da 13540 /* If this index value is greater than the size of the symbols
ba5cdace 13541 array, break to avoid an out-of-bounds read. */
26c527e6 13542 if (cnt + j >= num_syms)
dd24e3da
NC
13543 {
13544 warn (_("invalid index into symbol array\n"));
13545 break;
13546 }
13547
ab273396 13548 name = NULL;
978c4450 13549 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13550 {
b34976b6 13551 Elf_Internal_Verneed ivn;
26c527e6 13552 uint64_t offset;
252b5132 13553
d93f0186 13554 offset = offset_from_vma
978c4450
AM
13555 (filedata,
13556 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13557 sizeof (Elf_External_Verneed));
252b5132 13558
b34976b6 13559 do
252b5132 13560 {
b34976b6
AM
13561 Elf_Internal_Vernaux ivna;
13562 Elf_External_Verneed evn;
13563 Elf_External_Vernaux evna;
26c527e6 13564 uint64_t a_off;
252b5132 13565
dda8d76d 13566 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13567 _("version need")) == NULL)
13568 break;
0b4362b0 13569
252b5132
RH
13570 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13571 ivn.vn_next = BYTE_GET (evn.vn_next);
13572
13573 a_off = offset + ivn.vn_aux;
13574
13575 do
13576 {
dda8d76d 13577 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13578 1, _("version need aux (2)")) == NULL)
13579 {
13580 ivna.vna_next = 0;
13581 ivna.vna_other = 0;
13582 }
13583 else
13584 {
13585 ivna.vna_next = BYTE_GET (evna.vna_next);
13586 ivna.vna_other = BYTE_GET (evna.vna_other);
13587 }
252b5132
RH
13588
13589 a_off += ivna.vna_next;
13590 }
b34976b6 13591 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13592 && ivna.vna_next != 0);
13593
b34976b6 13594 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13595 {
13596 ivna.vna_name = BYTE_GET (evna.vna_name);
13597
54806181 13598 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13599 name = invalid;
54806181
AM
13600 else
13601 name = strtab + ivna.vna_name;
252b5132
RH
13602 break;
13603 }
13604
13605 offset += ivn.vn_next;
13606 }
13607 while (ivn.vn_next);
13608 }
00d93f34 13609
ab273396 13610 if (data[cnt + j] != 0x8001
978c4450 13611 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13612 {
b34976b6
AM
13613 Elf_Internal_Verdef ivd;
13614 Elf_External_Verdef evd;
26c527e6 13615 uint64_t offset;
252b5132 13616
d93f0186 13617 offset = offset_from_vma
978c4450
AM
13618 (filedata,
13619 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13620 sizeof evd);
252b5132
RH
13621
13622 do
13623 {
dda8d76d 13624 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13625 _("version def")) == NULL)
13626 {
13627 ivd.vd_next = 0;
948f632f 13628 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13629 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13630 break;
59245841
NC
13631 }
13632 else
13633 {
13634 ivd.vd_next = BYTE_GET (evd.vd_next);
13635 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13636 }
252b5132
RH
13637
13638 offset += ivd.vd_next;
13639 }
c244d050 13640 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13641 && ivd.vd_next != 0);
13642
c244d050 13643 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13644 {
b34976b6
AM
13645 Elf_External_Verdaux evda;
13646 Elf_Internal_Verdaux ivda;
252b5132
RH
13647
13648 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13649
dda8d76d 13650 if (get_data (&evda, filedata,
59245841
NC
13651 offset - ivd.vd_next + ivd.vd_aux,
13652 sizeof (evda), 1,
13653 _("version def aux")) == NULL)
13654 break;
252b5132
RH
13655
13656 ivda.vda_name = BYTE_GET (evda.vda_name);
13657
54806181 13658 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13659 name = invalid;
13660 else if (name != NULL && name != invalid)
13661 name = _("*both*");
54806181
AM
13662 else
13663 name = strtab + ivda.vda_name;
252b5132
RH
13664 }
13665 }
ab273396
AM
13666 if (name != NULL)
13667 nn += printf ("(%s%-*s",
13668 name,
13669 12 - (int) strlen (name),
13670 ")");
252b5132
RH
13671
13672 if (nn < 18)
13673 printf ("%*c", 18 - nn, ' ');
13674 }
13675
13676 putchar ('\n');
13677 }
13678
13679 free (data);
13680 free (strtab);
13681 free (symbols);
13682 }
13683 break;
103f02d3 13684
252b5132
RH
13685 default:
13686 break;
13687 }
13688 }
13689
13690 if (! found)
ca0e11aa
NC
13691 {
13692 if (filedata->is_separate)
13693 printf (_("\nNo version information found in linked file '%s'.\n"),
13694 filedata->file_name);
13695 else
13696 printf (_("\nNo version information found in this file.\n"));
13697 }
252b5132 13698
015dc7e1 13699 return true;
252b5132
RH
13700}
13701
d1133906 13702static const char *
dda8d76d 13703get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13704{
89246a0e 13705 static char buff[64];
252b5132
RH
13706
13707 switch (binding)
13708 {
b34976b6
AM
13709 case STB_LOCAL: return "LOCAL";
13710 case STB_GLOBAL: return "GLOBAL";
13711 case STB_WEAK: return "WEAK";
252b5132
RH
13712 default:
13713 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13714 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13715 binding);
252b5132 13716 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13717 {
13718 if (binding == STB_GNU_UNIQUE
df3a023b 13719 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13720 return "UNIQUE";
13721 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13722 }
252b5132 13723 else
e9e44622 13724 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13725 return buff;
13726 }
13727}
13728
d1133906 13729static const char *
dda8d76d 13730get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13731{
89246a0e 13732 static char buff[64];
252b5132
RH
13733
13734 switch (type)
13735 {
b34976b6
AM
13736 case STT_NOTYPE: return "NOTYPE";
13737 case STT_OBJECT: return "OBJECT";
13738 case STT_FUNC: return "FUNC";
13739 case STT_SECTION: return "SECTION";
13740 case STT_FILE: return "FILE";
13741 case STT_COMMON: return "COMMON";
13742 case STT_TLS: return "TLS";
15ab5209
DB
13743 case STT_RELC: return "RELC";
13744 case STT_SRELC: return "SRELC";
252b5132
RH
13745 default:
13746 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13747 {
dda8d76d 13748 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13749 return "THUMB_FUNC";
103f02d3 13750
dda8d76d 13751 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13752 return "REGISTER";
13753
dda8d76d 13754 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13755 return "PARISC_MILLI";
13756
e9e44622 13757 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13758 }
252b5132 13759 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13760 {
dda8d76d 13761 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13762 {
13763 if (type == STT_HP_OPAQUE)
13764 return "HP_OPAQUE";
13765 if (type == STT_HP_STUB)
13766 return "HP_STUB";
13767 }
13768
8654c01f
ML
13769 if (type == STT_GNU_IFUNC
13770 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13771 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13772 return "IFUNC";
13773
e9e44622 13774 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13775 }
252b5132 13776 else
e9e44622 13777 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13778 return buff;
13779 }
13780}
13781
d1133906 13782static const char *
d3ba0551 13783get_symbol_visibility (unsigned int visibility)
d1133906
NC
13784{
13785 switch (visibility)
13786 {
b34976b6
AM
13787 case STV_DEFAULT: return "DEFAULT";
13788 case STV_INTERNAL: return "INTERNAL";
13789 case STV_HIDDEN: return "HIDDEN";
d1133906 13790 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13791 default:
27a45f42 13792 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13793 return _("<unknown>");
d1133906
NC
13794 }
13795}
13796
2057d69d
CZ
13797static const char *
13798get_alpha_symbol_other (unsigned int other)
9abca702 13799{
2057d69d
CZ
13800 switch (other)
13801 {
13802 case STO_ALPHA_NOPV: return "NOPV";
13803 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13804 default:
27a45f42 13805 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13806 return _("<unknown>");
9abca702 13807 }
2057d69d
CZ
13808}
13809
fd85a6a1
NC
13810static const char *
13811get_solaris_symbol_visibility (unsigned int visibility)
13812{
13813 switch (visibility)
13814 {
13815 case 4: return "EXPORTED";
13816 case 5: return "SINGLETON";
13817 case 6: return "ELIMINATE";
13818 default: return get_symbol_visibility (visibility);
13819 }
13820}
13821
2301ed1c
SN
13822static const char *
13823get_aarch64_symbol_other (unsigned int other)
13824{
13825 static char buf[32];
13826
13827 if (other & STO_AARCH64_VARIANT_PCS)
13828 {
13829 other &= ~STO_AARCH64_VARIANT_PCS;
13830 if (other == 0)
13831 return "VARIANT_PCS";
13832 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13833 return buf;
13834 }
13835 return NULL;
13836}
13837
5e2b0d47
NC
13838static const char *
13839get_mips_symbol_other (unsigned int other)
13840{
13841 switch (other)
13842 {
32ec8896
NC
13843 case STO_OPTIONAL: return "OPTIONAL";
13844 case STO_MIPS_PLT: return "MIPS PLT";
13845 case STO_MIPS_PIC: return "MIPS PIC";
13846 case STO_MICROMIPS: return "MICROMIPS";
13847 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13848 case STO_MIPS16: return "MIPS16";
13849 default: return NULL;
5e2b0d47
NC
13850 }
13851}
13852
28f997cf 13853static const char *
dda8d76d 13854get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13855{
dda8d76d 13856 if (is_ia64_vms (filedata))
28f997cf
TG
13857 {
13858 static char res[32];
13859
13860 res[0] = 0;
13861
13862 /* Function types is for images and .STB files only. */
dda8d76d 13863 switch (filedata->file_header.e_type)
28f997cf
TG
13864 {
13865 case ET_DYN:
13866 case ET_EXEC:
13867 switch (VMS_ST_FUNC_TYPE (other))
13868 {
13869 case VMS_SFT_CODE_ADDR:
13870 strcat (res, " CA");
13871 break;
13872 case VMS_SFT_SYMV_IDX:
13873 strcat (res, " VEC");
13874 break;
13875 case VMS_SFT_FD:
13876 strcat (res, " FD");
13877 break;
13878 case VMS_SFT_RESERVE:
13879 strcat (res, " RSV");
13880 break;
13881 default:
bee0ee85
NC
13882 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13883 VMS_ST_FUNC_TYPE (other));
13884 strcat (res, " <unknown>");
13885 break;
28f997cf
TG
13886 }
13887 break;
13888 default:
13889 break;
13890 }
13891 switch (VMS_ST_LINKAGE (other))
13892 {
13893 case VMS_STL_IGNORE:
13894 strcat (res, " IGN");
13895 break;
13896 case VMS_STL_RESERVE:
13897 strcat (res, " RSV");
13898 break;
13899 case VMS_STL_STD:
13900 strcat (res, " STD");
13901 break;
13902 case VMS_STL_LNK:
13903 strcat (res, " LNK");
13904 break;
13905 default:
bee0ee85
NC
13906 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13907 VMS_ST_LINKAGE (other));
13908 strcat (res, " <unknown>");
13909 break;
28f997cf
TG
13910 }
13911
13912 if (res[0] != 0)
13913 return res + 1;
13914 else
13915 return res;
13916 }
13917 return NULL;
13918}
13919
6911b7dc
AM
13920static const char *
13921get_ppc64_symbol_other (unsigned int other)
13922{
14732552
AM
13923 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13924 return NULL;
13925
13926 other >>= STO_PPC64_LOCAL_BIT;
13927 if (other <= 6)
6911b7dc 13928 {
89246a0e 13929 static char buf[64];
14732552
AM
13930 if (other >= 2)
13931 other = ppc64_decode_local_entry (other);
13932 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13933 return buf;
13934 }
13935 return NULL;
13936}
13937
8155b853
NC
13938static const char *
13939get_riscv_symbol_other (unsigned int other)
13940{
13941 static char buf[32];
13942 buf[0] = 0;
13943
13944 if (other & STO_RISCV_VARIANT_CC)
13945 {
13946 strcat (buf, _(" VARIANT_CC"));
13947 other &= ~STO_RISCV_VARIANT_CC;
13948 }
13949
13950 if (other != 0)
13951 snprintf (buf, sizeof buf, " %x", other);
13952
13953
13954 if (buf[0] != 0)
13955 return buf + 1;
13956 else
13957 return buf;
13958}
13959
5e2b0d47 13960static const char *
dda8d76d 13961get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13962{
13963 const char * result = NULL;
89246a0e 13964 static char buff [64];
5e2b0d47
NC
13965
13966 if (other == 0)
13967 return "";
13968
dda8d76d 13969 switch (filedata->file_header.e_machine)
5e2b0d47 13970 {
2057d69d
CZ
13971 case EM_ALPHA:
13972 result = get_alpha_symbol_other (other);
13973 break;
2301ed1c
SN
13974 case EM_AARCH64:
13975 result = get_aarch64_symbol_other (other);
13976 break;
5e2b0d47
NC
13977 case EM_MIPS:
13978 result = get_mips_symbol_other (other);
28f997cf
TG
13979 break;
13980 case EM_IA_64:
dda8d76d 13981 result = get_ia64_symbol_other (filedata, other);
28f997cf 13982 break;
6911b7dc
AM
13983 case EM_PPC64:
13984 result = get_ppc64_symbol_other (other);
13985 break;
8155b853
NC
13986 case EM_RISCV:
13987 result = get_riscv_symbol_other (other);
13988 break;
5e2b0d47 13989 default:
fd85a6a1 13990 result = NULL;
5e2b0d47
NC
13991 break;
13992 }
13993
13994 if (result)
13995 return result;
13996
13997 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13998 return buff;
13999}
14000
bb4d2ac2 14001static const char *
26c527e6
AM
14002get_symbol_version_string (Filedata *filedata,
14003 bool is_dynsym,
14004 const char *strtab,
14005 size_t strtab_size,
14006 unsigned int si,
14007 Elf_Internal_Sym *psym,
14008 enum versioned_symbol_info *sym_info,
14009 unsigned short *vna_other)
bb4d2ac2 14010{
ab273396
AM
14011 unsigned char data[2];
14012 unsigned short vers_data;
26c527e6 14013 uint64_t offset;
7a815dd5 14014 unsigned short max_vd_ndx;
bb4d2ac2 14015
ab273396 14016 if (!is_dynsym
978c4450 14017 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 14018 return NULL;
bb4d2ac2 14019
978c4450
AM
14020 offset = offset_from_vma (filedata,
14021 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 14022 sizeof data + si * sizeof (vers_data));
bb4d2ac2 14023
dda8d76d 14024 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
14025 sizeof (data), 1, _("version data")) == NULL)
14026 return NULL;
14027
14028 vers_data = byte_get (data, 2);
bb4d2ac2 14029
1f6f5dba 14030 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 14031 return NULL;
bb4d2ac2 14032
0b8b7609 14033 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
14034 max_vd_ndx = 0;
14035
ab273396
AM
14036 /* Usually we'd only see verdef for defined symbols, and verneed for
14037 undefined symbols. However, symbols defined by the linker in
14038 .dynbss for variables copied from a shared library in order to
14039 avoid text relocations are defined yet have verneed. We could
14040 use a heuristic to detect the special case, for example, check
14041 for verneed first on symbols defined in SHT_NOBITS sections, but
14042 it is simpler and more reliable to just look for both verdef and
14043 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 14044
ab273396
AM
14045 if (psym->st_shndx != SHN_UNDEF
14046 && vers_data != 0x8001
978c4450 14047 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
14048 {
14049 Elf_Internal_Verdef ivd;
14050 Elf_Internal_Verdaux ivda;
14051 Elf_External_Verdaux evda;
26c527e6 14052 uint64_t off;
bb4d2ac2 14053
dda8d76d 14054 off = offset_from_vma (filedata,
978c4450 14055 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
14056 sizeof (Elf_External_Verdef));
14057
14058 do
bb4d2ac2 14059 {
ab273396
AM
14060 Elf_External_Verdef evd;
14061
dda8d76d 14062 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
14063 _("version def")) == NULL)
14064 {
14065 ivd.vd_ndx = 0;
14066 ivd.vd_aux = 0;
14067 ivd.vd_next = 0;
1f6f5dba 14068 ivd.vd_flags = 0;
ab273396
AM
14069 }
14070 else
bb4d2ac2 14071 {
ab273396
AM
14072 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
14073 ivd.vd_aux = BYTE_GET (evd.vd_aux);
14074 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 14075 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 14076 }
bb4d2ac2 14077
7a815dd5
L
14078 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
14079 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
14080
ab273396
AM
14081 off += ivd.vd_next;
14082 }
14083 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 14084
ab273396
AM
14085 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
14086 {
9abca702 14087 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
14088 return NULL;
14089
ab273396
AM
14090 off -= ivd.vd_next;
14091 off += ivd.vd_aux;
bb4d2ac2 14092
dda8d76d 14093 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
14094 _("version def aux")) != NULL)
14095 {
14096 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 14097
ab273396 14098 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
14099 return (ivda.vda_name < strtab_size
14100 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
14101 }
14102 }
14103 }
bb4d2ac2 14104
978c4450 14105 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
14106 {
14107 Elf_External_Verneed evn;
14108 Elf_Internal_Verneed ivn;
14109 Elf_Internal_Vernaux ivna;
bb4d2ac2 14110
dda8d76d 14111 offset = offset_from_vma (filedata,
978c4450 14112 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
14113 sizeof evn);
14114 do
14115 {
26c527e6 14116 uint64_t vna_off;
bb4d2ac2 14117
dda8d76d 14118 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
14119 _("version need")) == NULL)
14120 {
14121 ivna.vna_next = 0;
14122 ivna.vna_other = 0;
14123 ivna.vna_name = 0;
14124 break;
14125 }
bb4d2ac2 14126
ab273396
AM
14127 ivn.vn_aux = BYTE_GET (evn.vn_aux);
14128 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 14129
ab273396 14130 vna_off = offset + ivn.vn_aux;
bb4d2ac2 14131
ab273396
AM
14132 do
14133 {
14134 Elf_External_Vernaux evna;
bb4d2ac2 14135
dda8d76d 14136 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 14137 _("version need aux (3)")) == NULL)
bb4d2ac2 14138 {
ab273396
AM
14139 ivna.vna_next = 0;
14140 ivna.vna_other = 0;
14141 ivna.vna_name = 0;
bb4d2ac2 14142 }
bb4d2ac2 14143 else
bb4d2ac2 14144 {
ab273396
AM
14145 ivna.vna_other = BYTE_GET (evna.vna_other);
14146 ivna.vna_next = BYTE_GET (evna.vna_next);
14147 ivna.vna_name = BYTE_GET (evna.vna_name);
14148 }
bb4d2ac2 14149
ab273396
AM
14150 vna_off += ivna.vna_next;
14151 }
14152 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 14153
ab273396
AM
14154 if (ivna.vna_other == vers_data)
14155 break;
bb4d2ac2 14156
ab273396
AM
14157 offset += ivn.vn_next;
14158 }
14159 while (ivn.vn_next != 0);
bb4d2ac2 14160
ab273396
AM
14161 if (ivna.vna_other == vers_data)
14162 {
14163 *sym_info = symbol_undefined;
14164 *vna_other = ivna.vna_other;
14165 return (ivna.vna_name < strtab_size
14166 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 14167 }
7a815dd5
L
14168 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
14169 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
14170 return _("<corrupt>");
bb4d2ac2 14171 }
ab273396 14172 return NULL;
bb4d2ac2
L
14173}
14174
047c3dbf
NL
14175/* Display a symbol size on stdout. Format is based on --sym-base setting. */
14176
14177static unsigned int
b6ac461a 14178print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
14179{
14180 switch (base)
14181 {
14182 case 8:
14183 return print_vma (vma, OCTAL_5);
14184
14185 case 10:
14186 return print_vma (vma, UNSIGNED_5);
14187
14188 case 16:
14189 return print_vma (vma, PREFIX_HEX_5);
14190
14191 case 0:
14192 default:
14193 return print_vma (vma, DEC_5);
14194 }
14195}
14196
b6ac461a
NC
14197/* Print information on a single symbol. */
14198
10ca4b04 14199static void
b6ac461a
NC
14200print_symbol (Filedata * filedata,
14201 uint64_t symbol_index,
14202 Elf_Internal_Sym * symtab,
14203 Elf_Internal_Shdr * section,
14204 char * strtab,
14205 size_t strtab_size)
252b5132 14206{
10ca4b04
L
14207 const char *version_string;
14208 enum versioned_symbol_info sym_info;
14209 unsigned short vna_other;
23356397 14210 const char * sstr;
b6ac461a 14211 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 14212
b6ac461a
NC
14213 /* FIXME: We should have a table of field widths,
14214 rather than using hard coded constants. */
14215 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
14216 print_vma (psym->st_value, LONG_HEX);
14217 putchar (' ');
b6ac461a 14218 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
14219 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
14220 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
14221 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
14222 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
14223 else
252b5132 14224 {
10ca4b04 14225 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 14226
10ca4b04 14227 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 14228
10ca4b04 14229 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
14230 FIXME: Displaying this information here disrupts the layout
14231 of the table being generated. */
10ca4b04
L
14232 if (psym->st_other ^ vis)
14233 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 14234 }
0942c7ab 14235
b6ac461a
NC
14236 bool is_special;
14237
14238 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
14239
14240 /* Print the symbol's section index. If the index is special
14241 then print the index's name rather than its number. */
14242 if (is_special)
14243 {
14244 int printed;
14245
14246 /* Special case: If there are no section headers, and the printable
14247 name is "<section 0x...." then just display the section number
14248 as a decimal. This happens when objcopy --strip -section-headers
14249 is used. */
14250 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
14251 printed = printf (" %4d ", psym->st_shndx);
14252 else
14253 printed = printf (" %4s ", sstr);
14254
14255 if (extra_sym_info && printed < 16)
14256 printf ("%*s", 16 - printed, "");
14257 }
14258 else
14259 {
14260 printf (" %4u ", psym->st_shndx);
14261
14262 if (extra_sym_info)
14263 {
14264 /* Display the section name referenced by the section index. */
14265 int printed = printf ("(%s) ", sstr);
14266 if (printed < 10)
14267 printf ("%*s", 10 - printed, "");
14268 }
14269 }
14270
14271 /* Get the symbol's name. For section symbols without a
14272 specific name use the (already computed) section name. */
23356397 14273 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 14274 && section_index_real (filedata, psym->st_shndx)
23356397
NC
14275 && psym->st_name == 0)
14276 {
b6ac461a 14277 ;
23356397
NC
14278 }
14279 else
14280 {
b6ac461a
NC
14281 bool is_valid;
14282
84714f86 14283 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
14284 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14285 }
10ca4b04
L
14286
14287 version_string
14288 = get_symbol_version_string (filedata,
14289 (section == NULL
14290 || section->sh_type == SHT_DYNSYM),
b6ac461a 14291 strtab, strtab_size, symbol_index,
10ca4b04 14292 psym, &sym_info, &vna_other);
b9e920ec 14293
0942c7ab
NC
14294 int len_avail = 21;
14295 if (! do_wide && version_string != NULL)
14296 {
ddb43bab 14297 char buffer[16];
0942c7ab 14298
ddb43bab 14299 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
14300
14301 if (sym_info == symbol_undefined)
14302 len_avail -= sprintf (buffer," (%d)", vna_other);
14303 else if (sym_info != symbol_hidden)
14304 len_avail -= 1;
14305 }
14306
b6ac461a 14307 print_symbol_name (len_avail, sstr);
b9e920ec 14308
10ca4b04
L
14309 if (version_string)
14310 {
14311 if (sym_info == symbol_undefined)
14312 printf ("@%s (%d)", version_string, vna_other);
f7a99963 14313 else
10ca4b04
L
14314 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14315 version_string);
14316 }
6bd1a22c 14317
10ca4b04 14318 putchar ('\n');
6bd1a22c 14319
10ca4b04
L
14320 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14321 && section != NULL
b6ac461a 14322 && symbol_index >= section->sh_info
10ca4b04
L
14323 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14324 && filedata->file_header.e_machine != EM_MIPS
14325 /* Solaris binaries have been found to violate this requirement as
14326 well. Not sure if this is a bug or an ABI requirement. */
14327 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 14328 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 14329 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 14330}
f16a9783 14331
0f03783c
NC
14332static const char *
14333get_lto_kind (unsigned int kind)
14334{
14335 switch (kind)
14336 {
14337 case 0: return "DEF";
14338 case 1: return "WEAKDEF";
14339 case 2: return "UNDEF";
14340 case 3: return "WEAKUNDEF";
14341 case 4: return "COMMON";
14342 default:
14343 break;
14344 }
14345
14346 static char buffer[30];
14347 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14348 sprintf (buffer, "<unknown: %u>", kind);
14349 return buffer;
14350}
14351
14352static const char *
14353get_lto_visibility (unsigned int visibility)
14354{
14355 switch (visibility)
14356 {
14357 case 0: return "DEFAULT";
14358 case 1: return "PROTECTED";
14359 case 2: return "INTERNAL";
14360 case 3: return "HIDDEN";
14361 default:
14362 break;
14363 }
14364
14365 static char buffer[30];
14366 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14367 sprintf (buffer, "<unknown: %u>", visibility);
14368 return buffer;
14369}
14370
14371static const char *
14372get_lto_sym_type (unsigned int sym_type)
14373{
14374 switch (sym_type)
14375 {
14376 case 0: return "UNKNOWN";
14377 case 1: return "FUNCTION";
14378 case 2: return "VARIABLE";
14379 default:
14380 break;
14381 }
14382
14383 static char buffer[30];
14384 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14385 sprintf (buffer, "<unknown: %u>", sym_type);
14386 return buffer;
14387}
14388
14389/* Display an LTO format symbol table.
14390 FIXME: The format of LTO symbol tables is not formalized.
14391 So this code could need changing in the future. */
14392
015dc7e1 14393static bool
0f03783c
NC
14394display_lto_symtab (Filedata * filedata,
14395 Elf_Internal_Shdr * section)
14396{
14397 if (section->sh_size == 0)
14398 {
ca0e11aa
NC
14399 if (filedata->is_separate)
14400 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14401 printable_section_name (filedata, section),
14402 filedata->file_name);
14403 else
14404 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14405 printable_section_name (filedata, section));
047c3dbf 14406
015dc7e1 14407 return true;
0f03783c
NC
14408 }
14409
14410 if (section->sh_size > filedata->file_size)
14411 {
26c527e6 14412 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 14413 printable_section_name (filedata, section),
26c527e6 14414 section->sh_size);
015dc7e1 14415 return false;
0f03783c
NC
14416 }
14417
14418 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14419 section->sh_size, 1, _("LTO symbols"));
14420 if (alloced_data == NULL)
015dc7e1 14421 return false;
0f03783c
NC
14422
14423 /* Look for extended data for the symbol table. */
765a0c0a 14424 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
14425 void * ext_data_orig = NULL;
14426 char * ext_data = NULL;
14427 char * ext_data_end = NULL;
14428 char * ext_name = NULL;
14429
14430 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
14431 (section_name (filedata, section)
14432 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
14433 && ext_name != NULL /* Paranoia. */
14434 && (ext = find_section (filedata, ext_name)) != NULL)
14435 {
14436 if (ext->sh_size < 3)
14437 error (_("LTO Symbol extension table '%s' is empty!\n"),
14438 printable_section_name (filedata, ext));
14439 else
14440 {
14441 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14442 ext->sh_size, 1,
14443 _("LTO ext symbol data"));
14444 if (ext_data != NULL)
14445 {
14446 ext_data_end = ext_data + ext->sh_size;
14447 if (* ext_data++ != 1)
14448 error (_("Unexpected version number in symbol extension table\n"));
14449 }
14450 }
14451 }
b9e920ec 14452
0f03783c
NC
14453 const unsigned char * data = (const unsigned char *) alloced_data;
14454 const unsigned char * end = data + section->sh_size;
14455
ca0e11aa
NC
14456 if (filedata->is_separate)
14457 printf (_("\nIn linked file '%s': "), filedata->file_name);
14458 else
14459 printf ("\n");
14460
0f03783c
NC
14461 if (ext_data_orig != NULL)
14462 {
14463 if (do_wide)
ca0e11aa 14464 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
14465 printable_section_name (filedata, section),
14466 printable_section_name (filedata, ext));
14467 else
14468 {
ca0e11aa 14469 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
14470 printable_section_name (filedata, section));
14471 printf (_(" and extension table '%s' contain:\n"),
14472 printable_section_name (filedata, ext));
14473 }
14474 }
14475 else
ca0e11aa 14476 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 14477 printable_section_name (filedata, section));
b9e920ec 14478
0f03783c 14479 /* FIXME: Add a wide version. */
b9e920ec 14480 if (ext_data_orig != NULL)
0f03783c
NC
14481 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14482 else
14483 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14484
14485 /* FIXME: We do not handle style prefixes. */
14486
14487 while (data < end)
14488 {
14489 const unsigned char * sym_name = data;
14490 data += strnlen ((const char *) sym_name, end - data) + 1;
14491 if (data >= end)
14492 goto fail;
14493
14494 const unsigned char * comdat_key = data;
14495 data += strnlen ((const char *) comdat_key, end - data) + 1;
14496 if (data >= end)
14497 goto fail;
14498
14499 if (data + 2 + 8 + 4 > end)
14500 goto fail;
14501
14502 unsigned int kind = *data++;
14503 unsigned int visibility = *data++;
14504
928c411d 14505 uint64_t size = byte_get (data, 8);
0f03783c
NC
14506 data += 8;
14507
928c411d 14508 uint64_t slot = byte_get (data, 4);
0f03783c
NC
14509 data += 4;
14510
14511 if (ext_data != NULL)
14512 {
14513 if (ext_data < (ext_data_end - 1))
14514 {
14515 unsigned int sym_type = * ext_data ++;
14516 unsigned int sec_kind = * ext_data ++;
14517
31e5a3a3 14518 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
14519 * comdat_key == 0 ? "-" : (char *) comdat_key,
14520 get_lto_kind (kind),
14521 get_lto_visibility (visibility),
31e5a3a3
AM
14522 size,
14523 slot,
0f03783c 14524 get_lto_sym_type (sym_type),
31e5a3a3 14525 sec_kind);
b6ac461a 14526 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
14527 }
14528 else
14529 {
14530 error (_("Ran out of LTO symbol extension data\n"));
14531 ext_data = NULL;
14532 /* FIXME: return FAIL result ? */
14533 }
14534 }
14535 else
14536 {
31e5a3a3 14537 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
14538 * comdat_key == 0 ? "-" : (char *) comdat_key,
14539 get_lto_kind (kind),
14540 get_lto_visibility (visibility),
31e5a3a3
AM
14541 size,
14542 slot);
b6ac461a 14543 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
14544 }
14545 putchar ('\n');
14546 }
14547
14548 if (ext_data != NULL && ext_data < ext_data_end)
14549 {
14550 error (_("Data remains in the LTO symbol extension table\n"));
14551 goto fail;
14552 }
14553
14554 free (alloced_data);
14555 free (ext_data_orig);
14556 free (ext_name);
015dc7e1 14557 return true;
b9e920ec 14558
0f03783c
NC
14559 fail:
14560 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14561 free (alloced_data);
14562 free (ext_data_orig);
14563 free (ext_name);
015dc7e1 14564 return false;
0f03783c
NC
14565}
14566
14567/* Display LTO symbol tables. */
14568
015dc7e1 14569static bool
0f03783c
NC
14570process_lto_symbol_tables (Filedata * filedata)
14571{
14572 Elf_Internal_Shdr * section;
14573 unsigned int i;
015dc7e1 14574 bool res = true;
0f03783c
NC
14575
14576 if (!do_lto_syms)
015dc7e1 14577 return true;
0f03783c
NC
14578
14579 if (filedata->section_headers == NULL)
015dc7e1 14580 return true;
0f03783c
NC
14581
14582 for (i = 0, section = filedata->section_headers;
14583 i < filedata->file_header.e_shnum;
14584 i++, section++)
84714f86
AM
14585 if (section_name_valid (filedata, section)
14586 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14587 res &= display_lto_symtab (filedata, section);
14588
b9e920ec 14589 return res;
0f03783c
NC
14590}
14591
b6ac461a
NC
14592static void
14593print_symbol_table_heading (void)
14594{
14595 /* FIXME: We should store the size of each field in the display in a table and
14596 then use the values inside print_symbol(), instead of that function using
14597 hard coded constants. */
14598 if (is_32bit_elf)
14599 {
14600 if (extra_sym_info)
14601 {
14602 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14603 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14604 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14605 }
14606 else if (do_wide)
14607 {
14608 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14609 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14610 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14611 }
14612 else
14613 {
14614 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14615 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14616 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14617 }
14618 }
14619 else
14620 {
14621 if (extra_sym_info)
14622 {
14623 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14624 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14625 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14626
14627 }
14628 else if (do_wide)
14629 {
14630 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14631 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14632 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14633 }
14634 else
14635 {
14636 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14637 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14638 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14639 }
14640 }
14641}
14642
8e8d0b63
NC
14643static bool
14644dump_symbol_section (Elf_Internal_Shdr * section,
14645 Filedata * filedata)
14646{
14647 if (section->sh_entsize == 0)
14648 {
14649 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14650 printable_section_name (filedata, section));
14651 return false;
14652 }
14653
14654 uint64_t num_syms = section->sh_size / section->sh_entsize;
14655
14656 if (filedata->is_separate)
14657 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14658 " contains %" PRIu64 " entry:\n",
14659 "\nIn linked file '%s' symbol section '%s'"
14660 " contains %" PRIu64 " entries:\n",
14661 num_syms),
14662 filedata->file_name,
14663 printable_section_name (filedata, section),
14664 num_syms);
14665 else
14666 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14667 " entry:\n",
14668 "\nSymbol table '%s' contains %" PRIu64
14669 " entries:\n",
14670 num_syms),
14671 printable_section_name (filedata, section),
14672 num_syms);
14673
14674 print_symbol_table_heading ();
14675
14676 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14677 if (symtab == NULL)
14678 /* An error message will have already been displayed. */
14679 return false;
14680
14681 char * strtab = NULL;
14682 uint64_t strtab_size = 0;
14683
14684 if (section->sh_link == filedata->file_header.e_shstrndx)
14685 {
14686 strtab = filedata->string_table;
14687 strtab_size = filedata->string_table_length;
14688 }
14689 else if (section->sh_link < filedata->file_header.e_shnum)
14690 {
14691 Elf_Internal_Shdr * string_sec;
14692
14693 string_sec = filedata->section_headers + section->sh_link;
14694
14695 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14696 1, string_sec->sh_size,
14697 _("string table"));
14698 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14699 }
14700
14701 uint64_t si;
14702
14703 for (si = 0; si < num_syms; si++)
14704 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14705
14706 free (symtab);
14707
14708 if (strtab != filedata->string_table)
14709 free (strtab);
14710
14711 return true;
14712}
14713
10ca4b04 14714/* Dump the symbol table. */
0f03783c 14715
015dc7e1 14716static bool
10ca4b04
L
14717process_symbol_table (Filedata * filedata)
14718{
14719 Elf_Internal_Shdr * section;
f16a9783 14720
10ca4b04 14721 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14722 return true;
6bd1a22c 14723
978c4450 14724 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14725 && do_syms
14726 && do_using_dynamic
978c4450
AM
14727 && filedata->dynamic_strings != NULL
14728 && filedata->dynamic_symbols != NULL)
6bd1a22c 14729 {
26c527e6 14730 uint64_t si;
6bd1a22c 14731
ca0e11aa
NC
14732 if (filedata->is_separate)
14733 {
26c527e6
AM
14734 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14735 " contains %" PRIu64 " entry:\n",
14736 "\nIn linked file '%s' the dynamic symbol table"
14737 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14738 filedata->num_dynamic_syms),
14739 filedata->file_name,
14740 filedata->num_dynamic_syms);
14741 }
14742 else
14743 {
26c527e6
AM
14744 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14745 " entry:\n",
14746 "\nSymbol table for image contains %" PRIu64
14747 " entries:\n",
ca0e11aa
NC
14748 filedata->num_dynamic_syms),
14749 filedata->num_dynamic_syms);
14750 }
b6ac461a
NC
14751
14752 print_symbol_table_heading ();
6bd1a22c 14753
978c4450 14754 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14755 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14756 filedata->dynamic_strings,
14757 filedata->dynamic_strings_length);
252b5132 14758 }
8b73c356 14759 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14760 && filedata->section_headers != NULL)
252b5132 14761 {
b34976b6 14762 unsigned int i;
252b5132 14763
dda8d76d
NC
14764 for (i = 0, section = filedata->section_headers;
14765 i < filedata->file_header.e_shnum;
252b5132
RH
14766 i++, section++)
14767 {
2c610e4b
L
14768 if ((section->sh_type != SHT_SYMTAB
14769 && section->sh_type != SHT_DYNSYM)
14770 || (!do_syms
14771 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14772 continue;
14773
8e8d0b63 14774 dump_symbol_section (section, filedata);
252b5132
RH
14775 }
14776 }
14777 else if (do_syms)
14778 printf
14779 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14780
978c4450 14781 if (do_histogram && filedata->buckets != NULL)
252b5132 14782 {
26c527e6
AM
14783 uint64_t *lengths;
14784 uint64_t *counts;
14785 uint64_t hn;
625d49fc 14786 uint64_t si;
26c527e6
AM
14787 uint64_t maxlength = 0;
14788 uint64_t nzero_counts = 0;
14789 uint64_t nsyms = 0;
6bd6a03d 14790 char *visited;
252b5132 14791
d3a49aa8 14792 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14793 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14794 "\nHistogram for bucket list length "
26c527e6
AM
14795 "(total of %" PRIu64 " buckets):\n",
14796 filedata->nbuckets),
14797 filedata->nbuckets);
252b5132 14798
26c527e6 14799 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14800 if (lengths == NULL)
14801 {
8b73c356 14802 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14803 goto err_out;
252b5132 14804 }
978c4450
AM
14805 visited = xcmalloc (filedata->nchains, 1);
14806 memset (visited, 0, filedata->nchains);
8b73c356
NC
14807
14808 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14809 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14810 {
978c4450 14811 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14812 {
b34976b6 14813 ++nsyms;
252b5132 14814 if (maxlength < ++lengths[hn])
b34976b6 14815 ++maxlength;
978c4450 14816 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14817 {
14818 error (_("histogram chain is corrupt\n"));
14819 break;
14820 }
14821 visited[si] = 1;
252b5132
RH
14822 }
14823 }
6bd6a03d 14824 free (visited);
252b5132 14825
26c527e6 14826 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14827 if (counts == NULL)
14828 {
b2e951ec 14829 free (lengths);
8b73c356 14830 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14831 goto err_out;
252b5132
RH
14832 }
14833
978c4450 14834 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14835 ++counts[lengths[hn]];
252b5132 14836
978c4450 14837 if (filedata->nbuckets > 0)
252b5132 14838 {
26c527e6
AM
14839 uint64_t i;
14840 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14841 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14842 for (i = 1; i <= maxlength; ++i)
103f02d3 14843 {
66543521 14844 nzero_counts += counts[i] * i;
26c527e6 14845 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14846 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14847 (nzero_counts * 100.0) / nsyms);
14848 }
252b5132
RH
14849 }
14850
14851 free (counts);
14852 free (lengths);
14853 }
14854
978c4450
AM
14855 free (filedata->buckets);
14856 filedata->buckets = NULL;
14857 filedata->nbuckets = 0;
14858 free (filedata->chains);
14859 filedata->chains = NULL;
252b5132 14860
978c4450 14861 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14862 {
26c527e6
AM
14863 uint64_t *lengths;
14864 uint64_t *counts;
14865 uint64_t hn;
14866 uint64_t maxlength = 0;
14867 uint64_t nzero_counts = 0;
14868 uint64_t nsyms = 0;
fdc90cb4 14869
f16a9783 14870 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14871 "(total of %" PRIu64 " bucket):\n",
f16a9783 14872 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14873 "(total of %" PRIu64 " buckets):\n",
14874 filedata->ngnubuckets),
978c4450 14875 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14876 filedata->ngnubuckets);
8b73c356 14877
26c527e6 14878 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14879 if (lengths == NULL)
14880 {
8b73c356 14881 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14882 goto err_out;
fdc90cb4
JJ
14883 }
14884
fdc90cb4
JJ
14885 printf (_(" Length Number %% of total Coverage\n"));
14886
978c4450
AM
14887 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14888 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14889 {
625d49fc 14890 uint64_t off, length = 1;
fdc90cb4 14891
978c4450 14892 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14893 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14894 off < filedata->ngnuchains
14895 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14896 ++off)
fdc90cb4
JJ
14897 ++length;
14898 lengths[hn] = length;
14899 if (length > maxlength)
14900 maxlength = length;
14901 nsyms += length;
14902 }
14903
26c527e6 14904 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14905 if (counts == NULL)
14906 {
b2e951ec 14907 free (lengths);
8b73c356 14908 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14909 goto err_out;
fdc90cb4
JJ
14910 }
14911
978c4450 14912 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14913 ++counts[lengths[hn]];
14914
978c4450 14915 if (filedata->ngnubuckets > 0)
fdc90cb4 14916 {
26c527e6
AM
14917 uint64_t j;
14918 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14919 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14920 for (j = 1; j <= maxlength; ++j)
14921 {
14922 nzero_counts += counts[j] * j;
26c527e6 14923 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14924 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14925 (nzero_counts * 100.0) / nsyms);
14926 }
14927 }
14928
14929 free (counts);
14930 free (lengths);
fdc90cb4 14931 }
978c4450
AM
14932 free (filedata->gnubuckets);
14933 filedata->gnubuckets = NULL;
14934 filedata->ngnubuckets = 0;
14935 free (filedata->gnuchains);
14936 filedata->gnuchains = NULL;
14937 filedata->ngnuchains = 0;
14938 free (filedata->mipsxlat);
14939 filedata->mipsxlat = NULL;
015dc7e1 14940 return true;
fd486f32
AM
14941
14942 err_out:
978c4450
AM
14943 free (filedata->gnubuckets);
14944 filedata->gnubuckets = NULL;
14945 filedata->ngnubuckets = 0;
14946 free (filedata->gnuchains);
14947 filedata->gnuchains = NULL;
14948 filedata->ngnuchains = 0;
14949 free (filedata->mipsxlat);
14950 filedata->mipsxlat = NULL;
14951 free (filedata->buckets);
14952 filedata->buckets = NULL;
14953 filedata->nbuckets = 0;
14954 free (filedata->chains);
14955 filedata->chains = NULL;
015dc7e1 14956 return false;
252b5132
RH
14957}
14958
015dc7e1 14959static bool
ca0e11aa 14960process_syminfo (Filedata * filedata)
252b5132 14961{
b4c96d0d 14962 unsigned int i;
252b5132 14963
978c4450 14964 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14965 || !do_dynamic)
14966 /* No syminfo, this is ok. */
015dc7e1 14967 return true;
252b5132
RH
14968
14969 /* There better should be a dynamic symbol section. */
978c4450 14970 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14971 return false;
252b5132 14972
ca0e11aa 14973 if (filedata->is_separate)
26c527e6
AM
14974 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14975 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14976 filedata->dynamic_syminfo_nent),
14977 filedata->file_name,
14978 filedata->dynamic_syminfo_offset,
14979 filedata->dynamic_syminfo_nent);
14980 else
26c527e6
AM
14981 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14982 " contains %d entry:\n",
14983 "\nDynamic info segment at offset %#" PRIx64
14984 " contains %d entries:\n",
978c4450 14985 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14986 filedata->dynamic_syminfo_offset,
14987 filedata->dynamic_syminfo_nent);
252b5132
RH
14988
14989 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14990 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14991 {
978c4450 14992 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14993
31104126 14994 printf ("%4d: ", i);
978c4450 14995 if (i >= filedata->num_dynamic_syms)
4082ef84 14996 printf (_("<corrupt index>"));
84714f86 14997 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14998 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14999 filedata->dynamic_symbols[i].st_name));
d79b3d50 15000 else
978c4450 15001 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 15002 putchar (' ');
252b5132 15003
978c4450 15004 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
15005 {
15006 case SYMINFO_BT_SELF:
15007 fputs ("SELF ", stdout);
15008 break;
15009 case SYMINFO_BT_PARENT:
15010 fputs ("PARENT ", stdout);
15011 break;
15012 default:
978c4450
AM
15013 if (filedata->dynamic_syminfo[i].si_boundto > 0
15014 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 15015 && valid_dynamic_name (filedata,
978c4450 15016 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 15017 {
b6ac461a 15018 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 15019 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
15020 putchar (' ' );
15021 }
252b5132 15022 else
978c4450 15023 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
15024 break;
15025 }
15026
15027 if (flags & SYMINFO_FLG_DIRECT)
15028 printf (" DIRECT");
15029 if (flags & SYMINFO_FLG_PASSTHRU)
15030 printf (" PASSTHRU");
15031 if (flags & SYMINFO_FLG_COPY)
15032 printf (" COPY");
15033 if (flags & SYMINFO_FLG_LAZYLOAD)
15034 printf (" LAZYLOAD");
15035
15036 puts ("");
15037 }
15038
015dc7e1 15039 return true;
252b5132
RH
15040}
15041
75802ccb
CE
15042/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
15043 is contained by the region START .. END. The types of ADDR, START
15044 and END should all be the same. Note both ADDR + NELEM and END
15045 point to just beyond the end of the regions that are being tested. */
15046#define IN_RANGE(START,END,ADDR,NELEM) \
15047 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 15048
cf13d699
NC
15049/* Check to see if the given reloc needs to be handled in a target specific
15050 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
15051 FALSE.
15052
15053 If called with reloc == NULL, then this is a signal that reloc processing
15054 for the current section has finished, and any saved state should be
15055 discarded. */
09c11c86 15056
015dc7e1 15057static bool
26c527e6
AM
15058target_specific_reloc_handling (Filedata *filedata,
15059 Elf_Internal_Rela *reloc,
15060 unsigned char *start,
15061 unsigned char *end,
15062 Elf_Internal_Sym *symtab,
15063 uint64_t num_syms)
252b5132 15064{
f84ce13b 15065 unsigned int reloc_type = 0;
26c527e6 15066 uint64_t sym_index = 0;
f84ce13b
NC
15067
15068 if (reloc)
15069 {
dda8d76d 15070 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
15071 sym_index = get_reloc_symindex (reloc->r_info);
15072 }
252b5132 15073
dda8d76d 15074 switch (filedata->file_header.e_machine)
252b5132 15075 {
76244462 15076 case EM_LOONGARCH:
15077 {
15078 switch (reloc_type)
15079 {
15080 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
15081 at assembly time. */
15082 case 107: /* R_LARCH_ADD_ULEB128. */
15083 case 108: /* R_LARCH_SUB_ULEB128. */
15084 {
d3f34076 15085 uint64_t value = 0;
76244462 15086 unsigned int reloc_size = 0;
15087 int leb_ret = 0;
15088
89c70cd3
AM
15089 if (reloc->r_offset < (size_t) (end - start))
15090 value = read_leb128 (start + reloc->r_offset, end, false,
15091 &reloc_size, &leb_ret);
76244462 15092 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15093 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
15094 "ULEB128 value\n"),
15095 (long) reloc->r_offset);
15096
74a965d8
AM
15097 else if (sym_index >= num_syms)
15098 error (_("%s reloc contains invalid symbol index "
15099 "%" PRIu64 "\n"),
15100 (reloc_type == 107
15101 ? "R_LARCH_ADD_ULEB128"
15102 : "R_LARCH_SUB_ULEB128"),
15103 sym_index);
15104 else
76244462 15105 {
74a965d8
AM
15106 if (reloc_type == 107)
15107 value += reloc->r_addend + symtab[sym_index].st_value;
15108 else
15109 value -= reloc->r_addend + symtab[sym_index].st_value;
15110
15111 /* Write uleb128 value to p. */
15112 bfd_byte *p = start + reloc->r_offset;
15113 do
15114 {
15115 bfd_byte c = value & 0x7f;
15116 value >>= 7;
15117 if (--reloc_size != 0)
15118 c |= 0x80;
15119 *p++ = c;
15120 }
15121 while (reloc_size);
76244462 15122 }
76244462 15123
15124 return true;
15125 }
15126 }
15127 break;
15128 }
15129
13761a11
NC
15130 case EM_MSP430:
15131 case EM_MSP430_OLD:
15132 {
15133 static Elf_Internal_Sym * saved_sym = NULL;
15134
f84ce13b
NC
15135 if (reloc == NULL)
15136 {
15137 saved_sym = NULL;
015dc7e1 15138 return true;
f84ce13b
NC
15139 }
15140
13761a11
NC
15141 switch (reloc_type)
15142 {
15143 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 15144 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 15145 if (uses_msp430x_relocs (filedata))
13761a11 15146 break;
1a0670f3 15147 /* Fall through. */
13761a11 15148 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 15149 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
15150 /* PR 21139. */
15151 if (sym_index >= num_syms)
74a965d8
AM
15152 error (_("%s reloc contains invalid symbol index "
15153 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
15154 else
15155 saved_sym = symtab + sym_index;
015dc7e1 15156 return true;
13761a11
NC
15157
15158 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15159 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
15160 goto handle_sym_diff;
0b4362b0 15161
13761a11
NC
15162 case 5: /* R_MSP430_16_BYTE */
15163 case 9: /* R_MSP430_8 */
7d81bc93 15164 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 15165 if (uses_msp430x_relocs (filedata))
13761a11
NC
15166 break;
15167 goto handle_sym_diff;
15168
15169 case 2: /* R_MSP430_ABS16 */
15170 case 15: /* R_MSP430X_ABS16 */
7d81bc93 15171 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 15172 if (! uses_msp430x_relocs (filedata))
13761a11
NC
15173 break;
15174 goto handle_sym_diff;
0b4362b0 15175
13761a11
NC
15176 handle_sym_diff:
15177 if (saved_sym != NULL)
15178 {
625d49fc 15179 uint64_t value;
5a805384 15180 unsigned int reloc_size = 0;
7d81bc93
JL
15181 int leb_ret = 0;
15182 switch (reloc_type)
15183 {
15184 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15185 reloc_size = 4;
15186 break;
15187 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15188 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 15189 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 15190 read_leb128 (start + reloc->r_offset, end, false,
5a805384 15191 &reloc_size, &leb_ret);
7d81bc93
JL
15192 break;
15193 default:
15194 reloc_size = 2;
15195 break;
15196 }
13761a11 15197
5a805384 15198 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
15199 error (_("MSP430 ULEB128 field at %#" PRIx64
15200 " contains invalid ULEB128 value\n"),
15201 reloc->r_offset);
7d81bc93 15202 else if (sym_index >= num_syms)
74a965d8
AM
15203 error (_("%s reloc contains invalid symbol index "
15204 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 15205 else
f84ce13b
NC
15206 {
15207 value = reloc->r_addend + (symtab[sym_index].st_value
15208 - saved_sym->st_value);
15209
b32e566b 15210 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 15211 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
15212 else
15213 /* PR 21137 */
26c527e6
AM
15214 error (_("MSP430 sym diff reloc contains invalid offset: "
15215 "%#" PRIx64 "\n"),
15216 reloc->r_offset);
f84ce13b 15217 }
13761a11
NC
15218
15219 saved_sym = NULL;
015dc7e1 15220 return true;
13761a11
NC
15221 }
15222 break;
15223
15224 default:
15225 if (saved_sym != NULL)
071436c6 15226 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
15227 break;
15228 }
15229 break;
15230 }
15231
cf13d699
NC
15232 case EM_MN10300:
15233 case EM_CYGNUS_MN10300:
15234 {
15235 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 15236
f84ce13b
NC
15237 if (reloc == NULL)
15238 {
15239 saved_sym = NULL;
015dc7e1 15240 return true;
f84ce13b
NC
15241 }
15242
cf13d699
NC
15243 switch (reloc_type)
15244 {
15245 case 34: /* R_MN10300_ALIGN */
015dc7e1 15246 return true;
cf13d699 15247 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 15248 if (sym_index >= num_syms)
74a965d8
AM
15249 error (_("%s reloc contains invalid symbol index "
15250 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
15251 else
15252 saved_sym = symtab + sym_index;
015dc7e1 15253 return true;
f84ce13b 15254
cf13d699
NC
15255 case 1: /* R_MN10300_32 */
15256 case 2: /* R_MN10300_16 */
15257 if (saved_sym != NULL)
15258 {
03f7786e 15259 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 15260 uint64_t value;
252b5132 15261
f84ce13b 15262 if (sym_index >= num_syms)
74a965d8
AM
15263 error (_("%s reloc contains invalid symbol index "
15264 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 15265 else
f84ce13b
NC
15266 {
15267 value = reloc->r_addend + (symtab[sym_index].st_value
15268 - saved_sym->st_value);
15269
b32e566b 15270 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 15271 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 15272 else
26c527e6
AM
15273 error (_("MN10300 sym diff reloc contains invalid offset:"
15274 " %#" PRIx64 "\n"),
15275 reloc->r_offset);
f84ce13b 15276 }
252b5132 15277
cf13d699 15278 saved_sym = NULL;
015dc7e1 15279 return true;
cf13d699
NC
15280 }
15281 break;
15282 default:
15283 if (saved_sym != NULL)
071436c6 15284 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
15285 break;
15286 }
15287 break;
15288 }
6ff71e76
NC
15289
15290 case EM_RL78:
15291 {
625d49fc
AM
15292 static uint64_t saved_sym1 = 0;
15293 static uint64_t saved_sym2 = 0;
15294 static uint64_t value;
6ff71e76 15295
f84ce13b
NC
15296 if (reloc == NULL)
15297 {
15298 saved_sym1 = saved_sym2 = 0;
015dc7e1 15299 return true;
f84ce13b
NC
15300 }
15301
6ff71e76
NC
15302 switch (reloc_type)
15303 {
15304 case 0x80: /* R_RL78_SYM. */
15305 saved_sym1 = saved_sym2;
f84ce13b 15306 if (sym_index >= num_syms)
74a965d8
AM
15307 error (_("%s reloc contains invalid symbol index "
15308 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
15309 else
15310 {
15311 saved_sym2 = symtab[sym_index].st_value;
15312 saved_sym2 += reloc->r_addend;
15313 }
015dc7e1 15314 return true;
6ff71e76
NC
15315
15316 case 0x83: /* R_RL78_OPsub. */
15317 value = saved_sym1 - saved_sym2;
15318 saved_sym2 = saved_sym1 = 0;
015dc7e1 15319 return true;
6ff71e76
NC
15320 break;
15321
15322 case 0x41: /* R_RL78_ABS32. */
b32e566b 15323 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 15324 byte_put (start + reloc->r_offset, value, 4);
b32e566b 15325 else
26c527e6
AM
15326 error (_("RL78 sym diff reloc contains invalid offset: "
15327 "%#" PRIx64 "\n"),
15328 reloc->r_offset);
6ff71e76 15329 value = 0;
015dc7e1 15330 return true;
6ff71e76
NC
15331
15332 case 0x43: /* R_RL78_ABS16. */
b32e566b 15333 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 15334 byte_put (start + reloc->r_offset, value, 2);
b32e566b 15335 else
26c527e6
AM
15336 error (_("RL78 sym diff reloc contains invalid offset: "
15337 "%#" PRIx64 "\n"),
15338 reloc->r_offset);
6ff71e76 15339 value = 0;
015dc7e1 15340 return true;
6ff71e76
NC
15341
15342 default:
15343 break;
15344 }
15345 break;
15346 }
252b5132
RH
15347 }
15348
015dc7e1 15349 return false;
252b5132
RH
15350}
15351
aca88567
NC
15352/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15353 DWARF debug sections. This is a target specific test. Note - we do not
15354 go through the whole including-target-headers-multiple-times route, (as
15355 we have already done with <elf/h8.h>) because this would become very
15356 messy and even then this function would have to contain target specific
15357 information (the names of the relocs instead of their numeric values).
15358 FIXME: This is not the correct way to solve this problem. The proper way
15359 is to have target specific reloc sizing and typing functions created by
15360 the reloc-macros.h header, in the same way that it already creates the
15361 reloc naming functions. */
15362
015dc7e1 15363static bool
dda8d76d 15364is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15365{
d347c9df 15366 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15367 switch (filedata->file_header.e_machine)
aca88567 15368 {
41e92641 15369 case EM_386:
22abe556 15370 case EM_IAMCU:
41e92641 15371 return reloc_type == 1; /* R_386_32. */
aca88567
NC
15372 case EM_68K:
15373 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
15374 case EM_860:
15375 return reloc_type == 1; /* R_860_32. */
15376 case EM_960:
15377 return reloc_type == 2; /* R_960_32. */
a06ea964 15378 case EM_AARCH64:
9282b95a
JW
15379 return (reloc_type == 258
15380 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
15381 case EM_BPF:
15382 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
15383 case EM_ADAPTEVA_EPIPHANY:
15384 return reloc_type == 3;
aca88567 15385 case EM_ALPHA:
137b6b5f 15386 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
15387 case EM_ARC:
15388 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
15389 case EM_ARC_COMPACT:
15390 case EM_ARC_COMPACT2:
b5c37946
SJ
15391 case EM_ARC_COMPACT3:
15392 case EM_ARC_COMPACT3_64:
886a2506 15393 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
15394 case EM_ARM:
15395 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 15396 case EM_AVR_OLD:
aca88567
NC
15397 case EM_AVR:
15398 return reloc_type == 1;
15399 case EM_BLACKFIN:
15400 return reloc_type == 0x12; /* R_byte4_data. */
15401 case EM_CRIS:
15402 return reloc_type == 3; /* R_CRIS_32. */
15403 case EM_CR16:
15404 return reloc_type == 3; /* R_CR16_NUM32. */
15405 case EM_CRX:
15406 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
15407 case EM_CSKY:
15408 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
15409 case EM_CYGNUS_FRV:
15410 return reloc_type == 1;
41e92641
NC
15411 case EM_CYGNUS_D10V:
15412 case EM_D10V:
15413 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
15414 case EM_CYGNUS_D30V:
15415 case EM_D30V:
15416 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
15417 case EM_DLX:
15418 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
15419 case EM_CYGNUS_FR30:
15420 case EM_FR30:
15421 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
15422 case EM_FT32:
15423 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
15424 case EM_H8S:
15425 case EM_H8_300:
15426 case EM_H8_300H:
15427 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 15428 case EM_IA_64:
262cdac7
AM
15429 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15430 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15431 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15432 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
15433 case EM_IP2K_OLD:
15434 case EM_IP2K:
15435 return reloc_type == 2; /* R_IP2K_32. */
15436 case EM_IQ2000:
15437 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
15438 case EM_KVX:
15439 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
15440 case EM_LATTICEMICO32:
15441 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 15442 case EM_LOONGARCH:
15443 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 15444 case EM_M32C_OLD:
aca88567
NC
15445 case EM_M32C:
15446 return reloc_type == 3; /* R_M32C_32. */
15447 case EM_M32R:
15448 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
15449 case EM_68HC11:
15450 case EM_68HC12:
15451 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 15452 case EM_S12Z:
2849d19f
JD
15453 return reloc_type == 7 || /* R_S12Z_EXT32 */
15454 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
15455 case EM_MCORE:
15456 return reloc_type == 1; /* R_MCORE_ADDR32. */
15457 case EM_CYGNUS_MEP:
15458 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
15459 case EM_METAG:
15460 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
15461 case EM_MICROBLAZE:
15462 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
15463 case EM_MIPS:
15464 return reloc_type == 2; /* R_MIPS_32. */
15465 case EM_MMIX:
15466 return reloc_type == 4; /* R_MMIX_32. */
15467 case EM_CYGNUS_MN10200:
15468 case EM_MN10200:
15469 return reloc_type == 1; /* R_MN10200_32. */
15470 case EM_CYGNUS_MN10300:
15471 case EM_MN10300:
15472 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
15473 case EM_MOXIE:
15474 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
15475 case EM_MSP430_OLD:
15476 case EM_MSP430:
13761a11 15477 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
15478 case EM_MT:
15479 return reloc_type == 2; /* R_MT_32. */
35c08157 15480 case EM_NDS32:
81c5e376 15481 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 15482 case EM_ALTERA_NIOS2:
36591ba1 15483 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
15484 case EM_NIOS32:
15485 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
15486 case EM_OR1K:
15487 return reloc_type == 1; /* R_OR1K_32. */
aca88567 15488 case EM_PARISC:
9abca702 15489 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 15490 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 15491 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
15492 case EM_PJ:
15493 case EM_PJ_OLD:
15494 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15495 case EM_PPC64:
15496 return reloc_type == 1; /* R_PPC64_ADDR32. */
15497 case EM_PPC:
15498 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
15499 case EM_TI_PRU:
15500 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
15501 case EM_RISCV:
15502 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
15503 case EM_RL78:
15504 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
15505 case EM_RX:
15506 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
15507 case EM_S370:
15508 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
15509 case EM_S390_OLD:
15510 case EM_S390:
15511 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
15512 case EM_SCORE:
15513 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
15514 case EM_SH:
15515 return reloc_type == 1; /* R_SH_DIR32. */
15516 case EM_SPARC32PLUS:
15517 case EM_SPARCV9:
15518 case EM_SPARC:
15519 return reloc_type == 3 /* R_SPARC_32. */
15520 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
15521 case EM_SPU:
15522 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
15523 case EM_TI_C6000:
15524 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
15525 case EM_TILEGX:
15526 return reloc_type == 2; /* R_TILEGX_32. */
15527 case EM_TILEPRO:
15528 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
15529 case EM_CYGNUS_V850:
15530 case EM_V850:
15531 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
15532 case EM_V800:
15533 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
15534 case EM_VAX:
15535 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
15536 case EM_VISIUM:
15537 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
15538 case EM_WEBASSEMBLY:
15539 return reloc_type == 1; /* R_WASM32_32. */
aca88567 15540 case EM_X86_64:
8a9036a4 15541 case EM_L1OM:
7a9068fe 15542 case EM_K1OM:
aca88567 15543 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
15544 case EM_XGATE:
15545 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
15546 case EM_XSTORMY16:
15547 return reloc_type == 1; /* R_XSTROMY16_32. */
15548 case EM_XTENSA_OLD:
15549 case EM_XTENSA:
15550 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
15551 case EM_Z80:
15552 return reloc_type == 6; /* R_Z80_32. */
aca88567 15553 default:
bee0ee85
NC
15554 {
15555 static unsigned int prev_warn = 0;
15556
15557 /* Avoid repeating the same warning multiple times. */
dda8d76d 15558 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15559 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15560 filedata->file_header.e_machine);
15561 prev_warn = filedata->file_header.e_machine;
015dc7e1 15562 return false;
bee0ee85 15563 }
aca88567
NC
15564 }
15565}
15566
15567/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15568 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15569
015dc7e1 15570static bool
dda8d76d 15571is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15572{
dda8d76d 15573 switch (filedata->file_header.e_machine)
d347c9df 15574 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15575 {
41e92641 15576 case EM_386:
22abe556 15577 case EM_IAMCU:
3e0873ac 15578 return reloc_type == 2; /* R_386_PC32. */
aca88567 15579 case EM_68K:
3e0873ac 15580 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15581 case EM_AARCH64:
15582 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15583 case EM_ADAPTEVA_EPIPHANY:
15584 return reloc_type == 6;
aca88567
NC
15585 case EM_ALPHA:
15586 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15587 case EM_ARC_COMPACT:
15588 case EM_ARC_COMPACT2:
b5c37946
SJ
15589 case EM_ARC_COMPACT3:
15590 case EM_ARC_COMPACT3_64:
726c18e1 15591 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15592 case EM_ARM:
3e0873ac 15593 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15594 case EM_AVR_OLD:
15595 case EM_AVR:
15596 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15597 case EM_LOONGARCH:
15598 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15599 case EM_MICROBLAZE:
15600 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15601 case EM_OR1K:
15602 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15603 case EM_PARISC:
85acf597 15604 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15605 case EM_PPC:
15606 return reloc_type == 26; /* R_PPC_REL32. */
15607 case EM_PPC64:
3e0873ac 15608 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15609 case EM_RISCV:
15610 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15611 case EM_S390_OLD:
15612 case EM_S390:
3e0873ac 15613 return reloc_type == 5; /* R_390_PC32. */
aca88567 15614 case EM_SH:
3e0873ac 15615 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15616 case EM_SPARC32PLUS:
15617 case EM_SPARCV9:
15618 case EM_SPARC:
3e0873ac 15619 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15620 case EM_SPU:
15621 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15622 case EM_TILEGX:
15623 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15624 case EM_TILEPRO:
15625 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15626 case EM_VISIUM:
15627 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15628 case EM_X86_64:
8a9036a4 15629 case EM_L1OM:
7a9068fe 15630 case EM_K1OM:
3e0873ac 15631 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15632 case EM_VAX:
15633 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15634 case EM_XTENSA_OLD:
15635 case EM_XTENSA:
15636 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15637 case EM_KVX:
15638 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15639 default:
15640 /* Do not abort or issue an error message here. Not all targets use
15641 pc-relative 32-bit relocs in their DWARF debug information and we
15642 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15643 more helpful warning message will be generated by apply_relocations
15644 anyway, so just return. */
015dc7e1 15645 return false;
aca88567
NC
15646 }
15647}
15648
15649/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15650 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15651
015dc7e1 15652static bool
dda8d76d 15653is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15654{
dda8d76d 15655 switch (filedata->file_header.e_machine)
aca88567 15656 {
a06ea964
NC
15657 case EM_AARCH64:
15658 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15659 case EM_ARC_COMPACT3_64:
15660 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15661 case EM_ALPHA:
15662 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15663 case EM_IA_64:
262cdac7
AM
15664 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15665 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15666 case EM_LOONGARCH:
15667 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15668 case EM_PARISC:
15669 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15670 case EM_PPC64:
15671 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15672 case EM_RISCV:
15673 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15674 case EM_SPARC32PLUS:
15675 case EM_SPARCV9:
15676 case EM_SPARC:
714da62f
NC
15677 return reloc_type == 32 /* R_SPARC_64. */
15678 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15679 case EM_X86_64:
8a9036a4 15680 case EM_L1OM:
7a9068fe 15681 case EM_K1OM:
aca88567 15682 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15683 case EM_S390_OLD:
15684 case EM_S390:
aa137e4d
NC
15685 return reloc_type == 22; /* R_S390_64. */
15686 case EM_TILEGX:
15687 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15688 case EM_MIPS:
aa137e4d 15689 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15690 case EM_KVX:
15691 return reloc_type == 3; /* R_KVX_64 */
aca88567 15692 default:
015dc7e1 15693 return false;
aca88567
NC
15694 }
15695}
15696
85acf597
RH
15697/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15698 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15699
015dc7e1 15700static bool
dda8d76d 15701is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15702{
dda8d76d 15703 switch (filedata->file_header.e_machine)
85acf597 15704 {
a06ea964
NC
15705 case EM_AARCH64:
15706 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15707 case EM_ALPHA:
aa137e4d 15708 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15709 case EM_IA_64:
262cdac7
AM
15710 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15711 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15712 case EM_PARISC:
aa137e4d 15713 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15714 case EM_PPC64:
aa137e4d 15715 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15716 case EM_SPARC32PLUS:
15717 case EM_SPARCV9:
15718 case EM_SPARC:
aa137e4d 15719 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15720 case EM_X86_64:
8a9036a4 15721 case EM_L1OM:
7a9068fe 15722 case EM_K1OM:
aa137e4d 15723 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15724 case EM_S390_OLD:
15725 case EM_S390:
aa137e4d
NC
15726 return reloc_type == 23; /* R_S390_PC64. */
15727 case EM_TILEGX:
15728 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15729 default:
015dc7e1 15730 return false;
85acf597
RH
15731 }
15732}
15733
4dc3c23d
AM
15734/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15735 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15736
015dc7e1 15737static bool
dda8d76d 15738is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15739{
dda8d76d 15740 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15741 {
15742 case EM_CYGNUS_MN10200:
15743 case EM_MN10200:
15744 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15745 case EM_FT32:
15746 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15747 case EM_Z80:
15748 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15749 default:
015dc7e1 15750 return false;
4dc3c23d
AM
15751 }
15752}
15753
aca88567
NC
15754/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15755 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15756
015dc7e1 15757static bool
dda8d76d 15758is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15759{
d347c9df 15760 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15761 switch (filedata->file_header.e_machine)
4b78141a 15762 {
886a2506
NC
15763 case EM_ARC:
15764 case EM_ARC_COMPACT:
15765 case EM_ARC_COMPACT2:
b5c37946
SJ
15766 case EM_ARC_COMPACT3:
15767 case EM_ARC_COMPACT3_64:
886a2506 15768 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15769 case EM_ADAPTEVA_EPIPHANY:
15770 return reloc_type == 5;
aca88567
NC
15771 case EM_AVR_OLD:
15772 case EM_AVR:
15773 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15774 case EM_CYGNUS_D10V:
15775 case EM_D10V:
15776 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15777 case EM_FT32:
15778 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15779 case EM_H8S:
15780 case EM_H8_300:
15781 case EM_H8_300H:
aca88567
NC
15782 return reloc_type == R_H8_DIR16;
15783 case EM_IP2K_OLD:
15784 case EM_IP2K:
15785 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15786 case EM_M32C_OLD:
f4236fe4
DD
15787 case EM_M32C:
15788 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15789 case EM_CYGNUS_MN10200:
15790 case EM_MN10200:
15791 return reloc_type == 2; /* R_MN10200_16. */
15792 case EM_CYGNUS_MN10300:
15793 case EM_MN10300:
15794 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15795 case EM_KVX:
15796 return reloc_type == 1; /* R_KVX_16 */
aca88567 15797 case EM_MSP430:
dda8d76d 15798 if (uses_msp430x_relocs (filedata))
13761a11 15799 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15800 /* Fall through. */
78c8d46c 15801 case EM_MSP430_OLD:
aca88567 15802 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15803 case EM_NDS32:
81c5e376 15804 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15805 case EM_ALTERA_NIOS2:
36591ba1 15806 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15807 case EM_NIOS32:
15808 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15809 case EM_OR1K:
15810 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15811 case EM_RISCV:
15812 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15813 case EM_TI_PRU:
15814 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15815 case EM_TI_C6000:
15816 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15817 case EM_VISIUM:
15818 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15819 case EM_XGATE:
15820 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15821 case EM_Z80:
15822 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15823 default:
015dc7e1 15824 return false;
4b78141a
NC
15825 }
15826}
15827
39e07931
AS
15828/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15829 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15830
015dc7e1 15831static bool
39e07931
AS
15832is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15833{
15834 switch (filedata->file_header.e_machine)
15835 {
15836 case EM_RISCV:
15837 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15838 case EM_Z80:
15839 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15840 case EM_MICROBLAZE:
15841 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15842 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15843 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15844 default:
015dc7e1 15845 return false;
39e07931
AS
15846 }
15847}
15848
15849/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15850 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15851
015dc7e1 15852static bool
39e07931
AS
15853is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15854{
15855 switch (filedata->file_header.e_machine)
15856 {
15857 case EM_RISCV:
15858 return reloc_type == 53; /* R_RISCV_SET6. */
15859 default:
015dc7e1 15860 return false;
39e07931
AS
15861 }
15862}
15863
03336641
JW
15864/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15865 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15866
015dc7e1 15867static bool
03336641
JW
15868is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15869{
15870 /* Please keep this table alpha-sorted for ease of visual lookup. */
15871 switch (filedata->file_header.e_machine)
15872 {
76244462 15873 case EM_LOONGARCH:
15874 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15875 case EM_RISCV:
15876 return reloc_type == 35; /* R_RISCV_ADD32. */
15877 default:
015dc7e1 15878 return false;
03336641
JW
15879 }
15880}
15881
15882/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15883 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15884
015dc7e1 15885static bool
03336641
JW
15886is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15887{
15888 /* Please keep this table alpha-sorted for ease of visual lookup. */
15889 switch (filedata->file_header.e_machine)
15890 {
76244462 15891 case EM_LOONGARCH:
15892 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15893 case EM_RISCV:
15894 return reloc_type == 39; /* R_RISCV_SUB32. */
15895 default:
015dc7e1 15896 return false;
03336641
JW
15897 }
15898}
15899
15900/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15901 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15902
015dc7e1 15903static bool
03336641
JW
15904is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15905{
15906 /* Please keep this table alpha-sorted for ease of visual lookup. */
15907 switch (filedata->file_header.e_machine)
15908 {
76244462 15909 case EM_LOONGARCH:
15910 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15911 case EM_RISCV:
15912 return reloc_type == 36; /* R_RISCV_ADD64. */
15913 default:
015dc7e1 15914 return false;
03336641
JW
15915 }
15916}
15917
15918/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15919 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15920
015dc7e1 15921static bool
03336641
JW
15922is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15923{
15924 /* Please keep this table alpha-sorted for ease of visual lookup. */
15925 switch (filedata->file_header.e_machine)
15926 {
76244462 15927 case EM_LOONGARCH:
15928 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15929 case EM_RISCV:
15930 return reloc_type == 40; /* R_RISCV_SUB64. */
15931 default:
015dc7e1 15932 return false;
03336641
JW
15933 }
15934}
15935
15936/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15937 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15938
015dc7e1 15939static bool
03336641
JW
15940is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15941{
15942 /* Please keep this table alpha-sorted for ease of visual lookup. */
15943 switch (filedata->file_header.e_machine)
15944 {
76244462 15945 case EM_LOONGARCH:
15946 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15947 case EM_RISCV:
15948 return reloc_type == 34; /* R_RISCV_ADD16. */
15949 default:
015dc7e1 15950 return false;
03336641
JW
15951 }
15952}
15953
15954/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15955 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15956
015dc7e1 15957static bool
03336641
JW
15958is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15959{
15960 /* Please keep this table alpha-sorted for ease of visual lookup. */
15961 switch (filedata->file_header.e_machine)
15962 {
76244462 15963 case EM_LOONGARCH:
15964 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15965 case EM_RISCV:
15966 return reloc_type == 38; /* R_RISCV_SUB16. */
15967 default:
015dc7e1 15968 return false;
03336641
JW
15969 }
15970}
15971
15972/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15973 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15974
015dc7e1 15975static bool
03336641
JW
15976is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15977{
15978 /* Please keep this table alpha-sorted for ease of visual lookup. */
15979 switch (filedata->file_header.e_machine)
15980 {
76244462 15981 case EM_LOONGARCH:
15982 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15983 case EM_RISCV:
15984 return reloc_type == 33; /* R_RISCV_ADD8. */
15985 default:
015dc7e1 15986 return false;
03336641
JW
15987 }
15988}
15989
15990/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15991 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15992
015dc7e1 15993static bool
03336641
JW
15994is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15995{
15996 /* Please keep this table alpha-sorted for ease of visual lookup. */
15997 switch (filedata->file_header.e_machine)
15998 {
76244462 15999 case EM_LOONGARCH:
16000 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
16001 case EM_RISCV:
16002 return reloc_type == 37; /* R_RISCV_SUB8. */
16003 default:
015dc7e1 16004 return false;
03336641
JW
16005 }
16006}
16007
76244462 16008/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16009 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
16010
16011static bool
16012is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16013{
16014 switch (filedata->file_header.e_machine)
16015 {
16016 case EM_LOONGARCH:
16017 return reloc_type == 105; /* R_LARCH_ADD6. */
16018 default:
16019 return false;
16020 }
16021}
16022
39e07931
AS
16023/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16024 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
16025
015dc7e1 16026static bool
39e07931
AS
16027is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16028{
16029 switch (filedata->file_header.e_machine)
16030 {
76244462 16031 case EM_LOONGARCH:
16032 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
16033 case EM_RISCV:
16034 return reloc_type == 52; /* R_RISCV_SUB6. */
16035 default:
015dc7e1 16036 return false;
39e07931
AS
16037 }
16038}
16039
2a7b2e88
JK
16040/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
16041 relocation entries (possibly formerly used for SHT_GROUP sections). */
16042
015dc7e1 16043static bool
dda8d76d 16044is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 16045{
dda8d76d 16046 switch (filedata->file_header.e_machine)
2a7b2e88 16047 {
cb8f3167 16048 case EM_386: /* R_386_NONE. */
d347c9df 16049 case EM_68K: /* R_68K_NONE. */
cfb8c092 16050 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
16051 case EM_ALPHA: /* R_ALPHA_NONE. */
16052 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 16053 case EM_ARC: /* R_ARC_NONE. */
886a2506 16054 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 16055 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
16056 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
16057 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 16058 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 16059 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
16060 case EM_FT32: /* R_FT32_NONE. */
16061 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 16062 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 16063 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
16064 case EM_L1OM: /* R_X86_64_NONE. */
16065 case EM_M32R: /* R_M32R_NONE. */
16066 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 16067 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 16068 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
16069 case EM_NIOS32: /* R_NIOS_NONE. */
16070 case EM_OR1K: /* R_OR1K_NONE. */
16071 case EM_PARISC: /* R_PARISC_NONE. */
16072 case EM_PPC64: /* R_PPC64_NONE. */
16073 case EM_PPC: /* R_PPC_NONE. */
e23eba97 16074 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
16075 case EM_S390: /* R_390_NONE. */
16076 case EM_S390_OLD:
16077 case EM_SH: /* R_SH_NONE. */
16078 case EM_SPARC32PLUS:
16079 case EM_SPARC: /* R_SPARC_NONE. */
16080 case EM_SPARCV9:
aa137e4d
NC
16081 case EM_TILEGX: /* R_TILEGX_NONE. */
16082 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
16083 case EM_TI_C6000:/* R_C6000_NONE. */
16084 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 16085 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 16086 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 16087 return reloc_type == 0;
d347c9df 16088
a06ea964
NC
16089 case EM_AARCH64:
16090 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
16091 case EM_AVR_OLD:
16092 case EM_AVR:
16093 return (reloc_type == 0 /* R_AVR_NONE. */
16094 || reloc_type == 30 /* R_AVR_DIFF8. */
16095 || reloc_type == 31 /* R_AVR_DIFF16. */
16096 || reloc_type == 32 /* R_AVR_DIFF32. */);
16097 case EM_METAG:
16098 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 16099 case EM_NDS32:
81c5e376
AM
16100 return (reloc_type == 0 /* R_NDS32_NONE. */
16101 || reloc_type == 205 /* R_NDS32_DIFF8. */
16102 || reloc_type == 206 /* R_NDS32_DIFF16. */
16103 || reloc_type == 207 /* R_NDS32_DIFF32. */
16104 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
16105 case EM_TI_PRU:
16106 return (reloc_type == 0 /* R_PRU_NONE. */
16107 || reloc_type == 65 /* R_PRU_DIFF8. */
16108 || reloc_type == 66 /* R_PRU_DIFF16. */
16109 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
16110 case EM_XTENSA_OLD:
16111 case EM_XTENSA:
4dc3c23d
AM
16112 return (reloc_type == 0 /* R_XTENSA_NONE. */
16113 || reloc_type == 17 /* R_XTENSA_DIFF8. */
16114 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
16115 || reloc_type == 19 /* R_XTENSA_DIFF32. */
16116 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
16117 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
16118 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
16119 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
16120 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
16121 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 16122 }
015dc7e1 16123 return false;
2a7b2e88
JK
16124}
16125
d1c4b12b
NC
16126/* Returns TRUE if there is a relocation against
16127 section NAME at OFFSET bytes. */
16128
015dc7e1 16129bool
31e5a3a3 16130reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
16131{
16132 Elf_Internal_Rela * relocs;
16133 Elf_Internal_Rela * rp;
16134
16135 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 16136 return false;
d1c4b12b
NC
16137
16138 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
16139
16140 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
16141 if (rp->r_offset == offset)
015dc7e1 16142 return true;
d1c4b12b 16143
015dc7e1 16144 return false;
d1c4b12b
NC
16145}
16146
cf13d699 16147/* Apply relocations to a section.
32ec8896
NC
16148 Returns TRUE upon success, FALSE otherwise.
16149 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
16150 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
16151 will be set to the number of relocs loaded.
16152
cf13d699 16153 Note: So far support has been added only for those relocations
32ec8896
NC
16154 which can be found in debug sections. FIXME: Add support for
16155 more relocations ? */
1b315056 16156
015dc7e1 16157static bool
be7d229a
AM
16158apply_relocations (Filedata *filedata,
16159 const Elf_Internal_Shdr *section,
16160 unsigned char *start,
16161 size_t size,
16162 void **relocs_return,
26c527e6 16163 uint64_t *num_relocs_return)
1b315056 16164{
cf13d699 16165 Elf_Internal_Shdr * relsec;
0d2a7a93 16166 unsigned char * end = start + size;
cb8f3167 16167
d1c4b12b
NC
16168 if (relocs_return != NULL)
16169 {
16170 * (Elf_Internal_Rela **) relocs_return = NULL;
16171 * num_relocs_return = 0;
16172 }
16173
dda8d76d 16174 if (filedata->file_header.e_type != ET_REL)
32ec8896 16175 /* No relocs to apply. */
015dc7e1 16176 return true;
1b315056 16177
cf13d699 16178 /* Find the reloc section associated with the section. */
dda8d76d
NC
16179 for (relsec = filedata->section_headers;
16180 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 16181 ++relsec)
252b5132 16182 {
015dc7e1 16183 bool is_rela;
26c527e6 16184 uint64_t num_relocs;
2cf0635d
NC
16185 Elf_Internal_Rela * relocs;
16186 Elf_Internal_Rela * rp;
16187 Elf_Internal_Shdr * symsec;
16188 Elf_Internal_Sym * symtab;
26c527e6 16189 uint64_t num_syms;
2cf0635d 16190 Elf_Internal_Sym * sym;
252b5132 16191
41e92641 16192 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16193 || relsec->sh_info >= filedata->file_header.e_shnum
16194 || filedata->section_headers + relsec->sh_info != section
c256ffe7 16195 || relsec->sh_size == 0
dda8d76d 16196 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 16197 continue;
428409d5 16198
a788aedd
AM
16199 symsec = filedata->section_headers + relsec->sh_link;
16200 if (symsec->sh_type != SHT_SYMTAB
16201 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 16202 return false;
a788aedd 16203
41e92641
NC
16204 is_rela = relsec->sh_type == SHT_RELA;
16205
16206 if (is_rela)
16207 {
dda8d76d 16208 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 16209 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 16210 return false;
41e92641
NC
16211 }
16212 else
16213 {
dda8d76d 16214 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 16215 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 16216 return false;
41e92641
NC
16217 }
16218
16219 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 16220 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 16221 is_rela = false;
428409d5 16222
4de91c10 16223 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 16224
41e92641 16225 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 16226 {
625d49fc 16227 uint64_t addend;
015dc7e1
AM
16228 unsigned int reloc_type;
16229 unsigned int reloc_size;
16230 bool reloc_inplace = false;
16231 bool reloc_subtract = false;
16232 unsigned char *rloc;
26c527e6 16233 uint64_t sym_index;
4b78141a 16234
dda8d76d 16235 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 16236
dda8d76d 16237 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 16238 continue;
dda8d76d 16239 else if (is_none_reloc (filedata, reloc_type))
98fb390a 16240 continue;
dda8d76d
NC
16241 else if (is_32bit_abs_reloc (filedata, reloc_type)
16242 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 16243 reloc_size = 4;
dda8d76d
NC
16244 else if (is_64bit_abs_reloc (filedata, reloc_type)
16245 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 16246 reloc_size = 8;
dda8d76d 16247 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 16248 reloc_size = 3;
dda8d76d 16249 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 16250 reloc_size = 2;
39e07931
AS
16251 else if (is_8bit_abs_reloc (filedata, reloc_type)
16252 || is_6bit_abs_reloc (filedata, reloc_type))
16253 reloc_size = 1;
03336641
JW
16254 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
16255 reloc_type))
16256 || is_32bit_inplace_add_reloc (filedata, reloc_type))
16257 {
16258 reloc_size = 4;
015dc7e1 16259 reloc_inplace = true;
03336641
JW
16260 }
16261 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
16262 reloc_type))
16263 || is_64bit_inplace_add_reloc (filedata, reloc_type))
16264 {
16265 reloc_size = 8;
015dc7e1 16266 reloc_inplace = true;
03336641
JW
16267 }
16268 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
16269 reloc_type))
16270 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16271 {
16272 reloc_size = 2;
015dc7e1 16273 reloc_inplace = true;
03336641
JW
16274 }
16275 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16276 reloc_type))
16277 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16278 {
16279 reloc_size = 1;
015dc7e1 16280 reloc_inplace = true;
03336641 16281 }
39e07931 16282 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 16283 reloc_type))
16284 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16285 {
16286 reloc_size = 1;
015dc7e1 16287 reloc_inplace = true;
39e07931 16288 }
aca88567 16289 else
4b78141a 16290 {
bee0ee85 16291 static unsigned int prev_reloc = 0;
dda8d76d 16292
bee0ee85
NC
16293 if (reloc_type != prev_reloc)
16294 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 16295 reloc_type, printable_section_name (filedata, section));
bee0ee85 16296 prev_reloc = reloc_type;
4b78141a
NC
16297 continue;
16298 }
103f02d3 16299
91d6fa6a 16300 rloc = start + rp->r_offset;
75802ccb 16301 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 16302 {
26c527e6
AM
16303 warn (_("skipping invalid relocation offset %#" PRIx64
16304 " in section %s\n"),
16305 rp->r_offset,
dda8d76d 16306 printable_section_name (filedata, section));
700dd8b7
L
16307 continue;
16308 }
103f02d3 16309
26c527e6 16310 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
16311 if (sym_index >= num_syms)
16312 {
26c527e6
AM
16313 warn (_("skipping invalid relocation symbol index %#" PRIx64
16314 " in section %s\n"),
dda8d76d 16315 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
16316 continue;
16317 }
16318 sym = symtab + sym_index;
41e92641
NC
16319
16320 /* If the reloc has a symbol associated with it,
55f25fc3
L
16321 make sure that it is of an appropriate type.
16322
16323 Relocations against symbols without type can happen.
16324 Gcc -feliminate-dwarf2-dups may generate symbols
16325 without type for debug info.
16326
16327 Icc generates relocations against function symbols
16328 instead of local labels.
16329
16330 Relocations against object symbols can happen, eg when
16331 referencing a global array. For an example of this see
16332 the _clz.o binary in libgcc.a. */
aca88567 16333 if (sym != symtab
b8871f35 16334 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 16335 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 16336 {
26c527e6 16337 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
16338 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16339 printable_section_name (filedata, relsec),
26c527e6 16340 rp - relocs);
aca88567 16341 continue;
5b18a4bc 16342 }
252b5132 16343
4dc3c23d
AM
16344 addend = 0;
16345 if (is_rela)
16346 addend += rp->r_addend;
c47320c3
AM
16347 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16348 partial_inplace. */
4dc3c23d 16349 if (!is_rela
dda8d76d 16350 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 16351 && reloc_type == 1)
dda8d76d
NC
16352 || ((filedata->file_header.e_machine == EM_PJ
16353 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 16354 && reloc_type == 1)
dda8d76d
NC
16355 || ((filedata->file_header.e_machine == EM_D30V
16356 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
16357 && reloc_type == 12)
16358 || reloc_inplace)
39e07931
AS
16359 {
16360 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16361 addend += byte_get (rloc, reloc_size) & 0x3f;
16362 else
16363 addend += byte_get (rloc, reloc_size);
16364 }
cb8f3167 16365
dda8d76d
NC
16366 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16367 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
16368 {
16369 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 16370 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 16371 addend -= 8;
91d6fa6a 16372 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
16373 reloc_size);
16374 }
39e07931 16375 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 16376 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16377 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16378 {
16379 if (reloc_subtract)
16380 addend -= sym->st_value;
16381 else
16382 addend += sym->st_value;
16383 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16384 byte_put (rloc, addend, reloc_size);
16385 }
03336641
JW
16386 else if (reloc_subtract)
16387 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 16388 else
91d6fa6a 16389 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 16390 }
252b5132 16391
5b18a4bc 16392 free (symtab);
f84ce13b
NC
16393 /* Let the target specific reloc processing code know that
16394 we have finished with these relocs. */
dda8d76d 16395 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
16396
16397 if (relocs_return)
16398 {
16399 * (Elf_Internal_Rela **) relocs_return = relocs;
16400 * num_relocs_return = num_relocs;
16401 }
16402 else
16403 free (relocs);
16404
5b18a4bc
NC
16405 break;
16406 }
32ec8896 16407
015dc7e1 16408 return true;
5b18a4bc 16409}
103f02d3 16410
cf13d699 16411#ifdef SUPPORT_DISASSEMBLY
015dc7e1 16412static bool
dda8d76d 16413disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16414{
dda8d76d 16415 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 16416
74e1a04b 16417 /* FIXME: XXX -- to be done --- XXX */
cf13d699 16418
015dc7e1 16419 return true;
cf13d699
NC
16420}
16421#endif
16422
16423/* Reads in the contents of SECTION from FILE, returning a pointer
16424 to a malloc'ed buffer or NULL if something went wrong. */
16425
16426static char *
dda8d76d 16427get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16428{
be7d229a 16429 uint64_t num_bytes = section->sh_size;
cf13d699
NC
16430
16431 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16432 {
c6b78c96 16433 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 16434 printable_section_name (filedata, section));
cf13d699
NC
16435 return NULL;
16436 }
16437
dda8d76d 16438 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 16439 _("section contents"));
cf13d699
NC
16440}
16441
1f5a3546 16442/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 16443
015dc7e1 16444static bool
45f5fe46
NC
16445uncompress_section_contents (bool is_zstd,
16446 unsigned char ** buffer,
16447 uint64_t uncompressed_size,
16448 uint64_t * size,
16449 uint64_t file_size)
0e602686 16450{
31e5a3a3
AM
16451 uint64_t compressed_size = *size;
16452 unsigned char *compressed_buffer = *buffer;
45f5fe46 16453 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
16454 z_stream strm;
16455 int rc;
16456
f9ee45c3 16457 /* Similar to bfd_section_size_insane() in the BFD library we expect an
45f5fe46
NC
16458 upper limit of ~10x compression. Any compression larger than that is
16459 thought to be due to fuzzing of the compression header. */
16460 if (uncompressed_size > file_size * 10)
16461 {
16462 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16463 uncompressed_size);
16464 goto fail;
16465 }
16466
16467 uncompressed_buffer = xmalloc (uncompressed_size);
16468
1f5a3546
FS
16469 if (is_zstd)
16470 {
16471#ifdef HAVE_ZSTD
16472 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16473 compressed_buffer, compressed_size);
16474 if (ZSTD_isError (ret))
16475 goto fail;
16476#endif
16477 }
16478 else
16479 {
16480 /* It is possible the section consists of several compressed
16481 buffers concatenated together, so we uncompress in a loop. */
16482 /* PR 18313: The state field in the z_stream structure is supposed
16483 to be invisible to the user (ie us), but some compilers will
16484 still complain about it being used without initialisation. So
16485 we first zero the entire z_stream structure and then set the fields
16486 that we need. */
16487 memset (&strm, 0, sizeof strm);
16488 strm.avail_in = compressed_size;
16489 strm.next_in = (Bytef *)compressed_buffer;
16490 strm.avail_out = uncompressed_size;
16491
16492 rc = inflateInit (&strm);
16493 while (strm.avail_in > 0)
16494 {
16495 if (rc != Z_OK)
16496 break;
16497 strm.next_out = ((Bytef *)uncompressed_buffer
16498 + (uncompressed_size - strm.avail_out));
16499 rc = inflate (&strm, Z_FINISH);
16500 if (rc != Z_STREAM_END)
16501 break;
16502 rc = inflateReset (&strm);
16503 }
16504 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16505 goto fail;
16506 }
0e602686
NC
16507
16508 *buffer = uncompressed_buffer;
16509 *size = uncompressed_size;
015dc7e1 16510 return true;
0e602686
NC
16511
16512 fail:
16513 free (uncompressed_buffer);
16514 /* Indicate decompression failure. */
16515 *buffer = NULL;
015dc7e1 16516 return false;
0e602686 16517}
dd24e3da 16518
fab62191
NC
16519static uint64_t
16520maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16521 Filedata * filedata,
16522 unsigned char ** start_ptr,
16523 bool relocate)
cf13d699 16524{
fab62191
NC
16525 uint64_t section_size = section->sh_size;
16526 unsigned char * start = * start_ptr;
16527
0e602686
NC
16528 if (decompress_dumps)
16529 {
fab62191 16530 uint64_t new_size = section_size;
31e5a3a3 16531 uint64_t uncompressed_size = 0;
1f5a3546 16532 bool is_zstd = false;
0e602686
NC
16533
16534 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16535 {
16536 Elf_Internal_Chdr chdr;
16537 unsigned int compression_header_size
fab62191
NC
16538 = get_compression_header (& chdr, start, section_size);
16539
5844b465
NC
16540 if (compression_header_size == 0)
16541 /* An error message will have already been generated
16542 by get_compression_header. */
fab62191 16543 return (uint64_t) -1;
0e602686 16544
89dbeac7 16545 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16546 ;
16547#ifdef HAVE_ZSTD
89dbeac7 16548 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16549 is_zstd = true;
16550#endif
16551 else
0e602686 16552 {
813dabb9 16553 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16554 printable_section_name (filedata, section), chdr.ch_type);
fab62191 16555 return (uint64_t) -1;
813dabb9 16556 }
fab62191 16557
813dabb9
L
16558 uncompressed_size = chdr.ch_size;
16559 start += compression_header_size;
16560 new_size -= compression_header_size;
0e602686
NC
16561 }
16562 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16563 {
16564 /* Read the zlib header. In this case, it should be "ZLIB"
16565 followed by the uncompressed section size, 8 bytes in
16566 big-endian order. */
16567 uncompressed_size = start[4]; uncompressed_size <<= 8;
16568 uncompressed_size += start[5]; uncompressed_size <<= 8;
16569 uncompressed_size += start[6]; uncompressed_size <<= 8;
16570 uncompressed_size += start[7]; uncompressed_size <<= 8;
16571 uncompressed_size += start[8]; uncompressed_size <<= 8;
16572 uncompressed_size += start[9]; uncompressed_size <<= 8;
16573 uncompressed_size += start[10]; uncompressed_size <<= 8;
16574 uncompressed_size += start[11];
16575 start += 12;
16576 new_size -= 12;
16577 }
16578
1835f746
NC
16579 if (uncompressed_size)
16580 {
1f5a3546 16581 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16582 &new_size, filedata->file_size))
fab62191 16583 section_size = new_size;
1835f746
NC
16584 else
16585 {
16586 error (_("Unable to decompress section %s\n"),
dda8d76d 16587 printable_section_name (filedata, section));
fab62191 16588 return (uint64_t) -1;
1835f746
NC
16589 }
16590 }
bc303e5d 16591 else
fab62191
NC
16592 start = * start_ptr;
16593 }
16594 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16595 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16596 {
16597 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
0e602686 16598 }
fd8008d8 16599
fab62191 16600 if (relocate)
cf13d699 16601 {
fab62191
NC
16602 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16603 return (uint64_t) -1;
16604 }
16605 else
16606 {
16607 Elf_Internal_Shdr *relsec;
cf13d699 16608
fab62191
NC
16609 /* If the section being dumped has relocations against it the user might
16610 be expecting these relocations to have been applied. Check for this
16611 case and issue a warning message in order to avoid confusion.
16612 FIXME: Maybe we ought to have an option that dumps a section with
16613 relocs applied ? */
16614 for (relsec = filedata->section_headers;
16615 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16616 ++relsec)
16617 {
16618 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16619 || relsec->sh_info >= filedata->file_header.e_shnum
16620 || filedata->section_headers + relsec->sh_info != section
16621 || relsec->sh_size == 0
16622 || relsec->sh_link >= filedata->file_header.e_shnum)
16623 continue;
16624
16625 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16626 break;
16627 }
cf13d699
NC
16628 }
16629
fab62191
NC
16630 * start_ptr = start;
16631 return section_size;
16632}
16633
16634static bool
16635dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16636{
16637 uint64_t num_bytes;
16638 unsigned char *data;
16639 unsigned char *end;
16640 unsigned char *real_start;
16641 unsigned char *start;
16642 bool some_strings_shown;
16643
16644 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16645 if (start == NULL)
16646 /* PR 21820: Do not fail if the section was empty. */
16647 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16648
16649 num_bytes = section->sh_size;
16650
16651 if (filedata->is_separate)
16652 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16653 printable_section_name (filedata, section),
16654 filedata->file_name);
16655 else
16656 printf (_("\nString dump of section '%s':\n"),
16657 printable_section_name (filedata, section));
16658
16659 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16660 if (num_bytes == (uint64_t) -1)
16661 goto error_out;
16662
cf13d699
NC
16663 data = start;
16664 end = start + num_bytes;
015dc7e1 16665 some_strings_shown = false;
cf13d699 16666
ba3265d0
NC
16667#ifdef HAVE_MBSTATE_T
16668 mbstate_t state;
16669 /* Initialise the multibyte conversion state. */
16670 memset (& state, 0, sizeof (state));
16671#endif
16672
015dc7e1 16673 bool continuing = false;
ba3265d0 16674
cf13d699
NC
16675 while (data < end)
16676 {
16677 while (!ISPRINT (* data))
16678 if (++ data >= end)
16679 break;
16680
16681 if (data < end)
16682 {
071436c6
NC
16683 size_t maxlen = end - data;
16684
ba3265d0
NC
16685 if (continuing)
16686 {
16687 printf (" ");
015dc7e1 16688 continuing = false;
ba3265d0
NC
16689 }
16690 else
16691 {
26c527e6 16692 printf (" [%6tx] ", data - start);
ba3265d0
NC
16693 }
16694
4082ef84
NC
16695 if (maxlen > 0)
16696 {
f3da8a96 16697 char c = 0;
ba3265d0
NC
16698
16699 while (maxlen)
16700 {
16701 c = *data++;
16702
16703 if (c == 0)
16704 break;
16705
16706 /* PR 25543: Treat new-lines as string-ending characters. */
16707 if (c == '\n')
16708 {
16709 printf ("\\n\n");
16710 if (*data != 0)
015dc7e1 16711 continuing = true;
ba3265d0
NC
16712 break;
16713 }
16714
16715 /* Do not print control characters directly as they can affect terminal
16716 settings. Such characters usually appear in the names generated
16717 by the assembler for local labels. */
16718 if (ISCNTRL (c))
16719 {
16720 printf ("^%c", c + 0x40);
16721 }
16722 else if (ISPRINT (c))
16723 {
16724 putchar (c);
16725 }
16726 else
16727 {
16728 size_t n;
16729#ifdef HAVE_MBSTATE_T
16730 wchar_t w;
16731#endif
16732 /* Let printf do the hard work of displaying multibyte characters. */
16733 printf ("%.1s", data - 1);
16734#ifdef HAVE_MBSTATE_T
16735 /* Try to find out how many bytes made up the character that was
16736 just printed. Advance the symbol pointer past the bytes that
16737 were displayed. */
16738 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16739#else
16740 n = 1;
16741#endif
16742 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16743 data += (n - 1);
16744 }
16745 }
16746
16747 if (c != '\n')
16748 putchar ('\n');
4082ef84
NC
16749 }
16750 else
16751 {
16752 printf (_("<corrupt>\n"));
16753 data = end;
16754 }
015dc7e1 16755 some_strings_shown = true;
cf13d699
NC
16756 }
16757 }
16758
16759 if (! some_strings_shown)
16760 printf (_(" No strings found in this section."));
16761
0e602686 16762 free (real_start);
cf13d699
NC
16763
16764 putchar ('\n');
015dc7e1 16765 return true;
f761cb13
AM
16766
16767error_out:
16768 free (real_start);
015dc7e1 16769 return false;
cf13d699
NC
16770}
16771
015dc7e1
AM
16772static bool
16773dump_section_as_bytes (Elf_Internal_Shdr *section,
16774 Filedata *filedata,
16775 bool relocate)
cf13d699 16776{
be7d229a
AM
16777 size_t bytes;
16778 uint64_t section_size;
625d49fc 16779 uint64_t addr;
be7d229a
AM
16780 unsigned char *data;
16781 unsigned char *real_start;
16782 unsigned char *start;
0e602686 16783
dda8d76d 16784 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16785 if (start == NULL)
c6b78c96 16786 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16787 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16788
0e602686 16789 section_size = section->sh_size;
cf13d699 16790
835f2fae
NC
16791 if (filedata->is_separate)
16792 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16793 printable_section_name (filedata, section),
16794 filedata->file_name);
16795 else
16796 printf (_("\nHex dump of section '%s':\n"),
16797 printable_section_name (filedata, section));
cf13d699 16798
fab62191
NC
16799 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16800 if (section_size == (uint64_t) -1)
16801 goto error_out;
cf13d699
NC
16802
16803 addr = section->sh_addr;
0e602686 16804 bytes = section_size;
cf13d699
NC
16805 data = start;
16806
16807 while (bytes)
16808 {
16809 int j;
16810 int k;
16811 int lbytes;
16812
16813 lbytes = (bytes > 16 ? 16 : bytes);
16814
26c527e6 16815 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16816
16817 for (j = 0; j < 16; j++)
16818 {
16819 if (j < lbytes)
16820 printf ("%2.2x", data[j]);
16821 else
16822 printf (" ");
16823
16824 if ((j & 3) == 3)
16825 printf (" ");
16826 }
16827
16828 for (j = 0; j < lbytes; j++)
16829 {
16830 k = data[j];
16831 if (k >= ' ' && k < 0x7f)
16832 printf ("%c", k);
16833 else
16834 printf (".");
16835 }
16836
16837 putchar ('\n');
16838
16839 data += lbytes;
16840 addr += lbytes;
16841 bytes -= lbytes;
16842 }
16843
0e602686 16844 free (real_start);
cf13d699
NC
16845
16846 putchar ('\n');
015dc7e1 16847 return true;
f761cb13
AM
16848
16849 error_out:
16850 free (real_start);
015dc7e1 16851 return false;
cf13d699
NC
16852}
16853
094e34f2 16854#ifdef ENABLE_LIBCTF
7d9813f1
NA
16855static ctf_sect_t *
16856shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16857{
b6ac461a 16858 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16859 buf->cts_size = shdr->sh_size;
16860 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16861
16862 return buf;
16863}
16864
16865/* Formatting callback function passed to ctf_dump. Returns either the pointer
16866 it is passed, or a pointer to newly-allocated storage, in which case
16867 dump_ctf() will free it when it no longer needs it. */
16868
2f6ecaed
NA
16869static char *
16870dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16871 char *s, void *arg)
7d9813f1 16872{
3e50a591 16873 const char *blanks = arg;
7d9813f1
NA
16874 char *new_s;
16875
3e50a591 16876 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16877 return s;
16878 return new_s;
16879}
16880
926c9e76
NA
16881/* Dump CTF errors/warnings. */
16882static void
139633c3 16883dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16884{
16885 ctf_next_t *it = NULL;
16886 char *errtext;
16887 int is_warning;
16888 int err;
16889
16890 /* Dump accumulated errors and warnings. */
16891 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16892 {
5e9b84f7 16893 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16894 errtext);
16895 free (errtext);
16896 }
16897 if (err != ECTF_NEXT_END)
16898 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16899}
16900
2f6ecaed
NA
16901/* Dump one CTF archive member. */
16902
80b56fad
NA
16903static void
16904dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16905 size_t member)
2f6ecaed 16906{
2f6ecaed
NA
16907 const char *things[] = {"Header", "Labels", "Data objects",
16908 "Function objects", "Variables", "Types", "Strings",
16909 ""};
16910 const char **thing;
16911 size_t i;
16912
80b56fad
NA
16913 /* Don't print out the name of the default-named archive member if it appears
16914 first in the list. The name .ctf appears everywhere, even for things that
16915 aren't really archives, so printing it out is liable to be confusing; also,
16916 the common case by far is for only one archive member to exist, and hiding
16917 it in that case seems worthwhile. */
2f6ecaed 16918
80b56fad
NA
16919 if (strcmp (name, ".ctf") != 0 || member != 0)
16920 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16921
80b56fad
NA
16922 if (ctf_parent_name (ctf) != NULL)
16923 ctf_import (ctf, parent);
2f6ecaed
NA
16924
16925 for (i = 0, thing = things; *thing[0]; thing++, i++)
16926 {
16927 ctf_dump_state_t *s = NULL;
16928 char *item;
16929
16930 printf ("\n %s:\n", *thing);
16931 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16932 (void *) " ")) != NULL)
16933 {
16934 printf ("%s\n", item);
16935 free (item);
16936 }
16937
16938 if (ctf_errno (ctf))
16939 {
16940 error (_("Iteration failed: %s, %s\n"), *thing,
16941 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16942 break;
2f6ecaed
NA
16943 }
16944 }
8b37e7b6 16945
926c9e76 16946 dump_ctf_errs (ctf);
2f6ecaed
NA
16947}
16948
015dc7e1 16949static bool
7d9813f1
NA
16950dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16951{
7d9813f1
NA
16952 Elf_Internal_Shdr * symtab_sec = NULL;
16953 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16954 void * data = NULL;
16955 void * symdata = NULL;
16956 void * strdata = NULL;
80b56fad 16957 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16958 ctf_sect_t * symsectp = NULL;
16959 ctf_sect_t * strsectp = NULL;
2f6ecaed 16960 ctf_archive_t * ctfa = NULL;
139633c3 16961 ctf_dict_t * parent = NULL;
80b56fad 16962 ctf_dict_t * fp;
7d9813f1 16963
80b56fad
NA
16964 ctf_next_t *i = NULL;
16965 const char *name;
16966 size_t member = 0;
7d9813f1 16967 int err;
015dc7e1 16968 bool ret = false;
7d9813f1
NA
16969
16970 shdr_to_ctf_sect (&ctfsect, section, filedata);
16971 data = get_section_contents (section, filedata);
16972 ctfsect.cts_data = data;
16973
616febde 16974 if (!dump_ctf_symtab_name)
3d16b64e 16975 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16976
16977 if (!dump_ctf_strtab_name)
3d16b64e 16978 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16979
16980 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16981 {
16982 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16983 {
16984 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16985 goto fail;
16986 }
16987 if ((symdata = (void *) get_data (NULL, filedata,
16988 symtab_sec->sh_offset, 1,
16989 symtab_sec->sh_size,
16990 _("symbols"))) == NULL)
16991 goto fail;
16992 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16993 symsect.cts_data = symdata;
16994 }
835f2fae 16995
df16e041 16996 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16997 {
16998 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16999 {
17000 error (_("No string table section named %s\n"),
17001 dump_ctf_strtab_name);
17002 goto fail;
17003 }
17004 if ((strdata = (void *) get_data (NULL, filedata,
17005 strtab_sec->sh_offset, 1,
17006 strtab_sec->sh_size,
17007 _("strings"))) == NULL)
17008 goto fail;
17009 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
17010 strsect.cts_data = strdata;
17011 }
835f2fae 17012
2f6ecaed
NA
17013 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
17014 libctf papers over the difference, so we can pretend it is always an
80b56fad 17015 archive. */
7d9813f1 17016
2f6ecaed 17017 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 17018 {
926c9e76 17019 dump_ctf_errs (NULL);
7d9813f1
NA
17020 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17021 goto fail;
17022 }
17023
96c61be5
NA
17024 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
17025 != ELFDATA2MSB);
17026
80b56fad
NA
17027 /* Preload the parent dict, since it will need to be imported into every
17028 child in turn. */
17029 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 17030 {
926c9e76 17031 dump_ctf_errs (NULL);
2f6ecaed
NA
17032 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17033 goto fail;
7d9813f1
NA
17034 }
17035
015dc7e1 17036 ret = true;
7d9813f1 17037
835f2fae
NC
17038 if (filedata->is_separate)
17039 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
17040 printable_section_name (filedata, section),
17041 filedata->file_name);
17042 else
17043 printf (_("\nDump of CTF section '%s':\n"),
17044 printable_section_name (filedata, section));
7d9813f1 17045
80b56fad
NA
17046 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
17047 dump_ctf_archive_member (fp, name, parent, member++);
17048 if (err != ECTF_NEXT_END)
17049 {
17050 dump_ctf_errs (NULL);
17051 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
17052 ret = false;
17053 }
7d9813f1
NA
17054
17055 fail:
139633c3 17056 ctf_dict_close (parent);
2f6ecaed 17057 ctf_close (ctfa);
7d9813f1
NA
17058 free (data);
17059 free (symdata);
17060 free (strdata);
17061 return ret;
17062}
094e34f2 17063#endif
7d9813f1 17064
42b6953b
IB
17065static bool
17066dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
17067{
17068 void * data = NULL;
17069 sframe_decoder_ctx *sfd_ctx = NULL;
17070 const char *print_name = printable_section_name (filedata, section);
17071
17072 bool ret = true;
17073 size_t sf_size;
17074 int err = 0;
17075
17076 if (strcmp (print_name, "") == 0)
17077 {
17078 error (_("Section name must be provided \n"));
17079 ret = false;
17080 return ret;
17081 }
17082
17083 data = get_section_contents (section, filedata);
17084 sf_size = section->sh_size;
17085 /* Decode the contents of the section. */
17086 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
17087 if (!sfd_ctx)
17088 {
17089 ret = false;
17090 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
17091 goto fail;
17092 }
17093
17094 printf (_("Contents of the SFrame section %s:"), print_name);
17095 /* Dump the contents as text. */
17096 dump_sframe (sfd_ctx, section->sh_addr);
17097
17098 fail:
17099 free (data);
17100 return ret;
17101}
17102
015dc7e1 17103static bool
dda8d76d
NC
17104load_specific_debug_section (enum dwarf_section_display_enum debug,
17105 const Elf_Internal_Shdr * sec,
17106 void * data)
1007acb3 17107{
2cf0635d 17108 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 17109 char buf [64];
dda8d76d 17110 Filedata * filedata = (Filedata *) data;
9abca702 17111
19e6b90e 17112 if (section->start != NULL)
dda8d76d
NC
17113 {
17114 /* If it is already loaded, do nothing. */
17115 if (streq (section->filename, filedata->file_name))
015dc7e1 17116 return true;
dda8d76d
NC
17117 free (section->start);
17118 }
1007acb3 17119
19e6b90e
L
17120 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
17121 section->address = sec->sh_addr;
dda8d76d
NC
17122 section->filename = filedata->file_name;
17123 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
17124 sec->sh_offset, 1,
17125 sec->sh_size, buf);
59245841
NC
17126 if (section->start == NULL)
17127 section->size = 0;
17128 else
17129 {
77115a4a 17130 unsigned char *start = section->start;
31e5a3a3
AM
17131 uint64_t size = sec->sh_size;
17132 uint64_t uncompressed_size = 0;
1f5a3546 17133 bool is_zstd = false;
77115a4a
L
17134
17135 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
17136 {
17137 Elf_Internal_Chdr chdr;
d8024a91
NC
17138 unsigned int compression_header_size;
17139
f53be977
L
17140 if (size < (is_32bit_elf
17141 ? sizeof (Elf32_External_Chdr)
17142 : sizeof (Elf64_External_Chdr)))
d8024a91 17143 {
55be8fd0 17144 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 17145 section->name);
015dc7e1 17146 return false;
d8024a91
NC
17147 }
17148
ebdf1ebf 17149 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
17150 if (compression_header_size == 0)
17151 /* An error message will have already been generated
17152 by get_compression_header. */
015dc7e1 17153 return false;
d8024a91 17154
89dbeac7 17155 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
17156 ;
17157#ifdef HAVE_ZSTD
89dbeac7 17158 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
17159 is_zstd = true;
17160#endif
17161 else
813dabb9
L
17162 {
17163 warn (_("section '%s' has unsupported compress type: %d\n"),
17164 section->name, chdr.ch_type);
015dc7e1 17165 return false;
813dabb9 17166 }
dab394de 17167 uncompressed_size = chdr.ch_size;
77115a4a
L
17168 start += compression_header_size;
17169 size -= compression_header_size;
17170 }
dab394de
L
17171 else if (size > 12 && streq ((char *) start, "ZLIB"))
17172 {
17173 /* Read the zlib header. In this case, it should be "ZLIB"
17174 followed by the uncompressed section size, 8 bytes in
17175 big-endian order. */
17176 uncompressed_size = start[4]; uncompressed_size <<= 8;
17177 uncompressed_size += start[5]; uncompressed_size <<= 8;
17178 uncompressed_size += start[6]; uncompressed_size <<= 8;
17179 uncompressed_size += start[7]; uncompressed_size <<= 8;
17180 uncompressed_size += start[8]; uncompressed_size <<= 8;
17181 uncompressed_size += start[9]; uncompressed_size <<= 8;
17182 uncompressed_size += start[10]; uncompressed_size <<= 8;
17183 uncompressed_size += start[11];
17184 start += 12;
17185 size -= 12;
17186 }
17187
1835f746 17188 if (uncompressed_size)
77115a4a 17189 {
1f5a3546 17190 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 17191 &size, filedata->file_size))
1835f746
NC
17192 {
17193 /* Free the compressed buffer, update the section buffer
17194 and the section size if uncompress is successful. */
17195 free (section->start);
17196 section->start = start;
17197 }
17198 else
17199 {
17200 error (_("Unable to decompress section %s\n"),
dda8d76d 17201 printable_section_name (filedata, sec));
015dc7e1 17202 return false;
1835f746 17203 }
77115a4a 17204 }
bc303e5d 17205
77115a4a 17206 section->size = size;
59245841 17207 }
4a114e3e 17208
1b315056 17209 if (section->start == NULL)
015dc7e1 17210 return false;
1b315056 17211
19e6b90e 17212 if (debug_displays [debug].relocate)
32ec8896 17213 {
dda8d76d 17214 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 17215 & section->reloc_info, & section->num_relocs))
015dc7e1 17216 return false;
32ec8896 17217 }
d1c4b12b
NC
17218 else
17219 {
17220 section->reloc_info = NULL;
17221 section->num_relocs = 0;
17222 }
1007acb3 17223
015dc7e1 17224 return true;
1007acb3
L
17225}
17226
301a9420
AM
17227#if HAVE_LIBDEBUGINFOD
17228/* Return a hex string representation of the build-id. */
17229unsigned char *
17230get_build_id (void * data)
17231{
ca0e11aa 17232 Filedata * filedata = (Filedata *) data;
301a9420 17233 Elf_Internal_Shdr * shdr;
26c527e6 17234 size_t i;
301a9420 17235
55be8fd0
NC
17236 /* Iterate through notes to find note.gnu.build-id.
17237 FIXME: Only the first note in any note section is examined. */
301a9420
AM
17238 for (i = 0, shdr = filedata->section_headers;
17239 i < filedata->file_header.e_shnum && shdr != NULL;
17240 i++, shdr++)
17241 {
17242 if (shdr->sh_type != SHT_NOTE)
17243 continue;
17244
17245 char * next;
17246 char * end;
17247 size_t data_remaining;
17248 size_t min_notesz;
17249 Elf_External_Note * enote;
17250 Elf_Internal_Note inote;
17251
625d49fc
AM
17252 uint64_t offset = shdr->sh_offset;
17253 uint64_t align = shdr->sh_addralign;
17254 uint64_t length = shdr->sh_size;
301a9420
AM
17255
17256 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
17257 if (enote == NULL)
17258 continue;
17259
17260 if (align < 4)
17261 align = 4;
17262 else if (align != 4 && align != 8)
f761cb13
AM
17263 {
17264 free (enote);
17265 continue;
17266 }
301a9420
AM
17267
17268 end = (char *) enote + length;
17269 data_remaining = end - (char *) enote;
17270
17271 if (!is_ia64_vms (filedata))
17272 {
17273 min_notesz = offsetof (Elf_External_Note, name);
17274 if (data_remaining < min_notesz)
17275 {
55be8fd0
NC
17276 warn (_("\
17277malformed note encountered in section %s whilst scanning for build-id note\n"),
17278 printable_section_name (filedata, shdr));
f761cb13 17279 free (enote);
55be8fd0 17280 continue;
301a9420
AM
17281 }
17282 data_remaining -= min_notesz;
17283
17284 inote.type = BYTE_GET (enote->type);
17285 inote.namesz = BYTE_GET (enote->namesz);
17286 inote.namedata = enote->name;
17287 inote.descsz = BYTE_GET (enote->descsz);
17288 inote.descdata = ((char *) enote
17289 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17290 inote.descpos = offset + (inote.descdata - (char *) enote);
17291 next = ((char *) enote
17292 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17293 }
17294 else
17295 {
17296 Elf64_External_VMS_Note *vms_enote;
17297
17298 /* PR binutils/15191
17299 Make sure that there is enough data to read. */
17300 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17301 if (data_remaining < min_notesz)
17302 {
55be8fd0
NC
17303 warn (_("\
17304malformed note encountered in section %s whilst scanning for build-id note\n"),
17305 printable_section_name (filedata, shdr));
f761cb13 17306 free (enote);
55be8fd0 17307 continue;
301a9420
AM
17308 }
17309 data_remaining -= min_notesz;
17310
17311 vms_enote = (Elf64_External_VMS_Note *) enote;
17312 inote.type = BYTE_GET (vms_enote->type);
17313 inote.namesz = BYTE_GET (vms_enote->namesz);
17314 inote.namedata = vms_enote->name;
17315 inote.descsz = BYTE_GET (vms_enote->descsz);
17316 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17317 inote.descpos = offset + (inote.descdata - (char *) enote);
17318 next = inote.descdata + align_power (inote.descsz, 3);
17319 }
17320
17321 /* Skip malformed notes. */
17322 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17323 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17324 || (size_t) (next - inote.descdata) < inote.descsz
17325 || ((size_t) (next - inote.descdata)
17326 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17327 {
55be8fd0
NC
17328 warn (_("\
17329malformed note encountered in section %s whilst scanning for build-id note\n"),
17330 printable_section_name (filedata, shdr));
f761cb13 17331 free (enote);
301a9420
AM
17332 continue;
17333 }
17334
17335 /* Check if this is the build-id note. If so then convert the build-id
17336 bytes to a hex string. */
17337 if (inote.namesz > 0
24d127aa 17338 && startswith (inote.namedata, "GNU")
301a9420
AM
17339 && inote.type == NT_GNU_BUILD_ID)
17340 {
26c527e6 17341 size_t j;
301a9420
AM
17342 char * build_id;
17343
17344 build_id = malloc (inote.descsz * 2 + 1);
17345 if (build_id == NULL)
f761cb13
AM
17346 {
17347 free (enote);
17348 return NULL;
17349 }
301a9420
AM
17350
17351 for (j = 0; j < inote.descsz; ++j)
17352 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17353 build_id[inote.descsz * 2] = '\0';
f761cb13 17354 free (enote);
301a9420 17355
55be8fd0 17356 return (unsigned char *) build_id;
301a9420 17357 }
f761cb13 17358 free (enote);
301a9420
AM
17359 }
17360
17361 return NULL;
17362}
17363#endif /* HAVE_LIBDEBUGINFOD */
17364
657d0d47
CC
17365/* If this is not NULL, load_debug_section will only look for sections
17366 within the list of sections given here. */
32ec8896 17367static unsigned int * section_subset = NULL;
657d0d47 17368
015dc7e1 17369bool
dda8d76d 17370load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 17371{
2cf0635d
NC
17372 struct dwarf_section * section = &debug_displays [debug].section;
17373 Elf_Internal_Shdr * sec;
dda8d76d
NC
17374 Filedata * filedata = (Filedata *) data;
17375
e1dbfc17
L
17376 if (!dump_any_debugging)
17377 return false;
17378
f425ec66
NC
17379 /* Without section headers we cannot find any sections. */
17380 if (filedata->section_headers == NULL)
015dc7e1 17381 return false;
f425ec66 17382
9c1ce108
AM
17383 if (filedata->string_table == NULL
17384 && filedata->file_header.e_shstrndx != SHN_UNDEF
17385 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
17386 {
17387 Elf_Internal_Shdr * strs;
17388
17389 /* Read in the string table, so that we have section names to scan. */
17390 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17391
4dff97b2 17392 if (strs != NULL && strs->sh_size != 0)
dda8d76d 17393 {
9c1ce108
AM
17394 filedata->string_table
17395 = (char *) get_data (NULL, filedata, strs->sh_offset,
17396 1, strs->sh_size, _("string table"));
dda8d76d 17397
9c1ce108
AM
17398 filedata->string_table_length
17399 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
17400 }
17401 }
d966045b
DJ
17402
17403 /* Locate the debug section. */
dda8d76d 17404 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
17405 if (sec != NULL)
17406 section->name = section->uncompressed_name;
17407 else
17408 {
dda8d76d 17409 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
17410 if (sec != NULL)
17411 section->name = section->compressed_name;
17412 }
17413 if (sec == NULL)
015dc7e1 17414 return false;
d966045b 17415
657d0d47
CC
17416 /* If we're loading from a subset of sections, and we've loaded
17417 a section matching this name before, it's likely that it's a
17418 different one. */
17419 if (section_subset != NULL)
17420 free_debug_section (debug);
17421
dda8d76d 17422 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
17423}
17424
19e6b90e
L
17425void
17426free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 17427{
2cf0635d 17428 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 17429
19e6b90e
L
17430 if (section->start == NULL)
17431 return;
1007acb3 17432
19e6b90e
L
17433 free ((char *) section->start);
17434 section->start = NULL;
17435 section->address = 0;
17436 section->size = 0;
a788aedd 17437
9db70fc3
AM
17438 free (section->reloc_info);
17439 section->reloc_info = NULL;
17440 section->num_relocs = 0;
1007acb3
L
17441}
17442
015dc7e1 17443static bool
dda8d76d 17444display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 17445{
84714f86
AM
17446 const char *name = (section_name_valid (filedata, section)
17447 ? section_name (filedata, section) : "");
17448 const char *print_name = printable_section_name (filedata, section);
be7d229a 17449 uint64_t length;
015dc7e1 17450 bool result = true;
3f5e193b 17451 int i;
1007acb3 17452
19e6b90e
L
17453 length = section->sh_size;
17454 if (length == 0)
1007acb3 17455 {
74e1a04b 17456 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 17457 return true;
1007acb3 17458 }
5dff79d8
NC
17459 if (section->sh_type == SHT_NOBITS)
17460 {
17461 /* There is no point in dumping the contents of a debugging section
17462 which has the NOBITS type - the bits in the file will be random.
17463 This can happen when a file containing a .eh_frame section is
17464 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
17465 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17466 print_name);
015dc7e1 17467 return false;
5dff79d8 17468 }
1007acb3 17469
24d127aa 17470 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 17471 name = ".debug_info";
1007acb3 17472
19e6b90e
L
17473 /* See if we know how to display the contents of this section. */
17474 for (i = 0; i < max; i++)
d85bf2ba
NC
17475 {
17476 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17477 struct dwarf_section_display * display = debug_displays + i;
17478 struct dwarf_section * sec = & display->section;
d966045b 17479
d85bf2ba 17480 if (streq (sec->uncompressed_name, name)
24d127aa 17481 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17482 || streq (sec->compressed_name, name))
17483 {
015dc7e1 17484 bool secondary = (section != find_section (filedata, name));
1007acb3 17485
d85bf2ba
NC
17486 if (secondary)
17487 free_debug_section (id);
dda8d76d 17488
24d127aa 17489 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17490 sec->name = name;
17491 else if (streq (sec->uncompressed_name, name))
17492 sec->name = sec->uncompressed_name;
17493 else
17494 sec->name = sec->compressed_name;
657d0d47 17495
d85bf2ba
NC
17496 if (load_specific_debug_section (id, section, filedata))
17497 {
17498 /* If this debug section is part of a CU/TU set in a .dwp file,
17499 restrict load_debug_section to the sections in that set. */
17500 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17501
d85bf2ba 17502 result &= display->display (sec, filedata);
657d0d47 17503
d85bf2ba 17504 section_subset = NULL;
1007acb3 17505
44266f36 17506 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17507 free_debug_section (id);
17508 }
17509 break;
17510 }
17511 }
1007acb3 17512
19e6b90e 17513 if (i == max)
1007acb3 17514 {
74e1a04b 17515 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17516 result = false;
1007acb3
L
17517 }
17518
19e6b90e 17519 return result;
5b18a4bc 17520}
103f02d3 17521
aef1f6d0
DJ
17522/* Set DUMP_SECTS for all sections where dumps were requested
17523 based on section name. */
17524
17525static void
dda8d76d 17526initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17527{
2cf0635d 17528 struct dump_list_entry * cur;
aef1f6d0
DJ
17529
17530 for (cur = dump_sects_byname; cur; cur = cur->next)
17531 {
17532 unsigned int i;
015dc7e1 17533 bool any = false;
aef1f6d0 17534
dda8d76d 17535 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17536 if (section_name_valid (filedata, filedata->section_headers + i)
17537 && streq (section_name (filedata, filedata->section_headers + i),
17538 cur->name))
aef1f6d0 17539 {
6431e409 17540 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17541 any = true;
aef1f6d0
DJ
17542 }
17543
835f2fae
NC
17544 if (!any && !filedata->is_separate)
17545 warn (_("Section '%s' was not dumped because it does not exist\n"),
17546 cur->name);
aef1f6d0
DJ
17547 }
17548}
17549
015dc7e1 17550static bool
dda8d76d 17551process_section_contents (Filedata * filedata)
5b18a4bc 17552{
2cf0635d 17553 Elf_Internal_Shdr * section;
19e6b90e 17554 unsigned int i;
015dc7e1 17555 bool res = true;
103f02d3 17556
19e6b90e 17557 if (! do_dump)
015dc7e1 17558 return true;
103f02d3 17559
dda8d76d 17560 initialise_dumps_byname (filedata);
aef1f6d0 17561
dda8d76d 17562 for (i = 0, section = filedata->section_headers;
6431e409 17563 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17564 i++, section++)
17565 {
6431e409 17566 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17567
d6bfbc39
NC
17568 if (filedata->is_separate && ! process_links)
17569 dump &= DEBUG_DUMP;
047c3dbf 17570
8e8d0b63
NC
17571 if (dump & AUTO_DUMP)
17572 {
17573 switch (section->sh_type)
17574 {
17575 case SHT_PROGBITS:
17576 /* FIXME: There are lots of different type of section that have
17577 SHT_PROGBITS set in their header - code, debug info, etc. So
17578 we should check the section's name and interpret its contents
17579 that way, rather than just defaulting to a byte dump. */
17580#ifdef SUPPORT_DISASSEMBLY
17581 res &= disassemble_section (section, filedata);
17582#else
17583 res &= dump_section_as_bytes (section, filedata, false);
17584#endif
17585 break;
17586
17587 case SHT_DYNSYM:
17588 case SHT_SYMTAB:
17589 res &= dump_symbol_section (section, filedata);
17590 break;
17591
17592 case SHT_STRTAB:
17593 res &= dump_section_as_strings (section, filedata);
17594 break;
17595
17596 case SHT_RELA:
17597 case SHT_REL:
17598 case SHT_RELR:
17599 res &= display_relocations (section, filedata);
17600 break;
17601
17602 case SHT_NOTE:
17603 res &= process_notes_at (filedata, section, section->sh_offset,
17604 section->sh_size, section->sh_addralign);
17605 break;
17606
17607 case SHT_NULL:
17608 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17609 break;
17610
17611 case SHT_NOBITS:
17612 inform (_("Unable to display section %d - it has no contents\n"), i);
17613 break;
17614
17615 case SHT_HASH:
17616 case SHT_DYNAMIC:
17617 case SHT_GROUP:
17618 case SHT_GNU_ATTRIBUTES:
17619 /* FIXME: Implement these. */
17620 /* Fall through. */
17621 default:
17622 /* FIXME: Add Proc and OS specific section types ? */
17623 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17624 i, section->sh_type);
17625 res = false;
17626 break;
17627 }
17628 }
17629
19e6b90e 17630#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17631 if (dump & DISASS_DUMP)
17632 {
17633 if (! disassemble_section (section, filedata))
015dc7e1 17634 res = false;
dda8d76d 17635 }
19e6b90e 17636#endif
dda8d76d 17637 if (dump & HEX_DUMP)
32ec8896 17638 {
015dc7e1
AM
17639 if (! dump_section_as_bytes (section, filedata, false))
17640 res = false;
32ec8896 17641 }
103f02d3 17642
dda8d76d 17643 if (dump & RELOC_DUMP)
32ec8896 17644 {
015dc7e1
AM
17645 if (! dump_section_as_bytes (section, filedata, true))
17646 res = false;
32ec8896 17647 }
09c11c86 17648
dda8d76d 17649 if (dump & STRING_DUMP)
32ec8896 17650 {
dda8d76d 17651 if (! dump_section_as_strings (section, filedata))
015dc7e1 17652 res = false;
32ec8896 17653 }
cf13d699 17654
dda8d76d 17655 if (dump & DEBUG_DUMP)
32ec8896 17656 {
dda8d76d 17657 if (! display_debug_section (i, section, filedata))
015dc7e1 17658 res = false;
32ec8896 17659 }
7d9813f1 17660
094e34f2 17661#ifdef ENABLE_LIBCTF
7d9813f1
NA
17662 if (dump & CTF_DUMP)
17663 {
17664 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17665 res = false;
7d9813f1 17666 }
094e34f2 17667#endif
42b6953b
IB
17668 if (dump & SFRAME_DUMP)
17669 {
17670 if (! dump_section_as_sframe (section, filedata))
17671 res = false;
17672 }
5b18a4bc 17673 }
103f02d3 17674
835f2fae 17675 if (! filedata->is_separate)
0ee3043f 17676 {
835f2fae
NC
17677 /* Check to see if the user requested a
17678 dump of a section that does not exist. */
17679 for (; i < filedata->dump.num_dump_sects; i++)
17680 if (filedata->dump.dump_sects[i])
17681 {
ca0e11aa 17682 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17683 res = false;
835f2fae 17684 }
0ee3043f 17685 }
32ec8896
NC
17686
17687 return res;
5b18a4bc 17688}
103f02d3 17689
5b18a4bc 17690static void
19e6b90e 17691process_mips_fpe_exception (int mask)
5b18a4bc 17692{
19e6b90e
L
17693 if (mask)
17694 {
015dc7e1 17695 bool first = true;
32ec8896 17696
19e6b90e 17697 if (mask & OEX_FPU_INEX)
015dc7e1 17698 fputs ("INEX", stdout), first = false;
19e6b90e 17699 if (mask & OEX_FPU_UFLO)
015dc7e1 17700 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17701 if (mask & OEX_FPU_OFLO)
015dc7e1 17702 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17703 if (mask & OEX_FPU_DIV0)
015dc7e1 17704 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17705 if (mask & OEX_FPU_INVAL)
17706 printf ("%sINVAL", first ? "" : "|");
17707 }
5b18a4bc 17708 else
19e6b90e 17709 fputs ("0", stdout);
5b18a4bc 17710}
103f02d3 17711
f6f0e17b
NC
17712/* Display's the value of TAG at location P. If TAG is
17713 greater than 0 it is assumed to be an unknown tag, and
17714 a message is printed to this effect. Otherwise it is
17715 assumed that a message has already been printed.
17716
17717 If the bottom bit of TAG is set it assumed to have a
17718 string value, otherwise it is assumed to have an integer
17719 value.
17720
17721 Returns an updated P pointing to the first unread byte
17722 beyond the end of TAG's value.
17723
17724 Reads at or beyond END will not be made. */
17725
17726static unsigned char *
60abdbed 17727display_tag_value (signed int tag,
f6f0e17b
NC
17728 unsigned char * p,
17729 const unsigned char * const end)
17730{
26c527e6 17731 uint64_t val;
f6f0e17b
NC
17732
17733 if (tag > 0)
17734 printf (" Tag_unknown_%d: ", tag);
17735
17736 if (p >= end)
17737 {
4082ef84 17738 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17739 }
17740 else if (tag & 1)
17741 {
071436c6
NC
17742 /* PR 17531 file: 027-19978-0.004. */
17743 size_t maxlen = (end - p) - 1;
17744
17745 putchar ('"');
4082ef84
NC
17746 if (maxlen > 0)
17747 {
b6ac461a 17748 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17749 p += strnlen ((char *) p, maxlen) + 1;
17750 }
17751 else
17752 {
17753 printf (_("<corrupt string tag>"));
17754 p = (unsigned char *) end;
17755 }
071436c6 17756 printf ("\"\n");
f6f0e17b
NC
17757 }
17758 else
17759 {
cd30bcef 17760 READ_ULEB (val, p, end);
26c527e6 17761 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17762 }
17763
4082ef84 17764 assert (p <= end);
f6f0e17b
NC
17765 return p;
17766}
17767
53a346d8
CZ
17768/* ARC ABI attributes section. */
17769
17770static unsigned char *
17771display_arc_attribute (unsigned char * p,
17772 const unsigned char * const end)
17773{
17774 unsigned int tag;
53a346d8
CZ
17775 unsigned int val;
17776
cd30bcef 17777 READ_ULEB (tag, p, end);
53a346d8
CZ
17778
17779 switch (tag)
17780 {
17781 case Tag_ARC_PCS_config:
cd30bcef 17782 READ_ULEB (val, p, end);
53a346d8
CZ
17783 printf (" Tag_ARC_PCS_config: ");
17784 switch (val)
17785 {
17786 case 0:
17787 printf (_("Absent/Non standard\n"));
17788 break;
17789 case 1:
17790 printf (_("Bare metal/mwdt\n"));
17791 break;
17792 case 2:
17793 printf (_("Bare metal/newlib\n"));
17794 break;
17795 case 3:
17796 printf (_("Linux/uclibc\n"));
17797 break;
17798 case 4:
17799 printf (_("Linux/glibc\n"));
17800 break;
17801 default:
17802 printf (_("Unknown\n"));
17803 break;
17804 }
17805 break;
17806
17807 case Tag_ARC_CPU_base:
cd30bcef 17808 READ_ULEB (val, p, end);
53a346d8
CZ
17809 printf (" Tag_ARC_CPU_base: ");
17810 switch (val)
17811 {
17812 default:
17813 case TAG_CPU_NONE:
17814 printf (_("Absent\n"));
17815 break;
17816 case TAG_CPU_ARC6xx:
17817 printf ("ARC6xx\n");
17818 break;
17819 case TAG_CPU_ARC7xx:
17820 printf ("ARC7xx\n");
17821 break;
17822 case TAG_CPU_ARCEM:
17823 printf ("ARCEM\n");
17824 break;
17825 case TAG_CPU_ARCHS:
17826 printf ("ARCHS\n");
17827 break;
17828 }
17829 break;
17830
17831 case Tag_ARC_CPU_variation:
cd30bcef 17832 READ_ULEB (val, p, end);
53a346d8
CZ
17833 printf (" Tag_ARC_CPU_variation: ");
17834 switch (val)
17835 {
17836 default:
17837 if (val > 0 && val < 16)
53a346d8 17838 printf ("Core%d\n", val);
d8cbc93b
JL
17839 else
17840 printf ("Unknown\n");
17841 break;
17842
53a346d8
CZ
17843 case 0:
17844 printf (_("Absent\n"));
17845 break;
17846 }
17847 break;
17848
17849 case Tag_ARC_CPU_name:
17850 printf (" Tag_ARC_CPU_name: ");
17851 p = display_tag_value (-1, p, end);
17852 break;
17853
17854 case Tag_ARC_ABI_rf16:
cd30bcef 17855 READ_ULEB (val, p, end);
53a346d8
CZ
17856 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17857 break;
17858
17859 case Tag_ARC_ABI_osver:
cd30bcef 17860 READ_ULEB (val, p, end);
53a346d8
CZ
17861 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17862 break;
17863
17864 case Tag_ARC_ABI_pic:
17865 case Tag_ARC_ABI_sda:
cd30bcef 17866 READ_ULEB (val, p, end);
53a346d8
CZ
17867 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17868 : " Tag_ARC_ABI_pic: ");
17869 switch (val)
17870 {
17871 case 0:
17872 printf (_("Absent\n"));
17873 break;
17874 case 1:
17875 printf ("MWDT\n");
17876 break;
17877 case 2:
17878 printf ("GNU\n");
17879 break;
17880 default:
17881 printf (_("Unknown\n"));
17882 break;
17883 }
17884 break;
17885
17886 case Tag_ARC_ABI_tls:
cd30bcef 17887 READ_ULEB (val, p, end);
53a346d8
CZ
17888 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17889 break;
17890
17891 case Tag_ARC_ABI_enumsize:
cd30bcef 17892 READ_ULEB (val, p, end);
53a346d8
CZ
17893 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17894 _("smallest"));
17895 break;
17896
17897 case Tag_ARC_ABI_exceptions:
cd30bcef 17898 READ_ULEB (val, p, end);
53a346d8
CZ
17899 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17900 : _("default"));
17901 break;
17902
17903 case Tag_ARC_ABI_double_size:
cd30bcef 17904 READ_ULEB (val, p, end);
53a346d8
CZ
17905 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17906 break;
17907
17908 case Tag_ARC_ISA_config:
17909 printf (" Tag_ARC_ISA_config: ");
17910 p = display_tag_value (-1, p, end);
17911 break;
17912
17913 case Tag_ARC_ISA_apex:
17914 printf (" Tag_ARC_ISA_apex: ");
17915 p = display_tag_value (-1, p, end);
17916 break;
17917
17918 case Tag_ARC_ISA_mpy_option:
cd30bcef 17919 READ_ULEB (val, p, end);
53a346d8
CZ
17920 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17921 break;
17922
db1e1b45 17923 case Tag_ARC_ATR_version:
cd30bcef 17924 READ_ULEB (val, p, end);
db1e1b45 17925 printf (" Tag_ARC_ATR_version: %d\n", val);
17926 break;
17927
53a346d8
CZ
17928 default:
17929 return display_tag_value (tag & 1, p, end);
17930 }
17931
17932 return p;
17933}
17934
11c1ff18
PB
17935/* ARM EABI attributes section. */
17936typedef struct
17937{
70e99720 17938 unsigned int tag;
2cf0635d 17939 const char * name;
11c1ff18 17940 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17941 unsigned int type;
288f0ba2 17942 const char *const *table;
11c1ff18
PB
17943} arm_attr_public_tag;
17944
288f0ba2 17945static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17946 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17947 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17948 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17949 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17950static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17951static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17952 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17953static const char *const arm_attr_tag_FP_arch[] =
bca38921 17954 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17955 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17956static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17957static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17958 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17959 "NEON for ARMv8.1"};
288f0ba2 17960static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17961 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17962 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17963static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17964 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17965static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17966 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17967static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17968 {"Absolute", "PC-relative", "None"};
288f0ba2 17969static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17970 {"None", "direct", "GOT-indirect"};
288f0ba2 17971static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17972 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17973static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17974static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17975 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17976static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17977static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17978static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17979 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17980static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17981 {"Unused", "small", "int", "forced to int"};
288f0ba2 17982static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17983 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17984static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17985 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17986static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17987 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17988static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17989 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17990 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17991static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17992 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17993 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17994static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17995static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17996 {"Not Allowed", "Allowed"};
288f0ba2 17997static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17998 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17999static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 18000 {"Follow architecture", "Allowed"};
288f0ba2 18001static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 18002 {"Not Allowed", "Allowed"};
288f0ba2 18003static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 18004 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 18005 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
18006static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
18007static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 18008 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 18009 "TrustZone and Virtualization Extensions"};
288f0ba2 18010static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 18011 {"Not Allowed", "Allowed"};
11c1ff18 18012
288f0ba2 18013static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
18014 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
18015
99db83d0
AC
18016static const char * arm_attr_tag_PAC_extension[] =
18017 {"No PAC/AUT instructions",
18018 "PAC/AUT instructions permitted in the NOP space",
18019 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
18020
4b535030
AC
18021static const char * arm_attr_tag_BTI_extension[] =
18022 {"BTI instructions not permitted",
18023 "BTI instructions permitted in the NOP space",
18024 "BTI instructions permitted in the NOP and in the non-NOP space"};
18025
b81ee92f
AC
18026static const char * arm_attr_tag_BTI_use[] =
18027 {"Compiled without branch target enforcement",
18028 "Compiled with branch target enforcement"};
18029
c9fed665
AC
18030static const char * arm_attr_tag_PACRET_use[] =
18031 {"Compiled without return address signing and authentication",
18032 "Compiled with return address signing and authentication"};
18033
11c1ff18
PB
18034#define LOOKUP(id, name) \
18035 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 18036static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
18037{
18038 {4, "CPU_raw_name", 1, NULL},
18039 {5, "CPU_name", 1, NULL},
18040 LOOKUP(6, CPU_arch),
18041 {7, "CPU_arch_profile", 0, NULL},
18042 LOOKUP(8, ARM_ISA_use),
18043 LOOKUP(9, THUMB_ISA_use),
75375b3e 18044 LOOKUP(10, FP_arch),
11c1ff18 18045 LOOKUP(11, WMMX_arch),
f5f53991
AS
18046 LOOKUP(12, Advanced_SIMD_arch),
18047 LOOKUP(13, PCS_config),
11c1ff18
PB
18048 LOOKUP(14, ABI_PCS_R9_use),
18049 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 18050 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
18051 LOOKUP(17, ABI_PCS_GOT_use),
18052 LOOKUP(18, ABI_PCS_wchar_t),
18053 LOOKUP(19, ABI_FP_rounding),
18054 LOOKUP(20, ABI_FP_denormal),
18055 LOOKUP(21, ABI_FP_exceptions),
18056 LOOKUP(22, ABI_FP_user_exceptions),
18057 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
18058 {24, "ABI_align_needed", 0, NULL},
18059 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
18060 LOOKUP(26, ABI_enum_size),
18061 LOOKUP(27, ABI_HardFP_use),
18062 LOOKUP(28, ABI_VFP_args),
18063 LOOKUP(29, ABI_WMMX_args),
18064 LOOKUP(30, ABI_optimization_goals),
18065 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 18066 {32, "compatibility", 0, NULL},
f5f53991 18067 LOOKUP(34, CPU_unaligned_access),
75375b3e 18068 LOOKUP(36, FP_HP_extension),
8e79c3df 18069 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
18070 LOOKUP(42, MPextension_use),
18071 LOOKUP(44, DIV_use),
15afaa63 18072 LOOKUP(46, DSP_extension),
a7ad558c 18073 LOOKUP(48, MVE_arch),
99db83d0 18074 LOOKUP(50, PAC_extension),
4b535030 18075 LOOKUP(52, BTI_extension),
b81ee92f 18076 LOOKUP(74, BTI_use),
c9fed665 18077 LOOKUP(76, PACRET_use),
f5f53991
AS
18078 {64, "nodefaults", 0, NULL},
18079 {65, "also_compatible_with", 0, NULL},
18080 LOOKUP(66, T2EE_use),
18081 {67, "conformance", 1, NULL},
18082 LOOKUP(68, Virtualization_use),
cd21e546 18083 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
18084};
18085#undef LOOKUP
18086
11c1ff18 18087static unsigned char *
f6f0e17b
NC
18088display_arm_attribute (unsigned char * p,
18089 const unsigned char * const end)
11c1ff18 18090{
70e99720 18091 unsigned int tag;
70e99720 18092 unsigned int val;
2cf0635d 18093 arm_attr_public_tag * attr;
11c1ff18 18094 unsigned i;
70e99720 18095 unsigned int type;
11c1ff18 18096
cd30bcef 18097 READ_ULEB (tag, p, end);
11c1ff18 18098 attr = NULL;
2cf0635d 18099 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
18100 {
18101 if (arm_attr_public_tags[i].tag == tag)
18102 {
18103 attr = &arm_attr_public_tags[i];
18104 break;
18105 }
18106 }
18107
18108 if (attr)
18109 {
18110 printf (" Tag_%s: ", attr->name);
18111 switch (attr->type)
18112 {
18113 case 0:
18114 switch (tag)
18115 {
18116 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 18117 READ_ULEB (val, p, end);
11c1ff18
PB
18118 switch (val)
18119 {
2b692964
NC
18120 case 0: printf (_("None\n")); break;
18121 case 'A': printf (_("Application\n")); break;
18122 case 'R': printf (_("Realtime\n")); break;
18123 case 'M': printf (_("Microcontroller\n")); break;
18124 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
18125 default: printf ("??? (%d)\n", val); break;
18126 }
18127 break;
18128
75375b3e 18129 case 24: /* Tag_align_needed. */
cd30bcef 18130 READ_ULEB (val, p, end);
75375b3e
MGD
18131 switch (val)
18132 {
2b692964
NC
18133 case 0: printf (_("None\n")); break;
18134 case 1: printf (_("8-byte\n")); break;
18135 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
18136 case 3: printf ("??? 3\n"); break;
18137 default:
18138 if (val <= 12)
dd24e3da 18139 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
18140 1 << val);
18141 else
18142 printf ("??? (%d)\n", val);
18143 break;
18144 }
18145 break;
18146
18147 case 25: /* Tag_align_preserved. */
cd30bcef 18148 READ_ULEB (val, p, end);
75375b3e
MGD
18149 switch (val)
18150 {
2b692964
NC
18151 case 0: printf (_("None\n")); break;
18152 case 1: printf (_("8-byte, except leaf SP\n")); break;
18153 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
18154 case 3: printf ("??? 3\n"); break;
18155 default:
18156 if (val <= 12)
dd24e3da 18157 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
18158 1 << val);
18159 else
18160 printf ("??? (%d)\n", val);
18161 break;
18162 }
18163 break;
18164
11c1ff18 18165 case 32: /* Tag_compatibility. */
071436c6 18166 {
cd30bcef 18167 READ_ULEB (val, p, end);
071436c6 18168 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18169 if (p < end - 1)
18170 {
18171 size_t maxlen = (end - p) - 1;
18172
b6ac461a 18173 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18174 p += strnlen ((char *) p, maxlen) + 1;
18175 }
18176 else
18177 {
18178 printf (_("<corrupt>"));
18179 p = (unsigned char *) end;
18180 }
071436c6 18181 putchar ('\n');
071436c6 18182 }
11c1ff18
PB
18183 break;
18184
f5f53991 18185 case 64: /* Tag_nodefaults. */
541a3cbd
NC
18186 /* PR 17531: file: 001-505008-0.01. */
18187 if (p < end)
18188 p++;
2b692964 18189 printf (_("True\n"));
f5f53991
AS
18190 break;
18191
18192 case 65: /* Tag_also_compatible_with. */
cd30bcef 18193 READ_ULEB (val, p, end);
f5f53991
AS
18194 if (val == 6 /* Tag_CPU_arch. */)
18195 {
cd30bcef 18196 READ_ULEB (val, p, end);
071436c6 18197 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
18198 printf ("??? (%d)\n", val);
18199 else
18200 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
18201 }
18202 else
18203 printf ("???\n");
071436c6
NC
18204 while (p < end && *(p++) != '\0' /* NUL terminator. */)
18205 ;
f5f53991
AS
18206 break;
18207
11c1ff18 18208 default:
bee0ee85
NC
18209 printf (_("<unknown: %d>\n"), tag);
18210 break;
11c1ff18
PB
18211 }
18212 return p;
18213
18214 case 1:
f6f0e17b 18215 return display_tag_value (-1, p, end);
11c1ff18 18216 case 2:
f6f0e17b 18217 return display_tag_value (0, p, end);
11c1ff18
PB
18218
18219 default:
18220 assert (attr->type & 0x80);
cd30bcef 18221 READ_ULEB (val, p, end);
11c1ff18
PB
18222 type = attr->type & 0x7f;
18223 if (val >= type)
18224 printf ("??? (%d)\n", val);
18225 else
18226 printf ("%s\n", attr->table[val]);
18227 return p;
18228 }
18229 }
11c1ff18 18230
f6f0e17b 18231 return display_tag_value (tag, p, end);
11c1ff18
PB
18232}
18233
104d59d1 18234static unsigned char *
60bca95a 18235display_gnu_attribute (unsigned char * p,
8e8d0b63
NC
18236 unsigned char * (* display_proc_gnu_attribute)
18237 (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 18238 const unsigned char * const end)
104d59d1 18239{
cd30bcef 18240 unsigned int tag;
60abdbed 18241 unsigned int val;
104d59d1 18242
cd30bcef 18243 READ_ULEB (tag, p, end);
104d59d1
JM
18244
18245 /* Tag_compatibility is the only generic GNU attribute defined at
18246 present. */
18247 if (tag == 32)
18248 {
cd30bcef 18249 READ_ULEB (val, p, end);
071436c6
NC
18250
18251 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
18252 if (p == end)
18253 {
071436c6 18254 printf (_("<corrupt>\n"));
f6f0e17b
NC
18255 warn (_("corrupt vendor attribute\n"));
18256 }
18257 else
18258 {
4082ef84
NC
18259 if (p < end - 1)
18260 {
18261 size_t maxlen = (end - p) - 1;
071436c6 18262
b6ac461a 18263 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18264 p += strnlen ((char *) p, maxlen) + 1;
18265 }
18266 else
18267 {
18268 printf (_("<corrupt>"));
18269 p = (unsigned char *) end;
18270 }
071436c6 18271 putchar ('\n');
f6f0e17b 18272 }
104d59d1
JM
18273 return p;
18274 }
18275
18276 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 18277 return display_proc_gnu_attribute (p, tag, end);
104d59d1 18278
f6f0e17b 18279 return display_tag_value (tag, p, end);
104d59d1
JM
18280}
18281
85f7484a
PB
18282static unsigned char *
18283display_m68k_gnu_attribute (unsigned char * p,
18284 unsigned int tag,
18285 const unsigned char * const end)
18286{
18287 unsigned int val;
18288
18289 if (tag == Tag_GNU_M68K_ABI_FP)
18290 {
18291 printf (" Tag_GNU_M68K_ABI_FP: ");
18292 if (p == end)
18293 {
18294 printf (_("<corrupt>\n"));
18295 return p;
18296 }
18297 READ_ULEB (val, p, end);
18298
18299 if (val > 3)
18300 printf ("(%#x), ", val);
18301
18302 switch (val & 3)
18303 {
18304 case 0:
18305 printf (_("unspecified hard/soft float\n"));
18306 break;
18307 case 1:
18308 printf (_("hard float\n"));
18309 break;
18310 case 2:
18311 printf (_("soft float\n"));
18312 break;
18313 }
18314 return p;
18315 }
18316
18317 return display_tag_value (tag & 1, p, end);
18318}
18319
34c8bcba 18320static unsigned char *
f6f0e17b 18321display_power_gnu_attribute (unsigned char * p,
60abdbed 18322 unsigned int tag,
f6f0e17b 18323 const unsigned char * const end)
34c8bcba 18324{
005d79fd 18325 unsigned int val;
34c8bcba
JM
18326
18327 if (tag == Tag_GNU_Power_ABI_FP)
18328 {
34c8bcba 18329 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 18330 if (p == end)
005d79fd
AM
18331 {
18332 printf (_("<corrupt>\n"));
18333 return p;
18334 }
cd30bcef 18335 READ_ULEB (val, p, end);
60bca95a 18336
005d79fd
AM
18337 if (val > 15)
18338 printf ("(%#x), ", val);
18339
18340 switch (val & 3)
34c8bcba
JM
18341 {
18342 case 0:
005d79fd 18343 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
18344 break;
18345 case 1:
005d79fd 18346 printf (_("hard float, "));
34c8bcba
JM
18347 break;
18348 case 2:
005d79fd 18349 printf (_("soft float, "));
34c8bcba 18350 break;
3c7b9897 18351 case 3:
005d79fd 18352 printf (_("single-precision hard float, "));
3c7b9897 18353 break;
005d79fd
AM
18354 }
18355
18356 switch (val & 0xC)
18357 {
18358 case 0:
18359 printf (_("unspecified long double\n"));
18360 break;
18361 case 4:
18362 printf (_("128-bit IBM long double\n"));
18363 break;
18364 case 8:
18365 printf (_("64-bit long double\n"));
18366 break;
18367 case 12:
18368 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
18369 break;
18370 }
18371 return p;
005d79fd 18372 }
34c8bcba 18373
c6e65352
DJ
18374 if (tag == Tag_GNU_Power_ABI_Vector)
18375 {
c6e65352 18376 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 18377 if (p == end)
005d79fd
AM
18378 {
18379 printf (_("<corrupt>\n"));
18380 return p;
18381 }
cd30bcef 18382 READ_ULEB (val, p, end);
005d79fd
AM
18383
18384 if (val > 3)
18385 printf ("(%#x), ", val);
18386
18387 switch (val & 3)
c6e65352
DJ
18388 {
18389 case 0:
005d79fd 18390 printf (_("unspecified\n"));
c6e65352
DJ
18391 break;
18392 case 1:
005d79fd 18393 printf (_("generic\n"));
c6e65352
DJ
18394 break;
18395 case 2:
18396 printf ("AltiVec\n");
18397 break;
18398 case 3:
18399 printf ("SPE\n");
18400 break;
c6e65352
DJ
18401 }
18402 return p;
005d79fd 18403 }
c6e65352 18404
f82e0623
NF
18405 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18406 {
005d79fd 18407 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 18408 if (p == end)
f6f0e17b 18409 {
005d79fd 18410 printf (_("<corrupt>\n"));
f6f0e17b
NC
18411 return p;
18412 }
cd30bcef 18413 READ_ULEB (val, p, end);
0b4362b0 18414
005d79fd
AM
18415 if (val > 2)
18416 printf ("(%#x), ", val);
18417
18418 switch (val & 3)
18419 {
18420 case 0:
18421 printf (_("unspecified\n"));
18422 break;
18423 case 1:
18424 printf ("r3/r4\n");
18425 break;
18426 case 2:
18427 printf (_("memory\n"));
18428 break;
18429 case 3:
18430 printf ("???\n");
18431 break;
18432 }
f82e0623
NF
18433 return p;
18434 }
18435
f6f0e17b 18436 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
18437}
18438
643f7afb
AK
18439static unsigned char *
18440display_s390_gnu_attribute (unsigned char * p,
60abdbed 18441 unsigned int tag,
643f7afb
AK
18442 const unsigned char * const end)
18443{
cd30bcef 18444 unsigned int val;
643f7afb
AK
18445
18446 if (tag == Tag_GNU_S390_ABI_Vector)
18447 {
643f7afb 18448 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 18449 READ_ULEB (val, p, end);
643f7afb
AK
18450
18451 switch (val)
18452 {
18453 case 0:
18454 printf (_("any\n"));
18455 break;
18456 case 1:
18457 printf (_("software\n"));
18458 break;
18459 case 2:
18460 printf (_("hardware\n"));
18461 break;
18462 default:
18463 printf ("??? (%d)\n", val);
18464 break;
18465 }
18466 return p;
18467 }
18468
18469 return display_tag_value (tag & 1, p, end);
18470}
18471
9e8c70f9 18472static void
60abdbed 18473display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
18474{
18475 if (mask)
18476 {
015dc7e1 18477 bool first = true;
071436c6 18478
9e8c70f9 18479 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 18480 fputs ("mul32", stdout), first = false;
9e8c70f9 18481 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 18482 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 18483 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 18484 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 18485 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 18486 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 18487 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 18488 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 18489 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 18490 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 18491 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 18492 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 18493 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 18494 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 18495 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 18496 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 18497 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 18498 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 18499 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 18500 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 18501 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 18502 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 18503 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 18504 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 18505 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 18506 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 18507 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 18508 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 18509 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 18510 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
18511 }
18512 else
071436c6
NC
18513 fputc ('0', stdout);
18514 fputc ('\n', stdout);
9e8c70f9
DM
18515}
18516
3d68f91c 18517static void
60abdbed 18518display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
18519{
18520 if (mask)
18521 {
015dc7e1 18522 bool first = true;
071436c6 18523
3d68f91c 18524 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 18525 fputs ("fjathplus", stdout), first = false;
3d68f91c 18526 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 18527 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 18528 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 18529 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 18530 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 18531 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 18532 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 18533 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 18534 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 18535 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 18536 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 18537 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 18538 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 18539 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 18540 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 18541 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 18542 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 18543 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 18544 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 18545 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
18546 }
18547 else
071436c6
NC
18548 fputc ('0', stdout);
18549 fputc ('\n', stdout);
3d68f91c
JM
18550}
18551
9e8c70f9 18552static unsigned char *
f6f0e17b 18553display_sparc_gnu_attribute (unsigned char * p,
60abdbed 18554 unsigned int tag,
f6f0e17b 18555 const unsigned char * const end)
9e8c70f9 18556{
cd30bcef 18557 unsigned int val;
3d68f91c 18558
9e8c70f9
DM
18559 if (tag == Tag_GNU_Sparc_HWCAPS)
18560 {
cd30bcef 18561 READ_ULEB (val, p, end);
9e8c70f9 18562 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18563 display_sparc_hwcaps (val);
18564 return p;
3d68f91c
JM
18565 }
18566 if (tag == Tag_GNU_Sparc_HWCAPS2)
18567 {
cd30bcef 18568 READ_ULEB (val, p, end);
3d68f91c
JM
18569 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18570 display_sparc_hwcaps2 (val);
18571 return p;
18572 }
9e8c70f9 18573
f6f0e17b 18574 return display_tag_value (tag, p, end);
9e8c70f9
DM
18575}
18576
351cdf24 18577static void
32ec8896 18578print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18579{
18580 switch (val)
18581 {
18582 case Val_GNU_MIPS_ABI_FP_ANY:
18583 printf (_("Hard or soft float\n"));
18584 break;
18585 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18586 printf (_("Hard float (double precision)\n"));
18587 break;
18588 case Val_GNU_MIPS_ABI_FP_SINGLE:
18589 printf (_("Hard float (single precision)\n"));
18590 break;
18591 case Val_GNU_MIPS_ABI_FP_SOFT:
18592 printf (_("Soft float\n"));
18593 break;
18594 case Val_GNU_MIPS_ABI_FP_OLD_64:
18595 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18596 break;
18597 case Val_GNU_MIPS_ABI_FP_XX:
18598 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18599 break;
18600 case Val_GNU_MIPS_ABI_FP_64:
18601 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18602 break;
18603 case Val_GNU_MIPS_ABI_FP_64A:
18604 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18605 break;
3350cc01
CM
18606 case Val_GNU_MIPS_ABI_FP_NAN2008:
18607 printf (_("NaN 2008 compatibility\n"));
18608 break;
351cdf24
MF
18609 default:
18610 printf ("??? (%d)\n", val);
18611 break;
18612 }
18613}
18614
2cf19d5c 18615static unsigned char *
f6f0e17b 18616display_mips_gnu_attribute (unsigned char * p,
60abdbed 18617 unsigned int tag,
f6f0e17b 18618 const unsigned char * const end)
2cf19d5c 18619{
2cf19d5c
JM
18620 if (tag == Tag_GNU_MIPS_ABI_FP)
18621 {
32ec8896 18622 unsigned int val;
f6f0e17b 18623
2cf19d5c 18624 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18625 READ_ULEB (val, p, end);
351cdf24 18626 print_mips_fp_abi_value (val);
2cf19d5c
JM
18627 return p;
18628 }
18629
a9f58168
CF
18630 if (tag == Tag_GNU_MIPS_ABI_MSA)
18631 {
32ec8896 18632 unsigned int val;
a9f58168 18633
a9f58168 18634 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18635 READ_ULEB (val, p, end);
a9f58168
CF
18636
18637 switch (val)
18638 {
18639 case Val_GNU_MIPS_ABI_MSA_ANY:
18640 printf (_("Any MSA or not\n"));
18641 break;
18642 case Val_GNU_MIPS_ABI_MSA_128:
18643 printf (_("128-bit MSA\n"));
18644 break;
18645 default:
18646 printf ("??? (%d)\n", val);
18647 break;
18648 }
18649 return p;
18650 }
18651
f6f0e17b 18652 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18653}
18654
59e6276b 18655static unsigned char *
f6f0e17b
NC
18656display_tic6x_attribute (unsigned char * p,
18657 const unsigned char * const end)
59e6276b 18658{
60abdbed 18659 unsigned int tag;
cd30bcef 18660 unsigned int val;
59e6276b 18661
cd30bcef 18662 READ_ULEB (tag, p, end);
59e6276b
JM
18663
18664 switch (tag)
18665 {
75fa6dc1 18666 case Tag_ISA:
75fa6dc1 18667 printf (" Tag_ISA: ");
cd30bcef 18668 READ_ULEB (val, p, end);
59e6276b
JM
18669
18670 switch (val)
18671 {
75fa6dc1 18672 case C6XABI_Tag_ISA_none:
59e6276b
JM
18673 printf (_("None\n"));
18674 break;
75fa6dc1 18675 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18676 printf ("C62x\n");
18677 break;
75fa6dc1 18678 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18679 printf ("C67x\n");
18680 break;
75fa6dc1 18681 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18682 printf ("C67x+\n");
18683 break;
75fa6dc1 18684 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18685 printf ("C64x\n");
18686 break;
75fa6dc1 18687 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18688 printf ("C64x+\n");
18689 break;
75fa6dc1 18690 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18691 printf ("C674x\n");
18692 break;
18693 default:
18694 printf ("??? (%d)\n", val);
18695 break;
18696 }
18697 return p;
18698
87779176 18699 case Tag_ABI_wchar_t:
87779176 18700 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18701 READ_ULEB (val, p, end);
87779176
JM
18702 switch (val)
18703 {
18704 case 0:
18705 printf (_("Not used\n"));
18706 break;
18707 case 1:
18708 printf (_("2 bytes\n"));
18709 break;
18710 case 2:
18711 printf (_("4 bytes\n"));
18712 break;
18713 default:
18714 printf ("??? (%d)\n", val);
18715 break;
18716 }
18717 return p;
18718
18719 case Tag_ABI_stack_align_needed:
87779176 18720 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18721 READ_ULEB (val, p, end);
87779176
JM
18722 switch (val)
18723 {
18724 case 0:
18725 printf (_("8-byte\n"));
18726 break;
18727 case 1:
18728 printf (_("16-byte\n"));
18729 break;
18730 default:
18731 printf ("??? (%d)\n", val);
18732 break;
18733 }
18734 return p;
18735
18736 case Tag_ABI_stack_align_preserved:
cd30bcef 18737 READ_ULEB (val, p, end);
87779176
JM
18738 printf (" Tag_ABI_stack_align_preserved: ");
18739 switch (val)
18740 {
18741 case 0:
18742 printf (_("8-byte\n"));
18743 break;
18744 case 1:
18745 printf (_("16-byte\n"));
18746 break;
18747 default:
18748 printf ("??? (%d)\n", val);
18749 break;
18750 }
18751 return p;
18752
b5593623 18753 case Tag_ABI_DSBT:
cd30bcef 18754 READ_ULEB (val, p, end);
b5593623
JM
18755 printf (" Tag_ABI_DSBT: ");
18756 switch (val)
18757 {
18758 case 0:
18759 printf (_("DSBT addressing not used\n"));
18760 break;
18761 case 1:
18762 printf (_("DSBT addressing used\n"));
18763 break;
18764 default:
18765 printf ("??? (%d)\n", val);
18766 break;
18767 }
18768 return p;
18769
87779176 18770 case Tag_ABI_PID:
cd30bcef 18771 READ_ULEB (val, p, end);
87779176
JM
18772 printf (" Tag_ABI_PID: ");
18773 switch (val)
18774 {
18775 case 0:
18776 printf (_("Data addressing position-dependent\n"));
18777 break;
18778 case 1:
18779 printf (_("Data addressing position-independent, GOT near DP\n"));
18780 break;
18781 case 2:
18782 printf (_("Data addressing position-independent, GOT far from DP\n"));
18783 break;
18784 default:
18785 printf ("??? (%d)\n", val);
18786 break;
18787 }
18788 return p;
18789
18790 case Tag_ABI_PIC:
cd30bcef 18791 READ_ULEB (val, p, end);
87779176
JM
18792 printf (" Tag_ABI_PIC: ");
18793 switch (val)
18794 {
18795 case 0:
18796 printf (_("Code addressing position-dependent\n"));
18797 break;
18798 case 1:
18799 printf (_("Code addressing position-independent\n"));
18800 break;
18801 default:
18802 printf ("??? (%d)\n", val);
18803 break;
18804 }
18805 return p;
18806
18807 case Tag_ABI_array_object_alignment:
cd30bcef 18808 READ_ULEB (val, p, end);
87779176
JM
18809 printf (" Tag_ABI_array_object_alignment: ");
18810 switch (val)
18811 {
18812 case 0:
18813 printf (_("8-byte\n"));
18814 break;
18815 case 1:
18816 printf (_("4-byte\n"));
18817 break;
18818 case 2:
18819 printf (_("16-byte\n"));
18820 break;
18821 default:
18822 printf ("??? (%d)\n", val);
18823 break;
18824 }
18825 return p;
18826
18827 case Tag_ABI_array_object_align_expected:
cd30bcef 18828 READ_ULEB (val, p, end);
87779176
JM
18829 printf (" Tag_ABI_array_object_align_expected: ");
18830 switch (val)
18831 {
18832 case 0:
18833 printf (_("8-byte\n"));
18834 break;
18835 case 1:
18836 printf (_("4-byte\n"));
18837 break;
18838 case 2:
18839 printf (_("16-byte\n"));
18840 break;
18841 default:
18842 printf ("??? (%d)\n", val);
18843 break;
18844 }
18845 return p;
18846
3cbd1c06 18847 case Tag_ABI_compatibility:
071436c6 18848 {
cd30bcef 18849 READ_ULEB (val, p, end);
071436c6 18850 printf (" Tag_ABI_compatibility: ");
071436c6 18851 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18852 if (p < end - 1)
18853 {
18854 size_t maxlen = (end - p) - 1;
18855
b6ac461a 18856 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18857 p += strnlen ((char *) p, maxlen) + 1;
18858 }
18859 else
18860 {
18861 printf (_("<corrupt>"));
18862 p = (unsigned char *) end;
18863 }
071436c6 18864 putchar ('\n');
071436c6
NC
18865 return p;
18866 }
87779176
JM
18867
18868 case Tag_ABI_conformance:
071436c6 18869 {
4082ef84
NC
18870 printf (" Tag_ABI_conformance: \"");
18871 if (p < end - 1)
18872 {
18873 size_t maxlen = (end - p) - 1;
071436c6 18874
b6ac461a 18875 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18876 p += strnlen ((char *) p, maxlen) + 1;
18877 }
18878 else
18879 {
18880 printf (_("<corrupt>"));
18881 p = (unsigned char *) end;
18882 }
071436c6 18883 printf ("\"\n");
071436c6
NC
18884 return p;
18885 }
59e6276b
JM
18886 }
18887
f6f0e17b
NC
18888 return display_tag_value (tag, p, end);
18889}
59e6276b 18890
f6f0e17b 18891static void
60abdbed 18892display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18893{
26c527e6 18894 uint64_t addr = 0;
f6f0e17b
NC
18895 size_t bytes = end - p;
18896
feceaa59 18897 assert (end >= p);
f6f0e17b 18898 while (bytes)
87779176 18899 {
f6f0e17b
NC
18900 int j;
18901 int k;
18902 int lbytes = (bytes > 16 ? 16 : bytes);
18903
26c527e6 18904 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18905
18906 for (j = 0; j < 16; j++)
18907 {
18908 if (j < lbytes)
18909 printf ("%2.2x", p[j]);
18910 else
18911 printf (" ");
18912
18913 if ((j & 3) == 3)
18914 printf (" ");
18915 }
18916
18917 for (j = 0; j < lbytes; j++)
18918 {
18919 k = p[j];
18920 if (k >= ' ' && k < 0x7f)
18921 printf ("%c", k);
18922 else
18923 printf (".");
18924 }
18925
18926 putchar ('\n');
18927
18928 p += lbytes;
18929 bytes -= lbytes;
18930 addr += lbytes;
87779176 18931 }
59e6276b 18932
f6f0e17b 18933 putchar ('\n');
59e6276b
JM
18934}
18935
13761a11 18936static unsigned char *
b0191216 18937display_msp430_attribute (unsigned char * p,
26c527e6 18938 const unsigned char * const end)
13761a11 18939{
26c527e6
AM
18940 uint64_t val;
18941 uint64_t tag;
13761a11 18942
cd30bcef 18943 READ_ULEB (tag, p, end);
0b4362b0 18944
13761a11
NC
18945 switch (tag)
18946 {
18947 case OFBA_MSPABI_Tag_ISA:
13761a11 18948 printf (" Tag_ISA: ");
cd30bcef 18949 READ_ULEB (val, p, end);
13761a11
NC
18950 switch (val)
18951 {
18952 case 0: printf (_("None\n")); break;
18953 case 1: printf (_("MSP430\n")); break;
18954 case 2: printf (_("MSP430X\n")); break;
26c527e6 18955 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18956 }
18957 break;
18958
18959 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18960 printf (" Tag_Code_Model: ");
cd30bcef 18961 READ_ULEB (val, p, end);
13761a11
NC
18962 switch (val)
18963 {
18964 case 0: printf (_("None\n")); break;
18965 case 1: printf (_("Small\n")); break;
18966 case 2: printf (_("Large\n")); break;
26c527e6 18967 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18968 }
18969 break;
18970
18971 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18972 printf (" Tag_Data_Model: ");
cd30bcef 18973 READ_ULEB (val, p, end);
13761a11
NC
18974 switch (val)
18975 {
18976 case 0: printf (_("None\n")); break;
18977 case 1: printf (_("Small\n")); break;
18978 case 2: printf (_("Large\n")); break;
18979 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18980 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18981 }
18982 break;
18983
18984 default:
26c527e6 18985 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18986
18987 if (tag & 1)
18988 {
071436c6 18989 putchar ('"');
4082ef84
NC
18990 if (p < end - 1)
18991 {
18992 size_t maxlen = (end - p) - 1;
18993
b6ac461a 18994 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18995 p += strnlen ((char *) p, maxlen) + 1;
18996 }
18997 else
18998 {
18999 printf (_("<corrupt>"));
19000 p = (unsigned char *) end;
19001 }
071436c6 19002 printf ("\"\n");
13761a11
NC
19003 }
19004 else
19005 {
cd30bcef 19006 READ_ULEB (val, p, end);
26c527e6 19007 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
19008 }
19009 break;
19010 }
19011
4082ef84 19012 assert (p <= end);
13761a11
NC
19013 return p;
19014}
19015
c0ea7c52
JL
19016static unsigned char *
19017display_msp430_gnu_attribute (unsigned char * p,
19018 unsigned int tag,
19019 const unsigned char * const end)
19020{
19021 if (tag == Tag_GNU_MSP430_Data_Region)
19022 {
26c527e6 19023 uint64_t val;
c0ea7c52 19024
c0ea7c52 19025 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 19026 READ_ULEB (val, p, end);
c0ea7c52
JL
19027
19028 switch (val)
19029 {
19030 case Val_GNU_MSP430_Data_Region_Any:
19031 printf (_("Any Region\n"));
19032 break;
19033 case Val_GNU_MSP430_Data_Region_Lower:
19034 printf (_("Lower Region Only\n"));
19035 break;
19036 default:
26c527e6 19037 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
19038 }
19039 return p;
19040 }
19041 return display_tag_value (tag & 1, p, end);
19042}
19043
2dc8dd17
JW
19044struct riscv_attr_tag_t {
19045 const char *name;
cd30bcef 19046 unsigned int tag;
2dc8dd17
JW
19047};
19048
19049static struct riscv_attr_tag_t riscv_attr_tag[] =
19050{
19051#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
19052 T(arch),
19053 T(priv_spec),
19054 T(priv_spec_minor),
19055 T(priv_spec_revision),
19056 T(unaligned_access),
19057 T(stack_align),
19058#undef T
19059};
19060
19061static unsigned char *
19062display_riscv_attribute (unsigned char *p,
19063 const unsigned char * const end)
19064{
26c527e6
AM
19065 uint64_t val;
19066 uint64_t tag;
2dc8dd17
JW
19067 struct riscv_attr_tag_t *attr = NULL;
19068 unsigned i;
19069
cd30bcef 19070 READ_ULEB (tag, p, end);
2dc8dd17
JW
19071
19072 /* Find the name of attribute. */
19073 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
19074 {
19075 if (riscv_attr_tag[i].tag == tag)
19076 {
19077 attr = &riscv_attr_tag[i];
19078 break;
19079 }
19080 }
19081
19082 if (attr)
19083 printf (" %s: ", attr->name);
19084 else
19085 return display_tag_value (tag, p, end);
19086
19087 switch (tag)
19088 {
19089 case Tag_RISCV_priv_spec:
19090 case Tag_RISCV_priv_spec_minor:
19091 case Tag_RISCV_priv_spec_revision:
cd30bcef 19092 READ_ULEB (val, p, end);
26c527e6 19093 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
19094 break;
19095 case Tag_RISCV_unaligned_access:
cd30bcef 19096 READ_ULEB (val, p, end);
2dc8dd17
JW
19097 switch (val)
19098 {
19099 case 0:
19100 printf (_("No unaligned access\n"));
19101 break;
19102 case 1:
19103 printf (_("Unaligned access\n"));
19104 break;
19105 }
19106 break;
19107 case Tag_RISCV_stack_align:
cd30bcef 19108 READ_ULEB (val, p, end);
26c527e6 19109 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
19110 break;
19111 case Tag_RISCV_arch:
19112 p = display_tag_value (-1, p, end);
19113 break;
19114 default:
19115 return display_tag_value (tag, p, end);
19116 }
19117
19118 return p;
19119}
19120
0861f561
CQ
19121static unsigned char *
19122display_csky_attribute (unsigned char * p,
19123 const unsigned char * const end)
19124{
26c527e6
AM
19125 uint64_t tag;
19126 uint64_t val;
0861f561
CQ
19127 READ_ULEB (tag, p, end);
19128
19129 if (tag >= Tag_CSKY_MAX)
19130 {
19131 return display_tag_value (-1, p, end);
19132 }
19133
19134 switch (tag)
19135 {
19136 case Tag_CSKY_ARCH_NAME:
19137 printf (" Tag_CSKY_ARCH_NAME:\t\t");
19138 return display_tag_value (-1, p, end);
19139 case Tag_CSKY_CPU_NAME:
19140 printf (" Tag_CSKY_CPU_NAME:\t\t");
19141 return display_tag_value (-1, p, end);
19142
19143 case Tag_CSKY_ISA_FLAGS:
19144 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
19145 return display_tag_value (0, p, end);
19146 case Tag_CSKY_ISA_EXT_FLAGS:
19147 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
19148 return display_tag_value (0, p, end);
19149
19150 case Tag_CSKY_DSP_VERSION:
19151 printf (" Tag_CSKY_DSP_VERSION:\t\t");
19152 READ_ULEB (val, p, end);
19153 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
19154 printf ("DSP Extension\n");
19155 else if (val == VAL_CSKY_DSP_VERSION_2)
19156 printf ("DSP 2.0\n");
19157 break;
19158
19159 case Tag_CSKY_VDSP_VERSION:
19160 printf (" Tag_CSKY_VDSP_VERSION:\t");
19161 READ_ULEB (val, p, end);
26c527e6 19162 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
19163 break;
19164
19165 case Tag_CSKY_FPU_VERSION:
19166 printf (" Tag_CSKY_FPU_VERSION:\t\t");
19167 READ_ULEB (val, p, end);
19168 if (val == VAL_CSKY_FPU_VERSION_1)
19169 printf ("ABIV1 FPU Version 1\n");
19170 else if (val == VAL_CSKY_FPU_VERSION_2)
19171 printf ("FPU Version 2\n");
19172 break;
19173
19174 case Tag_CSKY_FPU_ABI:
19175 printf (" Tag_CSKY_FPU_ABI:\t\t");
19176 READ_ULEB (val, p, end);
19177 if (val == VAL_CSKY_FPU_ABI_HARD)
19178 printf ("Hard\n");
19179 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
19180 printf ("SoftFP\n");
19181 else if (val == VAL_CSKY_FPU_ABI_SOFT)
19182 printf ("Soft\n");
19183 break;
19184 case Tag_CSKY_FPU_ROUNDING:
19185 READ_ULEB (val, p, end);
f253158f
NC
19186 if (val == 1)
19187 {
19188 printf (" Tag_CSKY_FPU_ROUNDING:\t");
19189 printf ("Needed\n");
19190 }
0861f561
CQ
19191 break;
19192 case Tag_CSKY_FPU_DENORMAL:
19193 READ_ULEB (val, p, end);
f253158f
NC
19194 if (val == 1)
19195 {
19196 printf (" Tag_CSKY_FPU_DENORMAL:\t");
19197 printf ("Needed\n");
19198 }
0861f561
CQ
19199 break;
19200 case Tag_CSKY_FPU_Exception:
19201 READ_ULEB (val, p, end);
f253158f
NC
19202 if (val == 1)
19203 {
19204 printf (" Tag_CSKY_FPU_Exception:\t");
19205 printf ("Needed\n");
19206 }
0861f561
CQ
19207 break;
19208 case Tag_CSKY_FPU_NUMBER_MODULE:
19209 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
19210 return display_tag_value (-1, p, end);
19211 case Tag_CSKY_FPU_HARDFP:
19212 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
19213 READ_ULEB (val, p, end);
19214 if (val & VAL_CSKY_FPU_HARDFP_HALF)
19215 printf (" Half");
19216 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
19217 printf (" Single");
19218 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
19219 printf (" Double");
19220 printf ("\n");
19221 break;
19222 default:
19223 return display_tag_value (tag, p, end);
19224 }
19225 return p;
19226}
19227
015dc7e1 19228static bool
dda8d76d 19229process_attributes (Filedata * filedata,
60bca95a 19230 const char * public_name,
104d59d1 19231 unsigned int proc_type,
f6f0e17b 19232 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 19233 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 19234{
2cf0635d 19235 Elf_Internal_Shdr * sect;
11c1ff18 19236 unsigned i;
015dc7e1 19237 bool res = true;
11c1ff18
PB
19238
19239 /* Find the section header so that we get the size. */
dda8d76d
NC
19240 for (i = 0, sect = filedata->section_headers;
19241 i < filedata->file_header.e_shnum;
11c1ff18
PB
19242 i++, sect++)
19243 {
071436c6
NC
19244 unsigned char * contents;
19245 unsigned char * p;
19246
104d59d1 19247 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
19248 continue;
19249
dda8d76d 19250 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 19251 sect->sh_size, _("attributes"));
60bca95a 19252 if (contents == NULL)
32ec8896 19253 {
015dc7e1 19254 res = false;
32ec8896
NC
19255 continue;
19256 }
60bca95a 19257
11c1ff18 19258 p = contents;
60abdbed
NC
19259 /* The first character is the version of the attributes.
19260 Currently only version 1, (aka 'A') is recognised here. */
19261 if (*p != 'A')
32ec8896
NC
19262 {
19263 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 19264 res = false;
32ec8896 19265 }
60abdbed 19266 else
11c1ff18 19267 {
625d49fc 19268 uint64_t section_len;
071436c6
NC
19269
19270 section_len = sect->sh_size - 1;
11c1ff18 19271 p++;
60bca95a 19272
071436c6 19273 while (section_len > 0)
11c1ff18 19274 {
625d49fc 19275 uint64_t attr_len;
e9847026 19276 unsigned int namelen;
015dc7e1
AM
19277 bool public_section;
19278 bool gnu_section;
11c1ff18 19279
071436c6 19280 if (section_len <= 4)
e0a31db1
NC
19281 {
19282 error (_("Tag section ends prematurely\n"));
015dc7e1 19283 res = false;
e0a31db1
NC
19284 break;
19285 }
071436c6 19286 attr_len = byte_get (p, 4);
11c1ff18 19287 p += 4;
60bca95a 19288
071436c6 19289 if (attr_len > section_len)
11c1ff18 19290 {
071436c6
NC
19291 error (_("Bad attribute length (%u > %u)\n"),
19292 (unsigned) attr_len, (unsigned) section_len);
19293 attr_len = section_len;
015dc7e1 19294 res = false;
11c1ff18 19295 }
74e1a04b 19296 /* PR 17531: file: 001-101425-0.004 */
071436c6 19297 else if (attr_len < 5)
74e1a04b 19298 {
071436c6 19299 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 19300 res = false;
74e1a04b
NC
19301 break;
19302 }
e9847026 19303
071436c6
NC
19304 section_len -= attr_len;
19305 attr_len -= 4;
19306
19307 namelen = strnlen ((char *) p, attr_len) + 1;
19308 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
19309 {
19310 error (_("Corrupt attribute section name\n"));
015dc7e1 19311 res = false;
e9847026
NC
19312 break;
19313 }
19314
071436c6 19315 printf (_("Attribute Section: "));
b6ac461a 19316 print_symbol_name (INT_MAX, (const char *) p);
071436c6 19317 putchar ('\n');
60bca95a
NC
19318
19319 if (public_name && streq ((char *) p, public_name))
015dc7e1 19320 public_section = true;
11c1ff18 19321 else
015dc7e1 19322 public_section = false;
60bca95a
NC
19323
19324 if (streq ((char *) p, "gnu"))
015dc7e1 19325 gnu_section = true;
104d59d1 19326 else
015dc7e1 19327 gnu_section = false;
60bca95a 19328
11c1ff18 19329 p += namelen;
071436c6 19330 attr_len -= namelen;
e0a31db1 19331
071436c6 19332 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 19333 {
e0a31db1 19334 int tag;
cd30bcef 19335 unsigned int val;
625d49fc 19336 uint64_t size;
071436c6 19337 unsigned char * end;
60bca95a 19338
e0a31db1 19339 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 19340 if (attr_len < 6)
e0a31db1
NC
19341 {
19342 error (_("Unused bytes at end of section\n"));
015dc7e1 19343 res = false;
e0a31db1
NC
19344 section_len = 0;
19345 break;
19346 }
19347
19348 tag = *(p++);
11c1ff18 19349 size = byte_get (p, 4);
071436c6 19350 if (size > attr_len)
11c1ff18 19351 {
e9847026 19352 error (_("Bad subsection length (%u > %u)\n"),
071436c6 19353 (unsigned) size, (unsigned) attr_len);
015dc7e1 19354 res = false;
071436c6 19355 size = attr_len;
11c1ff18 19356 }
e0a31db1
NC
19357 /* PR binutils/17531: Safe handling of corrupt files. */
19358 if (size < 6)
19359 {
19360 error (_("Bad subsection length (%u < 6)\n"),
19361 (unsigned) size);
015dc7e1 19362 res = false;
e0a31db1
NC
19363 section_len = 0;
19364 break;
19365 }
60bca95a 19366
071436c6 19367 attr_len -= size;
11c1ff18 19368 end = p + size - 1;
071436c6 19369 assert (end <= contents + sect->sh_size);
11c1ff18 19370 p += 4;
60bca95a 19371
11c1ff18
PB
19372 switch (tag)
19373 {
19374 case 1:
2b692964 19375 printf (_("File Attributes\n"));
11c1ff18
PB
19376 break;
19377 case 2:
2b692964 19378 printf (_("Section Attributes:"));
11c1ff18
PB
19379 goto do_numlist;
19380 case 3:
2b692964 19381 printf (_("Symbol Attributes:"));
1a0670f3 19382 /* Fall through. */
11c1ff18
PB
19383 do_numlist:
19384 for (;;)
19385 {
cd30bcef 19386 READ_ULEB (val, p, end);
11c1ff18
PB
19387 if (val == 0)
19388 break;
19389 printf (" %d", val);
19390 }
19391 printf ("\n");
19392 break;
19393 default:
2b692964 19394 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 19395 public_section = false;
11c1ff18
PB
19396 break;
19397 }
60bca95a 19398
071436c6 19399 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
19400 {
19401 while (p < end)
f6f0e17b 19402 p = display_pub_attribute (p, end);
60abdbed 19403 assert (p == end);
104d59d1 19404 }
071436c6 19405 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
19406 {
19407 while (p < end)
19408 p = display_gnu_attribute (p,
f6f0e17b
NC
19409 display_proc_gnu_attribute,
19410 end);
60abdbed 19411 assert (p == end);
11c1ff18 19412 }
071436c6 19413 else if (p < end)
11c1ff18 19414 {
071436c6 19415 printf (_(" Unknown attribute:\n"));
f6f0e17b 19416 display_raw_attribute (p, end);
11c1ff18
PB
19417 p = end;
19418 }
071436c6
NC
19419 else
19420 attr_len = 0;
11c1ff18
PB
19421 }
19422 }
19423 }
d70c5fc7 19424
60bca95a 19425 free (contents);
11c1ff18 19426 }
32ec8896
NC
19427
19428 return res;
11c1ff18
PB
19429}
19430
ccb4c951
RS
19431/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19432 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
19433 and return the VMA of the next entry, or -1 if there was a problem.
19434 Does not read from DATA_END or beyond. */
ccb4c951 19435
625d49fc
AM
19436static uint64_t
19437print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 19438 unsigned char * data_end)
ccb4c951
RS
19439{
19440 printf (" ");
19441 print_vma (addr, LONG_HEX);
19442 printf (" ");
19443 if (addr < pltgot + 0xfff0)
19444 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19445 else
19446 printf ("%10s", "");
19447 printf (" ");
19448 if (data == NULL)
2b692964 19449 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
19450 else
19451 {
625d49fc 19452 uint64_t entry;
82b1b41b 19453 unsigned char * from = data + addr - pltgot;
ccb4c951 19454
82b1b41b
NC
19455 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19456 {
19457 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19458 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 19459 return (uint64_t) -1;
82b1b41b
NC
19460 }
19461 else
19462 {
19463 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19464 print_vma (entry, LONG_HEX);
19465 }
ccb4c951
RS
19466 }
19467 return addr + (is_32bit_elf ? 4 : 8);
19468}
19469
861fb55a
DJ
19470/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19471 PLTGOT. Print the Address and Initial fields of an entry at VMA
19472 ADDR and return the VMA of the next entry. */
19473
625d49fc
AM
19474static uint64_t
19475print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
19476{
19477 printf (" ");
19478 print_vma (addr, LONG_HEX);
19479 printf (" ");
19480 if (data == NULL)
2b692964 19481 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
19482 else
19483 {
625d49fc 19484 uint64_t entry;
861fb55a
DJ
19485
19486 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19487 print_vma (entry, LONG_HEX);
19488 }
19489 return addr + (is_32bit_elf ? 4 : 8);
19490}
19491
351cdf24
MF
19492static void
19493print_mips_ases (unsigned int mask)
19494{
19495 if (mask & AFL_ASE_DSP)
19496 fputs ("\n\tDSP ASE", stdout);
19497 if (mask & AFL_ASE_DSPR2)
19498 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
19499 if (mask & AFL_ASE_DSPR3)
19500 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
19501 if (mask & AFL_ASE_EVA)
19502 fputs ("\n\tEnhanced VA Scheme", stdout);
19503 if (mask & AFL_ASE_MCU)
19504 fputs ("\n\tMCU (MicroController) ASE", stdout);
19505 if (mask & AFL_ASE_MDMX)
19506 fputs ("\n\tMDMX ASE", stdout);
19507 if (mask & AFL_ASE_MIPS3D)
19508 fputs ("\n\tMIPS-3D ASE", stdout);
19509 if (mask & AFL_ASE_MT)
19510 fputs ("\n\tMT ASE", stdout);
19511 if (mask & AFL_ASE_SMARTMIPS)
19512 fputs ("\n\tSmartMIPS ASE", stdout);
19513 if (mask & AFL_ASE_VIRT)
19514 fputs ("\n\tVZ ASE", stdout);
19515 if (mask & AFL_ASE_MSA)
19516 fputs ("\n\tMSA ASE", stdout);
19517 if (mask & AFL_ASE_MIPS16)
19518 fputs ("\n\tMIPS16 ASE", stdout);
19519 if (mask & AFL_ASE_MICROMIPS)
19520 fputs ("\n\tMICROMIPS ASE", stdout);
19521 if (mask & AFL_ASE_XPA)
19522 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
19523 if (mask & AFL_ASE_MIPS16E2)
19524 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
19525 if (mask & AFL_ASE_CRC)
19526 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
19527 if (mask & AFL_ASE_GINV)
19528 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
19529 if (mask & AFL_ASE_LOONGSON_MMI)
19530 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
19531 if (mask & AFL_ASE_LOONGSON_CAM)
19532 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
19533 if (mask & AFL_ASE_LOONGSON_EXT)
19534 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
19535 if (mask & AFL_ASE_LOONGSON_EXT2)
19536 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
19537 if (mask == 0)
19538 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
19539 else if ((mask & ~AFL_ASE_MASK) != 0)
19540 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
19541}
19542
19543static void
19544print_mips_isa_ext (unsigned int isa_ext)
19545{
19546 switch (isa_ext)
19547 {
19548 case 0:
19549 fputs (_("None"), stdout);
19550 break;
19551 case AFL_EXT_XLR:
19552 fputs ("RMI XLR", stdout);
19553 break;
2c629856
N
19554 case AFL_EXT_OCTEON3:
19555 fputs ("Cavium Networks Octeon3", stdout);
19556 break;
351cdf24
MF
19557 case AFL_EXT_OCTEON2:
19558 fputs ("Cavium Networks Octeon2", stdout);
19559 break;
19560 case AFL_EXT_OCTEONP:
19561 fputs ("Cavium Networks OcteonP", stdout);
19562 break;
351cdf24
MF
19563 case AFL_EXT_OCTEON:
19564 fputs ("Cavium Networks Octeon", stdout);
19565 break;
19566 case AFL_EXT_5900:
19567 fputs ("Toshiba R5900", stdout);
19568 break;
19569 case AFL_EXT_4650:
19570 fputs ("MIPS R4650", stdout);
19571 break;
19572 case AFL_EXT_4010:
19573 fputs ("LSI R4010", stdout);
19574 break;
19575 case AFL_EXT_4100:
19576 fputs ("NEC VR4100", stdout);
19577 break;
19578 case AFL_EXT_3900:
19579 fputs ("Toshiba R3900", stdout);
19580 break;
19581 case AFL_EXT_10000:
19582 fputs ("MIPS R10000", stdout);
19583 break;
19584 case AFL_EXT_SB1:
19585 fputs ("Broadcom SB-1", stdout);
19586 break;
19587 case AFL_EXT_4111:
19588 fputs ("NEC VR4111/VR4181", stdout);
19589 break;
19590 case AFL_EXT_4120:
19591 fputs ("NEC VR4120", stdout);
19592 break;
19593 case AFL_EXT_5400:
19594 fputs ("NEC VR5400", stdout);
19595 break;
19596 case AFL_EXT_5500:
19597 fputs ("NEC VR5500", stdout);
19598 break;
19599 case AFL_EXT_LOONGSON_2E:
19600 fputs ("ST Microelectronics Loongson 2E", stdout);
19601 break;
19602 case AFL_EXT_LOONGSON_2F:
19603 fputs ("ST Microelectronics Loongson 2F", stdout);
19604 break;
38bf472a
MR
19605 case AFL_EXT_INTERAPTIV_MR2:
19606 fputs ("Imagination interAptiv MR2", stdout);
19607 break;
351cdf24 19608 default:
00ac7aa0 19609 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19610 }
19611}
19612
32ec8896 19613static signed int
351cdf24
MF
19614get_mips_reg_size (int reg_size)
19615{
19616 return (reg_size == AFL_REG_NONE) ? 0
19617 : (reg_size == AFL_REG_32) ? 32
19618 : (reg_size == AFL_REG_64) ? 64
19619 : (reg_size == AFL_REG_128) ? 128
19620 : -1;
19621}
19622
015dc7e1 19623static bool
dda8d76d 19624process_mips_specific (Filedata * filedata)
5b18a4bc 19625{
2cf0635d 19626 Elf_Internal_Dyn * entry;
351cdf24 19627 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19628 size_t liblist_offset = 0;
19629 size_t liblistno = 0;
19630 size_t conflictsno = 0;
19631 size_t options_offset = 0;
19632 size_t conflicts_offset = 0;
861fb55a
DJ
19633 size_t pltrelsz = 0;
19634 size_t pltrel = 0;
625d49fc
AM
19635 uint64_t pltgot = 0;
19636 uint64_t mips_pltgot = 0;
19637 uint64_t jmprel = 0;
19638 uint64_t local_gotno = 0;
19639 uint64_t gotsym = 0;
19640 uint64_t symtabno = 0;
015dc7e1 19641 bool res = true;
103f02d3 19642
dda8d76d 19643 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19644 display_mips_gnu_attribute))
015dc7e1 19645 res = false;
2cf19d5c 19646
dda8d76d 19647 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19648
19649 if (sect != NULL)
19650 {
19651 Elf_External_ABIFlags_v0 *abiflags_ext;
19652 Elf_Internal_ABIFlags_v0 abiflags_in;
19653
19654 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19655 {
19656 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19657 res = false;
32ec8896 19658 }
351cdf24
MF
19659 else
19660 {
dda8d76d 19661 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19662 sect->sh_size, _("MIPS ABI Flags section"));
19663 if (abiflags_ext)
19664 {
19665 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19666 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19667 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19668 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19669 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19670 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19671 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19672 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19673 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19674 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19675 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19676
19677 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19678 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19679 if (abiflags_in.isa_rev > 1)
19680 printf ("r%d", abiflags_in.isa_rev);
19681 printf ("\nGPR size: %d",
19682 get_mips_reg_size (abiflags_in.gpr_size));
19683 printf ("\nCPR1 size: %d",
19684 get_mips_reg_size (abiflags_in.cpr1_size));
19685 printf ("\nCPR2 size: %d",
19686 get_mips_reg_size (abiflags_in.cpr2_size));
19687 fputs ("\nFP ABI: ", stdout);
19688 print_mips_fp_abi_value (abiflags_in.fp_abi);
19689 fputs ("ISA Extension: ", stdout);
19690 print_mips_isa_ext (abiflags_in.isa_ext);
19691 fputs ("\nASEs:", stdout);
19692 print_mips_ases (abiflags_in.ases);
19693 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19694 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19695 fputc ('\n', stdout);
19696 free (abiflags_ext);
19697 }
19698 }
19699 }
19700
19e6b90e 19701 /* We have a lot of special sections. Thanks SGI! */
978c4450 19702 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19703 {
19704 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19705 sect = find_section (filedata, ".got");
bbdd9a68
MR
19706 if (sect != NULL)
19707 {
19708 unsigned char *data_end;
19709 unsigned char *data;
625d49fc 19710 uint64_t ent, end;
bbdd9a68
MR
19711 int addr_size;
19712
19713 pltgot = sect->sh_addr;
19714
19715 ent = pltgot;
19716 addr_size = (is_32bit_elf ? 4 : 8);
19717 end = pltgot + sect->sh_size;
19718
dda8d76d 19719 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19720 end - pltgot, 1,
19721 _("Global Offset Table data"));
19722 /* PR 12855: Null data is handled gracefully throughout. */
19723 data_end = data + (end - pltgot);
19724
19725 printf (_("\nStatic GOT:\n"));
19726 printf (_(" Canonical gp value: "));
19727 print_vma (ent + 0x7ff0, LONG_HEX);
19728 printf ("\n\n");
19729
19730 /* In a dynamic binary GOT[0] is reserved for the dynamic
19731 loader to store the lazy resolver pointer, however in
19732 a static binary it may well have been omitted and GOT
19733 reduced to a table of addresses.
19734 PR 21344: Check for the entry being fully available
19735 before fetching it. */
19736 if (data
19737 && data + ent - pltgot + addr_size <= data_end
19738 && byte_get (data + ent - pltgot, addr_size) == 0)
19739 {
19740 printf (_(" Reserved entries:\n"));
19741 printf (_(" %*s %10s %*s\n"),
19742 addr_size * 2, _("Address"), _("Access"),
19743 addr_size * 2, _("Value"));
19744 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19745 printf ("\n");
625d49fc 19746 if (ent == (uint64_t) -1)
bbdd9a68
MR
19747 goto sgot_print_fail;
19748
19749 /* Check for the MSB of GOT[1] being set, identifying a
19750 GNU object. This entry will be used by some runtime
19751 loaders, to store the module pointer. Otherwise this
19752 is an ordinary local entry.
19753 PR 21344: Check for the entry being fully available
19754 before fetching it. */
19755 if (data
19756 && data + ent - pltgot + addr_size <= data_end
19757 && (byte_get (data + ent - pltgot, addr_size)
19758 >> (addr_size * 8 - 1)) != 0)
19759 {
19760 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19761 printf ("\n");
625d49fc 19762 if (ent == (uint64_t) -1)
bbdd9a68
MR
19763 goto sgot_print_fail;
19764 }
19765 printf ("\n");
19766 }
19767
f17e9d8a 19768 if (data != NULL && ent < end)
bbdd9a68
MR
19769 {
19770 printf (_(" Local entries:\n"));
19771 printf (" %*s %10s %*s\n",
19772 addr_size * 2, _("Address"), _("Access"),
19773 addr_size * 2, _("Value"));
19774 while (ent < end)
19775 {
19776 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19777 printf ("\n");
625d49fc 19778 if (ent == (uint64_t) -1)
bbdd9a68
MR
19779 goto sgot_print_fail;
19780 }
19781 printf ("\n");
19782 }
19783
19784 sgot_print_fail:
9db70fc3 19785 free (data);
bbdd9a68
MR
19786 }
19787 return res;
19788 }
252b5132 19789
978c4450 19790 for (entry = filedata->dynamic_section;
071436c6 19791 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19792 (entry < filedata->dynamic_section + filedata->dynamic_nent
19793 && entry->d_tag != DT_NULL);
071436c6 19794 ++entry)
252b5132
RH
19795 switch (entry->d_tag)
19796 {
19797 case DT_MIPS_LIBLIST:
d93f0186 19798 liblist_offset
dda8d76d 19799 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19800 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19801 break;
19802 case DT_MIPS_LIBLISTNO:
19803 liblistno = entry->d_un.d_val;
19804 break;
19805 case DT_MIPS_OPTIONS:
dda8d76d 19806 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19807 break;
19808 case DT_MIPS_CONFLICT:
d93f0186 19809 conflicts_offset
dda8d76d 19810 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19811 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19812 break;
19813 case DT_MIPS_CONFLICTNO:
19814 conflictsno = entry->d_un.d_val;
19815 break;
ccb4c951 19816 case DT_PLTGOT:
861fb55a
DJ
19817 pltgot = entry->d_un.d_ptr;
19818 break;
ccb4c951
RS
19819 case DT_MIPS_LOCAL_GOTNO:
19820 local_gotno = entry->d_un.d_val;
19821 break;
19822 case DT_MIPS_GOTSYM:
19823 gotsym = entry->d_un.d_val;
19824 break;
19825 case DT_MIPS_SYMTABNO:
19826 symtabno = entry->d_un.d_val;
19827 break;
861fb55a
DJ
19828 case DT_MIPS_PLTGOT:
19829 mips_pltgot = entry->d_un.d_ptr;
19830 break;
19831 case DT_PLTREL:
19832 pltrel = entry->d_un.d_val;
19833 break;
19834 case DT_PLTRELSZ:
19835 pltrelsz = entry->d_un.d_val;
19836 break;
19837 case DT_JMPREL:
19838 jmprel = entry->d_un.d_ptr;
19839 break;
252b5132
RH
19840 default:
19841 break;
19842 }
19843
19844 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19845 {
2cf0635d 19846 Elf32_External_Lib * elib;
252b5132
RH
19847 size_t cnt;
19848
dda8d76d 19849 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19850 sizeof (Elf32_External_Lib),
19851 liblistno,
19852 _("liblist section data"));
a6e9f9df 19853 if (elib)
252b5132 19854 {
26c527e6
AM
19855 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19856 "\nSection '.liblist' contains %zu entries:\n",
19857 liblistno),
19858 liblistno);
2b692964 19859 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19860 stdout);
19861
19862 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19863 {
a6e9f9df 19864 Elf32_Lib liblist;
91d6fa6a 19865 time_t atime;
d5b07ef4 19866 char timebuf[128];
2cf0635d 19867 struct tm * tmp;
a6e9f9df
AM
19868
19869 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19870 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19871 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19872 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19873 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19874
91d6fa6a 19875 tmp = gmtime (&atime);
e9e44622
JJ
19876 snprintf (timebuf, sizeof (timebuf),
19877 "%04u-%02u-%02uT%02u:%02u:%02u",
19878 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19879 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19880
26c527e6 19881 printf ("%3zu: ", cnt);
84714f86 19882 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19883 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19884 else
2b692964 19885 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19886 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19887 liblist.l_version);
a6e9f9df
AM
19888
19889 if (liblist.l_flags == 0)
2b692964 19890 puts (_(" NONE"));
a6e9f9df
AM
19891 else
19892 {
19893 static const struct
252b5132 19894 {
2cf0635d 19895 const char * name;
a6e9f9df 19896 int bit;
252b5132 19897 }
a6e9f9df
AM
19898 l_flags_vals[] =
19899 {
19900 { " EXACT_MATCH", LL_EXACT_MATCH },
19901 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19902 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19903 { " EXPORTS", LL_EXPORTS },
19904 { " DELAY_LOAD", LL_DELAY_LOAD },
19905 { " DELTA", LL_DELTA }
19906 };
19907 int flags = liblist.l_flags;
19908 size_t fcnt;
19909
60bca95a 19910 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19911 if ((flags & l_flags_vals[fcnt].bit) != 0)
19912 {
19913 fputs (l_flags_vals[fcnt].name, stdout);
19914 flags ^= l_flags_vals[fcnt].bit;
19915 }
19916 if (flags != 0)
19917 printf (" %#x", (unsigned int) flags);
252b5132 19918
a6e9f9df
AM
19919 puts ("");
19920 }
252b5132 19921 }
252b5132 19922
a6e9f9df
AM
19923 free (elib);
19924 }
32ec8896 19925 else
015dc7e1 19926 res = false;
252b5132
RH
19927 }
19928
19929 if (options_offset != 0)
19930 {
2cf0635d 19931 Elf_External_Options * eopt;
252b5132
RH
19932 size_t offset;
19933 int cnt;
19934
19935 /* Find the section header so that we get the size. */
dda8d76d 19936 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19937 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19938 if (sect == NULL)
19939 {
19940 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19941 return false;
071436c6 19942 }
7fc0c668
NC
19943 /* PR 24243 */
19944 if (sect->sh_size < sizeof (* eopt))
19945 {
19946 error (_("The MIPS options section is too small.\n"));
015dc7e1 19947 return false;
7fc0c668 19948 }
252b5132 19949
dda8d76d 19950 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19951 sect->sh_size, _("options"));
a6e9f9df 19952 if (eopt)
252b5132 19953 {
fd17d1e6 19954 Elf_Internal_Options option;
76da6bbe 19955
a6e9f9df 19956 offset = cnt = 0;
82b1b41b 19957 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19958 {
2cf0635d 19959 Elf_External_Options * eoption;
fd17d1e6 19960 unsigned int optsize;
252b5132 19961
a6e9f9df 19962 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19963
fd17d1e6 19964 optsize = BYTE_GET (eoption->size);
76da6bbe 19965
82b1b41b 19966 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19967 if (optsize < sizeof (* eopt)
19968 || optsize > sect->sh_size - offset)
82b1b41b 19969 {
645f43a8 19970 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19971 optsize);
645f43a8 19972 free (eopt);
015dc7e1 19973 return false;
82b1b41b 19974 }
fd17d1e6 19975 offset += optsize;
a6e9f9df
AM
19976 ++cnt;
19977 }
252b5132 19978
d3a49aa8
AM
19979 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19980 "\nSection '%s' contains %d entries:\n",
19981 cnt),
dda8d76d 19982 printable_section_name (filedata, sect), cnt);
76da6bbe 19983
82b1b41b 19984 offset = 0;
a6e9f9df 19985 while (cnt-- > 0)
252b5132 19986 {
a6e9f9df 19987 size_t len;
fd17d1e6
AM
19988 Elf_External_Options * eoption;
19989
19990 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19991
19992 option.kind = BYTE_GET (eoption->kind);
19993 option.size = BYTE_GET (eoption->size);
19994 option.section = BYTE_GET (eoption->section);
19995 option.info = BYTE_GET (eoption->info);
a6e9f9df 19996
fd17d1e6 19997 switch (option.kind)
252b5132 19998 {
a6e9f9df
AM
19999 case ODK_NULL:
20000 /* This shouldn't happen. */
d0c4e780 20001 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 20002 option.section, option.info);
a6e9f9df 20003 break;
2e6be59c 20004
a6e9f9df
AM
20005 case ODK_REGINFO:
20006 printf (" REGINFO ");
dda8d76d 20007 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 20008 {
2cf0635d 20009 Elf32_External_RegInfo * ereg;
b34976b6 20010 Elf32_RegInfo reginfo;
a6e9f9df 20011
2e6be59c 20012 /* 32bit form. */
fd17d1e6
AM
20013 if (option.size < (sizeof (Elf_External_Options)
20014 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
20015 {
20016 printf (_("<corrupt>\n"));
20017 error (_("Truncated MIPS REGINFO option\n"));
20018 cnt = 0;
20019 break;
20020 }
20021
fd17d1e6 20022 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 20023
a6e9f9df
AM
20024 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20025 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20026 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20027 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20028 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20029 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20030
d0c4e780
AM
20031 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
20032 reginfo.ri_gprmask, reginfo.ri_gp_value);
20033 printf (" "
20034 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20035 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
20036 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20037 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20038 }
20039 else
20040 {
20041 /* 64 bit form. */
2cf0635d 20042 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
20043 Elf64_Internal_RegInfo reginfo;
20044
fd17d1e6
AM
20045 if (option.size < (sizeof (Elf_External_Options)
20046 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
20047 {
20048 printf (_("<corrupt>\n"));
20049 error (_("Truncated MIPS REGINFO option\n"));
20050 cnt = 0;
20051 break;
20052 }
20053
fd17d1e6 20054 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
20055 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20056 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20057 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20058 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20059 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 20060 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 20061
d0c4e780
AM
20062 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
20063 reginfo.ri_gprmask, reginfo.ri_gp_value);
20064 printf (" "
20065 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20066 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
20067 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20068 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20069 }
fd17d1e6 20070 offset += option.size;
a6e9f9df 20071 continue;
2e6be59c 20072
a6e9f9df
AM
20073 case ODK_EXCEPTIONS:
20074 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 20075 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 20076 fputs (") fpe_max(", stdout);
fd17d1e6 20077 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
20078 fputs (")", stdout);
20079
fd17d1e6 20080 if (option.info & OEX_PAGE0)
a6e9f9df 20081 fputs (" PAGE0", stdout);
fd17d1e6 20082 if (option.info & OEX_SMM)
a6e9f9df 20083 fputs (" SMM", stdout);
fd17d1e6 20084 if (option.info & OEX_FPDBUG)
a6e9f9df 20085 fputs (" FPDBUG", stdout);
fd17d1e6 20086 if (option.info & OEX_DISMISS)
a6e9f9df
AM
20087 fputs (" DISMISS", stdout);
20088 break;
2e6be59c 20089
a6e9f9df
AM
20090 case ODK_PAD:
20091 fputs (" PAD ", stdout);
fd17d1e6 20092 if (option.info & OPAD_PREFIX)
a6e9f9df 20093 fputs (" PREFIX", stdout);
fd17d1e6 20094 if (option.info & OPAD_POSTFIX)
a6e9f9df 20095 fputs (" POSTFIX", stdout);
fd17d1e6 20096 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
20097 fputs (" SYMBOL", stdout);
20098 break;
2e6be59c 20099
a6e9f9df
AM
20100 case ODK_HWPATCH:
20101 fputs (" HWPATCH ", stdout);
fd17d1e6 20102 if (option.info & OHW_R4KEOP)
a6e9f9df 20103 fputs (" R4KEOP", stdout);
fd17d1e6 20104 if (option.info & OHW_R8KPFETCH)
a6e9f9df 20105 fputs (" R8KPFETCH", stdout);
fd17d1e6 20106 if (option.info & OHW_R5KEOP)
a6e9f9df 20107 fputs (" R5KEOP", stdout);
fd17d1e6 20108 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
20109 fputs (" R5KCVTL", stdout);
20110 break;
2e6be59c 20111
a6e9f9df
AM
20112 case ODK_FILL:
20113 fputs (" FILL ", stdout);
20114 /* XXX Print content of info word? */
20115 break;
2e6be59c 20116
a6e9f9df
AM
20117 case ODK_TAGS:
20118 fputs (" TAGS ", stdout);
20119 /* XXX Print content of info word? */
20120 break;
2e6be59c 20121
a6e9f9df
AM
20122 case ODK_HWAND:
20123 fputs (" HWAND ", stdout);
fd17d1e6 20124 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 20125 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 20126 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
20127 fputs (" R4KEOP_CLEAN", stdout);
20128 break;
2e6be59c 20129
a6e9f9df
AM
20130 case ODK_HWOR:
20131 fputs (" HWOR ", stdout);
fd17d1e6 20132 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 20133 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 20134 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
20135 fputs (" R4KEOP_CLEAN", stdout);
20136 break;
2e6be59c 20137
a6e9f9df 20138 case ODK_GP_GROUP:
d0c4e780 20139 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
20140 option.info & OGP_GROUP,
20141 (option.info & OGP_SELF) >> 16);
a6e9f9df 20142 break;
2e6be59c 20143
a6e9f9df 20144 case ODK_IDENT:
d0c4e780 20145 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
20146 option.info & OGP_GROUP,
20147 (option.info & OGP_SELF) >> 16);
a6e9f9df 20148 break;
2e6be59c 20149
a6e9f9df
AM
20150 default:
20151 /* This shouldn't happen. */
d0c4e780 20152 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 20153 option.kind, option.section, option.info);
a6e9f9df 20154 break;
252b5132 20155 }
a6e9f9df 20156
2cf0635d 20157 len = sizeof (* eopt);
fd17d1e6 20158 while (len < option.size)
82b1b41b 20159 {
fd17d1e6 20160 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 20161
82b1b41b
NC
20162 if (ISPRINT (datum))
20163 printf ("%c", datum);
20164 else
20165 printf ("\\%03o", datum);
20166 len ++;
20167 }
a6e9f9df 20168 fputs ("\n", stdout);
82b1b41b 20169
fd17d1e6 20170 offset += option.size;
252b5132 20171 }
a6e9f9df 20172 free (eopt);
252b5132 20173 }
32ec8896 20174 else
015dc7e1 20175 res = false;
252b5132
RH
20176 }
20177
20178 if (conflicts_offset != 0 && conflictsno != 0)
20179 {
2cf0635d 20180 Elf32_Conflict * iconf;
252b5132
RH
20181 size_t cnt;
20182
978c4450 20183 if (filedata->dynamic_symbols == NULL)
252b5132 20184 {
591a748a 20185 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 20186 return false;
252b5132
RH
20187 }
20188
7296a62a
NC
20189 /* PR 21345 - print a slightly more helpful error message
20190 if we are sure that the cmalloc will fail. */
645f43a8 20191 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 20192 {
26c527e6
AM
20193 error (_("Overlarge number of conflicts detected: %zx\n"),
20194 conflictsno);
015dc7e1 20195 return false;
7296a62a
NC
20196 }
20197
3f5e193b 20198 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
20199 if (iconf == NULL)
20200 {
8b73c356 20201 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 20202 return false;
252b5132
RH
20203 }
20204
9ea033b2 20205 if (is_32bit_elf)
252b5132 20206 {
2cf0635d 20207 Elf32_External_Conflict * econf32;
a6e9f9df 20208
3f5e193b 20209 econf32 = (Elf32_External_Conflict *)
95099889
AM
20210 get_data (NULL, filedata, conflicts_offset,
20211 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 20212 if (!econf32)
5a814d6d
AM
20213 {
20214 free (iconf);
015dc7e1 20215 return false;
5a814d6d 20216 }
252b5132
RH
20217
20218 for (cnt = 0; cnt < conflictsno; ++cnt)
20219 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
20220
20221 free (econf32);
252b5132
RH
20222 }
20223 else
20224 {
2cf0635d 20225 Elf64_External_Conflict * econf64;
a6e9f9df 20226
3f5e193b 20227 econf64 = (Elf64_External_Conflict *)
95099889
AM
20228 get_data (NULL, filedata, conflicts_offset,
20229 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 20230 if (!econf64)
5a814d6d
AM
20231 {
20232 free (iconf);
015dc7e1 20233 return false;
5a814d6d 20234 }
252b5132
RH
20235
20236 for (cnt = 0; cnt < conflictsno; ++cnt)
20237 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
20238
20239 free (econf64);
252b5132
RH
20240 }
20241
26c527e6
AM
20242 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
20243 "\nSection '.conflict' contains %zu entries:\n",
20244 conflictsno),
20245 conflictsno);
252b5132
RH
20246 puts (_(" Num: Index Value Name"));
20247
20248 for (cnt = 0; cnt < conflictsno; ++cnt)
20249 {
26c527e6 20250 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 20251
978c4450 20252 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 20253 printf (_("<corrupt symbol index>"));
d79b3d50 20254 else
e0a31db1
NC
20255 {
20256 Elf_Internal_Sym * psym;
20257
978c4450 20258 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
20259 print_vma (psym->st_value, FULL_HEX);
20260 putchar (' ');
84714f86 20261 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20262 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20263 else
20264 printf (_("<corrupt: %14ld>"), psym->st_name);
20265 }
31104126 20266 putchar ('\n');
252b5132
RH
20267 }
20268
252b5132
RH
20269 free (iconf);
20270 }
20271
ccb4c951
RS
20272 if (pltgot != 0 && local_gotno != 0)
20273 {
625d49fc 20274 uint64_t ent, local_end, global_end;
bbeee7ea 20275 size_t i, offset;
2cf0635d 20276 unsigned char * data;
82b1b41b 20277 unsigned char * data_end;
bbeee7ea 20278 int addr_size;
ccb4c951 20279
91d6fa6a 20280 ent = pltgot;
ccb4c951
RS
20281 addr_size = (is_32bit_elf ? 4 : 8);
20282 local_end = pltgot + local_gotno * addr_size;
ccb4c951 20283
74e1a04b
NC
20284 /* PR binutils/17533 file: 012-111227-0.004 */
20285 if (symtabno < gotsym)
20286 {
26c527e6
AM
20287 error (_("The GOT symbol offset (%" PRIu64
20288 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20289 gotsym, symtabno);
015dc7e1 20290 return false;
74e1a04b 20291 }
82b1b41b 20292
74e1a04b 20293 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
20294 /* PR 17531: file: 54c91a34. */
20295 if (global_end < local_end)
20296 {
26c527e6 20297 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 20298 return false;
82b1b41b 20299 }
948f632f 20300
dda8d76d
NC
20301 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20302 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
20303 global_end - pltgot, 1,
20304 _("Global Offset Table data"));
919383ac 20305 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 20306 data_end = data + (global_end - pltgot);
59245841 20307
ccb4c951
RS
20308 printf (_("\nPrimary GOT:\n"));
20309 printf (_(" Canonical gp value: "));
20310 print_vma (pltgot + 0x7ff0, LONG_HEX);
20311 printf ("\n\n");
20312
20313 printf (_(" Reserved entries:\n"));
20314 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
20315 addr_size * 2, _("Address"), _("Access"),
20316 addr_size * 2, _("Initial"));
82b1b41b 20317 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 20318 printf (_(" Lazy resolver\n"));
625d49fc 20319 if (ent == (uint64_t) -1)
82b1b41b 20320 goto got_print_fail;
75ec1fdb 20321
c4ab9505
MR
20322 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20323 This entry will be used by some runtime loaders, to store the
20324 module pointer. Otherwise this is an ordinary local entry.
20325 PR 21344: Check for the entry being fully available before
20326 fetching it. */
20327 if (data
20328 && data + ent - pltgot + addr_size <= data_end
20329 && (byte_get (data + ent - pltgot, addr_size)
20330 >> (addr_size * 8 - 1)) != 0)
20331 {
20332 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20333 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 20334 if (ent == (uint64_t) -1)
c4ab9505 20335 goto got_print_fail;
ccb4c951
RS
20336 }
20337 printf ("\n");
20338
f17e9d8a 20339 if (data != NULL && ent < local_end)
ccb4c951
RS
20340 {
20341 printf (_(" Local entries:\n"));
cc5914eb 20342 printf (" %*s %10s %*s\n",
2b692964
NC
20343 addr_size * 2, _("Address"), _("Access"),
20344 addr_size * 2, _("Initial"));
91d6fa6a 20345 while (ent < local_end)
ccb4c951 20346 {
82b1b41b 20347 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20348 printf ("\n");
625d49fc 20349 if (ent == (uint64_t) -1)
82b1b41b 20350 goto got_print_fail;
ccb4c951
RS
20351 }
20352 printf ("\n");
20353 }
20354
f17e9d8a 20355 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
20356 {
20357 int sym_width;
20358
20359 printf (_(" Global entries:\n"));
cc5914eb 20360 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
20361 addr_size * 2, _("Address"),
20362 _("Access"),
2b692964 20363 addr_size * 2, _("Initial"),
9cf03b7e
NC
20364 addr_size * 2, _("Sym.Val."),
20365 _("Type"),
20366 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20367 _("Ndx"), _("Name"));
0b4362b0 20368
ccb4c951 20369 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 20370
ccb4c951
RS
20371 for (i = gotsym; i < symtabno; i++)
20372 {
82b1b41b 20373 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20374 printf (" ");
e0a31db1 20375
978c4450 20376 if (filedata->dynamic_symbols == NULL)
e0a31db1 20377 printf (_("<no dynamic symbols>"));
978c4450 20378 else if (i < filedata->num_dynamic_syms)
e0a31db1 20379 {
978c4450 20380 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
20381
20382 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
20383 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20384
20385 bool is_special;
20386 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20387 if (is_special)
20388 printf ("%3s ", s);
20389 else
20390 printf ("%3u ", psym->st_shndx);
e0a31db1 20391
84714f86 20392 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20393 print_symbol_name (sym_width,
84714f86 20394 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20395 else
20396 printf (_("<corrupt: %14ld>"), psym->st_name);
20397 }
ccb4c951 20398 else
26c527e6
AM
20399 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20400 i);
e0a31db1 20401
ccb4c951 20402 printf ("\n");
625d49fc 20403 if (ent == (uint64_t) -1)
82b1b41b 20404 break;
ccb4c951
RS
20405 }
20406 printf ("\n");
20407 }
20408
82b1b41b 20409 got_print_fail:
9db70fc3 20410 free (data);
ccb4c951
RS
20411 }
20412
861fb55a
DJ
20413 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20414 {
625d49fc 20415 uint64_t ent, end;
26c527e6
AM
20416 uint64_t offset, rel_offset;
20417 uint64_t count, i;
2cf0635d 20418 unsigned char * data;
861fb55a 20419 int addr_size, sym_width;
2cf0635d 20420 Elf_Internal_Rela * rels;
861fb55a 20421
dda8d76d 20422 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
20423 if (pltrel == DT_RELA)
20424 {
dda8d76d 20425 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20426 return false;
861fb55a
DJ
20427 }
20428 else
20429 {
dda8d76d 20430 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20431 return false;
861fb55a
DJ
20432 }
20433
91d6fa6a 20434 ent = mips_pltgot;
861fb55a
DJ
20435 addr_size = (is_32bit_elf ? 4 : 8);
20436 end = mips_pltgot + (2 + count) * addr_size;
20437
dda8d76d
NC
20438 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20439 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 20440 1, _("Procedure Linkage Table data"));
59245841 20441 if (data == NULL)
288f0ba2
AM
20442 {
20443 free (rels);
015dc7e1 20444 return false;
288f0ba2 20445 }
59245841 20446
9cf03b7e 20447 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
20448 printf (_(" Reserved entries:\n"));
20449 printf (_(" %*s %*s Purpose\n"),
2b692964 20450 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 20451 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20452 printf (_(" PLT lazy resolver\n"));
91d6fa6a 20453 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20454 printf (_(" Module pointer\n"));
861fb55a
DJ
20455 printf ("\n");
20456
20457 printf (_(" Entries:\n"));
cc5914eb 20458 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
20459 addr_size * 2, _("Address"),
20460 addr_size * 2, _("Initial"),
20461 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
20462 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20463 for (i = 0; i < count; i++)
20464 {
26c527e6 20465 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 20466
91d6fa6a 20467 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 20468 printf (" ");
e0a31db1 20469
978c4450 20470 if (idx >= filedata->num_dynamic_syms)
26c527e6 20471 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 20472 else
e0a31db1 20473 {
978c4450 20474 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
20475
20476 print_vma (psym->st_value, LONG_HEX);
20477 printf (" %-7s %3s ",
dda8d76d 20478 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 20479 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 20480 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20481 print_symbol_name (sym_width,
84714f86 20482 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20483 else
20484 printf (_("<corrupt: %14ld>"), psym->st_name);
20485 }
861fb55a
DJ
20486 printf ("\n");
20487 }
20488 printf ("\n");
20489
9db70fc3 20490 free (data);
861fb55a
DJ
20491 free (rels);
20492 }
20493
32ec8896 20494 return res;
252b5132
RH
20495}
20496
015dc7e1 20497static bool
dda8d76d 20498process_nds32_specific (Filedata * filedata)
35c08157
KLC
20499{
20500 Elf_Internal_Shdr *sect = NULL;
20501
dda8d76d 20502 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 20503 if (sect != NULL && sect->sh_size >= 4)
35c08157 20504 {
9c7b8e9b
AM
20505 unsigned char *buf;
20506 unsigned int flag;
35c08157
KLC
20507
20508 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
20509 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20510 _("NDS32 elf flags section"));
35c08157 20511
9c7b8e9b 20512 if (buf == NULL)
015dc7e1 20513 return false;
32ec8896 20514
9c7b8e9b
AM
20515 flag = byte_get (buf, 4);
20516 free (buf);
20517 switch (flag & 0x3)
35c08157
KLC
20518 {
20519 case 0:
20520 printf ("(VEC_SIZE):\tNo entry.\n");
20521 break;
20522 case 1:
20523 printf ("(VEC_SIZE):\t4 bytes\n");
20524 break;
20525 case 2:
20526 printf ("(VEC_SIZE):\t16 bytes\n");
20527 break;
20528 case 3:
20529 printf ("(VEC_SIZE):\treserved\n");
20530 break;
20531 }
20532 }
20533
015dc7e1 20534 return true;
35c08157
KLC
20535}
20536
015dc7e1 20537static bool
dda8d76d 20538process_gnu_liblist (Filedata * filedata)
047b2264 20539{
2cf0635d
NC
20540 Elf_Internal_Shdr * section;
20541 Elf_Internal_Shdr * string_sec;
20542 Elf32_External_Lib * elib;
20543 char * strtab;
c256ffe7 20544 size_t strtab_size;
047b2264 20545 size_t cnt;
26c527e6 20546 uint64_t num_liblist;
047b2264 20547 unsigned i;
015dc7e1 20548 bool res = true;
047b2264
JJ
20549
20550 if (! do_arch)
015dc7e1 20551 return true;
047b2264 20552
dda8d76d
NC
20553 for (i = 0, section = filedata->section_headers;
20554 i < filedata->file_header.e_shnum;
b34976b6 20555 i++, section++)
047b2264
JJ
20556 {
20557 switch (section->sh_type)
20558 {
20559 case SHT_GNU_LIBLIST:
dda8d76d 20560 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20561 break;
20562
3f5e193b 20563 elib = (Elf32_External_Lib *)
dda8d76d 20564 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20565 _("liblist section data"));
047b2264
JJ
20566
20567 if (elib == NULL)
32ec8896 20568 {
015dc7e1 20569 res = false;
32ec8896
NC
20570 break;
20571 }
047b2264 20572
dda8d76d
NC
20573 string_sec = filedata->section_headers + section->sh_link;
20574 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20575 string_sec->sh_size,
20576 _("liblist string table"));
047b2264
JJ
20577 if (strtab == NULL
20578 || section->sh_entsize != sizeof (Elf32_External_Lib))
20579 {
20580 free (elib);
2842702f 20581 free (strtab);
015dc7e1 20582 res = false;
047b2264
JJ
20583 break;
20584 }
59245841 20585 strtab_size = string_sec->sh_size;
047b2264 20586
d3a49aa8 20587 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20588 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20589 " entries:\n",
20590 "\nLibrary list section '%s' contains %" PRIu64
20591 " entries:\n",
d3a49aa8 20592 num_liblist),
dda8d76d 20593 printable_section_name (filedata, section),
d3a49aa8 20594 num_liblist);
047b2264 20595
2b692964 20596 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20597
20598 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20599 ++cnt)
20600 {
20601 Elf32_Lib liblist;
91d6fa6a 20602 time_t atime;
d5b07ef4 20603 char timebuf[128];
2cf0635d 20604 struct tm * tmp;
047b2264
JJ
20605
20606 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20607 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20608 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20609 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20610 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20611
91d6fa6a 20612 tmp = gmtime (&atime);
e9e44622
JJ
20613 snprintf (timebuf, sizeof (timebuf),
20614 "%04u-%02u-%02uT%02u:%02u:%02u",
20615 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20616 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20617
26c527e6 20618 printf ("%3zu: ", cnt);
047b2264 20619 if (do_wide)
c256ffe7 20620 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20621 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20622 else
c256ffe7 20623 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20624 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20625 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20626 liblist.l_version, liblist.l_flags);
20627 }
20628
20629 free (elib);
2842702f 20630 free (strtab);
047b2264
JJ
20631 }
20632 }
20633
32ec8896 20634 return res;
047b2264
JJ
20635}
20636
9437c45b 20637static const char *
dda8d76d 20638get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20639{
20640 static char buff[64];
103f02d3 20641
dda8d76d 20642 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20643 switch (e_type)
20644 {
57346661 20645 case NT_AUXV:
1ec5cd37 20646 return _("NT_AUXV (auxiliary vector)");
57346661 20647 case NT_PRSTATUS:
1ec5cd37 20648 return _("NT_PRSTATUS (prstatus structure)");
57346661 20649 case NT_FPREGSET:
1ec5cd37 20650 return _("NT_FPREGSET (floating point registers)");
57346661 20651 case NT_PRPSINFO:
1ec5cd37 20652 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20653 case NT_TASKSTRUCT:
1ec5cd37 20654 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20655 case NT_GDB_TDESC:
20656 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20657 case NT_PRXFPREG:
1ec5cd37 20658 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20659 case NT_PPC_VMX:
20660 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20661 case NT_PPC_VSX:
20662 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20663 case NT_PPC_TAR:
20664 return _("NT_PPC_TAR (ppc TAR register)");
20665 case NT_PPC_PPR:
20666 return _("NT_PPC_PPR (ppc PPR register)");
20667 case NT_PPC_DSCR:
20668 return _("NT_PPC_DSCR (ppc DSCR register)");
20669 case NT_PPC_EBB:
20670 return _("NT_PPC_EBB (ppc EBB registers)");
20671 case NT_PPC_PMU:
20672 return _("NT_PPC_PMU (ppc PMU registers)");
20673 case NT_PPC_TM_CGPR:
20674 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20675 case NT_PPC_TM_CFPR:
20676 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20677 case NT_PPC_TM_CVMX:
20678 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20679 case NT_PPC_TM_CVSX:
3fd21718 20680 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20681 case NT_PPC_TM_SPR:
20682 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20683 case NT_PPC_TM_CTAR:
20684 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20685 case NT_PPC_TM_CPPR:
20686 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20687 case NT_PPC_TM_CDSCR:
20688 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20689 case NT_386_TLS:
20690 return _("NT_386_TLS (x86 TLS information)");
20691 case NT_386_IOPERM:
20692 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20693 case NT_X86_XSTATE:
20694 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20695 case NT_X86_CET:
20696 return _("NT_X86_CET (x86 CET state)");
eccdc733
SC
20697 case NT_X86_SHSTK:
20698 return _("NT_X86_SHSTK (x86 SHSTK state)");
0675e188
UW
20699 case NT_S390_HIGH_GPRS:
20700 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20701 case NT_S390_TIMER:
20702 return _("NT_S390_TIMER (s390 timer register)");
20703 case NT_S390_TODCMP:
20704 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20705 case NT_S390_TODPREG:
20706 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20707 case NT_S390_CTRS:
20708 return _("NT_S390_CTRS (s390 control registers)");
20709 case NT_S390_PREFIX:
20710 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20711 case NT_S390_LAST_BREAK:
20712 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20713 case NT_S390_SYSTEM_CALL:
20714 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20715 case NT_S390_TDB:
20716 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20717 case NT_S390_VXRS_LOW:
20718 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20719 case NT_S390_VXRS_HIGH:
20720 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20721 case NT_S390_GS_CB:
20722 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20723 case NT_S390_GS_BC:
20724 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20725 case NT_ARM_VFP:
20726 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20727 case NT_ARM_TLS:
20728 return _("NT_ARM_TLS (AArch TLS registers)");
20729 case NT_ARM_HW_BREAK:
20730 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20731 case NT_ARM_HW_WATCH:
20732 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20733 case NT_ARM_SYSTEM_CALL:
20734 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20735 case NT_ARM_SVE:
20736 return _("NT_ARM_SVE (AArch SVE registers)");
20737 case NT_ARM_PAC_MASK:
20738 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20739 case NT_ARM_PACA_KEYS:
20740 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20741 case NT_ARM_PACG_KEYS:
20742 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20743 case NT_ARM_TAGGED_ADDR_CTRL:
20744 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20745 case NT_ARM_SSVE:
20746 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20747 case NT_ARM_ZA:
20748 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20749 case NT_ARM_ZT:
20750 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20751 case NT_ARM_PAC_ENABLED_KEYS:
20752 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20753 case NT_ARC_V2:
20754 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20755 case NT_RISCV_CSR:
20756 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20757 case NT_PSTATUS:
1ec5cd37 20758 return _("NT_PSTATUS (pstatus structure)");
57346661 20759 case NT_FPREGS:
1ec5cd37 20760 return _("NT_FPREGS (floating point registers)");
57346661 20761 case NT_PSINFO:
1ec5cd37 20762 return _("NT_PSINFO (psinfo structure)");
57346661 20763 case NT_LWPSTATUS:
1ec5cd37 20764 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20765 case NT_LWPSINFO:
1ec5cd37 20766 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20767 case NT_WIN32PSTATUS:
1ec5cd37 20768 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20769 case NT_SIGINFO:
20770 return _("NT_SIGINFO (siginfo_t data)");
20771 case NT_FILE:
20772 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20773 default:
20774 break;
20775 }
20776 else
20777 switch (e_type)
20778 {
20779 case NT_VERSION:
20780 return _("NT_VERSION (version)");
20781 case NT_ARCH:
20782 return _("NT_ARCH (architecture)");
9ef920e9 20783 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20784 return _("OPEN");
9ef920e9 20785 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20786 return _("func");
c8795e1f
NC
20787 case NT_GO_BUILDID:
20788 return _("GO BUILDID");
3ac925fc
LB
20789 case FDO_PACKAGING_METADATA:
20790 return _("FDO_PACKAGING_METADATA");
762910fb
LB
20791 case FDO_DLOPEN_METADATA:
20792 return _("FDO_DLOPEN_METADATA");
1ec5cd37
NC
20793 default:
20794 break;
20795 }
20796
e9e44622 20797 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20798 return buff;
779fe533
NC
20799}
20800
015dc7e1 20801static bool
9ece1fa9
TT
20802print_core_note (Elf_Internal_Note *pnote)
20803{
20804 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20805 uint64_t count, page_size;
9ece1fa9
TT
20806 unsigned char *descdata, *filenames, *descend;
20807
20808 if (pnote->type != NT_FILE)
04ac15ab
AS
20809 {
20810 if (do_wide)
20811 printf ("\n");
015dc7e1 20812 return true;
04ac15ab 20813 }
9ece1fa9 20814
9ece1fa9
TT
20815 if (pnote->descsz < 2 * addr_size)
20816 {
32ec8896 20817 error (_(" Malformed note - too short for header\n"));
015dc7e1 20818 return false;
9ece1fa9
TT
20819 }
20820
20821 descdata = (unsigned char *) pnote->descdata;
20822 descend = descdata + pnote->descsz;
20823
20824 if (descdata[pnote->descsz - 1] != '\0')
20825 {
32ec8896 20826 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20827 return false;
9ece1fa9
TT
20828 }
20829
20830 count = byte_get (descdata, addr_size);
20831 descdata += addr_size;
20832
20833 page_size = byte_get (descdata, addr_size);
20834 descdata += addr_size;
20835
625d49fc 20836 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20837 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20838 {
32ec8896 20839 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20840 return false;
9ece1fa9
TT
20841 }
20842
20843 printf (_(" Page size: "));
20844 print_vma (page_size, DEC);
20845 printf ("\n");
20846
20847 printf (_(" %*s%*s%*s\n"),
20848 (int) (2 + 2 * addr_size), _("Start"),
20849 (int) (4 + 2 * addr_size), _("End"),
20850 (int) (4 + 2 * addr_size), _("Page Offset"));
20851 filenames = descdata + count * 3 * addr_size;
595712bb 20852 while (count-- > 0)
9ece1fa9 20853 {
625d49fc 20854 uint64_t start, end, file_ofs;
9ece1fa9
TT
20855
20856 if (filenames == descend)
20857 {
32ec8896 20858 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20859 return false;
9ece1fa9
TT
20860 }
20861
20862 start = byte_get (descdata, addr_size);
20863 descdata += addr_size;
20864 end = byte_get (descdata, addr_size);
20865 descdata += addr_size;
20866 file_ofs = byte_get (descdata, addr_size);
20867 descdata += addr_size;
20868
20869 printf (" ");
20870 print_vma (start, FULL_HEX);
20871 printf (" ");
20872 print_vma (end, FULL_HEX);
20873 printf (" ");
20874 print_vma (file_ofs, FULL_HEX);
20875 printf ("\n %s\n", filenames);
20876
20877 filenames += 1 + strlen ((char *) filenames);
20878 }
20879
015dc7e1 20880 return true;
9ece1fa9
TT
20881}
20882
1118d252
RM
20883static const char *
20884get_gnu_elf_note_type (unsigned e_type)
20885{
1449284b 20886 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20887 switch (e_type)
20888 {
20889 case NT_GNU_ABI_TAG:
20890 return _("NT_GNU_ABI_TAG (ABI version tag)");
20891 case NT_GNU_HWCAP:
20892 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20893 case NT_GNU_BUILD_ID:
20894 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20895 case NT_GNU_GOLD_VERSION:
20896 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20897 case NT_GNU_PROPERTY_TYPE_0:
20898 return _("NT_GNU_PROPERTY_TYPE_0");
20899 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20900 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20901 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20902 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20903 default:
1449284b
NC
20904 {
20905 static char buff[64];
1118d252 20906
1449284b
NC
20907 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20908 return buff;
20909 }
20910 }
1118d252
RM
20911}
20912
a9eafb08
L
20913static void
20914decode_x86_compat_isa (unsigned int bitmask)
20915{
20916 while (bitmask)
20917 {
20918 unsigned int bit = bitmask & (- bitmask);
20919
20920 bitmask &= ~ bit;
20921 switch (bit)
20922 {
20923 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20924 printf ("i486");
20925 break;
20926 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20927 printf ("586");
20928 break;
20929 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20930 printf ("686");
20931 break;
20932 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20933 printf ("SSE");
20934 break;
20935 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20936 printf ("SSE2");
20937 break;
20938 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20939 printf ("SSE3");
20940 break;
20941 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20942 printf ("SSSE3");
20943 break;
20944 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20945 printf ("SSE4_1");
20946 break;
20947 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20948 printf ("SSE4_2");
20949 break;
20950 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20951 printf ("AVX");
20952 break;
20953 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20954 printf ("AVX2");
20955 break;
20956 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20957 printf ("AVX512F");
20958 break;
20959 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20960 printf ("AVX512CD");
20961 break;
20962 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20963 printf ("AVX512ER");
20964 break;
20965 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20966 printf ("AVX512PF");
20967 break;
20968 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20969 printf ("AVX512VL");
20970 break;
20971 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20972 printf ("AVX512DQ");
20973 break;
20974 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20975 printf ("AVX512BW");
20976 break;
65b3d26e
L
20977 default:
20978 printf (_("<unknown: %x>"), bit);
20979 break;
a9eafb08
L
20980 }
20981 if (bitmask)
20982 printf (", ");
20983 }
20984}
20985
9ef920e9 20986static void
32930e4e 20987decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20988{
0a59decb 20989 if (!bitmask)
90c745dc
L
20990 {
20991 printf (_("<None>"));
20992 return;
20993 }
90c745dc 20994
9ef920e9
NC
20995 while (bitmask)
20996 {
1fc87489 20997 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20998
20999 bitmask &= ~ bit;
21000 switch (bit)
21001 {
32930e4e 21002 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
21003 printf ("CMOV");
21004 break;
32930e4e 21005 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
21006 printf ("SSE");
21007 break;
32930e4e 21008 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
21009 printf ("SSE2");
21010 break;
32930e4e 21011 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
21012 printf ("SSE3");
21013 break;
32930e4e 21014 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
21015 printf ("SSSE3");
21016 break;
32930e4e 21017 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
21018 printf ("SSE4_1");
21019 break;
32930e4e 21020 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
21021 printf ("SSE4_2");
21022 break;
32930e4e 21023 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
21024 printf ("AVX");
21025 break;
32930e4e 21026 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
21027 printf ("AVX2");
21028 break;
32930e4e 21029 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
21030 printf ("FMA");
21031 break;
32930e4e 21032 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
21033 printf ("AVX512F");
21034 break;
32930e4e 21035 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
21036 printf ("AVX512CD");
21037 break;
32930e4e 21038 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
21039 printf ("AVX512ER");
21040 break;
32930e4e 21041 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
21042 printf ("AVX512PF");
21043 break;
32930e4e 21044 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
21045 printf ("AVX512VL");
21046 break;
32930e4e 21047 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
21048 printf ("AVX512DQ");
21049 break;
32930e4e 21050 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
21051 printf ("AVX512BW");
21052 break;
32930e4e 21053 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
21054 printf ("AVX512_4FMAPS");
21055 break;
32930e4e 21056 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
21057 printf ("AVX512_4VNNIW");
21058 break;
32930e4e 21059 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
21060 printf ("AVX512_BITALG");
21061 break;
32930e4e 21062 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
21063 printf ("AVX512_IFMA");
21064 break;
32930e4e 21065 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
21066 printf ("AVX512_VBMI");
21067 break;
32930e4e 21068 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
21069 printf ("AVX512_VBMI2");
21070 break;
32930e4e 21071 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
21072 printf ("AVX512_VNNI");
21073 break;
32930e4e 21074 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
21075 printf ("AVX512_BF16");
21076 break;
65b3d26e
L
21077 default:
21078 printf (_("<unknown: %x>"), bit);
21079 break;
9ef920e9
NC
21080 }
21081 if (bitmask)
21082 printf (", ");
21083 }
21084}
21085
28cdbb18
SM
21086static const char *
21087get_amdgpu_elf_note_type (unsigned int e_type)
21088{
21089 switch (e_type)
21090 {
21091 case NT_AMDGPU_METADATA:
21092 return _("NT_AMDGPU_METADATA (code object metadata)");
21093 default:
21094 {
21095 static char buf[64];
21096 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
21097 return buf;
21098 }
21099 }
21100}
21101
32930e4e
L
21102static void
21103decode_x86_isa (unsigned int bitmask)
21104{
32930e4e
L
21105 while (bitmask)
21106 {
21107 unsigned int bit = bitmask & (- bitmask);
21108
21109 bitmask &= ~ bit;
21110 switch (bit)
21111 {
b0ab0693
L
21112 case GNU_PROPERTY_X86_ISA_1_BASELINE:
21113 printf ("x86-64-baseline");
21114 break;
32930e4e
L
21115 case GNU_PROPERTY_X86_ISA_1_V2:
21116 printf ("x86-64-v2");
21117 break;
21118 case GNU_PROPERTY_X86_ISA_1_V3:
21119 printf ("x86-64-v3");
21120 break;
21121 case GNU_PROPERTY_X86_ISA_1_V4:
21122 printf ("x86-64-v4");
21123 break;
21124 default:
21125 printf (_("<unknown: %x>"), bit);
21126 break;
21127 }
21128 if (bitmask)
21129 printf (", ");
21130 }
21131}
21132
ee2fdd6f 21133static void
a9eafb08 21134decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 21135{
0a59decb 21136 if (!bitmask)
90c745dc
L
21137 {
21138 printf (_("<None>"));
21139 return;
21140 }
90c745dc 21141
ee2fdd6f
L
21142 while (bitmask)
21143 {
21144 unsigned int bit = bitmask & (- bitmask);
21145
21146 bitmask &= ~ bit;
21147 switch (bit)
21148 {
21149 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 21150 printf ("IBT");
ee2fdd6f 21151 break;
48580982 21152 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 21153 printf ("SHSTK");
48580982 21154 break;
279d901e
L
21155 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
21156 printf ("LAM_U48");
21157 break;
21158 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
21159 printf ("LAM_U57");
21160 break;
ee2fdd6f
L
21161 default:
21162 printf (_("<unknown: %x>"), bit);
21163 break;
21164 }
21165 if (bitmask)
21166 printf (", ");
21167 }
21168}
21169
a9eafb08
L
21170static void
21171decode_x86_feature_2 (unsigned int bitmask)
21172{
0a59decb 21173 if (!bitmask)
90c745dc
L
21174 {
21175 printf (_("<None>"));
21176 return;
21177 }
90c745dc 21178
a9eafb08
L
21179 while (bitmask)
21180 {
21181 unsigned int bit = bitmask & (- bitmask);
21182
21183 bitmask &= ~ bit;
21184 switch (bit)
21185 {
21186 case GNU_PROPERTY_X86_FEATURE_2_X86:
21187 printf ("x86");
21188 break;
21189 case GNU_PROPERTY_X86_FEATURE_2_X87:
21190 printf ("x87");
21191 break;
21192 case GNU_PROPERTY_X86_FEATURE_2_MMX:
21193 printf ("MMX");
21194 break;
21195 case GNU_PROPERTY_X86_FEATURE_2_XMM:
21196 printf ("XMM");
21197 break;
21198 case GNU_PROPERTY_X86_FEATURE_2_YMM:
21199 printf ("YMM");
21200 break;
21201 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
21202 printf ("ZMM");
21203 break;
a308b89d
L
21204 case GNU_PROPERTY_X86_FEATURE_2_TMM:
21205 printf ("TMM");
21206 break;
32930e4e
L
21207 case GNU_PROPERTY_X86_FEATURE_2_MASK:
21208 printf ("MASK");
21209 break;
a9eafb08
L
21210 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
21211 printf ("FXSR");
21212 break;
21213 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
21214 printf ("XSAVE");
21215 break;
21216 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
21217 printf ("XSAVEOPT");
21218 break;
21219 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
21220 printf ("XSAVEC");
21221 break;
65b3d26e
L
21222 default:
21223 printf (_("<unknown: %x>"), bit);
21224 break;
a9eafb08
L
21225 }
21226 if (bitmask)
21227 printf (", ");
21228 }
21229}
21230
cd702818
SD
21231static void
21232decode_aarch64_feature_1_and (unsigned int bitmask)
21233{
21234 while (bitmask)
21235 {
21236 unsigned int bit = bitmask & (- bitmask);
21237
21238 bitmask &= ~ bit;
21239 switch (bit)
21240 {
21241 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
21242 printf ("BTI");
21243 break;
21244
21245 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
21246 printf ("PAC");
21247 break;
21248
21249 default:
21250 printf (_("<unknown: %x>"), bit);
21251 break;
21252 }
21253 if (bitmask)
21254 printf (", ");
21255 }
21256}
21257
6320fd00
L
21258static void
21259decode_1_needed (unsigned int bitmask)
21260{
21261 while (bitmask)
21262 {
21263 unsigned int bit = bitmask & (- bitmask);
21264
21265 bitmask &= ~ bit;
21266 switch (bit)
21267 {
21268 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
21269 printf ("indirect external access");
21270 break;
21271 default:
21272 printf (_("<unknown: %x>"), bit);
21273 break;
21274 }
21275 if (bitmask)
21276 printf (", ");
21277 }
21278}
21279
9ef920e9 21280static void
dda8d76d 21281print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
21282{
21283 unsigned char * ptr = (unsigned char *) pnote->descdata;
21284 unsigned char * ptr_end = ptr + pnote->descsz;
21285 unsigned int size = is_32bit_elf ? 4 : 8;
21286
21287 printf (_(" Properties: "));
21288
1fc87489 21289 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
21290 {
21291 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21292 return;
21293 }
21294
6ab2c4ed 21295 while (ptr < ptr_end)
9ef920e9 21296 {
1fc87489 21297 unsigned int j;
6ab2c4ed
MC
21298 unsigned int type;
21299 unsigned int datasz;
21300
21301 if ((size_t) (ptr_end - ptr) < 8)
21302 {
21303 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21304 break;
21305 }
21306
21307 type = byte_get (ptr, 4);
21308 datasz = byte_get (ptr + 4, 4);
9ef920e9 21309
1fc87489 21310 ptr += 8;
9ef920e9 21311
6ab2c4ed 21312 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 21313 {
1fc87489
L
21314 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21315 type, datasz);
9ef920e9 21316 break;
1fc87489 21317 }
9ef920e9 21318
1fc87489
L
21319 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21320 {
dda8d76d
NC
21321 if (filedata->file_header.e_machine == EM_X86_64
21322 || filedata->file_header.e_machine == EM_IAMCU
21323 || filedata->file_header.e_machine == EM_386)
1fc87489 21324 {
aa7bca9b
L
21325 unsigned int bitmask;
21326
21327 if (datasz == 4)
0a59decb 21328 bitmask = byte_get (ptr, 4);
aa7bca9b
L
21329 else
21330 bitmask = 0;
21331
1fc87489
L
21332 switch (type)
21333 {
21334 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 21335 if (datasz != 4)
aa7bca9b
L
21336 printf (_("x86 ISA used: <corrupt length: %#x> "),
21337 datasz);
1fc87489 21338 else
aa7bca9b
L
21339 {
21340 printf ("x86 ISA used: ");
21341 decode_x86_isa (bitmask);
21342 }
1fc87489 21343 goto next;
9ef920e9 21344
1fc87489 21345 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 21346 if (datasz != 4)
aa7bca9b
L
21347 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21348 datasz);
1fc87489 21349 else
aa7bca9b
L
21350 {
21351 printf ("x86 ISA needed: ");
21352 decode_x86_isa (bitmask);
21353 }
1fc87489 21354 goto next;
9ef920e9 21355
ee2fdd6f 21356 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 21357 if (datasz != 4)
aa7bca9b
L
21358 printf (_("x86 feature: <corrupt length: %#x> "),
21359 datasz);
ee2fdd6f 21360 else
aa7bca9b
L
21361 {
21362 printf ("x86 feature: ");
a9eafb08
L
21363 decode_x86_feature_1 (bitmask);
21364 }
21365 goto next;
21366
21367 case GNU_PROPERTY_X86_FEATURE_2_USED:
21368 if (datasz != 4)
21369 printf (_("x86 feature used: <corrupt length: %#x> "),
21370 datasz);
21371 else
21372 {
21373 printf ("x86 feature used: ");
21374 decode_x86_feature_2 (bitmask);
21375 }
21376 goto next;
21377
21378 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21379 if (datasz != 4)
21380 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21381 else
21382 {
21383 printf ("x86 feature needed: ");
21384 decode_x86_feature_2 (bitmask);
21385 }
21386 goto next;
21387
21388 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21389 if (datasz != 4)
21390 printf (_("x86 ISA used: <corrupt length: %#x> "),
21391 datasz);
21392 else
21393 {
21394 printf ("x86 ISA used: ");
21395 decode_x86_compat_isa (bitmask);
21396 }
21397 goto next;
21398
21399 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21400 if (datasz != 4)
21401 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21402 datasz);
21403 else
21404 {
21405 printf ("x86 ISA needed: ");
21406 decode_x86_compat_isa (bitmask);
aa7bca9b 21407 }
ee2fdd6f
L
21408 goto next;
21409
32930e4e
L
21410 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21411 if (datasz != 4)
21412 printf (_("x86 ISA used: <corrupt length: %#x> "),
21413 datasz);
21414 else
21415 {
21416 printf ("x86 ISA used: ");
21417 decode_x86_compat_2_isa (bitmask);
21418 }
21419 goto next;
21420
21421 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21422 if (datasz != 4)
21423 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21424 datasz);
21425 else
21426 {
21427 printf ("x86 ISA needed: ");
21428 decode_x86_compat_2_isa (bitmask);
21429 }
21430 goto next;
21431
1fc87489
L
21432 default:
21433 break;
21434 }
21435 }
cd702818
SD
21436 else if (filedata->file_header.e_machine == EM_AARCH64)
21437 {
21438 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21439 {
21440 printf ("AArch64 feature: ");
21441 if (datasz != 4)
21442 printf (_("<corrupt length: %#x> "), datasz);
21443 else
21444 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21445 goto next;
21446 }
21447 }
1fc87489
L
21448 }
21449 else
21450 {
21451 switch (type)
9ef920e9 21452 {
1fc87489
L
21453 case GNU_PROPERTY_STACK_SIZE:
21454 printf (_("stack size: "));
21455 if (datasz != size)
21456 printf (_("<corrupt length: %#x> "), datasz);
21457 else
26c527e6 21458 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
21459 goto next;
21460
21461 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21462 printf ("no copy on protected ");
21463 if (datasz)
21464 printf (_("<corrupt length: %#x> "), datasz);
21465 goto next;
21466
21467 default:
5a767724
L
21468 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21469 && type <= GNU_PROPERTY_UINT32_AND_HI)
21470 || (type >= GNU_PROPERTY_UINT32_OR_LO
21471 && type <= GNU_PROPERTY_UINT32_OR_HI))
21472 {
6320fd00
L
21473 switch (type)
21474 {
21475 case GNU_PROPERTY_1_NEEDED:
21476 if (datasz != 4)
21477 printf (_("1_needed: <corrupt length: %#x> "),
21478 datasz);
21479 else
21480 {
21481 unsigned int bitmask = byte_get (ptr, 4);
21482 printf ("1_needed: ");
21483 decode_1_needed (bitmask);
21484 }
21485 goto next;
21486
21487 default:
21488 break;
21489 }
5a767724
L
21490 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21491 printf (_("UINT32_AND (%#x): "), type);
21492 else
21493 printf (_("UINT32_OR (%#x): "), type);
21494 if (datasz != 4)
21495 printf (_("<corrupt length: %#x> "), datasz);
21496 else
21497 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21498 goto next;
21499 }
9ef920e9
NC
21500 break;
21501 }
9ef920e9
NC
21502 }
21503
1fc87489
L
21504 if (type < GNU_PROPERTY_LOPROC)
21505 printf (_("<unknown type %#x data: "), type);
21506 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 21507 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
21508 else
21509 printf (_("<application-specific type %#x data: "), type);
21510 for (j = 0; j < datasz; ++j)
21511 printf ("%02x ", ptr[j] & 0xff);
21512 printf (">");
21513
dc1e8a47 21514 next:
9ef920e9 21515 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
21516 if (ptr == ptr_end)
21517 break;
1fc87489 21518
6ab2c4ed
MC
21519 if (do_wide)
21520 printf (", ");
21521 else
21522 printf ("\n\t");
9ef920e9
NC
21523 }
21524
21525 printf ("\n");
21526}
21527
015dc7e1 21528static bool
dda8d76d 21529print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 21530{
1449284b 21531 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
21532 switch (pnote->type)
21533 {
21534 case NT_GNU_BUILD_ID:
21535 {
26c527e6 21536 size_t i;
664f90a3
TT
21537
21538 printf (_(" Build ID: "));
21539 for (i = 0; i < pnote->descsz; ++i)
21540 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 21541 printf ("\n");
664f90a3
TT
21542 }
21543 break;
21544
21545 case NT_GNU_ABI_TAG:
21546 {
26c527e6 21547 unsigned int os, major, minor, subminor;
664f90a3
TT
21548 const char *osname;
21549
3102e897
NC
21550 /* PR 17531: file: 030-599401-0.004. */
21551 if (pnote->descsz < 16)
21552 {
21553 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21554 break;
21555 }
21556
664f90a3
TT
21557 os = byte_get ((unsigned char *) pnote->descdata, 4);
21558 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21559 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21560 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21561
21562 switch (os)
21563 {
21564 case GNU_ABI_TAG_LINUX:
21565 osname = "Linux";
21566 break;
21567 case GNU_ABI_TAG_HURD:
21568 osname = "Hurd";
21569 break;
21570 case GNU_ABI_TAG_SOLARIS:
21571 osname = "Solaris";
21572 break;
21573 case GNU_ABI_TAG_FREEBSD:
21574 osname = "FreeBSD";
21575 break;
21576 case GNU_ABI_TAG_NETBSD:
21577 osname = "NetBSD";
21578 break;
14ae95f2
RM
21579 case GNU_ABI_TAG_SYLLABLE:
21580 osname = "Syllable";
21581 break;
21582 case GNU_ABI_TAG_NACL:
21583 osname = "NaCl";
21584 break;
664f90a3
TT
21585 default:
21586 osname = "Unknown";
21587 break;
21588 }
21589
26c527e6 21590 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21591 major, minor, subminor);
21592 }
21593 break;
926c5385
CC
21594
21595 case NT_GNU_GOLD_VERSION:
21596 {
26c527e6 21597 size_t i;
926c5385
CC
21598
21599 printf (_(" Version: "));
21600 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21601 printf ("%c", pnote->descdata[i]);
21602 printf ("\n");
21603 }
21604 break;
1449284b
NC
21605
21606 case NT_GNU_HWCAP:
21607 {
26c527e6 21608 unsigned int num_entries, mask;
1449284b
NC
21609
21610 /* Hardware capabilities information. Word 0 is the number of entries.
21611 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21612 is a series of entries, where each entry is a single byte followed
21613 by a nul terminated string. The byte gives the bit number to test
21614 if enabled in the bitmask. */
21615 printf (_(" Hardware Capabilities: "));
21616 if (pnote->descsz < 8)
21617 {
32ec8896 21618 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21619 return false;
1449284b
NC
21620 }
21621 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21622 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21623 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21624 /* FIXME: Add code to display the entries... */
21625 }
21626 break;
21627
9ef920e9 21628 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21629 print_gnu_property_note (filedata, pnote);
9ef920e9 21630 break;
9abca702 21631
1449284b
NC
21632 default:
21633 /* Handle unrecognised types. An error message should have already been
21634 created by get_gnu_elf_note_type(), so all that we need to do is to
21635 display the data. */
21636 {
26c527e6 21637 size_t i;
1449284b
NC
21638
21639 printf (_(" Description data: "));
21640 for (i = 0; i < pnote->descsz; ++i)
21641 printf ("%02x ", pnote->descdata[i] & 0xff);
21642 printf ("\n");
21643 }
21644 break;
664f90a3
TT
21645 }
21646
015dc7e1 21647 return true;
664f90a3
TT
21648}
21649
685080f2
NC
21650static const char *
21651get_v850_elf_note_type (enum v850_notes n_type)
21652{
21653 static char buff[64];
21654
21655 switch (n_type)
21656 {
21657 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21658 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21659 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21660 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21661 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21662 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21663 default:
21664 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21665 return buff;
21666 }
21667}
21668
015dc7e1 21669static bool
685080f2
NC
21670print_v850_note (Elf_Internal_Note * pnote)
21671{
21672 unsigned int val;
21673
21674 if (pnote->descsz != 4)
015dc7e1 21675 return false;
32ec8896 21676
685080f2
NC
21677 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21678
21679 if (val == 0)
21680 {
21681 printf (_("not set\n"));
015dc7e1 21682 return true;
685080f2
NC
21683 }
21684
21685 switch (pnote->type)
21686 {
21687 case V850_NOTE_ALIGNMENT:
21688 switch (val)
21689 {
015dc7e1
AM
21690 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21691 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21692 }
21693 break;
14ae95f2 21694
685080f2
NC
21695 case V850_NOTE_DATA_SIZE:
21696 switch (val)
21697 {
015dc7e1
AM
21698 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21699 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21700 }
21701 break;
14ae95f2 21702
685080f2
NC
21703 case V850_NOTE_FPU_INFO:
21704 switch (val)
21705 {
015dc7e1
AM
21706 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21707 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21708 }
21709 break;
14ae95f2 21710
685080f2
NC
21711 case V850_NOTE_MMU_INFO:
21712 case V850_NOTE_CACHE_INFO:
21713 case V850_NOTE_SIMD_INFO:
21714 if (val == EF_RH850_SIMD)
21715 {
21716 printf (_("yes\n"));
015dc7e1 21717 return true;
685080f2
NC
21718 }
21719 break;
21720
21721 default:
21722 /* An 'unknown note type' message will already have been displayed. */
21723 break;
21724 }
21725
21726 printf (_("unknown value: %x\n"), val);
015dc7e1 21727 return false;
685080f2
NC
21728}
21729
015dc7e1 21730static bool
c6056a74
SF
21731process_netbsd_elf_note (Elf_Internal_Note * pnote)
21732{
21733 unsigned int version;
21734
21735 switch (pnote->type)
21736 {
21737 case NT_NETBSD_IDENT:
b966f55f
AM
21738 if (pnote->descsz < 1)
21739 break;
c6056a74
SF
21740 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21741 if ((version / 10000) % 100)
b966f55f 21742 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21743 version, version / 100000000, (version / 1000000) % 100,
21744 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21745 'A' + (version / 10000) % 26);
c6056a74
SF
21746 else
21747 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21748 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21749 (version / 100) % 100);
015dc7e1 21750 return true;
c6056a74
SF
21751
21752 case NT_NETBSD_MARCH:
9abca702 21753 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21754 pnote->descdata);
015dc7e1 21755 return true;
c6056a74 21756
9abca702 21757 case NT_NETBSD_PAX:
b966f55f
AM
21758 if (pnote->descsz < 1)
21759 break;
9abca702
CZ
21760 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21761 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21762 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21763 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21764 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21765 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21766 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21767 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21768 return true;
c6056a74 21769 }
b966f55f
AM
21770
21771 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21772 pnote->descsz, pnote->type);
015dc7e1 21773 return false;
c6056a74
SF
21774}
21775
f4ddf30f 21776static const char *
dda8d76d 21777get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21778{
f4ddf30f
JB
21779 switch (e_type)
21780 {
21781 case NT_FREEBSD_THRMISC:
21782 return _("NT_THRMISC (thrmisc structure)");
21783 case NT_FREEBSD_PROCSTAT_PROC:
21784 return _("NT_PROCSTAT_PROC (proc data)");
21785 case NT_FREEBSD_PROCSTAT_FILES:
21786 return _("NT_PROCSTAT_FILES (files data)");
21787 case NT_FREEBSD_PROCSTAT_VMMAP:
21788 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21789 case NT_FREEBSD_PROCSTAT_GROUPS:
21790 return _("NT_PROCSTAT_GROUPS (groups data)");
21791 case NT_FREEBSD_PROCSTAT_UMASK:
21792 return _("NT_PROCSTAT_UMASK (umask data)");
21793 case NT_FREEBSD_PROCSTAT_RLIMIT:
21794 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21795 case NT_FREEBSD_PROCSTAT_OSREL:
21796 return _("NT_PROCSTAT_OSREL (osreldate data)");
21797 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21798 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21799 case NT_FREEBSD_PROCSTAT_AUXV:
21800 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21801 case NT_FREEBSD_PTLWPINFO:
21802 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21803 case NT_FREEBSD_X86_SEGBASES:
21804 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21805 }
dda8d76d 21806 return get_note_type (filedata, e_type);
f4ddf30f
JB
21807}
21808
9437c45b 21809static const char *
dda8d76d 21810get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21811{
21812 static char buff[64];
21813
540e6170
CZ
21814 switch (e_type)
21815 {
21816 case NT_NETBSDCORE_PROCINFO:
21817 /* NetBSD core "procinfo" structure. */
21818 return _("NetBSD procinfo structure");
9437c45b 21819
540e6170
CZ
21820 case NT_NETBSDCORE_AUXV:
21821 return _("NetBSD ELF auxiliary vector data");
9437c45b 21822
06d949ec
KR
21823 case NT_NETBSDCORE_LWPSTATUS:
21824 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21825
540e6170 21826 default:
06d949ec 21827 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21828 defined for NetBSD core files. If the note type is less
21829 than the start of the machine-dependent note types, we don't
21830 understand it. */
21831
21832 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21833 {
21834 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21835 return buff;
21836 }
21837 break;
9437c45b
JT
21838 }
21839
dda8d76d 21840 switch (filedata->file_header.e_machine)
9437c45b
JT
21841 {
21842 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21843 and PT_GETFPREGS == mach+2. */
21844
21845 case EM_OLD_ALPHA:
21846 case EM_ALPHA:
21847 case EM_SPARC:
21848 case EM_SPARC32PLUS:
21849 case EM_SPARCV9:
21850 switch (e_type)
21851 {
2b692964 21852 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21853 return _("PT_GETREGS (reg structure)");
2b692964 21854 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21855 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21856 default:
21857 break;
21858 }
21859 break;
21860
c0d38b0e
CZ
21861 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21862 There's also old PT___GETREGS40 == mach + 1 for old reg
21863 structure which lacks GBR. */
21864 case EM_SH:
21865 switch (e_type)
21866 {
21867 case NT_NETBSDCORE_FIRSTMACH + 1:
21868 return _("PT___GETREGS40 (old reg structure)");
21869 case NT_NETBSDCORE_FIRSTMACH + 3:
21870 return _("PT_GETREGS (reg structure)");
21871 case NT_NETBSDCORE_FIRSTMACH + 5:
21872 return _("PT_GETFPREGS (fpreg structure)");
21873 default:
21874 break;
21875 }
21876 break;
21877
9437c45b
JT
21878 /* On all other arch's, PT_GETREGS == mach+1 and
21879 PT_GETFPREGS == mach+3. */
21880 default:
21881 switch (e_type)
21882 {
2b692964 21883 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21884 return _("PT_GETREGS (reg structure)");
2b692964 21885 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21886 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21887 default:
21888 break;
21889 }
21890 }
21891
9cf03b7e 21892 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21893 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21894 return buff;
21895}
21896
98ca73af
FC
21897static const char *
21898get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21899{
21900 switch (e_type)
21901 {
21902 case NT_OPENBSD_PROCINFO:
21903 return _("OpenBSD procinfo structure");
21904 case NT_OPENBSD_AUXV:
21905 return _("OpenBSD ELF auxiliary vector data");
21906 case NT_OPENBSD_REGS:
21907 return _("OpenBSD regular registers");
21908 case NT_OPENBSD_FPREGS:
21909 return _("OpenBSD floating point registers");
21910 case NT_OPENBSD_WCOOKIE:
21911 return _("OpenBSD window cookie");
21912 }
21913
21914 return get_note_type (filedata, e_type);
21915}
21916
e263a66b
CC
21917static const char *
21918get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21919{
21920 switch (e_type)
21921 {
21922 case QNT_DEBUG_FULLPATH:
21923 return _("QNX debug fullpath");
21924 case QNT_DEBUG_RELOC:
21925 return _("QNX debug relocation");
21926 case QNT_STACK:
21927 return _("QNX stack");
21928 case QNT_GENERATOR:
21929 return _("QNX generator");
21930 case QNT_DEFAULT_LIB:
21931 return _("QNX default library");
21932 case QNT_CORE_SYSINFO:
21933 return _("QNX core sysinfo");
21934 case QNT_CORE_INFO:
21935 return _("QNX core info");
21936 case QNT_CORE_STATUS:
21937 return _("QNX core status");
21938 case QNT_CORE_GREG:
21939 return _("QNX general registers");
21940 case QNT_CORE_FPREG:
21941 return _("QNX floating point registers");
21942 case QNT_LINK_MAP:
21943 return _("QNX link map");
21944 }
21945
21946 return get_note_type (filedata, e_type);
21947}
21948
70616151
TT
21949static const char *
21950get_stapsdt_note_type (unsigned e_type)
21951{
21952 static char buff[64];
21953
21954 switch (e_type)
21955 {
21956 case NT_STAPSDT:
21957 return _("NT_STAPSDT (SystemTap probe descriptors)");
21958
21959 default:
21960 break;
21961 }
21962
21963 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21964 return buff;
21965}
21966
015dc7e1 21967static bool
c6a9fc58
TT
21968print_stapsdt_note (Elf_Internal_Note *pnote)
21969{
3ca60c57 21970 size_t len, maxlen;
26c527e6 21971 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21972 char *data = pnote->descdata;
21973 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21974 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21975 char *provider, *probe, *arg_fmt;
21976
3ca60c57
NC
21977 if (pnote->descsz < (addr_size * 3))
21978 goto stapdt_note_too_small;
21979
c6a9fc58
TT
21980 pc = byte_get ((unsigned char *) data, addr_size);
21981 data += addr_size;
3ca60c57 21982
c6a9fc58
TT
21983 base_addr = byte_get ((unsigned char *) data, addr_size);
21984 data += addr_size;
3ca60c57 21985
c6a9fc58
TT
21986 semaphore = byte_get ((unsigned char *) data, addr_size);
21987 data += addr_size;
21988
3ca60c57
NC
21989 if (data >= data_end)
21990 goto stapdt_note_too_small;
21991 maxlen = data_end - data;
21992 len = strnlen (data, maxlen);
21993 if (len < maxlen)
21994 {
21995 provider = data;
21996 data += len + 1;
21997 }
21998 else
21999 goto stapdt_note_too_small;
22000
22001 if (data >= data_end)
22002 goto stapdt_note_too_small;
22003 maxlen = data_end - data;
22004 len = strnlen (data, maxlen);
22005 if (len < maxlen)
22006 {
22007 probe = data;
22008 data += len + 1;
22009 }
22010 else
22011 goto stapdt_note_too_small;
9abca702 22012
3ca60c57
NC
22013 if (data >= data_end)
22014 goto stapdt_note_too_small;
22015 maxlen = data_end - data;
22016 len = strnlen (data, maxlen);
22017 if (len < maxlen)
22018 {
22019 arg_fmt = data;
22020 data += len + 1;
22021 }
22022 else
22023 goto stapdt_note_too_small;
c6a9fc58
TT
22024
22025 printf (_(" Provider: %s\n"), provider);
22026 printf (_(" Name: %s\n"), probe);
22027 printf (_(" Location: "));
22028 print_vma (pc, FULL_HEX);
22029 printf (_(", Base: "));
22030 print_vma (base_addr, FULL_HEX);
22031 printf (_(", Semaphore: "));
22032 print_vma (semaphore, FULL_HEX);
9cf03b7e 22033 printf ("\n");
c6a9fc58
TT
22034 printf (_(" Arguments: %s\n"), arg_fmt);
22035
22036 return data == data_end;
3ca60c57
NC
22037
22038 stapdt_note_too_small:
22039 printf (_(" <corrupt - note is too small>\n"));
22040 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 22041 return false;
c6a9fc58
TT
22042}
22043
e5382207
LB
22044static bool
22045print_fdo_note (Elf_Internal_Note * pnote)
22046{
22047 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
22048 {
22049 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22050 return true;
22051 }
762910fb
LB
22052 if (pnote->descsz > 0 && pnote->type == FDO_DLOPEN_METADATA)
22053 {
22054 printf (_(" Dlopen Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22055 return true;
22056 }
e5382207
LB
22057 return false;
22058}
22059
00e98fc7
TG
22060static const char *
22061get_ia64_vms_note_type (unsigned e_type)
22062{
22063 static char buff[64];
22064
22065 switch (e_type)
22066 {
22067 case NT_VMS_MHD:
22068 return _("NT_VMS_MHD (module header)");
22069 case NT_VMS_LNM:
22070 return _("NT_VMS_LNM (language name)");
22071 case NT_VMS_SRC:
22072 return _("NT_VMS_SRC (source files)");
22073 case NT_VMS_TITLE:
9cf03b7e 22074 return "NT_VMS_TITLE";
00e98fc7
TG
22075 case NT_VMS_EIDC:
22076 return _("NT_VMS_EIDC (consistency check)");
22077 case NT_VMS_FPMODE:
22078 return _("NT_VMS_FPMODE (FP mode)");
22079 case NT_VMS_LINKTIME:
9cf03b7e 22080 return "NT_VMS_LINKTIME";
00e98fc7
TG
22081 case NT_VMS_IMGNAM:
22082 return _("NT_VMS_IMGNAM (image name)");
22083 case NT_VMS_IMGID:
22084 return _("NT_VMS_IMGID (image id)");
22085 case NT_VMS_LINKID:
22086 return _("NT_VMS_LINKID (link id)");
22087 case NT_VMS_IMGBID:
22088 return _("NT_VMS_IMGBID (build id)");
22089 case NT_VMS_GSTNAM:
22090 return _("NT_VMS_GSTNAM (sym table name)");
22091 case NT_VMS_ORIG_DYN:
9cf03b7e 22092 return "NT_VMS_ORIG_DYN";
00e98fc7 22093 case NT_VMS_PATCHTIME:
9cf03b7e 22094 return "NT_VMS_PATCHTIME";
00e98fc7
TG
22095 default:
22096 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22097 return buff;
22098 }
22099}
22100
015dc7e1 22101static bool
00e98fc7
TG
22102print_ia64_vms_note (Elf_Internal_Note * pnote)
22103{
26c527e6 22104 unsigned int maxlen = pnote->descsz;
8d18bf79 22105
26c527e6 22106 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
22107 goto desc_size_fail;
22108
00e98fc7
TG
22109 switch (pnote->type)
22110 {
22111 case NT_VMS_MHD:
8d18bf79
NC
22112 if (maxlen <= 36)
22113 goto desc_size_fail;
22114
26c527e6 22115 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
22116
22117 printf (_(" Creation date : %.17s\n"), pnote->descdata);
22118 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
22119 if (l + 34 < maxlen)
22120 {
22121 printf (_(" Module name : %s\n"), pnote->descdata + 34);
22122 if (l + 35 < maxlen)
22123 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
22124 else
22125 printf (_(" Module version : <missing>\n"));
22126 }
00e98fc7 22127 else
8d18bf79
NC
22128 {
22129 printf (_(" Module name : <missing>\n"));
22130 printf (_(" Module version : <missing>\n"));
22131 }
00e98fc7 22132 break;
8d18bf79 22133
00e98fc7 22134 case NT_VMS_LNM:
8d18bf79 22135 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22136 break;
8d18bf79 22137
00e98fc7 22138 case NT_VMS_FPMODE:
9cf03b7e 22139 printf (_(" Floating Point mode: "));
8d18bf79
NC
22140 if (maxlen < 8)
22141 goto desc_size_fail;
22142 /* FIXME: Generate an error if descsz > 8 ? */
22143
b8281767 22144 printf ("0x%016" PRIx64 "\n",
625d49fc 22145 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 22146 break;
8d18bf79 22147
00e98fc7
TG
22148 case NT_VMS_LINKTIME:
22149 printf (_(" Link time: "));
8d18bf79
NC
22150 if (maxlen < 8)
22151 goto desc_size_fail;
22152 /* FIXME: Generate an error if descsz > 8 ? */
22153
0e3c1eeb 22154 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
22155 printf ("\n");
22156 break;
8d18bf79 22157
00e98fc7
TG
22158 case NT_VMS_PATCHTIME:
22159 printf (_(" Patch time: "));
8d18bf79
NC
22160 if (maxlen < 8)
22161 goto desc_size_fail;
22162 /* FIXME: Generate an error if descsz > 8 ? */
22163
0e3c1eeb 22164 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
22165 printf ("\n");
22166 break;
8d18bf79 22167
00e98fc7 22168 case NT_VMS_ORIG_DYN:
8d18bf79
NC
22169 if (maxlen < 34)
22170 goto desc_size_fail;
22171
00e98fc7 22172 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
22173 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
22174 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 22175 printf (_(" Last modified : "));
0e3c1eeb 22176 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 22177 printf (_("\n Link flags : "));
b8281767 22178 printf ("0x%016" PRIx64 "\n",
625d49fc 22179 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 22180 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 22181 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 22182 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 22183 break;
8d18bf79 22184
00e98fc7 22185 case NT_VMS_IMGNAM:
8d18bf79 22186 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22187 break;
8d18bf79 22188
00e98fc7 22189 case NT_VMS_GSTNAM:
8d18bf79 22190 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22191 break;
8d18bf79 22192
00e98fc7 22193 case NT_VMS_IMGID:
8d18bf79 22194 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22195 break;
8d18bf79 22196
00e98fc7 22197 case NT_VMS_LINKID:
8d18bf79 22198 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22199 break;
8d18bf79 22200
00e98fc7 22201 default:
015dc7e1 22202 return false;
00e98fc7 22203 }
8d18bf79 22204
015dc7e1 22205 return true;
8d18bf79
NC
22206
22207 desc_size_fail:
22208 printf (_(" <corrupt - data size is too small>\n"));
22209 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 22210 return false;
00e98fc7
TG
22211}
22212
fd486f32
AM
22213struct build_attr_cache {
22214 Filedata *filedata;
22215 char *strtab;
26c527e6 22216 uint64_t strtablen;
fd486f32 22217 Elf_Internal_Sym *symtab;
26c527e6 22218 uint64_t nsyms;
fd486f32
AM
22219} ba_cache;
22220
6f156d7a
NC
22221/* Find the symbol associated with a build attribute that is attached
22222 to address OFFSET. If PNAME is non-NULL then store the name of
22223 the symbol (if found) in the provided pointer, Returns NULL if a
22224 symbol could not be found. */
c799a79d 22225
6f156d7a 22226static Elf_Internal_Sym *
015dc7e1 22227get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 22228 uint64_t offset,
015dc7e1
AM
22229 bool is_open_attr,
22230 const char **pname)
9ef920e9 22231{
fd486f32
AM
22232 Elf_Internal_Sym *saved_sym = NULL;
22233 Elf_Internal_Sym *sym;
9ef920e9 22234
dda8d76d 22235 if (filedata->section_headers != NULL
fd486f32 22236 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 22237 {
c799a79d 22238 Elf_Internal_Shdr * symsec;
9ef920e9 22239
fd486f32
AM
22240 free (ba_cache.strtab);
22241 ba_cache.strtab = NULL;
22242 free (ba_cache.symtab);
22243 ba_cache.symtab = NULL;
22244
c799a79d 22245 /* Load the symbol and string sections. */
dda8d76d
NC
22246 for (symsec = filedata->section_headers;
22247 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 22248 symsec ++)
9ef920e9 22249 {
28d13567
AM
22250 if (symsec->sh_type == SHT_SYMTAB
22251 && get_symtab (filedata, symsec,
22252 &ba_cache.symtab, &ba_cache.nsyms,
22253 &ba_cache.strtab, &ba_cache.strtablen))
22254 break;
9ef920e9 22255 }
fd486f32 22256 ba_cache.filedata = filedata;
9ef920e9
NC
22257 }
22258
fd486f32 22259 if (ba_cache.symtab == NULL)
6f156d7a 22260 return NULL;
9ef920e9 22261
c799a79d 22262 /* Find a symbol whose value matches offset. */
fd486f32 22263 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
22264 if (sym->st_value == offset)
22265 {
fd486f32 22266 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
22267 /* Huh ? This should not happen. */
22268 continue;
9ef920e9 22269
fd486f32 22270 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 22271 continue;
9ef920e9 22272
9b9b1092 22273 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 22274 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
22275 if (ba_cache.strtab[sym->st_name] == '$'
22276 && ba_cache.strtab[sym->st_name + 1] != 0
22277 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
22278 continue;
22279
c799a79d
NC
22280 if (is_open_attr)
22281 {
22282 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22283 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22284 FUNC symbols entirely. */
22285 switch (ELF_ST_TYPE (sym->st_info))
22286 {
c799a79d 22287 case STT_OBJECT:
6f156d7a 22288 case STT_FILE:
c799a79d 22289 saved_sym = sym;
6f156d7a
NC
22290 if (sym->st_size)
22291 {
22292 /* If the symbol has a size associated
22293 with it then we can stop searching. */
fd486f32 22294 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 22295 }
c799a79d 22296 continue;
9ef920e9 22297
c799a79d
NC
22298 case STT_FUNC:
22299 /* Ignore function symbols. */
22300 continue;
22301
22302 default:
22303 break;
22304 }
22305
22306 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 22307 {
c799a79d
NC
22308 case STB_GLOBAL:
22309 if (saved_sym == NULL
22310 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22311 saved_sym = sym;
22312 break;
c871dade 22313
c799a79d
NC
22314 case STB_LOCAL:
22315 if (saved_sym == NULL)
22316 saved_sym = sym;
22317 break;
22318
22319 default:
9ef920e9
NC
22320 break;
22321 }
22322 }
c799a79d
NC
22323 else
22324 {
22325 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22326 continue;
22327
22328 saved_sym = sym;
22329 break;
22330 }
22331 }
22332
6f156d7a 22333 if (saved_sym && pname)
fd486f32 22334 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
22335
22336 return saved_sym;
c799a79d
NC
22337}
22338
d20e98ab
NC
22339/* Returns true iff addr1 and addr2 are in the same section. */
22340
015dc7e1 22341static bool
26c527e6 22342same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
22343{
22344 Elf_Internal_Shdr * a1;
22345 Elf_Internal_Shdr * a2;
22346
22347 a1 = find_section_by_address (filedata, addr1);
22348 a2 = find_section_by_address (filedata, addr2);
9abca702 22349
d20e98ab
NC
22350 return a1 == a2 && a1 != NULL;
22351}
22352
015dc7e1 22353static bool
dda8d76d
NC
22354print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22355 Filedata * filedata)
c799a79d 22356{
26c527e6
AM
22357 static uint64_t global_offset = 0;
22358 static uint64_t global_end = 0;
22359 static uint64_t func_offset = 0;
22360 static uint64_t func_end = 0;
c871dade 22361
015dc7e1
AM
22362 Elf_Internal_Sym *sym;
22363 const char *name;
26c527e6
AM
22364 uint64_t start;
22365 uint64_t end;
015dc7e1 22366 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
22367
22368 switch (pnote->descsz)
c799a79d 22369 {
6f156d7a
NC
22370 case 0:
22371 /* A zero-length description means that the range of
22372 the previous note of the same type should be used. */
c799a79d 22373 if (is_open_attr)
c871dade 22374 {
6f156d7a 22375 if (global_end > global_offset)
26c527e6
AM
22376 printf (_(" Applies to region from %#" PRIx64
22377 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 22378 else
26c527e6
AM
22379 printf (_(" Applies to region from %#" PRIx64
22380 "\n"), global_offset);
c799a79d
NC
22381 }
22382 else
22383 {
6f156d7a 22384 if (func_end > func_offset)
26c527e6
AM
22385 printf (_(" Applies to region from %#" PRIx64
22386 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 22387 else
26c527e6
AM
22388 printf (_(" Applies to region from %#" PRIx64
22389 "\n"), func_offset);
c871dade 22390 }
015dc7e1 22391 return true;
9ef920e9 22392
6f156d7a
NC
22393 case 4:
22394 start = byte_get ((unsigned char *) pnote->descdata, 4);
22395 end = 0;
22396 break;
22397
22398 case 8:
c74147bb
NC
22399 start = byte_get ((unsigned char *) pnote->descdata, 4);
22400 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
22401 break;
22402
22403 case 16:
22404 start = byte_get ((unsigned char *) pnote->descdata, 8);
22405 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22406 break;
9abca702 22407
6f156d7a 22408 default:
c799a79d
NC
22409 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22410 printf (_(" <invalid descsz>"));
015dc7e1 22411 return false;
c799a79d
NC
22412 }
22413
6f156d7a
NC
22414 name = NULL;
22415 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
22416 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22417 in order to avoid them being confused with the start address of the
22418 first function in the file... */
22419 if (sym == NULL && is_open_attr)
22420 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22421 & name);
6f156d7a
NC
22422
22423 if (end == 0 && sym != NULL && sym->st_size > 0)
22424 end = start + sym->st_size;
c799a79d
NC
22425
22426 if (is_open_attr)
22427 {
d20e98ab
NC
22428 /* FIXME: Need to properly allow for section alignment.
22429 16 is just the alignment used on x86_64. */
22430 if (global_end > 0
22431 && start > BFD_ALIGN (global_end, 16)
22432 /* Build notes are not guaranteed to be organised in order of
22433 increasing address, but we should find the all of the notes
22434 for one section in the same place. */
22435 && same_section (filedata, start, global_end))
26c527e6
AM
22436 warn (_("Gap in build notes detected from %#" PRIx64
22437 " to %#" PRIx64 "\n"),
6f156d7a
NC
22438 global_end + 1, start - 1);
22439
26c527e6 22440 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22441 global_offset = start;
22442
22443 if (end)
22444 {
26c527e6 22445 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22446 global_end = end;
22447 }
c799a79d
NC
22448 }
22449 else
22450 {
26c527e6 22451 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22452 func_offset = start;
22453
22454 if (end)
22455 {
26c527e6 22456 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22457 func_end = end;
22458 }
c799a79d
NC
22459 }
22460
6f156d7a
NC
22461 if (sym && name)
22462 printf (_(" (%s)"), name);
22463
22464 printf ("\n");
015dc7e1 22465 return true;
9ef920e9
NC
22466}
22467
015dc7e1 22468static bool
9ef920e9
NC
22469print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22470{
1d15e434
NC
22471 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22472 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22473 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
22474 char name_type;
22475 char name_attribute;
1d15e434 22476 const char * expected_types;
9ef920e9
NC
22477 const char * name = pnote->namedata;
22478 const char * text;
88305e1b 22479 signed int left;
9ef920e9
NC
22480
22481 if (name == NULL || pnote->namesz < 2)
22482 {
22483 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22484 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22485 return false;
9ef920e9
NC
22486 }
22487
6f156d7a
NC
22488 if (do_wide)
22489 left = 28;
22490 else
22491 left = 20;
88305e1b
NC
22492
22493 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22494 if (name[0] == 'G' && name[1] == 'A')
22495 {
6f156d7a
NC
22496 if (pnote->namesz < 4)
22497 {
22498 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22499 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22500 return false;
6f156d7a
NC
22501 }
22502
88305e1b
NC
22503 printf ("GA");
22504 name += 2;
22505 left -= 2;
22506 }
22507
9ef920e9
NC
22508 switch ((name_type = * name))
22509 {
22510 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22511 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22512 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22513 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22514 printf ("%c", * name);
88305e1b 22515 left --;
9ef920e9
NC
22516 break;
22517 default:
22518 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 22519 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 22520 return false;
9ef920e9
NC
22521 }
22522
9ef920e9
NC
22523 ++ name;
22524 text = NULL;
22525
22526 switch ((name_attribute = * name))
22527 {
22528 case GNU_BUILD_ATTRIBUTE_VERSION:
22529 text = _("<version>");
1d15e434 22530 expected_types = string_expected;
9ef920e9
NC
22531 ++ name;
22532 break;
22533 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22534 text = _("<stack prot>");
75d7d298 22535 expected_types = "!+*";
9ef920e9
NC
22536 ++ name;
22537 break;
22538 case GNU_BUILD_ATTRIBUTE_RELRO:
22539 text = _("<relro>");
1d15e434 22540 expected_types = bool_expected;
9ef920e9
NC
22541 ++ name;
22542 break;
22543 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22544 text = _("<stack size>");
1d15e434 22545 expected_types = number_expected;
9ef920e9
NC
22546 ++ name;
22547 break;
22548 case GNU_BUILD_ATTRIBUTE_TOOL:
22549 text = _("<tool>");
1d15e434 22550 expected_types = string_expected;
9ef920e9
NC
22551 ++ name;
22552 break;
22553 case GNU_BUILD_ATTRIBUTE_ABI:
22554 text = _("<ABI>");
22555 expected_types = "$*";
22556 ++ name;
22557 break;
22558 case GNU_BUILD_ATTRIBUTE_PIC:
22559 text = _("<PIC>");
1d15e434 22560 expected_types = number_expected;
9ef920e9
NC
22561 ++ name;
22562 break;
a8be5506
NC
22563 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22564 text = _("<short enum>");
1d15e434 22565 expected_types = bool_expected;
a8be5506
NC
22566 ++ name;
22567 break;
9ef920e9
NC
22568 default:
22569 if (ISPRINT (* name))
22570 {
22571 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22572
22573 if (len > left && ! do_wide)
22574 len = left;
75d7d298 22575 printf ("%.*s:", len, name);
9ef920e9 22576 left -= len;
0dd6ae21 22577 name += len;
9ef920e9
NC
22578 }
22579 else
22580 {
3e6b6445 22581 static char tmpbuf [128];
88305e1b 22582
3e6b6445
NC
22583 error (_("unrecognised byte in name field: %d\n"), * name);
22584 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22585 text = tmpbuf;
22586 name ++;
9ef920e9
NC
22587 }
22588 expected_types = "*$!+";
22589 break;
22590 }
22591
22592 if (text)
88305e1b 22593 left -= printf ("%s", text);
9ef920e9
NC
22594
22595 if (strchr (expected_types, name_type) == NULL)
75d7d298 22596 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22597
26c527e6 22598 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22599 {
26c527e6
AM
22600 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22601 pnote->namesz,
22602 name - pnote->namedata);
015dc7e1 22603 return false;
9ef920e9
NC
22604 }
22605
22606 if (left < 1 && ! do_wide)
015dc7e1 22607 return true;
9ef920e9
NC
22608
22609 switch (name_type)
22610 {
22611 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22612 {
26c527e6
AM
22613 unsigned int bytes;
22614 uint64_t val = 0;
22615 unsigned int shift = 0;
22616 char *decoded = NULL;
ddef72cd 22617
b06b2c92
NC
22618 bytes = pnote->namesz - (name - pnote->namedata);
22619 if (bytes > 0)
22620 /* The -1 is because the name field is always 0 terminated, and we
22621 want to be able to ensure that the shift in the while loop below
22622 will not overflow. */
22623 -- bytes;
22624
ddef72cd
NC
22625 if (bytes > sizeof (val))
22626 {
3e6b6445
NC
22627 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22628 bytes);
22629 bytes = sizeof (val);
ddef72cd 22630 }
3e6b6445
NC
22631 /* We do not bother to warn if bytes == 0 as this can
22632 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22633
22634 while (bytes --)
22635 {
26c527e6 22636 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22637
22638 val |= byte << shift;
9ef920e9
NC
22639 shift += 8;
22640 }
22641
75d7d298 22642 switch (name_attribute)
9ef920e9 22643 {
75d7d298 22644 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22645 switch (val)
22646 {
75d7d298
NC
22647 case 0: decoded = "static"; break;
22648 case 1: decoded = "pic"; break;
22649 case 2: decoded = "PIC"; break;
22650 case 3: decoded = "pie"; break;
22651 case 4: decoded = "PIE"; break;
22652 default: break;
9ef920e9 22653 }
75d7d298
NC
22654 break;
22655 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22656 switch (val)
9ef920e9 22657 {
75d7d298
NC
22658 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22659 case 0: decoded = "off"; break;
22660 case 1: decoded = "on"; break;
22661 case 2: decoded = "all"; break;
22662 case 3: decoded = "strong"; break;
22663 case 4: decoded = "explicit"; break;
22664 default: break;
9ef920e9 22665 }
75d7d298
NC
22666 break;
22667 default:
22668 break;
9ef920e9
NC
22669 }
22670
75d7d298 22671 if (decoded != NULL)
3e6b6445 22672 {
b6ac461a 22673 print_symbol_name (-left, decoded);
3e6b6445
NC
22674 left = 0;
22675 }
22676 else if (val == 0)
22677 {
22678 printf ("0x0");
22679 left -= 3;
22680 }
9ef920e9 22681 else
75d7d298
NC
22682 {
22683 if (do_wide)
26c527e6 22684 left -= printf ("0x%" PRIx64, val);
75d7d298 22685 else
26c527e6 22686 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22687 }
9ef920e9
NC
22688 }
22689 break;
22690 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22691 left -= print_symbol_name (- left, name);
9ef920e9
NC
22692 break;
22693 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22694 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22695 break;
22696 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22697 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22698 break;
22699 }
22700
22701 if (do_wide && left > 0)
22702 printf ("%-*s", left, " ");
9abca702 22703
015dc7e1 22704 return true;
9ef920e9
NC
22705}
22706
2952f10c
SM
22707/* Print the contents of PNOTE as hex. */
22708
22709static void
22710print_note_contents_hex (Elf_Internal_Note *pnote)
22711{
22712 if (pnote->descsz)
22713 {
26c527e6 22714 size_t i;
2952f10c
SM
22715
22716 printf (_(" description data: "));
22717 for (i = 0; i < pnote->descsz; i++)
22718 printf ("%02x ", pnote->descdata[i] & 0xff);
22719 if (!do_wide)
22720 printf ("\n");
22721 }
22722
22723 if (do_wide)
22724 printf ("\n");
22725}
22726
22727#if defined HAVE_MSGPACK
22728
22729static void
22730print_indents (int n)
22731{
22732 printf (" ");
22733
22734 for (int i = 0; i < n; i++)
22735 printf (" ");
22736}
22737
22738/* Print OBJ in human-readable form. */
22739
22740static void
22741dump_msgpack_obj (const msgpack_object *obj, int indent)
22742{
22743 switch (obj->type)
22744 {
22745 case MSGPACK_OBJECT_NIL:
22746 printf ("(nil)");
22747 break;
22748
22749 case MSGPACK_OBJECT_BOOLEAN:
22750 printf ("%s", obj->via.boolean ? "true" : "false");
22751 break;
22752
22753 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22754 printf ("%" PRIu64, obj->via.u64);
22755 break;
22756
22757 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22758 printf ("%" PRIi64, obj->via.i64);
22759 break;
22760
22761 case MSGPACK_OBJECT_FLOAT32:
22762 case MSGPACK_OBJECT_FLOAT64:
22763 printf ("%f", obj->via.f64);
22764 break;
22765
22766 case MSGPACK_OBJECT_STR:
22767 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22768 break;
22769
22770 case MSGPACK_OBJECT_ARRAY:
22771 {
22772 const msgpack_object_array *array = &obj->via.array;
22773
22774 printf ("[\n");
22775 ++indent;
22776
22777 for (uint32_t i = 0; i < array->size; ++i)
22778 {
22779 const msgpack_object *item = &array->ptr[i];
22780
22781 print_indents (indent);
22782 dump_msgpack_obj (item, indent);
22783 printf (",\n");
22784 }
22785
22786 --indent;
22787 print_indents (indent);
22788 printf ("]");
22789 break;
22790 }
22791 break;
22792
22793 case MSGPACK_OBJECT_MAP:
22794 {
22795 const msgpack_object_map *map = &obj->via.map;
22796
22797 printf ("{\n");
22798 ++indent;
22799
22800 for (uint32_t i = 0; i < map->size; ++i)
22801 {
22802 const msgpack_object_kv *kv = &map->ptr[i];
22803 const msgpack_object *key = &kv->key;
22804 const msgpack_object *val = &kv->val;
22805
22806 print_indents (indent);
22807 dump_msgpack_obj (key, indent);
22808 printf (": ");
22809 dump_msgpack_obj (val, indent);
22810
22811 printf (",\n");
22812 }
22813
22814 --indent;
22815 print_indents (indent);
22816 printf ("}");
22817
22818 break;
22819 }
22820
22821 case MSGPACK_OBJECT_BIN:
22822 printf ("(bin)");
22823 break;
22824
22825 case MSGPACK_OBJECT_EXT:
22826 printf ("(ext)");
22827 break;
22828 }
22829}
22830
22831static void
22832dump_msgpack (const msgpack_unpacked *msg)
22833{
22834 print_indents (0);
22835 dump_msgpack_obj (&msg->data, 0);
22836 printf ("\n");
22837}
22838
22839#endif /* defined HAVE_MSGPACK */
22840
22841static bool
22842print_amdgpu_note (Elf_Internal_Note *pnote)
22843{
22844#if defined HAVE_MSGPACK
22845 /* If msgpack is available, decode and dump the note's content. */
22846 bool ret;
22847 msgpack_unpacked msg;
22848 msgpack_unpack_return msgpack_ret;
22849
22850 assert (pnote->type == NT_AMDGPU_METADATA);
22851
22852 msgpack_unpacked_init (&msg);
22853 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22854 NULL);
22855
22856 switch (msgpack_ret)
22857 {
22858 case MSGPACK_UNPACK_SUCCESS:
22859 dump_msgpack (&msg);
22860 ret = true;
22861 break;
22862
22863 default:
22864 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22865 ret = false;
22866 break;
22867 }
22868
22869 msgpack_unpacked_destroy (&msg);
22870 return ret;
22871#else
22872 /* msgpack is not available, dump contents as hex. */
22873 print_note_contents_hex (pnote);
22874 return true;
22875#endif
22876}
22877
e263a66b
CC
22878static bool
22879print_qnx_note (Elf_Internal_Note *pnote)
22880{
22881 switch (pnote->type)
22882 {
22883 case QNT_STACK:
22884 if (pnote->descsz != 12)
22885 goto desc_size_fail;
22886
22887 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22888 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22889 printf (_(" Stack allocated: %" PRIx32 "\n"),
22890 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22891 printf (_(" Executable: %s\n"),
22892 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22893 break;
22894
22895 default:
22896 print_note_contents_hex(pnote);
22897 }
22898 return true;
22899
22900desc_size_fail:
22901 printf (_(" <corrupt - data size is too small>\n"));
22902 error (_("corrupt QNX note: data size is too small\n"));
22903 return false;
22904}
22905
22906
6d118b09
NC
22907/* Note that by the ELF standard, the name field is already null byte
22908 terminated, and namesz includes the terminating null byte.
22909 I.E. the value of namesz for the name "FSF" is 4.
22910
e3c8793a 22911 If the value of namesz is zero, there is no name present. */
9ef920e9 22912
015dc7e1 22913static bool
9ef920e9 22914process_note (Elf_Internal_Note * pnote,
dda8d76d 22915 Filedata * filedata)
779fe533 22916{
2cf0635d
NC
22917 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22918 const char * nt;
9437c45b
JT
22919
22920 if (pnote->namesz == 0)
1ec5cd37
NC
22921 /* If there is no note name, then use the default set of
22922 note type strings. */
dda8d76d 22923 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22924
24d127aa 22925 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22926 /* GNU-specific object file notes. */
22927 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22928
28cdbb18
SM
22929 else if (startswith (pnote->namedata, "AMDGPU"))
22930 /* AMDGPU-specific object file notes. */
22931 nt = get_amdgpu_elf_note_type (pnote->type);
22932
24d127aa 22933 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22934 /* FreeBSD-specific core file notes. */
dda8d76d 22935 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22936
24d127aa 22937 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22938 /* NetBSD-specific core file notes. */
dda8d76d 22939 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22940
24d127aa 22941 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22942 /* NetBSD-specific core file notes. */
22943 return process_netbsd_elf_note (pnote);
22944
24d127aa 22945 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22946 /* NetBSD-specific core file notes. */
22947 return process_netbsd_elf_note (pnote);
22948
98ca73af
FC
22949 else if (startswith (pnote->namedata, "OpenBSD"))
22950 /* OpenBSD-specific core file notes. */
22951 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22952
e263a66b
CC
22953 else if (startswith (pnote->namedata, "QNX"))
22954 /* QNX-specific core file notes. */
22955 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22956
e9b095a5 22957 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22958 {
22959 /* SPU-specific core file notes. */
22960 nt = pnote->namedata + 4;
22961 name = "SPU";
22962 }
22963
24d127aa 22964 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22965 /* VMS/ia64-specific file notes. */
22966 nt = get_ia64_vms_note_type (pnote->type);
22967
24d127aa 22968 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22969 nt = get_stapsdt_note_type (pnote->type);
22970
9437c45b 22971 else
1ec5cd37
NC
22972 /* Don't recognize this note name; just use the default set of
22973 note type strings. */
dda8d76d 22974 nt = get_note_type (filedata, pnote->type);
9437c45b 22975
1449284b 22976 printf (" ");
9ef920e9 22977
24d127aa 22978 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22979 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22980 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22981 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22982 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22983 print_gnu_build_attribute_name (pnote);
22984 else
b6ac461a 22985 print_symbol_name (-20, name);
9ef920e9
NC
22986
22987 if (do_wide)
22988 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22989 else
22990 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22991
24d127aa 22992 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22993 return print_ia64_vms_note (pnote);
24d127aa 22994 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22995 return print_gnu_note (filedata, pnote);
24d127aa 22996 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22997 return print_stapsdt_note (pnote);
24d127aa 22998 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22999 return print_core_note (pnote);
e5382207
LB
23000 else if (startswith (pnote->namedata, "FDO"))
23001 return print_fdo_note (pnote);
24d127aa 23002 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
23003 && strchr ("*$!+", pnote->namedata[2]) != NULL)
23004 || strchr ("*$!+", pnote->namedata[0]) != NULL)
23005 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
23006 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 23007 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
23008 else if (startswith (pnote->namedata, "AMDGPU")
23009 && pnote->type == NT_AMDGPU_METADATA)
23010 return print_amdgpu_note (pnote);
e263a66b
CC
23011 else if (startswith (pnote->namedata, "QNX"))
23012 return print_qnx_note (pnote);
779fe533 23013
2952f10c 23014 print_note_contents_hex (pnote);
015dc7e1 23015 return true;
1449284b 23016}
6d118b09 23017
015dc7e1 23018static bool
dda8d76d
NC
23019process_notes_at (Filedata * filedata,
23020 Elf_Internal_Shdr * section,
625d49fc
AM
23021 uint64_t offset,
23022 uint64_t length,
23023 uint64_t align)
779fe533 23024{
015dc7e1
AM
23025 Elf_External_Note *pnotes;
23026 Elf_External_Note *external;
23027 char *end;
23028 bool res = true;
103f02d3 23029
779fe533 23030 if (length <= 0)
015dc7e1 23031 return false;
103f02d3 23032
1449284b
NC
23033 if (section)
23034 {
dda8d76d 23035 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 23036 if (pnotes)
32ec8896 23037 {
dda8d76d 23038 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
23039 {
23040 free (pnotes);
015dc7e1 23041 return false;
f761cb13 23042 }
32ec8896 23043 }
1449284b
NC
23044 }
23045 else
82ed9683 23046 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 23047 _("notes"));
4dff97b2 23048
dd24e3da 23049 if (pnotes == NULL)
015dc7e1 23050 return false;
779fe533 23051
103f02d3 23052 external = pnotes;
103f02d3 23053
ca0e11aa
NC
23054 if (filedata->is_separate)
23055 printf (_("In linked file '%s': "), filedata->file_name);
23056 else
23057 printf ("\n");
1449284b 23058 if (section)
ca0e11aa 23059 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 23060 else
26c527e6
AM
23061 printf (_("Displaying notes found at file offset 0x%08" PRIx64
23062 " with length 0x%08" PRIx64 ":\n"),
23063 offset, length);
1449284b 23064
82ed9683
L
23065 /* NB: Some note sections may have alignment value of 0 or 1. gABI
23066 specifies that notes should be aligned to 4 bytes in 32-bit
23067 objects and to 8 bytes in 64-bit objects. As a Linux extension,
23068 we also support 4 byte alignment in 64-bit objects. If section
23069 alignment is less than 4, we treate alignment as 4 bytes. */
23070 if (align < 4)
23071 align = 4;
23072 else if (align != 4 && align != 8)
23073 {
26c527e6
AM
23074 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
23075 align);
a788aedd 23076 free (pnotes);
015dc7e1 23077 return false;
82ed9683
L
23078 }
23079
dbe15e4e 23080 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 23081
c8071705
NC
23082 end = (char *) pnotes + length;
23083 while ((char *) external < end)
779fe533 23084 {
b34976b6 23085 Elf_Internal_Note inote;
15b42fb0 23086 size_t min_notesz;
4dff97b2 23087 char * next;
2cf0635d 23088 char * temp = NULL;
c8071705 23089 size_t data_remaining = end - (char *) external;
6d118b09 23090
dda8d76d 23091 if (!is_ia64_vms (filedata))
15b42fb0 23092 {
9dd3a467
NC
23093 /* PR binutils/15191
23094 Make sure that there is enough data to read. */
15b42fb0
AM
23095 min_notesz = offsetof (Elf_External_Note, name);
23096 if (data_remaining < min_notesz)
9dd3a467 23097 {
26c527e6 23098 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 23099 "not enough for a full note\n",
26c527e6 23100 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
23101 "not enough for a full note\n",
23102 data_remaining),
26c527e6 23103 data_remaining);
9dd3a467
NC
23104 break;
23105 }
5396a86e
AM
23106 data_remaining -= min_notesz;
23107
15b42fb0
AM
23108 inote.type = BYTE_GET (external->type);
23109 inote.namesz = BYTE_GET (external->namesz);
23110 inote.namedata = external->name;
23111 inote.descsz = BYTE_GET (external->descsz);
276da9b3 23112 inote.descdata = ((char *) external
4dff97b2 23113 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 23114 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 23115 next = ((char *) external
4dff97b2 23116 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 23117 }
00e98fc7 23118 else
15b42fb0
AM
23119 {
23120 Elf64_External_VMS_Note *vms_external;
00e98fc7 23121
9dd3a467
NC
23122 /* PR binutils/15191
23123 Make sure that there is enough data to read. */
15b42fb0
AM
23124 min_notesz = offsetof (Elf64_External_VMS_Note, name);
23125 if (data_remaining < min_notesz)
9dd3a467 23126 {
26c527e6 23127 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 23128 "not enough for a full note\n",
26c527e6 23129 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
23130 "not enough for a full note\n",
23131 data_remaining),
26c527e6 23132 data_remaining);
9dd3a467
NC
23133 break;
23134 }
5396a86e 23135 data_remaining -= min_notesz;
3e55a963 23136
15b42fb0
AM
23137 vms_external = (Elf64_External_VMS_Note *) external;
23138 inote.type = BYTE_GET (vms_external->type);
23139 inote.namesz = BYTE_GET (vms_external->namesz);
23140 inote.namedata = vms_external->name;
23141 inote.descsz = BYTE_GET (vms_external->descsz);
23142 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
23143 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23144 next = inote.descdata + align_power (inote.descsz, 3);
23145 }
23146
5396a86e
AM
23147 /* PR 17531: file: 3443835e. */
23148 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
23149 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
23150 || (size_t) (inote.descdata - inote.namedata) > data_remaining
23151 || (size_t) (next - inote.descdata) < inote.descsz
23152 || ((size_t) (next - inote.descdata)
23153 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 23154 {
26c527e6
AM
23155 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
23156 (char *) external - (char *) pnotes);
23157 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 23158 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
23159 break;
23160 }
23161
15b42fb0 23162 external = (Elf_External_Note *) next;
dd24e3da 23163
6d118b09
NC
23164 /* Verify that name is null terminated. It appears that at least
23165 one version of Linux (RedHat 6.0) generates corefiles that don't
23166 comply with the ELF spec by failing to include the null byte in
23167 namesz. */
18344509 23168 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 23169 {
5396a86e 23170 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 23171 {
5396a86e
AM
23172 temp = (char *) malloc (inote.namesz + 1);
23173 if (temp == NULL)
23174 {
23175 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 23176 res = false;
5396a86e
AM
23177 break;
23178 }
76da6bbe 23179
5396a86e
AM
23180 memcpy (temp, inote.namedata, inote.namesz);
23181 inote.namedata = temp;
23182 }
23183 inote.namedata[inote.namesz] = 0;
6d118b09
NC
23184 }
23185
dda8d76d 23186 if (! process_note (& inote, filedata))
015dc7e1 23187 res = false;
103f02d3 23188
9db70fc3
AM
23189 free (temp);
23190 temp = NULL;
779fe533
NC
23191 }
23192
23193 free (pnotes);
103f02d3 23194
779fe533
NC
23195 return res;
23196}
23197
015dc7e1 23198static bool
dda8d76d 23199process_corefile_note_segments (Filedata * filedata)
779fe533 23200{
015dc7e1 23201 Elf_Internal_Phdr *segment;
b34976b6 23202 unsigned int i;
015dc7e1 23203 bool res = true;
103f02d3 23204
dda8d76d 23205 if (! get_program_headers (filedata))
015dc7e1 23206 return true;
103f02d3 23207
dda8d76d
NC
23208 for (i = 0, segment = filedata->program_headers;
23209 i < filedata->file_header.e_phnum;
b34976b6 23210 i++, segment++)
779fe533
NC
23211 {
23212 if (segment->p_type == PT_NOTE)
625d49fc
AM
23213 if (! process_notes_at (filedata, NULL, segment->p_offset,
23214 segment->p_filesz, segment->p_align))
015dc7e1 23215 res = false;
779fe533 23216 }
103f02d3 23217
779fe533
NC
23218 return res;
23219}
23220
015dc7e1 23221static bool
625d49fc 23222process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
23223{
23224 Elf_External_Note * pnotes;
23225 Elf_External_Note * external;
c8071705 23226 char * end;
015dc7e1 23227 bool res = true;
685080f2
NC
23228
23229 if (length <= 0)
015dc7e1 23230 return false;
685080f2 23231
dda8d76d 23232 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
23233 _("v850 notes"));
23234 if (pnotes == NULL)
015dc7e1 23235 return false;
685080f2
NC
23236
23237 external = pnotes;
c8071705 23238 end = (char*) pnotes + length;
685080f2 23239
26c527e6
AM
23240 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
23241 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
23242 offset, length);
685080f2 23243
c8071705 23244 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
23245 {
23246 Elf_External_Note * next;
23247 Elf_Internal_Note inote;
23248
23249 inote.type = BYTE_GET (external->type);
23250 inote.namesz = BYTE_GET (external->namesz);
23251 inote.namedata = external->name;
23252 inote.descsz = BYTE_GET (external->descsz);
23253 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
23254 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23255
c8071705
NC
23256 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
23257 {
23258 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
23259 inote.descdata = inote.namedata;
23260 inote.namesz = 0;
23261 }
23262
685080f2
NC
23263 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
23264
c8071705 23265 if ( ((char *) next > end)
685080f2
NC
23266 || ((char *) next < (char *) pnotes))
23267 {
26c527e6
AM
23268 warn (_("corrupt descsz found in note at offset %#tx\n"),
23269 (char *) external - (char *) pnotes);
23270 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
23271 inote.type, inote.namesz, inote.descsz);
23272 break;
23273 }
23274
23275 external = next;
23276
23277 /* Prevent out-of-bounds indexing. */
c8071705 23278 if ( inote.namedata + inote.namesz > end
685080f2
NC
23279 || inote.namedata + inote.namesz < inote.namedata)
23280 {
26c527e6
AM
23281 warn (_("corrupt namesz found in note at offset %#zx\n"),
23282 (char *) external - (char *) pnotes);
23283 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
23284 inote.type, inote.namesz, inote.descsz);
23285 break;
23286 }
23287
23288 printf (" %s: ", get_v850_elf_note_type (inote.type));
23289
23290 if (! print_v850_note (& inote))
23291 {
015dc7e1 23292 res = false;
26c527e6 23293 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
23294 inote.namesz, inote.descsz);
23295 }
23296 }
23297
23298 free (pnotes);
23299
23300 return res;
23301}
23302
015dc7e1 23303static bool
dda8d76d 23304process_note_sections (Filedata * filedata)
1ec5cd37 23305{
015dc7e1 23306 Elf_Internal_Shdr *section;
26c527e6 23307 size_t i;
32ec8896 23308 unsigned int n = 0;
015dc7e1 23309 bool res = true;
1ec5cd37 23310
dda8d76d
NC
23311 for (i = 0, section = filedata->section_headers;
23312 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 23313 i++, section++)
685080f2
NC
23314 {
23315 if (section->sh_type == SHT_NOTE)
23316 {
625d49fc
AM
23317 if (! process_notes_at (filedata, section, section->sh_offset,
23318 section->sh_size, section->sh_addralign))
015dc7e1 23319 res = false;
685080f2
NC
23320 n++;
23321 }
23322
dda8d76d
NC
23323 if (( filedata->file_header.e_machine == EM_V800
23324 || filedata->file_header.e_machine == EM_V850
23325 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
23326 && section->sh_type == SHT_RENESAS_INFO)
23327 {
625d49fc
AM
23328 if (! process_v850_notes (filedata, section->sh_offset,
23329 section->sh_size))
015dc7e1 23330 res = false;
685080f2
NC
23331 n++;
23332 }
23333 }
df565f32
NC
23334
23335 if (n == 0)
23336 /* Try processing NOTE segments instead. */
dda8d76d 23337 return process_corefile_note_segments (filedata);
1ec5cd37
NC
23338
23339 return res;
23340}
23341
015dc7e1 23342static bool
dda8d76d 23343process_notes (Filedata * filedata)
779fe533
NC
23344{
23345 /* If we have not been asked to display the notes then do nothing. */
23346 if (! do_notes)
015dc7e1 23347 return true;
103f02d3 23348
dda8d76d
NC
23349 if (filedata->file_header.e_type != ET_CORE)
23350 return process_note_sections (filedata);
103f02d3 23351
779fe533 23352 /* No program headers means no NOTE segment. */
dda8d76d
NC
23353 if (filedata->file_header.e_phnum > 0)
23354 return process_corefile_note_segments (filedata);
779fe533 23355
ca0e11aa
NC
23356 if (filedata->is_separate)
23357 printf (_("No notes found in linked file '%s'.\n"),
23358 filedata->file_name);
23359 else
23360 printf (_("No notes found file.\n"));
23361
015dc7e1 23362 return true;
779fe533
NC
23363}
23364
60abdbed
NC
23365static unsigned char *
23366display_public_gnu_attributes (unsigned char * start,
23367 const unsigned char * const end)
23368{
23369 printf (_(" Unknown GNU attribute: %s\n"), start);
23370
23371 start += strnlen ((char *) start, end - start);
23372 display_raw_attribute (start, end);
23373
23374 return (unsigned char *) end;
23375}
23376
23377static unsigned char *
23378display_generic_attribute (unsigned char * start,
23379 unsigned int tag,
23380 const unsigned char * const end)
23381{
23382 if (tag == 0)
23383 return (unsigned char *) end;
23384
23385 return display_tag_value (tag, start, end);
23386}
23387
015dc7e1 23388static bool
dda8d76d 23389process_arch_specific (Filedata * filedata)
252b5132 23390{
a952a375 23391 if (! do_arch)
015dc7e1 23392 return true;
a952a375 23393
dda8d76d 23394 switch (filedata->file_header.e_machine)
252b5132 23395 {
53a346d8
CZ
23396 case EM_ARC:
23397 case EM_ARC_COMPACT:
23398 case EM_ARC_COMPACT2:
b5c37946
SJ
23399 case EM_ARC_COMPACT3:
23400 case EM_ARC_COMPACT3_64:
dda8d76d 23401 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
23402 display_arc_attribute,
23403 display_generic_attribute);
11c1ff18 23404 case EM_ARM:
dda8d76d 23405 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
23406 display_arm_attribute,
23407 display_generic_attribute);
23408
252b5132 23409 case EM_MIPS:
4fe85591 23410 case EM_MIPS_RS3_LE:
dda8d76d 23411 return process_mips_specific (filedata);
60abdbed
NC
23412
23413 case EM_MSP430:
dda8d76d 23414 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 23415 display_msp430_attribute,
c0ea7c52 23416 display_msp430_gnu_attribute);
60abdbed 23417
2dc8dd17
JW
23418 case EM_RISCV:
23419 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23420 display_riscv_attribute,
23421 display_generic_attribute);
23422
35c08157 23423 case EM_NDS32:
dda8d76d 23424 return process_nds32_specific (filedata);
60abdbed 23425
85f7484a
PB
23426 case EM_68K:
23427 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23428 display_m68k_gnu_attribute);
23429
34c8bcba 23430 case EM_PPC:
b82317dd 23431 case EM_PPC64:
dda8d76d 23432 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23433 display_power_gnu_attribute);
23434
643f7afb
AK
23435 case EM_S390:
23436 case EM_S390_OLD:
dda8d76d 23437 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23438 display_s390_gnu_attribute);
23439
9e8c70f9
DM
23440 case EM_SPARC:
23441 case EM_SPARC32PLUS:
23442 case EM_SPARCV9:
dda8d76d 23443 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23444 display_sparc_gnu_attribute);
23445
59e6276b 23446 case EM_TI_C6000:
dda8d76d 23447 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
23448 display_tic6x_attribute,
23449 display_generic_attribute);
23450
0861f561
CQ
23451 case EM_CSKY:
23452 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23453 display_csky_attribute, NULL);
23454
252b5132 23455 default:
dda8d76d 23456 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
23457 display_public_gnu_attributes,
23458 display_generic_attribute);
252b5132 23459 }
252b5132
RH
23460}
23461
015dc7e1 23462static bool
dda8d76d 23463get_file_header (Filedata * filedata)
252b5132 23464{
9ea033b2 23465 /* Read in the identity array. */
dda8d76d 23466 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23467 return false;
252b5132 23468
9ea033b2 23469 /* Determine how to read the rest of the header. */
dda8d76d 23470 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 23471 {
1a0670f3
AM
23472 default:
23473 case ELFDATANONE:
adab8cdc
AO
23474 case ELFDATA2LSB:
23475 byte_get = byte_get_little_endian;
23476 byte_put = byte_put_little_endian;
23477 break;
23478 case ELFDATA2MSB:
23479 byte_get = byte_get_big_endian;
23480 byte_put = byte_put_big_endian;
23481 break;
9ea033b2
NC
23482 }
23483
23484 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 23485 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
23486
23487 /* Read in the rest of the header. */
23488 if (is_32bit_elf)
23489 {
23490 Elf32_External_Ehdr ehdr32;
252b5132 23491
dda8d76d 23492 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23493 return false;
103f02d3 23494
dda8d76d
NC
23495 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23496 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23497 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23498 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23499 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23500 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23501 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23502 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23503 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23504 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23505 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23506 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23507 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 23508 }
252b5132 23509 else
9ea033b2
NC
23510 {
23511 Elf64_External_Ehdr ehdr64;
a952a375 23512
dda8d76d 23513 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23514 return false;
103f02d3 23515
dda8d76d
NC
23516 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23517 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23518 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23519 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23520 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23521 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23522 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23523 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23524 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23525 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23526 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23527 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23528 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 23529 }
252b5132 23530
015dc7e1 23531 return true;
252b5132
RH
23532}
23533
13acb58d
AM
23534static void
23535free_filedata (Filedata *filedata)
23536{
23537 free (filedata->program_interpreter);
13acb58d 23538 free (filedata->program_headers);
13acb58d 23539 free (filedata->section_headers);
13acb58d 23540 free (filedata->string_table);
13acb58d 23541 free (filedata->dump.dump_sects);
13acb58d 23542 free (filedata->dynamic_strings);
13acb58d 23543 free (filedata->dynamic_symbols);
13acb58d 23544 free (filedata->dynamic_syminfo);
13acb58d 23545 free (filedata->dynamic_section);
13acb58d
AM
23546
23547 while (filedata->symtab_shndx_list != NULL)
23548 {
23549 elf_section_list *next = filedata->symtab_shndx_list->next;
23550 free (filedata->symtab_shndx_list);
23551 filedata->symtab_shndx_list = next;
23552 }
23553
23554 free (filedata->section_headers_groups);
13acb58d
AM
23555
23556 if (filedata->section_groups)
23557 {
23558 size_t i;
23559 struct group_list * g;
23560 struct group_list * next;
23561
23562 for (i = 0; i < filedata->group_count; i++)
23563 {
23564 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23565 {
23566 next = g->next;
23567 free (g);
23568 }
23569 }
23570
23571 free (filedata->section_groups);
13acb58d 23572 }
066f8fbe
AM
23573 memset (&filedata->section_headers, 0,
23574 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23575}
23576
dda8d76d
NC
23577static void
23578close_file (Filedata * filedata)
23579{
23580 if (filedata)
23581 {
23582 if (filedata->handle)
23583 fclose (filedata->handle);
23584 free (filedata);
23585 }
23586}
23587
23588void
23589close_debug_file (void * data)
23590{
13acb58d 23591 free_filedata ((Filedata *) data);
dda8d76d
NC
23592 close_file ((Filedata *) data);
23593}
23594
23595static Filedata *
015dc7e1 23596open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23597{
23598 struct stat statbuf;
23599 Filedata * filedata = NULL;
23600
23601 if (stat (pathname, & statbuf) < 0
23602 || ! S_ISREG (statbuf.st_mode))
23603 goto fail;
23604
23605 filedata = calloc (1, sizeof * filedata);
23606 if (filedata == NULL)
23607 goto fail;
23608
23609 filedata->handle = fopen (pathname, "rb");
23610 if (filedata->handle == NULL)
23611 goto fail;
23612
be7d229a 23613 filedata->file_size = statbuf.st_size;
dda8d76d 23614 filedata->file_name = pathname;
ca0e11aa 23615 filedata->is_separate = is_separate;
dda8d76d
NC
23616
23617 if (! get_file_header (filedata))
23618 goto fail;
23619
4de91c10
AM
23620 if (!get_section_headers (filedata, false))
23621 goto fail;
dda8d76d
NC
23622
23623 return filedata;
23624
23625 fail:
23626 if (filedata)
23627 {
23628 if (filedata->handle)
23629 fclose (filedata->handle);
23630 free (filedata);
23631 }
23632 return NULL;
23633}
23634
23635void *
23636open_debug_file (const char * pathname)
23637{
015dc7e1 23638 return open_file (pathname, true);
dda8d76d
NC
23639}
23640
835f2fae
NC
23641static void
23642initialise_dump_sects (Filedata * filedata)
23643{
23644 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23645 Note we do this even if cmdline_dump_sects is empty because we
23646 must make sure that the dump_sets array is zeroed out before each
23647 object file is processed. */
23648 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23649 memset (filedata->dump.dump_sects, 0,
23650 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23651
23652 if (cmdline.num_dump_sects > 0)
23653 {
23654 if (filedata->dump.num_dump_sects == 0)
23655 /* A sneaky way of allocating the dump_sects array. */
23656 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23657
23658 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23659 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23660 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23661 }
23662}
23663
94585d6d
NC
23664static bool
23665might_need_separate_debug_info (Filedata * filedata)
23666{
23667 /* Debuginfo files do not need further separate file loading. */
23668 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23669 return false;
23670
23671 /* Since do_follow_links might be enabled by default, only treat it as an
23672 indication that separate files should be loaded if setting it was a
23673 deliberate user action. */
23674 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23675 return true;
23676
23677 if (process_links || do_syms || do_unwind
23678 || dump_any_debugging || do_dump || do_debugging)
23679 return true;
23680
23681 return false;
23682}
23683
fb52b2f4
NC
23684/* Process one ELF object file according to the command line options.
23685 This file may actually be stored in an archive. The file is
32ec8896
NC
23686 positioned at the start of the ELF object. Returns TRUE if no
23687 problems were encountered, FALSE otherwise. */
fb52b2f4 23688
015dc7e1 23689static bool
dda8d76d 23690process_object (Filedata * filedata)
252b5132 23691{
015dc7e1 23692 bool have_separate_files;
252b5132 23693 unsigned int i;
015dc7e1 23694 bool res;
252b5132 23695
dda8d76d 23696 if (! get_file_header (filedata))
252b5132 23697 {
dda8d76d 23698 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23699 return false;
252b5132
RH
23700 }
23701
23702 /* Initialise per file variables. */
978c4450
AM
23703 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23704 filedata->version_info[i] = 0;
252b5132 23705
978c4450
AM
23706 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23707 filedata->dynamic_info[i] = 0;
23708 filedata->dynamic_info_DT_GNU_HASH = 0;
23709 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23710
23711 /* Process the file. */
23712 if (show_name)
dda8d76d 23713 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23714
835f2fae 23715 initialise_dump_sects (filedata);
d70c5fc7 23716
4de91c10
AM
23717 /* There may be some extensions in the first section header. Don't
23718 bomb if we can't read it. */
23719 get_section_headers (filedata, true);
23720
dda8d76d 23721 if (! process_file_header (filedata))
4de91c10
AM
23722 {
23723 res = false;
23724 goto out;
23725 }
252b5132 23726
e331b18d
AM
23727 /* Throw away the single section header read above, so that we
23728 re-read the entire set. */
23729 free (filedata->section_headers);
23730 filedata->section_headers = NULL;
23731
dda8d76d 23732 if (! process_section_headers (filedata))
2f62977e 23733 {
32ec8896 23734 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23735 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23736
2f62977e 23737 if (! do_using_dynamic)
015dc7e1 23738 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23739 }
252b5132 23740
dda8d76d 23741 if (! process_section_groups (filedata))
32ec8896 23742 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23743 do_unwind = false;
d1f5c6e3 23744
93df3340
AM
23745 process_program_headers (filedata);
23746
23747 res = process_dynamic_section (filedata);
252b5132 23748
dda8d76d 23749 if (! process_relocs (filedata))
015dc7e1 23750 res = false;
252b5132 23751
dda8d76d 23752 if (! process_unwind (filedata))
015dc7e1 23753 res = false;
4d6ed7c8 23754
dda8d76d 23755 if (! process_symbol_table (filedata))
015dc7e1 23756 res = false;
252b5132 23757
0f03783c 23758 if (! process_lto_symbol_tables (filedata))
015dc7e1 23759 res = false;
b9e920ec 23760
dda8d76d 23761 if (! process_syminfo (filedata))
015dc7e1 23762 res = false;
252b5132 23763
dda8d76d 23764 if (! process_version_sections (filedata))
015dc7e1 23765 res = false;
252b5132 23766
94585d6d 23767 if (might_need_separate_debug_info (filedata))
24841daa 23768 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23769 else
015dc7e1 23770 have_separate_files = false;
dda8d76d
NC
23771
23772 if (! process_section_contents (filedata))
015dc7e1 23773 res = false;
f5842774 23774
24841daa 23775 if (have_separate_files)
dda8d76d 23776 {
24841daa
NC
23777 separate_info * d;
23778
23779 for (d = first_separate_info; d != NULL; d = d->next)
23780 {
835f2fae
NC
23781 initialise_dump_sects (d->handle);
23782
ca0e11aa 23783 if (process_links && ! process_file_header (d->handle))
015dc7e1 23784 res = false;
ca0e11aa 23785 else if (! process_section_headers (d->handle))
015dc7e1 23786 res = false;
d6bfbc39 23787 else if (! process_section_contents (d->handle))
015dc7e1 23788 res = false;
ca0e11aa
NC
23789 else if (process_links)
23790 {
ca0e11aa 23791 if (! process_section_groups (d->handle))
015dc7e1 23792 res = false;
93df3340 23793 process_program_headers (d->handle);
ca0e11aa 23794 if (! process_dynamic_section (d->handle))
015dc7e1 23795 res = false;
ca0e11aa 23796 if (! process_relocs (d->handle))
015dc7e1 23797 res = false;
ca0e11aa 23798 if (! process_unwind (d->handle))
015dc7e1 23799 res = false;
ca0e11aa 23800 if (! process_symbol_table (d->handle))
015dc7e1 23801 res = false;
ca0e11aa 23802 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23803 res = false;
ca0e11aa 23804 if (! process_syminfo (d->handle))
015dc7e1 23805 res = false;
ca0e11aa 23806 if (! process_version_sections (d->handle))
015dc7e1 23807 res = false;
ca0e11aa 23808 if (! process_notes (d->handle))
015dc7e1 23809 res = false;
ca0e11aa 23810 }
24841daa
NC
23811 }
23812
23813 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23814 }
23815
23816 if (! process_notes (filedata))
015dc7e1 23817 res = false;
103f02d3 23818
dda8d76d 23819 if (! process_gnu_liblist (filedata))
015dc7e1 23820 res = false;
047b2264 23821
dda8d76d 23822 if (! process_arch_specific (filedata))
015dc7e1 23823 res = false;
252b5132 23824
4de91c10 23825 out:
13acb58d 23826 free_filedata (filedata);
e4b17d5c 23827
19e6b90e 23828 free_debug_memory ();
18bd398b 23829
32ec8896 23830 return res;
252b5132
RH
23831}
23832
2cf0635d 23833/* Process an ELF archive.
32ec8896
NC
23834 On entry the file is positioned just after the ARMAG string.
23835 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23836
015dc7e1
AM
23837static bool
23838process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23839{
23840 struct archive_info arch;
23841 struct archive_info nested_arch;
23842 size_t got;
015dc7e1 23843 bool ret = true;
2cf0635d 23844
015dc7e1 23845 show_name = true;
2cf0635d
NC
23846
23847 /* The ARCH structure is used to hold information about this archive. */
23848 arch.file_name = NULL;
23849 arch.file = NULL;
23850 arch.index_array = NULL;
23851 arch.sym_table = NULL;
23852 arch.longnames = NULL;
23853
23854 /* The NESTED_ARCH structure is used as a single-item cache of information
23855 about a nested archive (when members of a thin archive reside within
23856 another regular archive file). */
23857 nested_arch.file_name = NULL;
23858 nested_arch.file = NULL;
23859 nested_arch.index_array = NULL;
23860 nested_arch.sym_table = NULL;
23861 nested_arch.longnames = NULL;
23862
dda8d76d 23863 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23864 filedata->file_size, is_thin_archive,
23865 do_archive_index) != 0)
2cf0635d 23866 {
015dc7e1 23867 ret = false;
2cf0635d 23868 goto out;
4145f1d5 23869 }
fb52b2f4 23870
4145f1d5
NC
23871 if (do_archive_index)
23872 {
2cf0635d 23873 if (arch.sym_table == NULL)
1cb7d8b1
AM
23874 error (_("%s: unable to dump the index as none was found\n"),
23875 filedata->file_name);
4145f1d5
NC
23876 else
23877 {
26c527e6
AM
23878 uint64_t i, l;
23879 uint64_t current_pos;
4145f1d5 23880
26c527e6
AM
23881 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23882 " %#" PRIx64 " bytes in the symbol table)\n"),
23883 filedata->file_name, arch.index_num,
1cb7d8b1 23884 arch.sym_size);
dda8d76d
NC
23885
23886 current_pos = ftell (filedata->handle);
4145f1d5 23887
2cf0635d 23888 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23889 {
1cb7d8b1
AM
23890 if (i == 0
23891 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23892 {
23893 char * member_name
23894 = get_archive_member_name_at (&arch, arch.index_array[i],
23895 &nested_arch);
2cf0635d 23896
1cb7d8b1
AM
23897 if (member_name != NULL)
23898 {
23899 char * qualified_name
23900 = make_qualified_name (&arch, &nested_arch,
23901 member_name);
2cf0635d 23902
1cb7d8b1
AM
23903 if (qualified_name != NULL)
23904 {
23905 printf (_("Contents of binary %s at offset "),
23906 qualified_name);
c2a7d3f5
NC
23907 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23908 putchar ('\n');
1cb7d8b1
AM
23909 free (qualified_name);
23910 }
fd486f32 23911 free (member_name);
4145f1d5
NC
23912 }
23913 }
2cf0635d
NC
23914
23915 if (l >= arch.sym_size)
4145f1d5 23916 {
1cb7d8b1
AM
23917 error (_("%s: end of the symbol table reached "
23918 "before the end of the index\n"),
dda8d76d 23919 filedata->file_name);
015dc7e1 23920 ret = false;
cb8f3167 23921 break;
4145f1d5 23922 }
591f7597 23923 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23924 printf ("\t%.*s\n",
23925 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23926 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23927 }
23928
67ce483b 23929 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23930 l = (l + 7) & ~ 7;
23931 else
23932 l += l & 1;
23933
2cf0635d 23934 if (l < arch.sym_size)
32ec8896 23935 {
26c527e6 23936 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23937 "but without corresponding entries in "
23938 "the index table\n",
26c527e6 23939 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23940 "but without corresponding entries in "
23941 "the index table\n",
23942 arch.sym_size - l),
dda8d76d 23943 filedata->file_name, arch.sym_size - l);
015dc7e1 23944 ret = false;
32ec8896 23945 }
4145f1d5 23946
63cf857e 23947 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23948 {
1cb7d8b1
AM
23949 error (_("%s: failed to seek back to start of object files "
23950 "in the archive\n"),
dda8d76d 23951 filedata->file_name);
015dc7e1 23952 ret = false;
2cf0635d 23953 goto out;
4145f1d5 23954 }
fb52b2f4 23955 }
4145f1d5
NC
23956
23957 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23958 && !do_segments && !do_header && !do_dump && !do_version
23959 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23960 && !do_section_groups && !do_dyn_syms)
2cf0635d 23961 {
015dc7e1 23962 ret = true; /* Archive index only. */
2cf0635d
NC
23963 goto out;
23964 }
fb52b2f4
NC
23965 }
23966
fb52b2f4
NC
23967 while (1)
23968 {
2cf0635d
NC
23969 char * name;
23970 size_t namelen;
23971 char * qualified_name;
23972
23973 /* Read the next archive header. */
63cf857e 23974 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23975 {
23976 error (_("%s: failed to seek to next archive header\n"),
23977 arch.file_name);
015dc7e1 23978 ret = false;
1cb7d8b1
AM
23979 break;
23980 }
dda8d76d 23981 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23982 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23983 {
23984 if (got == 0)
2cf0635d 23985 break;
28e817cc
NC
23986 /* PR 24049 - we cannot use filedata->file_name as this will
23987 have already been freed. */
23988 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23989
015dc7e1 23990 ret = false;
1cb7d8b1
AM
23991 break;
23992 }
2cf0635d 23993 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23994 {
23995 error (_("%s: did not find a valid archive header\n"),
23996 arch.file_name);
015dc7e1 23997 ret = false;
1cb7d8b1
AM
23998 break;
23999 }
2cf0635d
NC
24000
24001 arch.next_arhdr_offset += sizeof arch.arhdr;
24002
978c4450 24003 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
24004
24005 name = get_archive_member_name (&arch, &nested_arch);
24006 if (name == NULL)
fb52b2f4 24007 {
28e817cc 24008 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 24009 ret = false;
d989285c 24010 break;
fb52b2f4 24011 }
2cf0635d 24012 namelen = strlen (name);
fb52b2f4 24013
2cf0635d
NC
24014 qualified_name = make_qualified_name (&arch, &nested_arch, name);
24015 if (qualified_name == NULL)
fb52b2f4 24016 {
28e817cc 24017 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 24018 free (name);
015dc7e1 24019 ret = false;
d989285c 24020 break;
fb52b2f4
NC
24021 }
24022
2cf0635d 24023 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
24024 {
24025 /* This is a proxy for an external member of a thin archive. */
24026 Filedata * member_filedata;
24027 char * member_file_name = adjust_relative_path
dda8d76d 24028 (filedata->file_name, name, namelen);
32ec8896 24029
fd486f32 24030 free (name);
1cb7d8b1
AM
24031 if (member_file_name == NULL)
24032 {
fd486f32 24033 free (qualified_name);
015dc7e1 24034 ret = false;
1cb7d8b1
AM
24035 break;
24036 }
2cf0635d 24037
015dc7e1 24038 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
24039 if (member_filedata == NULL)
24040 {
24041 error (_("Input file '%s' is not readable.\n"), member_file_name);
24042 free (member_file_name);
fd486f32 24043 free (qualified_name);
015dc7e1 24044 ret = false;
1cb7d8b1
AM
24045 break;
24046 }
2cf0635d 24047
978c4450 24048 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 24049 member_filedata->file_name = qualified_name;
2cf0635d 24050
75a2da57
AH
24051 /* The call to process_object() expects the file to be at the beginning. */
24052 rewind (member_filedata->handle);
24053
1cb7d8b1 24054 if (! process_object (member_filedata))
015dc7e1 24055 ret = false;
2cf0635d 24056
1cb7d8b1
AM
24057 close_file (member_filedata);
24058 free (member_file_name);
1cb7d8b1 24059 }
2cf0635d 24060 else if (is_thin_archive)
1cb7d8b1
AM
24061 {
24062 Filedata thin_filedata;
eb02c04d 24063
1cb7d8b1 24064 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 24065
a043396b
NC
24066 /* PR 15140: Allow for corrupt thin archives. */
24067 if (nested_arch.file == NULL)
24068 {
24069 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 24070 qualified_name, name);
fd486f32
AM
24071 free (qualified_name);
24072 free (name);
015dc7e1 24073 ret = false;
a043396b
NC
24074 break;
24075 }
fd486f32 24076 free (name);
a043396b 24077
1cb7d8b1 24078 /* This is a proxy for a member of a nested archive. */
978c4450
AM
24079 filedata->archive_file_offset
24080 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 24081
1cb7d8b1
AM
24082 /* The nested archive file will have been opened and setup by
24083 get_archive_member_name. */
63cf857e
AM
24084 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
24085 SEEK_SET) != 0)
1cb7d8b1
AM
24086 {
24087 error (_("%s: failed to seek to archive member.\n"),
24088 nested_arch.file_name);
fd486f32 24089 free (qualified_name);
015dc7e1 24090 ret = false;
1cb7d8b1
AM
24091 break;
24092 }
2cf0635d 24093
dda8d76d
NC
24094 thin_filedata.handle = nested_arch.file;
24095 thin_filedata.file_name = qualified_name;
9abca702 24096
1cb7d8b1 24097 if (! process_object (& thin_filedata))
015dc7e1 24098 ret = false;
1cb7d8b1 24099 }
2cf0635d 24100 else
1cb7d8b1 24101 {
fd486f32 24102 free (name);
978c4450 24103 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 24104 filedata->file_name = qualified_name;
1cb7d8b1 24105 if (! process_object (filedata))
015dc7e1 24106 ret = false;
237877b8 24107 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 24108 /* Stop looping with "negative" archive_file_size. */
978c4450 24109 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 24110 arch.next_arhdr_offset = -1ul;
1cb7d8b1 24111 }
fb52b2f4 24112
2cf0635d 24113 free (qualified_name);
fb52b2f4
NC
24114 }
24115
4145f1d5 24116 out:
2cf0635d
NC
24117 if (nested_arch.file != NULL)
24118 fclose (nested_arch.file);
24119 release_archive (&nested_arch);
24120 release_archive (&arch);
fb52b2f4 24121
d989285c 24122 return ret;
fb52b2f4
NC
24123}
24124
015dc7e1 24125static bool
2cf0635d 24126process_file (char * file_name)
fb52b2f4 24127{
dda8d76d 24128 Filedata * filedata = NULL;
fb52b2f4
NC
24129 struct stat statbuf;
24130 char armag[SARMAG];
015dc7e1 24131 bool ret = true;
fb52b2f4
NC
24132
24133 if (stat (file_name, &statbuf) < 0)
24134 {
f24ddbdd
NC
24135 if (errno == ENOENT)
24136 error (_("'%s': No such file\n"), file_name);
24137 else
24138 error (_("Could not locate '%s'. System error message: %s\n"),
24139 file_name, strerror (errno));
015dc7e1 24140 return false;
f24ddbdd
NC
24141 }
24142
24143 if (! S_ISREG (statbuf.st_mode))
24144 {
24145 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 24146 return false;
fb52b2f4
NC
24147 }
24148
dda8d76d
NC
24149 filedata = calloc (1, sizeof * filedata);
24150 if (filedata == NULL)
24151 {
24152 error (_("Out of memory allocating file data structure\n"));
015dc7e1 24153 return false;
dda8d76d
NC
24154 }
24155
24156 filedata->file_name = file_name;
24157 filedata->handle = fopen (file_name, "rb");
24158 if (filedata->handle == NULL)
fb52b2f4 24159 {
f24ddbdd 24160 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 24161 free (filedata);
015dc7e1 24162 return false;
fb52b2f4
NC
24163 }
24164
dda8d76d 24165 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 24166 {
4145f1d5 24167 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
24168 fclose (filedata->handle);
24169 free (filedata);
015dc7e1 24170 return false;
fb52b2f4
NC
24171 }
24172
be7d229a 24173 filedata->file_size = statbuf.st_size;
015dc7e1 24174 filedata->is_separate = false;
f54498b4 24175
fb52b2f4 24176 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 24177 {
015dc7e1
AM
24178 if (! process_archive (filedata, false))
24179 ret = false;
32ec8896 24180 }
2cf0635d 24181 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 24182 {
015dc7e1
AM
24183 if ( ! process_archive (filedata, true))
24184 ret = false;
32ec8896 24185 }
fb52b2f4
NC
24186 else
24187 {
1b513401 24188 if (do_archive_index && !check_all)
4145f1d5
NC
24189 error (_("File %s is not an archive so its index cannot be displayed.\n"),
24190 file_name);
24191
dda8d76d 24192 rewind (filedata->handle);
978c4450 24193 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 24194
dda8d76d 24195 if (! process_object (filedata))
015dc7e1 24196 ret = false;
fb52b2f4
NC
24197 }
24198
dda8d76d 24199 fclose (filedata->handle);
8fb879cd
AM
24200 free (filedata->section_headers);
24201 free (filedata->program_headers);
24202 free (filedata->string_table);
6431e409 24203 free (filedata->dump.dump_sects);
dda8d76d 24204 free (filedata);
32ec8896 24205
fd486f32 24206 free (ba_cache.strtab);
1bd6175a 24207 ba_cache.strtab = NULL;
fd486f32 24208 free (ba_cache.symtab);
1bd6175a 24209 ba_cache.symtab = NULL;
fd486f32
AM
24210 ba_cache.filedata = NULL;
24211
fb52b2f4
NC
24212 return ret;
24213}
24214
252b5132
RH
24215#ifdef SUPPORT_DISASSEMBLY
24216/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 24217 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 24218 symbols. */
252b5132
RH
24219
24220void
2cf0635d 24221print_address (unsigned int addr, FILE * outfile)
252b5132
RH
24222{
24223 fprintf (outfile,"0x%8.8x", addr);
24224}
24225
e3c8793a 24226/* Needed by the i386 disassembler. */
dda8d76d 24227
252b5132
RH
24228void
24229db_task_printsym (unsigned int addr)
24230{
24231 print_address (addr, stderr);
24232}
24233#endif
24234
24235int
2cf0635d 24236main (int argc, char ** argv)
252b5132 24237{
ff78d6d6
L
24238 int err;
24239
87b9f255 24240#ifdef HAVE_LC_MESSAGES
252b5132 24241 setlocale (LC_MESSAGES, "");
3882b010 24242#endif
3882b010 24243 setlocale (LC_CTYPE, "");
252b5132
RH
24244 bindtextdomain (PACKAGE, LOCALEDIR);
24245 textdomain (PACKAGE);
24246
869b9d07
MM
24247 expandargv (&argc, &argv);
24248
dda8d76d 24249 parse_args (& cmdline, argc, argv);
59f14fc0 24250
18bd398b 24251 if (optind < (argc - 1))
1b513401
NC
24252 /* When displaying information for more than one file,
24253 prefix the information with the file name. */
015dc7e1 24254 show_name = true;
5656ba2c
L
24255 else if (optind >= argc)
24256 {
1b513401 24257 /* Ensure that the warning is always displayed. */
015dc7e1 24258 do_checks = true;
1b513401 24259
5656ba2c
L
24260 warn (_("Nothing to do.\n"));
24261 usage (stderr);
24262 }
18bd398b 24263
015dc7e1 24264 err = false;
252b5132 24265 while (optind < argc)
32ec8896 24266 if (! process_file (argv[optind++]))
015dc7e1 24267 err = true;
252b5132 24268
9db70fc3 24269 free (cmdline.dump_sects);
252b5132 24270
7d9813f1
NA
24271 free (dump_ctf_symtab_name);
24272 free (dump_ctf_strtab_name);
24273 free (dump_ctf_parent_name);
24274
32ec8896 24275 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 24276}