]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
e8e7cf2a 2 Copyright (C) 1998-2025 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}
5d526bdf 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);
5d526bdf 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;
5d526bdf 803
b3aa80b4
NC
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. */
5d526bdf 814
b3aa80b4
NC
815 switch (nbytes)
816 {
817 case 2:
818 if (width_remaining < 6)
819 break;
820 printf ("\\u%02x%02x",
5d526bdf 821 (bytes[0] & 0x1c) >> 2,
b3aa80b4
NC
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));
5d526bdf 838
b3aa80b4
NC
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 }
5d526bdf 848
b3aa80b4
NC
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
978dae65
NC
890 STRING. Uses a rotating array of static buffers, so that multiple
891 successive calls will still work. eg when used in a call to printf().
892
893 If supplied MAX_LEN is the maximum number of characters to be read
894 starting from STRING.
895
896 This function is similar to print_symbol_name(), except that it does
897 not try to print multibyte characters, it just shows them as hex values.
898
899 If the string is too long for the static buffer or if it is not
900 terminated then a truncated version of the string will be returned. */
74e1a04b
NC
901
902static const char *
978dae65 903printable_string (const char * string, unsigned int max_len)
74e1a04b 904{
978dae65
NC
905#define NUM_STRING_BUFS 5
906#define MAX_STRING_LEN 256
5d526bdf 907
978dae65
NC
908 static int string_buf_index = 0;
909 static char string_buf [NUM_STRING_BUFS][MAX_STRING_LEN + 1];
910
b6ac461a
NC
911 char * buf;
912 char * buf_start;
b6ac461a
NC
913
914 /* Select a buffer to use. */
978dae65
NC
915 buf_start = buf = string_buf[string_buf_index];
916 if (++ string_buf_index >= NUM_STRING_BUFS)
917 string_buf_index = 0;
b6ac461a 918
978dae65
NC
919 char c;
920 unsigned int remaining = MAX_STRING_LEN;
5d526bdf 921
978dae65 922 while ((c = * string ++) != 0)
74e1a04b
NC
923 {
924 if (ISCNTRL (c))
925 {
926 if (remaining < 2)
927 break;
948f632f 928
74e1a04b
NC
929 * buf ++ = '^';
930 * buf ++ = c + 0x40;
931 remaining -= 2;
932 }
933 else if (ISPRINT (c))
934 {
935 * buf ++ = c;
936 remaining -= 1;
937 }
938 else
939 {
940 static char hex[17] = "0123456789ABCDEF";
941
942 if (remaining < 4)
943 break;
944 * buf ++ = '<';
945 * buf ++ = hex[(c & 0xf0) >> 4];
946 * buf ++ = hex[c & 0x0f];
947 * buf ++ = '>';
948 remaining -= 4;
949 }
950
951 if (remaining == 0)
952 break;
978dae65
NC
953
954 if (max_len > 0)
955 {
956 max_len -= 1;
957 if (max_len == 0)
958 break;
959 }
74e1a04b
NC
960 }
961
962 * buf = 0;
5d526bdf 963 return buf_start;
978dae65
NC
964}
965
966/* Returns a pointer to a static buffer containing a
967 printable version of the given section's name. */
968
969static const char *
970printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
971{
972 /* Validate the input parameters. */
973 if (filedata == NULL)
974 return _("<internal error>");
975 if (sec == NULL)
976 return _("<none>");
977 if (filedata->string_table == NULL)
978 return _("<no-strings>");
979 if (sec->sh_name >= filedata->string_table_length)
980 return _("<corrupt>");
981
982 return printable_string (section_name (filedata, sec),
983 filedata->string_table_length - sec->sh_name);
b6ac461a
NC
984}
985
986/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
987 This OS has so many departures from the ELF standard that we test it at
988 many places. */
989
990static inline bool
991is_ia64_vms (Filedata * filedata)
992{
993 return filedata->file_header.e_machine == EM_IA_64
994 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
74e1a04b
NC
995}
996
997static const char *
b6ac461a
NC
998printable_section_name_from_index (Filedata * filedata,
999 size_t ndx,
1000 bool * is_special)
74e1a04b 1001{
b6ac461a
NC
1002 if (is_special != NULL)
1003 * is_special = true;
1004
1005 switch (ndx)
1006 {
1007 case SHN_UNDEF: return "UND";
1008 case SHN_ABS: return "ABS";
1009 case SHN_COMMON: return "COM";
1010 break;
1011 }
1012
1013 if (filedata != NULL)
1014 {
1015 switch (filedata->file_header.e_machine)
1016 {
1017 case EM_MIPS:
1018 if (ndx == SHN_MIPS_SCOMMON)
1019 return "SCOMMON";
1020 if (ndx == SHN_MIPS_SUNDEFINED)
1021 return "SUNDEF";
1022 break;
1023
1024 case EM_TI_C6000:
1025 if (ndx == SHN_TIC6X_SCOMMON)
1026 return "SCOM";
1027 break;
1028
1029 case EM_X86_64:
1030 case EM_L1OM:
1031 case EM_K1OM:
1032 if (ndx == SHN_X86_64_LCOMMON)
1033 return "LARGE_COM";
1034 break;
1035
1036 case EM_IA_64:
1037 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1038 && ndx == SHN_IA_64_ANSI_COMMON)
1039 return "ANSI_COM";
1040
1041 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1042 return "VMS_SYMVEC";
1043 break;
1044
1045 default:
1046 break;
1047 }
74e1a04b 1048
b6ac461a
NC
1049 if (filedata->section_headers != NULL
1050 && ndx < filedata->file_header.e_shnum)
1051 {
1052 const char * res;
1053
1054 res = printable_section_name (filedata, filedata->section_headers + ndx);
1055 if (is_special != NULL)
1056 * is_special = (res[0] == '<');
1057
1058 return res;
1059 }
1060 }
1061
1062 static char name_buf[40];
1063 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1064
1065 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1066 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1067 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1068 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1069 else if (ndx >= SHN_LORESERVE)
1070 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1071 else if (filedata->file_header.e_shnum != 0
1072 && ndx >= filedata->file_header.e_shnum)
1073 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1074 else
1075 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1076
1077 return name_buf;
74e1a04b
NC
1078}
1079
89fac5e3
RS
1080/* Return a pointer to section NAME, or NULL if no such section exists. */
1081
1082static Elf_Internal_Shdr *
dda8d76d 1083find_section (Filedata * filedata, const char * name)
89fac5e3
RS
1084{
1085 unsigned int i;
1086
68807c3c
NC
1087 if (filedata->section_headers == NULL)
1088 return NULL;
dda8d76d
NC
1089
1090 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
1091 if (section_name_valid (filedata, filedata->section_headers + i)
1092 && streq (section_name (filedata, filedata->section_headers + i),
1093 name))
dda8d76d 1094 return filedata->section_headers + i;
89fac5e3
RS
1095
1096 return NULL;
1097}
1098
0b6ae522
DJ
1099/* Return a pointer to a section containing ADDR, or NULL if no such
1100 section exists. */
1101
1102static Elf_Internal_Shdr *
625d49fc 1103find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
1104{
1105 unsigned int i;
1106
68807c3c
NC
1107 if (filedata->section_headers == NULL)
1108 return NULL;
1109
dda8d76d 1110 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 1111 {
dda8d76d
NC
1112 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1113
0b6ae522
DJ
1114 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1115 return sec;
1116 }
1117
1118 return NULL;
1119}
1120
071436c6 1121static Elf_Internal_Shdr *
dda8d76d 1122find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
1123{
1124 unsigned int i;
1125
68807c3c
NC
1126 if (filedata->section_headers == NULL)
1127 return NULL;
1128
dda8d76d 1129 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 1130 {
dda8d76d
NC
1131 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1132
071436c6
NC
1133 if (sec->sh_type == type)
1134 return sec;
1135 }
1136
1137 return NULL;
1138}
1139
fcf8f323
NC
1140static Elf_Internal_Shdr *
1141find_section_by_name (Filedata * filedata, const char * name)
1142{
1143 unsigned int i;
1144
1145 if (filedata->section_headers == NULL || filedata->string_table_length == 0)
1146 return NULL;
1147
1148 for (i = 0; i < filedata->file_header.e_shnum; i++)
1149 {
1150 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1151
1152 if (sec->sh_name < filedata->string_table_length
1153 && streq (name, filedata->string_table + sec->sh_name))
1154 return sec;
1155 }
1156
1157 return NULL;
1158}
1159
657d0d47
CC
1160/* Return a pointer to section NAME, or NULL if no such section exists,
1161 restricted to the list of sections given in SET. */
1162
1163static Elf_Internal_Shdr *
dda8d76d 1164find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
1165{
1166 unsigned int i;
1167
68807c3c
NC
1168 if (filedata->section_headers == NULL)
1169 return NULL;
1170
657d0d47
CC
1171 if (set != NULL)
1172 {
1173 while ((i = *set++) > 0)
b814a36d
NC
1174 {
1175 /* See PR 21156 for a reproducer. */
dda8d76d 1176 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1177 continue; /* FIXME: Should we issue an error message ? */
1178
84714f86
AM
1179 if (section_name_valid (filedata, filedata->section_headers + i)
1180 && streq (section_name (filedata, filedata->section_headers + i),
1181 name))
dda8d76d 1182 return filedata->section_headers + i;
b814a36d 1183 }
657d0d47
CC
1184 }
1185
dda8d76d 1186 return find_section (filedata, name);
657d0d47
CC
1187}
1188
bcedfee6 1189/* Guess the relocation size commonly used by the specific machines. */
252b5132 1190
015dc7e1 1191static bool
2dc4cec1 1192guess_is_rela (unsigned int e_machine)
252b5132 1193{
9c19a809 1194 switch (e_machine)
252b5132
RH
1195 {
1196 /* Targets that use REL relocations. */
252b5132 1197 case EM_386:
22abe556 1198 case EM_IAMCU:
f954747f 1199 case EM_960:
e9f53129 1200 case EM_ARM:
2b0337b0 1201 case EM_D10V:
252b5132 1202 case EM_CYGNUS_D10V:
e9f53129 1203 case EM_DLX:
252b5132 1204 case EM_MIPS:
4fe85591 1205 case EM_MIPS_RS3_LE:
e9f53129 1206 case EM_CYGNUS_M32R:
1c0d3aa6 1207 case EM_SCORE:
f6c1a2d5 1208 case EM_XGATE:
fe944acf 1209 case EM_NFP:
aca4efc7 1210 case EM_BPF:
015dc7e1 1211 return false;
103f02d3 1212
252b5132
RH
1213 /* Targets that use RELA relocations. */
1214 case EM_68K:
f954747f 1215 case EM_860:
a06ea964 1216 case EM_AARCH64:
cfb8c092 1217 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1218 case EM_ALPHA:
1219 case EM_ALTERA_NIOS2:
886a2506
NC
1220 case EM_ARC:
1221 case EM_ARC_COMPACT:
1222 case EM_ARC_COMPACT2:
b5c37946
SJ
1223 case EM_ARC_COMPACT3:
1224 case EM_ARC_COMPACT3_64:
e9f53129
AM
1225 case EM_AVR:
1226 case EM_AVR_OLD:
1227 case EM_BLACKFIN:
60bca95a 1228 case EM_CR16:
e9f53129
AM
1229 case EM_CRIS:
1230 case EM_CRX:
b8891f8d 1231 case EM_CSKY:
2b0337b0 1232 case EM_D30V:
252b5132 1233 case EM_CYGNUS_D30V:
2b0337b0 1234 case EM_FR30:
3f8107ab 1235 case EM_FT32:
252b5132 1236 case EM_CYGNUS_FR30:
5c70f934 1237 case EM_CYGNUS_FRV:
e9f53129
AM
1238 case EM_H8S:
1239 case EM_H8_300:
1240 case EM_H8_300H:
800eeca4 1241 case EM_IA_64:
1e4cf259
NC
1242 case EM_IP2K:
1243 case EM_IP2K_OLD:
3b36097d 1244 case EM_IQ2000:
6e712424 1245 case EM_KVX:
84e94c90 1246 case EM_LATTICEMICO32:
ff7eeb89 1247 case EM_M32C_OLD:
49f58d10 1248 case EM_M32C:
e9f53129
AM
1249 case EM_M32R:
1250 case EM_MCORE:
15ab5209 1251 case EM_CYGNUS_MEP:
a3c62988 1252 case EM_METAG:
e9f53129
AM
1253 case EM_MMIX:
1254 case EM_MN10200:
1255 case EM_CYGNUS_MN10200:
1256 case EM_MN10300:
1257 case EM_CYGNUS_MN10300:
5506d11a 1258 case EM_MOXIE:
e9f53129
AM
1259 case EM_MSP430:
1260 case EM_MSP430_OLD:
d031aafb 1261 case EM_MT:
35c08157 1262 case EM_NDS32:
64fd6348 1263 case EM_NIOS32:
73589c9d 1264 case EM_OR1K:
e9f53129
AM
1265 case EM_PPC64:
1266 case EM_PPC:
2b100bb5 1267 case EM_TI_PRU:
e23eba97 1268 case EM_RISCV:
99c513f6 1269 case EM_RL78:
c7927a3c 1270 case EM_RX:
e9f53129
AM
1271 case EM_S390:
1272 case EM_S390_OLD:
1273 case EM_SH:
1274 case EM_SPARC:
1275 case EM_SPARC32PLUS:
1276 case EM_SPARCV9:
1277 case EM_SPU:
40b36596 1278 case EM_TI_C6000:
aa137e4d
NC
1279 case EM_TILEGX:
1280 case EM_TILEPRO:
708e2187 1281 case EM_V800:
e9f53129
AM
1282 case EM_V850:
1283 case EM_CYGNUS_V850:
1284 case EM_VAX:
619ed720 1285 case EM_VISIUM:
e9f53129 1286 case EM_X86_64:
8a9036a4 1287 case EM_L1OM:
7a9068fe 1288 case EM_K1OM:
e9f53129
AM
1289 case EM_XSTORMY16:
1290 case EM_XTENSA:
1291 case EM_XTENSA_OLD:
7ba29e2a
NC
1292 case EM_MICROBLAZE:
1293 case EM_MICROBLAZE_OLD:
f96bd6c2 1294 case EM_WEBASSEMBLY:
015dc7e1 1295 return true;
103f02d3 1296
e9f53129
AM
1297 case EM_68HC05:
1298 case EM_68HC08:
1299 case EM_68HC11:
1300 case EM_68HC16:
1301 case EM_FX66:
1302 case EM_ME16:
d1133906 1303 case EM_MMA:
d1133906
NC
1304 case EM_NCPU:
1305 case EM_NDR1:
e9f53129 1306 case EM_PCP:
d1133906 1307 case EM_ST100:
e9f53129 1308 case EM_ST19:
d1133906 1309 case EM_ST7:
e9f53129
AM
1310 case EM_ST9PLUS:
1311 case EM_STARCORE:
d1133906 1312 case EM_SVX:
e9f53129 1313 case EM_TINYJ:
9c19a809
NC
1314 default:
1315 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1316 return false;
9c19a809
NC
1317 }
1318}
252b5132 1319
dda8d76d 1320/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1321 Returns TRUE upon success, FALSE otherwise. If successful then a
1322 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1323 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1324 responsibility to free the allocated buffer. */
1325
015dc7e1 1326static bool
26c527e6
AM
1327slurp_rela_relocs (Filedata *filedata,
1328 uint64_t rel_offset,
1329 uint64_t rel_size,
1330 Elf_Internal_Rela **relasp,
1331 uint64_t *nrelasp)
9c19a809 1332{
2cf0635d 1333 Elf_Internal_Rela * relas;
26c527e6 1334 uint64_t nrelas;
4d6ed7c8 1335 unsigned int i;
252b5132 1336
4d6ed7c8
NC
1337 if (is_32bit_elf)
1338 {
2cf0635d 1339 Elf32_External_Rela * erelas;
103f02d3 1340
dda8d76d 1341 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1342 rel_size, _("32-bit relocation data"));
a6e9f9df 1343 if (!erelas)
015dc7e1 1344 return false;
252b5132 1345
4d6ed7c8 1346 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1347
3f5e193b
NC
1348 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1349 sizeof (Elf_Internal_Rela));
103f02d3 1350
4d6ed7c8
NC
1351 if (relas == NULL)
1352 {
c256ffe7 1353 free (erelas);
591a748a 1354 error (_("out of memory parsing relocs\n"));
015dc7e1 1355 return false;
4d6ed7c8 1356 }
103f02d3 1357
4d6ed7c8
NC
1358 for (i = 0; i < nrelas; i++)
1359 {
1360 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1361 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1362 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1363 }
103f02d3 1364
4d6ed7c8
NC
1365 free (erelas);
1366 }
1367 else
1368 {
2cf0635d 1369 Elf64_External_Rela * erelas;
103f02d3 1370
dda8d76d 1371 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1372 rel_size, _("64-bit relocation data"));
a6e9f9df 1373 if (!erelas)
015dc7e1 1374 return false;
4d6ed7c8
NC
1375
1376 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1377
3f5e193b
NC
1378 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1379 sizeof (Elf_Internal_Rela));
103f02d3 1380
4d6ed7c8
NC
1381 if (relas == NULL)
1382 {
c256ffe7 1383 free (erelas);
591a748a 1384 error (_("out of memory parsing relocs\n"));
015dc7e1 1385 return false;
9c19a809 1386 }
4d6ed7c8
NC
1387
1388 for (i = 0; i < nrelas; i++)
9c19a809 1389 {
66543521
AM
1390 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1391 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1392 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1393
dda8d76d
NC
1394 if (filedata->file_header.e_machine == EM_MIPS
1395 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1396 {
1397 /* In little-endian objects, r_info isn't really a
1398 64-bit little-endian value: it has a 32-bit
1399 little-endian symbol index followed by four
1400 individual byte fields. Reorder INFO
1401 accordingly. */
625d49fc 1402 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1403 inf = (((inf & 0xffffffff) << 32)
1404 | ((inf >> 56) & 0xff)
1405 | ((inf >> 40) & 0xff00)
1406 | ((inf >> 24) & 0xff0000)
1407 | ((inf >> 8) & 0xff000000));
1408 relas[i].r_info = inf;
861fb55a 1409 }
4d6ed7c8 1410 }
103f02d3 1411
4d6ed7c8
NC
1412 free (erelas);
1413 }
32ec8896 1414
4d6ed7c8
NC
1415 *relasp = relas;
1416 *nrelasp = nrelas;
015dc7e1 1417 return true;
4d6ed7c8 1418}
103f02d3 1419
dda8d76d 1420/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1421 Returns TRUE upon success, FALSE otherwise. If successful then a
1422 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1423 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1424 responsibility to free the allocated buffer. */
1425
015dc7e1 1426static bool
26c527e6
AM
1427slurp_rel_relocs (Filedata *filedata,
1428 uint64_t rel_offset,
1429 uint64_t rel_size,
1430 Elf_Internal_Rela **relsp,
1431 uint64_t *nrelsp)
4d6ed7c8 1432{
2cf0635d 1433 Elf_Internal_Rela * rels;
26c527e6 1434 uint64_t nrels;
4d6ed7c8 1435 unsigned int i;
103f02d3 1436
4d6ed7c8
NC
1437 if (is_32bit_elf)
1438 {
2cf0635d 1439 Elf32_External_Rel * erels;
103f02d3 1440
dda8d76d 1441 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1442 rel_size, _("32-bit relocation data"));
a6e9f9df 1443 if (!erels)
015dc7e1 1444 return false;
103f02d3 1445
4d6ed7c8 1446 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1447
3f5e193b 1448 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1449
4d6ed7c8
NC
1450 if (rels == NULL)
1451 {
c256ffe7 1452 free (erels);
591a748a 1453 error (_("out of memory parsing relocs\n"));
015dc7e1 1454 return false;
4d6ed7c8
NC
1455 }
1456
1457 for (i = 0; i < nrels; i++)
1458 {
1459 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1460 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1461 rels[i].r_addend = 0;
9ea033b2 1462 }
4d6ed7c8
NC
1463
1464 free (erels);
9c19a809
NC
1465 }
1466 else
1467 {
2cf0635d 1468 Elf64_External_Rel * erels;
9ea033b2 1469
dda8d76d 1470 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1471 rel_size, _("64-bit relocation data"));
a6e9f9df 1472 if (!erels)
015dc7e1 1473 return false;
103f02d3 1474
4d6ed7c8 1475 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1476
3f5e193b 1477 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1478
4d6ed7c8 1479 if (rels == NULL)
9c19a809 1480 {
c256ffe7 1481 free (erels);
591a748a 1482 error (_("out of memory parsing relocs\n"));
015dc7e1 1483 return false;
4d6ed7c8 1484 }
103f02d3 1485
4d6ed7c8
NC
1486 for (i = 0; i < nrels; i++)
1487 {
66543521
AM
1488 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1489 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1490 rels[i].r_addend = 0;
861fb55a 1491
dda8d76d
NC
1492 if (filedata->file_header.e_machine == EM_MIPS
1493 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1494 {
1495 /* In little-endian objects, r_info isn't really a
1496 64-bit little-endian value: it has a 32-bit
1497 little-endian symbol index followed by four
1498 individual byte fields. Reorder INFO
1499 accordingly. */
625d49fc 1500 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1501 inf = (((inf & 0xffffffff) << 32)
1502 | ((inf >> 56) & 0xff)
1503 | ((inf >> 40) & 0xff00)
1504 | ((inf >> 24) & 0xff0000)
1505 | ((inf >> 8) & 0xff000000));
1506 rels[i].r_info = inf;
861fb55a 1507 }
4d6ed7c8 1508 }
103f02d3 1509
4d6ed7c8
NC
1510 free (erels);
1511 }
32ec8896 1512
4d6ed7c8
NC
1513 *relsp = rels;
1514 *nrelsp = nrels;
015dc7e1 1515 return true;
4d6ed7c8 1516}
103f02d3 1517
aca88567
NC
1518/* Returns the reloc type extracted from the reloc info field. */
1519
1520static unsigned int
625d49fc 1521get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1522{
1523 if (is_32bit_elf)
1524 return ELF32_R_TYPE (reloc_info);
1525
dda8d76d 1526 switch (filedata->file_header.e_machine)
aca88567
NC
1527 {
1528 case EM_MIPS:
1529 /* Note: We assume that reloc_info has already been adjusted for us. */
1530 return ELF64_MIPS_R_TYPE (reloc_info);
1531
1532 case EM_SPARCV9:
1533 return ELF64_R_TYPE_ID (reloc_info);
1534
1535 default:
1536 return ELF64_R_TYPE (reloc_info);
1537 }
1538}
1539
1540/* Return the symbol index extracted from the reloc info field. */
1541
625d49fc
AM
1542static uint64_t
1543get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1544{
1545 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1546}
1547
015dc7e1 1548static inline bool
dda8d76d 1549uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1550{
1551 return
dda8d76d 1552 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1553 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1554 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1555 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1556 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1557}
1558
fcf8f323
NC
1559
1560static const char *
d565a958
SN
1561get_symbol_at (Filedata * filedata,
1562 Elf_Internal_Sym * symtab,
fcf8f323
NC
1563 uint64_t nsyms,
1564 char * strtab,
fcf8f323
NC
1565 uint64_t where,
1566 uint64_t * offset_return)
1567{
1568 Elf_Internal_Sym * beg = symtab;
1569 Elf_Internal_Sym * end = symtab + nsyms;
1570 Elf_Internal_Sym * best = NULL;
1571 uint64_t dist = 0x100000;
1572
1573 /* FIXME: Since this function is likely to be called repeatedly with
1574 slightly increasing addresses each time, we could speed things up by
1575 caching the last returned value and starting our search from there. */
1576 while (beg < end)
1577 {
1578 Elf_Internal_Sym * sym;
1579 uint64_t value;
1580
1581 sym = beg + (end - beg) / 2;
1582
1583 value = sym->st_value;
1584
d41629d3 1585 if (where >= value
fcf8f323
NC
1586 && where - value < dist)
1587 {
1588 best = sym;
1589 dist = where - value;
1590 if (dist == 0)
1591 break;
1592 }
1593
1594 if (where < value)
1595 end = sym;
1596 else
1597 beg = sym + 1;
1598 }
1599
d565a958
SN
1600 const char *name;
1601
1602 /* If there is a section start closer than the found symbol then
1603 use that for symbolizing the address. */
1604 Elf_Internal_Shdr *sec = find_section_by_address (filedata, where);
1605 if (sec != NULL
1606 && where - sec->sh_addr < dist
1607 && section_name_valid (filedata, sec))
1608 {
1609 name = section_name (filedata, sec);
1610 dist = where - sec->sh_addr;
1611 }
1612 else if (best != NULL)
1613 name = strtab + best->st_name;
1614 else
fcf8f323
NC
1615 return NULL;
1616
fcf8f323
NC
1617 if (offset_return != NULL)
1618 * offset_return = dist;
1619
d565a958 1620 return name;
fcf8f323
NC
1621}
1622
1623static void
d565a958
SN
1624print_relr_addr_and_sym (Filedata * filedata,
1625 Elf_Internal_Sym * symtab,
fcf8f323
NC
1626 uint64_t nsyms,
1627 char * strtab,
fcf8f323
NC
1628 uint64_t where)
1629{
1630 const char * symname = NULL;
1631 uint64_t offset = 0;
1632
1633 print_vma (where, ZERO_HEX);
1634 printf (" ");
1635
d565a958 1636 symname = get_symbol_at (filedata, symtab, nsyms, strtab, where, & offset);
fcf8f323
NC
1637
1638 if (symname == NULL)
1639 printf ("<no sym>");
1640 else if (offset == 0)
1641 print_symbol_name (38, symname);
1642 else
1643 {
1644 print_symbol_name (28, symname);
1645 printf (" + ");
1646 print_vma (offset, PREFIX_HEX);
1647 }
1648}
1649
d41629d3
SN
1650/* See bfd_is_aarch64_special_symbol_name. */
1651
1652static bool
1653is_aarch64_special_symbol_name (const char *name)
1654{
1655 if (!name || name[0] != '$')
1656 return false;
1657 if (name[1] == 'x' || name[1] == 'd')
1658 /* Map. */;
1659 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
1660 /* Tag. */;
1661 else
1662 return false;
1663 return name[2] == 0 || name[2] == '.';
1664}
1665
1666static bool
1667is_special_symbol_name (Filedata * filedata, const char * s)
1668{
1669 switch (filedata->file_header.e_machine)
1670 {
1671 case EM_AARCH64:
1672 return is_aarch64_special_symbol_name (s);
1673
1674 default:
1675 return false;
1676 }
1677}
1678
1679/* Allows selecting the best symbol from a set for displaying addresses.
1680 BEST is the current best or NULL if there are no good symbols yet.
1681 SYM is the next symbol to consider, if it is better than BEST then
1682 return SYM else return BEST. */
1683
1684static Elf_Internal_Sym *
1685select_display_sym (Filedata * filedata,
1686 char * strtab,
1687 uint64_t strtablen,
1688 Elf_Internal_Sym * best,
1689 Elf_Internal_Sym * sym)
1690{
1691 /* Ignore empty or invalid syms. */
1692 if (sym->st_name == 0)
1693 return best;
1694 if (sym->st_name >= strtablen)
1695 return best;
1696 /* Ignore undefined or TLS syms. */
1697 if (sym->st_shndx == SHN_UNDEF)
1698 return best;
1699 if (ELF_ST_TYPE (sym->st_info) == STT_TLS)
1700 return best;
1701
1702 char *s = strtab + sym->st_name;
1703
1704 /* Don't display special symbols. */
1705 if (is_special_symbol_name (filedata, s))
1706 return best;
1707
1708 /* Here SYM is good for display. */
1709
1710 if (best == NULL)
1711 return sym;
1712
1713 char *sbest = strtab + best->st_name;
1714
1715 /* Prefer non-local symbols. */
1716 if (ELF_ST_BIND (sym->st_info) == STB_LOCAL
1717 && ELF_ST_BIND (best->st_info) != STB_LOCAL)
1718 return best;
1719 if (ELF_ST_BIND (sym->st_info) != STB_LOCAL
1720 && ELF_ST_BIND (best->st_info) == STB_LOCAL)
1721 return sym;
1722
1723 /* Select based on lexicographic order. */
1724 return strcmp (s, sbest) < 0 ? sym : best;
1725}
1726
1727/* Filter the sorted SYMTAB symbol array in-place to select at most one
1728 symbol for an address and drop symbols that are not good to display.
1729 Returns the new array length. */
1730
1731static uint64_t
1732filter_display_syms (Filedata * filedata,
1733 Elf_Internal_Sym * symtab,
1734 uint64_t nsyms,
1735 char * strtab,
1736 uint64_t strtablen)
1737{
1738 Elf_Internal_Sym *r = symtab;
1739 Elf_Internal_Sym *w = symtab;
1740 Elf_Internal_Sym *best = NULL;
1741 Elf_Internal_Sym *end = symtab + nsyms;
1742 while (r < end)
1743 {
1744 /* Select the best symbol for an address. */
1745 while (r < end
1746 && (best == NULL || best->st_value == r->st_value))
1747 {
1748 best = select_display_sym (filedata, strtab, strtablen, best, r);
1749 r++;
1750 }
1751 if (best != NULL)
1752 {
1753 *w = *best;
1754 w++;
1755 best = NULL;
1756 }
1757 }
1758 return w - symtab;
1759}
1760
fcf8f323
NC
1761static /* signed */ int
1762symcmp (const void *p, const void *q)
1763{
1764 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1765 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1766
1767 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1768}
1769
3b3e2090
NC
1770static uint64_t
1771count_relr_relocations (Filedata * filedata,
1772 Elf_Internal_Shdr * section)
1773{
1774 uint64_t * relrs;
1775 uint64_t nentries;
1776 uint64_t i;
1777 uint64_t count;
1778 int entsize;
1779
1780 if (section == NULL
1781 || section->sh_type != SHT_RELR
1782 || section->sh_size == 0)
1783 return 0;
1784
1785 entsize = section->sh_entsize;
1786 if (entsize == 0)
1787 entsize = is_32bit_elf
1788 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1789 else if (entsize != sizeof (Elf32_External_Relr)
1790 && entsize != sizeof (Elf64_External_Relr))
1791 return 0;
1792
1793 nentries = section->sh_size / entsize;
1794 if (nentries == 0)
1795 return 0;
5d526bdf 1796
3b3e2090
NC
1797 /* FIXME: This call to get_data duplicates one that follows in
1798 dump_relr_relocations(). They could be combined into just
1799 one call. */
1800 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1801 section->sh_size, _("RELR relocation data"));
1802 if (relrs == NULL)
1803 return 0;
1804
1805 for (count = i = 0; i < nentries; i++)
1806 {
1807 uint64_t entry;
1808
1809 if (entsize == sizeof (Elf32_External_Relr))
1810 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1811 else
1812 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1813
1814 if ((entry & 1) == 0)
1815 {
1816 ++ count;
1817 }
1818 else
1819 {
1820 if (entry == 1)
1821 continue;
1822
1823 for (; entry >>= 1;)
1824 if ((entry & 1) == 1)
1825 ++ count;
1826 }
1827 }
1828
1829 free (relrs);
1830 return count;
1831}
1832
fcf8f323
NC
1833static bool
1834dump_relr_relocations (Filedata * filedata,
1835 Elf_Internal_Shdr * section,
1836 Elf_Internal_Sym * symtab,
1837 uint64_t nsyms,
1838 char * strtab,
1839 uint64_t strtablen)
1840{
1841 uint64_t * relrs;
1842 uint64_t nentries, i;
1843 uint64_t relr_size = section->sh_size;
1844 int relr_entsize = section->sh_entsize;
1845 uint64_t relr_offset = section->sh_offset;
1846 uint64_t where = 0;
1847 int num_bits_in_entry;
1848
fcf8f323 1849 if (relr_entsize == 0)
3b3e2090
NC
1850 relr_entsize = is_32bit_elf
1851 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
fcf8f323
NC
1852
1853 nentries = relr_size / relr_entsize;
1854
3b3e2090
NC
1855 if (nentries == 0)
1856 return true;
1857
fcf8f323
NC
1858 if (relr_entsize == sizeof (Elf32_External_Relr))
1859 num_bits_in_entry = 31;
1860 else if (relr_entsize == sizeof (Elf64_External_Relr))
1861 num_bits_in_entry = 63;
1862 else
1863 {
1864 warn (_("Unexpected entsize for RELR section\n"));
1865 return false;
1866 }
fcf8f323 1867
3b3e2090
NC
1868 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1869 if (relrs == NULL)
1870 return false;
1871
d41629d3
SN
1872 /* Paranoia. */
1873 if (strtab == NULL)
1874 strtablen = 0;
1875 if (symtab == NULL)
1876 nsyms = 0;
1877
3b3e2090
NC
1878 if (symtab != NULL)
1879 {
1880 /* Symbol tables are not sorted on address, but we want a quick lookup
1881 for the symbol associated with each address computed below, so sort
d41629d3
SN
1882 the table then filter out unwanted entries. FIXME: This assumes that
1883 the symbol table will not be used later on for some other purpose. */
3b3e2090 1884 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
d41629d3 1885 nsyms = filter_display_syms (filedata, symtab, nsyms, strtab, strtablen);
3b3e2090
NC
1886 }
1887
1888 if (relr_entsize == sizeof (Elf32_External_Relr))
21061c38 1889 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323 1890 else
21061c38 1891 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323
NC
1892
1893 for (i = 0; i < nentries; i++)
1894 {
1895 uint64_t entry;
1896
3b3e2090 1897 if (relr_entsize == sizeof (Elf32_External_Relr))
fcf8f323
NC
1898 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1899 else
1900 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1901
1902 /* We assume that there will never be more than 9999 entries. */
1903 printf (_("%04u: "), (unsigned int) i);
1904 print_vma (entry, ZERO_HEX);
1905 printf (" ");
1906
1907 if ((entry & 1) == 0)
1908 {
1909 where = entry;
d565a958 1910 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, where);
fcf8f323
NC
1911 printf ("\n");
1912 where += relr_entsize;
1913 }
1914 else
1915 {
1916 bool first = true;
1917 int j;
1918
1919 /* The least significant bit is ignored. */
1920 if (entry == 1)
3b3e2090
NC
1921 /* This can actually happen when the linker is allowed to shrink
1922 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1923 continue;
fcf8f323
NC
1924 else if (i == 0)
1925 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1926
1927 for (j = 0; entry >>= 1; j++)
1928 if ((entry & 1) == 1)
1929 {
1930 uint64_t addr = where + (j * relr_entsize);
5d526bdf 1931
fcf8f323
NC
1932 if (first)
1933 {
d565a958 1934 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
fcf8f323
NC
1935 first = false;
1936 }
1937 else
1938 {
1939 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
d565a958 1940 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
fcf8f323
NC
1941 }
1942 }
1943
1944 printf ("\n");
1945 where += num_bits_in_entry * relr_entsize;
1946 }
1947 }
1948
1949 free (relrs);
1950 return true;
1951}
5d526bdf 1952
d3ba0551
AM
1953/* Display the contents of the relocation data found at the specified
1954 offset. */
ee42cf8c 1955
015dc7e1 1956static bool
fcf8f323
NC
1957dump_relocations (Filedata * filedata,
1958 uint64_t rel_offset,
1959 uint64_t rel_size,
1960 Elf_Internal_Sym * symtab,
1961 uint64_t nsyms,
1962 char * strtab,
1963 uint64_t strtablen,
1964 relocation_type rel_type,
1965 bool is_dynsym)
26c527e6
AM
1966{
1967 size_t i;
2cf0635d 1968 Elf_Internal_Rela * rels;
015dc7e1 1969 bool res = true;
103f02d3 1970
a7fd1186
FS
1971 if (rel_type == reltype_unknown)
1972 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1973
a7fd1186 1974 if (rel_type == reltype_rela)
4d6ed7c8 1975 {
dda8d76d 1976 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1977 return false;
4d6ed7c8 1978 }
a7fd1186 1979 else if (rel_type == reltype_rel)
4d6ed7c8 1980 {
dda8d76d 1981 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1982 return false;
252b5132 1983 }
a7fd1186
FS
1984 else if (rel_type == reltype_relr)
1985 {
fcf8f323
NC
1986 /* This should have been handled by display_relocations(). */
1987 return false;
a7fd1186 1988 }
252b5132 1989
410f7a12
L
1990 if (is_32bit_elf)
1991 {
a7fd1186 1992 if (rel_type == reltype_rela)
2c71103e
NC
1993 {
1994 if (do_wide)
1995 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1996 else
1997 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1998 }
410f7a12 1999 else
2c71103e
NC
2000 {
2001 if (do_wide)
2002 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
2003 else
2004 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
2005 }
410f7a12 2006 }
252b5132 2007 else
410f7a12 2008 {
a7fd1186 2009 if (rel_type == reltype_rela)
2c71103e
NC
2010 {
2011 if (do_wide)
8beeaeb7 2012 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
2013 else
2014 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
2015 }
410f7a12 2016 else
2c71103e
NC
2017 {
2018 if (do_wide)
8beeaeb7 2019 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
2020 else
2021 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
2022 }
410f7a12 2023 }
252b5132
RH
2024
2025 for (i = 0; i < rel_size; i++)
2026 {
2cf0635d 2027 const char * rtype;
625d49fc
AM
2028 uint64_t offset;
2029 uint64_t inf;
2030 uint64_t symtab_index;
2031 uint64_t type;
103f02d3 2032
b34976b6 2033 offset = rels[i].r_offset;
91d6fa6a 2034 inf = rels[i].r_info;
103f02d3 2035
dda8d76d 2036 type = get_reloc_type (filedata, inf);
91d6fa6a 2037 symtab_index = get_reloc_symindex (inf);
252b5132 2038
410f7a12
L
2039 if (is_32bit_elf)
2040 {
39dbeff8
AM
2041 printf ("%8.8lx %8.8lx ",
2042 (unsigned long) offset & 0xffffffff,
91d6fa6a 2043 (unsigned long) inf & 0xffffffff);
410f7a12
L
2044 }
2045 else
2046 {
39dbeff8 2047 printf (do_wide
b8281767
AM
2048 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
2049 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 2050 offset, inf);
410f7a12 2051 }
103f02d3 2052
dda8d76d 2053 switch (filedata->file_header.e_machine)
252b5132
RH
2054 {
2055 default:
2056 rtype = NULL;
2057 break;
2058
a06ea964
NC
2059 case EM_AARCH64:
2060 rtype = elf_aarch64_reloc_type (type);
2061 break;
2062
2b0337b0 2063 case EM_M32R:
252b5132 2064 case EM_CYGNUS_M32R:
9ea033b2 2065 rtype = elf_m32r_reloc_type (type);
252b5132
RH
2066 break;
2067
2068 case EM_386:
22abe556 2069 case EM_IAMCU:
9ea033b2 2070 rtype = elf_i386_reloc_type (type);
252b5132
RH
2071 break;
2072
ba2685cc
AM
2073 case EM_68HC11:
2074 case EM_68HC12:
2075 rtype = elf_m68hc11_reloc_type (type);
2076 break;
75751cd9 2077
7b4ae824
JD
2078 case EM_S12Z:
2079 rtype = elf_s12z_reloc_type (type);
2080 break;
2081
252b5132 2082 case EM_68K:
9ea033b2 2083 rtype = elf_m68k_reloc_type (type);
252b5132
RH
2084 break;
2085
f954747f
AM
2086 case EM_960:
2087 rtype = elf_i960_reloc_type (type);
2088 break;
2089
adde6300 2090 case EM_AVR:
2b0337b0 2091 case EM_AVR_OLD:
adde6300
AM
2092 rtype = elf_avr_reloc_type (type);
2093 break;
2094
9ea033b2
NC
2095 case EM_OLD_SPARCV9:
2096 case EM_SPARC32PLUS:
2097 case EM_SPARCV9:
252b5132 2098 case EM_SPARC:
9ea033b2 2099 rtype = elf_sparc_reloc_type (type);
252b5132
RH
2100 break;
2101
e9f53129
AM
2102 case EM_SPU:
2103 rtype = elf_spu_reloc_type (type);
2104 break;
2105
708e2187
NC
2106 case EM_V800:
2107 rtype = v800_reloc_type (type);
2108 break;
2b0337b0 2109 case EM_V850:
252b5132 2110 case EM_CYGNUS_V850:
9ea033b2 2111 rtype = v850_reloc_type (type);
252b5132
RH
2112 break;
2113
2b0337b0 2114 case EM_D10V:
252b5132 2115 case EM_CYGNUS_D10V:
9ea033b2 2116 rtype = elf_d10v_reloc_type (type);
252b5132
RH
2117 break;
2118
2b0337b0 2119 case EM_D30V:
252b5132 2120 case EM_CYGNUS_D30V:
9ea033b2 2121 rtype = elf_d30v_reloc_type (type);
252b5132
RH
2122 break;
2123
d172d4ba
NC
2124 case EM_DLX:
2125 rtype = elf_dlx_reloc_type (type);
2126 break;
2127
252b5132 2128 case EM_SH:
9ea033b2 2129 rtype = elf_sh_reloc_type (type);
252b5132
RH
2130 break;
2131
2b0337b0 2132 case EM_MN10300:
252b5132 2133 case EM_CYGNUS_MN10300:
9ea033b2 2134 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
2135 break;
2136
2b0337b0 2137 case EM_MN10200:
252b5132 2138 case EM_CYGNUS_MN10200:
9ea033b2 2139 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
2140 break;
2141
2b0337b0 2142 case EM_FR30:
252b5132 2143 case EM_CYGNUS_FR30:
9ea033b2 2144 rtype = elf_fr30_reloc_type (type);
252b5132
RH
2145 break;
2146
ba2685cc
AM
2147 case EM_CYGNUS_FRV:
2148 rtype = elf_frv_reloc_type (type);
2149 break;
5c70f934 2150
b8891f8d
AJ
2151 case EM_CSKY:
2152 rtype = elf_csky_reloc_type (type);
2153 break;
2154
3f8107ab
AM
2155 case EM_FT32:
2156 rtype = elf_ft32_reloc_type (type);
2157 break;
2158
252b5132 2159 case EM_MCORE:
9ea033b2 2160 rtype = elf_mcore_reloc_type (type);
252b5132
RH
2161 break;
2162
3c3bdf30
NC
2163 case EM_MMIX:
2164 rtype = elf_mmix_reloc_type (type);
2165 break;
2166
5506d11a
AM
2167 case EM_MOXIE:
2168 rtype = elf_moxie_reloc_type (type);
2169 break;
2170
2469cfa2 2171 case EM_MSP430:
dda8d76d 2172 if (uses_msp430x_relocs (filedata))
13761a11
NC
2173 {
2174 rtype = elf_msp430x_reloc_type (type);
2175 break;
2176 }
1a0670f3 2177 /* Fall through. */
2469cfa2
NC
2178 case EM_MSP430_OLD:
2179 rtype = elf_msp430_reloc_type (type);
2180 break;
2181
35c08157
KLC
2182 case EM_NDS32:
2183 rtype = elf_nds32_reloc_type (type);
2184 break;
2185
252b5132 2186 case EM_PPC:
9ea033b2 2187 rtype = elf_ppc_reloc_type (type);
252b5132
RH
2188 break;
2189
c833c019
AM
2190 case EM_PPC64:
2191 rtype = elf_ppc64_reloc_type (type);
2192 break;
2193
252b5132 2194 case EM_MIPS:
4fe85591 2195 case EM_MIPS_RS3_LE:
9ea033b2 2196 rtype = elf_mips_reloc_type (type);
252b5132
RH
2197 break;
2198
e23eba97
NC
2199 case EM_RISCV:
2200 rtype = elf_riscv_reloc_type (type);
2201 break;
2202
252b5132 2203 case EM_ALPHA:
9ea033b2 2204 rtype = elf_alpha_reloc_type (type);
252b5132
RH
2205 break;
2206
2207 case EM_ARM:
9ea033b2 2208 rtype = elf_arm_reloc_type (type);
252b5132
RH
2209 break;
2210
584da044 2211 case EM_ARC:
886a2506
NC
2212 case EM_ARC_COMPACT:
2213 case EM_ARC_COMPACT2:
b5c37946
SJ
2214 case EM_ARC_COMPACT3:
2215 case EM_ARC_COMPACT3_64:
9ea033b2 2216 rtype = elf_arc_reloc_type (type);
252b5132
RH
2217 break;
2218
2219 case EM_PARISC:
69e617ca 2220 rtype = elf_hppa_reloc_type (type);
252b5132 2221 break;
7d466069 2222
b8720f9d
JL
2223 case EM_H8_300:
2224 case EM_H8_300H:
2225 case EM_H8S:
2226 rtype = elf_h8_reloc_type (type);
2227 break;
2228
73589c9d
CS
2229 case EM_OR1K:
2230 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
2231 break;
2232
7d466069 2233 case EM_PJ:
2b0337b0 2234 case EM_PJ_OLD:
7d466069
ILT
2235 rtype = elf_pj_reloc_type (type);
2236 break;
800eeca4
JW
2237 case EM_IA_64:
2238 rtype = elf_ia64_reloc_type (type);
2239 break;
1b61cf92 2240
6e712424
PI
2241 case EM_KVX:
2242 rtype = elf_kvx_reloc_type (type);
2243 break;
2244
1b61cf92
HPN
2245 case EM_CRIS:
2246 rtype = elf_cris_reloc_type (type);
2247 break;
535c37ff 2248
f954747f
AM
2249 case EM_860:
2250 rtype = elf_i860_reloc_type (type);
2251 break;
2252
bcedfee6 2253 case EM_X86_64:
8a9036a4 2254 case EM_L1OM:
7a9068fe 2255 case EM_K1OM:
bcedfee6
NC
2256 rtype = elf_x86_64_reloc_type (type);
2257 break;
a85d7ed0 2258
f954747f
AM
2259 case EM_S370:
2260 rtype = i370_reloc_type (type);
2261 break;
2262
53c7db4b
KH
2263 case EM_S390_OLD:
2264 case EM_S390:
2265 rtype = elf_s390_reloc_type (type);
2266 break;
93fbbb04 2267
1c0d3aa6
NC
2268 case EM_SCORE:
2269 rtype = elf_score_reloc_type (type);
2270 break;
2271
93fbbb04
GK
2272 case EM_XSTORMY16:
2273 rtype = elf_xstormy16_reloc_type (type);
2274 break;
179d3252 2275
1fe1f39c
NC
2276 case EM_CRX:
2277 rtype = elf_crx_reloc_type (type);
2278 break;
2279
179d3252
JT
2280 case EM_VAX:
2281 rtype = elf_vax_reloc_type (type);
2282 break;
1e4cf259 2283
619ed720
EB
2284 case EM_VISIUM:
2285 rtype = elf_visium_reloc_type (type);
2286 break;
2287
aca4efc7
JM
2288 case EM_BPF:
2289 rtype = elf_bpf_reloc_type (type);
2290 break;
2291
cfb8c092
NC
2292 case EM_ADAPTEVA_EPIPHANY:
2293 rtype = elf_epiphany_reloc_type (type);
2294 break;
2295
1e4cf259
NC
2296 case EM_IP2K:
2297 case EM_IP2K_OLD:
2298 rtype = elf_ip2k_reloc_type (type);
2299 break;
3b36097d
SC
2300
2301 case EM_IQ2000:
2302 rtype = elf_iq2000_reloc_type (type);
2303 break;
88da6820
NC
2304
2305 case EM_XTENSA_OLD:
2306 case EM_XTENSA:
2307 rtype = elf_xtensa_reloc_type (type);
2308 break;
a34e3ecb 2309
84e94c90
NC
2310 case EM_LATTICEMICO32:
2311 rtype = elf_lm32_reloc_type (type);
2312 break;
2313
ff7eeb89 2314 case EM_M32C_OLD:
49f58d10
JB
2315 case EM_M32C:
2316 rtype = elf_m32c_reloc_type (type);
2317 break;
2318
d031aafb
NS
2319 case EM_MT:
2320 rtype = elf_mt_reloc_type (type);
a34e3ecb 2321 break;
1d65ded4
CM
2322
2323 case EM_BLACKFIN:
2324 rtype = elf_bfin_reloc_type (type);
2325 break;
15ab5209
DB
2326
2327 case EM_CYGNUS_MEP:
2328 rtype = elf_mep_reloc_type (type);
2329 break;
60bca95a
NC
2330
2331 case EM_CR16:
2332 rtype = elf_cr16_reloc_type (type);
2333 break;
dd24e3da 2334
7ba29e2a
NC
2335 case EM_MICROBLAZE:
2336 case EM_MICROBLAZE_OLD:
2337 rtype = elf_microblaze_reloc_type (type);
2338 break;
c7927a3c 2339
99c513f6
DD
2340 case EM_RL78:
2341 rtype = elf_rl78_reloc_type (type);
2342 break;
2343
c7927a3c
NC
2344 case EM_RX:
2345 rtype = elf_rx_reloc_type (type);
2346 break;
c29aca4a 2347
a3c62988
NC
2348 case EM_METAG:
2349 rtype = elf_metag_reloc_type (type);
2350 break;
2351
40b36596
JM
2352 case EM_TI_C6000:
2353 rtype = elf_tic6x_reloc_type (type);
2354 break;
aa137e4d
NC
2355
2356 case EM_TILEGX:
2357 rtype = elf_tilegx_reloc_type (type);
2358 break;
2359
2360 case EM_TILEPRO:
2361 rtype = elf_tilepro_reloc_type (type);
2362 break;
f6c1a2d5 2363
f96bd6c2
PC
2364 case EM_WEBASSEMBLY:
2365 rtype = elf_wasm32_reloc_type (type);
2366 break;
2367
f6c1a2d5
NC
2368 case EM_XGATE:
2369 rtype = elf_xgate_reloc_type (type);
2370 break;
36591ba1
SL
2371
2372 case EM_ALTERA_NIOS2:
2373 rtype = elf_nios2_reloc_type (type);
2374 break;
2b100bb5
DD
2375
2376 case EM_TI_PRU:
2377 rtype = elf_pru_reloc_type (type);
2378 break;
fe944acf
FT
2379
2380 case EM_NFP:
2381 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2382 rtype = elf_nfp3200_reloc_type (type);
2383 else
2384 rtype = elf_nfp_reloc_type (type);
2385 break;
6655dba2
SB
2386
2387 case EM_Z80:
2388 rtype = elf_z80_reloc_type (type);
2389 break;
e9a0721f 2390
2391 case EM_LOONGARCH:
2392 rtype = elf_loongarch_reloc_type (type);
2393 break;
2394
0c857ef4
SM
2395 case EM_AMDGPU:
2396 rtype = elf_amdgpu_reloc_type (type);
2397 break;
252b5132
RH
2398 }
2399
2400 if (rtype == NULL)
39dbeff8 2401 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2402 else
5c144731 2403 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2404
dda8d76d 2405 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2406 && rtype != NULL
7ace3541 2407 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2408 && rel_type == reltype_rela)
7ace3541
RH
2409 {
2410 switch (rels[i].r_addend)
2411 {
2412 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2413 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2414 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2415 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2416 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2417 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2418 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2419 default: rtype = NULL;
2420 }
32ec8896 2421
7ace3541
RH
2422 if (rtype)
2423 printf (" (%s)", rtype);
2424 else
2425 {
2426 putchar (' ');
26c527e6
AM
2427 printf (_("<unknown addend: %" PRIx64 ">"),
2428 rels[i].r_addend);
015dc7e1 2429 res = false;
7ace3541
RH
2430 }
2431 }
2432 else if (symtab_index)
252b5132 2433 {
af3fc3bc 2434 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2435 {
27a45f42
AS
2436 error (_(" bad symbol index: %08lx in reloc\n"),
2437 (unsigned long) symtab_index);
015dc7e1 2438 res = false;
32ec8896 2439 }
af3fc3bc 2440 else
19936277 2441 {
2cf0635d 2442 Elf_Internal_Sym * psym;
bb4d2ac2
L
2443 const char * version_string;
2444 enum versioned_symbol_info sym_info;
2445 unsigned short vna_other;
19936277 2446
af3fc3bc 2447 psym = symtab + symtab_index;
103f02d3 2448
bb4d2ac2 2449 version_string
dda8d76d 2450 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2451 strtab, strtablen,
2452 symtab_index,
2453 psym,
2454 &sym_info,
2455 &vna_other);
2456
af3fc3bc 2457 printf (" ");
171191ba 2458
d8045f23
NC
2459 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2460 {
2461 const char * name;
2462 unsigned int len;
2463 unsigned int width = is_32bit_elf ? 8 : 14;
2464
2465 /* Relocations against GNU_IFUNC symbols do not use the value
2466 of the symbol as the address to relocate against. Instead
2467 they invoke the function named by the symbol and use its
2468 result as the address for relocation.
2469
2470 To indicate this to the user, do not display the value of
2471 the symbol in the "Symbols's Value" field. Instead show
2472 its name followed by () as a hint that the symbol is
2473 invoked. */
2474
2475 if (strtab == NULL
2476 || psym->st_name == 0
2477 || psym->st_name >= strtablen)
2478 name = "??";
2479 else
2480 name = strtab + psym->st_name;
2481
b6ac461a 2482 len = print_symbol_name (width, name);
bb4d2ac2
L
2483 if (version_string)
2484 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2485 version_string);
d8045f23
NC
2486 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2487 }
2488 else
2489 {
2490 print_vma (psym->st_value, LONG_HEX);
171191ba 2491
d8045f23
NC
2492 printf (is_32bit_elf ? " " : " ");
2493 }
103f02d3 2494
af3fc3bc 2495 if (psym->st_name == 0)
f1ef08cb 2496 {
2cf0635d 2497 const char * sec_name = "<null>";
f1ef08cb
AM
2498
2499 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2500 sec_name = printable_section_name_from_index
2501 (filedata, psym->st_shndx, NULL);
2502
2503 print_symbol_name (22, sec_name);
f1ef08cb 2504 }
af3fc3bc 2505 else if (strtab == NULL)
d79b3d50 2506 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2507 else if (psym->st_name >= strtablen)
32ec8896 2508 {
27a45f42
AS
2509 error (_("<corrupt string table index: %3ld>\n"),
2510 psym->st_name);
015dc7e1 2511 res = false;
32ec8896 2512 }
af3fc3bc 2513 else
bb4d2ac2 2514 {
b6ac461a 2515 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2516 if (version_string)
2517 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2518 version_string);
2519 }
103f02d3 2520
a7fd1186 2521 if (rel_type == reltype_rela)
171191ba 2522 {
625d49fc 2523 uint64_t off = rels[i].r_addend;
171191ba 2524
625d49fc
AM
2525 if ((int64_t) off < 0)
2526 printf (" - %" PRIx64, -off);
171191ba 2527 else
625d49fc 2528 printf (" + %" PRIx64, off);
171191ba 2529 }
19936277 2530 }
252b5132 2531 }
a7fd1186 2532 else if (rel_type == reltype_rela)
f7a99963 2533 {
625d49fc 2534 uint64_t off = rels[i].r_addend;
e04d7088
L
2535
2536 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2537 if ((int64_t) off < 0)
2538 printf ("-%" PRIx64, -off);
e04d7088 2539 else
625d49fc 2540 printf ("%" PRIx64, off);
f7a99963 2541 }
252b5132 2542
dda8d76d 2543 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2544 && rtype != NULL
2545 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2546 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2547
252b5132 2548 putchar ('\n');
2c71103e 2549
dda8d76d 2550 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2551 {
625d49fc
AM
2552 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2553 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2554 const char * rtype2 = elf_mips_reloc_type (type2);
2555 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2556
2c71103e
NC
2557 printf (" Type2: ");
2558
2559 if (rtype2 == NULL)
39dbeff8
AM
2560 printf (_("unrecognized: %-7lx"),
2561 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2562 else
2563 printf ("%-17.17s", rtype2);
2564
18bd398b 2565 printf ("\n Type3: ");
2c71103e
NC
2566
2567 if (rtype3 == NULL)
39dbeff8
AM
2568 printf (_("unrecognized: %-7lx"),
2569 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2570 else
2571 printf ("%-17.17s", rtype3);
2572
53c7db4b 2573 putchar ('\n');
2c71103e 2574 }
252b5132
RH
2575 }
2576
c8286bd1 2577 free (rels);
32ec8896
NC
2578
2579 return res;
252b5132
RH
2580}
2581
37c18eed
SD
2582static const char *
2583get_aarch64_dynamic_type (unsigned long type)
2584{
2585 switch (type)
2586 {
2587 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2588 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2589 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2590 default:
2591 return NULL;
2592 }
2593}
2594
252b5132 2595static const char *
d3ba0551 2596get_mips_dynamic_type (unsigned long type)
252b5132
RH
2597{
2598 switch (type)
2599 {
2600 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2601 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2602 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2603 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2604 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2605 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2606 case DT_MIPS_MSYM: return "MIPS_MSYM";
2607 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2608 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2609 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2610 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2611 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2612 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2613 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2614 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2615 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2616 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2617 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2618 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2619 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2620 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2621 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2622 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2623 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2624 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2625 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2626 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2627 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2628 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2629 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2630 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2631 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2632 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2633 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2634 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2635 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2636 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2637 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2638 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2639 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2640 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2641 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2642 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2643 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2644 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2645 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2646 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2647 default:
2648 return NULL;
2649 }
2650}
2651
9a097730 2652static const char *
d3ba0551 2653get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2654{
2655 switch (type)
2656 {
2657 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2658 default:
2659 return NULL;
2660 }
103f02d3
UD
2661}
2662
7490d522
AM
2663static const char *
2664get_ppc_dynamic_type (unsigned long type)
2665{
2666 switch (type)
2667 {
a7f2871e 2668 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2669 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2670 default:
2671 return NULL;
2672 }
2673}
2674
f1cb7e17 2675static const char *
d3ba0551 2676get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2677{
2678 switch (type)
2679 {
a7f2871e
AM
2680 case DT_PPC64_GLINK: return "PPC64_GLINK";
2681 case DT_PPC64_OPD: return "PPC64_OPD";
2682 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2683 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2684 default:
2685 return NULL;
2686 }
2687}
2688
103f02d3 2689static const char *
d3ba0551 2690get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2691{
2692 switch (type)
2693 {
2694 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2695 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2696 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2697 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2698 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2699 case DT_HP_PREINIT: return "HP_PREINIT";
2700 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2701 case DT_HP_NEEDED: return "HP_NEEDED";
2702 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2703 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2704 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2705 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2706 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2707 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2708 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2709 case DT_HP_FILTERED: return "HP_FILTERED";
2710 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2711 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2712 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2713 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2714 case DT_PLT: return "PLT";
2715 case DT_PLT_SIZE: return "PLT_SIZE";
2716 case DT_DLT: return "DLT";
2717 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2718 default:
2719 return NULL;
2720 }
2721}
9a097730 2722
ecc51f48 2723static const char *
d3ba0551 2724get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2725{
2726 switch (type)
2727 {
148b93f2
NC
2728 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2729 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2730 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2731 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2732 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2733 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2734 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2735 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2736 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2737 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2738 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2739 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2740 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2741 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2742 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2743 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2744 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2745 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2746 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2747 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2748 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2749 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2750 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2751 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2752 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2753 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2754 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2755 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2756 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2757 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2758 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2759 default:
2760 return NULL;
2761 }
2762}
2763
fd85a6a1
NC
2764static const char *
2765get_solaris_section_type (unsigned long type)
2766{
2767 switch (type)
2768 {
2769 case 0x6fffffee: return "SUNW_ancillary";
2770 case 0x6fffffef: return "SUNW_capchain";
2771 case 0x6ffffff0: return "SUNW_capinfo";
2772 case 0x6ffffff1: return "SUNW_symsort";
2773 case 0x6ffffff2: return "SUNW_tlssort";
2774 case 0x6ffffff3: return "SUNW_LDYNSYM";
2775 case 0x6ffffff4: return "SUNW_dof";
2776 case 0x6ffffff5: return "SUNW_cap";
2777 case 0x6ffffff6: return "SUNW_SIGNATURE";
2778 case 0x6ffffff7: return "SUNW_ANNOTATE";
2779 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2780 case 0x6ffffff9: return "SUNW_DEBUG";
2781 case 0x6ffffffa: return "SUNW_move";
2782 case 0x6ffffffb: return "SUNW_COMDAT";
2783 case 0x6ffffffc: return "SUNW_syminfo";
2784 case 0x6ffffffd: return "SUNW_verdef";
2785 case 0x6ffffffe: return "SUNW_verneed";
2786 case 0x6fffffff: return "SUNW_versym";
2787 case 0x70000000: return "SPARC_GOTDATA";
2788 default: return NULL;
2789 }
2790}
2791
fabcb361
RH
2792static const char *
2793get_alpha_dynamic_type (unsigned long type)
2794{
2795 switch (type)
2796 {
2797 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2798 default: return NULL;
fabcb361
RH
2799 }
2800}
2801
1c0d3aa6
NC
2802static const char *
2803get_score_dynamic_type (unsigned long type)
2804{
2805 switch (type)
2806 {
2807 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2808 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2809 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2810 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2811 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2812 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2813 default: return NULL;
1c0d3aa6
NC
2814 }
2815}
2816
40b36596
JM
2817static const char *
2818get_tic6x_dynamic_type (unsigned long type)
2819{
2820 switch (type)
2821 {
2822 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2823 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2824 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2825 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2826 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2827 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2828 default: return NULL;
40b36596
JM
2829 }
2830}
1c0d3aa6 2831
36591ba1
SL
2832static const char *
2833get_nios2_dynamic_type (unsigned long type)
2834{
2835 switch (type)
2836 {
2837 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2838 default: return NULL;
36591ba1
SL
2839 }
2840}
2841
fd85a6a1
NC
2842static const char *
2843get_solaris_dynamic_type (unsigned long type)
2844{
2845 switch (type)
2846 {
2847 case 0x6000000d: return "SUNW_AUXILIARY";
2848 case 0x6000000e: return "SUNW_RTLDINF";
2849 case 0x6000000f: return "SUNW_FILTER";
2850 case 0x60000010: return "SUNW_CAP";
2851 case 0x60000011: return "SUNW_SYMTAB";
2852 case 0x60000012: return "SUNW_SYMSZ";
2853 case 0x60000013: return "SUNW_SORTENT";
2854 case 0x60000014: return "SUNW_SYMSORT";
2855 case 0x60000015: return "SUNW_SYMSORTSZ";
2856 case 0x60000016: return "SUNW_TLSSORT";
2857 case 0x60000017: return "SUNW_TLSSORTSZ";
2858 case 0x60000018: return "SUNW_CAPINFO";
2859 case 0x60000019: return "SUNW_STRPAD";
2860 case 0x6000001a: return "SUNW_CAPCHAIN";
2861 case 0x6000001b: return "SUNW_LDMACH";
2862 case 0x6000001d: return "SUNW_CAPCHAINENT";
2863 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2864 case 0x60000021: return "SUNW_PARENT";
2865 case 0x60000023: return "SUNW_ASLR";
2866 case 0x60000025: return "SUNW_RELAX";
2867 case 0x60000029: return "SUNW_NXHEAP";
2868 case 0x6000002b: return "SUNW_NXSTACK";
2869
2870 case 0x70000001: return "SPARC_REGISTER";
2871 case 0x7ffffffd: return "AUXILIARY";
2872 case 0x7ffffffe: return "USED";
2873 case 0x7fffffff: return "FILTER";
2874
15f205b1 2875 default: return NULL;
fd85a6a1
NC
2876 }
2877}
2878
8155b853
NC
2879static const char *
2880get_riscv_dynamic_type (unsigned long type)
2881{
2882 switch (type)
2883 {
2884 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2885 default:
2886 return NULL;
2887 }
2888}
2889
832ca732
L
2890static const char *
2891get_x86_64_dynamic_type (unsigned long type)
2892{
2893 switch (type)
2894 {
2895 case DT_X86_64_PLT:
2896 return "DT_X86_64_PLT";
2897 case DT_X86_64_PLTSZ:
2898 return "DT_X86_64_PLTSZ";
2899 case DT_X86_64_PLTENT:
2900 return "DT_X86_64_PLTENT";
2901 default:
2902 return NULL;
2903 }
2904}
2905
252b5132 2906static const char *
dda8d76d 2907get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2908{
e9e44622 2909 static char buff[64];
252b5132
RH
2910
2911 switch (type)
2912 {
2913 case DT_NULL: return "NULL";
2914 case DT_NEEDED: return "NEEDED";
2915 case DT_PLTRELSZ: return "PLTRELSZ";
2916 case DT_PLTGOT: return "PLTGOT";
2917 case DT_HASH: return "HASH";
2918 case DT_STRTAB: return "STRTAB";
2919 case DT_SYMTAB: return "SYMTAB";
2920 case DT_RELA: return "RELA";
2921 case DT_RELASZ: return "RELASZ";
2922 case DT_RELAENT: return "RELAENT";
2923 case DT_STRSZ: return "STRSZ";
2924 case DT_SYMENT: return "SYMENT";
2925 case DT_INIT: return "INIT";
2926 case DT_FINI: return "FINI";
2927 case DT_SONAME: return "SONAME";
2928 case DT_RPATH: return "RPATH";
2929 case DT_SYMBOLIC: return "SYMBOLIC";
2930 case DT_REL: return "REL";
2931 case DT_RELSZ: return "RELSZ";
2932 case DT_RELENT: return "RELENT";
dd207c13
FS
2933 case DT_RELR: return "RELR";
2934 case DT_RELRSZ: return "RELRSZ";
2935 case DT_RELRENT: return "RELRENT";
252b5132
RH
2936 case DT_PLTREL: return "PLTREL";
2937 case DT_DEBUG: return "DEBUG";
2938 case DT_TEXTREL: return "TEXTREL";
2939 case DT_JMPREL: return "JMPREL";
2940 case DT_BIND_NOW: return "BIND_NOW";
2941 case DT_INIT_ARRAY: return "INIT_ARRAY";
2942 case DT_FINI_ARRAY: return "FINI_ARRAY";
2943 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2944 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2945 case DT_RUNPATH: return "RUNPATH";
2946 case DT_FLAGS: return "FLAGS";
2d0e6f43 2947
d1133906
NC
2948 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2949 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2950 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2951
05107a46 2952 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2953 case DT_PLTPADSZ: return "PLTPADSZ";
2954 case DT_MOVEENT: return "MOVEENT";
2955 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2956 case DT_FEATURE: return "FEATURE";
252b5132
RH
2957 case DT_POSFLAG_1: return "POSFLAG_1";
2958 case DT_SYMINSZ: return "SYMINSZ";
2959 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2960
252b5132 2961 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2962 case DT_CONFIG: return "CONFIG";
2963 case DT_DEPAUDIT: return "DEPAUDIT";
2964 case DT_AUDIT: return "AUDIT";
2965 case DT_PLTPAD: return "PLTPAD";
2966 case DT_MOVETAB: return "MOVETAB";
252b5132 2967 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2968
252b5132 2969 case DT_VERSYM: return "VERSYM";
103f02d3 2970
67a4f2b7
AO
2971 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2972 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2973 case DT_RELACOUNT: return "RELACOUNT";
2974 case DT_RELCOUNT: return "RELCOUNT";
2975 case DT_FLAGS_1: return "FLAGS_1";
2976 case DT_VERDEF: return "VERDEF";
2977 case DT_VERDEFNUM: return "VERDEFNUM";
2978 case DT_VERNEED: return "VERNEED";
2979 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2980
019148e4 2981 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2982 case DT_USED: return "USED";
2983 case DT_FILTER: return "FILTER";
103f02d3 2984
047b2264
JJ
2985 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2986 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2987 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2988 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2989 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2990 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2991 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2992
252b5132
RH
2993 default:
2994 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2995 {
2cf0635d 2996 const char * result;
103f02d3 2997
dda8d76d 2998 switch (filedata->file_header.e_machine)
252b5132 2999 {
37c18eed
SD
3000 case EM_AARCH64:
3001 result = get_aarch64_dynamic_type (type);
3002 break;
252b5132 3003 case EM_MIPS:
4fe85591 3004 case EM_MIPS_RS3_LE:
252b5132
RH
3005 result = get_mips_dynamic_type (type);
3006 break;
9a097730
RH
3007 case EM_SPARCV9:
3008 result = get_sparc64_dynamic_type (type);
3009 break;
7490d522
AM
3010 case EM_PPC:
3011 result = get_ppc_dynamic_type (type);
3012 break;
f1cb7e17
AM
3013 case EM_PPC64:
3014 result = get_ppc64_dynamic_type (type);
3015 break;
ecc51f48
NC
3016 case EM_IA_64:
3017 result = get_ia64_dynamic_type (type);
3018 break;
fabcb361
RH
3019 case EM_ALPHA:
3020 result = get_alpha_dynamic_type (type);
3021 break;
1c0d3aa6
NC
3022 case EM_SCORE:
3023 result = get_score_dynamic_type (type);
3024 break;
40b36596
JM
3025 case EM_TI_C6000:
3026 result = get_tic6x_dynamic_type (type);
3027 break;
36591ba1
SL
3028 case EM_ALTERA_NIOS2:
3029 result = get_nios2_dynamic_type (type);
3030 break;
8155b853
NC
3031 case EM_RISCV:
3032 result = get_riscv_dynamic_type (type);
3033 break;
832ca732
L
3034 case EM_X86_64:
3035 result = get_x86_64_dynamic_type (type);
3036 break;
252b5132 3037 default:
dda8d76d 3038 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
3039 result = get_solaris_dynamic_type (type);
3040 else
3041 result = NULL;
252b5132
RH
3042 break;
3043 }
3044
3045 if (result != NULL)
3046 return result;
3047
e9e44622 3048 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 3049 }
eec8f817 3050 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 3051 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 3052 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 3053 {
2cf0635d 3054 const char * result;
103f02d3 3055
dda8d76d 3056 switch (filedata->file_header.e_machine)
103f02d3
UD
3057 {
3058 case EM_PARISC:
3059 result = get_parisc_dynamic_type (type);
3060 break;
148b93f2
NC
3061 case EM_IA_64:
3062 result = get_ia64_dynamic_type (type);
3063 break;
103f02d3 3064 default:
dda8d76d 3065 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
3066 result = get_solaris_dynamic_type (type);
3067 else
3068 result = NULL;
103f02d3
UD
3069 break;
3070 }
3071
3072 if (result != NULL)
3073 return result;
3074
e9e44622
JJ
3075 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
3076 type);
103f02d3 3077 }
252b5132 3078 else
e9e44622 3079 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 3080
252b5132
RH
3081 return buff;
3082 }
3083}
3084
93df3340
AM
3085static bool get_program_headers (Filedata *);
3086static bool get_dynamic_section (Filedata *);
3087
3088static void
3089locate_dynamic_section (Filedata *filedata)
3090{
26c527e6 3091 uint64_t dynamic_addr = 0;
be7d229a 3092 uint64_t dynamic_size = 0;
93df3340
AM
3093
3094 if (filedata->file_header.e_phnum != 0
3095 && get_program_headers (filedata))
3096 {
3097 Elf_Internal_Phdr *segment;
3098 unsigned int i;
3099
3100 for (i = 0, segment = filedata->program_headers;
3101 i < filedata->file_header.e_phnum;
3102 i++, segment++)
3103 {
3104 if (segment->p_type == PT_DYNAMIC)
3105 {
3106 dynamic_addr = segment->p_offset;
3107 dynamic_size = segment->p_filesz;
3108
3109 if (filedata->section_headers != NULL)
3110 {
3111 Elf_Internal_Shdr *sec;
3112
3113 sec = find_section (filedata, ".dynamic");
3114 if (sec != NULL)
3115 {
3116 if (sec->sh_size == 0
3117 || sec->sh_type == SHT_NOBITS)
3118 {
3119 dynamic_addr = 0;
3120 dynamic_size = 0;
3121 }
3122 else
3123 {
3124 dynamic_addr = sec->sh_offset;
3125 dynamic_size = sec->sh_size;
3126 }
3127 }
3128 }
3129
3130 if (dynamic_addr > filedata->file_size
3131 || (dynamic_size > filedata->file_size - dynamic_addr))
3132 {
3133 dynamic_addr = 0;
3134 dynamic_size = 0;
3135 }
3136 break;
3137 }
3138 }
3139 }
3140 filedata->dynamic_addr = dynamic_addr;
3141 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
3142}
3143
3144static bool
3145is_pie (Filedata *filedata)
3146{
3147 Elf_Internal_Dyn *entry;
3148
3149 if (filedata->dynamic_size == 0)
3150 locate_dynamic_section (filedata);
3151 if (filedata->dynamic_size <= 1)
3152 return false;
3153
3154 if (!get_dynamic_section (filedata))
3155 return false;
3156
3157 for (entry = filedata->dynamic_section;
3158 entry < filedata->dynamic_section + filedata->dynamic_nent;
3159 entry++)
3160 {
3161 if (entry->d_tag == DT_FLAGS_1)
3162 {
3163 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3164 return true;
3165 break;
3166 }
3167 }
3168 return false;
3169}
3170
252b5132 3171static char *
93df3340 3172get_file_type (Filedata *filedata)
252b5132 3173{
93df3340 3174 unsigned e_type = filedata->file_header.e_type;
89246a0e 3175 static char buff[64];
252b5132
RH
3176
3177 switch (e_type)
3178 {
32ec8896
NC
3179 case ET_NONE: return _("NONE (None)");
3180 case ET_REL: return _("REL (Relocatable file)");
3181 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
3182 case ET_DYN:
3183 if (is_pie (filedata))
3184 return _("DYN (Position-Independent Executable file)");
3185 else
3186 return _("DYN (Shared object file)");
32ec8896 3187 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
3188
3189 default:
3190 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 3191 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 3192 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 3193 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 3194 else
e9e44622 3195 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
3196 return buff;
3197 }
3198}
3199
3200static char *
d3ba0551 3201get_machine_name (unsigned e_machine)
252b5132 3202{
b34976b6 3203 static char buff[64]; /* XXX */
252b5132
RH
3204
3205 switch (e_machine)
3206 {
55e22ca8
NC
3207 /* Please keep this switch table sorted by increasing EM_ value. */
3208 /* 0 */
c45021f2
NC
3209 case EM_NONE: return _("None");
3210 case EM_M32: return "WE32100";
3211 case EM_SPARC: return "Sparc";
3212 case EM_386: return "Intel 80386";
3213 case EM_68K: return "MC68000";
3214 case EM_88K: return "MC88000";
22abe556 3215 case EM_IAMCU: return "Intel MCU";
fb70ec17 3216 case EM_860: return "Intel 80860";
c45021f2
NC
3217 case EM_MIPS: return "MIPS R3000";
3218 case EM_S370: return "IBM System/370";
55e22ca8 3219 /* 10 */
7036c0e1 3220 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 3221 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 3222 case EM_PARISC: return "HPPA";
55e22ca8 3223 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 3224 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 3225 case EM_960: return "Intel 80960";
c45021f2 3226 case EM_PPC: return "PowerPC";
55e22ca8 3227 /* 20 */
285d1771 3228 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
3229 case EM_S390_OLD:
3230 case EM_S390: return "IBM S/390";
3231 case EM_SPU: return "SPU";
3232 /* 30 */
3233 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
3234 case EM_FR20: return "Fujitsu FR20";
3235 case EM_RH32: return "TRW RH32";
b34976b6 3236 case EM_MCORE: return "MCORE";
55e22ca8 3237 /* 40 */
7036c0e1
AJ
3238 case EM_ARM: return "ARM";
3239 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 3240 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
3241 case EM_SPARCV9: return "Sparc v9";
3242 case EM_TRICORE: return "Siemens Tricore";
584da044 3243 case EM_ARC: return "ARC";
c2dcd04e
NC
3244 case EM_H8_300: return "Renesas H8/300";
3245 case EM_H8_300H: return "Renesas H8/300H";
3246 case EM_H8S: return "Renesas H8S";
3247 case EM_H8_500: return "Renesas H8/500";
55e22ca8 3248 /* 50 */
30800947 3249 case EM_IA_64: return "Intel IA-64";
252b5132
RH
3250 case EM_MIPS_X: return "Stanford MIPS-X";
3251 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 3252 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
3253 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3254 case EM_PCP: return "Siemens PCP";
3255 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 3256 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
3257 case EM_STARCORE: return "Motorola Star*Core processor";
3258 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 3259 /* 60 */
7036c0e1
AJ
3260 case EM_ST100: return "STMicroelectronics ST100 processor";
3261 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 3262 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
3263 case EM_PDSP: return "Sony DSP processor";
3264 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3265 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
3266 case EM_FX66: return "Siemens FX66 microcontroller";
3267 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3268 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3269 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 3270 /* 70 */
7036c0e1
AJ
3271 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3272 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3273 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3274 case EM_SVX: return "Silicon Graphics SVx";
3275 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3276 case EM_VAX: return "Digital VAX";
1b61cf92 3277 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
3278 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3279 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3280 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 3281 /* 80 */
b34976b6 3282 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 3283 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 3284 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
3285 case EM_AVR_OLD:
3286 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3287 case EM_CYGNUS_FR30:
3288 case EM_FR30: return "Fujitsu FR30";
3289 case EM_CYGNUS_D10V:
3290 case EM_D10V: return "d10v";
3291 case EM_CYGNUS_D30V:
3292 case EM_D30V: return "d30v";
3293 case EM_CYGNUS_V850:
3294 case EM_V850: return "Renesas V850";
3295 case EM_CYGNUS_M32R:
3296 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3297 case EM_CYGNUS_MN10300:
3298 case EM_MN10300: return "mn10300";
3299 /* 90 */
3300 case EM_CYGNUS_MN10200:
3301 case EM_MN10200: return "mn10200";
3302 case EM_PJ: return "picoJava";
73589c9d 3303 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 3304 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
3305 case EM_XTENSA_OLD:
3306 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
3307 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3308 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3309 case EM_NS32K: return "National Semiconductor 32000 series";
3310 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
3311 case EM_SNP1K: return "Trebia SNP 1000 processor";
3312 /* 100 */
9abca702 3313 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
3314 case EM_IP2K_OLD:
3315 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
3316 case EM_MAX: return "MAX Processor";
3317 case EM_CR: return "National Semiconductor CompactRISC";
3318 case EM_F2MC16: return "Fujitsu F2MC16";
3319 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 3320 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
3321 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3322 case EM_SEP: return "Sharp embedded microprocessor";
3323 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 3324 /* 110 */
11636f9e
JM
3325 case EM_UNICORE: return "Unicore";
3326 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3327 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 3328 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
3329 case EM_CRX: return "National Semiconductor CRX microprocessor";
3330 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 3331 case EM_C166:
d70c5fc7 3332 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
3333 case EM_M16C: return "Renesas M16C series microprocessors";
3334 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3335 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
3336 /* 120 */
3337 case EM_M32C: return "Renesas M32c";
3338 /* 130 */
11636f9e
JM
3339 case EM_TSK3000: return "Altium TSK3000 core";
3340 case EM_RS08: return "Freescale RS08 embedded processor";
3341 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 3342 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
3343 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3344 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 3345 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 3346 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 3347 /* 140 */
11636f9e
JM
3348 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3349 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3350 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
3351 case EM_TI_PRU: return "TI PRU I/O processor";
3352 /* 160 */
11636f9e
JM
3353 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3354 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3355 case EM_R32C: return "Renesas R32C series microprocessors";
3356 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3357 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3358 case EM_8051: return "Intel 8051 and variants";
3359 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3360 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3361 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3362 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 3363 /* 170 */
11636f9e
JM
3364 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3365 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3366 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3367 case EM_RX: return "Renesas RX";
a3c62988 3368 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3369 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3370 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3371 case EM_CR16:
3372 case EM_MICROBLAZE:
3373 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3374 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3375 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3376 /* 180 */
3377 case EM_L1OM: return "Intel L1OM";
3378 case EM_K1OM: return "Intel K1OM";
3379 case EM_INTEL182: return "Intel (reserved)";
3380 case EM_AARCH64: return "AArch64";
3381 case EM_ARM184: return "ARM (reserved)";
3382 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3383 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3384 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3385 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3386 /* 190 */
11636f9e 3387 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3388 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3389 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3390 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3391 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3392 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3393 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3394 case EM_RL78: return "Renesas RL78";
6d913794 3395 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3396 case EM_78K0R: return "Renesas 78K0R";
3397 /* 200 */
6d913794 3398 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3399 case EM_BA1: return "Beyond BA1 CPU architecture";
3400 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3401 case EM_XCORE: return "XMOS xCORE processor family";
3402 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3403 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3404 /* 210 */
6d913794
NC
3405 case EM_KM32: return "KM211 KM32 32-bit processor";
3406 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3407 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3408 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3409 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3410 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3411 case EM_COGE: return "Cognitive Smart Memory Processor";
3412 case EM_COOL: return "Bluechip Systems CoolEngine";
3413 case EM_NORC: return "Nanoradio Optimized RISC";
3414 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3415 /* 220 */
15f205b1 3416 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3417 case EM_VISIUM: return "CDS VISIUMcore processor";
3418 case EM_FT32: return "FTDI Chip FT32";
3419 case EM_MOXIE: return "Moxie";
3420 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3421 /* 230 (all reserved) */
3422 /* 240 */
55e22ca8
NC
3423 case EM_RISCV: return "RISC-V";
3424 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3425 case EM_CEVA: return "CEVA Processor Architecture Family";
3426 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3427 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3428 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3429 case EM_IMG1: return "Imagination Technologies";
3430 /* 250 */
fe944acf 3431 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3432 case EM_VE: return "NEC Vector Engine";
3433 case EM_CSKY: return "C-SKY";
b5c37946 3434 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3435 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3436 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3437 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3438 case EM_65816: return "WDC 65816/65C816";
01a8c731 3439 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3440 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3441
3442 /* Large numbers... */
3443 case EM_MT: return "Morpho Techologies MT processor";
3444 case EM_ALPHA: return "Alpha";
3445 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3446 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3447 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3448 case EM_IQ2000: return "Vitesse IQ2000";
3449 case EM_M32C_OLD:
3450 case EM_NIOS32: return "Altera Nios";
3451 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3452 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3453 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3454 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3455
252b5132 3456 default:
35d9dd2f 3457 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3458 return buff;
3459 }
3460}
3461
f8c4789c
AM
3462static char *
3463decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3464{
3465 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3466 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3467 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3468 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3469 architectures.
3470
3471 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3472 but also sets a specific architecture type in the e_flags field.
3473
3474 However, when decoding the flags we don't worry if we see an
3475 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3476 ARCEM architecture type. */
3477
3478 switch (e_flags & EF_ARC_MACH_MSK)
3479 {
3480 /* We only expect these to occur for EM_ARC_COMPACT2. */
3481 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3482 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3483 break;
3484 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3485 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3486 break;
3487
3488 /* We only expect these to occur for EM_ARC_COMPACT. */
3489 case E_ARC_MACH_ARC600:
f8c4789c 3490 out = stpcpy (out, ", ARC600");
a9522a21
AB
3491 break;
3492 case E_ARC_MACH_ARC601:
f8c4789c 3493 out = stpcpy (out, ", ARC601");
a9522a21
AB
3494 break;
3495 case E_ARC_MACH_ARC700:
f8c4789c 3496 out = stpcpy (out, ", ARC700");
a9522a21
AB
3497 break;
3498
3499 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3500 new ELF with new architecture being read by an old version of
3501 readelf, or (c) An ELF built with non-GNU compiler that does not
3502 set the architecture in the e_flags. */
3503 default:
3504 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3505 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3506 else
f8c4789c 3507 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3508 break;
3509 }
3510
3511 switch (e_flags & EF_ARC_OSABI_MSK)
3512 {
3513 case E_ARC_OSABI_ORIG:
f8c4789c 3514 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3515 break;
3516 case E_ARC_OSABI_V2:
f8c4789c 3517 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3518 break;
3519 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3520 case E_ARC_OSABI_V3:
f8c4789c 3521 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3522 break;
53a346d8 3523 case E_ARC_OSABI_V4:
f8c4789c 3524 out = stpcpy (out, ", v4 ABI");
53a346d8 3525 break;
a9522a21 3526 default:
f8c4789c 3527 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3528 break;
3529 }
f8c4789c 3530 return out;
a9522a21
AB
3531}
3532
f8c4789c
AM
3533static char *
3534decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3535{
3536 unsigned eabi;
1efbe98a 3537 bool unknown_abi = false;
f3485b74
NC
3538
3539 eabi = EF_ARM_EABI_VERSION (e_flags);
3540 e_flags &= ~ EF_ARM_EABIMASK;
3541
3542 /* Handle "generic" ARM flags. */
3543 if (e_flags & EF_ARM_RELEXEC)
3544 {
f8c4789c 3545 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3546 e_flags &= ~ EF_ARM_RELEXEC;
3547 }
76da6bbe 3548
18a20338
CL
3549 if (e_flags & EF_ARM_PIC)
3550 {
f8c4789c 3551 out = stpcpy (out, ", position independent");
18a20338
CL
3552 e_flags &= ~ EF_ARM_PIC;
3553 }
3554
f3485b74
NC
3555 /* Now handle EABI specific flags. */
3556 switch (eabi)
3557 {
3558 default:
f8c4789c 3559 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3560 if (e_flags)
1efbe98a 3561 unknown_abi = true;
f3485b74
NC
3562 break;
3563
3564 case EF_ARM_EABI_VER1:
f8c4789c 3565 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3566 while (e_flags)
3567 {
3568 unsigned flag;
76da6bbe 3569
f3485b74
NC
3570 /* Process flags one bit at a time. */
3571 flag = e_flags & - e_flags;
3572 e_flags &= ~ flag;
76da6bbe 3573
f3485b74
NC
3574 switch (flag)
3575 {
a5bcd848 3576 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3577 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3578 break;
76da6bbe 3579
f3485b74 3580 default:
1efbe98a 3581 unknown_abi = true;
f3485b74
NC
3582 break;
3583 }
3584 }
3585 break;
76da6bbe 3586
a5bcd848 3587 case EF_ARM_EABI_VER2:
f8c4789c 3588 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3589 while (e_flags)
3590 {
3591 unsigned flag;
3592
3593 /* Process flags one bit at a time. */
3594 flag = e_flags & - e_flags;
3595 e_flags &= ~ flag;
3596
3597 switch (flag)
3598 {
3599 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3600 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3601 break;
3602
3603 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3604 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3605 break;
3606
3607 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3608 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3609 break;
3610
3611 default:
1efbe98a 3612 unknown_abi = true;
a5bcd848
PB
3613 break;
3614 }
3615 }
3616 break;
3617
d507cf36 3618 case EF_ARM_EABI_VER3:
f8c4789c 3619 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3620 break;
3621
3622 case EF_ARM_EABI_VER4:
f8c4789c 3623 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3624 while (e_flags)
3625 {
3626 unsigned flag;
3627
3628 /* Process flags one bit at a time. */
3629 flag = e_flags & - e_flags;
3630 e_flags &= ~ flag;
3631
3632 switch (flag)
3633 {
3634 case EF_ARM_BE8:
f8c4789c 3635 out = stpcpy (out, ", BE8");
3bfcb652
NC
3636 break;
3637
3638 case EF_ARM_LE8:
f8c4789c 3639 out = stpcpy (out, ", LE8");
3bfcb652
NC
3640 break;
3641
3642 default:
1efbe98a 3643 unknown_abi = true;
3bfcb652
NC
3644 break;
3645 }
3bfcb652
NC
3646 }
3647 break;
3a4a14e9
PB
3648
3649 case EF_ARM_EABI_VER5:
f8c4789c 3650 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3651 while (e_flags)
3652 {
3653 unsigned flag;
3654
3655 /* Process flags one bit at a time. */
3656 flag = e_flags & - e_flags;
3657 e_flags &= ~ flag;
3658
3659 switch (flag)
3660 {
3661 case EF_ARM_BE8:
f8c4789c 3662 out = stpcpy (out, ", BE8");
d507cf36
PB
3663 break;
3664
3665 case EF_ARM_LE8:
f8c4789c 3666 out = stpcpy (out, ", LE8");
d507cf36
PB
3667 break;
3668
3bfcb652 3669 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3670 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3671 break;
3672
3673 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3674 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3675 break;
3676
d507cf36 3677 default:
1efbe98a 3678 unknown_abi = true;
d507cf36
PB
3679 break;
3680 }
3681 }
3682 break;
3683
f3485b74 3684 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3685 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3686 while (e_flags)
3687 {
3688 unsigned flag;
76da6bbe 3689
f3485b74
NC
3690 /* Process flags one bit at a time. */
3691 flag = e_flags & - e_flags;
3692 e_flags &= ~ flag;
76da6bbe 3693
f3485b74
NC
3694 switch (flag)
3695 {
a5bcd848 3696 case EF_ARM_INTERWORK:
f8c4789c 3697 out = stpcpy (out, ", interworking enabled");
f3485b74 3698 break;
76da6bbe 3699
a5bcd848 3700 case EF_ARM_APCS_26:
f8c4789c 3701 out = stpcpy (out, ", uses APCS/26");
f3485b74 3702 break;
76da6bbe 3703
a5bcd848 3704 case EF_ARM_APCS_FLOAT:
f8c4789c 3705 out = stpcpy (out, ", uses APCS/float");
f3485b74 3706 break;
76da6bbe 3707
a5bcd848 3708 case EF_ARM_PIC:
f8c4789c 3709 out = stpcpy (out, ", position independent");
f3485b74 3710 break;
76da6bbe 3711
a5bcd848 3712 case EF_ARM_ALIGN8:
f8c4789c 3713 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3714 break;
76da6bbe 3715
a5bcd848 3716 case EF_ARM_NEW_ABI:
f8c4789c 3717 out = stpcpy (out, ", uses new ABI");
f3485b74 3718 break;
76da6bbe 3719
a5bcd848 3720 case EF_ARM_OLD_ABI:
f8c4789c 3721 out = stpcpy (out, ", uses old ABI");
f3485b74 3722 break;
76da6bbe 3723
a5bcd848 3724 case EF_ARM_SOFT_FLOAT:
f8c4789c 3725 out = stpcpy (out, ", software FP");
f3485b74 3726 break;
76da6bbe 3727
90e01f86 3728 case EF_ARM_VFP_FLOAT:
f8c4789c 3729 out = stpcpy (out, ", VFP");
90e01f86
ILT
3730 break;
3731
f3485b74 3732 default:
1efbe98a 3733 unknown_abi = true;
f3485b74
NC
3734 break;
3735 }
3736 }
3737 }
f3485b74 3738
1efbe98a 3739 if (unknown_abi)
f8c4789c
AM
3740 out = stpcpy (out,_(", <unknown>"));
3741 return out;
f3485b74
NC
3742}
3743
f8c4789c
AM
3744static char *
3745decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3746{
343433df
AB
3747 switch (e_flags & EF_AVR_MACH)
3748 {
3749 case E_AVR_MACH_AVR1:
f8c4789c 3750 out = stpcpy (out, ", avr:1");
343433df
AB
3751 break;
3752 case E_AVR_MACH_AVR2:
f8c4789c 3753 out = stpcpy (out, ", avr:2");
343433df
AB
3754 break;
3755 case E_AVR_MACH_AVR25:
f8c4789c 3756 out = stpcpy (out, ", avr:25");
343433df
AB
3757 break;
3758 case E_AVR_MACH_AVR3:
f8c4789c 3759 out = stpcpy (out, ", avr:3");
343433df
AB
3760 break;
3761 case E_AVR_MACH_AVR31:
f8c4789c 3762 out = stpcpy (out, ", avr:31");
343433df
AB
3763 break;
3764 case E_AVR_MACH_AVR35:
f8c4789c 3765 out = stpcpy (out, ", avr:35");
343433df
AB
3766 break;
3767 case E_AVR_MACH_AVR4:
f8c4789c 3768 out = stpcpy (out, ", avr:4");
343433df
AB
3769 break;
3770 case E_AVR_MACH_AVR5:
f8c4789c 3771 out = stpcpy (out, ", avr:5");
343433df
AB
3772 break;
3773 case E_AVR_MACH_AVR51:
f8c4789c 3774 out = stpcpy (out, ", avr:51");
343433df
AB
3775 break;
3776 case E_AVR_MACH_AVR6:
f8c4789c 3777 out = stpcpy (out, ", avr:6");
343433df
AB
3778 break;
3779 case E_AVR_MACH_AVRTINY:
f8c4789c 3780 out = stpcpy (out, ", avr:100");
343433df
AB
3781 break;
3782 case E_AVR_MACH_XMEGA1:
f8c4789c 3783 out = stpcpy (out, ", avr:101");
343433df
AB
3784 break;
3785 case E_AVR_MACH_XMEGA2:
f8c4789c 3786 out = stpcpy (out, ", avr:102");
343433df
AB
3787 break;
3788 case E_AVR_MACH_XMEGA3:
f8c4789c 3789 out = stpcpy (out, ", avr:103");
343433df
AB
3790 break;
3791 case E_AVR_MACH_XMEGA4:
f8c4789c 3792 out = stpcpy (out, ", avr:104");
343433df
AB
3793 break;
3794 case E_AVR_MACH_XMEGA5:
f8c4789c 3795 out = stpcpy (out, ", avr:105");
343433df
AB
3796 break;
3797 case E_AVR_MACH_XMEGA6:
f8c4789c 3798 out = stpcpy (out, ", avr:106");
343433df
AB
3799 break;
3800 case E_AVR_MACH_XMEGA7:
f8c4789c 3801 out = stpcpy (out, ", avr:107");
343433df
AB
3802 break;
3803 default:
f8c4789c 3804 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3805 break;
3806 }
3807
343433df 3808 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3809 out = stpcpy (out, ", link-relax");
3810 return out;
343433df
AB
3811}
3812
f8c4789c
AM
3813static char *
3814decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3815{
3816 if (e_flags & EF_BFIN_PIC)
3817 out = stpcpy (out, ", PIC");
3818
3819 if (e_flags & EF_BFIN_FDPIC)
3820 out = stpcpy (out, ", FDPIC");
3821
3822 if (e_flags & EF_BFIN_CODE_IN_L1)
3823 out = stpcpy (out, ", code in L1");
3824
3825 if (e_flags & EF_BFIN_DATA_IN_L1)
3826 out = stpcpy (out, ", data in L1");
3827 return out;
3828}
3829
3830static char *
3831decode_FRV_machine_flags (char *out, unsigned e_flags)
3832{
3833 switch (e_flags & EF_FRV_CPU_MASK)
3834 {
3835 case EF_FRV_CPU_GENERIC:
3836 break;
3837
3838 default:
3839 out = stpcpy (out, ", fr???");
3840 break;
3841
3842 case EF_FRV_CPU_FR300:
3843 out = stpcpy (out, ", fr300");
3844 break;
3845
3846 case EF_FRV_CPU_FR400:
3847 out = stpcpy (out, ", fr400");
3848 break;
3849 case EF_FRV_CPU_FR405:
3850 out = stpcpy (out, ", fr405");
3851 break;
3852
3853 case EF_FRV_CPU_FR450:
3854 out = stpcpy (out, ", fr450");
3855 break;
3856
3857 case EF_FRV_CPU_FR500:
3858 out = stpcpy (out, ", fr500");
3859 break;
3860 case EF_FRV_CPU_FR550:
3861 out = stpcpy (out, ", fr550");
3862 break;
3863
3864 case EF_FRV_CPU_SIMPLE:
3865 out = stpcpy (out, ", simple");
3866 break;
3867 case EF_FRV_CPU_TOMCAT:
3868 out = stpcpy (out, ", tomcat");
3869 break;
3870 }
3871 return out;
3872}
3873
3874static char *
3875decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3876{
3877 if ((e_flags & EF_IA_64_ABI64))
3878 out = stpcpy (out, ", 64-bit");
3879 else
3880 out = stpcpy (out, ", 32-bit");
3881 if ((e_flags & EF_IA_64_REDUCEDFP))
3882 out = stpcpy (out, ", reduced fp model");
3883 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3884 out = stpcpy (out, ", no function descriptors, constant gp");
3885 else if ((e_flags & EF_IA_64_CONS_GP))
3886 out = stpcpy (out, ", constant gp");
3887 if ((e_flags & EF_IA_64_ABSOLUTE))
3888 out = stpcpy (out, ", absolute");
3889 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3890 {
3891 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3892 out = stpcpy (out, ", vms_linkages");
3893 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3894 {
3895 case EF_IA_64_VMS_COMCOD_SUCCESS:
3896 break;
3897 case EF_IA_64_VMS_COMCOD_WARNING:
3898 out = stpcpy (out, ", warning");
3899 break;
3900 case EF_IA_64_VMS_COMCOD_ERROR:
3901 out = stpcpy (out, ", error");
3902 break;
3903 case EF_IA_64_VMS_COMCOD_ABORT:
3904 out = stpcpy (out, ", abort");
3905 break;
3906 default:
3907 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3908 e_flags & EF_IA_64_VMS_COMCOD);
3909 out = stpcpy (out, ", <unknown>");
3910 }
3911 }
3912 return out;
3913}
3914
3915static char *
3916decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3917{
3918 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3919 out = stpcpy (out, ", SOFT-FLOAT");
3920 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3921 out = stpcpy (out, ", SINGLE-FLOAT");
3922 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3923 out = stpcpy (out, ", DOUBLE-FLOAT");
3924
3925 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3926 out = stpcpy (out, ", OBJ-v0");
3927 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3928 out = stpcpy (out, ", OBJ-v1");
3929 return out;
3930}
3931
3932static char *
3933decode_M68K_machine_flags (char *out, unsigned int e_flags)
3934{
3935 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3936 out = stpcpy (out, ", m68000");
3937 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3938 out = stpcpy (out, ", cpu32");
3939 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3940 out = stpcpy (out, ", fido_a");
3941 else
3942 {
3943 char const *isa = _("unknown");
3944 char const *mac = _("unknown mac");
3945 char const *additional = NULL;
3946
3947 switch (e_flags & EF_M68K_CF_ISA_MASK)
3948 {
3949 case EF_M68K_CF_ISA_A_NODIV:
3950 isa = "A";
3951 additional = ", nodiv";
3952 break;
3953 case EF_M68K_CF_ISA_A:
3954 isa = "A";
3955 break;
3956 case EF_M68K_CF_ISA_A_PLUS:
3957 isa = "A+";
3958 break;
3959 case EF_M68K_CF_ISA_B_NOUSP:
3960 isa = "B";
3961 additional = ", nousp";
3962 break;
3963 case EF_M68K_CF_ISA_B:
3964 isa = "B";
3965 break;
3966 case EF_M68K_CF_ISA_C:
3967 isa = "C";
3968 break;
3969 case EF_M68K_CF_ISA_C_NODIV:
3970 isa = "C";
3971 additional = ", nodiv";
3972 break;
3973 }
3974 out = stpcpy (out, ", cf, isa ");
3975 out = stpcpy (out, isa);
3976 if (additional)
3977 out = stpcpy (out, additional);
3978 if (e_flags & EF_M68K_CF_FLOAT)
3979 out = stpcpy (out, ", float");
3980 switch (e_flags & EF_M68K_CF_MAC_MASK)
3981 {
3982 case 0:
3983 mac = NULL;
3984 break;
3985 case EF_M68K_CF_MAC:
3986 mac = "mac";
3987 break;
3988 case EF_M68K_CF_EMAC:
3989 mac = "emac";
3990 break;
3991 case EF_M68K_CF_EMAC_B:
3992 mac = "emac_b";
3993 break;
3994 }
3995 if (mac)
3996 {
3997 out = stpcpy (out, ", ");
3998 out = stpcpy (out, mac);
3999 }
4000 }
4001 return out;
4002}
4003
4004static char *
4005decode_MeP_machine_flags (char *out, unsigned int e_flags)
4006{
4007 switch (e_flags & EF_MEP_CPU_MASK)
4008 {
4009 case EF_MEP_CPU_MEP:
4010 out = stpcpy (out, ", generic MeP");
4011 break;
4012 case EF_MEP_CPU_C2:
4013 out = stpcpy (out, ", MeP C2");
4014 break;
4015 case EF_MEP_CPU_C3:
4016 out = stpcpy (out, ", MeP C3");
4017 break;
4018 case EF_MEP_CPU_C4:
4019 out = stpcpy (out, ", MeP C4");
4020 break;
4021 case EF_MEP_CPU_C5:
4022 out = stpcpy (out, ", MeP C5");
4023 break;
4024 case EF_MEP_CPU_H1:
4025 out = stpcpy (out, ", MeP H1");
4026 break;
4027 default:
4028 out = stpcpy (out, _(", <unknown MeP cpu type>"));
4029 break;
4030 }
4031
4032 switch (e_flags & EF_MEP_COP_MASK)
4033 {
4034 case EF_MEP_COP_NONE:
4035 break;
4036 case EF_MEP_COP_AVC:
4037 out = stpcpy (out, ", AVC coprocessor");
4038 break;
4039 case EF_MEP_COP_AVC2:
4040 out = stpcpy (out, ", AVC2 coprocessor");
4041 break;
4042 case EF_MEP_COP_FMAX:
4043 out = stpcpy (out, ", FMAX coprocessor");
4044 break;
4045 case EF_MEP_COP_IVC2:
4046 out = stpcpy (out, ", IVC2 coprocessor");
4047 break;
4048 default:
4049 out = stpcpy (out, _("<unknown MeP copro type>"));
4050 break;
4051 }
4052
4053 if (e_flags & EF_MEP_LIBRARY)
4054 out = stpcpy (out, ", Built for Library");
4055
4056 if (e_flags & EF_MEP_INDEX_MASK)
4057 out += sprintf (out, ", Configuration Index: %#x",
4058 e_flags & EF_MEP_INDEX_MASK);
4059
4060 if (e_flags & ~ EF_MEP_ALL_FLAGS)
4061 out += sprintf (out, _(", unknown flags bits: %#x"),
4062 e_flags & ~ EF_MEP_ALL_FLAGS);
4063 return out;
4064}
4065
4066static char *
4067decode_MIPS_machine_flags (char *out, unsigned int e_flags)
4068{
4069 if (e_flags & EF_MIPS_NOREORDER)
4070 out = stpcpy (out, ", noreorder");
4071
4072 if (e_flags & EF_MIPS_PIC)
4073 out = stpcpy (out, ", pic");
4074
4075 if (e_flags & EF_MIPS_CPIC)
4076 out = stpcpy (out, ", cpic");
4077
4078 if (e_flags & EF_MIPS_UCODE)
4079 out = stpcpy (out, ", ugen_reserved");
4080
4081 if (e_flags & EF_MIPS_ABI2)
4082 out = stpcpy (out, ", abi2");
4083
4084 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4085 out = stpcpy (out, ", odk first");
4086
4087 if (e_flags & EF_MIPS_32BITMODE)
4088 out = stpcpy (out, ", 32bitmode");
4089
4090 if (e_flags & EF_MIPS_NAN2008)
4091 out = stpcpy (out, ", nan2008");
4092
4093 if (e_flags & EF_MIPS_FP64)
4094 out = stpcpy (out, ", fp64");
4095
4096 switch ((e_flags & EF_MIPS_MACH))
4097 {
d173146d 4098 case EF_MIPS_MACH_3900:
f8c4789c
AM
4099 out = stpcpy (out, ", 3900");
4100 break;
d173146d 4101 case EF_MIPS_MACH_4010:
f8c4789c
AM
4102 out = stpcpy (out, ", 4010");
4103 break;
d173146d 4104 case EF_MIPS_MACH_4100:
f8c4789c
AM
4105 out = stpcpy (out, ", 4100");
4106 break;
d173146d 4107 case EF_MIPS_MACH_4111:
f8c4789c
AM
4108 out = stpcpy (out, ", 4111");
4109 break;
d173146d 4110 case EF_MIPS_MACH_4120:
f8c4789c
AM
4111 out = stpcpy (out, ", 4120");
4112 break;
d173146d 4113 case EF_MIPS_MACH_4650:
f8c4789c
AM
4114 out = stpcpy (out, ", 4650");
4115 break;
d173146d 4116 case EF_MIPS_MACH_5400:
f8c4789c
AM
4117 out = stpcpy (out, ", 5400");
4118 break;
d173146d 4119 case EF_MIPS_MACH_5500:
f8c4789c
AM
4120 out = stpcpy (out, ", 5500");
4121 break;
d173146d 4122 case EF_MIPS_MACH_5900:
f8c4789c
AM
4123 out = stpcpy (out, ", 5900");
4124 break;
d173146d 4125 case EF_MIPS_MACH_SB1:
f8c4789c
AM
4126 out = stpcpy (out, ", sb1");
4127 break;
d173146d 4128 case EF_MIPS_MACH_9000:
f8c4789c
AM
4129 out = stpcpy (out, ", 9000");
4130 break;
d173146d 4131 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
4132 out = stpcpy (out, ", loongson-2e");
4133 break;
d173146d 4134 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
4135 out = stpcpy (out, ", loongson-2f");
4136 break;
d173146d 4137 case EF_MIPS_MACH_GS464:
f8c4789c
AM
4138 out = stpcpy (out, ", gs464");
4139 break;
d173146d 4140 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
4141 out = stpcpy (out, ", gs464e");
4142 break;
d173146d 4143 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
4144 out = stpcpy (out, ", gs264e");
4145 break;
d173146d 4146 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
4147 out = stpcpy (out, ", octeon");
4148 break;
d173146d 4149 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
4150 out = stpcpy (out, ", octeon2");
4151 break;
d173146d 4152 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
4153 out = stpcpy (out, ", octeon3");
4154 break;
d173146d 4155 case EF_MIPS_MACH_XLR:
f8c4789c
AM
4156 out = stpcpy (out, ", xlr");
4157 break;
d173146d 4158 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
4159 out = stpcpy (out, ", interaptiv-mr2");
4160 break;
d173146d 4161 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
4162 out = stpcpy (out, ", allegrex");
4163 break;
4164 case 0:
4165 /* We simply ignore the field in this case to avoid confusion:
4166 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4167 extension. */
4168 break;
4169 default:
4170 out = stpcpy (out, _(", unknown CPU"));
4171 break;
4172 }
4173
4174 switch ((e_flags & EF_MIPS_ABI))
4175 {
d173146d 4176 case EF_MIPS_ABI_O32:
f8c4789c
AM
4177 out = stpcpy (out, ", o32");
4178 break;
d173146d 4179 case EF_MIPS_ABI_O64:
f8c4789c
AM
4180 out = stpcpy (out, ", o64");
4181 break;
d173146d 4182 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
4183 out = stpcpy (out, ", eabi32");
4184 break;
d173146d 4185 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
4186 out = stpcpy (out, ", eabi64");
4187 break;
4188 case 0:
4189 /* We simply ignore the field in this case to avoid confusion:
4190 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4191 This means it is likely to be an o32 file, but not for
4192 sure. */
4193 break;
4194 default:
4195 out = stpcpy (out, _(", unknown ABI"));
4196 break;
4197 }
4198
4199 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4200 out = stpcpy (out, ", mdmx");
4201
4202 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4203 out = stpcpy (out, ", mips16");
4204
4205 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4206 out = stpcpy (out, ", micromips");
4207
4208 switch ((e_flags & EF_MIPS_ARCH))
4209 {
d173146d 4210 case EF_MIPS_ARCH_1:
f8c4789c
AM
4211 out = stpcpy (out, ", mips1");
4212 break;
d173146d 4213 case EF_MIPS_ARCH_2:
f8c4789c
AM
4214 out = stpcpy (out, ", mips2");
4215 break;
d173146d 4216 case EF_MIPS_ARCH_3:
f8c4789c
AM
4217 out = stpcpy (out, ", mips3");
4218 break;
d173146d 4219 case EF_MIPS_ARCH_4:
f8c4789c
AM
4220 out = stpcpy (out, ", mips4");
4221 break;
d173146d 4222 case EF_MIPS_ARCH_5:
f8c4789c
AM
4223 out = stpcpy (out, ", mips5");
4224 break;
d173146d 4225 case EF_MIPS_ARCH_32:
f8c4789c
AM
4226 out = stpcpy (out, ", mips32");
4227 break;
d173146d 4228 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
4229 out = stpcpy (out, ", mips32r2");
4230 break;
d173146d 4231 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
4232 out = stpcpy (out, ", mips32r6");
4233 break;
d173146d 4234 case EF_MIPS_ARCH_64:
f8c4789c
AM
4235 out = stpcpy (out, ", mips64");
4236 break;
d173146d 4237 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
4238 out = stpcpy (out, ", mips64r2");
4239 break;
d173146d 4240 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
4241 out = stpcpy (out, ", mips64r6");
4242 break;
4243 default:
4244 out = stpcpy (out, _(", unknown ISA"));
4245 break;
4246 }
4247 return out;
4248}
4249
4250static char *
4251decode_MSP430_machine_flags (char *out, unsigned e_flags)
4252{
4253 out = stpcpy (out, _(": architecture variant: "));
4254 switch (e_flags & EF_MSP430_MACH)
4255 {
4256 case E_MSP430_MACH_MSP430x11:
4257 out = stpcpy (out, "MSP430x11");
4258 break;
4259 case E_MSP430_MACH_MSP430x11x1:
4260 out = stpcpy (out, "MSP430x11x1 ");
4261 break;
4262 case E_MSP430_MACH_MSP430x12:
4263 out = stpcpy (out, "MSP430x12");
4264 break;
4265 case E_MSP430_MACH_MSP430x13:
4266 out = stpcpy (out, "MSP430x13");
4267 break;
4268 case E_MSP430_MACH_MSP430x14:
4269 out = stpcpy (out, "MSP430x14");
4270 break;
4271 case E_MSP430_MACH_MSP430x15:
4272 out = stpcpy (out, "MSP430x15");
4273 break;
4274 case E_MSP430_MACH_MSP430x16:
4275 out = stpcpy (out, "MSP430x16");
4276 break;
4277 case E_MSP430_MACH_MSP430x31:
4278 out = stpcpy (out, "MSP430x31");
4279 break;
4280 case E_MSP430_MACH_MSP430x32:
4281 out = stpcpy (out, "MSP430x32");
4282 break;
4283 case E_MSP430_MACH_MSP430x33:
4284 out = stpcpy (out, "MSP430x33");
4285 break;
4286 case E_MSP430_MACH_MSP430x41:
4287 out = stpcpy (out, "MSP430x41");
4288 break;
4289 case E_MSP430_MACH_MSP430x42:
4290 out = stpcpy (out, "MSP430x42");
4291 break;
4292 case E_MSP430_MACH_MSP430x43:
4293 out = stpcpy (out, "MSP430x43");
4294 break;
4295 case E_MSP430_MACH_MSP430x44:
4296 out = stpcpy (out, "MSP430x44");
4297 break;
4298 case E_MSP430_MACH_MSP430X :
4299 out = stpcpy (out, "MSP430X");
4300 break;
4301 default:
4302 out = stpcpy (out, _(": unknown"));
4303 break;
4304 }
4305
4306 if (e_flags & ~ EF_MSP430_MACH)
4307 out = stpcpy (out, _(": unknown extra flag bits also present"));
4308 return out;
4309}
4310
4311static char *
4312decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
4313{
4314 unsigned abi;
4315 unsigned arch;
4316 unsigned config;
4317 unsigned version;
015dc7e1 4318 bool has_fpu = false;
35c08157
KLC
4319
4320 static const char *ABI_STRINGS[] =
4321 {
4322 "ABI v0", /* use r5 as return register; only used in N1213HC */
4323 "ABI v1", /* use r0 as return register */
4324 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4325 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
4326 "AABI",
4327 "ABI2 FP+"
35c08157
KLC
4328 };
4329 static const char *VER_STRINGS[] =
4330 {
4331 "Andes ELF V1.3 or older",
4332 "Andes ELF V1.3.1",
4333 "Andes ELF V1.4"
4334 };
4335 static const char *ARCH_STRINGS[] =
4336 {
4337 "",
4338 "Andes Star v1.0",
4339 "Andes Star v2.0",
4340 "Andes Star v3.0",
4341 "Andes Star v3.0m"
4342 };
4343
4344 abi = EF_NDS_ABI & e_flags;
4345 arch = EF_NDS_ARCH & e_flags;
4346 config = EF_NDS_INST & e_flags;
4347 version = EF_NDS32_ELF_VERSION & e_flags;
4348
35c08157
KLC
4349 switch (abi)
4350 {
4351 case E_NDS_ABI_V0:
4352 case E_NDS_ABI_V1:
4353 case E_NDS_ABI_V2:
4354 case E_NDS_ABI_V2FP:
4355 case E_NDS_ABI_AABI:
40c7a7cb 4356 case E_NDS_ABI_V2FP_PLUS:
35c08157 4357 /* In case there are holes in the array. */
f8c4789c 4358 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
4359 break;
4360
4361 default:
f8c4789c 4362 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4363 break;
4364 }
4365
4366 switch (version)
4367 {
4368 case E_NDS32_ELF_VER_1_2:
4369 case E_NDS32_ELF_VER_1_3:
4370 case E_NDS32_ELF_VER_1_4:
f8c4789c 4371 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4372 break;
4373
4374 default:
f8c4789c 4375 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4376 break;
4377 }
4378
4379 if (E_NDS_ABI_V0 == abi)
4380 {
4381 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4382 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4383 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4384 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4385 return out;
35c08157
KLC
4386 }
4387
4388 switch (arch)
4389 {
4390 case E_NDS_ARCH_STAR_V1_0:
4391 case E_NDS_ARCH_STAR_V2_0:
4392 case E_NDS_ARCH_STAR_V3_0:
4393 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4394 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4395 break;
4396
4397 default:
f8c4789c 4398 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4399 /* ARCH version determines how the e_flags are interpreted.
4400 If it is unknown, we cannot proceed. */
f8c4789c 4401 return out;
35c08157
KLC
4402 }
4403
4404 /* Newer ABI; Now handle architecture specific flags. */
4405 if (arch == E_NDS_ARCH_STAR_V1_0)
4406 {
4407 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4408 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4409
4410 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4411 out = stpcpy (out, ", MAC");
35c08157
KLC
4412
4413 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4414 out = stpcpy (out, ", DIV");
35c08157
KLC
4415
4416 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4417 out = stpcpy (out, ", 16b");
35c08157
KLC
4418 }
4419 else
4420 {
4421 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4422 {
4423 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4424 out = stpcpy (out, ", [B8]");
35c08157 4425 else
f8c4789c 4426 out = stpcpy (out, ", EX9");
35c08157
KLC
4427 }
4428
4429 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4430 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4431
4432 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4433 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4434
4435 if (config & E_NDS32_HAS_16BIT_INST)
4436 {
4437 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4438 out = stpcpy (out, ", 16b");
35c08157 4439 else
f8c4789c 4440 out = stpcpy (out, ", IFC");
35c08157
KLC
4441 }
4442 }
4443
4444 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4445 out = stpcpy (out, ", PERF1");
35c08157
KLC
4446
4447 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4448 out = stpcpy (out, ", PERF2");
35c08157
KLC
4449
4450 if (config & E_NDS32_HAS_FPU_INST)
4451 {
015dc7e1 4452 has_fpu = true;
f8c4789c 4453 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4454 }
4455
4456 if (config & E_NDS32_HAS_FPU_DP_INST)
4457 {
015dc7e1 4458 has_fpu = true;
f8c4789c 4459 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4460 }
4461
4462 if (config & E_NDS32_HAS_FPU_MAC_INST)
4463 {
015dc7e1 4464 has_fpu = true;
f8c4789c 4465 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4466 }
4467
4468 if (has_fpu)
4469 {
4470 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4471 {
4472 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4473 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4474 break;
4475 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4476 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4477 break;
4478 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4479 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4480 break;
4481 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4482 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4483 break;
4484 }
4485 }
4486
4487 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4488 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4489
4490 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4491 out = stpcpy (out, ", STR");
35c08157
KLC
4492
4493 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4494 out = stpcpy (out, ", 16REG");
35c08157
KLC
4495
4496 if (config & E_NDS32_HAS_VIDEO_INST)
4497 {
4498 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4499 out = stpcpy (out, ", VIDEO");
35c08157 4500 else
f8c4789c 4501 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4502 }
4503
4504 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4505 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4506
4507 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4508 out = stpcpy (out, ", L2C");
4509
4510 return out;
35c08157
KLC
4511}
4512
f8c4789c
AM
4513static char *
4514decode_PARISC_machine_flags (char *out, unsigned e_flags)
4515{
4516 switch (e_flags & EF_PARISC_ARCH)
4517 {
4518 case EFA_PARISC_1_0:
4519 out = stpcpy (out, ", PA-RISC 1.0");
4520 break;
4521 case EFA_PARISC_1_1:
4522 out = stpcpy (out, ", PA-RISC 1.1");
4523 break;
4524 case EFA_PARISC_2_0:
4525 out = stpcpy (out, ", PA-RISC 2.0");
4526 break;
4527 default:
4528 break;
4529 }
4530 if (e_flags & EF_PARISC_TRAPNIL)
4531 out = stpcpy (out, ", trapnil");
4532 if (e_flags & EF_PARISC_EXT)
4533 out = stpcpy (out, ", ext");
4534 if (e_flags & EF_PARISC_LSB)
4535 out = stpcpy (out, ", lsb");
4536 if (e_flags & EF_PARISC_WIDE)
4537 out = stpcpy (out, ", wide");
4538 if (e_flags & EF_PARISC_NO_KABP)
4539 out = stpcpy (out, ", no kabp");
4540 if (e_flags & EF_PARISC_LAZYSWAP)
4541 out = stpcpy (out, ", lazyswap");
4542 return out;
4543}
4544
4545static char *
4546decode_RISCV_machine_flags (char *out, unsigned e_flags)
4547{
4548 if (e_flags & EF_RISCV_RVC)
4549 out = stpcpy (out, ", RVC");
4550
4551 if (e_flags & EF_RISCV_RVE)
4552 out = stpcpy (out, ", RVE");
4553
4554 if (e_flags & EF_RISCV_TSO)
4555 out = stpcpy (out, ", TSO");
4556
4557 switch (e_flags & EF_RISCV_FLOAT_ABI)
4558 {
4559 case EF_RISCV_FLOAT_ABI_SOFT:
4560 out = stpcpy (out, ", soft-float ABI");
4561 break;
4562
4563 case EF_RISCV_FLOAT_ABI_SINGLE:
4564 out = stpcpy (out, ", single-float ABI");
4565 break;
4566
4567 case EF_RISCV_FLOAT_ABI_DOUBLE:
4568 out = stpcpy (out, ", double-float ABI");
4569 break;
4570
4571 case EF_RISCV_FLOAT_ABI_QUAD:
4572 out = stpcpy (out, ", quad-float ABI");
4573 break;
4574 }
4575 return out;
4576}
4577
4578static char *
4579decode_RL78_machine_flags (char *out, unsigned e_flags)
4580{
4581 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4582 {
4583 case E_FLAG_RL78_ANY_CPU:
4584 break;
4585 case E_FLAG_RL78_G10:
4586 out = stpcpy (out, ", G10");
4587 break;
4588 case E_FLAG_RL78_G13:
4589 out = stpcpy (out, ", G13");
4590 break;
4591 case E_FLAG_RL78_G14:
4592 out = stpcpy (out, ", G14");
4593 break;
4594 }
4595 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4596 out = stpcpy (out, ", 64-bit doubles");
4597 return out;
4598}
4599
4600static char *
4601decode_RX_machine_flags (char *out, unsigned e_flags)
4602{
4603 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4604 out = stpcpy (out, ", 64-bit doubles");
4605 if (e_flags & E_FLAG_RX_DSP)
4606 out = stpcpy (out, ", dsp");
4607 if (e_flags & E_FLAG_RX_PID)
4608 out = stpcpy (out, ", pid");
4609 if (e_flags & E_FLAG_RX_ABI)
4610 out = stpcpy (out, ", RX ABI");
4611 if (e_flags & E_FLAG_RX_SINSNS_SET)
4612 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4613 ? ", uses String instructions"
4614 : ", bans String instructions"));
4615 if (e_flags & E_FLAG_RX_V2)
4616 out = stpcpy (out, ", V2");
4617 if (e_flags & E_FLAG_RX_V3)
4618 out = stpcpy (out, ", V3");
4619 return out;
4620}
4621
4622static char *
4623decode_SH_machine_flags (char *out, unsigned e_flags)
4624{
4625 switch ((e_flags & EF_SH_MACH_MASK))
4626 {
4627 case EF_SH1:
4628 out = stpcpy (out, ", sh1");
4629 break;
4630 case EF_SH2:
4631 out = stpcpy (out, ", sh2");
4632 break;
4633 case EF_SH3:
4634 out = stpcpy (out, ", sh3");
4635 break;
4636 case EF_SH_DSP:
4637 out = stpcpy (out, ", sh-dsp");
4638 break;
4639 case EF_SH3_DSP:
4640 out = stpcpy (out, ", sh3-dsp");
4641 break;
4642 case EF_SH4AL_DSP:
4643 out = stpcpy (out, ", sh4al-dsp");
4644 break;
4645 case EF_SH3E:
4646 out = stpcpy (out, ", sh3e");
4647 break;
4648 case EF_SH4:
4649 out = stpcpy (out, ", sh4");
4650 break;
4651 case EF_SH5:
4652 out = stpcpy (out, ", sh5");
4653 break;
4654 case EF_SH2E:
4655 out = stpcpy (out, ", sh2e");
4656 break;
4657 case EF_SH4A:
4658 out = stpcpy (out, ", sh4a");
4659 break;
4660 case EF_SH2A:
4661 out = stpcpy (out, ", sh2a");
4662 break;
4663 case EF_SH4_NOFPU:
4664 out = stpcpy (out, ", sh4-nofpu");
4665 break;
4666 case EF_SH4A_NOFPU:
4667 out = stpcpy (out, ", sh4a-nofpu");
4668 break;
4669 case EF_SH2A_NOFPU:
4670 out = stpcpy (out, ", sh2a-nofpu");
4671 break;
4672 case EF_SH3_NOMMU:
4673 out = stpcpy (out, ", sh3-nommu");
4674 break;
4675 case EF_SH4_NOMMU_NOFPU:
4676 out = stpcpy (out, ", sh4-nommu-nofpu");
4677 break;
4678 case EF_SH2A_SH4_NOFPU:
4679 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4680 break;
4681 case EF_SH2A_SH3_NOFPU:
4682 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4683 break;
4684 case EF_SH2A_SH4:
4685 out = stpcpy (out, ", sh2a-or-sh4");
4686 break;
4687 case EF_SH2A_SH3E:
4688 out = stpcpy (out, ", sh2a-or-sh3e");
4689 break;
4690 default:
4691 out = stpcpy (out, _(", unknown ISA"));
4692 break;
4693 }
4694
4695 if (e_flags & EF_SH_PIC)
4696 out = stpcpy (out, ", pic");
4697
4698 if (e_flags & EF_SH_FDPIC)
4699 out = stpcpy (out, ", fdpic");
4700 return out;
4701}
4702
4703static char *
4704decode_SPARC_machine_flags (char *out, unsigned e_flags)
4705{
4706 if (e_flags & EF_SPARC_32PLUS)
4707 out = stpcpy (out, ", v8+");
4708
4709 if (e_flags & EF_SPARC_SUN_US1)
4710 out = stpcpy (out, ", ultrasparcI");
4711
4712 if (e_flags & EF_SPARC_SUN_US3)
4713 out = stpcpy (out, ", ultrasparcIII");
4714
4715 if (e_flags & EF_SPARC_HAL_R1)
4716 out = stpcpy (out, ", halr1");
4717
4718 if (e_flags & EF_SPARC_LEDATA)
4719 out = stpcpy (out, ", ledata");
4720
4721 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4722 out = stpcpy (out, ", tso");
4723
4724 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4725 out = stpcpy (out, ", pso");
4726
4727 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4728 out = stpcpy (out, ", rmo");
4729 return out;
4730}
4731
4732static char *
4733decode_V800_machine_flags (char *out, unsigned int e_flags)
4734{
4735 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4736 out = stpcpy (out, ", RH850 ABI");
4737
4738 if (e_flags & EF_V800_850E3)
4739 out = stpcpy (out, ", V3 architecture");
4740
4741 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4742 out = stpcpy (out, ", FPU not used");
4743
4744 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4745 out = stpcpy (out, ", regmode: COMMON");
4746
4747 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4748 out = stpcpy (out, ", r4 not used");
4749
4750 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4751 out = stpcpy (out, ", r30 not used");
4752
4753 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4754 out = stpcpy (out, ", r5 not used");
4755
4756 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4757 out = stpcpy (out, ", r2 not used");
4758
4759 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4760 {
4761 switch (e_flags & - e_flags)
4762 {
4763 case EF_RH850_FPU_DOUBLE:
4764 out = stpcpy (out, ", double precision FPU");
4765 break;
4766 case EF_RH850_FPU_SINGLE:
4767 out = stpcpy (out, ", single precision FPU");
4768 break;
4769 case EF_RH850_REGMODE22:
4770 out = stpcpy (out, ", regmode:22");
4771 break;
4772 case EF_RH850_REGMODE32:
4773 out = stpcpy (out, ", regmode:23");
4774 break;
4775 case EF_RH850_GP_FIX:
4776 out = stpcpy (out, ", r4 fixed");
4777 break;
4778 case EF_RH850_GP_NOFIX:
4779 out = stpcpy (out, ", r4 free");
4780 break;
4781 case EF_RH850_EP_FIX:
4782 out = stpcpy (out, ", r30 fixed");
4783 break;
4784 case EF_RH850_EP_NOFIX:
4785 out = stpcpy (out, ", r30 free");
4786 break;
4787 case EF_RH850_TP_FIX:
4788 out = stpcpy (out, ", r5 fixed");
4789 break;
4790 case EF_RH850_TP_NOFIX:
4791 out = stpcpy (out, ", r5 free");
4792 break;
4793 case EF_RH850_REG2_RESERVE:
4794 out = stpcpy (out, ", r2 fixed");
4795 break;
4796 case EF_RH850_REG2_NORESERVE:
4797 out = stpcpy (out, ", r2 free");
4798 break;
4799 default:
4800 break;
4801 }
4802 }
4803 return out;
4804}
4805
4806static char *
4807decode_V850_machine_flags (char *out, unsigned int e_flags)
4808{
4809 switch (e_flags & EF_V850_ARCH)
4810 {
4811 case E_V850E3V5_ARCH:
4812 out = stpcpy (out, ", v850e3v5");
4813 break;
4814 case E_V850E2V3_ARCH:
4815 out = stpcpy (out, ", v850e2v3");
4816 break;
4817 case E_V850E2_ARCH:
4818 out = stpcpy (out, ", v850e2");
4819 break;
4820 case E_V850E1_ARCH:
4821 out = stpcpy (out, ", v850e1");
4822 break;
4823 case E_V850E_ARCH:
4824 out = stpcpy (out, ", v850e");
4825 break;
4826 case E_V850_ARCH:
4827 out = stpcpy (out, ", v850");
4828 break;
4829 default:
4830 out = stpcpy (out, _(", unknown v850 architecture variant"));
4831 break;
4832 }
4833 return out;
4834}
4835
4836static char *
4837decode_Z80_machine_flags (char *out, unsigned int e_flags)
4838{
4839 switch (e_flags & EF_Z80_MACH_MSK)
4840 {
4841 case EF_Z80_MACH_Z80:
4842 out = stpcpy (out, ", Z80");
4843 break;
4844 case EF_Z80_MACH_Z180:
4845 out = stpcpy (out, ", Z180");
4846 break;
4847 case EF_Z80_MACH_R800:
4848 out = stpcpy (out, ", R800");
4849 break;
4850 case EF_Z80_MACH_EZ80_Z80:
4851 out = stpcpy (out, ", EZ80");
4852 break;
4853 case EF_Z80_MACH_EZ80_ADL:
4854 out = stpcpy (out, ", EZ80, ADL");
4855 break;
4856 case EF_Z80_MACH_GBZ80:
4857 out = stpcpy (out, ", GBZ80");
4858 break;
4859 case EF_Z80_MACH_Z80N:
4860 out = stpcpy (out, ", Z80N");
4861 break;
4862 default:
4863 out = stpcpy (out, _(", unknown"));
4864 break;
4865 }
4866 return out;
4867}
4868
4869static char *
4870decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4871{
4872 unsigned char *e_ident = filedata->file_header.e_ident;
4873 unsigned char osabi = e_ident[EI_OSABI];
4874 unsigned char abiversion = e_ident[EI_ABIVERSION];
4875 unsigned int mach;
4876
4877 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4878 it has been deprecated for a while.
4879
4880 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4881 of writing, they use the same flags as HSA v3, so the code below uses that
4882 assumption. */
4883 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4884 return out;
c077c580
SM
4885
4886 mach = e_flags & EF_AMDGPU_MACH;
4887 switch (mach)
4888 {
4889#define AMDGPU_CASE(code, string) \
f8c4789c 4890 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4891 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4892 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4893 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4894 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4895 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4896 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4897 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4898 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4899 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4900 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4901 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4902 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4903 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4904 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4905 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4906 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4907 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4908 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4909 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4910 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4911 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4912 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4913 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4914 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4915 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4916 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4917 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4918 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4919 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4920 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4921 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4922 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4923 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4924 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4925 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4926 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4927 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4928 default:
f8c4789c 4929 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4930 break;
4931#undef AMDGPU_CASE
4932 }
4933
c077c580
SM
4934 e_flags &= ~EF_AMDGPU_MACH;
4935
4936 if ((osabi == ELFOSABI_AMDGPU_HSA
4937 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4938 || osabi != ELFOSABI_AMDGPU_HSA)
4939 {
4940 /* For HSA v3 and other OS ABIs. */
4941 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4942 {
f8c4789c 4943 out = stpcpy (out, ", xnack on");
c077c580
SM
4944 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4945 }
4946
4947 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4948 {
f8c4789c 4949 out = stpcpy (out, ", sramecc on");
c077c580
SM
4950 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4951 }
4952 }
4953 else
4954 {
4955 /* For HSA v4+. */
4956 int xnack, sramecc;
4957
4958 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4959 switch (xnack)
4960 {
4961 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4962 break;
4963
4964 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4965 out = stpcpy (out, ", xnack any");
c077c580
SM
4966 break;
4967
4968 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4969 out = stpcpy (out, ", xnack off");
c077c580
SM
4970 break;
4971
4972 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4973 out = stpcpy (out, ", xnack on");
c077c580
SM
4974 break;
4975
4976 default:
f8c4789c 4977 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4978 break;
4979 }
4980
c077c580
SM
4981 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4982
4983 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4984 switch (sramecc)
4985 {
4986 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4987 break;
4988
4989 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4990 out = stpcpy (out, ", sramecc any");
c077c580
SM
4991 break;
4992
4993 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4994 out = stpcpy (out, ", sramecc off");
c077c580
SM
4995 break;
4996
4997 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4998 out = stpcpy (out, ", sramecc on");
c077c580
SM
4999 break;
5000
5001 default:
f8c4789c 5002 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
5003 break;
5004 }
5005
c077c580
SM
5006 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
5007 }
5008
5009 if (e_flags != 0)
f8c4789c
AM
5010 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
5011 return out;
c077c580
SM
5012}
5013
252b5132 5014static char *
dda8d76d 5015get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 5016{
b34976b6 5017 static char buf[1024];
f8c4789c 5018 char *out = buf;
252b5132
RH
5019
5020 buf[0] = '\0';
76da6bbe 5021
252b5132
RH
5022 if (e_flags)
5023 {
5024 switch (e_machine)
5025 {
5026 default:
5027 break;
5028
b5c37946 5029 case EM_ARC_COMPACT3:
f8c4789c 5030 out = stpcpy (out, ", HS5x");
b5c37946
SJ
5031 break;
5032
5033 case EM_ARC_COMPACT3_64:
f8c4789c 5034 out = stpcpy (out, ", HS6x");
b5c37946
SJ
5035 break;
5036
886a2506 5037 case EM_ARC_COMPACT2:
886a2506 5038 case EM_ARC_COMPACT:
f8c4789c
AM
5039 out = decode_ARC_machine_flags (out, e_flags, e_machine);
5040 break;
886a2506 5041
f3485b74 5042 case EM_ARM:
f8c4789c 5043 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 5044 break;
76da6bbe 5045
f8c4789c
AM
5046 case EM_AVR:
5047 out = decode_AVR_machine_flags (out, e_flags);
5048 break;
343433df 5049
781303ce 5050 case EM_BLACKFIN:
f8c4789c 5051 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
5052 break;
5053
ec2dfb42 5054 case EM_CYGNUS_FRV:
f8c4789c 5055 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 5056 break;
ec2dfb42 5057
53c7db4b 5058 case EM_68K:
f8c4789c 5059 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 5060 break;
33c63f9d 5061
c077c580 5062 case EM_AMDGPU:
f8c4789c 5063 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
5064 break;
5065
153a2776 5066 case EM_CYGNUS_MEP:
f8c4789c 5067 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
5068 break;
5069
252b5132
RH
5070 case EM_PPC:
5071 if (e_flags & EF_PPC_EMB)
f8c4789c 5072 out = stpcpy (out, ", emb");
252b5132
RH
5073
5074 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 5075 out = stpcpy (out, _(", relocatable"));
252b5132
RH
5076
5077 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 5078 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
5079 break;
5080
ee67d69a
AM
5081 case EM_PPC64:
5082 if (e_flags & EF_PPC64_ABI)
f8c4789c 5083 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
5084 break;
5085
708e2187 5086 case EM_V800:
f8c4789c 5087 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
5088 break;
5089
2b0337b0 5090 case EM_V850:
252b5132 5091 case EM_CYGNUS_V850:
f8c4789c 5092 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
5093 break;
5094
2b0337b0 5095 case EM_M32R:
252b5132
RH
5096 case EM_CYGNUS_M32R:
5097 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 5098 out = stpcpy (out, ", m32r");
252b5132
RH
5099 break;
5100
5101 case EM_MIPS:
4fe85591 5102 case EM_MIPS_RS3_LE:
f8c4789c 5103 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 5104 break;
351b4b40 5105
35c08157 5106 case EM_NDS32:
f8c4789c 5107 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
5108 break;
5109
fe944acf
FT
5110 case EM_NFP:
5111 switch (EF_NFP_MACH (e_flags))
5112 {
5113 case E_NFP_MACH_3200:
f8c4789c 5114 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
5115 break;
5116 case E_NFP_MACH_6000:
f8c4789c 5117 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
5118 break;
5119 }
5120 break;
5121
e23eba97 5122 case EM_RISCV:
f8c4789c 5123 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
5124 break;
5125
ccde1100 5126 case EM_SH:
f8c4789c 5127 out = decode_SH_machine_flags (out, e_flags);
ccde1100 5128 break;
948f632f 5129
f8c4789c
AM
5130 case EM_OR1K:
5131 if (e_flags & EF_OR1K_NODELAY)
5132 out = stpcpy (out, ", no delay");
5133 break;
57346661 5134
f8c4789c
AM
5135 case EM_BPF:
5136 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
5137 break;
b5c37946 5138
351b4b40 5139 case EM_SPARCV9:
f8c4789c 5140 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 5141 break;
7d466069 5142
103f02d3 5143 case EM_PARISC:
f8c4789c 5144 out = decode_PARISC_machine_flags (out, e_flags);
30800947 5145 break;
76da6bbe 5146
7d466069 5147 case EM_PJ:
2b0337b0 5148 case EM_PJ_OLD:
7d466069 5149 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 5150 out = stpcpy (out, ", new calling convention");
7d466069
ILT
5151
5152 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 5153 out = stpcpy (out, ", gnu calling convention");
7d466069 5154 break;
4d6ed7c8
NC
5155
5156 case EM_IA_64:
f8c4789c 5157 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 5158 break;
179d3252
JT
5159
5160 case EM_VAX:
5161 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 5162 out = stpcpy (out, ", non-PIC");
179d3252 5163 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 5164 out = stpcpy (out, ", D-Float");
179d3252 5165 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 5166 out = stpcpy (out, ", G-Float");
179d3252 5167 break;
c7927a3c 5168
f8c4789c 5169 case EM_VISIUM:
619ed720 5170 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 5171 out = stpcpy (out, ", mcm");
619ed720 5172 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 5173 out = stpcpy (out, ", mcm24");
619ed720 5174 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 5175 out = stpcpy (out, ", gr6");
619ed720
EB
5176 break;
5177
4046d87a 5178 case EM_RL78:
f8c4789c 5179 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 5180 break;
0b4362b0 5181
c7927a3c 5182 case EM_RX:
f8c4789c 5183 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 5184 break;
55786da2
AK
5185
5186 case EM_S390:
5187 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 5188 out = stpcpy (out, ", highgprs");
d4cb0ea0 5189 break;
40b36596
JM
5190
5191 case EM_TI_C6000:
5192 if ((e_flags & EF_C6000_REL))
f8c4789c 5193 out = stpcpy (out, ", relocatable module");
d4cb0ea0 5194 break;
13761a11 5195
6e712424
PI
5196 case EM_KVX:
5197 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5198 strcat (buf, ", Kalray VLIW kv3-1");
5199 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5200 strcat (buf, ", Kalray VLIW kv3-2");
5201 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5202 strcat (buf, ", Kalray VLIW kv4-1");
5203 else
5204 strcat (buf, ", unknown KVX MPPA");
5205 break;
5206
13761a11 5207 case EM_MSP430:
f8c4789c 5208 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
5209 break;
5210
5211 case EM_Z80:
f8c4789c 5212 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 5213 break;
c4a7e6b5 5214
f8c4789c
AM
5215 case EM_LOONGARCH:
5216 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 5217 break;
252b5132
RH
5218 }
5219 }
5220
5221 return buf;
5222}
5223
252b5132 5224static const char *
dda8d76d 5225get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
5226{
5227 static char buff[32];
5228
5229 switch (osabi)
5230 {
5231 case ELFOSABI_NONE: return "UNIX - System V";
5232 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5233 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 5234 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
5235 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5236 case ELFOSABI_AIX: return "UNIX - AIX";
5237 case ELFOSABI_IRIX: return "UNIX - IRIX";
5238 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5239 case ELFOSABI_TRU64: return "UNIX - TRU64";
5240 case ELFOSABI_MODESTO: return "Novell - Modesto";
5241 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5242 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5243 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 5244 case ELFOSABI_AROS: return "AROS";
11636f9e 5245 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
5246 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5247 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
08b0f198 5248 case ELFOSABI_CUDA: return "CUDA";
d3ba0551 5249 default:
40b36596 5250 if (osabi >= 64)
dda8d76d 5251 switch (filedata->file_header.e_machine)
40b36596 5252 {
37870be8
SM
5253 case EM_AMDGPU:
5254 switch (osabi)
5255 {
5256 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5257 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5258 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5259 default:
5260 break;
5261 }
5262 break;
5263
40b36596
JM
5264 case EM_ARM:
5265 switch (osabi)
5266 {
5267 case ELFOSABI_ARM: return "ARM";
18a20338 5268 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
5269 default:
5270 break;
5271 }
5272 break;
5273
5274 case EM_MSP430:
5275 case EM_MSP430_OLD:
619ed720 5276 case EM_VISIUM:
40b36596
JM
5277 switch (osabi)
5278 {
5279 case ELFOSABI_STANDALONE: return _("Standalone App");
5280 default:
5281 break;
5282 }
5283 break;
5284
5285 case EM_TI_C6000:
5286 switch (osabi)
5287 {
5288 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5289 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5290 default:
5291 break;
5292 }
5293 break;
5294
5295 default:
5296 break;
5297 }
e9e44622 5298 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
5299 return buff;
5300 }
5301}
5302
a06ea964
NC
5303static const char *
5304get_aarch64_segment_type (unsigned long type)
5305{
5306 switch (type)
5307 {
08b0f198 5308 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 5309 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
08b0f198 5310 default: return NULL;
a06ea964 5311 }
a06ea964
NC
5312}
5313
b294bdf8
MM
5314static const char *
5315get_arm_segment_type (unsigned long type)
5316{
5317 switch (type)
5318 {
08b0f198
NC
5319 case PT_ARM_ARCHEXT: return "ARM_ARCHEXT";
5320 case PT_ARM_EXIDX: return "ARM_EXIDX";
5321 default: return NULL;
b294bdf8 5322 }
b294bdf8
MM
5323}
5324
b4cbbe8f
AK
5325static const char *
5326get_s390_segment_type (unsigned long type)
5327{
5328 switch (type)
5329 {
5330 case PT_S390_PGSTE: return "S390_PGSTE";
5331 default: return NULL;
5332 }
5333}
5334
d3ba0551
AM
5335static const char *
5336get_mips_segment_type (unsigned long type)
252b5132
RH
5337{
5338 switch (type)
5339 {
32ec8896
NC
5340 case PT_MIPS_REGINFO: return "REGINFO";
5341 case PT_MIPS_RTPROC: return "RTPROC";
5342 case PT_MIPS_OPTIONS: return "OPTIONS";
5343 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5344 default: return NULL;
252b5132 5345 }
252b5132
RH
5346}
5347
103f02d3 5348static const char *
d3ba0551 5349get_parisc_segment_type (unsigned long type)
103f02d3
UD
5350{
5351 switch (type)
5352 {
103f02d3
UD
5353 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5354 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 5355 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 5356 default: return NULL;
103f02d3 5357 }
103f02d3
UD
5358}
5359
4d6ed7c8 5360static const char *
d3ba0551 5361get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
5362{
5363 switch (type)
5364 {
5365 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5366 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5367 default: return NULL;
4d6ed7c8 5368 }
4d6ed7c8
NC
5369}
5370
40b36596
JM
5371static const char *
5372get_tic6x_segment_type (unsigned long type)
5373{
5374 switch (type)
5375 {
32ec8896
NC
5376 case PT_C6000_PHATTR: return "C6000_PHATTR";
5377 default: return NULL;
40b36596 5378 }
40b36596
JM
5379}
5380
fbc95f1e
KC
5381static const char *
5382get_riscv_segment_type (unsigned long type)
5383{
5384 switch (type)
5385 {
5386 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5387 default: return NULL;
5388 }
5389}
5390
df3a023b
AM
5391static const char *
5392get_hpux_segment_type (unsigned long type, unsigned e_machine)
5393{
5394 if (e_machine == EM_PARISC)
5395 switch (type)
5396 {
5397 case PT_HP_TLS: return "HP_TLS";
5398 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5399 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5400 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5401 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5402 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5403 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5404 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5405 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5406 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5407 case PT_HP_PARALLEL: return "HP_PARALLEL";
5408 case PT_HP_FASTBIND: return "HP_FASTBIND";
5409 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5410 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5411 case PT_HP_STACK: return "HP_STACK";
5412 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
08b0f198
NC
5413 default:
5414 break;
df3a023b
AM
5415 }
5416
5417 if (e_machine == EM_IA_64)
5418 switch (type)
5419 {
08b0f198 5420 case PT_HP_TLS: return "HP_TLS";
df3a023b
AM
5421 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5422 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5423 case PT_IA_64_HP_STACK: return "HP_STACK";
08b0f198
NC
5424 default:
5425 break;
df3a023b
AM
5426 }
5427
5428 return NULL;
5429}
5430
5522f910
NC
5431static const char *
5432get_solaris_segment_type (unsigned long type)
5433{
5434 switch (type)
5435 {
08b0f198
NC
5436 case PT_SUNW_UNWIND: return "SUNW_UNWIND";
5437 case PT_SUNW_EH_FRAME: return "SUNW_EH_FRAME";
5438 case PT_SUNWBSS: return "SUNW_BSS";
5439 case PT_SUNWSTACK: return "SUNW_STACK";
5440 case PT_SUNWDTRACE: return "SUNW_DTRACE";
5441 case PT_SUNWCAP: return "SUNW_CAP";
5442 default: return NULL;
5443 }
5444}
5445
5446static const char *
5447get_os_specific_segment_type (Filedata * filedata, unsigned long p_type)
5448{
5449 static char buff[32];
5450 const char * result = NULL;
5451
5452 switch (filedata->file_header.e_ident[EI_OSABI])
5453 {
5454 case ELFOSABI_GNU:
5455 case ELFOSABI_FREEBSD:
5456 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5457 {
5458 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5459 result = buff;
5460 }
5461 break;
5462
5463 case ELFOSABI_HPUX:
5464 result = get_hpux_segment_type (p_type,
5465 filedata->file_header.e_machine);
5466 break;
5467
5468 case ELFOSABI_SOLARIS:
5469 result = get_solaris_segment_type (p_type);
5470 break;
5471
5472 default:
5473 break;
5474 }
5475
5476 if (result != NULL)
5477 return result;
5d526bdf 5478
08b0f198
NC
5479 switch (p_type)
5480 {
5481 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5482 case PT_GNU_STACK: return "GNU_STACK";
5483 case PT_GNU_RELRO: return "GNU_RELRO";
5484 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5485 case PT_GNU_SFRAME: return "GNU_SFRAME";
5486
5487 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5488 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5489 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5490 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5491 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5492 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5493
5494 default:
5495 break;
5522f910 5496 }
08b0f198
NC
5497
5498 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5499 return buff;
5522f910
NC
5500}
5501
08b0f198
NC
5502static const char *
5503get_processor_specific_segment_type (Filedata * filedata, unsigned long p_type)
5504{
5505 static char buff[32];
5506 const char * result = NULL;
5507
5508 switch (filedata->file_header.e_machine)
5509 {
5510 case EM_AARCH64:
5511 result = get_aarch64_segment_type (p_type);
5512 break;
5513
5514 case EM_ARM:
5515 result = get_arm_segment_type (p_type);
5516 break;
5517
5518 case EM_MIPS:
5519 case EM_MIPS_RS3_LE:
5520 result = get_mips_segment_type (p_type);
5521 break;
5522
5523 case EM_PARISC:
5524 result = get_parisc_segment_type (p_type);
5525 break;
5526
5527 case EM_IA_64:
5528 result = get_ia64_segment_type (p_type);
5529 break;
5530
5531 case EM_TI_C6000:
5532 result = get_tic6x_segment_type (p_type);
5533 break;
5534
5535 case EM_S390:
5536 case EM_S390_OLD:
5537 result = get_s390_segment_type (p_type);
5538 break;
5539
5540 case EM_RISCV:
5541 result = get_riscv_segment_type (p_type);
5542 break;
5543
5544 default:
5545 result = NULL;
5546 break;
5547 }
5548
5549 if (result != NULL)
5550 return result;
5551
5552 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5553 return buff;
5554}
5d526bdf 5555
252b5132 5556static const char *
dda8d76d 5557get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5558{
b34976b6 5559 static char buff[32];
252b5132
RH
5560
5561 switch (p_type)
5562 {
b34976b6
AM
5563 case PT_NULL: return "NULL";
5564 case PT_LOAD: return "LOAD";
252b5132 5565 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5566 case PT_INTERP: return "INTERP";
5567 case PT_NOTE: return "NOTE";
5568 case PT_SHLIB: return "SHLIB";
5569 case PT_PHDR: return "PHDR";
13ae64f3 5570 case PT_TLS: return "TLS";
08b0f198
NC
5571 case PT_NUM: return "NUM";
5572 }
103f02d3 5573
08b0f198
NC
5574 if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5575 return get_os_specific_segment_type (filedata, p_type);
103f02d3 5576
08b0f198
NC
5577 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5578 return get_processor_specific_segment_type (filedata, p_type);
252b5132 5579
08b0f198
NC
5580 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5581 return buff;
252b5132
RH
5582}
5583
53a346d8
CZ
5584static const char *
5585get_arc_section_type_name (unsigned int sh_type)
5586{
5587 switch (sh_type)
5588 {
5589 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5590 default:
5591 break;
5592 }
5593 return NULL;
5594}
5595
252b5132 5596static const char *
d3ba0551 5597get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5598{
5599 switch (sh_type)
5600 {
b34976b6
AM
5601 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5602 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5603 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5604 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5605 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5606 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5607 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5608 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5609 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5610 case SHT_MIPS_RELD: return "MIPS_RELD";
5611 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5612 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5613 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5614 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5615 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5616 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5617 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5618 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5619 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5620 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5621 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5622 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5623 case SHT_MIPS_LINE: return "MIPS_LINE";
5624 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5625 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5626 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5627 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5628 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5629 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5630 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5631 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5632 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5633 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5634 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5635 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5636 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5637 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5638 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5639 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5640 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5641 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5642 default:
5643 break;
5644 }
5645 return NULL;
5646}
5647
103f02d3 5648static const char *
d3ba0551 5649get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5650{
5651 switch (sh_type)
5652 {
5653 case SHT_PARISC_EXT: return "PARISC_EXT";
5654 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5655 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817 5656 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
08b0f198 5657 case SHT_PARISC_DLKM: return "PARISC_DLKM";
eec8f817
DA
5658 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5659 case SHT_PARISC_STUBS: return "PARISC_STUBS";
32ec8896 5660 default: return NULL;
103f02d3 5661 }
103f02d3
UD
5662}
5663
4d6ed7c8 5664static const char *
dda8d76d 5665get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5666{
18bd398b 5667 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5668 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5669 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5670
4d6ed7c8
NC
5671 switch (sh_type)
5672 {
148b93f2
NC
5673 case SHT_IA_64_EXT: return "IA_64_EXT";
5674 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5675 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
08b0f198
NC
5676 default:
5677 break;
5678 }
5679 return NULL;
5680}
5681
5682static const char *
5683get_vms_section_type_name (unsigned int sh_type)
5684{
5685 switch (sh_type)
5686 {
148b93f2
NC
5687 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5688 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5689 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5690 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5691 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5692 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5693 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5694 default:
5695 break;
5696 }
5697 return NULL;
5698}
5699
d2b2c203
DJ
5700static const char *
5701get_x86_64_section_type_name (unsigned int sh_type)
5702{
5703 switch (sh_type)
5704 {
5705 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5706 default: return NULL;
d2b2c203 5707 }
d2b2c203
DJ
5708}
5709
a06ea964
NC
5710static const char *
5711get_aarch64_section_type_name (unsigned int sh_type)
5712{
5713 switch (sh_type)
5714 {
08b0f198
NC
5715 case SHT_AARCH64_ATTRIBUTES:
5716 return "AARCH64_ATTRIBUTES";
5717 case SHT_AARCH64_AUTH_RELR:
5718 return "AARCH64_AUTH_RELR";
5719 case SHT_AARCH64_MEMTAG_GLOBALS_STATIC:
5720 return "AARCH64_MEMTAG_GLOBALS_STATIC";
5721 case SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC:
5722 return "AARCH64_MEMTAG_GLOBALS_DYNAMIC";
5723 default:
5724 return NULL;
a06ea964 5725 }
a06ea964
NC
5726}
5727
40a18ebd
NC
5728static const char *
5729get_arm_section_type_name (unsigned int sh_type)
5730{
5731 switch (sh_type)
5732 {
7f6fed87
NC
5733 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5734 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5735 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5736 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5737 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5738 default: return NULL;
40a18ebd 5739 }
40a18ebd
NC
5740}
5741
40b36596
JM
5742static const char *
5743get_tic6x_section_type_name (unsigned int sh_type)
5744{
5745 switch (sh_type)
5746 {
32ec8896
NC
5747 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5748 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5749 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5750 case SHT_TI_ICODE: return "TI_ICODE";
5751 case SHT_TI_XREF: return "TI_XREF";
5752 case SHT_TI_HANDLER: return "TI_HANDLER";
5753 case SHT_TI_INITINFO: return "TI_INITINFO";
5754 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5755 default: return NULL;
40b36596 5756 }
40b36596
JM
5757}
5758
13761a11 5759static const char *
b0191216 5760get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5761{
5762 switch (sh_type)
5763 {
32ec8896
NC
5764 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5765 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5766 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5767 default: return NULL;
13761a11
NC
5768 }
5769}
5770
fe944acf
FT
5771static const char *
5772get_nfp_section_type_name (unsigned int sh_type)
5773{
5774 switch (sh_type)
5775 {
5776 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5777 case SHT_NFP_INITREG: return "NFP_INITREG";
5778 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5779 default: return NULL;
5780 }
5781}
5782
685080f2
NC
5783static const char *
5784get_v850_section_type_name (unsigned int sh_type)
5785{
5786 switch (sh_type)
5787 {
32ec8896
NC
5788 case SHT_V850_SCOMMON: return "V850 Small Common";
5789 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5790 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5791 case SHT_RENESAS_IOP: return "RENESAS IOP";
5792 case SHT_RENESAS_INFO: return "RENESAS INFO";
5793 default: return NULL;
685080f2
NC
5794 }
5795}
5796
2dc8dd17
JW
5797static const char *
5798get_riscv_section_type_name (unsigned int sh_type)
5799{
5800 switch (sh_type)
5801 {
5802 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5803 default: return NULL;
5804 }
5805}
5806
0861f561
CQ
5807static const char *
5808get_csky_section_type_name (unsigned int sh_type)
5809{
5810 switch (sh_type)
5811 {
5812 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5813 default: return NULL;
5814 }
5815}
5816
252b5132 5817static const char *
08b0f198
NC
5818get_powerpc_section_type_name (unsigned int sh_type)
5819{
5820 switch (sh_type)
5821 {
5822 case SHT_ORDERED: return "ORDERED";
5823 default: return NULL;
5824 }
5825}
5826
5827static const char *
5828get_alpha_section_type_name (unsigned int sh_type)
5829{
5830 switch (sh_type)
5831 {
5832 case SHT_ALPHA_DEBUG: return "DEBUG";
5833 case SHT_ALPHA_REGINFO: return "REGINFO";
5834 default: return NULL;
5835 }
5836}
5837
5838static const char *
5839get_processor_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5840{
5841 static char buff[32];
5842 const char * result = NULL;
5843
5844 switch (filedata->file_header.e_machine)
5845 {
5846 case EM_AARCH64:
5847 result = get_aarch64_section_type_name (sh_type);
5848 break;
5849
5850 case EM_ALPHA:
5851 result = get_alpha_section_type_name (sh_type);
5852 break;
5853
5854 case EM_ARC:
5855 case EM_ARC_COMPACT:
5856 case EM_ARC_COMPACT2:
5857 case EM_ARC_COMPACT3:
5858 case EM_ARC_COMPACT3_64:
5859 result = get_arc_section_type_name (sh_type);
5860 break;
5861
5862 case EM_ARM:
5863 result = get_arm_section_type_name (sh_type);
5864 break;
5865
5866 case EM_CSKY:
5867 result = get_csky_section_type_name (sh_type);
5868 break;
5869
5870 case EM_IA_64:
5871 result = get_ia64_section_type_name (filedata, sh_type);
5872 break;
5873
5874 case EM_MIPS:
5875 case EM_MIPS_RS3_LE:
5876 result = get_mips_section_type_name (sh_type);
5877 break;
5878
5879 case EM_MSP430:
5880 result = get_msp430_section_type_name (sh_type);
5881 break;
5882
5883 case EM_NFP:
5884 result = get_nfp_section_type_name (sh_type);
5885 break;
5886
5887 case EM_PARISC:
5888 result = get_parisc_section_type_name (sh_type);
5889 break;
5890
5891 case EM_PPC64:
5892 case EM_PPC:
5893 return get_powerpc_section_type_name (sh_type);
5894 break;
5895
5896 case EM_RISCV:
5897 result = get_riscv_section_type_name (sh_type);
5898 break;
5899
5900 case EM_TI_C6000:
5901 result = get_tic6x_section_type_name (sh_type);
5902 break;
5903
5904 case EM_V800:
5905 case EM_V850:
5906 case EM_CYGNUS_V850:
5907 result = get_v850_section_type_name (sh_type);
5908 break;
5909
5910 case EM_X86_64:
5911 case EM_L1OM:
5912 case EM_K1OM:
5913 result = get_x86_64_section_type_name (sh_type);
5914 break;
5915
5916 default:
5917 break;
5918 }
5919
5920 if (result != NULL)
5921 return result;
5922
5923 switch (sh_type)
5924 {
5925 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5926 case 0x7ffffffd: return "AUXILIARY";
5927 case 0x7fffffff: return "FILTER";
5928 default:
5929 break;
5930 }
5931
5932 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5933 return buff;
5934}
5935
5936static const char *
5937get_os_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5938{
5939 static char buff[32];
5940 const char * result = NULL;
5941
5942 switch (filedata->file_header.e_machine)
5943 {
5944 case EM_IA_64:
5945 result = get_vms_section_type_name (sh_type);
5946 break;
5947 default:
5948 break;
5949 }
5950
5951 if (result != NULL)
5952 return result;
5953
5954 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5955 result = get_solaris_section_type (sh_type);
5956
5957 if (result != NULL)
5958 return result;
5959
5960 switch (sh_type)
5961 {
5962 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
5963 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5964 case SHT_GNU_HASH: return "GNU_HASH";
5965 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
9b854f16 5966 case SHT_GNU_OBJECT_ONLY: return "GNU_OBJECT_ONLY";
08b0f198
NC
5967
5968 case SHT_SUNW_move: return "SUNW_MOVE";
5969 case SHT_SUNW_COMDAT: return "SUNW_COMDAT";
5970 case SHT_SUNW_syminfo: return "SUNW_SYMINFO";
5971 case SHT_GNU_verdef: return "VERDEF";
5972 case SHT_GNU_verneed: return "VERNEED";
5973 case SHT_GNU_versym: return "VERSYM";
5d526bdf 5974
08b0f198
NC
5975 case SHT_LLVM_ODRTAB: return "LLVM_ODRTAB";
5976 case SHT_LLVM_LINKER_OPTIONS: return "LLVM_LINKER_OPTIONS";
5977 case SHT_LLVM_ADDRSIG: return "LLVM_ADDRSIG";
5978 case SHT_LLVM_DEPENDENT_LIBRARIES: return "LLVM_DEPENDENT_LIBRARIES";
5979 case SHT_LLVM_SYMPART: return "LLVM_SYMPART";
5980 case SHT_LLVM_PART_EHDR: return "LLVM_PART_EHDR";
5981 case SHT_LLVM_PART_PHDR: return "LLVM_PART_PHDR";
5982 case SHT_LLVM_BB_ADDR_MAP_V0: return "LLVM_BB_ADDR_MAP_V0";
5983 case SHT_LLVM_CALL_GRAPH_PROFILE: return "LLVM_CALL_GRAPH_PROFILE";
5984 case SHT_LLVM_BB_ADDR_MAP: return "LLVM_BB_ADDR_MAP";
5985 case SHT_LLVM_OFFLOADING: return "LLVM_OFFLOADING";
5986 case SHT_LLVM_LTO: return "LLVM_LTO";
5987
5988 case SHT_ANDROID_REL: return "ANDROID_REL";
5989 case SHT_ANDROID_RELA: return "ANDROID_RELA";
5990 case SHT_ANDROID_RELR: return "ANDROID_RELR";
5991
5992 case SHT_CHECKSUM: return "CHECKSUM";
5d526bdf 5993
08b0f198
NC
5994 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5995 case 0x6ffffff0: return "VERSYM";
5d526bdf 5996
08b0f198
NC
5997 default:
5998 break;
5999 }
6000
6001 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
6002 return buff;
6003}
6004
6005static const char *
6006get_user_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 6007{
b34976b6 6008 static char buff[32];
9fb71ee4 6009 const char * result;
252b5132 6010
08b0f198
NC
6011 switch (filedata->file_header.e_machine)
6012 {
6013 case EM_V800:
6014 case EM_V850:
6015 case EM_CYGNUS_V850:
6016 result = get_v850_section_type_name (sh_type);
6017 break;
6018
6019 default:
6020 result = NULL;
6021 break;
6022 }
6023
6024 if (result != NULL)
6025 return result;
6026
6027 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
6028 return buff;
6029}
6030
6031static const char *
6032get_section_type_name (Filedata * filedata,
6033 unsigned int sh_type)
6034{
252b5132
RH
6035 switch (sh_type)
6036 {
6037 case SHT_NULL: return "NULL";
6038 case SHT_PROGBITS: return "PROGBITS";
6039 case SHT_SYMTAB: return "SYMTAB";
6040 case SHT_STRTAB: return "STRTAB";
6041 case SHT_RELA: return "RELA";
6042 case SHT_HASH: return "HASH";
6043 case SHT_DYNAMIC: return "DYNAMIC";
6044 case SHT_NOTE: return "NOTE";
6045 case SHT_NOBITS: return "NOBITS";
6046 case SHT_REL: return "REL";
6047 case SHT_SHLIB: return "SHLIB";
6048 case SHT_DYNSYM: return "DYNSYM";
8e8d0b63 6049 /* 12 and 13 are not defined. */
d1133906
NC
6050 case SHT_INIT_ARRAY: return "INIT_ARRAY";
6051 case SHT_FINI_ARRAY: return "FINI_ARRAY";
6052 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586 6053 case SHT_GROUP: return "GROUP";
67ce483b 6054 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
8e8d0b63
NC
6055 case SHT_RELR: return "RELR";
6056 /* End of generic section types. */
6057
252b5132 6058 default:
08b0f198
NC
6059 break;
6060 }
148b93f2 6061
08b0f198
NC
6062 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
6063 return get_processor_specific_section_type_name (filedata, sh_type);
148b93f2 6064
08b0f198
NC
6065 if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
6066 return get_os_specific_section_type_name (filedata, sh_type);
685080f2 6067
08b0f198
NC
6068 if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
6069 return get_user_specific_section_type_name (filedata, sh_type);
9fb71ee4 6070
08b0f198 6071 static char buff[32];
103f02d3 6072
08b0f198
NC
6073 /* This message is probably going to be displayed in a 15
6074 character wide field, so put the hex value first. */
6075 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
6076 return buff;
252b5132
RH
6077}
6078
79bc120c
NC
6079enum long_option_values
6080{
6081 OPTION_DEBUG_DUMP = 512,
6082 OPTION_DYN_SYMS,
0f03783c 6083 OPTION_LTO_SYMS,
79bc120c
NC
6084 OPTION_DWARF_DEPTH,
6085 OPTION_DWARF_START,
6086 OPTION_DWARF_CHECK,
6087 OPTION_CTF_DUMP,
6088 OPTION_CTF_PARENT,
6089 OPTION_CTF_SYMBOLS,
6090 OPTION_CTF_STRINGS,
42b6953b 6091 OPTION_SFRAME_DUMP,
79bc120c
NC
6092 OPTION_WITH_SYMBOL_VERSIONS,
6093 OPTION_RECURSE_LIMIT,
6094 OPTION_NO_RECURSE_LIMIT,
047c3dbf 6095 OPTION_NO_DEMANGLING,
b6ac461a 6096 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 6097 OPTION_SYM_BASE
79bc120c 6098};
2979dc34 6099
85b1c36d 6100static struct option options[] =
252b5132 6101{
79bc120c
NC
6102 /* Note - This table is alpha-sorted on the 'val'
6103 field in order to make adding new options easier. */
6104 {"arch-specific", no_argument, 0, 'A'},
b34976b6 6105 {"all", no_argument, 0, 'a'},
79bc120c
NC
6106 {"demangle", optional_argument, 0, 'C'},
6107 {"archive-index", no_argument, 0, 'c'},
6108 {"use-dynamic", no_argument, 0, 'D'},
6109 {"dynamic", no_argument, 0, 'd'},
b34976b6 6110 {"headers", no_argument, 0, 'e'},
79bc120c
NC
6111 {"section-groups", no_argument, 0, 'g'},
6112 {"help", no_argument, 0, 'H'},
6113 {"file-header", no_argument, 0, 'h'},
b34976b6 6114 {"histogram", no_argument, 0, 'I'},
8e8d0b63 6115 {"display-section", required_argument, 0, 'j'},
79bc120c
NC
6116 {"lint", no_argument, 0, 'L'},
6117 {"enable-checks", no_argument, 0, 'L'},
6118 {"program-headers", no_argument, 0, 'l'},
b34976b6 6119 {"segments", no_argument, 0, 'l'},
595cf52e 6120 {"full-section-name",no_argument, 0, 'N'},
79bc120c 6121 {"notes", no_argument, 0, 'n'},
ca0e11aa 6122 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
6123 {"string-dump", required_argument, 0, 'p'},
6124 {"relocated-dump", required_argument, 0, 'R'},
6125 {"relocs", no_argument, 0, 'r'},
6126 {"section-headers", no_argument, 0, 'S'},
6127 {"sections", no_argument, 0, 'S'},
b34976b6
AM
6128 {"symbols", no_argument, 0, 's'},
6129 {"syms", no_argument, 0, 's'},
79bc120c
NC
6130 {"silent-truncation",no_argument, 0, 'T'},
6131 {"section-details", no_argument, 0, 't'},
b3aa80b4 6132 {"unicode", required_argument, NULL, 'U'},
09c11c86 6133 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
6134 {"version-info", no_argument, 0, 'V'},
6135 {"version", no_argument, 0, 'v'},
6136 {"wide", no_argument, 0, 'W'},
b6ac461a 6137 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 6138 {"hex-dump", required_argument, 0, 'x'},
0e602686 6139 {"decompress", no_argument, 0, 'z'},
252b5132 6140
79bc120c 6141 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 6142 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
6143 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
6144 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6145 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6146 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 6147 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 6148 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
6149 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
6150 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 6151 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 6152#ifdef ENABLE_LIBCTF
d344b407 6153 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
6154 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
6155 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
6156 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 6157#endif
42b6953b 6158 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 6159 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 6160
b34976b6 6161 {0, no_argument, 0, 0}
252b5132
RH
6162};
6163
6164static void
2cf0635d 6165usage (FILE * stream)
252b5132 6166{
92f01d61
JM
6167 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
6168 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
6169 fprintf (stream, _(" Options are:\n"));
6170 fprintf (stream, _("\
6171 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
6172 fprintf (stream, _("\
6173 -h --file-header Display the ELF file header\n"));
6174 fprintf (stream, _("\
6175 -l --program-headers Display the program headers\n"));
6176 fprintf (stream, _("\
6177 --segments An alias for --program-headers\n"));
6178 fprintf (stream, _("\
6179 -S --section-headers Display the sections' header\n"));
6180 fprintf (stream, _("\
6181 --sections An alias for --section-headers\n"));
6182 fprintf (stream, _("\
6183 -g --section-groups Display the section groups\n"));
6184 fprintf (stream, _("\
6185 -t --section-details Display the section details\n"));
6186 fprintf (stream, _("\
6187 -e --headers Equivalent to: -h -l -S\n"));
6188 fprintf (stream, _("\
6189 -s --syms Display the symbol table\n"));
6190 fprintf (stream, _("\
6191 --symbols An alias for --syms\n"));
6192 fprintf (stream, _("\
6193 --dyn-syms Display the dynamic symbol table\n"));
6194 fprintf (stream, _("\
6195 --lto-syms Display LTO symbol tables\n"));
6196 fprintf (stream, _("\
047c3dbf
NL
6197 --sym-base=[0|8|10|16] \n\
6198 Force base for symbol sizes. The options are \n\
d6249f5f
AM
6199 mixed (the default), octal, decimal, hexadecimal.\n"));
6200 fprintf (stream, _("\
0d646226
AM
6201 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
6202 display_demangler_styles (stream, _("\
6203 STYLE can be "));
d6249f5f
AM
6204 fprintf (stream, _("\
6205 --no-demangle Do not demangle low-level symbol names. (default)\n"));
6206 fprintf (stream, _("\
6207 --recurse-limit Enable a demangling recursion limit. (default)\n"));
6208 fprintf (stream, _("\
6209 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
6210 fprintf (stream, _("\
6211 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
6212 Display unicode characters as determined by the current locale\n\
6213 (default), escape sequences, \"<hex sequences>\", highlighted\n\
6214 escape sequences, or treat them as invalid and display as\n\
6215 \"{hex sequences}\"\n"));
d6249f5f 6216 fprintf (stream, _("\
b6ac461a
NC
6217 -X --extra-sym-info Display extra information when showing symbols\n"));
6218 fprintf (stream, _("\
5d526bdf 6219 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
b6ac461a
NC
6220 fprintf (stream, _("\
6221 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
6222 fprintf (stream, _("\
6223 -r --relocs Display the relocations (if present)\n"));
6224 fprintf (stream, _("\
6225 -u --unwind Display the unwind info (if present)\n"));
6226 fprintf (stream, _("\
6227 -d --dynamic Display the dynamic section (if present)\n"));
6228 fprintf (stream, _("\
6229 -V --version-info Display the version sections (if present)\n"));
6230 fprintf (stream, _("\
6231 -A --arch-specific Display architecture specific information (if any)\n"));
6232 fprintf (stream, _("\
6233 -c --archive-index Display the symbol/file index in an archive\n"));
6234 fprintf (stream, _("\
6235 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
6236 fprintf (stream, _("\
6237 -L --lint|--enable-checks\n\
6238 Display warning messages for possible problems\n"));
6239 fprintf (stream, _("\
09c11c86 6240 -x --hex-dump=<number|name>\n\
d6249f5f
AM
6241 Dump the contents of section <number|name> as bytes\n"));
6242 fprintf (stream, _("\
09c11c86 6243 -p --string-dump=<number|name>\n\
d6249f5f
AM
6244 Dump the contents of section <number|name> as strings\n"));
6245 fprintf (stream, _("\
cf13d699 6246 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
6247 Dump the relocated contents of section <number|name>\n"));
6248 fprintf (stream, _("\
6249 -z --decompress Decompress section before dumping it\n"));
8e8d0b63
NC
6250 fprintf (stream, _("\n\
6251 -j --display-section=<name|number>\n\
6252 Display the contents of the indicated section. Can be repeated\n"));
d6249f5f
AM
6253 fprintf (stream, _("\
6254 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
6255 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
6256 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
6257 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
6258 U/=trace_info]\n\
6259 Display the contents of DWARF debug sections\n"));
6260 fprintf (stream, _("\
6261 -wk --debug-dump=links Display the contents of sections that link to separate\n\
6262 debuginfo files\n"));
6263 fprintf (stream, _("\
6264 -P --process-links Display the contents of non-debug sections in separate\n\
6265 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
6266#if DEFAULT_FOR_FOLLOW_LINKS
6267 fprintf (stream, _("\
d6249f5f
AM
6268 -wK --debug-dump=follow-links\n\
6269 Follow links to separate debug info files (default)\n"));
6270 fprintf (stream, _("\
6271 -wN --debug-dump=no-follow-links\n\
6272 Do not follow links to separate debug info files\n"));
c46b7066
NC
6273#else
6274 fprintf (stream, _("\
d6249f5f
AM
6275 -wK --debug-dump=follow-links\n\
6276 Follow links to separate debug info files\n"));
6277 fprintf (stream, _("\
6278 -wN --debug-dump=no-follow-links\n\
6279 Do not follow links to separate debug info files\n\
6280 (default)\n"));
bed566bb
NC
6281#endif
6282#if HAVE_LIBDEBUGINFOD
6283 fprintf (stream, _("\
6284 -wD --debug-dump=use-debuginfod\n\
6285 When following links, also query debuginfod servers (default)\n"));
6286 fprintf (stream, _("\
6287 -wE --debug-dump=do-not-use-debuginfod\n\
6288 When following links, do not query debuginfod servers\n"));
c46b7066 6289#endif
fd2f0033 6290 fprintf (stream, _("\
d6249f5f
AM
6291 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6292 fprintf (stream, _("\
6293 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 6294#ifdef ENABLE_LIBCTF
7d9813f1 6295 fprintf (stream, _("\
d6249f5f
AM
6296 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6297 fprintf (stream, _("\
80b56fad 6298 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 6299 fprintf (stream, _("\
7d9813f1 6300 --ctf-symbols=<number|name>\n\
d6249f5f
AM
6301 Use section <number|name> as the CTF external symtab\n"));
6302 fprintf (stream, _("\
7d9813f1 6303 --ctf-strings=<number|name>\n\
d6249f5f 6304 Use section <number|name> as the CTF external strtab\n"));
094e34f2 6305#endif
42b6953b
IB
6306 fprintf (stream, _("\
6307 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 6308
252b5132 6309#ifdef SUPPORT_DISASSEMBLY
92f01d61 6310 fprintf (stream, _("\
09c11c86
NC
6311 -i --instruction-dump=<number|name>\n\
6312 Disassemble the contents of section <number|name>\n"));
252b5132 6313#endif
92f01d61 6314 fprintf (stream, _("\
d6249f5f
AM
6315 -I --histogram Display histogram of bucket list lengths\n"));
6316 fprintf (stream, _("\
6317 -W --wide Allow output width to exceed 80 characters\n"));
6318 fprintf (stream, _("\
6319 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6320 fprintf (stream, _("\
6321 @<file> Read options from <file>\n"));
6322 fprintf (stream, _("\
6323 -H --help Display this information\n"));
6324 fprintf (stream, _("\
8b53311e 6325 -v --version Display the version number of readelf\n"));
1118d252 6326
92f01d61
JM
6327 if (REPORT_BUGS_TO[0] && stream == stdout)
6328 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 6329
92f01d61 6330 exit (stream == stdout ? 0 : 1);
252b5132
RH
6331}
6332
18bd398b
NC
6333/* Record the fact that the user wants the contents of section number
6334 SECTION to be displayed using the method(s) encoded as flags bits
6335 in TYPE. Note, TYPE can be zero if we are creating the array for
6336 the first time. */
6337
252b5132 6338static void
6431e409
AM
6339request_dump_bynumber (struct dump_data *dumpdata,
6340 unsigned int section, dump_type type)
252b5132 6341{
6431e409 6342 if (section >= dumpdata->num_dump_sects)
252b5132 6343 {
2cf0635d 6344 dump_type * new_dump_sects;
252b5132 6345
3f5e193b 6346 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 6347 sizeof (* new_dump_sects));
252b5132
RH
6348
6349 if (new_dump_sects == NULL)
591a748a 6350 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
6351 else
6352 {
6431e409 6353 if (dumpdata->dump_sects)
21b65bac
NC
6354 {
6355 /* Copy current flag settings. */
6431e409
AM
6356 memcpy (new_dump_sects, dumpdata->dump_sects,
6357 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 6358
6431e409 6359 free (dumpdata->dump_sects);
21b65bac 6360 }
252b5132 6361
6431e409
AM
6362 dumpdata->dump_sects = new_dump_sects;
6363 dumpdata->num_dump_sects = section + 1;
252b5132
RH
6364 }
6365 }
6366
6431e409
AM
6367 if (dumpdata->dump_sects)
6368 dumpdata->dump_sects[section] |= type;
252b5132
RH
6369}
6370
aef1f6d0
DJ
6371/* Request a dump by section name. */
6372
6373static void
2cf0635d 6374request_dump_byname (const char * section, dump_type type)
aef1f6d0 6375{
2cf0635d 6376 struct dump_list_entry * new_request;
aef1f6d0 6377
3f5e193b
NC
6378 new_request = (struct dump_list_entry *)
6379 malloc (sizeof (struct dump_list_entry));
aef1f6d0 6380 if (!new_request)
591a748a 6381 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6382
6383 new_request->name = strdup (section);
6384 if (!new_request->name)
591a748a 6385 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6386
6387 new_request->type = type;
6388
6389 new_request->next = dump_sects_byname;
6390 dump_sects_byname = new_request;
6391}
6392
cf13d699 6393static inline void
6431e409 6394request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
6395{
6396 int section;
6397 char * cp;
6398
015dc7e1 6399 do_dump = true;
cf13d699
NC
6400 section = strtoul (optarg, & cp, 0);
6401
6402 if (! *cp && section >= 0)
6431e409 6403 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
6404 else
6405 request_dump_byname (optarg, type);
6406}
6407
252b5132 6408static void
6431e409 6409parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
6410{
6411 int c;
6412
6413 if (argc < 2)
92f01d61 6414 usage (stderr);
252b5132
RH
6415
6416 while ((c = getopt_long
8e8d0b63 6417 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 6418 {
252b5132
RH
6419 switch (c)
6420 {
6421 case 0:
6422 /* Long options. */
6423 break;
6424 case 'H':
92f01d61 6425 usage (stdout);
252b5132
RH
6426 break;
6427
6428 case 'a':
015dc7e1
AM
6429 do_syms = true;
6430 do_reloc = true;
6431 do_unwind = true;
6432 do_dynamic = true;
6433 do_header = true;
6434 do_sections = true;
6435 do_section_groups = true;
6436 do_segments = true;
6437 do_version = true;
6438 do_histogram = true;
6439 do_arch = true;
6440 do_notes = true;
252b5132 6441 break;
79bc120c 6442
f5842774 6443 case 'g':
015dc7e1 6444 do_section_groups = true;
f5842774 6445 break;
5477e8a0 6446 case 't':
595cf52e 6447 case 'N':
015dc7e1
AM
6448 do_sections = true;
6449 do_section_details = true;
595cf52e 6450 break;
252b5132 6451 case 'e':
015dc7e1
AM
6452 do_header = true;
6453 do_sections = true;
6454 do_segments = true;
252b5132 6455 break;
a952a375 6456 case 'A':
015dc7e1 6457 do_arch = true;
a952a375 6458 break;
252b5132 6459 case 'D':
015dc7e1 6460 do_using_dynamic = true;
252b5132
RH
6461 break;
6462 case 'r':
015dc7e1 6463 do_reloc = true;
252b5132 6464 break;
4d6ed7c8 6465 case 'u':
015dc7e1 6466 do_unwind = true;
4d6ed7c8 6467 break;
252b5132 6468 case 'h':
015dc7e1 6469 do_header = true;
252b5132
RH
6470 break;
6471 case 'l':
015dc7e1 6472 do_segments = true;
252b5132
RH
6473 break;
6474 case 's':
015dc7e1 6475 do_syms = true;
252b5132
RH
6476 break;
6477 case 'S':
015dc7e1 6478 do_sections = true;
252b5132
RH
6479 break;
6480 case 'd':
015dc7e1 6481 do_dynamic = true;
252b5132 6482 break;
a952a375 6483 case 'I':
015dc7e1 6484 do_histogram = true;
a952a375 6485 break;
779fe533 6486 case 'n':
015dc7e1 6487 do_notes = true;
779fe533 6488 break;
4145f1d5 6489 case 'c':
015dc7e1 6490 do_archive_index = true;
4145f1d5 6491 break;
1b513401 6492 case 'L':
015dc7e1 6493 do_checks = true;
1b513401 6494 break;
ca0e11aa 6495 case 'P':
015dc7e1
AM
6496 process_links = true;
6497 do_follow_links = true;
e1dbfc17 6498 dump_any_debugging = true;
ca0e11aa 6499 break;
8e8d0b63
NC
6500 case 'j':
6501 request_dump (dumpdata, AUTO_DUMP);
6502 break;
252b5132 6503 case 'x':
6431e409 6504 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 6505 break;
09c11c86 6506 case 'p':
6431e409 6507 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
6508 break;
6509 case 'R':
6431e409 6510 request_dump (dumpdata, RELOC_DUMP);
09c11c86 6511 break;
0e602686 6512 case 'z':
015dc7e1 6513 decompress_dumps = true;
0e602686 6514 break;
252b5132 6515 case 'w':
0f03783c 6516 if (optarg == NULL)
613ff48b 6517 {
015dc7e1 6518 do_debugging = true;
94585d6d
NC
6519 do_dump = true;
6520 dump_any_debugging = true;
613ff48b
CC
6521 dwarf_select_sections_all ();
6522 }
252b5132
RH
6523 else
6524 {
015dc7e1 6525 do_debugging = false;
94585d6d
NC
6526 if (dwarf_select_sections_by_letters (optarg))
6527 {
6528 do_dump = true;
6529 dump_any_debugging = true;
6530 }
252b5132
RH
6531 }
6532 break;
2979dc34 6533 case OPTION_DEBUG_DUMP:
0f03783c 6534 if (optarg == NULL)
d6249f5f 6535 {
94585d6d 6536 do_dump = true;
d6249f5f 6537 do_debugging = true;
94585d6d 6538 dump_any_debugging = true;
d6249f5f
AM
6539 dwarf_select_sections_all ();
6540 }
2979dc34
JJ
6541 else
6542 {
015dc7e1 6543 do_debugging = false;
94585d6d
NC
6544 if (dwarf_select_sections_by_names (optarg))
6545 {
6546 do_dump = true;
6547 dump_any_debugging = true;
6548 }
2979dc34
JJ
6549 }
6550 break;
fd2f0033
TT
6551 case OPTION_DWARF_DEPTH:
6552 {
6553 char *cp;
6554
6555 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6556 }
6557 break;
6558 case OPTION_DWARF_START:
6559 {
6560 char *cp;
6561
6562 dwarf_start_die = strtoul (optarg, & cp, 0);
6563 }
6564 break;
4723351a 6565 case OPTION_DWARF_CHECK:
015dc7e1 6566 dwarf_check = true;
4723351a 6567 break;
7d9813f1 6568 case OPTION_CTF_DUMP:
015dc7e1 6569 do_ctf = true;
6431e409 6570 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6571 break;
6572 case OPTION_CTF_SYMBOLS:
df16e041 6573 free (dump_ctf_symtab_name);
7d9813f1
NA
6574 dump_ctf_symtab_name = strdup (optarg);
6575 break;
6576 case OPTION_CTF_STRINGS:
df16e041 6577 free (dump_ctf_strtab_name);
7d9813f1
NA
6578 dump_ctf_strtab_name = strdup (optarg);
6579 break;
6580 case OPTION_CTF_PARENT:
df16e041 6581 free (dump_ctf_parent_name);
7d9813f1
NA
6582 dump_ctf_parent_name = strdup (optarg);
6583 break;
42b6953b
IB
6584 case OPTION_SFRAME_DUMP:
6585 do_sframe = true;
6586 /* Providing section name is optional. request_dump (), however,
6587 thrives on non NULL optarg. Handle it explicitly here. */
6588 if (optarg != NULL)
6589 request_dump (dumpdata, SFRAME_DUMP);
6590 else
6591 {
6592 do_dump = true;
6593 const char *sframe_sec_name = strdup (".sframe");
6594 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6595 }
6596 break;
2c610e4b 6597 case OPTION_DYN_SYMS:
015dc7e1 6598 do_dyn_syms = true;
2c610e4b 6599 break;
0f03783c 6600 case OPTION_LTO_SYMS:
015dc7e1 6601 do_lto_syms = true;
0f03783c 6602 break;
b6ac461a
NC
6603 case 'X':
6604 extra_sym_info = true;
6605 break;
6606 case OPTION_NO_EXTRA_SYM_INFO:
6607 extra_sym_info = false;
6608 break;
5d526bdf 6609
252b5132
RH
6610#ifdef SUPPORT_DISASSEMBLY
6611 case 'i':
6431e409 6612 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6613 break;
252b5132
RH
6614#endif
6615 case 'v':
6616 print_version (program_name);
6617 break;
6618 case 'V':
015dc7e1 6619 do_version = true;
252b5132 6620 break;
d974e256 6621 case 'W':
015dc7e1 6622 do_wide = true;
d974e256 6623 break;
0942c7ab 6624 case 'T':
015dc7e1 6625 do_not_show_symbol_truncation = true;
0942c7ab 6626 break;
79bc120c 6627 case 'C':
015dc7e1 6628 do_demangle = true;
79bc120c
NC
6629 if (optarg != NULL)
6630 {
6631 enum demangling_styles style;
6632
6633 style = cplus_demangle_name_to_style (optarg);
6634 if (style == unknown_demangling)
6635 error (_("unknown demangling style `%s'"), optarg);
6636
6637 cplus_demangle_set_style (style);
6638 }
6639 break;
6640 case OPTION_NO_DEMANGLING:
015dc7e1 6641 do_demangle = false;
79bc120c
NC
6642 break;
6643 case OPTION_RECURSE_LIMIT:
6644 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6645 break;
6646 case OPTION_NO_RECURSE_LIMIT:
6647 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6648 break;
6649 case OPTION_WITH_SYMBOL_VERSIONS:
6650 /* Ignored for backward compatibility. */
6651 break;
b9e920ec 6652
b3aa80b4
NC
6653 case 'U':
6654 if (optarg == NULL)
6655 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6656 else if (streq (optarg, "default") || streq (optarg, "d"))
6657 unicode_display = unicode_default;
6658 else if (streq (optarg, "locale") || streq (optarg, "l"))
6659 unicode_display = unicode_locale;
6660 else if (streq (optarg, "escape") || streq (optarg, "e"))
6661 unicode_display = unicode_escape;
6662 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6663 unicode_display = unicode_invalid;
6664 else if (streq (optarg, "hex") || streq (optarg, "x"))
6665 unicode_display = unicode_hex;
6666 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6667 unicode_display = unicode_highlight;
6668 else
6669 error (_("invalid argument to -U/--unicode: %s"), optarg);
6670 break;
6671
047c3dbf
NL
6672 case OPTION_SYM_BASE:
6673 sym_base = 0;
6674 if (optarg != NULL)
6675 {
6676 sym_base = strtoul (optarg, NULL, 0);
6677 switch (sym_base)
6678 {
6679 case 0:
6680 case 8:
6681 case 10:
6682 case 16:
6683 break;
6684
6685 default:
6686 sym_base = 0;
6687 break;
6688 }
6689 }
6690 break;
6691
252b5132 6692 default:
252b5132
RH
6693 /* xgettext:c-format */
6694 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6695 /* Fall through. */
252b5132 6696 case '?':
92f01d61 6697 usage (stderr);
252b5132
RH
6698 }
6699 }
6700
4d6ed7c8 6701 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6702 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6703 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6704 && !do_section_groups && !do_archive_index
0f03783c 6705 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6706 {
6707 if (do_checks)
6708 {
015dc7e1
AM
6709 check_all = true;
6710 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6711 do_segments = do_header = do_dump = do_version = true;
6712 do_histogram = do_debugging = do_arch = do_notes = true;
6713 do_section_groups = do_archive_index = do_dyn_syms = true;
6714 do_lto_syms = true;
1b513401
NC
6715 }
6716 else
6717 usage (stderr);
6718 }
252b5132
RH
6719}
6720
6721static const char *
d3ba0551 6722get_elf_class (unsigned int elf_class)
252b5132 6723{
b34976b6 6724 static char buff[32];
103f02d3 6725
252b5132
RH
6726 switch (elf_class)
6727 {
6728 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6729 case ELFCLASS32: return "ELF32";
6730 case ELFCLASS64: return "ELF64";
ab5e7794 6731 default:
e9e44622 6732 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6733 return buff;
252b5132
RH
6734 }
6735}
6736
6737static const char *
d3ba0551 6738get_data_encoding (unsigned int encoding)
252b5132 6739{
b34976b6 6740 static char buff[32];
103f02d3 6741
252b5132
RH
6742 switch (encoding)
6743 {
6744 case ELFDATANONE: return _("none");
33c63f9d
CM
6745 case ELFDATA2LSB: return _("2's complement, little endian");
6746 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6747 default:
e9e44622 6748 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6749 return buff;
252b5132
RH
6750 }
6751}
6752
521f7268
NC
6753static bool
6754check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6755{
6756 if (header->e_ident[EI_MAG0] == ELFMAG0
6757 && header->e_ident[EI_MAG1] == ELFMAG1
6758 && header->e_ident[EI_MAG2] == ELFMAG2
6759 && header->e_ident[EI_MAG3] == ELFMAG3)
6760 return true;
6761
6762 /* Some compilers produce object files that are not in the ELF file format.
6763 As an aid to users of readelf, try to identify these cases and suggest
6764 alternative tools.
6765
6766 FIXME: It is not clear if all four bytes are used as constant magic
6767 valus by all compilers. It may be necessary to recode this function if
6768 different tools use different length sequences. */
5d526bdf 6769
521f7268
NC
6770 static struct
6771 {
6772 unsigned char magic[4];
6773 const char * obj_message;
6774 const char * ar_message;
6775 }
6776 known_magic[] =
6777 {
5d526bdf 6778 { { 'B', 'C', 0xc0, 0xde },
521f7268 6779 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6780 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6781 },
6782 { { 'g', 'o', ' ', 'o' },
6783 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6784 NULL
6785 }
6786 };
6787 int i;
6788
6789 for (i = ARRAY_SIZE (known_magic); i--;)
6790 {
6791 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6792 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6793 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6794 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6795 {
6796 /* Some compiler's analyzer tools do not handle archives,
6797 so we provide two different kinds of error message. */
6798 if (filedata->archive_file_size > 0
6799 && known_magic[i].ar_message != NULL)
b3ea2010 6800 error ("%s", known_magic[i].ar_message);
521f7268 6801 else
b3ea2010 6802 error ("%s", known_magic[i].obj_message);
521f7268
NC
6803 return false;
6804 }
6805 }
6806
6807 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6808 return false;
6809}
6810
dda8d76d 6811/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6812
015dc7e1 6813static bool
dda8d76d 6814process_file_header (Filedata * filedata)
252b5132 6815{
dda8d76d
NC
6816 Elf_Internal_Ehdr * header = & filedata->file_header;
6817
521f7268
NC
6818 if (! check_magic_number (filedata, header))
6819 return false;
252b5132 6820
ca0e11aa
NC
6821 if (! filedata->is_separate)
6822 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6823
252b5132
RH
6824 if (do_header)
6825 {
32ec8896 6826 unsigned i;
252b5132 6827
ca0e11aa 6828 if (filedata->is_separate)
978dae65
NC
6829 printf (_("ELF Header in linked file '%s':\n"),
6830 printable_string (filedata->file_name, 0));
ca0e11aa
NC
6831 else
6832 printf (_("ELF Header:\n"));
252b5132 6833 printf (_(" Magic: "));
b34976b6 6834 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6835 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6836 printf ("\n");
6837 printf (_(" Class: %s\n"),
dda8d76d 6838 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6839 printf (_(" Data: %s\n"),
dda8d76d 6840 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6841 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6842 header->e_ident[EI_VERSION],
6843 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6844 ? _(" (current)")
dda8d76d 6845 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6846 ? _(" <unknown>")
789be9f7 6847 : "")));
252b5132 6848 printf (_(" OS/ABI: %s\n"),
dda8d76d 6849 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6850 printf (_(" ABI Version: %d\n"),
dda8d76d 6851 header->e_ident[EI_ABIVERSION]);
252b5132 6852 printf (_(" Type: %s\n"),
93df3340 6853 get_file_type (filedata));
252b5132 6854 printf (_(" Machine: %s\n"),
dda8d76d 6855 get_machine_name (header->e_machine));
252b5132 6856 printf (_(" Version: 0x%lx\n"),
e8a64888 6857 header->e_version);
76da6bbe 6858
f7a99963 6859 printf (_(" Entry point address: "));
e8a64888 6860 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6861 printf (_("\n Start of program headers: "));
e8a64888 6862 print_vma (header->e_phoff, DEC);
f7a99963 6863 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6864 print_vma (header->e_shoff, DEC);
f7a99963 6865 printf (_(" (bytes into file)\n"));
76da6bbe 6866
252b5132 6867 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6868 header->e_flags,
dda8d76d 6869 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6870 printf (_(" Size of this header: %u (bytes)\n"),
6871 header->e_ehsize);
6872 printf (_(" Size of program headers: %u (bytes)\n"),
6873 header->e_phentsize);
6874 printf (_(" Number of program headers: %u"),
6875 header->e_phnum);
dda8d76d
NC
6876 if (filedata->section_headers != NULL
6877 && header->e_phnum == PN_XNUM
6878 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6879 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6880 putc ('\n', stdout);
e8a64888
AM
6881 printf (_(" Size of section headers: %u (bytes)\n"),
6882 header->e_shentsize);
6883 printf (_(" Number of section headers: %u"),
6884 header->e_shnum);
dda8d76d 6885 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6886 {
6887 header->e_shnum = filedata->section_headers[0].sh_size;
6888 printf (" (%u)", header->e_shnum);
6889 }
560f3c1c 6890 putc ('\n', stdout);
e8a64888
AM
6891 printf (_(" Section header string table index: %u"),
6892 header->e_shstrndx);
dda8d76d
NC
6893 if (filedata->section_headers != NULL
6894 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6895 {
6896 header->e_shstrndx = filedata->section_headers[0].sh_link;
6897 printf (" (%u)", header->e_shstrndx);
6898 }
6899 if (header->e_shstrndx != SHN_UNDEF
6900 && header->e_shstrndx >= header->e_shnum)
6901 {
6902 header->e_shstrndx = SHN_UNDEF;
6903 printf (_(" <corrupt: out of range>"));
6904 }
560f3c1c
AM
6905 putc ('\n', stdout);
6906 }
6907
dda8d76d 6908 if (filedata->section_headers != NULL)
560f3c1c 6909 {
dda8d76d
NC
6910 if (header->e_phnum == PN_XNUM
6911 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6912 {
6913 /* Throw away any cached read of PN_XNUM headers. */
6914 free (filedata->program_headers);
6915 filedata->program_headers = NULL;
6916 header->e_phnum = filedata->section_headers[0].sh_info;
6917 }
dda8d76d
NC
6918 if (header->e_shnum == SHN_UNDEF)
6919 header->e_shnum = filedata->section_headers[0].sh_size;
6920 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6921 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6922 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6923 header->e_shstrndx = SHN_UNDEF;
252b5132 6924 }
103f02d3 6925
015dc7e1 6926 return true;
9ea033b2
NC
6927}
6928
dda8d76d
NC
6929/* Read in the program headers from FILEDATA and store them in PHEADERS.
6930 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6931
015dc7e1 6932static bool
dda8d76d 6933get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6934{
2cf0635d
NC
6935 Elf32_External_Phdr * phdrs;
6936 Elf32_External_Phdr * external;
6937 Elf_Internal_Phdr * internal;
b34976b6 6938 unsigned int i;
dda8d76d
NC
6939 unsigned int size = filedata->file_header.e_phentsize;
6940 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6941
6942 /* PR binutils/17531: Cope with unexpected section header sizes. */
6943 if (size == 0 || num == 0)
015dc7e1 6944 return false;
e0a31db1
NC
6945 if (size < sizeof * phdrs)
6946 {
6947 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6948 return false;
e0a31db1
NC
6949 }
6950 if (size > sizeof * phdrs)
6951 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6952
dda8d76d 6953 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6954 size, num, _("program headers"));
6955 if (phdrs == NULL)
015dc7e1 6956 return false;
9ea033b2 6957
91d6fa6a 6958 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6959 i < filedata->file_header.e_phnum;
b34976b6 6960 i++, internal++, external++)
252b5132 6961 {
9ea033b2
NC
6962 internal->p_type = BYTE_GET (external->p_type);
6963 internal->p_offset = BYTE_GET (external->p_offset);
6964 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6965 internal->p_paddr = BYTE_GET (external->p_paddr);
6966 internal->p_filesz = BYTE_GET (external->p_filesz);
6967 internal->p_memsz = BYTE_GET (external->p_memsz);
6968 internal->p_flags = BYTE_GET (external->p_flags);
6969 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6970 }
6971
9ea033b2 6972 free (phdrs);
015dc7e1 6973 return true;
252b5132
RH
6974}
6975
dda8d76d
NC
6976/* Read in the program headers from FILEDATA and store them in PHEADERS.
6977 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6978
015dc7e1 6979static bool
dda8d76d 6980get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6981{
2cf0635d
NC
6982 Elf64_External_Phdr * phdrs;
6983 Elf64_External_Phdr * external;
6984 Elf_Internal_Phdr * internal;
b34976b6 6985 unsigned int i;
dda8d76d
NC
6986 unsigned int size = filedata->file_header.e_phentsize;
6987 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6988
6989 /* PR binutils/17531: Cope with unexpected section header sizes. */
6990 if (size == 0 || num == 0)
015dc7e1 6991 return false;
e0a31db1
NC
6992 if (size < sizeof * phdrs)
6993 {
6994 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6995 return false;
e0a31db1
NC
6996 }
6997 if (size > sizeof * phdrs)
6998 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6999
dda8d76d 7000 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 7001 size, num, _("program headers"));
a6e9f9df 7002 if (!phdrs)
015dc7e1 7003 return false;
9ea033b2 7004
91d6fa6a 7005 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 7006 i < filedata->file_header.e_phnum;
b34976b6 7007 i++, internal++, external++)
9ea033b2
NC
7008 {
7009 internal->p_type = BYTE_GET (external->p_type);
7010 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
7011 internal->p_offset = BYTE_GET (external->p_offset);
7012 internal->p_vaddr = BYTE_GET (external->p_vaddr);
7013 internal->p_paddr = BYTE_GET (external->p_paddr);
7014 internal->p_filesz = BYTE_GET (external->p_filesz);
7015 internal->p_memsz = BYTE_GET (external->p_memsz);
7016 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
7017 }
7018
7019 free (phdrs);
015dc7e1 7020 return true;
9ea033b2 7021}
252b5132 7022
32ec8896 7023/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 7024
015dc7e1 7025static bool
dda8d76d 7026get_program_headers (Filedata * filedata)
d93f0186 7027{
2cf0635d 7028 Elf_Internal_Phdr * phdrs;
d93f0186
NC
7029
7030 /* Check cache of prior read. */
dda8d76d 7031 if (filedata->program_headers != NULL)
015dc7e1 7032 return true;
d93f0186 7033
82156ab7
NC
7034 /* Be kind to memory checkers by looking for
7035 e_phnum values which we know must be invalid. */
dda8d76d 7036 if (filedata->file_header.e_phnum
82156ab7 7037 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 7038 >= filedata->file_size)
82156ab7
NC
7039 {
7040 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 7041 filedata->file_header.e_phnum);
015dc7e1 7042 return false;
82156ab7 7043 }
d93f0186 7044
dda8d76d 7045 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 7046 sizeof (Elf_Internal_Phdr));
d93f0186
NC
7047 if (phdrs == NULL)
7048 {
8b73c356 7049 error (_("Out of memory reading %u program headers\n"),
dda8d76d 7050 filedata->file_header.e_phnum);
015dc7e1 7051 return false;
d93f0186
NC
7052 }
7053
7054 if (is_32bit_elf
dda8d76d
NC
7055 ? get_32bit_program_headers (filedata, phdrs)
7056 : get_64bit_program_headers (filedata, phdrs))
d93f0186 7057 {
dda8d76d 7058 filedata->program_headers = phdrs;
015dc7e1 7059 return true;
d93f0186
NC
7060 }
7061
7062 free (phdrs);
015dc7e1 7063 return false;
d93f0186
NC
7064}
7065
93df3340 7066/* Print program header info and locate dynamic section. */
2f62977e 7067
93df3340 7068static void
dda8d76d 7069process_program_headers (Filedata * filedata)
252b5132 7070{
2cf0635d 7071 Elf_Internal_Phdr * segment;
b34976b6 7072 unsigned int i;
1a9ccd70 7073 Elf_Internal_Phdr * previous_load = NULL;
252b5132 7074
dda8d76d 7075 if (filedata->file_header.e_phnum == 0)
252b5132 7076 {
82f2dbf7 7077 /* PR binutils/12467. */
dda8d76d 7078 if (filedata->file_header.e_phoff != 0)
93df3340
AM
7079 warn (_("possibly corrupt ELF header - it has a non-zero program"
7080 " header offset, but no program headers\n"));
82f2dbf7 7081 else if (do_segments)
ca0e11aa
NC
7082 {
7083 if (filedata->is_separate)
7084 printf (_("\nThere are no program headers in linked file '%s'.\n"),
978dae65 7085 printable_string (filedata->file_name, 0));
ca0e11aa
NC
7086 else
7087 printf (_("\nThere are no program headers in this file.\n"));
7088 }
93df3340 7089 goto no_headers;
252b5132
RH
7090 }
7091
7092 if (do_segments && !do_header)
7093 {
ca0e11aa
NC
7094 if (filedata->is_separate)
7095 printf ("\nIn linked file '%s' the ELF file type is %s\n",
978dae65
NC
7096 printable_string (filedata->file_name, 0),
7097 get_file_type (filedata));
ca0e11aa 7098 else
93df3340 7099 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 7100 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 7101 filedata->file_header.e_entry);
b8281767
AM
7102 printf (ngettext ("There is %d program header,"
7103 " starting at offset %" PRIu64 "\n",
7104 "There are %d program headers,"
7105 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
7106 filedata->file_header.e_phnum),
7107 filedata->file_header.e_phnum,
625d49fc 7108 filedata->file_header.e_phoff);
252b5132
RH
7109 }
7110
dda8d76d 7111 if (! get_program_headers (filedata))
93df3340 7112 goto no_headers;
103f02d3 7113
252b5132
RH
7114 if (do_segments)
7115 {
dda8d76d 7116 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
7117 printf (_("\nProgram Headers:\n"));
7118 else
7119 printf (_("\nProgram Headers:\n"));
76da6bbe 7120
f7a99963
NC
7121 if (is_32bit_elf)
7122 printf
7123 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
7124 else if (do_wide)
7125 printf
7126 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
7127 else
7128 {
7129 printf
7130 (_(" Type Offset VirtAddr PhysAddr\n"));
7131 printf
7132 (_(" FileSiz MemSiz Flags Align\n"));
7133 }
252b5132
RH
7134 }
7135
26c527e6 7136 uint64_t dynamic_addr = 0;
be7d229a 7137 uint64_t dynamic_size = 0;
dda8d76d
NC
7138 for (i = 0, segment = filedata->program_headers;
7139 i < filedata->file_header.e_phnum;
b34976b6 7140 i++, segment++)
252b5132
RH
7141 {
7142 if (do_segments)
7143 {
dda8d76d 7144 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
7145
7146 if (is_32bit_elf)
7147 {
7148 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7149 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
7150 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
7151 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
7152 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
7153 printf ("%c%c%c ",
7154 (segment->p_flags & PF_R ? 'R' : ' '),
7155 (segment->p_flags & PF_W ? 'W' : ' '),
7156 (segment->p_flags & PF_X ? 'E' : ' '));
7157 printf ("%#lx", (unsigned long) segment->p_align);
7158 }
d974e256
JJ
7159 else if (do_wide)
7160 {
7161 if ((unsigned long) segment->p_offset == segment->p_offset)
7162 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7163 else
7164 {
7165 print_vma (segment->p_offset, FULL_HEX);
7166 putchar (' ');
7167 }
7168
7169 print_vma (segment->p_vaddr, FULL_HEX);
7170 putchar (' ');
7171 print_vma (segment->p_paddr, FULL_HEX);
7172 putchar (' ');
7173
7174 if ((unsigned long) segment->p_filesz == segment->p_filesz)
7175 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
7176 else
7177 {
7178 print_vma (segment->p_filesz, FULL_HEX);
7179 putchar (' ');
7180 }
7181
7182 if ((unsigned long) segment->p_memsz == segment->p_memsz)
7183 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
7184 else
7185 {
f48e6c45 7186 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
7187 }
7188
7189 printf (" %c%c%c ",
7190 (segment->p_flags & PF_R ? 'R' : ' '),
7191 (segment->p_flags & PF_W ? 'W' : ' '),
7192 (segment->p_flags & PF_X ? 'E' : ' '));
7193
7194 if ((unsigned long) segment->p_align == segment->p_align)
7195 printf ("%#lx", (unsigned long) segment->p_align);
7196 else
7197 {
7198 print_vma (segment->p_align, PREFIX_HEX);
7199 }
7200 }
f7a99963
NC
7201 else
7202 {
7203 print_vma (segment->p_offset, FULL_HEX);
7204 putchar (' ');
7205 print_vma (segment->p_vaddr, FULL_HEX);
7206 putchar (' ');
7207 print_vma (segment->p_paddr, FULL_HEX);
7208 printf ("\n ");
7209 print_vma (segment->p_filesz, FULL_HEX);
7210 putchar (' ');
7211 print_vma (segment->p_memsz, FULL_HEX);
7212 printf (" %c%c%c ",
7213 (segment->p_flags & PF_R ? 'R' : ' '),
7214 (segment->p_flags & PF_W ? 'W' : ' '),
7215 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 7216 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 7217 }
252b5132 7218
1a9ccd70
NC
7219 putc ('\n', stdout);
7220 }
f54498b4 7221
252b5132
RH
7222 switch (segment->p_type)
7223 {
1a9ccd70 7224 case PT_LOAD:
502d895c
NC
7225#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
7226 required by the ELF standard, several programs, including the Linux
7227 kernel, make use of non-ordered segments. */
1a9ccd70
NC
7228 if (previous_load
7229 && previous_load->p_vaddr > segment->p_vaddr)
7230 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 7231#endif
1a9ccd70
NC
7232 if (segment->p_memsz < segment->p_filesz)
7233 error (_("the segment's file size is larger than its memory size\n"));
7234 previous_load = segment;
7235 break;
7236
7237 case PT_PHDR:
7238 /* PR 20815 - Verify that the program header is loaded into memory. */
7239 if (i > 0 && previous_load != NULL)
7240 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 7241 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
7242 {
7243 unsigned int j;
7244
dda8d76d 7245 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
7246 {
7247 Elf_Internal_Phdr *load = filedata->program_headers + j;
7248 if (load->p_type == PT_LOAD
7249 && load->p_offset <= segment->p_offset
7250 && (load->p_offset + load->p_filesz
7251 >= segment->p_offset + segment->p_filesz)
7252 && load->p_vaddr <= segment->p_vaddr
7253 && (load->p_vaddr + load->p_filesz
7254 >= segment->p_vaddr + segment->p_filesz))
7255 break;
7256 }
dda8d76d 7257 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
7258 error (_("the PHDR segment is not covered by a LOAD segment\n"));
7259 }
7260 break;
7261
252b5132 7262 case PT_DYNAMIC:
93df3340 7263 if (dynamic_addr)
252b5132
RH
7264 error (_("more than one dynamic segment\n"));
7265
20737c13
AM
7266 /* By default, assume that the .dynamic section is the first
7267 section in the DYNAMIC segment. */
93df3340
AM
7268 dynamic_addr = segment->p_offset;
7269 dynamic_size = segment->p_filesz;
20737c13 7270
b2d38a17
NC
7271 /* Try to locate the .dynamic section. If there is
7272 a section header table, we can easily locate it. */
dda8d76d 7273 if (filedata->section_headers != NULL)
b2d38a17 7274 {
2cf0635d 7275 Elf_Internal_Shdr * sec;
b2d38a17 7276
dda8d76d 7277 sec = find_section (filedata, ".dynamic");
89fac5e3 7278 if (sec == NULL || sec->sh_size == 0)
b2d38a17 7279 {
93df3340
AM
7280 /* A corresponding .dynamic section is expected, but on
7281 IA-64/OpenVMS it is OK for it to be missing. */
7282 if (!is_ia64_vms (filedata))
7283 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
7284 break;
7285 }
7286
42bb2e33 7287 if (sec->sh_type == SHT_NOBITS)
20737c13 7288 {
93df3340
AM
7289 dynamic_addr = 0;
7290 dynamic_size = 0;
20737c13
AM
7291 break;
7292 }
42bb2e33 7293
93df3340
AM
7294 dynamic_addr = sec->sh_offset;
7295 dynamic_size = sec->sh_size;
b2d38a17 7296
8ac10c5b
L
7297 /* The PT_DYNAMIC segment, which is used by the run-time
7298 loader, should exactly match the .dynamic section. */
7299 if (do_checks
93df3340
AM
7300 && (dynamic_addr != segment->p_offset
7301 || dynamic_size != segment->p_filesz))
8ac10c5b
L
7302 warn (_("\
7303the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 7304 }
39e224f6
MW
7305
7306 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7307 segment. Check this after matching against the section headers
7308 so we don't warn on debuginfo file (which have NOBITS .dynamic
7309 sections). */
93df3340
AM
7310 if (dynamic_addr > filedata->file_size
7311 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
7312 {
7313 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
7314 dynamic_addr = 0;
7315 dynamic_size = 0;
39e224f6 7316 }
252b5132
RH
7317 break;
7318
7319 case PT_INTERP:
13acb58d
AM
7320 if (segment->p_offset >= filedata->file_size
7321 || segment->p_filesz > filedata->file_size - segment->p_offset
7322 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
7323 || fseek64 (filedata->handle,
7324 filedata->archive_file_offset + segment->p_offset,
7325 SEEK_SET))
252b5132
RH
7326 error (_("Unable to find program interpreter name\n"));
7327 else
7328 {
13acb58d
AM
7329 size_t len = segment->p_filesz;
7330 free (filedata->program_interpreter);
7331 filedata->program_interpreter = xmalloc (len + 1);
7332 len = fread (filedata->program_interpreter, 1, len,
7333 filedata->handle);
7334 filedata->program_interpreter[len] = 0;
252b5132
RH
7335
7336 if (do_segments)
f54498b4 7337 printf (_(" [Requesting program interpreter: %s]\n"),
978dae65 7338 printable_string (filedata->program_interpreter, 0));
252b5132
RH
7339 }
7340 break;
7341 }
252b5132
RH
7342 }
7343
dda8d76d
NC
7344 if (do_segments
7345 && filedata->section_headers != NULL
7346 && filedata->string_table != NULL)
252b5132
RH
7347 {
7348 printf (_("\n Section to Segment mapping:\n"));
7349 printf (_(" Segment Sections...\n"));
7350
dda8d76d 7351 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 7352 {
9ad5cbcf 7353 unsigned int j;
2cf0635d 7354 Elf_Internal_Shdr * section;
252b5132 7355
dda8d76d
NC
7356 segment = filedata->program_headers + i;
7357 section = filedata->section_headers + 1;
252b5132
RH
7358
7359 printf (" %2.2d ", i);
7360
dda8d76d 7361 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 7362 {
f4638467
AM
7363 if (!ELF_TBSS_SPECIAL (section, segment)
7364 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 7365 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
7366 }
7367
7368 putc ('\n',stdout);
7369 }
7370 }
7371
93df3340
AM
7372 filedata->dynamic_addr = dynamic_addr;
7373 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7374 return;
7375
7376 no_headers:
7377 filedata->dynamic_addr = 0;
7378 filedata->dynamic_size = 1;
252b5132
RH
7379}
7380
7381
d93f0186
NC
7382/* Find the file offset corresponding to VMA by using the program headers. */
7383
26c527e6 7384static int64_t
625d49fc 7385offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 7386{
2cf0635d 7387 Elf_Internal_Phdr * seg;
d93f0186 7388
dda8d76d 7389 if (! get_program_headers (filedata))
d93f0186
NC
7390 {
7391 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7392 return (long) vma;
7393 }
7394
dda8d76d
NC
7395 for (seg = filedata->program_headers;
7396 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
7397 ++seg)
7398 {
7399 if (seg->p_type != PT_LOAD)
7400 continue;
7401
7402 if (vma >= (seg->p_vaddr & -seg->p_align)
7403 && vma + size <= seg->p_vaddr + seg->p_filesz)
7404 return vma - seg->p_vaddr + seg->p_offset;
7405 }
7406
26c527e6
AM
7407 warn (_("Virtual address %#" PRIx64
7408 " not located in any PT_LOAD segment.\n"), vma);
7409 return vma;
d93f0186
NC
7410}
7411
7412
dda8d76d
NC
7413/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7414 If PROBE is true, this is just a probe and we do not generate any error
7415 messages if the load fails. */
049b0c3a 7416
015dc7e1
AM
7417static bool
7418get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 7419{
2cf0635d
NC
7420 Elf32_External_Shdr * shdrs;
7421 Elf_Internal_Shdr * internal;
dda8d76d
NC
7422 unsigned int i;
7423 unsigned int size = filedata->file_header.e_shentsize;
7424 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7425
7426 /* PR binutils/17531: Cope with unexpected section header sizes. */
7427 if (size == 0 || num == 0)
015dc7e1 7428 return false;
907b52f4
NC
7429
7430 /* The section header cannot be at the start of the file - that is
7431 where the ELF file header is located. A file with absolutely no
7432 sections in it will use a shoff of 0. */
7433 if (filedata->file_header.e_shoff == 0)
7434 return false;
7435
049b0c3a
NC
7436 if (size < sizeof * shdrs)
7437 {
7438 if (! probe)
7439 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7440 return false;
049b0c3a
NC
7441 }
7442 if (!probe && size > sizeof * shdrs)
7443 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 7444
dda8d76d 7445 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
7446 size, num,
7447 probe ? NULL : _("section headers"));
7448 if (shdrs == NULL)
015dc7e1 7449 return false;
252b5132 7450
dda8d76d
NC
7451 filedata->section_headers = (Elf_Internal_Shdr *)
7452 cmalloc (num, sizeof (Elf_Internal_Shdr));
7453 if (filedata->section_headers == NULL)
252b5132 7454 {
049b0c3a 7455 if (!probe)
8b73c356 7456 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7457 free (shdrs);
015dc7e1 7458 return false;
252b5132
RH
7459 }
7460
dda8d76d 7461 for (i = 0, internal = filedata->section_headers;
560f3c1c 7462 i < num;
b34976b6 7463 i++, internal++)
252b5132
RH
7464 {
7465 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7466 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7467 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7468 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7469 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7470 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7471 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7472 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7473 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7474 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
7475 if (!probe && internal->sh_link > num)
7476 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7477 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7478 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
7479 }
7480
7481 free (shdrs);
015dc7e1 7482 return true;
252b5132
RH
7483}
7484
dda8d76d
NC
7485/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7486
015dc7e1
AM
7487static bool
7488get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 7489{
dda8d76d
NC
7490 Elf64_External_Shdr * shdrs;
7491 Elf_Internal_Shdr * internal;
7492 unsigned int i;
7493 unsigned int size = filedata->file_header.e_shentsize;
7494 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7495
7496 /* PR binutils/17531: Cope with unexpected section header sizes. */
7497 if (size == 0 || num == 0)
015dc7e1 7498 return false;
dda8d76d 7499
907b52f4
NC
7500 /* The section header cannot be at the start of the file - that is
7501 where the ELF file header is located. A file with absolutely no
7502 sections in it will use a shoff of 0. */
7503 if (filedata->file_header.e_shoff == 0)
7504 return false;
7505
049b0c3a
NC
7506 if (size < sizeof * shdrs)
7507 {
7508 if (! probe)
7509 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7510 return false;
049b0c3a 7511 }
dda8d76d 7512
049b0c3a
NC
7513 if (! probe && size > sizeof * shdrs)
7514 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 7515
dda8d76d
NC
7516 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7517 filedata->file_header.e_shoff,
049b0c3a
NC
7518 size, num,
7519 probe ? NULL : _("section headers"));
7520 if (shdrs == NULL)
015dc7e1 7521 return false;
9ea033b2 7522
dda8d76d
NC
7523 filedata->section_headers = (Elf_Internal_Shdr *)
7524 cmalloc (num, sizeof (Elf_Internal_Shdr));
7525 if (filedata->section_headers == NULL)
9ea033b2 7526 {
049b0c3a 7527 if (! probe)
8b73c356 7528 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7529 free (shdrs);
015dc7e1 7530 return false;
9ea033b2
NC
7531 }
7532
dda8d76d 7533 for (i = 0, internal = filedata->section_headers;
560f3c1c 7534 i < num;
b34976b6 7535 i++, internal++)
9ea033b2
NC
7536 {
7537 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7538 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7539 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7540 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7541 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7542 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7543 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7544 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7545 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7546 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7547 if (!probe && internal->sh_link > num)
7548 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7549 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7550 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7551 }
7552
7553 free (shdrs);
015dc7e1 7554 return true;
9ea033b2
NC
7555}
7556
4de91c10
AM
7557static bool
7558get_section_headers (Filedata *filedata, bool probe)
7559{
7560 if (filedata->section_headers != NULL)
7561 return true;
7562
4de91c10
AM
7563 if (is_32bit_elf)
7564 return get_32bit_section_headers (filedata, probe);
7565 else
7566 return get_64bit_section_headers (filedata, probe);
7567}
7568
252b5132 7569static Elf_Internal_Sym *
26c527e6
AM
7570get_32bit_elf_symbols (Filedata *filedata,
7571 Elf_Internal_Shdr *section,
7572 uint64_t *num_syms_return)
252b5132 7573{
26c527e6 7574 uint64_t number = 0;
dd24e3da 7575 Elf32_External_Sym * esyms = NULL;
ba5cdace 7576 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7577 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7578 Elf_Internal_Sym * psym;
b34976b6 7579 unsigned int j;
e3d39609 7580 elf_section_list * entry;
252b5132 7581
c9c1d674
EG
7582 if (section->sh_size == 0)
7583 {
7584 if (num_syms_return != NULL)
7585 * num_syms_return = 0;
7586 return NULL;
7587 }
7588
dd24e3da 7589 /* Run some sanity checks first. */
c9c1d674 7590 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7591 {
26c527e6 7592 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7593 printable_section_name (filedata, section),
26c527e6 7594 section->sh_entsize);
ba5cdace 7595 goto exit_point;
dd24e3da
NC
7596 }
7597
dda8d76d 7598 if (section->sh_size > filedata->file_size)
f54498b4 7599 {
26c527e6 7600 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7601 printable_section_name (filedata, section),
26c527e6 7602 section->sh_size);
f54498b4
NC
7603 goto exit_point;
7604 }
7605
dd24e3da
NC
7606 number = section->sh_size / section->sh_entsize;
7607
7608 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7609 {
26c527e6
AM
7610 error (_("Size (%#" PRIx64 ") of section %s "
7611 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7612 section->sh_size,
dda8d76d 7613 printable_section_name (filedata, section),
26c527e6 7614 section->sh_entsize);
ba5cdace 7615 goto exit_point;
dd24e3da
NC
7616 }
7617
dda8d76d 7618 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7619 section->sh_size, _("symbols"));
dd24e3da 7620 if (esyms == NULL)
ba5cdace 7621 goto exit_point;
252b5132 7622
e3d39609 7623 shndx = NULL;
978c4450 7624 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7625 {
26c527e6 7626 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7627 continue;
7628
7629 if (shndx != NULL)
7630 {
7631 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7632 free (shndx);
7633 }
7634
7635 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7636 entry->hdr->sh_offset,
7637 1, entry->hdr->sh_size,
7638 _("symbol table section indices"));
7639 if (shndx == NULL)
7640 goto exit_point;
7641
7642 /* PR17531: file: heap-buffer-overflow */
7643 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7644 {
26c527e6 7645 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7646 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7647 entry->hdr->sh_size,
7648 section->sh_size);
e3d39609 7649 goto exit_point;
c9c1d674 7650 }
e3d39609 7651 }
9ad5cbcf 7652
3f5e193b 7653 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7654
7655 if (isyms == NULL)
7656 {
26c527e6 7657 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7658 goto exit_point;
252b5132
RH
7659 }
7660
dd24e3da 7661 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7662 {
7663 psym->st_name = BYTE_GET (esyms[j].st_name);
7664 psym->st_value = BYTE_GET (esyms[j].st_value);
7665 psym->st_size = BYTE_GET (esyms[j].st_size);
7666 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7667 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7668 psym->st_shndx
7669 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7670 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7671 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7672 psym->st_info = BYTE_GET (esyms[j].st_info);
7673 psym->st_other = BYTE_GET (esyms[j].st_other);
7674 }
7675
dd24e3da 7676 exit_point:
e3d39609
NC
7677 free (shndx);
7678 free (esyms);
252b5132 7679
ba5cdace
NC
7680 if (num_syms_return != NULL)
7681 * num_syms_return = isyms == NULL ? 0 : number;
7682
252b5132
RH
7683 return isyms;
7684}
7685
9ea033b2 7686static Elf_Internal_Sym *
26c527e6
AM
7687get_64bit_elf_symbols (Filedata *filedata,
7688 Elf_Internal_Shdr *section,
7689 uint64_t *num_syms_return)
9ea033b2 7690{
26c527e6 7691 uint64_t number = 0;
ba5cdace
NC
7692 Elf64_External_Sym * esyms = NULL;
7693 Elf_External_Sym_Shndx * shndx = NULL;
7694 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7695 Elf_Internal_Sym * psym;
b34976b6 7696 unsigned int j;
e3d39609 7697 elf_section_list * entry;
9ea033b2 7698
c9c1d674
EG
7699 if (section->sh_size == 0)
7700 {
7701 if (num_syms_return != NULL)
7702 * num_syms_return = 0;
7703 return NULL;
7704 }
7705
dd24e3da 7706 /* Run some sanity checks first. */
c9c1d674 7707 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7708 {
26c527e6 7709 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7710 printable_section_name (filedata, section),
26c527e6 7711 section->sh_entsize);
ba5cdace 7712 goto exit_point;
dd24e3da
NC
7713 }
7714
dda8d76d 7715 if (section->sh_size > filedata->file_size)
f54498b4 7716 {
26c527e6 7717 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7718 printable_section_name (filedata, section),
26c527e6 7719 section->sh_size);
f54498b4
NC
7720 goto exit_point;
7721 }
7722
dd24e3da
NC
7723 number = section->sh_size / section->sh_entsize;
7724
7725 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7726 {
26c527e6
AM
7727 error (_("Size (%#" PRIx64 ") of section %s "
7728 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7729 section->sh_size,
dda8d76d 7730 printable_section_name (filedata, section),
26c527e6 7731 section->sh_entsize);
ba5cdace 7732 goto exit_point;
dd24e3da
NC
7733 }
7734
dda8d76d 7735 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7736 section->sh_size, _("symbols"));
a6e9f9df 7737 if (!esyms)
ba5cdace 7738 goto exit_point;
9ea033b2 7739
e3d39609 7740 shndx = NULL;
978c4450 7741 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7742 {
26c527e6 7743 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7744 continue;
7745
7746 if (shndx != NULL)
7747 {
7748 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7749 free (shndx);
c9c1d674 7750 }
e3d39609
NC
7751
7752 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7753 entry->hdr->sh_offset,
7754 1, entry->hdr->sh_size,
7755 _("symbol table section indices"));
7756 if (shndx == NULL)
7757 goto exit_point;
7758
7759 /* PR17531: file: heap-buffer-overflow */
7760 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7761 {
26c527e6 7762 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7763 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7764 entry->hdr->sh_size,
7765 section->sh_size);
e3d39609
NC
7766 goto exit_point;
7767 }
7768 }
9ad5cbcf 7769
3f5e193b 7770 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7771
7772 if (isyms == NULL)
7773 {
26c527e6 7774 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7775 goto exit_point;
9ea033b2
NC
7776 }
7777
ba5cdace 7778 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7779 {
7780 psym->st_name = BYTE_GET (esyms[j].st_name);
7781 psym->st_info = BYTE_GET (esyms[j].st_info);
7782 psym->st_other = BYTE_GET (esyms[j].st_other);
7783 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7784
4fbb74a6 7785 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7786 psym->st_shndx
7787 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7788 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7789 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7790
66543521
AM
7791 psym->st_value = BYTE_GET (esyms[j].st_value);
7792 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7793 }
7794
ba5cdace 7795 exit_point:
e3d39609
NC
7796 free (shndx);
7797 free (esyms);
ba5cdace
NC
7798
7799 if (num_syms_return != NULL)
7800 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7801
7802 return isyms;
7803}
7804
4de91c10
AM
7805static Elf_Internal_Sym *
7806get_elf_symbols (Filedata *filedata,
7807 Elf_Internal_Shdr *section,
26c527e6 7808 uint64_t *num_syms_return)
4de91c10
AM
7809{
7810 if (is_32bit_elf)
7811 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7812 else
7813 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7814}
7815
d1133906 7816static const char *
625d49fc 7817get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7818{
5477e8a0 7819 static char buff[1024];
2cf0635d 7820 char * p = buff;
32ec8896
NC
7821 unsigned int field_size = is_32bit_elf ? 8 : 16;
7822 signed int sindex;
7823 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7824 uint64_t os_flags = 0;
7825 uint64_t proc_flags = 0;
7826 uint64_t unknown_flags = 0;
148b93f2 7827 static const struct
5477e8a0 7828 {
2cf0635d 7829 const char * str;
32ec8896 7830 unsigned int len;
5477e8a0
L
7831 }
7832 flags [] =
7833 {
cfcac11d
NC
7834 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7835 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7836 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7837 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7838 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7839 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7840 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7841 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7842 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7843 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7844 /* IA-64 specific. */
7845 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7846 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7847 /* IA-64 OpenVMS specific. */
7848 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7849 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7850 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7851 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7852 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7853 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7854 /* Generic. */
cfcac11d 7855 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7856 /* SPARC specific. */
77115a4a 7857 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7858 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7859 /* ARM specific. */
7860 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7861 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7862 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7863 /* GNU specific. */
7864 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7865 /* VLE specific. */
7866 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7867 /* GNU specific. */
7868 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7869 };
7870
7871 if (do_section_details)
f8c4789c
AM
7872 p += sprintf (p, "[%*.*lx]: ",
7873 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7874
d1133906
NC
7875 while (sh_flags)
7876 {
625d49fc 7877 uint64_t flag;
d1133906
NC
7878
7879 flag = sh_flags & - sh_flags;
7880 sh_flags &= ~ flag;
76da6bbe 7881
5477e8a0 7882 if (do_section_details)
d1133906 7883 {
5477e8a0
L
7884 switch (flag)
7885 {
91d6fa6a
NC
7886 case SHF_WRITE: sindex = 0; break;
7887 case SHF_ALLOC: sindex = 1; break;
7888 case SHF_EXECINSTR: sindex = 2; break;
7889 case SHF_MERGE: sindex = 3; break;
7890 case SHF_STRINGS: sindex = 4; break;
7891 case SHF_INFO_LINK: sindex = 5; break;
7892 case SHF_LINK_ORDER: sindex = 6; break;
7893 case SHF_OS_NONCONFORMING: sindex = 7; break;
7894 case SHF_GROUP: sindex = 8; break;
7895 case SHF_TLS: sindex = 9; break;
18ae9cc1 7896 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7897 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7898
5477e8a0 7899 default:
91d6fa6a 7900 sindex = -1;
dda8d76d 7901 switch (filedata->file_header.e_machine)
148b93f2 7902 {
cfcac11d 7903 case EM_IA_64:
148b93f2 7904 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7905 sindex = 10;
148b93f2 7906 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7907 sindex = 11;
dda8d76d 7908 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7909 switch (flag)
7910 {
91d6fa6a
NC
7911 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7912 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7913 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7914 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7915 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7916 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7917 default: break;
7918 }
cfcac11d
NC
7919 break;
7920
caa83f8b 7921 case EM_386:
22abe556 7922 case EM_IAMCU:
caa83f8b 7923 case EM_X86_64:
7f502d6c 7924 case EM_L1OM:
7a9068fe 7925 case EM_K1OM:
cfcac11d
NC
7926 case EM_OLD_SPARCV9:
7927 case EM_SPARC32PLUS:
7928 case EM_SPARCV9:
7929 case EM_SPARC:
18ae9cc1 7930 if (flag == SHF_ORDERED)
91d6fa6a 7931 sindex = 19;
cfcac11d 7932 break;
ac4c9b04
MG
7933
7934 case EM_ARM:
7935 switch (flag)
7936 {
7937 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7938 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7939 case SHF_COMDEF: sindex = 23; break;
7940 default: break;
7941 }
7942 break;
83eef883
AFB
7943 case EM_PPC:
7944 if (flag == SHF_PPC_VLE)
7945 sindex = 25;
7946 break;
99fabbc9
JL
7947 default:
7948 break;
7949 }
ac4c9b04 7950
99fabbc9
JL
7951 switch (filedata->file_header.e_ident[EI_OSABI])
7952 {
7953 case ELFOSABI_GNU:
7954 case ELFOSABI_FREEBSD:
7955 if (flag == SHF_GNU_RETAIN)
7956 sindex = 26;
7957 /* Fall through */
7958 case ELFOSABI_NONE:
7959 if (flag == SHF_GNU_MBIND)
7960 /* We should not recognize SHF_GNU_MBIND for
7961 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7962 not set the EI_OSABI header byte. */
7963 sindex = 24;
7964 break;
cfcac11d
NC
7965 default:
7966 break;
148b93f2 7967 }
99fabbc9 7968 break;
5477e8a0
L
7969 }
7970
91d6fa6a 7971 if (sindex != -1)
5477e8a0 7972 {
8d5ff12c
L
7973 if (p != buff + field_size + 4)
7974 {
7975 if (size < (10 + 2))
bee0ee85
NC
7976 {
7977 warn (_("Internal error: not enough buffer room for section flag info"));
7978 return _("<unknown>");
7979 }
8d5ff12c
L
7980 size -= 2;
7981 *p++ = ',';
7982 *p++ = ' ';
7983 }
7984
91d6fa6a
NC
7985 size -= flags [sindex].len;
7986 p = stpcpy (p, flags [sindex].str);
5477e8a0 7987 }
3b22753a 7988 else if (flag & SHF_MASKOS)
8d5ff12c 7989 os_flags |= flag;
d1133906 7990 else if (flag & SHF_MASKPROC)
8d5ff12c 7991 proc_flags |= flag;
d1133906 7992 else
8d5ff12c 7993 unknown_flags |= flag;
5477e8a0
L
7994 }
7995 else
7996 {
7997 switch (flag)
7998 {
7999 case SHF_WRITE: *p = 'W'; break;
8000 case SHF_ALLOC: *p = 'A'; break;
8001 case SHF_EXECINSTR: *p = 'X'; break;
8002 case SHF_MERGE: *p = 'M'; break;
8003 case SHF_STRINGS: *p = 'S'; break;
8004 case SHF_INFO_LINK: *p = 'I'; break;
8005 case SHF_LINK_ORDER: *p = 'L'; break;
8006 case SHF_OS_NONCONFORMING: *p = 'O'; break;
8007 case SHF_GROUP: *p = 'G'; break;
8008 case SHF_TLS: *p = 'T'; break;
18ae9cc1 8009 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 8010 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
8011
8012 default:
dda8d76d
NC
8013 if ((filedata->file_header.e_machine == EM_X86_64
8014 || filedata->file_header.e_machine == EM_L1OM
8015 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
8016 && flag == SHF_X86_64_LARGE)
8017 *p = 'l';
dda8d76d 8018 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 8019 && flag == SHF_ARM_PURECODE)
99fabbc9 8020 *p = 'y';
dda8d76d 8021 else if (filedata->file_header.e_machine == EM_PPC
83eef883 8022 && flag == SHF_PPC_VLE)
99fabbc9 8023 *p = 'v';
5477e8a0
L
8024 else if (flag & SHF_MASKOS)
8025 {
99fabbc9
JL
8026 switch (filedata->file_header.e_ident[EI_OSABI])
8027 {
8028 case ELFOSABI_GNU:
8029 case ELFOSABI_FREEBSD:
8030 if (flag == SHF_GNU_RETAIN)
8031 {
8032 *p = 'R';
8033 break;
8034 }
8035 /* Fall through */
8036 case ELFOSABI_NONE:
8037 if (flag == SHF_GNU_MBIND)
8038 {
8039 /* We should not recognize SHF_GNU_MBIND for
8040 ELFOSABI_NONE, but binutils as of 2019-07-23 did
8041 not set the EI_OSABI header byte. */
8042 *p = 'D';
8043 break;
8044 }
8045 /* Fall through */
8046 default:
8047 *p = 'o';
8048 sh_flags &= ~SHF_MASKOS;
8049 break;
8050 }
5477e8a0
L
8051 }
8052 else if (flag & SHF_MASKPROC)
8053 {
8054 *p = 'p';
8055 sh_flags &= ~ SHF_MASKPROC;
8056 }
8057 else
8058 *p = 'x';
8059 break;
8060 }
8061 p++;
d1133906
NC
8062 }
8063 }
76da6bbe 8064
8d5ff12c
L
8065 if (do_section_details)
8066 {
8067 if (os_flags)
8068 {
8d5ff12c
L
8069 if (p != buff + field_size + 4)
8070 {
f8c4789c 8071 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
8072 {
8073 warn (_("Internal error: not enough buffer room for section flag info"));
8074 return _("<unknown>");
8075 }
8d5ff12c
L
8076 size -= 2;
8077 *p++ = ',';
8078 *p++ = ' ';
8079 }
f8c4789c
AM
8080 size -= 5 + field_size;
8081 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
8082 (unsigned long) os_flags);
8d5ff12c
L
8083 }
8084 if (proc_flags)
8085 {
8d5ff12c
L
8086 if (p != buff + field_size + 4)
8087 {
f8c4789c 8088 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
8089 {
8090 warn (_("Internal error: not enough buffer room for section flag info"));
8091 return _("<unknown>");
8092 }
8d5ff12c
L
8093 size -= 2;
8094 *p++ = ',';
8095 *p++ = ' ';
8096 }
f8c4789c
AM
8097 size -= 7 + field_size;
8098 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
8099 (unsigned long) proc_flags);
8d5ff12c
L
8100 }
8101 if (unknown_flags)
8102 {
8d5ff12c
L
8103 if (p != buff + field_size + 4)
8104 {
f8c4789c 8105 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
8106 {
8107 warn (_("Internal error: not enough buffer room for section flag info"));
8108 return _("<unknown>");
8109 }
8d5ff12c
L
8110 size -= 2;
8111 *p++ = ',';
8112 *p++ = ' ';
8113 }
f8c4789c
AM
8114 size -= 10 + field_size;
8115 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8116 (unsigned long) unknown_flags);
8d5ff12c
L
8117 }
8118 }
8119
e9e44622 8120 *p = '\0';
d1133906
NC
8121 return buff;
8122}
8123
5844b465 8124static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
8125get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
8126 uint64_t size)
77115a4a
L
8127{
8128 if (is_32bit_elf)
8129 {
8130 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 8131
ebdf1ebf
NC
8132 if (size < sizeof (* echdr))
8133 {
8134 error (_("Compressed section is too small even for a compression header\n"));
8135 return 0;
8136 }
8137
77115a4a
L
8138 chdr->ch_type = BYTE_GET (echdr->ch_type);
8139 chdr->ch_size = BYTE_GET (echdr->ch_size);
8140 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8141 return sizeof (*echdr);
8142 }
8143 else
8144 {
8145 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 8146
ebdf1ebf
NC
8147 if (size < sizeof (* echdr))
8148 {
8149 error (_("Compressed section is too small even for a compression header\n"));
8150 return 0;
8151 }
8152
77115a4a
L
8153 chdr->ch_type = BYTE_GET (echdr->ch_type);
8154 chdr->ch_size = BYTE_GET (echdr->ch_size);
8155 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8156 return sizeof (*echdr);
8157 }
8158}
8159
015dc7e1 8160static bool
dda8d76d 8161process_section_headers (Filedata * filedata)
252b5132 8162{
2cf0635d 8163 Elf_Internal_Shdr * section;
b34976b6 8164 unsigned int i;
252b5132 8165
dda8d76d 8166 if (filedata->file_header.e_shnum == 0)
252b5132 8167 {
82f2dbf7 8168 /* PR binutils/12467. */
dda8d76d 8169 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
8170 {
8171 warn (_("possibly corrupt ELF file header - it has a non-zero"
8172 " section header offset, but no section headers\n"));
015dc7e1 8173 return false;
32ec8896 8174 }
82f2dbf7 8175 else if (do_sections)
252b5132
RH
8176 printf (_("\nThere are no sections in this file.\n"));
8177
015dc7e1 8178 return true;
252b5132
RH
8179 }
8180
8181 if (do_sections && !do_header)
ca0e11aa
NC
8182 {
8183 if (filedata->is_separate && process_links)
978dae65
NC
8184 printf (_("In linked file '%s': "),
8185 printable_string (filedata->file_name, 0));
ca0e11aa
NC
8186 if (! filedata->is_separate || process_links)
8187 printf (ngettext ("There is %d section header, "
26c527e6 8188 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 8189 "There are %d section headers, "
26c527e6 8190 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
8191 filedata->file_header.e_shnum),
8192 filedata->file_header.e_shnum,
26c527e6 8193 filedata->file_header.e_shoff);
ca0e11aa 8194 }
252b5132 8195
4de91c10
AM
8196 if (!get_section_headers (filedata, false))
8197 return false;
252b5132
RH
8198
8199 /* Read in the string table, so that we have names to display. */
94e2b2a7
AM
8200 if (filedata->string_table == NULL
8201 && filedata->file_header.e_shstrndx != SHN_UNDEF
8202 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 8203 {
dda8d76d 8204 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 8205
c256ffe7
JJ
8206 if (section->sh_size != 0)
8207 {
dda8d76d
NC
8208 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
8209 1, section->sh_size,
8210 _("string table"));
0de14b54 8211
dda8d76d 8212 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 8213 }
252b5132
RH
8214 }
8215
8216 /* Scan the sections for the dynamic symbol table
e3c8793a 8217 and dynamic string table and debug sections. */
89fac5e3 8218 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 8219 switch (filedata->file_header.e_machine)
89fac5e3
RS
8220 {
8221 case EM_MIPS:
8222 case EM_MIPS_RS3_LE:
8223 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
8224 FDE addresses. However, the ABI also has a semi-official ILP32
8225 variant for which the normal FDE address size rules apply.
8226
8227 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
8228 section, where XX is the size of longs in bits. Unfortunately,
8229 earlier compilers provided no way of distinguishing ILP32 objects
8230 from LP64 objects, so if there's any doubt, we should assume that
8231 the official LP64 form is being used. */
d173146d 8232 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 8233 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
8234 eh_addr_size = 8;
8235 break;
0f56a26a
DD
8236
8237 case EM_H8_300:
8238 case EM_H8_300H:
dda8d76d 8239 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
8240 {
8241 case E_H8_MACH_H8300:
8242 case E_H8_MACH_H8300HN:
8243 case E_H8_MACH_H8300SN:
8244 case E_H8_MACH_H8300SXN:
8245 eh_addr_size = 2;
8246 break;
8247 case E_H8_MACH_H8300H:
8248 case E_H8_MACH_H8300S:
8249 case E_H8_MACH_H8300SX:
8250 eh_addr_size = 4;
8251 break;
8252 }
f4236fe4
DD
8253 break;
8254
ff7eeb89 8255 case EM_M32C_OLD:
f4236fe4 8256 case EM_M32C:
dda8d76d 8257 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
8258 {
8259 case EF_M32C_CPU_M16C:
8260 eh_addr_size = 2;
8261 break;
8262 }
8263 break;
89fac5e3
RS
8264 }
8265
76ca31c0
NC
8266#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
8267 do \
8268 { \
be7d229a 8269 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 8270 if (section->sh_entsize != expected_entsize) \
9dd3a467 8271 { \
f493c217 8272 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 8273 i, section->sh_entsize); \
f493c217 8274 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 8275 expected_entsize); \
9dd3a467 8276 section->sh_entsize = expected_entsize; \
76ca31c0
NC
8277 } \
8278 } \
08d8fa11 8279 while (0)
9dd3a467
NC
8280
8281#define CHECK_ENTSIZE(section, i, type) \
1b513401 8282 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
8283 sizeof (Elf64_External_##type))
8284
dda8d76d
NC
8285 for (i = 0, section = filedata->section_headers;
8286 i < filedata->file_header.e_shnum;
b34976b6 8287 i++, section++)
252b5132 8288 {
b6ac461a 8289 const char *name = printable_section_name (filedata, section);
252b5132 8290
1b513401
NC
8291 /* Run some sanity checks on the headers and
8292 possibly fill in some file data as well. */
8293 switch (section->sh_type)
252b5132 8294 {
1b513401 8295 case SHT_DYNSYM:
978c4450 8296 if (filedata->dynamic_symbols != NULL)
252b5132
RH
8297 {
8298 error (_("File contains multiple dynamic symbol tables\n"));
8299 continue;
8300 }
8301
08d8fa11 8302 CHECK_ENTSIZE (section, i, Sym);
978c4450 8303 filedata->dynamic_symbols
4de91c10 8304 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 8305 filedata->dynamic_symtab_section = section;
1b513401
NC
8306 break;
8307
8308 case SHT_STRTAB:
8309 if (streq (name, ".dynstr"))
252b5132 8310 {
1b513401
NC
8311 if (filedata->dynamic_strings != NULL)
8312 {
8313 error (_("File contains multiple dynamic string tables\n"));
8314 continue;
8315 }
8316
8317 filedata->dynamic_strings
8318 = (char *) get_data (NULL, filedata, section->sh_offset,
8319 1, section->sh_size, _("dynamic strings"));
8320 filedata->dynamic_strings_length
8321 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 8322 filedata->dynamic_strtab_section = section;
252b5132 8323 }
1b513401
NC
8324 break;
8325
8326 case SHT_SYMTAB_SHNDX:
8327 {
8328 elf_section_list * entry = xmalloc (sizeof * entry);
8329
8330 entry->hdr = section;
8331 entry->next = filedata->symtab_shndx_list;
8332 filedata->symtab_shndx_list = entry;
8333 }
8334 break;
8335
8336 case SHT_SYMTAB:
8337 CHECK_ENTSIZE (section, i, Sym);
8338 break;
8339
8340 case SHT_GROUP:
8341 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8342 break;
252b5132 8343
1b513401
NC
8344 case SHT_REL:
8345 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 8346 if (do_checks && section->sh_size == 0)
1b513401
NC
8347 warn (_("Section '%s': zero-sized relocation section\n"), name);
8348 break;
8349
8350 case SHT_RELA:
8351 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 8352 if (do_checks && section->sh_size == 0)
1b513401
NC
8353 warn (_("Section '%s': zero-sized relocation section\n"), name);
8354 break;
8355
682351b9
AM
8356 case SHT_RELR:
8357 CHECK_ENTSIZE (section, i, Relr);
8358 break;
8359
1b513401
NC
8360 case SHT_NOTE:
8361 case SHT_PROGBITS:
546cb2d8
NC
8362 /* Having a zero sized section is not illegal according to the
8363 ELF standard, but it might be an indication that something
8364 is wrong. So issue a warning if we are running in lint mode. */
8365 if (do_checks && section->sh_size == 0)
1b513401
NC
8366 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8367 break;
8368
8369 default:
8370 break;
8371 }
8372
8373 if ((do_debugging || do_debug_info || do_debug_abbrevs
8374 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8375 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
8376 || do_debug_str || do_debug_str_offsets || do_debug_loc
8377 || do_debug_ranges
1b513401 8378 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
8379 && (startswith (name, ".debug_")
8380 || startswith (name, ".zdebug_")))
252b5132 8381 {
1b315056
CS
8382 if (name[1] == 'z')
8383 name += sizeof (".zdebug_") - 1;
8384 else
8385 name += sizeof (".debug_") - 1;
252b5132
RH
8386
8387 if (do_debugging
24d127aa
ML
8388 || (do_debug_info && startswith (name, "info"))
8389 || (do_debug_info && startswith (name, "types"))
8390 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 8391 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
8392 || (do_debug_lines && startswith (name, "line."))
8393 || (do_debug_pubnames && startswith (name, "pubnames"))
8394 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8395 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8396 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8397 || (do_debug_aranges && startswith (name, "aranges"))
8398 || (do_debug_ranges && startswith (name, "ranges"))
8399 || (do_debug_ranges && startswith (name, "rnglists"))
8400 || (do_debug_frames && startswith (name, "frame"))
8401 || (do_debug_macinfo && startswith (name, "macinfo"))
8402 || (do_debug_macinfo && startswith (name, "macro"))
8403 || (do_debug_str && startswith (name, "str"))
8404 || (do_debug_links && startswith (name, "sup"))
8405 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8406 || (do_debug_loc && startswith (name, "loc"))
8407 || (do_debug_loc && startswith (name, "loclists"))
8408 || (do_debug_addr && startswith (name, "addr"))
8409 || (do_debug_cu_index && startswith (name, "cu_index"))
8410 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 8411 )
6431e409 8412 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 8413 }
a262ae96 8414 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 8415 else if ((do_debugging || do_debug_info)
24d127aa 8416 && startswith (name, ".gnu.linkonce.wi."))
6431e409 8417 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 8418 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 8419 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
1878f44b
NC
8420 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8421 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
8422 else if (do_gdb_index && (streq (name, ".gdb_index")
8423 || streq (name, ".debug_names")))
6431e409 8424 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
8425 /* Trace sections for Itanium VMS. */
8426 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8427 || do_trace_aranges)
24d127aa 8428 && startswith (name, ".trace_"))
6f875884
TG
8429 {
8430 name += sizeof (".trace_") - 1;
8431
8432 if (do_debugging
8433 || (do_trace_info && streq (name, "info"))
8434 || (do_trace_abbrevs && streq (name, "abbrev"))
8435 || (do_trace_aranges && streq (name, "aranges"))
8436 )
6431e409 8437 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 8438 }
dda8d76d 8439 else if ((do_debugging || do_debug_links)
24d127aa
ML
8440 && (startswith (name, ".gnu_debuglink")
8441 || startswith (name, ".gnu_debugaltlink")))
6431e409 8442 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
8443 }
8444
8445 if (! do_sections)
015dc7e1 8446 return true;
252b5132 8447
ca0e11aa 8448 if (filedata->is_separate && ! process_links)
015dc7e1 8449 return true;
ca0e11aa
NC
8450
8451 if (filedata->is_separate)
978dae65
NC
8452 printf (_("\nSection Headers in linked file '%s':\n"),
8453 printable_string (filedata->file_name, 0));
ca0e11aa 8454 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
8455 printf (_("\nSection Headers:\n"));
8456 else
8457 printf (_("\nSection Header:\n"));
76da6bbe 8458
f7a99963 8459 if (is_32bit_elf)
595cf52e 8460 {
5477e8a0 8461 if (do_section_details)
595cf52e
L
8462 {
8463 printf (_(" [Nr] Name\n"));
5477e8a0 8464 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
8465 }
8466 else
8467 printf
8468 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8469 }
d974e256 8470 else if (do_wide)
595cf52e 8471 {
5477e8a0 8472 if (do_section_details)
595cf52e
L
8473 {
8474 printf (_(" [Nr] Name\n"));
5477e8a0 8475 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
8476 }
8477 else
8478 printf
8479 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8480 }
f7a99963
NC
8481 else
8482 {
5477e8a0 8483 if (do_section_details)
595cf52e
L
8484 {
8485 printf (_(" [Nr] Name\n"));
5477e8a0
L
8486 printf (_(" Type Address Offset Link\n"));
8487 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
8488 }
8489 else
8490 {
8491 printf (_(" [Nr] Name Type Address Offset\n"));
8492 printf (_(" Size EntSize Flags Link Info Align\n"));
8493 }
f7a99963 8494 }
252b5132 8495
5477e8a0
L
8496 if (do_section_details)
8497 printf (_(" Flags\n"));
8498
dda8d76d
NC
8499 for (i = 0, section = filedata->section_headers;
8500 i < filedata->file_header.e_shnum;
b34976b6 8501 i++, section++)
252b5132 8502 {
dd905818
NC
8503 /* Run some sanity checks on the section header. */
8504
8505 /* Check the sh_link field. */
8506 switch (section->sh_type)
8507 {
285e3f99 8508 case SHT_REL:
fcf8f323 8509 case SHT_RELR:
285e3f99
AM
8510 case SHT_RELA:
8511 if (section->sh_link == 0
8512 && (filedata->file_header.e_type == ET_EXEC
8513 || filedata->file_header.e_type == ET_DYN))
8514 /* A dynamic relocation section where all entries use a
8515 zero symbol index need not specify a symtab section. */
8516 break;
8517 /* Fall through. */
dd905818
NC
8518 case SHT_SYMTAB_SHNDX:
8519 case SHT_GROUP:
8520 case SHT_HASH:
8521 case SHT_GNU_HASH:
8522 case SHT_GNU_versym:
285e3f99 8523 if (section->sh_link == 0
dda8d76d
NC
8524 || section->sh_link >= filedata->file_header.e_shnum
8525 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8526 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
8527 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8528 i, section->sh_link);
8529 break;
8530
8531 case SHT_DYNAMIC:
8532 case SHT_SYMTAB:
8533 case SHT_DYNSYM:
8534 case SHT_GNU_verneed:
8535 case SHT_GNU_verdef:
8536 case SHT_GNU_LIBLIST:
285e3f99 8537 if (section->sh_link == 0
dda8d76d
NC
8538 || section->sh_link >= filedata->file_header.e_shnum
8539 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8540 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8541 i, section->sh_link);
8542 break;
8543
8544 case SHT_INIT_ARRAY:
8545 case SHT_FINI_ARRAY:
8546 case SHT_PREINIT_ARRAY:
8547 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8548 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8549 i, section->sh_link);
8550 break;
8551
8552 default:
8553 /* FIXME: Add support for target specific section types. */
8554#if 0 /* Currently we do not check other section types as there are too
8555 many special cases. Stab sections for example have a type
8556 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8557 section. */
8558 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8559 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8560 i, section->sh_link);
8561#endif
8562 break;
8563 }
8564
8565 /* Check the sh_info field. */
8566 switch (section->sh_type)
8567 {
8568 case SHT_REL:
8569 case SHT_RELA:
285e3f99
AM
8570 if (section->sh_info == 0
8571 && (filedata->file_header.e_type == ET_EXEC
8572 || filedata->file_header.e_type == ET_DYN))
8573 /* Dynamic relocations apply to segments, so they do not
8574 need to specify the section they relocate. */
8575 break;
8576 if (section->sh_info == 0
dda8d76d
NC
8577 || section->sh_info >= filedata->file_header.e_shnum
8578 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8579 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8580 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8581 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8582 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8583 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8584 /* FIXME: Are other section types valid ? */
dda8d76d 8585 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8586 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8587 i, section->sh_info);
dd905818
NC
8588 break;
8589
8590 case SHT_DYNAMIC:
8591 case SHT_HASH:
8592 case SHT_SYMTAB_SHNDX:
8593 case SHT_INIT_ARRAY:
8594 case SHT_FINI_ARRAY:
8595 case SHT_PREINIT_ARRAY:
8596 if (section->sh_info != 0)
8597 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8598 i, section->sh_info);
8599 break;
8600
8601 case SHT_GROUP:
8602 case SHT_SYMTAB:
8603 case SHT_DYNSYM:
8604 /* A symbol index - we assume that it is valid. */
8605 break;
8606
8607 default:
8608 /* FIXME: Add support for target specific section types. */
8609 if (section->sh_type == SHT_NOBITS)
8610 /* NOBITS section headers with non-zero sh_info fields can be
8611 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8612 information. The stripped sections have their headers
8613 preserved but their types set to SHT_NOBITS. So do not check
8614 this type of section. */
dd905818
NC
8615 ;
8616 else if (section->sh_flags & SHF_INFO_LINK)
8617 {
dda8d76d 8618 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8619 warn (_("[%2u]: Expected link to another section in info field"), i);
8620 }
a91e1603
L
8621 else if (section->sh_type < SHT_LOOS
8622 && (section->sh_flags & SHF_GNU_MBIND) == 0
8623 && section->sh_info != 0)
dd905818
NC
8624 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8625 i, section->sh_info);
8626 break;
8627 }
8628
3e6b6445 8629 /* Check the sh_size field. */
dda8d76d 8630 if (section->sh_size > filedata->file_size
3e6b6445
NC
8631 && section->sh_type != SHT_NOBITS
8632 && section->sh_type != SHT_NULL
8633 && section->sh_type < SHT_LOOS)
8634 warn (_("Size of section %u is larger than the entire file!\n"), i);
8635
7bfd842d 8636 printf (" [%2u] ", i);
5477e8a0 8637 if (do_section_details)
dda8d76d 8638 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8639 else
b6ac461a 8640 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8641
ea52a088 8642 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8643 get_section_type_name (filedata, section->sh_type));
0b4362b0 8644
f7a99963
NC
8645 if (is_32bit_elf)
8646 {
cfcac11d
NC
8647 const char * link_too_big = NULL;
8648
f7a99963 8649 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8650
f7a99963
NC
8651 printf ( " %6.6lx %6.6lx %2.2lx",
8652 (unsigned long) section->sh_offset,
8653 (unsigned long) section->sh_size,
8654 (unsigned long) section->sh_entsize);
d1133906 8655
5477e8a0
L
8656 if (do_section_details)
8657 fputs (" ", stdout);
8658 else
dda8d76d 8659 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8660
dda8d76d 8661 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8662 {
8663 link_too_big = "";
8664 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8665 an error but it can have special values in Solaris binaries. */
dda8d76d 8666 switch (filedata->file_header.e_machine)
cfcac11d 8667 {
caa83f8b 8668 case EM_386:
22abe556 8669 case EM_IAMCU:
caa83f8b 8670 case EM_X86_64:
7f502d6c 8671 case EM_L1OM:
7a9068fe 8672 case EM_K1OM:
cfcac11d
NC
8673 case EM_OLD_SPARCV9:
8674 case EM_SPARC32PLUS:
8675 case EM_SPARCV9:
8676 case EM_SPARC:
8677 if (section->sh_link == (SHN_BEFORE & 0xffff))
8678 link_too_big = "BEFORE";
8679 else if (section->sh_link == (SHN_AFTER & 0xffff))
8680 link_too_big = "AFTER";
8681 break;
8682 default:
8683 break;
8684 }
8685 }
8686
8687 if (do_section_details)
8688 {
8689 if (link_too_big != NULL && * link_too_big)
8690 printf ("<%s> ", link_too_big);
8691 else
8692 printf ("%2u ", section->sh_link);
8693 printf ("%3u %2lu\n", section->sh_info,
8694 (unsigned long) section->sh_addralign);
8695 }
8696 else
8697 printf ("%2u %3u %2lu\n",
8698 section->sh_link,
8699 section->sh_info,
8700 (unsigned long) section->sh_addralign);
8701
8702 if (link_too_big && ! * link_too_big)
8703 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8704 i, section->sh_link);
f7a99963 8705 }
d974e256
JJ
8706 else if (do_wide)
8707 {
8708 print_vma (section->sh_addr, LONG_HEX);
8709
8710 if ((long) section->sh_offset == section->sh_offset)
8711 printf (" %6.6lx", (unsigned long) section->sh_offset);
8712 else
8713 {
8714 putchar (' ');
8715 print_vma (section->sh_offset, LONG_HEX);
8716 }
8717
8718 if ((unsigned long) section->sh_size == section->sh_size)
8719 printf (" %6.6lx", (unsigned long) section->sh_size);
8720 else
8721 {
8722 putchar (' ');
8723 print_vma (section->sh_size, LONG_HEX);
8724 }
8725
8726 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8727 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8728 else
8729 {
8730 putchar (' ');
8731 print_vma (section->sh_entsize, LONG_HEX);
8732 }
8733
5477e8a0
L
8734 if (do_section_details)
8735 fputs (" ", stdout);
8736 else
dda8d76d 8737 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8738
72de5009 8739 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8740
8741 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8742 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8743 else
8744 {
8745 print_vma (section->sh_addralign, DEC);
8746 putchar ('\n');
8747 }
8748 }
5477e8a0 8749 else if (do_section_details)
595cf52e 8750 {
55cc53e9 8751 putchar (' ');
595cf52e
L
8752 print_vma (section->sh_addr, LONG_HEX);
8753 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8754 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8755 else
8756 {
8757 printf (" ");
8758 print_vma (section->sh_offset, LONG_HEX);
8759 }
72de5009 8760 printf (" %u\n ", section->sh_link);
595cf52e 8761 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8762 putchar (' ');
595cf52e
L
8763 print_vma (section->sh_entsize, LONG_HEX);
8764
72de5009
AM
8765 printf (" %-16u %lu\n",
8766 section->sh_info,
595cf52e
L
8767 (unsigned long) section->sh_addralign);
8768 }
f7a99963
NC
8769 else
8770 {
8771 putchar (' ');
8772 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8773 if ((long) section->sh_offset == section->sh_offset)
8774 printf (" %8.8lx", (unsigned long) section->sh_offset);
8775 else
8776 {
8777 printf (" ");
8778 print_vma (section->sh_offset, LONG_HEX);
8779 }
f7a99963
NC
8780 printf ("\n ");
8781 print_vma (section->sh_size, LONG_HEX);
8782 printf (" ");
8783 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8784
dda8d76d 8785 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8786
72de5009
AM
8787 printf (" %2u %3u %lu\n",
8788 section->sh_link,
8789 section->sh_info,
f7a99963
NC
8790 (unsigned long) section->sh_addralign);
8791 }
5477e8a0
L
8792
8793 if (do_section_details)
77115a4a 8794 {
dda8d76d 8795 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8796 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8797 {
8798 /* Minimum section size is 12 bytes for 32-bit compression
8799 header + 12 bytes for compressed data header. */
8800 unsigned char buf[24];
d8024a91 8801
77115a4a 8802 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8803 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8804 sizeof (buf), _("compression header")))
8805 {
8806 Elf_Internal_Chdr chdr;
d8024a91 8807
5844b465
NC
8808 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8809 printf (_(" [<corrupt>]\n"));
77115a4a 8810 else
5844b465 8811 {
89dbeac7 8812 if (chdr.ch_type == ch_compress_zlib)
5844b465 8813 printf (" ZLIB, ");
89dbeac7 8814 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8815 printf (" ZSTD, ");
5844b465
NC
8816 else
8817 printf (_(" [<unknown>: 0x%x], "),
8818 chdr.ch_type);
8819 print_vma (chdr.ch_size, LONG_HEX);
8820 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8821 }
77115a4a
L
8822 }
8823 }
8824 }
252b5132
RH
8825 }
8826
5477e8a0 8827 if (!do_section_details)
3dbcc61d 8828 {
9fb71ee4
NC
8829 /* The ordering of the letters shown here matches the ordering of the
8830 corresponding SHF_xxx values, and hence the order in which these
8831 letters will be displayed to the user. */
8832 printf (_("Key to Flags:\n\
8833 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8834 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8835 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8836 switch (filedata->file_header.e_ident[EI_OSABI])
8837 {
8838 case ELFOSABI_GNU:
8839 case ELFOSABI_FREEBSD:
8840 printf (_("R (retain), "));
8841 /* Fall through */
8842 case ELFOSABI_NONE:
8843 printf (_("D (mbind), "));
8844 break;
8845 default:
8846 break;
8847 }
dda8d76d
NC
8848 if (filedata->file_header.e_machine == EM_X86_64
8849 || filedata->file_header.e_machine == EM_L1OM
8850 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8851 printf (_("l (large), "));
dda8d76d 8852 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8853 printf (_("y (purecode), "));
dda8d76d 8854 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8855 printf (_("v (VLE), "));
9fb71ee4 8856 printf ("p (processor specific)\n");
0b4362b0 8857 }
d1133906 8858
015dc7e1 8859 return true;
252b5132
RH
8860}
8861
015dc7e1 8862static bool
fcf8f323
NC
8863get_symtab (Filedata * filedata,
8864 Elf_Internal_Shdr * symsec,
8865 Elf_Internal_Sym ** symtab,
8866 uint64_t * nsyms,
8867 char ** strtab,
8868 uint64_t * strtablen)
28d13567
AM
8869{
8870 *strtab = NULL;
8871 *strtablen = 0;
4de91c10 8872 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8873
8874 if (*symtab == NULL)
015dc7e1 8875 return false;
28d13567
AM
8876
8877 if (symsec->sh_link != 0)
8878 {
8879 Elf_Internal_Shdr *strsec;
8880
8881 if (symsec->sh_link >= filedata->file_header.e_shnum)
8882 {
8883 error (_("Bad sh_link in symbol table section\n"));
8884 free (*symtab);
8885 *symtab = NULL;
8886 *nsyms = 0;
015dc7e1 8887 return false;
28d13567
AM
8888 }
8889
8890 strsec = filedata->section_headers + symsec->sh_link;
8891
8892 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8893 1, strsec->sh_size, _("string table"));
8894 if (*strtab == NULL)
8895 {
8896 free (*symtab);
8897 *symtab = NULL;
8898 *nsyms = 0;
015dc7e1 8899 return false;
28d13567
AM
8900 }
8901 *strtablen = strsec->sh_size;
8902 }
015dc7e1 8903 return true;
28d13567
AM
8904}
8905
f5842774
L
8906static const char *
8907get_group_flags (unsigned int flags)
8908{
1449284b 8909 static char buff[128];
220453ec 8910
6d913794
NC
8911 if (flags == 0)
8912 return "";
8913 else if (flags == GRP_COMDAT)
8914 return "COMDAT ";
f5842774 8915
89246a0e
AM
8916 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8917 flags,
8918 flags & GRP_MASKOS ? _("<OS specific>") : "",
8919 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8920 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8921 ? _("<unknown>") : ""));
6d913794 8922
f5842774
L
8923 return buff;
8924}
8925
015dc7e1 8926static bool
dda8d76d 8927process_section_groups (Filedata * filedata)
f5842774 8928{
2cf0635d 8929 Elf_Internal_Shdr * section;
f5842774 8930 unsigned int i;
2cf0635d
NC
8931 struct group * group;
8932 Elf_Internal_Shdr * symtab_sec;
8933 Elf_Internal_Shdr * strtab_sec;
8934 Elf_Internal_Sym * symtab;
26c527e6 8935 uint64_t num_syms;
2cf0635d 8936 char * strtab;
c256ffe7 8937 size_t strtab_size;
d1f5c6e3
L
8938
8939 /* Don't process section groups unless needed. */
8940 if (!do_unwind && !do_section_groups)
015dc7e1 8941 return true;
f5842774 8942
dda8d76d 8943 if (filedata->file_header.e_shnum == 0)
f5842774
L
8944 {
8945 if (do_section_groups)
ca0e11aa
NC
8946 {
8947 if (filedata->is_separate)
8948 printf (_("\nThere are no sections group in linked file '%s'.\n"),
978dae65 8949 printable_string (filedata->file_name, 0));
ca0e11aa
NC
8950 else
8951 printf (_("\nThere are no section groups in this file.\n"));
8952 }
015dc7e1 8953 return true;
f5842774
L
8954 }
8955
dda8d76d 8956 if (filedata->section_headers == NULL)
f5842774
L
8957 {
8958 error (_("Section headers are not available!\n"));
fa1908fd 8959 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8960 return false;
f5842774
L
8961 }
8962
978c4450
AM
8963 filedata->section_headers_groups
8964 = (struct group **) calloc (filedata->file_header.e_shnum,
8965 sizeof (struct group *));
e4b17d5c 8966
978c4450 8967 if (filedata->section_headers_groups == NULL)
e4b17d5c 8968 {
8b73c356 8969 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8970 filedata->file_header.e_shnum);
015dc7e1 8971 return false;
e4b17d5c
L
8972 }
8973
f5842774 8974 /* Scan the sections for the group section. */
978c4450 8975 filedata->group_count = 0;
dda8d76d
NC
8976 for (i = 0, section = filedata->section_headers;
8977 i < filedata->file_header.e_shnum;
f5842774 8978 i++, section++)
e4b17d5c 8979 if (section->sh_type == SHT_GROUP)
978c4450 8980 filedata->group_count++;
e4b17d5c 8981
978c4450 8982 if (filedata->group_count == 0)
d1f5c6e3
L
8983 {
8984 if (do_section_groups)
ca0e11aa
NC
8985 {
8986 if (filedata->is_separate)
8987 printf (_("\nThere are no section groups in linked file '%s'.\n"),
978dae65 8988 printable_string (filedata->file_name, 0));
ca0e11aa
NC
8989 else
8990 printf (_("\nThere are no section groups in this file.\n"));
8991 }
d1f5c6e3 8992
015dc7e1 8993 return true;
d1f5c6e3
L
8994 }
8995
978c4450
AM
8996 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8997 sizeof (struct group));
e4b17d5c 8998
978c4450 8999 if (filedata->section_groups == NULL)
e4b17d5c 9000 {
26c527e6 9001 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 9002 return false;
e4b17d5c
L
9003 }
9004
d1f5c6e3
L
9005 symtab_sec = NULL;
9006 strtab_sec = NULL;
9007 symtab = NULL;
ba5cdace 9008 num_syms = 0;
d1f5c6e3 9009 strtab = NULL;
c256ffe7 9010 strtab_size = 0;
ca0e11aa
NC
9011
9012 if (filedata->is_separate)
978dae65
NC
9013 printf (_("Section groups in linked file '%s'\n"),
9014 printable_string (filedata->file_name, 0));
047c3dbf 9015
978c4450 9016 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 9017 i < filedata->file_header.e_shnum;
e4b17d5c 9018 i++, section++)
f5842774
L
9019 {
9020 if (section->sh_type == SHT_GROUP)
9021 {
dda8d76d 9022 const char * name = printable_section_name (filedata, section);
74e1a04b 9023 const char * group_name;
2cf0635d
NC
9024 unsigned char * start;
9025 unsigned char * indices;
f5842774 9026 unsigned int entry, j, size;
2cf0635d
NC
9027 Elf_Internal_Shdr * sec;
9028 Elf_Internal_Sym * sym;
f5842774
L
9029
9030 /* Get the symbol table. */
dda8d76d
NC
9031 if (section->sh_link >= filedata->file_header.e_shnum
9032 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 9033 != SHT_SYMTAB))
f5842774
L
9034 {
9035 error (_("Bad sh_link in group section `%s'\n"), name);
9036 continue;
9037 }
d1f5c6e3
L
9038
9039 if (symtab_sec != sec)
9040 {
9041 symtab_sec = sec;
9db70fc3 9042 free (symtab);
4de91c10 9043 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 9044 }
f5842774 9045
dd24e3da
NC
9046 if (symtab == NULL)
9047 {
9048 error (_("Corrupt header in group section `%s'\n"), name);
9049 continue;
9050 }
9051
ba5cdace
NC
9052 if (section->sh_info >= num_syms)
9053 {
9054 error (_("Bad sh_info in group section `%s'\n"), name);
9055 continue;
9056 }
9057
f5842774
L
9058 sym = symtab + section->sh_info;
9059
9060 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
9061 {
4fbb74a6 9062 if (sym->st_shndx == 0
dda8d76d 9063 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
9064 {
9065 error (_("Bad sh_info in group section `%s'\n"), name);
9066 continue;
9067 }
ba2685cc 9068
b6ac461a
NC
9069 group_name = printable_section_name (filedata,
9070 filedata->section_headers
9071 + sym->st_shndx);
c256ffe7 9072 strtab_sec = NULL;
9db70fc3 9073 free (strtab);
f5842774 9074 strtab = NULL;
c256ffe7 9075 strtab_size = 0;
f5842774
L
9076 }
9077 else
9078 {
9079 /* Get the string table. */
dda8d76d 9080 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
9081 {
9082 strtab_sec = NULL;
9db70fc3 9083 free (strtab);
c256ffe7
JJ
9084 strtab = NULL;
9085 strtab_size = 0;
9086 }
9087 else if (strtab_sec
dda8d76d 9088 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
9089 {
9090 strtab_sec = sec;
9db70fc3 9091 free (strtab);
071436c6 9092
dda8d76d 9093 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
9094 1, strtab_sec->sh_size,
9095 _("string table"));
c256ffe7 9096 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 9097 }
c256ffe7 9098 group_name = sym->st_name < strtab_size
2b692964 9099 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
9100 }
9101
c9c1d674
EG
9102 /* PR 17531: file: loop. */
9103 if (section->sh_entsize > section->sh_size)
9104 {
26c527e6
AM
9105 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
9106 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 9107 printable_section_name (filedata, section),
26c527e6
AM
9108 section->sh_entsize,
9109 section->sh_size);
61dd8e19 9110 continue;
c9c1d674
EG
9111 }
9112
dda8d76d 9113 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
9114 1, section->sh_size,
9115 _("section data"));
59245841
NC
9116 if (start == NULL)
9117 continue;
f5842774
L
9118
9119 indices = start;
9120 size = (section->sh_size / section->sh_entsize) - 1;
9121 entry = byte_get (indices, 4);
9122 indices += 4;
e4b17d5c
L
9123
9124 if (do_section_groups)
9125 {
2b692964 9126 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 9127 get_group_flags (entry), i, name, group_name, size);
ba2685cc 9128
e4b17d5c
L
9129 printf (_(" [Index] Name\n"));
9130 }
9131
9132 group->group_index = i;
9133
f5842774
L
9134 for (j = 0; j < size; j++)
9135 {
2cf0635d 9136 struct group_list * g;
e4b17d5c 9137
f5842774
L
9138 entry = byte_get (indices, 4);
9139 indices += 4;
9140
dda8d76d 9141 if (entry >= filedata->file_header.e_shnum)
391cb864 9142 {
57028622
NC
9143 static unsigned num_group_errors = 0;
9144
9145 if (num_group_errors ++ < 10)
9146 {
9147 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 9148 entry, i, filedata->file_header.e_shnum - 1);
57028622 9149 if (num_group_errors == 10)
67ce483b 9150 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 9151 }
391cb864
L
9152 continue;
9153 }
391cb864 9154
978c4450 9155 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 9156 {
d1f5c6e3
L
9157 if (entry)
9158 {
57028622
NC
9159 static unsigned num_errs = 0;
9160
9161 if (num_errs ++ < 10)
9162 {
9163 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
9164 entry, i,
978c4450 9165 filedata->section_headers_groups [entry]->group_index);
57028622
NC
9166 if (num_errs == 10)
9167 warn (_("Further error messages about already contained group sections suppressed\n"));
9168 }
d1f5c6e3
L
9169 continue;
9170 }
9171 else
9172 {
9173 /* Intel C/C++ compiler may put section 0 in a
32ec8896 9174 section group. We just warn it the first time
d1f5c6e3 9175 and ignore it afterwards. */
015dc7e1 9176 static bool warned = false;
d1f5c6e3
L
9177 if (!warned)
9178 {
9179 error (_("section 0 in group section [%5u]\n"),
978c4450 9180 filedata->section_headers_groups [entry]->group_index);
015dc7e1 9181 warned = true;
d1f5c6e3
L
9182 }
9183 }
e4b17d5c
L
9184 }
9185
978c4450 9186 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
9187
9188 if (do_section_groups)
9189 {
dda8d76d
NC
9190 sec = filedata->section_headers + entry;
9191 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
9192 }
9193
3f5e193b 9194 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
9195 g->section_index = entry;
9196 g->next = group->root;
9197 group->root = g;
f5842774
L
9198 }
9199
9db70fc3 9200 free (start);
e4b17d5c
L
9201
9202 group++;
f5842774
L
9203 }
9204 }
9205
9db70fc3
AM
9206 free (symtab);
9207 free (strtab);
015dc7e1 9208 return true;
f5842774
L
9209}
9210
28f997cf
TG
9211/* Data used to display dynamic fixups. */
9212
9213struct ia64_vms_dynfixup
9214{
625d49fc
AM
9215 uint64_t needed_ident; /* Library ident number. */
9216 uint64_t needed; /* Index in the dstrtab of the library name. */
9217 uint64_t fixup_needed; /* Index of the library. */
9218 uint64_t fixup_rela_cnt; /* Number of fixups. */
9219 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
9220};
9221
9222/* Data used to display dynamic relocations. */
9223
9224struct ia64_vms_dynimgrela
9225{
625d49fc
AM
9226 uint64_t img_rela_cnt; /* Number of relocations. */
9227 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
9228};
9229
9230/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
9231 library). */
9232
015dc7e1 9233static bool
dda8d76d
NC
9234dump_ia64_vms_dynamic_fixups (Filedata * filedata,
9235 struct ia64_vms_dynfixup * fixup,
9236 const char * strtab,
9237 unsigned int strtab_sz)
28f997cf 9238{
32ec8896 9239 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 9240 size_t i;
32ec8896 9241 const char * lib_name;
28f997cf 9242
978c4450
AM
9243 imfs = get_data (NULL, filedata,
9244 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 9245 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
9246 _("dynamic section image fixups"));
9247 if (!imfs)
015dc7e1 9248 return false;
28f997cf
TG
9249
9250 if (fixup->needed < strtab_sz)
9251 lib_name = strtab + fixup->needed;
9252 else
9253 {
26c527e6
AM
9254 warn (_("corrupt library name index of %#" PRIx64
9255 " found in dynamic entry"), fixup->needed);
28f997cf
TG
9256 lib_name = "???";
9257 }
736990c4 9258
26c527e6
AM
9259 printf (_("\nImage fixups for needed library #%" PRId64
9260 ": %s - ident: %" PRIx64 "\n"),
9261 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
9262 printf
9263 (_("Seg Offset Type SymVec DataType\n"));
9264
26c527e6 9265 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
9266 {
9267 unsigned int type;
9268 const char *rtype;
9269
9270 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 9271 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
9272 type = BYTE_GET (imfs [i].type);
9273 rtype = elf_ia64_reloc_type (type);
9274 if (rtype == NULL)
f493c217 9275 printf ("0x%08x ", type);
28f997cf 9276 else
f493c217 9277 printf ("%-32s ", rtype);
28f997cf
TG
9278 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
9279 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
9280 }
9281
9282 free (imfs);
015dc7e1 9283 return true;
28f997cf
TG
9284}
9285
9286/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
9287
015dc7e1 9288static bool
dda8d76d 9289dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
9290{
9291 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 9292 size_t i;
28f997cf 9293
978c4450
AM
9294 imrs = get_data (NULL, filedata,
9295 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 9296 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 9297 _("dynamic section image relocations"));
28f997cf 9298 if (!imrs)
015dc7e1 9299 return false;
28f997cf
TG
9300
9301 printf (_("\nImage relocs\n"));
9302 printf
9303 (_("Seg Offset Type Addend Seg Sym Off\n"));
9304
26c527e6 9305 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
9306 {
9307 unsigned int type;
9308 const char *rtype;
9309
9310 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 9311 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
9312 type = BYTE_GET (imrs [i].type);
9313 rtype = elf_ia64_reloc_type (type);
9314 if (rtype == NULL)
9315 printf ("0x%08x ", type);
9316 else
9317 printf ("%-31s ", rtype);
9318 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9319 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 9320 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
9321 }
9322
9323 free (imrs);
015dc7e1 9324 return true;
28f997cf
TG
9325}
9326
9327/* Display IA-64 OpenVMS dynamic relocations and fixups. */
9328
015dc7e1 9329static bool
dda8d76d 9330process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
9331{
9332 struct ia64_vms_dynfixup fixup;
9333 struct ia64_vms_dynimgrela imgrela;
9334 Elf_Internal_Dyn *entry;
625d49fc
AM
9335 uint64_t strtab_off = 0;
9336 uint64_t strtab_sz = 0;
28f997cf 9337 char *strtab = NULL;
015dc7e1 9338 bool res = true;
28f997cf
TG
9339
9340 memset (&fixup, 0, sizeof (fixup));
9341 memset (&imgrela, 0, sizeof (imgrela));
9342
9343 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
9344 for (entry = filedata->dynamic_section;
9345 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
9346 entry++)
9347 {
9348 switch (entry->d_tag)
9349 {
9350 case DT_IA_64_VMS_STRTAB_OFFSET:
9351 strtab_off = entry->d_un.d_val;
9352 break;
9353 case DT_STRSZ:
9354 strtab_sz = entry->d_un.d_val;
9355 if (strtab == NULL)
978c4450
AM
9356 strtab = get_data (NULL, filedata,
9357 filedata->dynamic_addr + strtab_off,
28f997cf 9358 1, strtab_sz, _("dynamic string section"));
736990c4
NC
9359 if (strtab == NULL)
9360 strtab_sz = 0;
28f997cf
TG
9361 break;
9362
9363 case DT_IA_64_VMS_NEEDED_IDENT:
9364 fixup.needed_ident = entry->d_un.d_val;
9365 break;
9366 case DT_NEEDED:
9367 fixup.needed = entry->d_un.d_val;
9368 break;
9369 case DT_IA_64_VMS_FIXUP_NEEDED:
9370 fixup.fixup_needed = entry->d_un.d_val;
9371 break;
9372 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9373 fixup.fixup_rela_cnt = entry->d_un.d_val;
9374 break;
9375 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9376 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 9377 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 9378 res = false;
28f997cf 9379 break;
28f997cf
TG
9380 case DT_IA_64_VMS_IMG_RELA_CNT:
9381 imgrela.img_rela_cnt = entry->d_un.d_val;
9382 break;
9383 case DT_IA_64_VMS_IMG_RELA_OFF:
9384 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 9385 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 9386 res = false;
28f997cf
TG
9387 break;
9388
9389 default:
9390 break;
9391 }
9392 }
9393
9db70fc3 9394 free (strtab);
28f997cf
TG
9395
9396 return res;
9397}
9398
85b1c36d 9399static struct
566b0d53 9400{
2cf0635d 9401 const char * name;
566b0d53
L
9402 int reloc;
9403 int size;
a7fd1186 9404 relocation_type rel_type;
32ec8896
NC
9405}
9406 dynamic_relocations [] =
566b0d53 9407{
a7fd1186
FS
9408 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9409 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9410 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9411 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
9412};
9413
8e8d0b63
NC
9414static relocation_type
9415rel_type_from_sh_type (unsigned int sh_type)
9416{
9417 switch (sh_type)
9418 {
9419 case SHT_RELA: return reltype_rela;
9420 case SHT_REL: return reltype_rel;
9421 case SHT_RELR: return reltype_relr;
9422 default: return reltype_unknown;
9423 }
9424}
9425
9426static bool
9427display_relocations (Elf_Internal_Shdr * section,
9428 Filedata * filedata)
9429{
fcf8f323
NC
9430 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9431
9432 if (rel_type == reltype_unknown)
8e8d0b63
NC
9433 return false;
9434
9435 uint64_t rel_size = section->sh_size;
9436
9437 if (rel_size == 0)
9438 return false;
9439
9440 if (filedata->is_separate)
9441 printf (_("\nIn linked file '%s' relocation section "),
978dae65 9442 printable_string (filedata->file_name, 0));
8e8d0b63
NC
9443 else
9444 printf (_("\nRelocation section "));
9445
9446 if (filedata->string_table == NULL)
9447 printf ("%d", section->sh_name);
9448 else
9449 printf ("'%s'", printable_section_name (filedata, section));
9450
9451 uint64_t num_rela = rel_size / section->sh_entsize;
9452 uint64_t rel_offset = section->sh_offset;
9453
3b3e2090
NC
9454 if (rel_type == reltype_relr)
9455 {
9456 /* Just stating the 'number of entries' in a RELR section can be
9457 misleading, since this is not the number of locations relocated, but
9458 the number of words in the compressed RELR format. So also provide
9459 the number of locations affected. */
ad43ae76
NC
9460
9461 uint64_t num_reloc = count_relr_relocations (filedata, section);
9462
9463 printf (_(" at offset %#" PRIx64), rel_offset);
9464 printf (ngettext (" contains %" PRIu64 " entry which relocates",
9465 " contains %" PRIu64 " entries which relocate",
9466 num_rela), num_rela);
9467 printf (ngettext (" %" PRIu64 " location:\n",
9468 " %" PRIu64 " locations:\n",
9469 num_reloc), num_reloc);
3b3e2090
NC
9470 }
9471 else
9472 {
9473 printf (ngettext (" at offset %#" PRIx64
9474 " contains %" PRIu64 " entry:\n",
9475 " at offset %#" PRIx64
9476 " contains %" PRIu64 " entries:\n",
9477 num_rela),
9478 rel_offset, num_rela);
9479 }
8e8d0b63 9480
fcf8f323
NC
9481 Elf_Internal_Shdr * symsec;
9482 Elf_Internal_Sym * symtab = NULL;
9483 uint64_t nsyms = 0;
9484 uint64_t strtablen = 0;
9485 char * strtab = NULL;
8e8d0b63
NC
9486
9487 if (section->sh_link == 0
9488 || section->sh_link >= filedata->file_header.e_shnum)
fcf8f323
NC
9489 {
9490 /* Symbol data not available.
9491 This can happen, especially with RELR relocs.
9492 See if there is a .symtab section present.
9493 If so then use it. */
9494 symsec = find_section_by_name (filedata, ".symtab");
9495 }
9496 else
9497 {
9498 symsec = filedata->section_headers + section->sh_link;
8e8d0b63 9499
fcf8f323
NC
9500 if (symsec->sh_type != SHT_SYMTAB
9501 && symsec->sh_type != SHT_DYNSYM)
9502 return false;
9503 }
8e8d0b63 9504
fcf8f323
NC
9505 if (symsec != NULL
9506 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
8e8d0b63
NC
9507 return false;
9508
fcf8f323
NC
9509 bool res;
9510
9511 if (rel_type == reltype_relr)
9512 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9513 else
9514 res = dump_relocations (filedata, rel_offset, rel_size,
9515 symtab, nsyms, strtab, strtablen,
9516 rel_type,
9517 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
8e8d0b63
NC
9518 free (strtab);
9519 free (symtab);
9520
9521 return res;
9522}
9523
252b5132 9524/* Process the reloc section. */
18bd398b 9525
015dc7e1 9526static bool
dda8d76d 9527process_relocs (Filedata * filedata)
252b5132 9528{
26c527e6
AM
9529 uint64_t rel_size;
9530 uint64_t rel_offset;
252b5132 9531
252b5132 9532 if (!do_reloc)
015dc7e1 9533 return true;
252b5132
RH
9534
9535 if (do_using_dynamic)
9536 {
a7fd1186 9537 relocation_type rel_type;
2cf0635d 9538 const char * name;
015dc7e1 9539 bool has_dynamic_reloc;
566b0d53 9540 unsigned int i;
0de14b54 9541
015dc7e1 9542 has_dynamic_reloc = false;
252b5132 9543
566b0d53 9544 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 9545 {
a7fd1186 9546 rel_type = dynamic_relocations [i].rel_type;
566b0d53 9547 name = dynamic_relocations [i].name;
978c4450
AM
9548 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9549 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 9550
32ec8896 9551 if (rel_size)
015dc7e1 9552 has_dynamic_reloc = true;
566b0d53 9553
a7fd1186 9554 if (rel_type == reltype_unknown)
aa903cfb 9555 {
566b0d53 9556 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 9557 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
9558 {
9559 case DT_REL:
a7fd1186 9560 rel_type = reltype_rel;
566b0d53
L
9561 break;
9562 case DT_RELA:
a7fd1186 9563 rel_type = reltype_rela;
566b0d53
L
9564 break;
9565 }
aa903cfb 9566 }
252b5132 9567
566b0d53
L
9568 if (rel_size)
9569 {
ca0e11aa
NC
9570 if (filedata->is_separate)
9571 printf
26c527e6
AM
9572 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9573 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
9574 filedata->file_name, name, rel_offset, rel_size);
9575 else
9576 printf
26c527e6
AM
9577 (_("\n'%s' relocation section at offset %#" PRIx64
9578 " contains %" PRId64 " bytes:\n"),
ca0e11aa 9579 name, rel_offset, rel_size);
252b5132 9580
dda8d76d
NC
9581 dump_relocations (filedata,
9582 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 9583 rel_size,
978c4450
AM
9584 filedata->dynamic_symbols,
9585 filedata->num_dynamic_syms,
9586 filedata->dynamic_strings,
9587 filedata->dynamic_strings_length,
a7fd1186 9588 rel_type, true /* is_dynamic */);
566b0d53 9589 }
252b5132 9590 }
566b0d53 9591
dda8d76d
NC
9592 if (is_ia64_vms (filedata))
9593 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 9594 has_dynamic_reloc = true;
28f997cf 9595
566b0d53 9596 if (! has_dynamic_reloc)
ca0e11aa
NC
9597 {
9598 if (filedata->is_separate)
9599 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9600 filedata->file_name);
9601 else
9602 printf (_("\nThere are no dynamic relocations in this file.\n"));
9603 }
252b5132
RH
9604 }
9605 else
9606 {
2cf0635d 9607 Elf_Internal_Shdr * section;
26c527e6 9608 size_t i;
015dc7e1 9609 bool found = false;
252b5132 9610
dda8d76d
NC
9611 for (i = 0, section = filedata->section_headers;
9612 i < filedata->file_header.e_shnum;
b34976b6 9613 i++, section++)
252b5132 9614 {
8e8d0b63
NC
9615 if (display_relocations (section, filedata))
9616 found = true;
252b5132
RH
9617 }
9618
9619 if (! found)
45ac8f4f
NC
9620 {
9621 /* Users sometimes forget the -D option, so try to be helpful. */
9622 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9623 {
978c4450 9624 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9625 {
ca0e11aa
NC
9626 if (filedata->is_separate)
9627 printf (_("\nThere are no static relocations in linked file '%s'."),
9628 filedata->file_name);
9629 else
9630 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9631 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9632
9633 break;
9634 }
9635 }
9636 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9637 {
9638 if (filedata->is_separate)
9639 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9640 filedata->file_name);
9641 else
9642 printf (_("\nThere are no relocations in this file.\n"));
9643 }
45ac8f4f 9644 }
252b5132
RH
9645 }
9646
015dc7e1 9647 return true;
252b5132
RH
9648}
9649
4d6ed7c8
NC
9650/* An absolute address consists of a section and an offset. If the
9651 section is NULL, the offset itself is the address, otherwise, the
9652 address equals to LOAD_ADDRESS(section) + offset. */
9653
9654struct absaddr
948f632f
DA
9655{
9656 unsigned short section;
625d49fc 9657 uint64_t offset;
948f632f 9658};
4d6ed7c8 9659
948f632f
DA
9660/* Find the nearest symbol at or below ADDR. Returns the symbol
9661 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9662
4d6ed7c8 9663static void
26c527e6
AM
9664find_symbol_for_address (Filedata *filedata,
9665 Elf_Internal_Sym *symtab,
9666 uint64_t nsyms,
9667 const char *strtab,
9668 uint64_t strtab_size,
9669 struct absaddr addr,
9670 const char **symname,
9671 uint64_t *offset)
4d6ed7c8 9672{
625d49fc 9673 uint64_t dist = 0x100000;
2cf0635d 9674 Elf_Internal_Sym * sym;
948f632f
DA
9675 Elf_Internal_Sym * beg;
9676 Elf_Internal_Sym * end;
2cf0635d 9677 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9678
0b6ae522 9679 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9680 beg = symtab;
9681 end = symtab + nsyms;
0b6ae522 9682
948f632f 9683 while (beg < end)
4d6ed7c8 9684 {
625d49fc 9685 uint64_t value;
948f632f
DA
9686
9687 sym = beg + (end - beg) / 2;
0b6ae522 9688
948f632f 9689 value = sym->st_value;
0b6ae522
DJ
9690 REMOVE_ARCH_BITS (value);
9691
948f632f 9692 if (sym->st_name != 0
4d6ed7c8 9693 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9694 && addr.offset >= value
9695 && addr.offset - value < dist)
4d6ed7c8
NC
9696 {
9697 best = sym;
0b6ae522 9698 dist = addr.offset - value;
4d6ed7c8
NC
9699 if (!dist)
9700 break;
9701 }
948f632f
DA
9702
9703 if (addr.offset < value)
9704 end = sym;
9705 else
9706 beg = sym + 1;
4d6ed7c8 9707 }
1b31d05e 9708
4d6ed7c8
NC
9709 if (best)
9710 {
57346661 9711 *symname = (best->st_name >= strtab_size
2b692964 9712 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9713 *offset = dist;
9714 return;
9715 }
1b31d05e 9716
4d6ed7c8
NC
9717 *symname = NULL;
9718 *offset = addr.offset;
9719}
9720
948f632f
DA
9721/* Process the unwind section. */
9722
9723#include "unwind-ia64.h"
9724
9725struct ia64_unw_table_entry
9726{
9727 struct absaddr start;
9728 struct absaddr end;
9729 struct absaddr info;
9730};
9731
9732struct ia64_unw_aux_info
9733{
32ec8896 9734 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9735 uint64_t table_len; /* Length of unwind table. */
32ec8896 9736 unsigned char * info; /* Unwind info. */
26c527e6 9737 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9738 uint64_t info_addr; /* Starting address of unwind info. */
9739 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9740 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9741 uint64_t nsyms; /* Number of symbols. */
32ec8896 9742 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9743 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9744 char * strtab; /* The string table. */
26c527e6 9745 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9746};
9747
015dc7e1 9748static bool
dda8d76d 9749dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9750{
2cf0635d 9751 struct ia64_unw_table_entry * tp;
26c527e6 9752 size_t j, nfuns;
4d6ed7c8 9753 int in_body;
015dc7e1 9754 bool res = true;
7036c0e1 9755
948f632f
DA
9756 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9757 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9758 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9759 aux->funtab[nfuns++] = aux->symtab[j];
9760 aux->nfuns = nfuns;
9761 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9762
4d6ed7c8
NC
9763 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9764 {
625d49fc
AM
9765 uint64_t stamp;
9766 uint64_t offset;
2cf0635d
NC
9767 const unsigned char * dp;
9768 const unsigned char * head;
53774b7e 9769 const unsigned char * end;
2cf0635d 9770 const char * procname;
4d6ed7c8 9771
dda8d76d 9772 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9773 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9774
9775 fputs ("\n<", stdout);
9776
9777 if (procname)
9778 {
9779 fputs (procname, stdout);
9780
9781 if (offset)
26c527e6 9782 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9783 }
9784
9785 fputs (">: [", stdout);
9786 print_vma (tp->start.offset, PREFIX_HEX);
9787 fputc ('-', stdout);
9788 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9789 printf ("], info at +0x%" PRIx64 "\n",
9790 tp->info.offset - aux->seg_base);
4d6ed7c8 9791
53774b7e
NC
9792 /* PR 17531: file: 86232b32. */
9793 if (aux->info == NULL)
9794 continue;
9795
97c0a079
AM
9796 offset = tp->info.offset;
9797 if (tp->info.section)
9798 {
9799 if (tp->info.section >= filedata->file_header.e_shnum)
9800 {
26c527e6
AM
9801 warn (_("Invalid section %u in table entry %td\n"),
9802 tp->info.section, tp - aux->table);
015dc7e1 9803 res = false;
97c0a079
AM
9804 continue;
9805 }
9806 offset += filedata->section_headers[tp->info.section].sh_addr;
9807 }
9808 offset -= aux->info_addr;
53774b7e 9809 /* PR 17531: file: 0997b4d1. */
90679903
AM
9810 if (offset >= aux->info_size
9811 || aux->info_size - offset < 8)
53774b7e 9812 {
26c527e6
AM
9813 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9814 tp->info.offset, tp - aux->table);
015dc7e1 9815 res = false;
53774b7e
NC
9816 continue;
9817 }
9818
97c0a079 9819 head = aux->info + offset;
a4a00738 9820 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9821
86f55779 9822 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9823 (unsigned) UNW_VER (stamp),
9824 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9825 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9826 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9827 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9828
9829 if (UNW_VER (stamp) != 1)
9830 {
2b692964 9831 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9832 continue;
9833 }
9834
9835 in_body = 0;
53774b7e
NC
9836 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9837 /* PR 17531: file: 16ceda89. */
9838 if (end > aux->info + aux->info_size)
9839 end = aux->info + aux->info_size;
9840 for (dp = head + 8; dp < end;)
b4477bc8 9841 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9842 }
948f632f
DA
9843
9844 free (aux->funtab);
32ec8896
NC
9845
9846 return res;
4d6ed7c8
NC
9847}
9848
015dc7e1 9849static bool
dda8d76d
NC
9850slurp_ia64_unwind_table (Filedata * filedata,
9851 struct ia64_unw_aux_info * aux,
9852 Elf_Internal_Shdr * sec)
4d6ed7c8 9853{
26c527e6 9854 uint64_t size, nrelas, i;
2cf0635d
NC
9855 Elf_Internal_Phdr * seg;
9856 struct ia64_unw_table_entry * tep;
9857 Elf_Internal_Shdr * relsec;
9858 Elf_Internal_Rela * rela;
9859 Elf_Internal_Rela * rp;
9860 unsigned char * table;
9861 unsigned char * tp;
9862 Elf_Internal_Sym * sym;
9863 const char * relname;
4d6ed7c8 9864
53774b7e
NC
9865 aux->table_len = 0;
9866
4d6ed7c8
NC
9867 /* First, find the starting address of the segment that includes
9868 this section: */
9869
dda8d76d 9870 if (filedata->file_header.e_phnum)
4d6ed7c8 9871 {
dda8d76d 9872 if (! get_program_headers (filedata))
015dc7e1 9873 return false;
4d6ed7c8 9874
dda8d76d
NC
9875 for (seg = filedata->program_headers;
9876 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9877 ++seg)
4d6ed7c8
NC
9878 {
9879 if (seg->p_type != PT_LOAD)
9880 continue;
9881
9882 if (sec->sh_addr >= seg->p_vaddr
9883 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9884 {
9885 aux->seg_base = seg->p_vaddr;
9886 break;
9887 }
9888 }
4d6ed7c8
NC
9889 }
9890
9891 /* Second, build the unwind table from the contents of the unwind section: */
9892 size = sec->sh_size;
dda8d76d 9893 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9894 _("unwind table"));
a6e9f9df 9895 if (!table)
015dc7e1 9896 return false;
4d6ed7c8 9897
53774b7e 9898 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9899 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9900 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9901 tep = aux->table;
53774b7e
NC
9902
9903 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9904 {
9905 tep->start.section = SHN_UNDEF;
9906 tep->end.section = SHN_UNDEF;
9907 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9908 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9909 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9910 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9911 tep->start.offset += aux->seg_base;
9912 tep->end.offset += aux->seg_base;
9913 tep->info.offset += aux->seg_base;
9914 }
9915 free (table);
9916
41e92641 9917 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9918 for (relsec = filedata->section_headers;
9919 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9920 ++relsec)
9921 {
9922 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9923 || relsec->sh_info >= filedata->file_header.e_shnum
9924 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9925 continue;
9926
dda8d76d 9927 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9928 & rela, & nrelas))
53774b7e
NC
9929 {
9930 free (aux->table);
9931 aux->table = NULL;
9932 aux->table_len = 0;
015dc7e1 9933 return false;
53774b7e 9934 }
4d6ed7c8
NC
9935
9936 for (rp = rela; rp < rela + nrelas; ++rp)
9937 {
4770fb94 9938 unsigned int sym_ndx;
726bd37d
AM
9939 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9940 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9941
82b1b41b
NC
9942 /* PR 17531: file: 9fa67536. */
9943 if (relname == NULL)
9944 {
726bd37d 9945 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9946 continue;
9947 }
948f632f 9948
24d127aa 9949 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9950 {
82b1b41b 9951 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9952 continue;
9953 }
9954
89fac5e3 9955 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9956
53774b7e
NC
9957 /* PR 17531: file: 5bc8d9bf. */
9958 if (i >= aux->table_len)
9959 {
26c527e6
AM
9960 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9961 i);
53774b7e
NC
9962 continue;
9963 }
9964
4770fb94
AM
9965 sym_ndx = get_reloc_symindex (rp->r_info);
9966 if (sym_ndx >= aux->nsyms)
9967 {
9968 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9969 sym_ndx);
9970 continue;
9971 }
9972 sym = aux->symtab + sym_ndx;
9973
53774b7e 9974 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9975 {
9976 case 0:
9977 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9978 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9979 break;
9980 case 1:
9981 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9982 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9983 break;
9984 case 2:
9985 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9986 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9987 break;
9988 default:
9989 break;
9990 }
9991 }
9992
9993 free (rela);
9994 }
9995
015dc7e1 9996 return true;
4d6ed7c8
NC
9997}
9998
015dc7e1 9999static bool
dda8d76d 10000ia64_process_unwind (Filedata * filedata)
4d6ed7c8 10001{
2cf0635d
NC
10002 Elf_Internal_Shdr * sec;
10003 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 10004 uint64_t i, unwcount = 0, unwstart = 0;
57346661 10005 struct ia64_unw_aux_info aux;
015dc7e1 10006 bool res = true;
f1467e33 10007
4d6ed7c8
NC
10008 memset (& aux, 0, sizeof (aux));
10009
dda8d76d 10010 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 10011 {
28d13567 10012 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 10013 {
28d13567 10014 if (aux.symtab)
4082ef84 10015 {
28d13567
AM
10016 error (_("Multiple symbol tables encountered\n"));
10017 free (aux.symtab);
10018 aux.symtab = NULL;
4082ef84 10019 free (aux.strtab);
28d13567 10020 aux.strtab = NULL;
4082ef84 10021 }
28d13567
AM
10022 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10023 &aux.strtab, &aux.strtab_size))
015dc7e1 10024 return false;
4d6ed7c8
NC
10025 }
10026 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
10027 unwcount++;
10028 }
10029
10030 if (!unwcount)
10031 printf (_("\nThere are no unwind sections in this file.\n"));
10032
10033 while (unwcount-- > 0)
10034 {
84714f86 10035 const char *suffix;
579f31ac
JJ
10036 size_t len, len2;
10037
dda8d76d
NC
10038 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
10039 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
10040 if (sec->sh_type == SHT_IA_64_UNWIND)
10041 {
10042 unwsec = sec;
10043 break;
10044 }
4082ef84
NC
10045 /* We have already counted the number of SHT_IA64_UNWIND
10046 sections so the loop above should never fail. */
10047 assert (unwsec != NULL);
579f31ac
JJ
10048
10049 unwstart = i + 1;
10050 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
10051
e4b17d5c
L
10052 if ((unwsec->sh_flags & SHF_GROUP) != 0)
10053 {
10054 /* We need to find which section group it is in. */
4082ef84 10055 struct group_list * g;
e4b17d5c 10056
978c4450
AM
10057 if (filedata->section_headers_groups == NULL
10058 || filedata->section_headers_groups[i] == NULL)
dda8d76d 10059 i = filedata->file_header.e_shnum;
4082ef84 10060 else
e4b17d5c 10061 {
978c4450 10062 g = filedata->section_headers_groups[i]->root;
18bd398b 10063
4082ef84
NC
10064 for (; g != NULL; g = g->next)
10065 {
dda8d76d 10066 sec = filedata->section_headers + g->section_index;
e4b17d5c 10067
84714f86
AM
10068 if (section_name_valid (filedata, sec)
10069 && streq (section_name (filedata, sec),
10070 ELF_STRING_ia64_unwind_info))
4082ef84
NC
10071 break;
10072 }
10073
10074 if (g == NULL)
dda8d76d 10075 i = filedata->file_header.e_shnum;
4082ef84 10076 }
e4b17d5c 10077 }
84714f86
AM
10078 else if (section_name_valid (filedata, unwsec)
10079 && startswith (section_name (filedata, unwsec),
e9b095a5 10080 ELF_STRING_ia64_unwind_once))
579f31ac 10081 {
18bd398b 10082 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 10083 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 10084 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
10085 for (i = 0, sec = filedata->section_headers;
10086 i < filedata->file_header.e_shnum;
579f31ac 10087 ++i, ++sec)
84714f86
AM
10088 if (section_name_valid (filedata, sec)
10089 && startswith (section_name (filedata, sec),
e9b095a5 10090 ELF_STRING_ia64_unwind_info_once)
84714f86 10091 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
10092 break;
10093 }
10094 else
10095 {
10096 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 10097 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
10098 len = sizeof (ELF_STRING_ia64_unwind) - 1;
10099 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
10100 suffix = "";
84714f86
AM
10101 if (section_name_valid (filedata, unwsec)
10102 && startswith (section_name (filedata, unwsec),
10103 ELF_STRING_ia64_unwind))
10104 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
10105 for (i = 0, sec = filedata->section_headers;
10106 i < filedata->file_header.e_shnum;
579f31ac 10107 ++i, ++sec)
84714f86
AM
10108 if (section_name_valid (filedata, sec)
10109 && startswith (section_name (filedata, sec),
10110 ELF_STRING_ia64_unwind_info)
10111 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
10112 break;
10113 }
10114
dda8d76d 10115 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
10116 {
10117 printf (_("\nCould not find unwind info section for "));
10118
dda8d76d 10119 if (filedata->string_table == NULL)
579f31ac
JJ
10120 printf ("%d", unwsec->sh_name);
10121 else
dda8d76d 10122 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
10123 }
10124 else
4d6ed7c8 10125 {
4d6ed7c8 10126 aux.info_addr = sec->sh_addr;
dda8d76d 10127 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
10128 sec->sh_size,
10129 _("unwind info"));
59245841 10130 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 10131
579f31ac 10132 printf (_("\nUnwind section "));
4d6ed7c8 10133
dda8d76d 10134 if (filedata->string_table == NULL)
579f31ac
JJ
10135 printf ("%d", unwsec->sh_name);
10136 else
dda8d76d 10137 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 10138
26c527e6
AM
10139 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
10140 unwsec->sh_offset,
10141 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 10142
dda8d76d 10143 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 10144 && aux.table_len > 0)
dda8d76d 10145 dump_ia64_unwind (filedata, & aux);
579f31ac 10146
9db70fc3
AM
10147 free ((char *) aux.table);
10148 free ((char *) aux.info);
579f31ac
JJ
10149 aux.table = NULL;
10150 aux.info = NULL;
10151 }
4d6ed7c8 10152 }
4d6ed7c8 10153
9db70fc3
AM
10154 free (aux.symtab);
10155 free ((char *) aux.strtab);
32ec8896
NC
10156
10157 return res;
4d6ed7c8
NC
10158}
10159
3f5e193b 10160struct hppa_unw_table_entry
32ec8896
NC
10161{
10162 struct absaddr start;
10163 struct absaddr end;
10164 unsigned int Cannot_unwind:1; /* 0 */
10165 unsigned int Millicode:1; /* 1 */
10166 unsigned int Millicode_save_sr0:1; /* 2 */
10167 unsigned int Region_description:2; /* 3..4 */
10168 unsigned int reserved1:1; /* 5 */
10169 unsigned int Entry_SR:1; /* 6 */
10170 unsigned int Entry_FR:4; /* Number saved 7..10 */
10171 unsigned int Entry_GR:5; /* Number saved 11..15 */
10172 unsigned int Args_stored:1; /* 16 */
10173 unsigned int Variable_Frame:1; /* 17 */
10174 unsigned int Separate_Package_Body:1; /* 18 */
10175 unsigned int Frame_Extension_Millicode:1; /* 19 */
10176 unsigned int Stack_Overflow_Check:1; /* 20 */
10177 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
10178 unsigned int Ada_Region:1; /* 22 */
10179 unsigned int cxx_info:1; /* 23 */
10180 unsigned int cxx_try_catch:1; /* 24 */
10181 unsigned int sched_entry_seq:1; /* 25 */
10182 unsigned int reserved2:1; /* 26 */
10183 unsigned int Save_SP:1; /* 27 */
10184 unsigned int Save_RP:1; /* 28 */
10185 unsigned int Save_MRP_in_frame:1; /* 29 */
10186 unsigned int extn_ptr_defined:1; /* 30 */
10187 unsigned int Cleanup_defined:1; /* 31 */
10188
10189 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
10190 unsigned int HP_UX_interrupt_marker:1; /* 1 */
10191 unsigned int Large_frame:1; /* 2 */
10192 unsigned int Pseudo_SP_Set:1; /* 3 */
10193 unsigned int reserved4:1; /* 4 */
10194 unsigned int Total_frame_size:27; /* 5..31 */
10195};
3f5e193b 10196
57346661 10197struct hppa_unw_aux_info
948f632f 10198{
32ec8896 10199 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 10200 uint64_t table_len; /* Length of unwind table. */
625d49fc 10201 uint64_t seg_base; /* Starting address of segment. */
32ec8896 10202 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 10203 uint64_t nsyms; /* Number of symbols. */
32ec8896 10204 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10205 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 10206 char * strtab; /* The string table. */
26c527e6 10207 uint64_t strtab_size; /* Size of string table. */
948f632f 10208};
57346661 10209
015dc7e1 10210static bool
dda8d76d 10211dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 10212{
2cf0635d 10213 struct hppa_unw_table_entry * tp;
26c527e6 10214 uint64_t j, nfuns;
015dc7e1 10215 bool res = true;
948f632f
DA
10216
10217 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10218 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10219 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10220 aux->funtab[nfuns++] = aux->symtab[j];
10221 aux->nfuns = nfuns;
10222 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 10223
57346661
AM
10224 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
10225 {
625d49fc 10226 uint64_t offset;
2cf0635d 10227 const char * procname;
57346661 10228
dda8d76d 10229 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
10230 aux->strtab_size, tp->start, &procname,
10231 &offset);
10232
10233 fputs ("\n<", stdout);
10234
10235 if (procname)
10236 {
10237 fputs (procname, stdout);
10238
10239 if (offset)
26c527e6 10240 printf ("+%" PRIx64, offset);
57346661
AM
10241 }
10242
10243 fputs (">: [", stdout);
10244 print_vma (tp->start.offset, PREFIX_HEX);
10245 fputc ('-', stdout);
10246 print_vma (tp->end.offset, PREFIX_HEX);
10247 printf ("]\n\t");
10248
18bd398b
NC
10249#define PF(_m) if (tp->_m) printf (#_m " ");
10250#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
10251 PF(Cannot_unwind);
10252 PF(Millicode);
10253 PF(Millicode_save_sr0);
18bd398b 10254 /* PV(Region_description); */
57346661
AM
10255 PF(Entry_SR);
10256 PV(Entry_FR);
10257 PV(Entry_GR);
10258 PF(Args_stored);
10259 PF(Variable_Frame);
10260 PF(Separate_Package_Body);
10261 PF(Frame_Extension_Millicode);
10262 PF(Stack_Overflow_Check);
10263 PF(Two_Instruction_SP_Increment);
10264 PF(Ada_Region);
10265 PF(cxx_info);
10266 PF(cxx_try_catch);
10267 PF(sched_entry_seq);
10268 PF(Save_SP);
10269 PF(Save_RP);
10270 PF(Save_MRP_in_frame);
10271 PF(extn_ptr_defined);
10272 PF(Cleanup_defined);
10273 PF(MPE_XL_interrupt_marker);
10274 PF(HP_UX_interrupt_marker);
10275 PF(Large_frame);
10276 PF(Pseudo_SP_Set);
10277 PV(Total_frame_size);
10278#undef PF
10279#undef PV
10280 }
10281
18bd398b 10282 printf ("\n");
948f632f
DA
10283
10284 free (aux->funtab);
32ec8896
NC
10285
10286 return res;
57346661
AM
10287}
10288
015dc7e1 10289static bool
dda8d76d
NC
10290slurp_hppa_unwind_table (Filedata * filedata,
10291 struct hppa_unw_aux_info * aux,
10292 Elf_Internal_Shdr * sec)
57346661 10293{
26c527e6 10294 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
10295 Elf_Internal_Phdr * seg;
10296 struct hppa_unw_table_entry * tep;
10297 Elf_Internal_Shdr * relsec;
10298 Elf_Internal_Rela * rela;
10299 Elf_Internal_Rela * rp;
10300 unsigned char * table;
10301 unsigned char * tp;
10302 Elf_Internal_Sym * sym;
10303 const char * relname;
57346661 10304
57346661
AM
10305 /* First, find the starting address of the segment that includes
10306 this section. */
dda8d76d 10307 if (filedata->file_header.e_phnum)
57346661 10308 {
dda8d76d 10309 if (! get_program_headers (filedata))
015dc7e1 10310 return false;
57346661 10311
dda8d76d
NC
10312 for (seg = filedata->program_headers;
10313 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
10314 ++seg)
10315 {
10316 if (seg->p_type != PT_LOAD)
10317 continue;
10318
10319 if (sec->sh_addr >= seg->p_vaddr
10320 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10321 {
10322 aux->seg_base = seg->p_vaddr;
10323 break;
10324 }
10325 }
10326 }
10327
10328 /* Second, build the unwind table from the contents of the unwind
10329 section. */
10330 size = sec->sh_size;
dda8d76d 10331 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 10332 _("unwind table"));
57346661 10333 if (!table)
015dc7e1 10334 return false;
57346661 10335
1c0751b2
DA
10336 unw_ent_size = 16;
10337 nentries = size / unw_ent_size;
10338 size = unw_ent_size * nentries;
57346661 10339
e3fdc001 10340 aux->table_len = nentries;
3f5e193b
NC
10341 tep = aux->table = (struct hppa_unw_table_entry *)
10342 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 10343
1c0751b2 10344 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
10345 {
10346 unsigned int tmp1, tmp2;
10347
10348 tep->start.section = SHN_UNDEF;
10349 tep->end.section = SHN_UNDEF;
10350
1c0751b2
DA
10351 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10352 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10353 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10354 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10355
10356 tep->start.offset += aux->seg_base;
10357 tep->end.offset += aux->seg_base;
57346661
AM
10358
10359 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10360 tep->Millicode = (tmp1 >> 30) & 0x1;
10361 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10362 tep->Region_description = (tmp1 >> 27) & 0x3;
10363 tep->reserved1 = (tmp1 >> 26) & 0x1;
10364 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10365 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10366 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10367 tep->Args_stored = (tmp1 >> 15) & 0x1;
10368 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10369 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10370 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10371 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10372 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10373 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10374 tep->cxx_info = (tmp1 >> 8) & 0x1;
10375 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10376 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10377 tep->reserved2 = (tmp1 >> 5) & 0x1;
10378 tep->Save_SP = (tmp1 >> 4) & 0x1;
10379 tep->Save_RP = (tmp1 >> 3) & 0x1;
10380 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10381 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10382 tep->Cleanup_defined = tmp1 & 0x1;
10383
10384 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10385 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10386 tep->Large_frame = (tmp2 >> 29) & 0x1;
10387 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10388 tep->reserved4 = (tmp2 >> 27) & 0x1;
10389 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
10390 }
10391 free (table);
10392
10393 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
10394 for (relsec = filedata->section_headers;
10395 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
10396 ++relsec)
10397 {
10398 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
10399 || relsec->sh_info >= filedata->file_header.e_shnum
10400 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
10401 continue;
10402
dda8d76d 10403 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 10404 & rela, & nrelas))
015dc7e1 10405 return false;
57346661
AM
10406
10407 for (rp = rela; rp < rela + nrelas; ++rp)
10408 {
4770fb94 10409 unsigned int sym_ndx;
726bd37d
AM
10410 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10411 relname = elf_hppa_reloc_type (r_type);
57346661 10412
726bd37d
AM
10413 if (relname == NULL)
10414 {
10415 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10416 continue;
10417 }
10418
57346661 10419 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 10420 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 10421 {
726bd37d 10422 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
10423 continue;
10424 }
10425
10426 i = rp->r_offset / unw_ent_size;
726bd37d
AM
10427 if (i >= aux->table_len)
10428 {
26c527e6
AM
10429 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10430 i);
726bd37d
AM
10431 continue;
10432 }
57346661 10433
4770fb94
AM
10434 sym_ndx = get_reloc_symindex (rp->r_info);
10435 if (sym_ndx >= aux->nsyms)
10436 {
10437 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10438 sym_ndx);
10439 continue;
10440 }
10441 sym = aux->symtab + sym_ndx;
10442
43f6cd05 10443 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
10444 {
10445 case 0:
10446 aux->table[i].start.section = sym->st_shndx;
1e456d54 10447 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
10448 break;
10449 case 1:
10450 aux->table[i].end.section = sym->st_shndx;
1e456d54 10451 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
10452 break;
10453 default:
10454 break;
10455 }
10456 }
10457
10458 free (rela);
10459 }
10460
015dc7e1 10461 return true;
57346661
AM
10462}
10463
015dc7e1 10464static bool
dda8d76d 10465hppa_process_unwind (Filedata * filedata)
57346661 10466{
57346661 10467 struct hppa_unw_aux_info aux;
2cf0635d 10468 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 10469 Elf_Internal_Shdr * sec;
26c527e6 10470 size_t i;
015dc7e1 10471 bool res = true;
57346661 10472
dda8d76d 10473 if (filedata->string_table == NULL)
015dc7e1 10474 return false;
1b31d05e
NC
10475
10476 memset (& aux, 0, sizeof (aux));
57346661 10477
dda8d76d 10478 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10479 {
28d13567 10480 if (sec->sh_type == SHT_SYMTAB)
57346661 10481 {
28d13567 10482 if (aux.symtab)
4082ef84 10483 {
28d13567
AM
10484 error (_("Multiple symbol tables encountered\n"));
10485 free (aux.symtab);
10486 aux.symtab = NULL;
4082ef84 10487 free (aux.strtab);
28d13567 10488 aux.strtab = NULL;
4082ef84 10489 }
28d13567
AM
10490 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10491 &aux.strtab, &aux.strtab_size))
015dc7e1 10492 return false;
57346661 10493 }
84714f86
AM
10494 else if (section_name_valid (filedata, sec)
10495 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
10496 unwsec = sec;
10497 }
10498
10499 if (!unwsec)
10500 printf (_("\nThere are no unwind sections in this file.\n"));
10501
dda8d76d 10502 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10503 {
84714f86
AM
10504 if (section_name_valid (filedata, sec)
10505 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 10506 {
26c527e6 10507 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 10508
26c527e6
AM
10509 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10510 "contains %" PRIu64 " entry:\n",
10511 "\nUnwind section '%s' at offset %#" PRIx64 " "
10512 "contains %" PRIu64 " entries:\n",
d3a49aa8 10513 num_unwind),
dda8d76d 10514 printable_section_name (filedata, sec),
26c527e6 10515 sec->sh_offset,
d3a49aa8 10516 num_unwind);
57346661 10517
dda8d76d 10518 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 10519 res = false;
66b09c7e
S
10520
10521 if (res && aux.table_len > 0)
32ec8896 10522 {
dda8d76d 10523 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 10524 res = false;
32ec8896 10525 }
57346661 10526
9db70fc3 10527 free ((char *) aux.table);
57346661
AM
10528 aux.table = NULL;
10529 }
10530 }
10531
9db70fc3
AM
10532 free (aux.symtab);
10533 free ((char *) aux.strtab);
32ec8896
NC
10534
10535 return res;
57346661
AM
10536}
10537
0b6ae522
DJ
10538struct arm_section
10539{
a734115a
NC
10540 unsigned char * data; /* The unwind data. */
10541 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10542 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 10543 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
10544 unsigned int rel_type; /* REL or RELA ? */
10545 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
10546};
10547
10548struct arm_unw_aux_info
10549{
dda8d76d 10550 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 10551 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 10552 uint64_t nsyms; /* Number of symbols. */
948f632f 10553 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10554 uint64_t nfuns; /* Number of these symbols. */
a734115a 10555 char * strtab; /* The file's string table. */
26c527e6 10556 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
10557};
10558
10559static const char *
dda8d76d
NC
10560arm_print_vma_and_name (Filedata * filedata,
10561 struct arm_unw_aux_info * aux,
625d49fc 10562 uint64_t fn,
dda8d76d 10563 struct absaddr addr)
0b6ae522
DJ
10564{
10565 const char *procname;
625d49fc 10566 uint64_t sym_offset;
0b6ae522
DJ
10567
10568 if (addr.section == SHN_UNDEF)
10569 addr.offset = fn;
10570
dda8d76d 10571 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
10572 aux->strtab_size, addr, &procname,
10573 &sym_offset);
10574
10575 print_vma (fn, PREFIX_HEX);
10576
10577 if (procname)
10578 {
10579 fputs (" <", stdout);
10580 fputs (procname, stdout);
10581
10582 if (sym_offset)
26c527e6 10583 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10584 fputc ('>', stdout);
10585 }
10586
10587 return procname;
10588}
10589
10590static void
10591arm_free_section (struct arm_section *arm_sec)
10592{
9db70fc3
AM
10593 free (arm_sec->data);
10594 free (arm_sec->rela);
0b6ae522
DJ
10595}
10596
a734115a
NC
10597/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10598 cached section and install SEC instead.
10599 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10600 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10601 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10602 relocation's offset in ADDR.
1b31d05e
NC
10603 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10604 into the string table of the symbol associated with the reloc. If no
10605 reloc was applied store -1 there.
10606 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10607
015dc7e1 10608static bool
dda8d76d
NC
10609get_unwind_section_word (Filedata * filedata,
10610 struct arm_unw_aux_info * aux,
1b31d05e
NC
10611 struct arm_section * arm_sec,
10612 Elf_Internal_Shdr * sec,
625d49fc 10613 uint64_t word_offset,
1b31d05e
NC
10614 unsigned int * wordp,
10615 struct absaddr * addr,
625d49fc 10616 uint64_t * sym_name)
0b6ae522
DJ
10617{
10618 Elf_Internal_Rela *rp;
10619 Elf_Internal_Sym *sym;
10620 const char * relname;
10621 unsigned int word;
015dc7e1 10622 bool wrapped;
0b6ae522 10623
e0a31db1 10624 if (sec == NULL || arm_sec == NULL)
015dc7e1 10625 return false;
e0a31db1 10626
0b6ae522
DJ
10627 addr->section = SHN_UNDEF;
10628 addr->offset = 0;
10629
1b31d05e 10630 if (sym_name != NULL)
625d49fc 10631 *sym_name = (uint64_t) -1;
1b31d05e 10632
a734115a 10633 /* If necessary, update the section cache. */
0b6ae522
DJ
10634 if (sec != arm_sec->sec)
10635 {
10636 Elf_Internal_Shdr *relsec;
10637
10638 arm_free_section (arm_sec);
10639
10640 arm_sec->sec = sec;
dda8d76d 10641 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10642 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10643 arm_sec->rela = NULL;
10644 arm_sec->nrelas = 0;
10645
dda8d76d
NC
10646 for (relsec = filedata->section_headers;
10647 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10648 ++relsec)
10649 {
dda8d76d
NC
10650 if (relsec->sh_info >= filedata->file_header.e_shnum
10651 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10652 /* PR 15745: Check the section type as well. */
10653 || (relsec->sh_type != SHT_REL
10654 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10655 continue;
10656
a734115a 10657 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10658 if (relsec->sh_type == SHT_REL)
10659 {
dda8d76d 10660 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10661 relsec->sh_size,
10662 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10663 return false;
0b6ae522 10664 }
1ae40aa4 10665 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10666 {
dda8d76d 10667 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10668 relsec->sh_size,
10669 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10670 return false;
0b6ae522 10671 }
1ae40aa4 10672 break;
0b6ae522
DJ
10673 }
10674
10675 arm_sec->next_rela = arm_sec->rela;
10676 }
10677
a734115a 10678 /* If there is no unwind data we can do nothing. */
0b6ae522 10679 if (arm_sec->data == NULL)
015dc7e1 10680 return false;
0b6ae522 10681
e0a31db1 10682 /* If the offset is invalid then fail. */
f32ba729
NC
10683 if (/* PR 21343 *//* PR 18879 */
10684 sec->sh_size < 4
625d49fc 10685 || word_offset > sec->sh_size - 4)
015dc7e1 10686 return false;
e0a31db1 10687
a734115a 10688 /* Get the word at the required offset. */
0b6ae522
DJ
10689 word = byte_get (arm_sec->data + word_offset, 4);
10690
0eff7165
NC
10691 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10692 if (arm_sec->rela == NULL)
10693 {
10694 * wordp = word;
015dc7e1 10695 return true;
0eff7165
NC
10696 }
10697
a734115a 10698 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10699 wrapped = false;
0b6ae522
DJ
10700 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10701 {
625d49fc 10702 uint64_t prelval, offset;
0b6ae522
DJ
10703
10704 if (rp->r_offset > word_offset && !wrapped)
10705 {
10706 rp = arm_sec->rela;
015dc7e1 10707 wrapped = true;
0b6ae522
DJ
10708 }
10709 if (rp->r_offset > word_offset)
10710 break;
10711
10712 if (rp->r_offset & 3)
10713 {
26c527e6
AM
10714 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10715 rp->r_offset);
0b6ae522
DJ
10716 continue;
10717 }
10718
10719 if (rp->r_offset < word_offset)
10720 continue;
10721
74e1a04b
NC
10722 /* PR 17531: file: 027-161405-0.004 */
10723 if (aux->symtab == NULL)
10724 continue;
10725
0b6ae522
DJ
10726 if (arm_sec->rel_type == SHT_REL)
10727 {
10728 offset = word & 0x7fffffff;
10729 if (offset & 0x40000000)
625d49fc 10730 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10731 }
a734115a 10732 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10733 offset = rp->r_addend;
a734115a 10734 else
74e1a04b
NC
10735 {
10736 error (_("Unknown section relocation type %d encountered\n"),
10737 arm_sec->rel_type);
10738 break;
10739 }
0b6ae522 10740
071436c6
NC
10741 /* PR 17531 file: 027-1241568-0.004. */
10742 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10743 {
26c527e6
AM
10744 error (_("Bad symbol index in unwind relocation "
10745 "(%" PRIu64 " > %" PRIu64 ")\n"),
10746 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10747 break;
10748 }
10749
10750 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10751 offset += sym->st_value;
10752 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10753
a734115a 10754 /* Check that we are processing the expected reloc type. */
dda8d76d 10755 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10756 {
10757 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10758 if (relname == NULL)
10759 {
10760 warn (_("Skipping unknown ARM relocation type: %d\n"),
10761 (int) ELF32_R_TYPE (rp->r_info));
10762 continue;
10763 }
a734115a
NC
10764
10765 if (streq (relname, "R_ARM_NONE"))
10766 continue;
0b4362b0 10767
a734115a
NC
10768 if (! streq (relname, "R_ARM_PREL31"))
10769 {
071436c6 10770 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10771 continue;
10772 }
10773 }
dda8d76d 10774 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10775 {
10776 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10777 if (relname == NULL)
10778 {
10779 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10780 (int) ELF32_R_TYPE (rp->r_info));
10781 continue;
10782 }
0b4362b0 10783
a734115a
NC
10784 if (streq (relname, "R_C6000_NONE"))
10785 continue;
10786
10787 if (! streq (relname, "R_C6000_PREL31"))
10788 {
071436c6 10789 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10790 continue;
10791 }
10792
10793 prelval >>= 1;
10794 }
10795 else
74e1a04b
NC
10796 {
10797 /* This function currently only supports ARM and TI unwinders. */
10798 warn (_("Only TI and ARM unwinders are currently supported\n"));
10799 break;
10800 }
fa197c1c 10801
625d49fc 10802 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10803 addr->section = sym->st_shndx;
10804 addr->offset = offset;
74e1a04b 10805
1b31d05e
NC
10806 if (sym_name)
10807 * sym_name = sym->st_name;
0b6ae522
DJ
10808 break;
10809 }
10810
10811 *wordp = word;
10812 arm_sec->next_rela = rp;
10813
015dc7e1 10814 return true;
0b6ae522
DJ
10815}
10816
a734115a
NC
10817static const char *tic6x_unwind_regnames[16] =
10818{
0b4362b0
RM
10819 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10820 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10821 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10822};
fa197c1c 10823
0b6ae522 10824static void
fa197c1c 10825decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10826{
fa197c1c
PB
10827 int i;
10828
10829 for (i = 12; mask; mask >>= 1, i--)
10830 {
10831 if (mask & 1)
10832 {
10833 fputs (tic6x_unwind_regnames[i], stdout);
10834 if (mask > 1)
10835 fputs (", ", stdout);
10836 }
10837 }
10838}
0b6ae522
DJ
10839
10840#define ADVANCE \
10841 if (remaining == 0 && more_words) \
10842 { \
10843 data_offset += 4; \
dda8d76d 10844 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10845 data_offset, & word, & addr, NULL)) \
015dc7e1 10846 return false; \
0b6ae522
DJ
10847 remaining = 4; \
10848 more_words--; \
10849 } \
10850
10851#define GET_OP(OP) \
10852 ADVANCE; \
10853 if (remaining) \
10854 { \
10855 remaining--; \
10856 (OP) = word >> 24; \
10857 word <<= 8; \
10858 } \
10859 else \
10860 { \
2b692964 10861 printf (_("[Truncated opcode]\n")); \
015dc7e1 10862 return false; \
0b6ae522 10863 } \
cc5914eb 10864 printf ("0x%02x ", OP)
0b6ae522 10865
015dc7e1 10866static bool
dda8d76d
NC
10867decode_arm_unwind_bytecode (Filedata * filedata,
10868 struct arm_unw_aux_info * aux,
948f632f
DA
10869 unsigned int word,
10870 unsigned int remaining,
10871 unsigned int more_words,
625d49fc 10872 uint64_t data_offset,
948f632f
DA
10873 Elf_Internal_Shdr * data_sec,
10874 struct arm_section * data_arm_sec)
fa197c1c
PB
10875{
10876 struct absaddr addr;
015dc7e1 10877 bool res = true;
0b6ae522
DJ
10878
10879 /* Decode the unwinding instructions. */
10880 while (1)
10881 {
10882 unsigned int op, op2;
10883
10884 ADVANCE;
10885 if (remaining == 0)
10886 break;
10887 remaining--;
10888 op = word >> 24;
10889 word <<= 8;
10890
cc5914eb 10891 printf (" 0x%02x ", op);
0b6ae522
DJ
10892
10893 if ((op & 0xc0) == 0x00)
10894 {
10895 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10896
cc5914eb 10897 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10898 }
10899 else if ((op & 0xc0) == 0x40)
10900 {
10901 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10902
cc5914eb 10903 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10904 }
10905 else if ((op & 0xf0) == 0x80)
10906 {
10907 GET_OP (op2);
10908 if (op == 0x80 && op2 == 0)
10909 printf (_("Refuse to unwind"));
10910 else
10911 {
10912 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10913 bool first = true;
0b6ae522 10914 int i;
2b692964 10915
0b6ae522
DJ
10916 printf ("pop {");
10917 for (i = 0; i < 12; i++)
10918 if (mask & (1 << i))
10919 {
10920 if (first)
015dc7e1 10921 first = false;
0b6ae522
DJ
10922 else
10923 printf (", ");
10924 printf ("r%d", 4 + i);
10925 }
10926 printf ("}");
10927 }
10928 }
10929 else if ((op & 0xf0) == 0x90)
10930 {
10931 if (op == 0x9d || op == 0x9f)
10932 printf (_(" [Reserved]"));
10933 else
cc5914eb 10934 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10935 }
10936 else if ((op & 0xf0) == 0xa0)
10937 {
10938 int end = 4 + (op & 0x07);
015dc7e1 10939 bool first = true;
0b6ae522 10940 int i;
61865e30 10941
0b6ae522
DJ
10942 printf (" pop {");
10943 for (i = 4; i <= end; i++)
10944 {
10945 if (first)
015dc7e1 10946 first = false;
0b6ae522
DJ
10947 else
10948 printf (", ");
10949 printf ("r%d", i);
10950 }
10951 if (op & 0x08)
10952 {
1b31d05e 10953 if (!first)
0b6ae522
DJ
10954 printf (", ");
10955 printf ("r14");
10956 }
10957 printf ("}");
10958 }
10959 else if (op == 0xb0)
10960 printf (_(" finish"));
10961 else if (op == 0xb1)
10962 {
10963 GET_OP (op2);
10964 if (op2 == 0 || (op2 & 0xf0) != 0)
10965 printf (_("[Spare]"));
10966 else
10967 {
10968 unsigned int mask = op2 & 0x0f;
015dc7e1 10969 bool first = true;
0b6ae522 10970 int i;
61865e30 10971
0b6ae522
DJ
10972 printf ("pop {");
10973 for (i = 0; i < 12; i++)
10974 if (mask & (1 << i))
10975 {
10976 if (first)
015dc7e1 10977 first = false;
0b6ae522
DJ
10978 else
10979 printf (", ");
10980 printf ("r%d", i);
10981 }
10982 printf ("}");
10983 }
10984 }
10985 else if (op == 0xb2)
10986 {
b115cf96 10987 unsigned char buf[9];
0b6ae522 10988 unsigned int i, len;
26c527e6 10989 uint64_t offset;
61865e30 10990
b115cf96 10991 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10992 {
10993 GET_OP (buf[i]);
10994 if ((buf[i] & 0x80) == 0)
10995 break;
10996 }
4082ef84 10997 if (i == sizeof (buf))
32ec8896 10998 {
27a45f42 10999 error (_("corrupt change to vsp\n"));
015dc7e1 11000 res = false;
32ec8896 11001 }
4082ef84
NC
11002 else
11003 {
015dc7e1 11004 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
11005 assert (len == i + 1);
11006 offset = offset * 4 + 0x204;
26c527e6 11007 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 11008 }
0b6ae522 11009 }
61865e30 11010 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 11011 {
61865e30
NC
11012 unsigned int first, last;
11013
11014 GET_OP (op2);
11015 first = op2 >> 4;
11016 last = op2 & 0x0f;
11017 if (op == 0xc8)
11018 first = first + 16;
11019 printf ("pop {D%d", first);
11020 if (last)
11021 printf ("-D%d", first + last);
11022 printf ("}");
11023 }
09854a88
TB
11024 else if (op == 0xb4)
11025 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
11026 else if (op == 0xb5)
11027 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
11028 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
11029 {
11030 unsigned int count = op & 0x07;
11031
11032 printf ("pop {D8");
11033 if (count)
11034 printf ("-D%d", 8 + count);
11035 printf ("}");
11036 }
11037 else if (op >= 0xc0 && op <= 0xc5)
11038 {
11039 unsigned int count = op & 0x07;
11040
11041 printf (" pop {wR10");
11042 if (count)
11043 printf ("-wR%d", 10 + count);
11044 printf ("}");
11045 }
11046 else if (op == 0xc6)
11047 {
11048 unsigned int first, last;
11049
11050 GET_OP (op2);
11051 first = op2 >> 4;
11052 last = op2 & 0x0f;
11053 printf ("pop {wR%d", first);
11054 if (last)
11055 printf ("-wR%d", first + last);
11056 printf ("}");
11057 }
11058 else if (op == 0xc7)
11059 {
11060 GET_OP (op2);
11061 if (op2 == 0 || (op2 & 0xf0) != 0)
11062 printf (_("[Spare]"));
0b6ae522
DJ
11063 else
11064 {
61865e30 11065 unsigned int mask = op2 & 0x0f;
015dc7e1 11066 bool first = true;
61865e30
NC
11067 int i;
11068
11069 printf ("pop {");
11070 for (i = 0; i < 4; i++)
11071 if (mask & (1 << i))
11072 {
11073 if (first)
015dc7e1 11074 first = false;
61865e30
NC
11075 else
11076 printf (", ");
11077 printf ("wCGR%d", i);
11078 }
11079 printf ("}");
0b6ae522
DJ
11080 }
11081 }
61865e30 11082 else
32ec8896
NC
11083 {
11084 printf (_(" [unsupported opcode]"));
015dc7e1 11085 res = false;
32ec8896
NC
11086 }
11087
0b6ae522
DJ
11088 printf ("\n");
11089 }
32ec8896
NC
11090
11091 return res;
fa197c1c
PB
11092}
11093
015dc7e1 11094static bool
dda8d76d
NC
11095decode_tic6x_unwind_bytecode (Filedata * filedata,
11096 struct arm_unw_aux_info * aux,
948f632f
DA
11097 unsigned int word,
11098 unsigned int remaining,
11099 unsigned int more_words,
625d49fc 11100 uint64_t data_offset,
948f632f
DA
11101 Elf_Internal_Shdr * data_sec,
11102 struct arm_section * data_arm_sec)
fa197c1c
PB
11103{
11104 struct absaddr addr;
11105
11106 /* Decode the unwinding instructions. */
11107 while (1)
11108 {
11109 unsigned int op, op2;
11110
11111 ADVANCE;
11112 if (remaining == 0)
11113 break;
11114 remaining--;
11115 op = word >> 24;
11116 word <<= 8;
11117
9cf03b7e 11118 printf (" 0x%02x ", op);
fa197c1c
PB
11119
11120 if ((op & 0xc0) == 0x00)
11121 {
11122 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 11123 printf (" sp = sp + %d", offset);
fa197c1c
PB
11124 }
11125 else if ((op & 0xc0) == 0x80)
11126 {
11127 GET_OP (op2);
11128 if (op == 0x80 && op2 == 0)
11129 printf (_("Refuse to unwind"));
11130 else
11131 {
11132 unsigned int mask = ((op & 0x1f) << 8) | op2;
11133 if (op & 0x20)
11134 printf ("pop compact {");
11135 else
11136 printf ("pop {");
11137
11138 decode_tic6x_unwind_regmask (mask);
11139 printf("}");
11140 }
11141 }
11142 else if ((op & 0xf0) == 0xc0)
11143 {
11144 unsigned int reg;
11145 unsigned int nregs;
11146 unsigned int i;
11147 const char *name;
a734115a
NC
11148 struct
11149 {
32ec8896
NC
11150 unsigned int offset;
11151 unsigned int reg;
fa197c1c
PB
11152 } regpos[16];
11153
11154 /* Scan entire instruction first so that GET_OP output is not
11155 interleaved with disassembly. */
11156 nregs = 0;
11157 for (i = 0; nregs < (op & 0xf); i++)
11158 {
11159 GET_OP (op2);
11160 reg = op2 >> 4;
11161 if (reg != 0xf)
11162 {
11163 regpos[nregs].offset = i * 2;
11164 regpos[nregs].reg = reg;
11165 nregs++;
11166 }
11167
11168 reg = op2 & 0xf;
11169 if (reg != 0xf)
11170 {
11171 regpos[nregs].offset = i * 2 + 1;
11172 regpos[nregs].reg = reg;
11173 nregs++;
11174 }
11175 }
11176
11177 printf (_("pop frame {"));
18344509 11178 if (nregs == 0)
fa197c1c 11179 {
18344509
NC
11180 printf (_("*corrupt* - no registers specified"));
11181 }
11182 else
11183 {
11184 reg = nregs - 1;
11185 for (i = i * 2; i > 0; i--)
fa197c1c 11186 {
18344509
NC
11187 if (regpos[reg].offset == i - 1)
11188 {
11189 name = tic6x_unwind_regnames[regpos[reg].reg];
11190 if (reg > 0)
11191 reg--;
11192 }
11193 else
11194 name = _("[pad]");
fa197c1c 11195
18344509
NC
11196 fputs (name, stdout);
11197 if (i > 1)
11198 printf (", ");
11199 }
fa197c1c
PB
11200 }
11201
11202 printf ("}");
11203 }
11204 else if (op == 0xd0)
11205 printf (" MOV FP, SP");
11206 else if (op == 0xd1)
11207 printf (" __c6xabi_pop_rts");
11208 else if (op == 0xd2)
11209 {
11210 unsigned char buf[9];
11211 unsigned int i, len;
26c527e6 11212 uint64_t offset;
a734115a 11213
fa197c1c
PB
11214 for (i = 0; i < sizeof (buf); i++)
11215 {
11216 GET_OP (buf[i]);
11217 if ((buf[i] & 0x80) == 0)
11218 break;
11219 }
0eff7165
NC
11220 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
11221 if (i == sizeof (buf))
11222 {
0eff7165 11223 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 11224 return false;
0eff7165 11225 }
948f632f 11226
015dc7e1 11227 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
11228 assert (len == i + 1);
11229 offset = offset * 8 + 0x408;
26c527e6 11230 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
11231 }
11232 else if ((op & 0xf0) == 0xe0)
11233 {
11234 if ((op & 0x0f) == 7)
11235 printf (" RETURN");
11236 else
11237 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
11238 }
11239 else
11240 {
11241 printf (_(" [unsupported opcode]"));
11242 }
11243 putchar ('\n');
11244 }
32ec8896 11245
015dc7e1 11246 return true;
fa197c1c
PB
11247}
11248
625d49fc
AM
11249static uint64_t
11250arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 11251{
625d49fc 11252 uint64_t offset;
fa197c1c
PB
11253
11254 offset = word & 0x7fffffff;
11255 if (offset & 0x40000000)
625d49fc 11256 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 11257
dda8d76d 11258 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
11259 offset <<= 1;
11260
11261 return offset + where;
11262}
11263
015dc7e1 11264static bool
dda8d76d
NC
11265decode_arm_unwind (Filedata * filedata,
11266 struct arm_unw_aux_info * aux,
1b31d05e
NC
11267 unsigned int word,
11268 unsigned int remaining,
625d49fc 11269 uint64_t data_offset,
1b31d05e
NC
11270 Elf_Internal_Shdr * data_sec,
11271 struct arm_section * data_arm_sec)
fa197c1c
PB
11272{
11273 int per_index;
11274 unsigned int more_words = 0;
37e14bc3 11275 struct absaddr addr;
625d49fc 11276 uint64_t sym_name = (uint64_t) -1;
015dc7e1 11277 bool res = true;
fa197c1c
PB
11278
11279 if (remaining == 0)
11280 {
1b31d05e
NC
11281 /* Fetch the first word.
11282 Note - when decoding an object file the address extracted
11283 here will always be 0. So we also pass in the sym_name
11284 parameter so that we can find the symbol associated with
11285 the personality routine. */
dda8d76d 11286 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 11287 & word, & addr, & sym_name))
015dc7e1 11288 return false;
1b31d05e 11289
fa197c1c
PB
11290 remaining = 4;
11291 }
c93dbb25
CZ
11292 else
11293 {
11294 addr.section = SHN_UNDEF;
11295 addr.offset = 0;
11296 }
fa197c1c
PB
11297
11298 if ((word & 0x80000000) == 0)
11299 {
11300 /* Expand prel31 for personality routine. */
625d49fc 11301 uint64_t fn;
fa197c1c
PB
11302 const char *procname;
11303
dda8d76d 11304 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 11305 printf (_(" Personality routine: "));
1b31d05e
NC
11306 if (fn == 0
11307 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 11308 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
11309 {
11310 procname = aux->strtab + sym_name;
11311 print_vma (fn, PREFIX_HEX);
11312 if (procname)
11313 {
11314 fputs (" <", stdout);
11315 fputs (procname, stdout);
11316 fputc ('>', stdout);
11317 }
11318 }
11319 else
dda8d76d 11320 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
11321 fputc ('\n', stdout);
11322
11323 /* The GCC personality routines use the standard compact
11324 encoding, starting with one byte giving the number of
11325 words. */
11326 if (procname != NULL
24d127aa
ML
11327 && (startswith (procname, "__gcc_personality_v0")
11328 || startswith (procname, "__gxx_personality_v0")
11329 || startswith (procname, "__gcj_personality_v0")
11330 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
11331 {
11332 remaining = 0;
11333 more_words = 1;
11334 ADVANCE;
11335 if (!remaining)
11336 {
11337 printf (_(" [Truncated data]\n"));
015dc7e1 11338 return false;
fa197c1c
PB
11339 }
11340 more_words = word >> 24;
11341 word <<= 8;
11342 remaining--;
11343 per_index = -1;
11344 }
11345 else
015dc7e1 11346 return true;
fa197c1c
PB
11347 }
11348 else
11349 {
1b31d05e 11350 /* ARM EHABI Section 6.3:
0b4362b0 11351
1b31d05e 11352 An exception-handling table entry for the compact model looks like:
0b4362b0 11353
1b31d05e
NC
11354 31 30-28 27-24 23-0
11355 -- ----- ----- ----
11356 1 0 index Data for personalityRoutine[index] */
11357
dda8d76d 11358 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 11359 && (word & 0x70000000))
32ec8896
NC
11360 {
11361 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 11362 res = false;
32ec8896 11363 }
1b31d05e 11364
fa197c1c 11365 per_index = (word >> 24) & 0x7f;
1b31d05e 11366 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
11367 if (per_index == 0)
11368 {
11369 more_words = 0;
11370 word <<= 8;
11371 remaining--;
11372 }
11373 else if (per_index < 3)
11374 {
11375 more_words = (word >> 16) & 0xff;
11376 word <<= 16;
11377 remaining -= 2;
11378 }
11379 }
11380
dda8d76d 11381 switch (filedata->file_header.e_machine)
fa197c1c
PB
11382 {
11383 case EM_ARM:
11384 if (per_index < 3)
11385 {
dda8d76d 11386 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11387 data_offset, data_sec, data_arm_sec))
015dc7e1 11388 res = false;
fa197c1c
PB
11389 }
11390 else
1b31d05e
NC
11391 {
11392 warn (_("Unknown ARM compact model index encountered\n"));
11393 printf (_(" [reserved]\n"));
015dc7e1 11394 res = false;
1b31d05e 11395 }
fa197c1c
PB
11396 break;
11397
11398 case EM_TI_C6000:
11399 if (per_index < 3)
11400 {
dda8d76d 11401 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11402 data_offset, data_sec, data_arm_sec))
015dc7e1 11403 res = false;
fa197c1c
PB
11404 }
11405 else if (per_index < 5)
11406 {
11407 if (((word >> 17) & 0x7f) == 0x7f)
11408 printf (_(" Restore stack from frame pointer\n"));
11409 else
11410 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11411 printf (_(" Registers restored: "));
11412 if (per_index == 4)
11413 printf (" (compact) ");
11414 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11415 putchar ('\n');
11416 printf (_(" Return register: %s\n"),
11417 tic6x_unwind_regnames[word & 0xf]);
11418 }
11419 else
1b31d05e 11420 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
11421 break;
11422
11423 default:
74e1a04b 11424 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 11425 filedata->file_header.e_machine);
015dc7e1 11426 res = false;
fa197c1c 11427 }
0b6ae522
DJ
11428
11429 /* Decode the descriptors. Not implemented. */
32ec8896
NC
11430
11431 return res;
0b6ae522
DJ
11432}
11433
015dc7e1 11434static bool
dda8d76d
NC
11435dump_arm_unwind (Filedata * filedata,
11436 struct arm_unw_aux_info * aux,
11437 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
11438{
11439 struct arm_section exidx_arm_sec, extab_arm_sec;
11440 unsigned int i, exidx_len;
26c527e6 11441 uint64_t j, nfuns;
015dc7e1 11442 bool res = true;
0b6ae522
DJ
11443
11444 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11445 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11446 exidx_len = exidx_sec->sh_size / 8;
11447
948f632f
DA
11448 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11449 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11450 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11451 aux->funtab[nfuns++] = aux->symtab[j];
11452 aux->nfuns = nfuns;
11453 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11454
0b6ae522
DJ
11455 for (i = 0; i < exidx_len; i++)
11456 {
11457 unsigned int exidx_fn, exidx_entry;
11458 struct absaddr fn_addr, entry_addr;
625d49fc 11459 uint64_t fn;
0b6ae522
DJ
11460
11461 fputc ('\n', stdout);
11462
dda8d76d 11463 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11464 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 11465 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11466 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 11467 {
948f632f 11468 free (aux->funtab);
1b31d05e
NC
11469 arm_free_section (& exidx_arm_sec);
11470 arm_free_section (& extab_arm_sec);
015dc7e1 11471 return false;
0b6ae522
DJ
11472 }
11473
83c257ca
NC
11474 /* ARM EHABI, Section 5:
11475 An index table entry consists of 2 words.
11476 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11477 if (exidx_fn & 0x80000000)
32ec8896
NC
11478 {
11479 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 11480 res = false;
32ec8896 11481 }
83c257ca 11482
dda8d76d 11483 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 11484
dda8d76d 11485 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
11486 fputs (": ", stdout);
11487
11488 if (exidx_entry == 1)
11489 {
11490 print_vma (exidx_entry, PREFIX_HEX);
11491 fputs (" [cantunwind]\n", stdout);
11492 }
11493 else if (exidx_entry & 0x80000000)
11494 {
11495 print_vma (exidx_entry, PREFIX_HEX);
11496 fputc ('\n', stdout);
dda8d76d 11497 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
11498 }
11499 else
11500 {
625d49fc 11501 uint64_t table, table_offset = 0;
0b6ae522
DJ
11502 Elf_Internal_Shdr *table_sec;
11503
11504 fputs ("@", stdout);
dda8d76d 11505 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
11506 print_vma (table, PREFIX_HEX);
11507 printf ("\n");
11508
11509 /* Locate the matching .ARM.extab. */
11510 if (entry_addr.section != SHN_UNDEF
dda8d76d 11511 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 11512 {
dda8d76d 11513 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 11514 table_offset = entry_addr.offset;
1a915552 11515 /* PR 18879 */
625d49fc 11516 if (table_offset > table_sec->sh_size)
1a915552 11517 {
26c527e6
AM
11518 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11519 table_offset,
dda8d76d 11520 printable_section_name (filedata, table_sec));
015dc7e1 11521 res = false;
1a915552
NC
11522 continue;
11523 }
0b6ae522
DJ
11524 }
11525 else
11526 {
dda8d76d 11527 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
11528 if (table_sec != NULL)
11529 table_offset = table - table_sec->sh_addr;
11530 }
32ec8896 11531
0b6ae522
DJ
11532 if (table_sec == NULL)
11533 {
26c527e6
AM
11534 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11535 table);
015dc7e1 11536 res = false;
0b6ae522
DJ
11537 continue;
11538 }
32ec8896 11539
dda8d76d 11540 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 11541 &extab_arm_sec))
015dc7e1 11542 res = false;
0b6ae522
DJ
11543 }
11544 }
11545
11546 printf ("\n");
11547
948f632f 11548 free (aux->funtab);
0b6ae522
DJ
11549 arm_free_section (&exidx_arm_sec);
11550 arm_free_section (&extab_arm_sec);
32ec8896
NC
11551
11552 return res;
0b6ae522
DJ
11553}
11554
fa197c1c 11555/* Used for both ARM and C6X unwinding tables. */
1b31d05e 11556
015dc7e1 11557static bool
dda8d76d 11558arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
11559{
11560 struct arm_unw_aux_info aux;
11561 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 11562 Elf_Internal_Shdr *sec;
26c527e6 11563 size_t i;
fa197c1c 11564 unsigned int sec_type;
015dc7e1 11565 bool res = true;
0b6ae522 11566
dda8d76d 11567 switch (filedata->file_header.e_machine)
fa197c1c
PB
11568 {
11569 case EM_ARM:
11570 sec_type = SHT_ARM_EXIDX;
11571 break;
11572
11573 case EM_TI_C6000:
11574 sec_type = SHT_C6000_UNWIND;
11575 break;
11576
0b4362b0 11577 default:
74e1a04b 11578 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11579 filedata->file_header.e_machine);
015dc7e1 11580 return false;
fa197c1c
PB
11581 }
11582
dda8d76d 11583 if (filedata->string_table == NULL)
015dc7e1 11584 return false;
1b31d05e
NC
11585
11586 memset (& aux, 0, sizeof (aux));
dda8d76d 11587 aux.filedata = filedata;
0b6ae522 11588
dda8d76d 11589 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11590 {
28d13567 11591 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11592 {
28d13567 11593 if (aux.symtab)
74e1a04b 11594 {
28d13567
AM
11595 error (_("Multiple symbol tables encountered\n"));
11596 free (aux.symtab);
11597 aux.symtab = NULL;
74e1a04b 11598 free (aux.strtab);
28d13567 11599 aux.strtab = NULL;
74e1a04b 11600 }
28d13567
AM
11601 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11602 &aux.strtab, &aux.strtab_size))
015dc7e1 11603 return false;
0b6ae522 11604 }
fa197c1c 11605 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11606 unwsec = sec;
11607 }
11608
1b31d05e 11609 if (unwsec == NULL)
0b6ae522 11610 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11611 else
dda8d76d 11612 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11613 {
11614 if (sec->sh_type == sec_type)
11615 {
26c527e6
AM
11616 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11617 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11618 "contains %" PRIu64 " entry:\n",
11619 "\nUnwind section '%s' at offset %#" PRIx64 " "
11620 "contains %" PRIu64 " entries:\n",
d3a49aa8 11621 num_unwind),
dda8d76d 11622 printable_section_name (filedata, sec),
26c527e6 11623 sec->sh_offset,
d3a49aa8 11624 num_unwind);
0b6ae522 11625
dda8d76d 11626 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11627 res = false;
1b31d05e
NC
11628 }
11629 }
0b6ae522 11630
9db70fc3
AM
11631 free (aux.symtab);
11632 free ((char *) aux.strtab);
32ec8896
NC
11633
11634 return res;
0b6ae522
DJ
11635}
11636
3ecc00ec
NC
11637static bool
11638no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11639{
11640 printf (_("No processor specific unwind information to decode\n"));
11641 return true;
11642}
11643
015dc7e1 11644static bool
dda8d76d 11645process_unwind (Filedata * filedata)
57346661 11646{
2cf0635d
NC
11647 struct unwind_handler
11648 {
32ec8896 11649 unsigned int machtype;
015dc7e1 11650 bool (* handler)(Filedata *);
2cf0635d
NC
11651 } handlers[] =
11652 {
0b6ae522 11653 { EM_ARM, arm_process_unwind },
57346661
AM
11654 { EM_IA_64, ia64_process_unwind },
11655 { EM_PARISC, hppa_process_unwind },
fa197c1c 11656 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11657 { EM_386, no_processor_specific_unwind },
11658 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11659 { 0, NULL }
57346661
AM
11660 };
11661 int i;
11662
11663 if (!do_unwind)
015dc7e1 11664 return true;
57346661
AM
11665
11666 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11667 if (filedata->file_header.e_machine == handlers[i].machtype)
11668 return handlers[i].handler (filedata);
57346661 11669
1b31d05e 11670 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11671 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11672 return true;
57346661
AM
11673}
11674
37c18eed
SD
11675static void
11676dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11677{
11678 switch (entry->d_tag)
11679 {
11680 case DT_AARCH64_BTI_PLT:
1dbade74 11681 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11682 break;
11683 default:
11684 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11685 break;
11686 }
11687 putchar ('\n');
11688}
11689
252b5132 11690static void
978c4450 11691dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11692{
11693 switch (entry->d_tag)
11694 {
11695 case DT_MIPS_FLAGS:
11696 if (entry->d_un.d_val == 0)
4b68bca3 11697 printf (_("NONE"));
252b5132
RH
11698 else
11699 {
11700 static const char * opts[] =
11701 {
11702 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11703 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11704 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11705 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11706 "RLD_ORDER_SAFE"
11707 };
11708 unsigned int cnt;
015dc7e1 11709 bool first = true;
2b692964 11710
60bca95a 11711 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11712 if (entry->d_un.d_val & (1 << cnt))
11713 {
11714 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11715 first = false;
252b5132 11716 }
252b5132
RH
11717 }
11718 break;
103f02d3 11719
252b5132 11720 case DT_MIPS_IVERSION:
84714f86 11721 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11722 printf (_("Interface Version: %s"),
84714f86 11723 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11724 else
f493c217 11725 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11726 entry->d_un.d_ptr);
252b5132 11727 break;
103f02d3 11728
252b5132
RH
11729 case DT_MIPS_TIME_STAMP:
11730 {
d5b07ef4 11731 char timebuf[128];
2cf0635d 11732 struct tm * tmp;
91d6fa6a 11733 time_t atime = entry->d_un.d_val;
82b1b41b 11734
91d6fa6a 11735 tmp = gmtime (&atime);
82b1b41b
NC
11736 /* PR 17531: file: 6accc532. */
11737 if (tmp == NULL)
11738 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11739 else
11740 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11741 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11742 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11743 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11744 }
11745 break;
103f02d3 11746
252b5132
RH
11747 case DT_MIPS_RLD_VERSION:
11748 case DT_MIPS_LOCAL_GOTNO:
11749 case DT_MIPS_CONFLICTNO:
11750 case DT_MIPS_LIBLISTNO:
11751 case DT_MIPS_SYMTABNO:
11752 case DT_MIPS_UNREFEXTNO:
11753 case DT_MIPS_HIPAGENO:
11754 case DT_MIPS_DELTA_CLASS_NO:
11755 case DT_MIPS_DELTA_INSTANCE_NO:
11756 case DT_MIPS_DELTA_RELOC_NO:
11757 case DT_MIPS_DELTA_SYM_NO:
11758 case DT_MIPS_DELTA_CLASSSYM_NO:
11759 case DT_MIPS_COMPACT_SIZE:
c69075ac 11760 print_vma (entry->d_un.d_val, DEC);
252b5132 11761 break;
103f02d3 11762
f16a9783 11763 case DT_MIPS_XHASH:
978c4450
AM
11764 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11765 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11766 /* Falls through. */
11767
103f02d3 11768 default:
4b68bca3 11769 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11770 }
4b68bca3 11771 putchar ('\n');
103f02d3
UD
11772}
11773
103f02d3 11774static void
2cf0635d 11775dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11776{
11777 switch (entry->d_tag)
11778 {
11779 case DT_HP_DLD_FLAGS:
11780 {
11781 static struct
11782 {
26c527e6 11783 unsigned int bit;
2cf0635d 11784 const char * str;
5e220199
NC
11785 }
11786 flags[] =
11787 {
11788 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11789 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11790 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11791 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11792 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11793 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11794 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11795 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11796 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11797 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11798 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11799 { DT_HP_GST, "HP_GST" },
11800 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11801 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11802 { DT_HP_NODELETE, "HP_NODELETE" },
11803 { DT_HP_GROUP, "HP_GROUP" },
11804 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11805 };
015dc7e1 11806 bool first = true;
5e220199 11807 size_t cnt;
625d49fc 11808 uint64_t val = entry->d_un.d_val;
103f02d3 11809
60bca95a 11810 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11811 if (val & flags[cnt].bit)
30800947
NC
11812 {
11813 if (! first)
11814 putchar (' ');
11815 fputs (flags[cnt].str, stdout);
015dc7e1 11816 first = false;
30800947
NC
11817 val ^= flags[cnt].bit;
11818 }
76da6bbe 11819
103f02d3 11820 if (val != 0 || first)
f7a99963
NC
11821 {
11822 if (! first)
11823 putchar (' ');
11824 print_vma (val, HEX);
11825 }
103f02d3
UD
11826 }
11827 break;
76da6bbe 11828
252b5132 11829 default:
f7a99963
NC
11830 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11831 break;
252b5132 11832 }
35b1837e 11833 putchar ('\n');
252b5132
RH
11834}
11835
28f997cf
TG
11836/* VMS vs Unix time offset and factor. */
11837
11838#define VMS_EPOCH_OFFSET 35067168000000000LL
11839#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11840#ifndef INT64_MIN
11841#define INT64_MIN (-9223372036854775807LL - 1)
11842#endif
28f997cf
TG
11843
11844/* Display a VMS time in a human readable format. */
11845
11846static void
0e3c1eeb 11847print_vms_time (int64_t vmstime)
28f997cf 11848{
dccc31de 11849 struct tm *tm = NULL;
28f997cf
TG
11850 time_t unxtime;
11851
dccc31de
AM
11852 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11853 {
11854 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11855 unxtime = vmstime;
11856 if (unxtime == vmstime)
11857 tm = gmtime (&unxtime);
11858 }
11859 if (tm != NULL)
11860 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11861 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11862 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11863}
28f997cf 11864
ecc51f48 11865static void
2cf0635d 11866dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11867{
11868 switch (entry->d_tag)
11869 {
0de14b54 11870 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11871 /* First 3 slots reserved. */
ecc51f48
NC
11872 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11873 printf (" -- ");
11874 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11875 break;
11876
28f997cf 11877 case DT_IA_64_VMS_LINKTIME:
28f997cf 11878 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11879 break;
11880
11881 case DT_IA_64_VMS_LNKFLAGS:
11882 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11883 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11884 printf (" CALL_DEBUG");
11885 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11886 printf (" NOP0BUFS");
11887 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11888 printf (" P0IMAGE");
11889 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11890 printf (" MKTHREADS");
11891 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11892 printf (" UPCALLS");
11893 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11894 printf (" IMGSTA");
11895 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11896 printf (" INITIALIZE");
11897 if (entry->d_un.d_val & VMS_LF_MAIN)
11898 printf (" MAIN");
11899 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11900 printf (" EXE_INIT");
11901 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11902 printf (" TBK_IN_IMG");
11903 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11904 printf (" DBG_IN_IMG");
11905 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11906 printf (" TBK_IN_DSF");
11907 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11908 printf (" DBG_IN_DSF");
11909 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11910 printf (" SIGNATURES");
11911 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11912 printf (" REL_SEG_OFF");
11913 break;
11914
bdf4d63a
JJ
11915 default:
11916 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11917 break;
ecc51f48 11918 }
bdf4d63a 11919 putchar ('\n');
ecc51f48
NC
11920}
11921
015dc7e1 11922static bool
dda8d76d 11923get_32bit_dynamic_section (Filedata * filedata)
252b5132 11924{
2cf0635d
NC
11925 Elf32_External_Dyn * edyn;
11926 Elf32_External_Dyn * ext;
11927 Elf_Internal_Dyn * entry;
103f02d3 11928
978c4450
AM
11929 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11930 filedata->dynamic_addr, 1,
11931 filedata->dynamic_size,
11932 _("dynamic section"));
a6e9f9df 11933 if (!edyn)
015dc7e1 11934 return false;
103f02d3 11935
071436c6
NC
11936 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11937 might not have the luxury of section headers. Look for the DT_NULL
11938 terminator to determine the number of entries. */
978c4450
AM
11939 for (ext = edyn, filedata->dynamic_nent = 0;
11940 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11941 ext++)
11942 {
978c4450 11943 filedata->dynamic_nent++;
ba2685cc
AM
11944 if (BYTE_GET (ext->d_tag) == DT_NULL)
11945 break;
11946 }
252b5132 11947
978c4450
AM
11948 filedata->dynamic_section
11949 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11950 if (filedata->dynamic_section == NULL)
252b5132 11951 {
26c527e6
AM
11952 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11953 filedata->dynamic_nent);
9ea033b2 11954 free (edyn);
015dc7e1 11955 return false;
9ea033b2 11956 }
252b5132 11957
978c4450
AM
11958 for (ext = edyn, entry = filedata->dynamic_section;
11959 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11960 ext++, entry++)
9ea033b2 11961 {
fb514b26
AM
11962 entry->d_tag = BYTE_GET (ext->d_tag);
11963 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11964 }
11965
9ea033b2
NC
11966 free (edyn);
11967
015dc7e1 11968 return true;
9ea033b2
NC
11969}
11970
015dc7e1 11971static bool
dda8d76d 11972get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11973{
2cf0635d
NC
11974 Elf64_External_Dyn * edyn;
11975 Elf64_External_Dyn * ext;
11976 Elf_Internal_Dyn * entry;
103f02d3 11977
071436c6 11978 /* Read in the data. */
978c4450
AM
11979 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11980 filedata->dynamic_addr, 1,
11981 filedata->dynamic_size,
11982 _("dynamic section"));
a6e9f9df 11983 if (!edyn)
015dc7e1 11984 return false;
103f02d3 11985
071436c6
NC
11986 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11987 might not have the luxury of section headers. Look for the DT_NULL
11988 terminator to determine the number of entries. */
978c4450 11989 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11990 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11991 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11992 ext++)
11993 {
978c4450 11994 filedata->dynamic_nent++;
66543521 11995 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11996 break;
11997 }
252b5132 11998
978c4450
AM
11999 filedata->dynamic_section
12000 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
12001 if (filedata->dynamic_section == NULL)
252b5132 12002 {
26c527e6
AM
12003 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
12004 filedata->dynamic_nent);
252b5132 12005 free (edyn);
015dc7e1 12006 return false;
252b5132
RH
12007 }
12008
071436c6 12009 /* Convert from external to internal formats. */
978c4450
AM
12010 for (ext = edyn, entry = filedata->dynamic_section;
12011 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 12012 ext++, entry++)
252b5132 12013 {
66543521
AM
12014 entry->d_tag = BYTE_GET (ext->d_tag);
12015 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
12016 }
12017
12018 free (edyn);
12019
015dc7e1 12020 return true;
9ea033b2
NC
12021}
12022
4de91c10
AM
12023static bool
12024get_dynamic_section (Filedata *filedata)
12025{
12026 if (filedata->dynamic_section)
12027 return true;
12028
12029 if (is_32bit_elf)
12030 return get_32bit_dynamic_section (filedata);
12031 else
12032 return get_64bit_dynamic_section (filedata);
12033}
12034
e9e44622 12035static void
625d49fc 12036print_dynamic_flags (uint64_t flags)
d1133906 12037{
015dc7e1 12038 bool first = true;
13ae64f3 12039
d1133906
NC
12040 while (flags)
12041 {
625d49fc 12042 uint64_t flag;
d1133906
NC
12043
12044 flag = flags & - flags;
12045 flags &= ~ flag;
12046
e9e44622 12047 if (first)
015dc7e1 12048 first = false;
e9e44622
JJ
12049 else
12050 putc (' ', stdout);
13ae64f3 12051
d1133906
NC
12052 switch (flag)
12053 {
e9e44622
JJ
12054 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
12055 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
12056 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
12057 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
12058 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 12059 default: fputs (_("unknown"), stdout); break;
d1133906
NC
12060 }
12061 }
e9e44622 12062 puts ("");
d1133906
NC
12063}
12064
625d49fc 12065static uint64_t *
be7d229a 12066get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
12067{
12068 unsigned char * e_data;
625d49fc 12069 uint64_t * i_data;
10ca4b04 12070
be7d229a
AM
12071 /* If size_t is smaller than uint64_t, eg because you are building
12072 on a 32-bit host, then make sure that when number is cast to
12073 size_t no information is lost. */
12074 if ((size_t) number != number
12075 || ent_size * number / ent_size != number)
10ca4b04 12076 {
be7d229a 12077 error (_("Size overflow prevents reading %" PRIu64
b8281767 12078 " elements of size %u\n"),
be7d229a 12079 number, ent_size);
10ca4b04
L
12080 return NULL;
12081 }
12082
12083 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
12084 attempting to allocate memory when the read is bound to fail. */
12085 if (ent_size * number > filedata->file_size)
12086 {
b8281767 12087 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 12088 number);
10ca4b04
L
12089 return NULL;
12090 }
12091
12092 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
12093 if (e_data == NULL)
12094 {
b8281767 12095 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 12096 number);
10ca4b04
L
12097 return NULL;
12098 }
12099
12100 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
12101 {
b8281767 12102 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 12103 number * ent_size);
10ca4b04
L
12104 free (e_data);
12105 return NULL;
12106 }
12107
625d49fc 12108 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
12109 if (i_data == NULL)
12110 {
b8281767 12111 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 12112 number);
10ca4b04
L
12113 free (e_data);
12114 return NULL;
12115 }
12116
12117 while (number--)
12118 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
12119
12120 free (e_data);
12121
12122 return i_data;
12123}
12124
26c527e6 12125static uint64_t
10ca4b04
L
12126get_num_dynamic_syms (Filedata * filedata)
12127{
26c527e6 12128 uint64_t num_of_syms = 0;
10ca4b04
L
12129
12130 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
12131 return num_of_syms;
12132
978c4450 12133 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
12134 {
12135 unsigned char nb[8];
12136 unsigned char nc[8];
12137 unsigned int hash_ent_size = 4;
12138
12139 if ((filedata->file_header.e_machine == EM_ALPHA
12140 || filedata->file_header.e_machine == EM_S390
12141 || filedata->file_header.e_machine == EM_S390_OLD)
12142 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
12143 hash_ent_size = 8;
12144
63cf857e
AM
12145 if (fseek64 (filedata->handle,
12146 (filedata->archive_file_offset
12147 + offset_from_vma (filedata,
12148 filedata->dynamic_info[DT_HASH],
12149 sizeof nb + sizeof nc)),
12150 SEEK_SET))
10ca4b04
L
12151 {
12152 error (_("Unable to seek to start of dynamic information\n"));
12153 goto no_hash;
12154 }
12155
12156 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
12157 {
12158 error (_("Failed to read in number of buckets\n"));
12159 goto no_hash;
12160 }
12161
12162 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
12163 {
12164 error (_("Failed to read in number of chains\n"));
12165 goto no_hash;
12166 }
12167
978c4450
AM
12168 filedata->nbuckets = byte_get (nb, hash_ent_size);
12169 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 12170
2482f306
AM
12171 if (filedata->nbuckets != 0 && filedata->nchains != 0)
12172 {
12173 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
12174 hash_ent_size);
12175 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
12176 hash_ent_size);
001890e1 12177
2482f306
AM
12178 if (filedata->buckets != NULL && filedata->chains != NULL)
12179 num_of_syms = filedata->nchains;
12180 }
ceb9bf11 12181 no_hash:
10ca4b04
L
12182 if (num_of_syms == 0)
12183 {
9db70fc3
AM
12184 free (filedata->buckets);
12185 filedata->buckets = NULL;
12186 free (filedata->chains);
12187 filedata->chains = NULL;
978c4450 12188 filedata->nbuckets = 0;
10ca4b04
L
12189 }
12190 }
12191
978c4450 12192 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
12193 {
12194 unsigned char nb[16];
625d49fc
AM
12195 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
12196 uint64_t buckets_vma;
26c527e6 12197 uint64_t hn;
10ca4b04 12198
63cf857e
AM
12199 if (fseek64 (filedata->handle,
12200 (filedata->archive_file_offset
12201 + offset_from_vma (filedata,
12202 filedata->dynamic_info_DT_GNU_HASH,
12203 sizeof nb)),
12204 SEEK_SET))
10ca4b04
L
12205 {
12206 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12207 goto no_gnu_hash;
12208 }
12209
12210 if (fread (nb, 16, 1, filedata->handle) != 1)
12211 {
12212 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
12213 goto no_gnu_hash;
12214 }
12215
978c4450
AM
12216 filedata->ngnubuckets = byte_get (nb, 4);
12217 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 12218 bitmaskwords = byte_get (nb + 8, 4);
978c4450 12219 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
12220 if (is_32bit_elf)
12221 buckets_vma += bitmaskwords * 4;
12222 else
12223 buckets_vma += bitmaskwords * 8;
12224
63cf857e
AM
12225 if (fseek64 (filedata->handle,
12226 (filedata->archive_file_offset
12227 + offset_from_vma (filedata, buckets_vma, 4)),
12228 SEEK_SET))
10ca4b04
L
12229 {
12230 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12231 goto no_gnu_hash;
12232 }
12233
978c4450
AM
12234 filedata->gnubuckets
12235 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 12236
978c4450 12237 if (filedata->gnubuckets == NULL)
90837ea7 12238 goto no_gnu_hash;
10ca4b04 12239
978c4450
AM
12240 for (i = 0; i < filedata->ngnubuckets; i++)
12241 if (filedata->gnubuckets[i] != 0)
10ca4b04 12242 {
978c4450 12243 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 12244 goto no_gnu_hash;
10ca4b04 12245
978c4450
AM
12246 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
12247 maxchain = filedata->gnubuckets[i];
10ca4b04
L
12248 }
12249
12250 if (maxchain == 0xffffffff)
90837ea7 12251 goto no_gnu_hash;
10ca4b04 12252
978c4450 12253 maxchain -= filedata->gnusymidx;
10ca4b04 12254
63cf857e
AM
12255 if (fseek64 (filedata->handle,
12256 (filedata->archive_file_offset
12257 + offset_from_vma (filedata,
12258 buckets_vma + 4 * (filedata->ngnubuckets
12259 + maxchain),
12260 4)),
12261 SEEK_SET))
10ca4b04
L
12262 {
12263 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12264 goto no_gnu_hash;
12265 }
12266
12267 do
12268 {
12269 if (fread (nb, 4, 1, filedata->handle) != 1)
12270 {
12271 error (_("Failed to determine last chain length\n"));
10ca4b04
L
12272 goto no_gnu_hash;
12273 }
12274
12275 if (maxchain + 1 == 0)
90837ea7 12276 goto no_gnu_hash;
10ca4b04
L
12277
12278 ++maxchain;
12279 }
12280 while ((byte_get (nb, 4) & 1) == 0);
12281
63cf857e
AM
12282 if (fseek64 (filedata->handle,
12283 (filedata->archive_file_offset
12284 + offset_from_vma (filedata, (buckets_vma
12285 + 4 * filedata->ngnubuckets),
12286 4)),
12287 SEEK_SET))
10ca4b04
L
12288 {
12289 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12290 goto no_gnu_hash;
12291 }
12292
978c4450
AM
12293 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
12294 filedata->ngnuchains = maxchain;
10ca4b04 12295
978c4450 12296 if (filedata->gnuchains == NULL)
90837ea7 12297 goto no_gnu_hash;
10ca4b04 12298
978c4450 12299 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12300 {
63cf857e
AM
12301 if (fseek64 (filedata->handle,
12302 (filedata->archive_file_offset
12303 + offset_from_vma (filedata, (buckets_vma
12304 + 4 * (filedata->ngnubuckets
12305 + maxchain)), 4)),
12306 SEEK_SET))
10ca4b04
L
12307 {
12308 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
12309 goto no_gnu_hash;
12310 }
12311
978c4450 12312 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
12313 if (filedata->mipsxlat == NULL)
12314 goto no_gnu_hash;
10ca4b04
L
12315 }
12316
978c4450
AM
12317 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12318 if (filedata->gnubuckets[hn] != 0)
10ca4b04 12319 {
625d49fc
AM
12320 uint64_t si = filedata->gnubuckets[hn];
12321 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
12322
12323 do
12324 {
978c4450 12325 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 12326 {
c31ab5a0
AM
12327 if (off < filedata->ngnuchains
12328 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 12329 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
12330 }
12331 else
12332 {
12333 if (si >= num_of_syms)
12334 num_of_syms = si + 1;
12335 }
12336 si++;
12337 }
978c4450
AM
12338 while (off < filedata->ngnuchains
12339 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
12340 }
12341
90837ea7 12342 if (num_of_syms == 0)
10ca4b04 12343 {
90837ea7 12344 no_gnu_hash:
9db70fc3
AM
12345 free (filedata->mipsxlat);
12346 filedata->mipsxlat = NULL;
12347 free (filedata->gnuchains);
12348 filedata->gnuchains = NULL;
12349 free (filedata->gnubuckets);
12350 filedata->gnubuckets = NULL;
978c4450
AM
12351 filedata->ngnubuckets = 0;
12352 filedata->ngnuchains = 0;
10ca4b04
L
12353 }
12354 }
12355
12356 return num_of_syms;
12357}
12358
b2d38a17
NC
12359/* Parse and display the contents of the dynamic section. */
12360
015dc7e1 12361static bool
dda8d76d 12362process_dynamic_section (Filedata * filedata)
9ea033b2 12363{
2cf0635d 12364 Elf_Internal_Dyn * entry;
9ea033b2 12365
93df3340 12366 if (filedata->dynamic_size <= 1)
9ea033b2
NC
12367 {
12368 if (do_dynamic)
ca0e11aa
NC
12369 {
12370 if (filedata->is_separate)
12371 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
978dae65 12372 printable_string (filedata->file_name, 0));
ca0e11aa
NC
12373 else
12374 printf (_("\nThere is no dynamic section in this file.\n"));
12375 }
9ea033b2 12376
015dc7e1 12377 return true;
9ea033b2
NC
12378 }
12379
4de91c10
AM
12380 if (!get_dynamic_section (filedata))
12381 return false;
9ea033b2 12382
252b5132 12383 /* Find the appropriate symbol table. */
978c4450 12384 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 12385 {
26c527e6 12386 uint64_t num_of_syms;
2482f306 12387
978c4450
AM
12388 for (entry = filedata->dynamic_section;
12389 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12390 ++entry)
10ca4b04 12391 if (entry->d_tag == DT_SYMTAB)
978c4450 12392 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 12393 else if (entry->d_tag == DT_SYMENT)
978c4450 12394 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 12395 else if (entry->d_tag == DT_HASH)
978c4450 12396 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 12397 else if (entry->d_tag == DT_GNU_HASH)
978c4450 12398 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
12399 else if ((filedata->file_header.e_machine == EM_MIPS
12400 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12401 && entry->d_tag == DT_MIPS_XHASH)
12402 {
978c4450
AM
12403 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12404 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 12405 }
252b5132 12406
2482f306
AM
12407 num_of_syms = get_num_dynamic_syms (filedata);
12408
12409 if (num_of_syms != 0
12410 && filedata->dynamic_symbols == NULL
12411 && filedata->dynamic_info[DT_SYMTAB]
978c4450 12412 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
12413 {
12414 Elf_Internal_Phdr *seg;
625d49fc 12415 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 12416
2482f306
AM
12417 if (! get_program_headers (filedata))
12418 {
12419 error (_("Cannot interpret virtual addresses "
12420 "without program headers.\n"));
015dc7e1 12421 return false;
2482f306 12422 }
252b5132 12423
2482f306
AM
12424 for (seg = filedata->program_headers;
12425 seg < filedata->program_headers + filedata->file_header.e_phnum;
12426 ++seg)
12427 {
12428 if (seg->p_type != PT_LOAD)
12429 continue;
252b5132 12430
2482f306
AM
12431 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12432 {
12433 /* See PR 21379 for a reproducer. */
12434 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 12435 return false;
2482f306 12436 }
252b5132 12437
2482f306
AM
12438 if (vma >= (seg->p_vaddr & -seg->p_align)
12439 && vma < seg->p_vaddr + seg->p_filesz)
12440 {
12441 /* Since we do not know how big the symbol table is,
12442 we default to reading in up to the end of PT_LOAD
12443 segment and processing that. This is overkill, I
12444 know, but it should work. */
12445 Elf_Internal_Shdr section;
12446 section.sh_offset = (vma - seg->p_vaddr
12447 + seg->p_offset);
12448 section.sh_size = (num_of_syms
12449 * filedata->dynamic_info[DT_SYMENT]);
12450 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
12451
12452 if (do_checks
12453 && filedata->dynamic_symtab_section != NULL
12454 && ((filedata->dynamic_symtab_section->sh_offset
12455 != section.sh_offset)
12456 || (filedata->dynamic_symtab_section->sh_size
12457 != section.sh_size)
12458 || (filedata->dynamic_symtab_section->sh_entsize
12459 != section.sh_entsize)))
12460 warn (_("\
12461the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12462
2482f306
AM
12463 section.sh_name = filedata->string_table_length;
12464 filedata->dynamic_symbols
4de91c10 12465 = get_elf_symbols (filedata, &section,
2482f306
AM
12466 &filedata->num_dynamic_syms);
12467 if (filedata->dynamic_symbols == NULL
12468 || filedata->num_dynamic_syms != num_of_syms)
12469 {
12470 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 12471 return false;
2482f306
AM
12472 }
12473 break;
12474 }
12475 }
12476 }
12477 }
252b5132
RH
12478
12479 /* Similarly find a string table. */
978c4450
AM
12480 if (filedata->dynamic_strings == NULL)
12481 for (entry = filedata->dynamic_section;
12482 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
12483 ++entry)
12484 {
12485 if (entry->d_tag == DT_STRTAB)
978c4450 12486 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 12487
10ca4b04 12488 if (entry->d_tag == DT_STRSZ)
978c4450 12489 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 12490
978c4450
AM
12491 if (filedata->dynamic_info[DT_STRTAB]
12492 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 12493 {
26c527e6 12494 uint64_t offset;
be7d229a 12495 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
12496
12497 offset = offset_from_vma (filedata,
978c4450 12498 filedata->dynamic_info[DT_STRTAB],
10ca4b04 12499 str_tab_len);
8ac10c5b
L
12500 if (do_checks
12501 && filedata->dynamic_strtab_section
12502 && ((filedata->dynamic_strtab_section->sh_offset
12503 != (file_ptr) offset)
12504 || (filedata->dynamic_strtab_section->sh_size
12505 != str_tab_len)))
12506 warn (_("\
12507the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12508
978c4450
AM
12509 filedata->dynamic_strings
12510 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12511 _("dynamic string table"));
12512 if (filedata->dynamic_strings == NULL)
10ca4b04
L
12513 {
12514 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12515 break;
12516 }
e3d39609 12517
978c4450 12518 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
12519 break;
12520 }
12521 }
252b5132
RH
12522
12523 /* And find the syminfo section if available. */
978c4450 12524 if (filedata->dynamic_syminfo == NULL)
252b5132 12525 {
26c527e6 12526 uint64_t syminsz = 0;
252b5132 12527
978c4450
AM
12528 for (entry = filedata->dynamic_section;
12529 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12530 ++entry)
252b5132
RH
12531 {
12532 if (entry->d_tag == DT_SYMINENT)
12533 {
12534 /* Note: these braces are necessary to avoid a syntax
12535 error from the SunOS4 C compiler. */
049b0c3a
NC
12536 /* PR binutils/17531: A corrupt file can trigger this test.
12537 So do not use an assert, instead generate an error message. */
12538 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 12539 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 12540 (int) entry->d_un.d_val);
252b5132
RH
12541 }
12542 else if (entry->d_tag == DT_SYMINSZ)
12543 syminsz = entry->d_un.d_val;
12544 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
12545 filedata->dynamic_syminfo_offset
12546 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
12547 }
12548
978c4450 12549 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 12550 {
2cf0635d
NC
12551 Elf_External_Syminfo * extsyminfo;
12552 Elf_External_Syminfo * extsym;
12553 Elf_Internal_Syminfo * syminfo;
252b5132
RH
12554
12555 /* There is a syminfo section. Read the data. */
3f5e193b 12556 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
12557 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12558 1, syminsz, _("symbol information"));
a6e9f9df 12559 if (!extsyminfo)
015dc7e1 12560 return false;
252b5132 12561
978c4450 12562 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
12563 {
12564 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 12565 free (filedata->dynamic_syminfo);
e3d39609 12566 }
978c4450
AM
12567 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12568 if (filedata->dynamic_syminfo == NULL)
252b5132 12569 {
26c527e6
AM
12570 error (_("Out of memory allocating %" PRIu64
12571 " bytes for dynamic symbol info\n"),
12572 syminsz);
015dc7e1 12573 return false;
252b5132
RH
12574 }
12575
2482f306
AM
12576 filedata->dynamic_syminfo_nent
12577 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12578 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12579 syminfo < (filedata->dynamic_syminfo
12580 + filedata->dynamic_syminfo_nent);
86dba8ee 12581 ++syminfo, ++extsym)
252b5132 12582 {
86dba8ee
AM
12583 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12584 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12585 }
12586
12587 free (extsyminfo);
12588 }
12589 }
12590
978c4450 12591 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12592 {
f253158f 12593 if (filedata->is_separate)
26c527e6
AM
12594 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12595 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12596 filedata->dynamic_nent),
f253158f
NC
12597 filedata->file_name,
12598 filedata->dynamic_addr,
26c527e6 12599 filedata->dynamic_nent);
84a9f195 12600 else
02da71ee 12601 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12602 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12603 filedata->dynamic_nent),
84a9f195 12604 filedata->dynamic_addr,
26c527e6 12605 filedata->dynamic_nent);
ca0e11aa 12606 }
252b5132
RH
12607 if (do_dynamic)
12608 printf (_(" Tag Type Name/Value\n"));
12609
978c4450
AM
12610 for (entry = filedata->dynamic_section;
12611 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12612 entry++)
252b5132
RH
12613 {
12614 if (do_dynamic)
f7a99963 12615 {
2cf0635d 12616 const char * dtype;
e699b9ff 12617
f7a99963
NC
12618 putchar (' ');
12619 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12620 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12621 printf (" (%s)%*s", dtype,
32ec8896 12622 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12623 }
252b5132
RH
12624
12625 switch (entry->d_tag)
12626 {
d1133906
NC
12627 case DT_FLAGS:
12628 if (do_dynamic)
e9e44622 12629 print_dynamic_flags (entry->d_un.d_val);
d1133906 12630 break;
76da6bbe 12631
252b5132
RH
12632 case DT_AUXILIARY:
12633 case DT_FILTER:
019148e4
L
12634 case DT_CONFIG:
12635 case DT_DEPAUDIT:
12636 case DT_AUDIT:
252b5132
RH
12637 if (do_dynamic)
12638 {
019148e4 12639 switch (entry->d_tag)
b34976b6 12640 {
019148e4
L
12641 case DT_AUXILIARY:
12642 printf (_("Auxiliary library"));
12643 break;
12644
12645 case DT_FILTER:
12646 printf (_("Filter library"));
12647 break;
12648
b34976b6 12649 case DT_CONFIG:
019148e4
L
12650 printf (_("Configuration file"));
12651 break;
12652
12653 case DT_DEPAUDIT:
12654 printf (_("Dependency audit library"));
12655 break;
12656
12657 case DT_AUDIT:
12658 printf (_("Audit library"));
12659 break;
12660 }
252b5132 12661
84714f86 12662 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12663 printf (": [%s]\n",
84714f86 12664 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12665 else
f7a99963
NC
12666 {
12667 printf (": ");
12668 print_vma (entry->d_un.d_val, PREFIX_HEX);
12669 putchar ('\n');
12670 }
252b5132
RH
12671 }
12672 break;
12673
dcefbbbd 12674 case DT_FEATURE:
252b5132
RH
12675 if (do_dynamic)
12676 {
12677 printf (_("Flags:"));
86f55779 12678
252b5132
RH
12679 if (entry->d_un.d_val == 0)
12680 printf (_(" None\n"));
12681 else
12682 {
26c527e6 12683 uint64_t val = entry->d_un.d_val;
86f55779 12684
252b5132
RH
12685 if (val & DTF_1_PARINIT)
12686 {
12687 printf (" PARINIT");
12688 val ^= DTF_1_PARINIT;
12689 }
dcefbbbd
L
12690 if (val & DTF_1_CONFEXP)
12691 {
12692 printf (" CONFEXP");
12693 val ^= DTF_1_CONFEXP;
12694 }
252b5132 12695 if (val != 0)
26c527e6 12696 printf (" %" PRIx64, val);
252b5132
RH
12697 puts ("");
12698 }
12699 }
12700 break;
12701
12702 case DT_POSFLAG_1:
12703 if (do_dynamic)
12704 {
12705 printf (_("Flags:"));
86f55779 12706
252b5132
RH
12707 if (entry->d_un.d_val == 0)
12708 printf (_(" None\n"));
12709 else
12710 {
26c527e6 12711 uint64_t val = entry->d_un.d_val;
86f55779 12712
252b5132
RH
12713 if (val & DF_P1_LAZYLOAD)
12714 {
12715 printf (" LAZYLOAD");
12716 val ^= DF_P1_LAZYLOAD;
12717 }
12718 if (val & DF_P1_GROUPPERM)
12719 {
12720 printf (" GROUPPERM");
12721 val ^= DF_P1_GROUPPERM;
12722 }
12723 if (val != 0)
26c527e6 12724 printf (" %" PRIx64, val);
252b5132
RH
12725 puts ("");
12726 }
12727 }
12728 break;
12729
12730 case DT_FLAGS_1:
12731 if (do_dynamic)
12732 {
12733 printf (_("Flags:"));
12734 if (entry->d_un.d_val == 0)
12735 printf (_(" None\n"));
12736 else
12737 {
26c527e6 12738 uint64_t val = entry->d_un.d_val;
86f55779 12739
252b5132
RH
12740 if (val & DF_1_NOW)
12741 {
12742 printf (" NOW");
12743 val ^= DF_1_NOW;
12744 }
12745 if (val & DF_1_GLOBAL)
12746 {
12747 printf (" GLOBAL");
12748 val ^= DF_1_GLOBAL;
12749 }
12750 if (val & DF_1_GROUP)
12751 {
12752 printf (" GROUP");
12753 val ^= DF_1_GROUP;
12754 }
12755 if (val & DF_1_NODELETE)
12756 {
12757 printf (" NODELETE");
12758 val ^= DF_1_NODELETE;
12759 }
12760 if (val & DF_1_LOADFLTR)
12761 {
12762 printf (" LOADFLTR");
12763 val ^= DF_1_LOADFLTR;
12764 }
12765 if (val & DF_1_INITFIRST)
12766 {
12767 printf (" INITFIRST");
12768 val ^= DF_1_INITFIRST;
12769 }
12770 if (val & DF_1_NOOPEN)
12771 {
12772 printf (" NOOPEN");
12773 val ^= DF_1_NOOPEN;
12774 }
12775 if (val & DF_1_ORIGIN)
12776 {
12777 printf (" ORIGIN");
12778 val ^= DF_1_ORIGIN;
12779 }
12780 if (val & DF_1_DIRECT)
12781 {
12782 printf (" DIRECT");
12783 val ^= DF_1_DIRECT;
12784 }
12785 if (val & DF_1_TRANS)
12786 {
12787 printf (" TRANS");
12788 val ^= DF_1_TRANS;
12789 }
12790 if (val & DF_1_INTERPOSE)
12791 {
12792 printf (" INTERPOSE");
12793 val ^= DF_1_INTERPOSE;
12794 }
f7db6139 12795 if (val & DF_1_NODEFLIB)
dcefbbbd 12796 {
f7db6139
L
12797 printf (" NODEFLIB");
12798 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12799 }
12800 if (val & DF_1_NODUMP)
12801 {
12802 printf (" NODUMP");
12803 val ^= DF_1_NODUMP;
12804 }
34b60028 12805 if (val & DF_1_CONFALT)
dcefbbbd 12806 {
34b60028
L
12807 printf (" CONFALT");
12808 val ^= DF_1_CONFALT;
12809 }
12810 if (val & DF_1_ENDFILTEE)
12811 {
12812 printf (" ENDFILTEE");
12813 val ^= DF_1_ENDFILTEE;
12814 }
12815 if (val & DF_1_DISPRELDNE)
12816 {
12817 printf (" DISPRELDNE");
12818 val ^= DF_1_DISPRELDNE;
12819 }
12820 if (val & DF_1_DISPRELPND)
12821 {
12822 printf (" DISPRELPND");
12823 val ^= DF_1_DISPRELPND;
12824 }
12825 if (val & DF_1_NODIRECT)
12826 {
12827 printf (" NODIRECT");
12828 val ^= DF_1_NODIRECT;
12829 }
12830 if (val & DF_1_IGNMULDEF)
12831 {
12832 printf (" IGNMULDEF");
12833 val ^= DF_1_IGNMULDEF;
12834 }
12835 if (val & DF_1_NOKSYMS)
12836 {
12837 printf (" NOKSYMS");
12838 val ^= DF_1_NOKSYMS;
12839 }
12840 if (val & DF_1_NOHDR)
12841 {
12842 printf (" NOHDR");
12843 val ^= DF_1_NOHDR;
12844 }
12845 if (val & DF_1_EDITED)
12846 {
12847 printf (" EDITED");
12848 val ^= DF_1_EDITED;
12849 }
12850 if (val & DF_1_NORELOC)
12851 {
12852 printf (" NORELOC");
12853 val ^= DF_1_NORELOC;
12854 }
12855 if (val & DF_1_SYMINTPOSE)
12856 {
12857 printf (" SYMINTPOSE");
12858 val ^= DF_1_SYMINTPOSE;
12859 }
12860 if (val & DF_1_GLOBAUDIT)
12861 {
12862 printf (" GLOBAUDIT");
12863 val ^= DF_1_GLOBAUDIT;
12864 }
12865 if (val & DF_1_SINGLETON)
12866 {
12867 printf (" SINGLETON");
12868 val ^= DF_1_SINGLETON;
dcefbbbd 12869 }
5c383f02
RO
12870 if (val & DF_1_STUB)
12871 {
12872 printf (" STUB");
12873 val ^= DF_1_STUB;
12874 }
12875 if (val & DF_1_PIE)
12876 {
12877 printf (" PIE");
12878 val ^= DF_1_PIE;
12879 }
b1202ffa
L
12880 if (val & DF_1_KMOD)
12881 {
12882 printf (" KMOD");
12883 val ^= DF_1_KMOD;
12884 }
12885 if (val & DF_1_WEAKFILTER)
12886 {
12887 printf (" WEAKFILTER");
12888 val ^= DF_1_WEAKFILTER;
12889 }
12890 if (val & DF_1_NOCOMMON)
12891 {
12892 printf (" NOCOMMON");
12893 val ^= DF_1_NOCOMMON;
12894 }
252b5132 12895 if (val != 0)
26c527e6 12896 printf (" %" PRIx64, val);
252b5132
RH
12897 puts ("");
12898 }
12899 }
12900 break;
12901
12902 case DT_PLTREL:
978c4450 12903 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12904 if (do_dynamic)
dda8d76d 12905 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12906 break;
12907
12908 case DT_NULL :
12909 case DT_NEEDED :
12910 case DT_PLTGOT :
12911 case DT_HASH :
12912 case DT_STRTAB :
12913 case DT_SYMTAB :
12914 case DT_RELA :
12915 case DT_INIT :
12916 case DT_FINI :
12917 case DT_SONAME :
12918 case DT_RPATH :
12919 case DT_SYMBOLIC:
12920 case DT_REL :
a7fd1186 12921 case DT_RELR :
252b5132
RH
12922 case DT_DEBUG :
12923 case DT_TEXTREL :
12924 case DT_JMPREL :
019148e4 12925 case DT_RUNPATH :
978c4450 12926 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12927
12928 if (do_dynamic)
12929 {
84714f86 12930 const char *name;
252b5132 12931
84714f86
AM
12932 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12933 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12934 else
d79b3d50 12935 name = NULL;
252b5132
RH
12936
12937 if (name)
12938 {
12939 switch (entry->d_tag)
12940 {
12941 case DT_NEEDED:
12942 printf (_("Shared library: [%s]"), name);
12943
13acb58d
AM
12944 if (filedata->program_interpreter
12945 && streq (name, filedata->program_interpreter))
f7a99963 12946 printf (_(" program interpreter"));
252b5132
RH
12947 break;
12948
12949 case DT_SONAME:
f7a99963 12950 printf (_("Library soname: [%s]"), name);
252b5132
RH
12951 break;
12952
12953 case DT_RPATH:
f7a99963 12954 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12955 break;
12956
019148e4
L
12957 case DT_RUNPATH:
12958 printf (_("Library runpath: [%s]"), name);
12959 break;
12960
252b5132 12961 default:
f7a99963
NC
12962 print_vma (entry->d_un.d_val, PREFIX_HEX);
12963 break;
252b5132
RH
12964 }
12965 }
12966 else
f7a99963
NC
12967 print_vma (entry->d_un.d_val, PREFIX_HEX);
12968
12969 putchar ('\n');
252b5132
RH
12970 }
12971 break;
12972
12973 case DT_PLTRELSZ:
12974 case DT_RELASZ :
12975 case DT_STRSZ :
12976 case DT_RELSZ :
12977 case DT_RELAENT :
a7fd1186
FS
12978 case DT_RELRENT :
12979 case DT_RELRSZ :
252b5132
RH
12980 case DT_SYMENT :
12981 case DT_RELENT :
978c4450 12982 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12983 /* Fall through. */
252b5132
RH
12984 case DT_PLTPADSZ:
12985 case DT_MOVEENT :
12986 case DT_MOVESZ :
04d8355a 12987 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12988 case DT_INIT_ARRAYSZ:
12989 case DT_FINI_ARRAYSZ:
047b2264
JJ
12990 case DT_GNU_CONFLICTSZ:
12991 case DT_GNU_LIBLISTSZ:
252b5132 12992 if (do_dynamic)
f7a99963
NC
12993 {
12994 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12995 printf (_(" (bytes)\n"));
f7a99963 12996 }
252b5132
RH
12997 break;
12998
12999 case DT_VERDEFNUM:
13000 case DT_VERNEEDNUM:
13001 case DT_RELACOUNT:
13002 case DT_RELCOUNT:
13003 if (do_dynamic)
f7a99963
NC
13004 {
13005 print_vma (entry->d_un.d_val, UNSIGNED);
13006 putchar ('\n');
13007 }
252b5132
RH
13008 break;
13009
13010 case DT_SYMINSZ:
13011 case DT_SYMINENT:
13012 case DT_SYMINFO:
13013 case DT_USED:
13014 case DT_INIT_ARRAY:
13015 case DT_FINI_ARRAY:
13016 if (do_dynamic)
13017 {
d79b3d50 13018 if (entry->d_tag == DT_USED
84714f86 13019 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 13020 {
84714f86
AM
13021 const char *name
13022 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 13023
b34976b6 13024 if (*name)
252b5132
RH
13025 {
13026 printf (_("Not needed object: [%s]\n"), name);
13027 break;
13028 }
13029 }
103f02d3 13030
f7a99963
NC
13031 print_vma (entry->d_un.d_val, PREFIX_HEX);
13032 putchar ('\n');
252b5132
RH
13033 }
13034 break;
13035
13036 case DT_BIND_NOW:
13037 /* The value of this entry is ignored. */
35b1837e
AM
13038 if (do_dynamic)
13039 putchar ('\n');
252b5132 13040 break;
103f02d3 13041
047b2264
JJ
13042 case DT_GNU_PRELINKED:
13043 if (do_dynamic)
13044 {
2cf0635d 13045 struct tm * tmp;
91d6fa6a 13046 time_t atime = entry->d_un.d_val;
047b2264 13047
91d6fa6a 13048 tmp = gmtime (&atime);
071436c6
NC
13049 /* PR 17533 file: 041-1244816-0.004. */
13050 if (tmp == NULL)
26c527e6
AM
13051 printf (_("<corrupt time val: %" PRIx64),
13052 (uint64_t) atime);
071436c6
NC
13053 else
13054 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
13055 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13056 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13057
13058 }
13059 break;
13060
fdc90cb4 13061 case DT_GNU_HASH:
978c4450 13062 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
13063 if (do_dynamic)
13064 {
13065 print_vma (entry->d_un.d_val, PREFIX_HEX);
13066 putchar ('\n');
13067 }
13068 break;
13069
a5da3dee
VDM
13070 case DT_GNU_FLAGS_1:
13071 if (do_dynamic)
13072 {
13073 printf (_("Flags:"));
13074 if (entry->d_un.d_val == 0)
13075 printf (_(" None\n"));
13076 else
13077 {
26c527e6 13078 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
13079
13080 if (val & DF_GNU_1_UNIQUE)
13081 {
13082 printf (" UNIQUE");
13083 val ^= DF_GNU_1_UNIQUE;
13084 }
13085 if (val != 0)
26c527e6 13086 printf (" %" PRIx64, val);
a5da3dee
VDM
13087 puts ("");
13088 }
13089 }
13090 break;
13091
252b5132
RH
13092 default:
13093 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
13094 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
13095 = entry->d_un.d_val;
252b5132
RH
13096
13097 if (do_dynamic)
13098 {
dda8d76d 13099 switch (filedata->file_header.e_machine)
252b5132 13100 {
37c18eed
SD
13101 case EM_AARCH64:
13102 dynamic_section_aarch64_val (entry);
13103 break;
252b5132 13104 case EM_MIPS:
4fe85591 13105 case EM_MIPS_RS3_LE:
978c4450 13106 dynamic_section_mips_val (filedata, entry);
252b5132 13107 break;
103f02d3 13108 case EM_PARISC:
b2d38a17 13109 dynamic_section_parisc_val (entry);
103f02d3 13110 break;
ecc51f48 13111 case EM_IA_64:
b2d38a17 13112 dynamic_section_ia64_val (entry);
ecc51f48 13113 break;
252b5132 13114 default:
f7a99963
NC
13115 print_vma (entry->d_un.d_val, PREFIX_HEX);
13116 putchar ('\n');
252b5132
RH
13117 }
13118 }
13119 break;
13120 }
13121 }
13122
015dc7e1 13123 return true;
252b5132
RH
13124}
13125
13126static char *
d3ba0551 13127get_ver_flags (unsigned int flags)
252b5132 13128{
6d4f21f6 13129 static char buff[128];
252b5132
RH
13130
13131 buff[0] = 0;
13132
13133 if (flags == 0)
13134 return _("none");
13135
13136 if (flags & VER_FLG_BASE)
7bb1ad17 13137 strcat (buff, "BASE");
252b5132
RH
13138
13139 if (flags & VER_FLG_WEAK)
13140 {
13141 if (flags & VER_FLG_BASE)
7bb1ad17 13142 strcat (buff, " | ");
252b5132 13143
7bb1ad17 13144 strcat (buff, "WEAK");
252b5132
RH
13145 }
13146
44ec90b9
RO
13147 if (flags & VER_FLG_INFO)
13148 {
13149 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 13150 strcat (buff, " | ");
44ec90b9 13151
7bb1ad17 13152 strcat (buff, "INFO");
44ec90b9
RO
13153 }
13154
13155 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
13156 {
13157 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13158 strcat (buff, " | ");
13159
13160 strcat (buff, _("<unknown>"));
13161 }
252b5132
RH
13162
13163 return buff;
13164}
13165
13166/* Display the contents of the version sections. */
98fb390a 13167
015dc7e1 13168static bool
dda8d76d 13169process_version_sections (Filedata * filedata)
252b5132 13170{
2cf0635d 13171 Elf_Internal_Shdr * section;
b34976b6 13172 unsigned i;
015dc7e1 13173 bool found = false;
252b5132
RH
13174
13175 if (! do_version)
015dc7e1 13176 return true;
252b5132 13177
dda8d76d
NC
13178 for (i = 0, section = filedata->section_headers;
13179 i < filedata->file_header.e_shnum;
b34976b6 13180 i++, section++)
252b5132
RH
13181 {
13182 switch (section->sh_type)
13183 {
13184 case SHT_GNU_verdef:
13185 {
2cf0635d 13186 Elf_External_Verdef * edefs;
26c527e6
AM
13187 size_t idx;
13188 size_t cnt;
2cf0635d 13189 char * endbuf;
252b5132 13190
015dc7e1 13191 found = true;
252b5132 13192
ca0e11aa
NC
13193 if (filedata->is_separate)
13194 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
13195 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
13196 section->sh_info),
13197 filedata->file_name,
13198 printable_section_name (filedata, section),
13199 section->sh_info);
13200 else
13201 printf (ngettext ("\nVersion definition section '%s' "
13202 "contains %u entry:\n",
13203 "\nVersion definition section '%s' "
13204 "contains %u entries:\n",
13205 section->sh_info),
13206 printable_section_name (filedata, section),
13207 section->sh_info);
047c3dbf 13208
625d49fc 13209 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13210 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13211 section->sh_offset, section->sh_link,
b6ac461a 13212 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 13213
3f5e193b 13214 edefs = (Elf_External_Verdef *)
dda8d76d 13215 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 13216 _("version definition section"));
a6e9f9df
AM
13217 if (!edefs)
13218 break;
59245841 13219 endbuf = (char *) edefs + section->sh_size;
252b5132 13220
1445030f 13221 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 13222 {
2cf0635d
NC
13223 char * vstart;
13224 Elf_External_Verdef * edef;
b34976b6 13225 Elf_Internal_Verdef ent;
2cf0635d 13226 Elf_External_Verdaux * eaux;
b34976b6 13227 Elf_Internal_Verdaux aux;
26c527e6 13228 size_t isum;
b34976b6 13229 int j;
103f02d3 13230
252b5132 13231 vstart = ((char *) edefs) + idx;
54806181
AM
13232 if (vstart + sizeof (*edef) > endbuf)
13233 break;
252b5132
RH
13234
13235 edef = (Elf_External_Verdef *) vstart;
13236
13237 ent.vd_version = BYTE_GET (edef->vd_version);
13238 ent.vd_flags = BYTE_GET (edef->vd_flags);
13239 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
13240 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
13241 ent.vd_hash = BYTE_GET (edef->vd_hash);
13242 ent.vd_aux = BYTE_GET (edef->vd_aux);
13243 ent.vd_next = BYTE_GET (edef->vd_next);
13244
26c527e6 13245 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
13246 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
13247
13248 printf (_(" Index: %d Cnt: %d "),
13249 ent.vd_ndx, ent.vd_cnt);
13250
452bf675 13251 /* Check for overflow. */
1445030f 13252 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
13253 break;
13254
252b5132
RH
13255 vstart += ent.vd_aux;
13256
1445030f
AM
13257 if (vstart + sizeof (*eaux) > endbuf)
13258 break;
252b5132
RH
13259 eaux = (Elf_External_Verdaux *) vstart;
13260
13261 aux.vda_name = BYTE_GET (eaux->vda_name);
13262 aux.vda_next = BYTE_GET (eaux->vda_next);
13263
84714f86 13264 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 13265 printf (_("Name: %s\n"),
84714f86 13266 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
13267 else
13268 printf (_("Name index: %ld\n"), aux.vda_name);
13269
13270 isum = idx + ent.vd_aux;
13271
b34976b6 13272 for (j = 1; j < ent.vd_cnt; j++)
252b5132 13273 {
1445030f
AM
13274 if (aux.vda_next < sizeof (*eaux)
13275 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
13276 {
13277 warn (_("Invalid vda_next field of %lx\n"),
13278 aux.vda_next);
13279 j = ent.vd_cnt;
13280 break;
13281 }
dd24e3da 13282 /* Check for overflow. */
7e26601c 13283 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
13284 break;
13285
252b5132
RH
13286 isum += aux.vda_next;
13287 vstart += aux.vda_next;
13288
54806181
AM
13289 if (vstart + sizeof (*eaux) > endbuf)
13290 break;
1445030f 13291 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
13292
13293 aux.vda_name = BYTE_GET (eaux->vda_name);
13294 aux.vda_next = BYTE_GET (eaux->vda_next);
13295
84714f86 13296 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 13297 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 13298 isum, j,
84714f86 13299 get_dynamic_name (filedata, aux.vda_name));
252b5132 13300 else
26c527e6 13301 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
13302 isum, j, aux.vda_name);
13303 }
dd24e3da 13304
54806181
AM
13305 if (j < ent.vd_cnt)
13306 printf (_(" Version def aux past end of section\n"));
252b5132 13307
c9f02c3e
MR
13308 /* PR 17531:
13309 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
13310 if (ent.vd_next < sizeof (*edef)
13311 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13312 {
13313 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13314 cnt = section->sh_info;
13315 break;
13316 }
452bf675 13317 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
13318 break;
13319
252b5132
RH
13320 idx += ent.vd_next;
13321 }
dd24e3da 13322
54806181
AM
13323 if (cnt < section->sh_info)
13324 printf (_(" Version definition past end of section\n"));
252b5132
RH
13325
13326 free (edefs);
13327 }
13328 break;
103f02d3 13329
252b5132
RH
13330 case SHT_GNU_verneed:
13331 {
2cf0635d 13332 Elf_External_Verneed * eneed;
26c527e6
AM
13333 size_t idx;
13334 size_t cnt;
2cf0635d 13335 char * endbuf;
252b5132 13336
015dc7e1 13337 found = true;
252b5132 13338
ca0e11aa
NC
13339 if (filedata->is_separate)
13340 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13341 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13342 section->sh_info),
13343 filedata->file_name,
13344 printable_section_name (filedata, section),
13345 section->sh_info);
13346 else
13347 printf (ngettext ("\nVersion needs section '%s' "
13348 "contains %u entry:\n",
13349 "\nVersion needs section '%s' "
13350 "contains %u entries:\n",
13351 section->sh_info),
13352 printable_section_name (filedata, section),
13353 section->sh_info);
047c3dbf 13354
625d49fc 13355 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13356 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13357 section->sh_offset, section->sh_link,
b6ac461a 13358 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 13359
dda8d76d 13360 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
13361 section->sh_offset, 1,
13362 section->sh_size,
9cf03b7e 13363 _("Version Needs section"));
a6e9f9df
AM
13364 if (!eneed)
13365 break;
59245841 13366 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
13367
13368 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13369 {
2cf0635d 13370 Elf_External_Verneed * entry;
b34976b6 13371 Elf_Internal_Verneed ent;
26c527e6 13372 size_t isum;
b34976b6 13373 int j;
2cf0635d 13374 char * vstart;
252b5132
RH
13375
13376 vstart = ((char *) eneed) + idx;
54806181
AM
13377 if (vstart + sizeof (*entry) > endbuf)
13378 break;
252b5132
RH
13379
13380 entry = (Elf_External_Verneed *) vstart;
13381
13382 ent.vn_version = BYTE_GET (entry->vn_version);
13383 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13384 ent.vn_file = BYTE_GET (entry->vn_file);
13385 ent.vn_aux = BYTE_GET (entry->vn_aux);
13386 ent.vn_next = BYTE_GET (entry->vn_next);
13387
26c527e6 13388 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 13389
84714f86 13390 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 13391 printf (_(" File: %s"),
84714f86 13392 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
13393 else
13394 printf (_(" File: %lx"), ent.vn_file);
13395
13396 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13397
dd24e3da 13398 /* Check for overflow. */
7e26601c 13399 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 13400 break;
252b5132
RH
13401 vstart += ent.vn_aux;
13402
13403 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13404 {
2cf0635d 13405 Elf_External_Vernaux * eaux;
b34976b6 13406 Elf_Internal_Vernaux aux;
252b5132 13407
54806181
AM
13408 if (vstart + sizeof (*eaux) > endbuf)
13409 break;
252b5132
RH
13410 eaux = (Elf_External_Vernaux *) vstart;
13411
13412 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13413 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13414 aux.vna_other = BYTE_GET (eaux->vna_other);
13415 aux.vna_name = BYTE_GET (eaux->vna_name);
13416 aux.vna_next = BYTE_GET (eaux->vna_next);
13417
84714f86 13418 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 13419 printf (_(" %#06zx: Name: %s"),
84714f86 13420 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 13421 else
26c527e6 13422 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
13423 isum, aux.vna_name);
13424
13425 printf (_(" Flags: %s Version: %d\n"),
13426 get_ver_flags (aux.vna_flags), aux.vna_other);
13427
1445030f
AM
13428 if (aux.vna_next < sizeof (*eaux)
13429 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
13430 {
13431 warn (_("Invalid vna_next field of %lx\n"),
13432 aux.vna_next);
13433 j = ent.vn_cnt;
13434 break;
13435 }
1445030f
AM
13436 /* Check for overflow. */
13437 if (aux.vna_next > (size_t) (endbuf - vstart))
13438 break;
252b5132
RH
13439 isum += aux.vna_next;
13440 vstart += aux.vna_next;
13441 }
9cf03b7e 13442
54806181 13443 if (j < ent.vn_cnt)
f9a6a8f0 13444 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 13445
1445030f
AM
13446 if (ent.vn_next < sizeof (*entry)
13447 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 13448 {
452bf675 13449 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
13450 cnt = section->sh_info;
13451 break;
13452 }
1445030f
AM
13453 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13454 break;
252b5132
RH
13455 idx += ent.vn_next;
13456 }
9cf03b7e 13457
54806181 13458 if (cnt < section->sh_info)
9cf03b7e 13459 warn (_("Missing Version Needs information\n"));
103f02d3 13460
252b5132
RH
13461 free (eneed);
13462 }
13463 break;
13464
13465 case SHT_GNU_versym:
13466 {
2cf0635d 13467 Elf_Internal_Shdr * link_section;
26c527e6 13468 uint64_t total;
8b73c356 13469 unsigned int cnt;
2cf0635d
NC
13470 unsigned char * edata;
13471 unsigned short * data;
13472 char * strtab;
13473 Elf_Internal_Sym * symbols;
13474 Elf_Internal_Shdr * string_sec;
26c527e6
AM
13475 uint64_t num_syms;
13476 uint64_t off;
252b5132 13477
dda8d76d 13478 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13479 break;
13480
dda8d76d 13481 link_section = filedata->section_headers + section->sh_link;
08d8fa11 13482 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 13483
dda8d76d 13484 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13485 break;
13486
015dc7e1 13487 found = true;
252b5132 13488
4de91c10 13489 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
13490 if (symbols == NULL)
13491 break;
252b5132 13492
dda8d76d 13493 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 13494
dda8d76d 13495 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
13496 string_sec->sh_size,
13497 _("version string table"));
a6e9f9df 13498 if (!strtab)
0429c154
MS
13499 {
13500 free (symbols);
13501 break;
13502 }
252b5132 13503
ca0e11aa 13504 if (filedata->is_separate)
26c527e6
AM
13505 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13506 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13507 total),
13508 filedata->file_name,
13509 printable_section_name (filedata, section),
26c527e6 13510 total);
ca0e11aa
NC
13511 else
13512 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 13513 "contains %" PRIu64 " entry:\n",
ca0e11aa 13514 "\nVersion symbols section '%s' "
26c527e6 13515 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13516 total),
13517 printable_section_name (filedata, section),
26c527e6 13518 total);
252b5132 13519
625d49fc 13520 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13521 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13522 section->sh_offset, section->sh_link,
dda8d76d 13523 printable_section_name (filedata, link_section));
252b5132 13524
dda8d76d 13525 off = offset_from_vma (filedata,
978c4450 13526 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 13527 total * sizeof (short));
95099889
AM
13528 edata = (unsigned char *) get_data (NULL, filedata, off,
13529 sizeof (short), total,
13530 _("version symbol data"));
a6e9f9df
AM
13531 if (!edata)
13532 {
13533 free (strtab);
0429c154 13534 free (symbols);
a6e9f9df
AM
13535 break;
13536 }
252b5132 13537
3f5e193b 13538 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
13539
13540 for (cnt = total; cnt --;)
b34976b6
AM
13541 data[cnt] = byte_get (edata + cnt * sizeof (short),
13542 sizeof (short));
252b5132
RH
13543
13544 free (edata);
13545
13546 for (cnt = 0; cnt < total; cnt += 4)
13547 {
13548 int j, nn;
ab273396
AM
13549 char *name;
13550 char *invalid = _("*invalid*");
252b5132
RH
13551
13552 printf (" %03x:", cnt);
13553
13554 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 13555 switch (data[cnt + j])
252b5132
RH
13556 {
13557 case 0:
13558 fputs (_(" 0 (*local*) "), stdout);
13559 break;
13560
13561 case 1:
13562 fputs (_(" 1 (*global*) "), stdout);
13563 break;
13564
13565 default:
c244d050
NC
13566 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13567 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 13568
dd24e3da 13569 /* If this index value is greater than the size of the symbols
ba5cdace 13570 array, break to avoid an out-of-bounds read. */
26c527e6 13571 if (cnt + j >= num_syms)
dd24e3da
NC
13572 {
13573 warn (_("invalid index into symbol array\n"));
13574 break;
13575 }
13576
ab273396 13577 name = NULL;
978c4450 13578 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13579 {
b34976b6 13580 Elf_Internal_Verneed ivn;
26c527e6 13581 uint64_t offset;
252b5132 13582
d93f0186 13583 offset = offset_from_vma
978c4450
AM
13584 (filedata,
13585 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13586 sizeof (Elf_External_Verneed));
252b5132 13587
b34976b6 13588 do
252b5132 13589 {
b34976b6
AM
13590 Elf_Internal_Vernaux ivna;
13591 Elf_External_Verneed evn;
13592 Elf_External_Vernaux evna;
26c527e6 13593 uint64_t a_off;
252b5132 13594
dda8d76d 13595 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13596 _("version need")) == NULL)
13597 break;
0b4362b0 13598
252b5132
RH
13599 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13600 ivn.vn_next = BYTE_GET (evn.vn_next);
13601
13602 a_off = offset + ivn.vn_aux;
13603
13604 do
13605 {
dda8d76d 13606 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13607 1, _("version need aux (2)")) == NULL)
13608 {
13609 ivna.vna_next = 0;
13610 ivna.vna_other = 0;
13611 }
13612 else
13613 {
13614 ivna.vna_next = BYTE_GET (evna.vna_next);
13615 ivna.vna_other = BYTE_GET (evna.vna_other);
13616 }
252b5132
RH
13617
13618 a_off += ivna.vna_next;
13619 }
b34976b6 13620 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13621 && ivna.vna_next != 0);
13622
b34976b6 13623 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13624 {
13625 ivna.vna_name = BYTE_GET (evna.vna_name);
13626
54806181 13627 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13628 name = invalid;
54806181
AM
13629 else
13630 name = strtab + ivna.vna_name;
252b5132
RH
13631 break;
13632 }
13633
13634 offset += ivn.vn_next;
13635 }
13636 while (ivn.vn_next);
13637 }
00d93f34 13638
ab273396 13639 if (data[cnt + j] != 0x8001
978c4450 13640 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13641 {
b34976b6
AM
13642 Elf_Internal_Verdef ivd;
13643 Elf_External_Verdef evd;
26c527e6 13644 uint64_t offset;
252b5132 13645
d93f0186 13646 offset = offset_from_vma
978c4450
AM
13647 (filedata,
13648 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13649 sizeof evd);
252b5132
RH
13650
13651 do
13652 {
dda8d76d 13653 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13654 _("version def")) == NULL)
13655 {
13656 ivd.vd_next = 0;
948f632f 13657 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13658 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13659 break;
59245841
NC
13660 }
13661 else
13662 {
13663 ivd.vd_next = BYTE_GET (evd.vd_next);
13664 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13665 }
252b5132
RH
13666
13667 offset += ivd.vd_next;
13668 }
c244d050 13669 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13670 && ivd.vd_next != 0);
13671
c244d050 13672 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13673 {
b34976b6
AM
13674 Elf_External_Verdaux evda;
13675 Elf_Internal_Verdaux ivda;
252b5132
RH
13676
13677 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13678
dda8d76d 13679 if (get_data (&evda, filedata,
59245841
NC
13680 offset - ivd.vd_next + ivd.vd_aux,
13681 sizeof (evda), 1,
13682 _("version def aux")) == NULL)
13683 break;
252b5132
RH
13684
13685 ivda.vda_name = BYTE_GET (evda.vda_name);
13686
54806181 13687 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13688 name = invalid;
13689 else if (name != NULL && name != invalid)
13690 name = _("*both*");
54806181
AM
13691 else
13692 name = strtab + ivda.vda_name;
252b5132
RH
13693 }
13694 }
ab273396
AM
13695 if (name != NULL)
13696 nn += printf ("(%s%-*s",
13697 name,
13698 12 - (int) strlen (name),
13699 ")");
252b5132
RH
13700
13701 if (nn < 18)
13702 printf ("%*c", 18 - nn, ' ');
13703 }
13704
13705 putchar ('\n');
13706 }
13707
13708 free (data);
13709 free (strtab);
13710 free (symbols);
13711 }
13712 break;
103f02d3 13713
252b5132
RH
13714 default:
13715 break;
13716 }
13717 }
13718
13719 if (! found)
ca0e11aa
NC
13720 {
13721 if (filedata->is_separate)
13722 printf (_("\nNo version information found in linked file '%s'.\n"),
13723 filedata->file_name);
13724 else
13725 printf (_("\nNo version information found in this file.\n"));
13726 }
252b5132 13727
015dc7e1 13728 return true;
252b5132
RH
13729}
13730
d1133906 13731static const char *
dda8d76d 13732get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13733{
89246a0e 13734 static char buff[64];
252b5132
RH
13735
13736 switch (binding)
13737 {
b34976b6
AM
13738 case STB_LOCAL: return "LOCAL";
13739 case STB_GLOBAL: return "GLOBAL";
13740 case STB_WEAK: return "WEAK";
252b5132
RH
13741 default:
13742 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13743 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13744 binding);
252b5132 13745 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13746 {
13747 if (binding == STB_GNU_UNIQUE
df3a023b 13748 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13749 return "UNIQUE";
13750 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13751 }
252b5132 13752 else
e9e44622 13753 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13754 return buff;
13755 }
13756}
13757
d1133906 13758static const char *
dda8d76d 13759get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13760{
89246a0e 13761 static char buff[64];
252b5132
RH
13762
13763 switch (type)
13764 {
b34976b6
AM
13765 case STT_NOTYPE: return "NOTYPE";
13766 case STT_OBJECT: return "OBJECT";
13767 case STT_FUNC: return "FUNC";
13768 case STT_SECTION: return "SECTION";
13769 case STT_FILE: return "FILE";
13770 case STT_COMMON: return "COMMON";
13771 case STT_TLS: return "TLS";
15ab5209
DB
13772 case STT_RELC: return "RELC";
13773 case STT_SRELC: return "SRELC";
252b5132
RH
13774 default:
13775 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13776 {
dda8d76d 13777 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13778 return "THUMB_FUNC";
103f02d3 13779
dda8d76d 13780 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13781 return "REGISTER";
13782
dda8d76d 13783 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13784 return "PARISC_MILLI";
13785
e9e44622 13786 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13787 }
252b5132 13788 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13789 {
dda8d76d 13790 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13791 {
13792 if (type == STT_HP_OPAQUE)
13793 return "HP_OPAQUE";
13794 if (type == STT_HP_STUB)
13795 return "HP_STUB";
13796 }
13797
8654c01f
ML
13798 if (type == STT_GNU_IFUNC
13799 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13800 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13801 return "IFUNC";
13802
e9e44622 13803 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13804 }
252b5132 13805 else
e9e44622 13806 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13807 return buff;
13808 }
13809}
13810
d1133906 13811static const char *
d3ba0551 13812get_symbol_visibility (unsigned int visibility)
d1133906
NC
13813{
13814 switch (visibility)
13815 {
b34976b6
AM
13816 case STV_DEFAULT: return "DEFAULT";
13817 case STV_INTERNAL: return "INTERNAL";
13818 case STV_HIDDEN: return "HIDDEN";
d1133906 13819 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13820 default:
27a45f42 13821 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13822 return _("<unknown>");
d1133906
NC
13823 }
13824}
13825
2057d69d
CZ
13826static const char *
13827get_alpha_symbol_other (unsigned int other)
9abca702 13828{
2057d69d
CZ
13829 switch (other)
13830 {
13831 case STO_ALPHA_NOPV: return "NOPV";
13832 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13833 default:
27a45f42 13834 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13835 return _("<unknown>");
9abca702 13836 }
2057d69d
CZ
13837}
13838
fd85a6a1
NC
13839static const char *
13840get_solaris_symbol_visibility (unsigned int visibility)
13841{
13842 switch (visibility)
13843 {
13844 case 4: return "EXPORTED";
13845 case 5: return "SINGLETON";
13846 case 6: return "ELIMINATE";
13847 default: return get_symbol_visibility (visibility);
13848 }
13849}
13850
2301ed1c
SN
13851static const char *
13852get_aarch64_symbol_other (unsigned int other)
13853{
13854 static char buf[32];
13855
13856 if (other & STO_AARCH64_VARIANT_PCS)
13857 {
13858 other &= ~STO_AARCH64_VARIANT_PCS;
13859 if (other == 0)
13860 return "VARIANT_PCS";
13861 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13862 return buf;
13863 }
13864 return NULL;
13865}
13866
5e2b0d47
NC
13867static const char *
13868get_mips_symbol_other (unsigned int other)
13869{
13870 switch (other)
13871 {
32ec8896
NC
13872 case STO_OPTIONAL: return "OPTIONAL";
13873 case STO_MIPS_PLT: return "MIPS PLT";
13874 case STO_MIPS_PIC: return "MIPS PIC";
13875 case STO_MICROMIPS: return "MICROMIPS";
13876 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13877 case STO_MIPS16: return "MIPS16";
13878 default: return NULL;
5e2b0d47
NC
13879 }
13880}
13881
28f997cf 13882static const char *
dda8d76d 13883get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13884{
dda8d76d 13885 if (is_ia64_vms (filedata))
28f997cf
TG
13886 {
13887 static char res[32];
13888
13889 res[0] = 0;
13890
13891 /* Function types is for images and .STB files only. */
dda8d76d 13892 switch (filedata->file_header.e_type)
28f997cf
TG
13893 {
13894 case ET_DYN:
13895 case ET_EXEC:
13896 switch (VMS_ST_FUNC_TYPE (other))
13897 {
13898 case VMS_SFT_CODE_ADDR:
13899 strcat (res, " CA");
13900 break;
13901 case VMS_SFT_SYMV_IDX:
13902 strcat (res, " VEC");
13903 break;
13904 case VMS_SFT_FD:
13905 strcat (res, " FD");
13906 break;
13907 case VMS_SFT_RESERVE:
13908 strcat (res, " RSV");
13909 break;
13910 default:
bee0ee85
NC
13911 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13912 VMS_ST_FUNC_TYPE (other));
13913 strcat (res, " <unknown>");
13914 break;
28f997cf
TG
13915 }
13916 break;
13917 default:
13918 break;
13919 }
13920 switch (VMS_ST_LINKAGE (other))
13921 {
13922 case VMS_STL_IGNORE:
13923 strcat (res, " IGN");
13924 break;
13925 case VMS_STL_RESERVE:
13926 strcat (res, " RSV");
13927 break;
13928 case VMS_STL_STD:
13929 strcat (res, " STD");
13930 break;
13931 case VMS_STL_LNK:
13932 strcat (res, " LNK");
13933 break;
13934 default:
bee0ee85
NC
13935 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13936 VMS_ST_LINKAGE (other));
13937 strcat (res, " <unknown>");
13938 break;
28f997cf
TG
13939 }
13940
13941 if (res[0] != 0)
13942 return res + 1;
13943 else
13944 return res;
13945 }
13946 return NULL;
13947}
13948
6911b7dc
AM
13949static const char *
13950get_ppc64_symbol_other (unsigned int other)
13951{
14732552
AM
13952 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13953 return NULL;
13954
13955 other >>= STO_PPC64_LOCAL_BIT;
13956 if (other <= 6)
6911b7dc 13957 {
89246a0e 13958 static char buf[64];
14732552
AM
13959 if (other >= 2)
13960 other = ppc64_decode_local_entry (other);
13961 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13962 return buf;
13963 }
13964 return NULL;
13965}
13966
8155b853
NC
13967static const char *
13968get_riscv_symbol_other (unsigned int other)
13969{
13970 static char buf[32];
13971 buf[0] = 0;
13972
13973 if (other & STO_RISCV_VARIANT_CC)
13974 {
13975 strcat (buf, _(" VARIANT_CC"));
13976 other &= ~STO_RISCV_VARIANT_CC;
13977 }
13978
13979 if (other != 0)
13980 snprintf (buf, sizeof buf, " %x", other);
13981
13982
13983 if (buf[0] != 0)
13984 return buf + 1;
13985 else
13986 return buf;
13987}
13988
5e2b0d47 13989static const char *
dda8d76d 13990get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13991{
13992 const char * result = NULL;
89246a0e 13993 static char buff [64];
5e2b0d47
NC
13994
13995 if (other == 0)
13996 return "";
13997
dda8d76d 13998 switch (filedata->file_header.e_machine)
5e2b0d47 13999 {
2057d69d
CZ
14000 case EM_ALPHA:
14001 result = get_alpha_symbol_other (other);
14002 break;
2301ed1c
SN
14003 case EM_AARCH64:
14004 result = get_aarch64_symbol_other (other);
14005 break;
5e2b0d47
NC
14006 case EM_MIPS:
14007 result = get_mips_symbol_other (other);
28f997cf
TG
14008 break;
14009 case EM_IA_64:
dda8d76d 14010 result = get_ia64_symbol_other (filedata, other);
28f997cf 14011 break;
6911b7dc
AM
14012 case EM_PPC64:
14013 result = get_ppc64_symbol_other (other);
14014 break;
8155b853
NC
14015 case EM_RISCV:
14016 result = get_riscv_symbol_other (other);
14017 break;
5e2b0d47 14018 default:
fd85a6a1 14019 result = NULL;
5e2b0d47
NC
14020 break;
14021 }
14022
14023 if (result)
14024 return result;
14025
14026 snprintf (buff, sizeof buff, _("<other>: %x"), other);
14027 return buff;
14028}
14029
bb4d2ac2 14030static const char *
26c527e6
AM
14031get_symbol_version_string (Filedata *filedata,
14032 bool is_dynsym,
14033 const char *strtab,
14034 size_t strtab_size,
14035 unsigned int si,
14036 Elf_Internal_Sym *psym,
14037 enum versioned_symbol_info *sym_info,
14038 unsigned short *vna_other)
bb4d2ac2 14039{
ab273396
AM
14040 unsigned char data[2];
14041 unsigned short vers_data;
26c527e6 14042 uint64_t offset;
7a815dd5 14043 unsigned short max_vd_ndx;
bb4d2ac2 14044
ab273396 14045 if (!is_dynsym
978c4450 14046 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 14047 return NULL;
bb4d2ac2 14048
978c4450
AM
14049 offset = offset_from_vma (filedata,
14050 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 14051 sizeof data + si * sizeof (vers_data));
bb4d2ac2 14052
dda8d76d 14053 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
14054 sizeof (data), 1, _("version data")) == NULL)
14055 return NULL;
14056
14057 vers_data = byte_get (data, 2);
bb4d2ac2 14058
1f6f5dba 14059 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 14060 return NULL;
bb4d2ac2 14061
0b8b7609 14062 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
14063 max_vd_ndx = 0;
14064
ab273396
AM
14065 /* Usually we'd only see verdef for defined symbols, and verneed for
14066 undefined symbols. However, symbols defined by the linker in
14067 .dynbss for variables copied from a shared library in order to
14068 avoid text relocations are defined yet have verneed. We could
14069 use a heuristic to detect the special case, for example, check
14070 for verneed first on symbols defined in SHT_NOBITS sections, but
14071 it is simpler and more reliable to just look for both verdef and
14072 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 14073
ab273396
AM
14074 if (psym->st_shndx != SHN_UNDEF
14075 && vers_data != 0x8001
978c4450 14076 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
14077 {
14078 Elf_Internal_Verdef ivd;
14079 Elf_Internal_Verdaux ivda;
14080 Elf_External_Verdaux evda;
26c527e6 14081 uint64_t off;
bb4d2ac2 14082
dda8d76d 14083 off = offset_from_vma (filedata,
978c4450 14084 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
14085 sizeof (Elf_External_Verdef));
14086
14087 do
bb4d2ac2 14088 {
ab273396
AM
14089 Elf_External_Verdef evd;
14090
dda8d76d 14091 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
14092 _("version def")) == NULL)
14093 {
14094 ivd.vd_ndx = 0;
14095 ivd.vd_aux = 0;
14096 ivd.vd_next = 0;
1f6f5dba 14097 ivd.vd_flags = 0;
ab273396
AM
14098 }
14099 else
bb4d2ac2 14100 {
ab273396
AM
14101 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
14102 ivd.vd_aux = BYTE_GET (evd.vd_aux);
14103 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 14104 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 14105 }
bb4d2ac2 14106
7a815dd5
L
14107 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
14108 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
14109
ab273396
AM
14110 off += ivd.vd_next;
14111 }
14112 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 14113
ab273396
AM
14114 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
14115 {
9abca702 14116 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
14117 return NULL;
14118
ab273396
AM
14119 off -= ivd.vd_next;
14120 off += ivd.vd_aux;
bb4d2ac2 14121
dda8d76d 14122 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
14123 _("version def aux")) != NULL)
14124 {
14125 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 14126
ab273396 14127 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
14128 return (ivda.vda_name < strtab_size
14129 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
14130 }
14131 }
14132 }
bb4d2ac2 14133
978c4450 14134 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
14135 {
14136 Elf_External_Verneed evn;
14137 Elf_Internal_Verneed ivn;
14138 Elf_Internal_Vernaux ivna;
bb4d2ac2 14139
dda8d76d 14140 offset = offset_from_vma (filedata,
978c4450 14141 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
14142 sizeof evn);
14143 do
14144 {
26c527e6 14145 uint64_t vna_off;
bb4d2ac2 14146
dda8d76d 14147 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
14148 _("version need")) == NULL)
14149 {
14150 ivna.vna_next = 0;
14151 ivna.vna_other = 0;
14152 ivna.vna_name = 0;
14153 break;
14154 }
bb4d2ac2 14155
ab273396
AM
14156 ivn.vn_aux = BYTE_GET (evn.vn_aux);
14157 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 14158
ab273396 14159 vna_off = offset + ivn.vn_aux;
bb4d2ac2 14160
ab273396
AM
14161 do
14162 {
14163 Elf_External_Vernaux evna;
bb4d2ac2 14164
dda8d76d 14165 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 14166 _("version need aux (3)")) == NULL)
bb4d2ac2 14167 {
ab273396
AM
14168 ivna.vna_next = 0;
14169 ivna.vna_other = 0;
14170 ivna.vna_name = 0;
bb4d2ac2 14171 }
bb4d2ac2 14172 else
bb4d2ac2 14173 {
ab273396
AM
14174 ivna.vna_other = BYTE_GET (evna.vna_other);
14175 ivna.vna_next = BYTE_GET (evna.vna_next);
14176 ivna.vna_name = BYTE_GET (evna.vna_name);
14177 }
bb4d2ac2 14178
ab273396
AM
14179 vna_off += ivna.vna_next;
14180 }
14181 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 14182
ab273396
AM
14183 if (ivna.vna_other == vers_data)
14184 break;
bb4d2ac2 14185
ab273396
AM
14186 offset += ivn.vn_next;
14187 }
14188 while (ivn.vn_next != 0);
bb4d2ac2 14189
ab273396
AM
14190 if (ivna.vna_other == vers_data)
14191 {
14192 *sym_info = symbol_undefined;
14193 *vna_other = ivna.vna_other;
14194 return (ivna.vna_name < strtab_size
14195 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 14196 }
7a815dd5
L
14197 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
14198 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
14199 return _("<corrupt>");
bb4d2ac2 14200 }
ab273396 14201 return NULL;
bb4d2ac2
L
14202}
14203
047c3dbf
NL
14204/* Display a symbol size on stdout. Format is based on --sym-base setting. */
14205
14206static unsigned int
b6ac461a 14207print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
14208{
14209 switch (base)
14210 {
14211 case 8:
14212 return print_vma (vma, OCTAL_5);
14213
14214 case 10:
14215 return print_vma (vma, UNSIGNED_5);
14216
14217 case 16:
14218 return print_vma (vma, PREFIX_HEX_5);
14219
14220 case 0:
14221 default:
14222 return print_vma (vma, DEC_5);
14223 }
14224}
14225
b6ac461a
NC
14226/* Print information on a single symbol. */
14227
10ca4b04 14228static void
b6ac461a
NC
14229print_symbol (Filedata * filedata,
14230 uint64_t symbol_index,
14231 Elf_Internal_Sym * symtab,
14232 Elf_Internal_Shdr * section,
14233 char * strtab,
14234 size_t strtab_size)
252b5132 14235{
10ca4b04
L
14236 const char *version_string;
14237 enum versioned_symbol_info sym_info;
14238 unsigned short vna_other;
23356397 14239 const char * sstr;
b6ac461a 14240 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 14241
b6ac461a
NC
14242 /* FIXME: We should have a table of field widths,
14243 rather than using hard coded constants. */
14244 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
14245 print_vma (psym->st_value, LONG_HEX);
14246 putchar (' ');
b6ac461a 14247 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
14248 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
14249 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
14250 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
14251 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
14252 else
252b5132 14253 {
10ca4b04 14254 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 14255
10ca4b04 14256 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 14257
10ca4b04 14258 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
14259 FIXME: Displaying this information here disrupts the layout
14260 of the table being generated. */
10ca4b04
L
14261 if (psym->st_other ^ vis)
14262 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 14263 }
0942c7ab 14264
b6ac461a
NC
14265 bool is_special;
14266
14267 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
14268
14269 /* Print the symbol's section index. If the index is special
14270 then print the index's name rather than its number. */
14271 if (is_special)
14272 {
14273 int printed;
14274
14275 /* Special case: If there are no section headers, and the printable
14276 name is "<section 0x...." then just display the section number
14277 as a decimal. This happens when objcopy --strip -section-headers
14278 is used. */
14279 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
14280 printed = printf (" %4d ", psym->st_shndx);
14281 else
14282 printed = printf (" %4s ", sstr);
14283
14284 if (extra_sym_info && printed < 16)
14285 printf ("%*s", 16 - printed, "");
14286 }
14287 else
14288 {
14289 printf (" %4u ", psym->st_shndx);
14290
14291 if (extra_sym_info)
14292 {
14293 /* Display the section name referenced by the section index. */
14294 int printed = printf ("(%s) ", sstr);
14295 if (printed < 10)
14296 printf ("%*s", 10 - printed, "");
14297 }
14298 }
5d526bdf 14299
b6ac461a
NC
14300 /* Get the symbol's name. For section symbols without a
14301 specific name use the (already computed) section name. */
23356397 14302 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 14303 && section_index_real (filedata, psym->st_shndx)
23356397
NC
14304 && psym->st_name == 0)
14305 {
b6ac461a 14306 ;
23356397
NC
14307 }
14308 else
14309 {
b6ac461a
NC
14310 bool is_valid;
14311
84714f86 14312 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
14313 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14314 }
10ca4b04
L
14315
14316 version_string
14317 = get_symbol_version_string (filedata,
14318 (section == NULL
14319 || section->sh_type == SHT_DYNSYM),
b6ac461a 14320 strtab, strtab_size, symbol_index,
10ca4b04 14321 psym, &sym_info, &vna_other);
b9e920ec 14322
0942c7ab
NC
14323 int len_avail = 21;
14324 if (! do_wide && version_string != NULL)
14325 {
ddb43bab 14326 char buffer[16];
0942c7ab 14327
ddb43bab 14328 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
14329
14330 if (sym_info == symbol_undefined)
14331 len_avail -= sprintf (buffer," (%d)", vna_other);
14332 else if (sym_info != symbol_hidden)
14333 len_avail -= 1;
14334 }
14335
b6ac461a 14336 print_symbol_name (len_avail, sstr);
b9e920ec 14337
10ca4b04
L
14338 if (version_string)
14339 {
14340 if (sym_info == symbol_undefined)
14341 printf ("@%s (%d)", version_string, vna_other);
f7a99963 14342 else
10ca4b04
L
14343 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14344 version_string);
14345 }
6bd1a22c 14346
10ca4b04 14347 putchar ('\n');
6bd1a22c 14348
10ca4b04
L
14349 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14350 && section != NULL
b6ac461a 14351 && symbol_index >= section->sh_info
10ca4b04
L
14352 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14353 && filedata->file_header.e_machine != EM_MIPS
14354 /* Solaris binaries have been found to violate this requirement as
14355 well. Not sure if this is a bug or an ABI requirement. */
14356 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 14357 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 14358 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 14359}
f16a9783 14360
0f03783c
NC
14361static const char *
14362get_lto_kind (unsigned int kind)
14363{
14364 switch (kind)
14365 {
14366 case 0: return "DEF";
14367 case 1: return "WEAKDEF";
14368 case 2: return "UNDEF";
14369 case 3: return "WEAKUNDEF";
14370 case 4: return "COMMON";
14371 default:
14372 break;
14373 }
14374
14375 static char buffer[30];
14376 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14377 sprintf (buffer, "<unknown: %u>", kind);
14378 return buffer;
14379}
14380
14381static const char *
14382get_lto_visibility (unsigned int visibility)
14383{
14384 switch (visibility)
14385 {
14386 case 0: return "DEFAULT";
14387 case 1: return "PROTECTED";
14388 case 2: return "INTERNAL";
14389 case 3: return "HIDDEN";
14390 default:
14391 break;
14392 }
14393
14394 static char buffer[30];
14395 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14396 sprintf (buffer, "<unknown: %u>", visibility);
14397 return buffer;
14398}
14399
14400static const char *
14401get_lto_sym_type (unsigned int sym_type)
14402{
14403 switch (sym_type)
14404 {
14405 case 0: return "UNKNOWN";
14406 case 1: return "FUNCTION";
14407 case 2: return "VARIABLE";
14408 default:
14409 break;
14410 }
14411
14412 static char buffer[30];
14413 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14414 sprintf (buffer, "<unknown: %u>", sym_type);
14415 return buffer;
14416}
14417
14418/* Display an LTO format symbol table.
14419 FIXME: The format of LTO symbol tables is not formalized.
14420 So this code could need changing in the future. */
14421
015dc7e1 14422static bool
0f03783c
NC
14423display_lto_symtab (Filedata * filedata,
14424 Elf_Internal_Shdr * section)
14425{
14426 if (section->sh_size == 0)
14427 {
ca0e11aa
NC
14428 if (filedata->is_separate)
14429 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14430 printable_section_name (filedata, section),
14431 filedata->file_name);
14432 else
14433 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14434 printable_section_name (filedata, section));
047c3dbf 14435
015dc7e1 14436 return true;
0f03783c
NC
14437 }
14438
14439 if (section->sh_size > filedata->file_size)
14440 {
26c527e6 14441 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 14442 printable_section_name (filedata, section),
26c527e6 14443 section->sh_size);
015dc7e1 14444 return false;
0f03783c
NC
14445 }
14446
14447 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14448 section->sh_size, 1, _("LTO symbols"));
14449 if (alloced_data == NULL)
015dc7e1 14450 return false;
0f03783c
NC
14451
14452 /* Look for extended data for the symbol table. */
0f03783c
NC
14453 void * ext_data_orig = NULL;
14454 char * ext_data = NULL;
14455 char * ext_data_end = NULL;
86b26b45
AM
14456 char *ext_name = xasprintf (".gnu.lto_.ext_symtab.%s",
14457 (section_name (filedata, section)
14458 + sizeof (".gnu.lto_.symtab.")));
14459 Elf_Internal_Shdr *ext = find_section (filedata, ext_name);
14460 if (ext != NULL)
0f03783c
NC
14461 {
14462 if (ext->sh_size < 3)
14463 error (_("LTO Symbol extension table '%s' is empty!\n"),
14464 printable_section_name (filedata, ext));
14465 else
14466 {
14467 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14468 ext->sh_size, 1,
14469 _("LTO ext symbol data"));
14470 if (ext_data != NULL)
14471 {
14472 ext_data_end = ext_data + ext->sh_size;
14473 if (* ext_data++ != 1)
14474 error (_("Unexpected version number in symbol extension table\n"));
14475 }
14476 }
14477 }
b9e920ec 14478
0f03783c
NC
14479 const unsigned char * data = (const unsigned char *) alloced_data;
14480 const unsigned char * end = data + section->sh_size;
14481
ca0e11aa
NC
14482 if (filedata->is_separate)
14483 printf (_("\nIn linked file '%s': "), filedata->file_name);
14484 else
14485 printf ("\n");
14486
0f03783c
NC
14487 if (ext_data_orig != NULL)
14488 {
14489 if (do_wide)
ca0e11aa 14490 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
14491 printable_section_name (filedata, section),
14492 printable_section_name (filedata, ext));
14493 else
14494 {
ca0e11aa 14495 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
14496 printable_section_name (filedata, section));
14497 printf (_(" and extension table '%s' contain:\n"),
14498 printable_section_name (filedata, ext));
14499 }
14500 }
14501 else
ca0e11aa 14502 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 14503 printable_section_name (filedata, section));
b9e920ec 14504
0f03783c 14505 /* FIXME: Add a wide version. */
b9e920ec 14506 if (ext_data_orig != NULL)
0f03783c
NC
14507 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14508 else
14509 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14510
14511 /* FIXME: We do not handle style prefixes. */
14512
14513 while (data < end)
14514 {
14515 const unsigned char * sym_name = data;
14516 data += strnlen ((const char *) sym_name, end - data) + 1;
14517 if (data >= end)
14518 goto fail;
14519
14520 const unsigned char * comdat_key = data;
14521 data += strnlen ((const char *) comdat_key, end - data) + 1;
14522 if (data >= end)
14523 goto fail;
14524
14525 if (data + 2 + 8 + 4 > end)
14526 goto fail;
14527
14528 unsigned int kind = *data++;
14529 unsigned int visibility = *data++;
14530
928c411d 14531 uint64_t size = byte_get (data, 8);
0f03783c
NC
14532 data += 8;
14533
928c411d 14534 uint64_t slot = byte_get (data, 4);
0f03783c
NC
14535 data += 4;
14536
14537 if (ext_data != NULL)
14538 {
14539 if (ext_data < (ext_data_end - 1))
14540 {
14541 unsigned int sym_type = * ext_data ++;
14542 unsigned int sec_kind = * ext_data ++;
14543
31e5a3a3 14544 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
14545 * comdat_key == 0 ? "-" : (char *) comdat_key,
14546 get_lto_kind (kind),
14547 get_lto_visibility (visibility),
31e5a3a3
AM
14548 size,
14549 slot,
0f03783c 14550 get_lto_sym_type (sym_type),
31e5a3a3 14551 sec_kind);
b6ac461a 14552 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
14553 }
14554 else
14555 {
14556 error (_("Ran out of LTO symbol extension data\n"));
14557 ext_data = NULL;
14558 /* FIXME: return FAIL result ? */
14559 }
14560 }
14561 else
14562 {
31e5a3a3 14563 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
14564 * comdat_key == 0 ? "-" : (char *) comdat_key,
14565 get_lto_kind (kind),
14566 get_lto_visibility (visibility),
31e5a3a3
AM
14567 size,
14568 slot);
b6ac461a 14569 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
14570 }
14571 putchar ('\n');
14572 }
14573
14574 if (ext_data != NULL && ext_data < ext_data_end)
14575 {
14576 error (_("Data remains in the LTO symbol extension table\n"));
14577 goto fail;
14578 }
14579
14580 free (alloced_data);
14581 free (ext_data_orig);
14582 free (ext_name);
015dc7e1 14583 return true;
b9e920ec 14584
0f03783c
NC
14585 fail:
14586 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14587 free (alloced_data);
14588 free (ext_data_orig);
14589 free (ext_name);
015dc7e1 14590 return false;
0f03783c
NC
14591}
14592
14593/* Display LTO symbol tables. */
14594
015dc7e1 14595static bool
0f03783c
NC
14596process_lto_symbol_tables (Filedata * filedata)
14597{
14598 Elf_Internal_Shdr * section;
14599 unsigned int i;
015dc7e1 14600 bool res = true;
0f03783c
NC
14601
14602 if (!do_lto_syms)
015dc7e1 14603 return true;
0f03783c
NC
14604
14605 if (filedata->section_headers == NULL)
015dc7e1 14606 return true;
0f03783c
NC
14607
14608 for (i = 0, section = filedata->section_headers;
14609 i < filedata->file_header.e_shnum;
14610 i++, section++)
84714f86
AM
14611 if (section_name_valid (filedata, section)
14612 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14613 res &= display_lto_symtab (filedata, section);
14614
b9e920ec 14615 return res;
0f03783c
NC
14616}
14617
b6ac461a
NC
14618static void
14619print_symbol_table_heading (void)
14620{
14621 /* FIXME: We should store the size of each field in the display in a table and
14622 then use the values inside print_symbol(), instead of that function using
14623 hard coded constants. */
14624 if (is_32bit_elf)
14625 {
14626 if (extra_sym_info)
14627 {
14628 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14629 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14630 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14631 }
14632 else if (do_wide)
14633 {
14634 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14635 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14636 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14637 }
14638 else
14639 {
14640 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14641 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14642 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14643 }
14644 }
14645 else
14646 {
14647 if (extra_sym_info)
14648 {
14649 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14650 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14651 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14652
14653 }
14654 else if (do_wide)
14655 {
14656 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14657 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14658 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14659 }
14660 else
14661 {
14662 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14663 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14664 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14665 }
14666 }
14667}
14668
8e8d0b63
NC
14669static bool
14670dump_symbol_section (Elf_Internal_Shdr * section,
14671 Filedata * filedata)
14672{
14673 if (section->sh_entsize == 0)
14674 {
14675 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14676 printable_section_name (filedata, section));
14677 return false;
14678 }
14679
14680 uint64_t num_syms = section->sh_size / section->sh_entsize;
14681
14682 if (filedata->is_separate)
14683 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14684 " contains %" PRIu64 " entry:\n",
14685 "\nIn linked file '%s' symbol section '%s'"
14686 " contains %" PRIu64 " entries:\n",
14687 num_syms),
14688 filedata->file_name,
14689 printable_section_name (filedata, section),
14690 num_syms);
14691 else
14692 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14693 " entry:\n",
14694 "\nSymbol table '%s' contains %" PRIu64
14695 " entries:\n",
14696 num_syms),
14697 printable_section_name (filedata, section),
14698 num_syms);
14699
14700 print_symbol_table_heading ();
14701
14702 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14703 if (symtab == NULL)
14704 /* An error message will have already been displayed. */
14705 return false;
14706
14707 char * strtab = NULL;
14708 uint64_t strtab_size = 0;
14709
14710 if (section->sh_link == filedata->file_header.e_shstrndx)
14711 {
14712 strtab = filedata->string_table;
14713 strtab_size = filedata->string_table_length;
14714 }
14715 else if (section->sh_link < filedata->file_header.e_shnum)
14716 {
14717 Elf_Internal_Shdr * string_sec;
14718
14719 string_sec = filedata->section_headers + section->sh_link;
14720
14721 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14722 1, string_sec->sh_size,
14723 _("string table"));
14724 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14725 }
14726
14727 uint64_t si;
14728
14729 for (si = 0; si < num_syms; si++)
14730 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14731
14732 free (symtab);
14733
14734 if (strtab != filedata->string_table)
14735 free (strtab);
14736
14737 return true;
14738}
14739
10ca4b04 14740/* Dump the symbol table. */
0f03783c 14741
015dc7e1 14742static bool
10ca4b04
L
14743process_symbol_table (Filedata * filedata)
14744{
14745 Elf_Internal_Shdr * section;
f16a9783 14746
10ca4b04 14747 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14748 return true;
6bd1a22c 14749
978c4450 14750 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14751 && do_syms
14752 && do_using_dynamic
978c4450
AM
14753 && filedata->dynamic_strings != NULL
14754 && filedata->dynamic_symbols != NULL)
6bd1a22c 14755 {
26c527e6 14756 uint64_t si;
6bd1a22c 14757
ca0e11aa
NC
14758 if (filedata->is_separate)
14759 {
26c527e6
AM
14760 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14761 " contains %" PRIu64 " entry:\n",
14762 "\nIn linked file '%s' the dynamic symbol table"
14763 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14764 filedata->num_dynamic_syms),
14765 filedata->file_name,
14766 filedata->num_dynamic_syms);
14767 }
14768 else
14769 {
26c527e6
AM
14770 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14771 " entry:\n",
14772 "\nSymbol table for image contains %" PRIu64
14773 " entries:\n",
ca0e11aa
NC
14774 filedata->num_dynamic_syms),
14775 filedata->num_dynamic_syms);
14776 }
b6ac461a
NC
14777
14778 print_symbol_table_heading ();
6bd1a22c 14779
978c4450 14780 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14781 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14782 filedata->dynamic_strings,
14783 filedata->dynamic_strings_length);
252b5132 14784 }
8b73c356 14785 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14786 && filedata->section_headers != NULL)
252b5132 14787 {
b34976b6 14788 unsigned int i;
252b5132 14789
dda8d76d
NC
14790 for (i = 0, section = filedata->section_headers;
14791 i < filedata->file_header.e_shnum;
252b5132
RH
14792 i++, section++)
14793 {
2c610e4b
L
14794 if ((section->sh_type != SHT_SYMTAB
14795 && section->sh_type != SHT_DYNSYM)
14796 || (!do_syms
14797 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14798 continue;
14799
8e8d0b63 14800 dump_symbol_section (section, filedata);
252b5132
RH
14801 }
14802 }
14803 else if (do_syms)
14804 printf
14805 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14806
978c4450 14807 if (do_histogram && filedata->buckets != NULL)
252b5132 14808 {
26c527e6
AM
14809 uint64_t *lengths;
14810 uint64_t *counts;
14811 uint64_t hn;
625d49fc 14812 uint64_t si;
26c527e6
AM
14813 uint64_t maxlength = 0;
14814 uint64_t nzero_counts = 0;
14815 uint64_t nsyms = 0;
6bd6a03d 14816 char *visited;
252b5132 14817
d3a49aa8 14818 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14819 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14820 "\nHistogram for bucket list length "
26c527e6
AM
14821 "(total of %" PRIu64 " buckets):\n",
14822 filedata->nbuckets),
14823 filedata->nbuckets);
252b5132 14824
26c527e6 14825 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14826 if (lengths == NULL)
14827 {
8b73c356 14828 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14829 goto err_out;
252b5132 14830 }
978c4450
AM
14831 visited = xcmalloc (filedata->nchains, 1);
14832 memset (visited, 0, filedata->nchains);
8b73c356
NC
14833
14834 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14835 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14836 {
978c4450 14837 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14838 {
b34976b6 14839 ++nsyms;
252b5132 14840 if (maxlength < ++lengths[hn])
b34976b6 14841 ++maxlength;
978c4450 14842 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14843 {
14844 error (_("histogram chain is corrupt\n"));
14845 break;
14846 }
14847 visited[si] = 1;
252b5132
RH
14848 }
14849 }
6bd6a03d 14850 free (visited);
252b5132 14851
26c527e6 14852 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14853 if (counts == NULL)
14854 {
b2e951ec 14855 free (lengths);
8b73c356 14856 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14857 goto err_out;
252b5132
RH
14858 }
14859
978c4450 14860 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14861 ++counts[lengths[hn]];
252b5132 14862
978c4450 14863 if (filedata->nbuckets > 0)
252b5132 14864 {
26c527e6
AM
14865 uint64_t i;
14866 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14867 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14868 for (i = 1; i <= maxlength; ++i)
103f02d3 14869 {
66543521 14870 nzero_counts += counts[i] * i;
26c527e6 14871 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14872 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14873 (nzero_counts * 100.0) / nsyms);
14874 }
252b5132
RH
14875 }
14876
14877 free (counts);
14878 free (lengths);
14879 }
14880
978c4450
AM
14881 free (filedata->buckets);
14882 filedata->buckets = NULL;
14883 filedata->nbuckets = 0;
14884 free (filedata->chains);
14885 filedata->chains = NULL;
252b5132 14886
978c4450 14887 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14888 {
26c527e6
AM
14889 uint64_t *lengths;
14890 uint64_t *counts;
14891 uint64_t hn;
14892 uint64_t maxlength = 0;
14893 uint64_t nzero_counts = 0;
14894 uint64_t nsyms = 0;
fdc90cb4 14895
f16a9783 14896 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14897 "(total of %" PRIu64 " bucket):\n",
f16a9783 14898 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14899 "(total of %" PRIu64 " buckets):\n",
14900 filedata->ngnubuckets),
978c4450 14901 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14902 filedata->ngnubuckets);
8b73c356 14903
26c527e6 14904 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14905 if (lengths == NULL)
14906 {
8b73c356 14907 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14908 goto err_out;
fdc90cb4
JJ
14909 }
14910
fdc90cb4
JJ
14911 printf (_(" Length Number %% of total Coverage\n"));
14912
978c4450
AM
14913 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14914 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14915 {
625d49fc 14916 uint64_t off, length = 1;
fdc90cb4 14917
978c4450 14918 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14919 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14920 off < filedata->ngnuchains
14921 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14922 ++off)
fdc90cb4
JJ
14923 ++length;
14924 lengths[hn] = length;
14925 if (length > maxlength)
14926 maxlength = length;
14927 nsyms += length;
14928 }
14929
26c527e6 14930 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14931 if (counts == NULL)
14932 {
b2e951ec 14933 free (lengths);
8b73c356 14934 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14935 goto err_out;
fdc90cb4
JJ
14936 }
14937
978c4450 14938 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14939 ++counts[lengths[hn]];
14940
978c4450 14941 if (filedata->ngnubuckets > 0)
fdc90cb4 14942 {
26c527e6
AM
14943 uint64_t j;
14944 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14945 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14946 for (j = 1; j <= maxlength; ++j)
14947 {
14948 nzero_counts += counts[j] * j;
26c527e6 14949 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14950 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14951 (nzero_counts * 100.0) / nsyms);
14952 }
14953 }
14954
14955 free (counts);
14956 free (lengths);
fdc90cb4 14957 }
978c4450
AM
14958 free (filedata->gnubuckets);
14959 filedata->gnubuckets = NULL;
14960 filedata->ngnubuckets = 0;
14961 free (filedata->gnuchains);
14962 filedata->gnuchains = NULL;
14963 filedata->ngnuchains = 0;
14964 free (filedata->mipsxlat);
14965 filedata->mipsxlat = NULL;
015dc7e1 14966 return true;
fd486f32
AM
14967
14968 err_out:
978c4450
AM
14969 free (filedata->gnubuckets);
14970 filedata->gnubuckets = NULL;
14971 filedata->ngnubuckets = 0;
14972 free (filedata->gnuchains);
14973 filedata->gnuchains = NULL;
14974 filedata->ngnuchains = 0;
14975 free (filedata->mipsxlat);
14976 filedata->mipsxlat = NULL;
14977 free (filedata->buckets);
14978 filedata->buckets = NULL;
14979 filedata->nbuckets = 0;
14980 free (filedata->chains);
14981 filedata->chains = NULL;
015dc7e1 14982 return false;
252b5132
RH
14983}
14984
015dc7e1 14985static bool
ca0e11aa 14986process_syminfo (Filedata * filedata)
252b5132 14987{
b4c96d0d 14988 unsigned int i;
252b5132 14989
978c4450 14990 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14991 || !do_dynamic)
14992 /* No syminfo, this is ok. */
015dc7e1 14993 return true;
252b5132
RH
14994
14995 /* There better should be a dynamic symbol section. */
978c4450 14996 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14997 return false;
252b5132 14998
ca0e11aa 14999 if (filedata->is_separate)
26c527e6
AM
15000 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
15001 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
15002 filedata->dynamic_syminfo_nent),
15003 filedata->file_name,
15004 filedata->dynamic_syminfo_offset,
15005 filedata->dynamic_syminfo_nent);
15006 else
26c527e6
AM
15007 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
15008 " contains %d entry:\n",
15009 "\nDynamic info segment at offset %#" PRIx64
15010 " contains %d entries:\n",
978c4450 15011 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
15012 filedata->dynamic_syminfo_offset,
15013 filedata->dynamic_syminfo_nent);
252b5132
RH
15014
15015 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 15016 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 15017 {
978c4450 15018 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 15019
31104126 15020 printf ("%4d: ", i);
978c4450 15021 if (i >= filedata->num_dynamic_syms)
4082ef84 15022 printf (_("<corrupt index>"));
84714f86 15023 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 15024 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 15025 filedata->dynamic_symbols[i].st_name));
d79b3d50 15026 else
978c4450 15027 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 15028 putchar (' ');
252b5132 15029
978c4450 15030 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
15031 {
15032 case SYMINFO_BT_SELF:
15033 fputs ("SELF ", stdout);
15034 break;
15035 case SYMINFO_BT_PARENT:
15036 fputs ("PARENT ", stdout);
15037 break;
15038 default:
978c4450
AM
15039 if (filedata->dynamic_syminfo[i].si_boundto > 0
15040 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 15041 && valid_dynamic_name (filedata,
978c4450 15042 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 15043 {
b6ac461a 15044 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 15045 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
15046 putchar (' ' );
15047 }
252b5132 15048 else
978c4450 15049 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
15050 break;
15051 }
15052
15053 if (flags & SYMINFO_FLG_DIRECT)
15054 printf (" DIRECT");
15055 if (flags & SYMINFO_FLG_PASSTHRU)
15056 printf (" PASSTHRU");
15057 if (flags & SYMINFO_FLG_COPY)
15058 printf (" COPY");
15059 if (flags & SYMINFO_FLG_LAZYLOAD)
15060 printf (" LAZYLOAD");
15061
15062 puts ("");
15063 }
15064
015dc7e1 15065 return true;
252b5132
RH
15066}
15067
75802ccb
CE
15068/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
15069 is contained by the region START .. END. The types of ADDR, START
15070 and END should all be the same. Note both ADDR + NELEM and END
15071 point to just beyond the end of the regions that are being tested. */
15072#define IN_RANGE(START,END,ADDR,NELEM) \
15073 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 15074
cf13d699
NC
15075/* Check to see if the given reloc needs to be handled in a target specific
15076 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
15077 FALSE.
15078
15079 If called with reloc == NULL, then this is a signal that reloc processing
15080 for the current section has finished, and any saved state should be
15081 discarded. */
09c11c86 15082
015dc7e1 15083static bool
26c527e6
AM
15084target_specific_reloc_handling (Filedata *filedata,
15085 Elf_Internal_Rela *reloc,
15086 unsigned char *start,
15087 unsigned char *end,
15088 Elf_Internal_Sym *symtab,
15089 uint64_t num_syms)
252b5132 15090{
f84ce13b 15091 unsigned int reloc_type = 0;
26c527e6 15092 uint64_t sym_index = 0;
f84ce13b
NC
15093
15094 if (reloc)
15095 {
dda8d76d 15096 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
15097 sym_index = get_reloc_symindex (reloc->r_info);
15098 }
252b5132 15099
dda8d76d 15100 switch (filedata->file_header.e_machine)
252b5132 15101 {
76244462 15102 case EM_LOONGARCH:
15103 {
15104 switch (reloc_type)
15105 {
15106 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
15107 at assembly time. */
15108 case 107: /* R_LARCH_ADD_ULEB128. */
15109 case 108: /* R_LARCH_SUB_ULEB128. */
15110 {
d3f34076 15111 uint64_t value = 0;
76244462 15112 unsigned int reloc_size = 0;
15113 int leb_ret = 0;
15114
89c70cd3
AM
15115 if (reloc->r_offset < (size_t) (end - start))
15116 value = read_leb128 (start + reloc->r_offset, end, false,
15117 &reloc_size, &leb_ret);
76244462 15118 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15119 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
15120 "ULEB128 value\n"),
15121 (long) reloc->r_offset);
15122
74a965d8
AM
15123 else if (sym_index >= num_syms)
15124 error (_("%s reloc contains invalid symbol index "
15125 "%" PRIu64 "\n"),
15126 (reloc_type == 107
15127 ? "R_LARCH_ADD_ULEB128"
15128 : "R_LARCH_SUB_ULEB128"),
15129 sym_index);
15130 else
76244462 15131 {
74a965d8
AM
15132 if (reloc_type == 107)
15133 value += reloc->r_addend + symtab[sym_index].st_value;
15134 else
15135 value -= reloc->r_addend + symtab[sym_index].st_value;
15136
15137 /* Write uleb128 value to p. */
15138 bfd_byte *p = start + reloc->r_offset;
15139 do
15140 {
15141 bfd_byte c = value & 0x7f;
15142 value >>= 7;
15143 if (--reloc_size != 0)
15144 c |= 0x80;
15145 *p++ = c;
15146 }
15147 while (reloc_size);
76244462 15148 }
76244462 15149
15150 return true;
15151 }
15152 }
15153 break;
15154 }
15155
13761a11
NC
15156 case EM_MSP430:
15157 case EM_MSP430_OLD:
15158 {
15159 static Elf_Internal_Sym * saved_sym = NULL;
15160
f84ce13b
NC
15161 if (reloc == NULL)
15162 {
15163 saved_sym = NULL;
015dc7e1 15164 return true;
f84ce13b
NC
15165 }
15166
13761a11
NC
15167 switch (reloc_type)
15168 {
15169 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 15170 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 15171 if (uses_msp430x_relocs (filedata))
13761a11 15172 break;
1a0670f3 15173 /* Fall through. */
13761a11 15174 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 15175 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
15176 /* PR 21139. */
15177 if (sym_index >= num_syms)
74a965d8
AM
15178 error (_("%s reloc contains invalid symbol index "
15179 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
15180 else
15181 saved_sym = symtab + sym_index;
015dc7e1 15182 return true;
13761a11
NC
15183
15184 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15185 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
15186 goto handle_sym_diff;
0b4362b0 15187
13761a11
NC
15188 case 5: /* R_MSP430_16_BYTE */
15189 case 9: /* R_MSP430_8 */
7d81bc93 15190 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 15191 if (uses_msp430x_relocs (filedata))
13761a11
NC
15192 break;
15193 goto handle_sym_diff;
15194
15195 case 2: /* R_MSP430_ABS16 */
15196 case 15: /* R_MSP430X_ABS16 */
7d81bc93 15197 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 15198 if (! uses_msp430x_relocs (filedata))
13761a11
NC
15199 break;
15200 goto handle_sym_diff;
0b4362b0 15201
13761a11
NC
15202 handle_sym_diff:
15203 if (saved_sym != NULL)
15204 {
625d49fc 15205 uint64_t value;
5a805384 15206 unsigned int reloc_size = 0;
7d81bc93
JL
15207 int leb_ret = 0;
15208 switch (reloc_type)
15209 {
15210 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15211 reloc_size = 4;
15212 break;
15213 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15214 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 15215 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 15216 read_leb128 (start + reloc->r_offset, end, false,
5a805384 15217 &reloc_size, &leb_ret);
7d81bc93
JL
15218 break;
15219 default:
15220 reloc_size = 2;
15221 break;
15222 }
13761a11 15223
5a805384 15224 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
15225 error (_("MSP430 ULEB128 field at %#" PRIx64
15226 " contains invalid ULEB128 value\n"),
15227 reloc->r_offset);
7d81bc93 15228 else if (sym_index >= num_syms)
74a965d8
AM
15229 error (_("%s reloc contains invalid symbol index "
15230 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 15231 else
f84ce13b
NC
15232 {
15233 value = reloc->r_addend + (symtab[sym_index].st_value
15234 - saved_sym->st_value);
15235
b32e566b 15236 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 15237 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
15238 else
15239 /* PR 21137 */
26c527e6
AM
15240 error (_("MSP430 sym diff reloc contains invalid offset: "
15241 "%#" PRIx64 "\n"),
15242 reloc->r_offset);
f84ce13b 15243 }
13761a11
NC
15244
15245 saved_sym = NULL;
015dc7e1 15246 return true;
13761a11
NC
15247 }
15248 break;
15249
15250 default:
15251 if (saved_sym != NULL)
071436c6 15252 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
15253 break;
15254 }
15255 break;
15256 }
15257
cf13d699
NC
15258 case EM_MN10300:
15259 case EM_CYGNUS_MN10300:
15260 {
15261 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 15262
f84ce13b
NC
15263 if (reloc == NULL)
15264 {
15265 saved_sym = NULL;
015dc7e1 15266 return true;
f84ce13b
NC
15267 }
15268
cf13d699
NC
15269 switch (reloc_type)
15270 {
15271 case 34: /* R_MN10300_ALIGN */
015dc7e1 15272 return true;
cf13d699 15273 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 15274 if (sym_index >= num_syms)
74a965d8
AM
15275 error (_("%s reloc contains invalid symbol index "
15276 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
15277 else
15278 saved_sym = symtab + sym_index;
015dc7e1 15279 return true;
f84ce13b 15280
cf13d699
NC
15281 case 1: /* R_MN10300_32 */
15282 case 2: /* R_MN10300_16 */
15283 if (saved_sym != NULL)
15284 {
03f7786e 15285 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 15286 uint64_t value;
252b5132 15287
f84ce13b 15288 if (sym_index >= num_syms)
74a965d8
AM
15289 error (_("%s reloc contains invalid symbol index "
15290 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 15291 else
f84ce13b
NC
15292 {
15293 value = reloc->r_addend + (symtab[sym_index].st_value
15294 - saved_sym->st_value);
15295
b32e566b 15296 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 15297 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 15298 else
26c527e6
AM
15299 error (_("MN10300 sym diff reloc contains invalid offset:"
15300 " %#" PRIx64 "\n"),
15301 reloc->r_offset);
f84ce13b 15302 }
252b5132 15303
cf13d699 15304 saved_sym = NULL;
015dc7e1 15305 return true;
cf13d699
NC
15306 }
15307 break;
15308 default:
15309 if (saved_sym != NULL)
071436c6 15310 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
15311 break;
15312 }
15313 break;
15314 }
6ff71e76
NC
15315
15316 case EM_RL78:
15317 {
625d49fc
AM
15318 static uint64_t saved_sym1 = 0;
15319 static uint64_t saved_sym2 = 0;
15320 static uint64_t value;
6ff71e76 15321
f84ce13b
NC
15322 if (reloc == NULL)
15323 {
15324 saved_sym1 = saved_sym2 = 0;
015dc7e1 15325 return true;
f84ce13b
NC
15326 }
15327
6ff71e76
NC
15328 switch (reloc_type)
15329 {
15330 case 0x80: /* R_RL78_SYM. */
15331 saved_sym1 = saved_sym2;
f84ce13b 15332 if (sym_index >= num_syms)
74a965d8
AM
15333 error (_("%s reloc contains invalid symbol index "
15334 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
15335 else
15336 {
15337 saved_sym2 = symtab[sym_index].st_value;
15338 saved_sym2 += reloc->r_addend;
15339 }
015dc7e1 15340 return true;
6ff71e76
NC
15341
15342 case 0x83: /* R_RL78_OPsub. */
15343 value = saved_sym1 - saved_sym2;
15344 saved_sym2 = saved_sym1 = 0;
015dc7e1 15345 return true;
6ff71e76
NC
15346 break;
15347
15348 case 0x41: /* R_RL78_ABS32. */
b32e566b 15349 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 15350 byte_put (start + reloc->r_offset, value, 4);
b32e566b 15351 else
26c527e6
AM
15352 error (_("RL78 sym diff reloc contains invalid offset: "
15353 "%#" PRIx64 "\n"),
15354 reloc->r_offset);
6ff71e76 15355 value = 0;
015dc7e1 15356 return true;
6ff71e76
NC
15357
15358 case 0x43: /* R_RL78_ABS16. */
b32e566b 15359 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 15360 byte_put (start + reloc->r_offset, value, 2);
b32e566b 15361 else
26c527e6
AM
15362 error (_("RL78 sym diff reloc contains invalid offset: "
15363 "%#" PRIx64 "\n"),
15364 reloc->r_offset);
6ff71e76 15365 value = 0;
015dc7e1 15366 return true;
6ff71e76
NC
15367
15368 default:
15369 break;
15370 }
15371 break;
15372 }
252b5132
RH
15373 }
15374
015dc7e1 15375 return false;
252b5132
RH
15376}
15377
aca88567
NC
15378/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15379 DWARF debug sections. This is a target specific test. Note - we do not
15380 go through the whole including-target-headers-multiple-times route, (as
15381 we have already done with <elf/h8.h>) because this would become very
15382 messy and even then this function would have to contain target specific
15383 information (the names of the relocs instead of their numeric values).
15384 FIXME: This is not the correct way to solve this problem. The proper way
15385 is to have target specific reloc sizing and typing functions created by
15386 the reloc-macros.h header, in the same way that it already creates the
15387 reloc naming functions. */
15388
015dc7e1 15389static bool
dda8d76d 15390is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15391{
d347c9df 15392 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15393 switch (filedata->file_header.e_machine)
aca88567 15394 {
41e92641 15395 case EM_386:
22abe556 15396 case EM_IAMCU:
41e92641 15397 return reloc_type == 1; /* R_386_32. */
aca88567
NC
15398 case EM_68K:
15399 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
15400 case EM_860:
15401 return reloc_type == 1; /* R_860_32. */
15402 case EM_960:
15403 return reloc_type == 2; /* R_960_32. */
a06ea964 15404 case EM_AARCH64:
9282b95a
JW
15405 return (reloc_type == 258
15406 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
15407 case EM_BPF:
15408 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
15409 case EM_ADAPTEVA_EPIPHANY:
15410 return reloc_type == 3;
aca88567 15411 case EM_ALPHA:
137b6b5f 15412 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
15413 case EM_ARC:
15414 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
15415 case EM_ARC_COMPACT:
15416 case EM_ARC_COMPACT2:
b5c37946
SJ
15417 case EM_ARC_COMPACT3:
15418 case EM_ARC_COMPACT3_64:
886a2506 15419 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
15420 case EM_ARM:
15421 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 15422 case EM_AVR_OLD:
aca88567
NC
15423 case EM_AVR:
15424 return reloc_type == 1;
15425 case EM_BLACKFIN:
15426 return reloc_type == 0x12; /* R_byte4_data. */
15427 case EM_CRIS:
15428 return reloc_type == 3; /* R_CRIS_32. */
15429 case EM_CR16:
15430 return reloc_type == 3; /* R_CR16_NUM32. */
15431 case EM_CRX:
15432 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
15433 case EM_CSKY:
15434 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
15435 case EM_CYGNUS_FRV:
15436 return reloc_type == 1;
41e92641
NC
15437 case EM_CYGNUS_D10V:
15438 case EM_D10V:
15439 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
15440 case EM_CYGNUS_D30V:
15441 case EM_D30V:
15442 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
15443 case EM_DLX:
15444 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
15445 case EM_CYGNUS_FR30:
15446 case EM_FR30:
15447 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
15448 case EM_FT32:
15449 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
15450 case EM_H8S:
15451 case EM_H8_300:
15452 case EM_H8_300H:
15453 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 15454 case EM_IA_64:
262cdac7
AM
15455 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15456 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15457 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15458 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
15459 case EM_IP2K_OLD:
15460 case EM_IP2K:
15461 return reloc_type == 2; /* R_IP2K_32. */
15462 case EM_IQ2000:
15463 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
15464 case EM_KVX:
15465 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
15466 case EM_LATTICEMICO32:
15467 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 15468 case EM_LOONGARCH:
15469 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 15470 case EM_M32C_OLD:
aca88567
NC
15471 case EM_M32C:
15472 return reloc_type == 3; /* R_M32C_32. */
15473 case EM_M32R:
15474 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
15475 case EM_68HC11:
15476 case EM_68HC12:
15477 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 15478 case EM_S12Z:
2849d19f
JD
15479 return reloc_type == 7 || /* R_S12Z_EXT32 */
15480 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
15481 case EM_MCORE:
15482 return reloc_type == 1; /* R_MCORE_ADDR32. */
15483 case EM_CYGNUS_MEP:
15484 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
15485 case EM_METAG:
15486 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
15487 case EM_MICROBLAZE:
15488 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
15489 case EM_MIPS:
15490 return reloc_type == 2; /* R_MIPS_32. */
15491 case EM_MMIX:
15492 return reloc_type == 4; /* R_MMIX_32. */
15493 case EM_CYGNUS_MN10200:
15494 case EM_MN10200:
15495 return reloc_type == 1; /* R_MN10200_32. */
15496 case EM_CYGNUS_MN10300:
15497 case EM_MN10300:
15498 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
15499 case EM_MOXIE:
15500 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
15501 case EM_MSP430_OLD:
15502 case EM_MSP430:
13761a11 15503 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
15504 case EM_MT:
15505 return reloc_type == 2; /* R_MT_32. */
35c08157 15506 case EM_NDS32:
81c5e376 15507 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 15508 case EM_ALTERA_NIOS2:
36591ba1 15509 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
15510 case EM_NIOS32:
15511 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
15512 case EM_OR1K:
15513 return reloc_type == 1; /* R_OR1K_32. */
aca88567 15514 case EM_PARISC:
9abca702 15515 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 15516 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 15517 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
15518 case EM_PJ:
15519 case EM_PJ_OLD:
15520 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15521 case EM_PPC64:
15522 return reloc_type == 1; /* R_PPC64_ADDR32. */
15523 case EM_PPC:
15524 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
15525 case EM_TI_PRU:
15526 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
15527 case EM_RISCV:
15528 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
15529 case EM_RL78:
15530 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
15531 case EM_RX:
15532 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
15533 case EM_S370:
15534 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
15535 case EM_S390_OLD:
15536 case EM_S390:
15537 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
15538 case EM_SCORE:
15539 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
15540 case EM_SH:
15541 return reloc_type == 1; /* R_SH_DIR32. */
15542 case EM_SPARC32PLUS:
15543 case EM_SPARCV9:
15544 case EM_SPARC:
15545 return reloc_type == 3 /* R_SPARC_32. */
15546 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
15547 case EM_SPU:
15548 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
15549 case EM_TI_C6000:
15550 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
15551 case EM_TILEGX:
15552 return reloc_type == 2; /* R_TILEGX_32. */
15553 case EM_TILEPRO:
15554 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
15555 case EM_CYGNUS_V850:
15556 case EM_V850:
15557 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
15558 case EM_V800:
15559 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
15560 case EM_VAX:
15561 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
15562 case EM_VISIUM:
15563 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
15564 case EM_WEBASSEMBLY:
15565 return reloc_type == 1; /* R_WASM32_32. */
aca88567 15566 case EM_X86_64:
8a9036a4 15567 case EM_L1OM:
7a9068fe 15568 case EM_K1OM:
aca88567 15569 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
15570 case EM_XGATE:
15571 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
15572 case EM_XSTORMY16:
15573 return reloc_type == 1; /* R_XSTROMY16_32. */
15574 case EM_XTENSA_OLD:
15575 case EM_XTENSA:
15576 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
15577 case EM_Z80:
15578 return reloc_type == 6; /* R_Z80_32. */
aca88567 15579 default:
bee0ee85
NC
15580 {
15581 static unsigned int prev_warn = 0;
15582
15583 /* Avoid repeating the same warning multiple times. */
dda8d76d 15584 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15585 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15586 filedata->file_header.e_machine);
15587 prev_warn = filedata->file_header.e_machine;
015dc7e1 15588 return false;
bee0ee85 15589 }
aca88567
NC
15590 }
15591}
15592
15593/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15594 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15595
015dc7e1 15596static bool
dda8d76d 15597is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15598{
dda8d76d 15599 switch (filedata->file_header.e_machine)
d347c9df 15600 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15601 {
41e92641 15602 case EM_386:
22abe556 15603 case EM_IAMCU:
3e0873ac 15604 return reloc_type == 2; /* R_386_PC32. */
aca88567 15605 case EM_68K:
3e0873ac 15606 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15607 case EM_AARCH64:
15608 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15609 case EM_ADAPTEVA_EPIPHANY:
15610 return reloc_type == 6;
aca88567
NC
15611 case EM_ALPHA:
15612 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15613 case EM_ARC_COMPACT:
15614 case EM_ARC_COMPACT2:
b5c37946
SJ
15615 case EM_ARC_COMPACT3:
15616 case EM_ARC_COMPACT3_64:
726c18e1 15617 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15618 case EM_ARM:
3e0873ac 15619 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15620 case EM_AVR_OLD:
15621 case EM_AVR:
15622 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15623 case EM_LOONGARCH:
15624 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15625 case EM_MICROBLAZE:
15626 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15627 case EM_OR1K:
15628 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15629 case EM_PARISC:
85acf597 15630 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15631 case EM_PPC:
15632 return reloc_type == 26; /* R_PPC_REL32. */
15633 case EM_PPC64:
3e0873ac 15634 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15635 case EM_RISCV:
15636 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15637 case EM_S390_OLD:
15638 case EM_S390:
3e0873ac 15639 return reloc_type == 5; /* R_390_PC32. */
aca88567 15640 case EM_SH:
3e0873ac 15641 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15642 case EM_SPARC32PLUS:
15643 case EM_SPARCV9:
15644 case EM_SPARC:
3e0873ac 15645 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15646 case EM_SPU:
15647 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15648 case EM_TILEGX:
15649 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15650 case EM_TILEPRO:
15651 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15652 case EM_VISIUM:
15653 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15654 case EM_X86_64:
8a9036a4 15655 case EM_L1OM:
7a9068fe 15656 case EM_K1OM:
3e0873ac 15657 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15658 case EM_VAX:
15659 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15660 case EM_XTENSA_OLD:
15661 case EM_XTENSA:
15662 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15663 case EM_KVX:
15664 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15665 default:
15666 /* Do not abort or issue an error message here. Not all targets use
15667 pc-relative 32-bit relocs in their DWARF debug information and we
15668 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15669 more helpful warning message will be generated by apply_relocations
15670 anyway, so just return. */
015dc7e1 15671 return false;
aca88567
NC
15672 }
15673}
15674
15675/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15676 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15677
015dc7e1 15678static bool
dda8d76d 15679is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15680{
dda8d76d 15681 switch (filedata->file_header.e_machine)
aca88567 15682 {
a06ea964
NC
15683 case EM_AARCH64:
15684 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15685 case EM_ARC_COMPACT3_64:
15686 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15687 case EM_ALPHA:
15688 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15689 case EM_IA_64:
262cdac7
AM
15690 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15691 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15692 case EM_LOONGARCH:
15693 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15694 case EM_PARISC:
15695 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15696 case EM_PPC64:
15697 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15698 case EM_RISCV:
15699 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15700 case EM_SPARC32PLUS:
15701 case EM_SPARCV9:
15702 case EM_SPARC:
714da62f
NC
15703 return reloc_type == 32 /* R_SPARC_64. */
15704 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15705 case EM_X86_64:
8a9036a4 15706 case EM_L1OM:
7a9068fe 15707 case EM_K1OM:
aca88567 15708 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15709 case EM_S390_OLD:
15710 case EM_S390:
aa137e4d
NC
15711 return reloc_type == 22; /* R_S390_64. */
15712 case EM_TILEGX:
15713 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15714 case EM_MIPS:
aa137e4d 15715 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15716 case EM_KVX:
15717 return reloc_type == 3; /* R_KVX_64 */
aca88567 15718 default:
015dc7e1 15719 return false;
aca88567
NC
15720 }
15721}
15722
85acf597
RH
15723/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15724 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15725
015dc7e1 15726static bool
dda8d76d 15727is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15728{
dda8d76d 15729 switch (filedata->file_header.e_machine)
85acf597 15730 {
a06ea964
NC
15731 case EM_AARCH64:
15732 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15733 case EM_ALPHA:
aa137e4d 15734 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15735 case EM_IA_64:
262cdac7
AM
15736 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15737 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15738 case EM_PARISC:
aa137e4d 15739 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15740 case EM_PPC64:
aa137e4d 15741 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15742 case EM_SPARC32PLUS:
15743 case EM_SPARCV9:
15744 case EM_SPARC:
aa137e4d 15745 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15746 case EM_X86_64:
8a9036a4 15747 case EM_L1OM:
7a9068fe 15748 case EM_K1OM:
aa137e4d 15749 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15750 case EM_S390_OLD:
15751 case EM_S390:
aa137e4d
NC
15752 return reloc_type == 23; /* R_S390_PC64. */
15753 case EM_TILEGX:
15754 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15755 default:
015dc7e1 15756 return false;
85acf597
RH
15757 }
15758}
15759
4dc3c23d
AM
15760/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15761 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15762
015dc7e1 15763static bool
dda8d76d 15764is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15765{
dda8d76d 15766 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15767 {
15768 case EM_CYGNUS_MN10200:
15769 case EM_MN10200:
15770 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15771 case EM_FT32:
15772 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15773 case EM_Z80:
15774 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15775 default:
015dc7e1 15776 return false;
4dc3c23d
AM
15777 }
15778}
15779
aca88567
NC
15780/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15781 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15782
015dc7e1 15783static bool
dda8d76d 15784is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15785{
d347c9df 15786 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15787 switch (filedata->file_header.e_machine)
4b78141a 15788 {
886a2506
NC
15789 case EM_ARC:
15790 case EM_ARC_COMPACT:
15791 case EM_ARC_COMPACT2:
b5c37946
SJ
15792 case EM_ARC_COMPACT3:
15793 case EM_ARC_COMPACT3_64:
886a2506 15794 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15795 case EM_ADAPTEVA_EPIPHANY:
15796 return reloc_type == 5;
aca88567
NC
15797 case EM_AVR_OLD:
15798 case EM_AVR:
15799 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15800 case EM_CYGNUS_D10V:
15801 case EM_D10V:
15802 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15803 case EM_FT32:
15804 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15805 case EM_H8S:
15806 case EM_H8_300:
15807 case EM_H8_300H:
aca88567
NC
15808 return reloc_type == R_H8_DIR16;
15809 case EM_IP2K_OLD:
15810 case EM_IP2K:
15811 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15812 case EM_M32C_OLD:
f4236fe4
DD
15813 case EM_M32C:
15814 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15815 case EM_CYGNUS_MN10200:
15816 case EM_MN10200:
15817 return reloc_type == 2; /* R_MN10200_16. */
15818 case EM_CYGNUS_MN10300:
15819 case EM_MN10300:
15820 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15821 case EM_KVX:
15822 return reloc_type == 1; /* R_KVX_16 */
aca88567 15823 case EM_MSP430:
dda8d76d 15824 if (uses_msp430x_relocs (filedata))
13761a11 15825 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15826 /* Fall through. */
78c8d46c 15827 case EM_MSP430_OLD:
aca88567 15828 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15829 case EM_NDS32:
81c5e376 15830 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15831 case EM_ALTERA_NIOS2:
36591ba1 15832 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15833 case EM_NIOS32:
15834 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15835 case EM_OR1K:
15836 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15837 case EM_RISCV:
15838 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15839 case EM_TI_PRU:
15840 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15841 case EM_TI_C6000:
15842 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15843 case EM_VISIUM:
15844 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15845 case EM_XGATE:
15846 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15847 case EM_Z80:
15848 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15849 default:
015dc7e1 15850 return false;
4b78141a
NC
15851 }
15852}
15853
39e07931
AS
15854/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15855 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15856
015dc7e1 15857static bool
39e07931
AS
15858is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15859{
15860 switch (filedata->file_header.e_machine)
15861 {
15862 case EM_RISCV:
15863 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15864 case EM_Z80:
15865 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15866 case EM_MICROBLAZE:
15867 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15868 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15869 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15870 default:
015dc7e1 15871 return false;
39e07931
AS
15872 }
15873}
15874
15875/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15876 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15877
015dc7e1 15878static bool
39e07931
AS
15879is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15880{
15881 switch (filedata->file_header.e_machine)
15882 {
15883 case EM_RISCV:
15884 return reloc_type == 53; /* R_RISCV_SET6. */
15885 default:
015dc7e1 15886 return false;
39e07931
AS
15887 }
15888}
15889
03336641
JW
15890/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15891 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15892
015dc7e1 15893static bool
03336641
JW
15894is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15895{
15896 /* Please keep this table alpha-sorted for ease of visual lookup. */
15897 switch (filedata->file_header.e_machine)
15898 {
76244462 15899 case EM_LOONGARCH:
15900 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15901 case EM_RISCV:
15902 return reloc_type == 35; /* R_RISCV_ADD32. */
15903 default:
015dc7e1 15904 return false;
03336641
JW
15905 }
15906}
15907
15908/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15909 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15910
015dc7e1 15911static bool
03336641
JW
15912is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15913{
15914 /* Please keep this table alpha-sorted for ease of visual lookup. */
15915 switch (filedata->file_header.e_machine)
15916 {
76244462 15917 case EM_LOONGARCH:
15918 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15919 case EM_RISCV:
15920 return reloc_type == 39; /* R_RISCV_SUB32. */
15921 default:
015dc7e1 15922 return false;
03336641
JW
15923 }
15924}
15925
15926/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15927 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15928
015dc7e1 15929static bool
03336641
JW
15930is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15931{
15932 /* Please keep this table alpha-sorted for ease of visual lookup. */
15933 switch (filedata->file_header.e_machine)
15934 {
76244462 15935 case EM_LOONGARCH:
15936 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15937 case EM_RISCV:
15938 return reloc_type == 36; /* R_RISCV_ADD64. */
15939 default:
015dc7e1 15940 return false;
03336641
JW
15941 }
15942}
15943
15944/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15945 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15946
015dc7e1 15947static bool
03336641
JW
15948is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15949{
15950 /* Please keep this table alpha-sorted for ease of visual lookup. */
15951 switch (filedata->file_header.e_machine)
15952 {
76244462 15953 case EM_LOONGARCH:
15954 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15955 case EM_RISCV:
15956 return reloc_type == 40; /* R_RISCV_SUB64. */
15957 default:
015dc7e1 15958 return false;
03336641
JW
15959 }
15960}
15961
15962/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15963 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15964
015dc7e1 15965static bool
03336641
JW
15966is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15967{
15968 /* Please keep this table alpha-sorted for ease of visual lookup. */
15969 switch (filedata->file_header.e_machine)
15970 {
76244462 15971 case EM_LOONGARCH:
15972 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15973 case EM_RISCV:
15974 return reloc_type == 34; /* R_RISCV_ADD16. */
15975 default:
015dc7e1 15976 return false;
03336641
JW
15977 }
15978}
15979
15980/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15981 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15982
015dc7e1 15983static bool
03336641
JW
15984is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15985{
15986 /* Please keep this table alpha-sorted for ease of visual lookup. */
15987 switch (filedata->file_header.e_machine)
15988 {
76244462 15989 case EM_LOONGARCH:
15990 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15991 case EM_RISCV:
15992 return reloc_type == 38; /* R_RISCV_SUB16. */
15993 default:
015dc7e1 15994 return false;
03336641
JW
15995 }
15996}
15997
15998/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15999 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
16000
015dc7e1 16001static bool
03336641
JW
16002is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16003{
16004 /* Please keep this table alpha-sorted for ease of visual lookup. */
16005 switch (filedata->file_header.e_machine)
16006 {
76244462 16007 case EM_LOONGARCH:
16008 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
16009 case EM_RISCV:
16010 return reloc_type == 33; /* R_RISCV_ADD8. */
16011 default:
015dc7e1 16012 return false;
03336641
JW
16013 }
16014}
16015
16016/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16017 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
16018
015dc7e1 16019static bool
03336641
JW
16020is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16021{
16022 /* Please keep this table alpha-sorted for ease of visual lookup. */
16023 switch (filedata->file_header.e_machine)
16024 {
76244462 16025 case EM_LOONGARCH:
16026 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
16027 case EM_RISCV:
16028 return reloc_type == 37; /* R_RISCV_SUB8. */
16029 default:
015dc7e1 16030 return false;
03336641
JW
16031 }
16032}
16033
76244462 16034/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16035 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
16036
16037static bool
16038is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16039{
16040 switch (filedata->file_header.e_machine)
16041 {
16042 case EM_LOONGARCH:
16043 return reloc_type == 105; /* R_LARCH_ADD6. */
16044 default:
16045 return false;
16046 }
16047}
16048
39e07931
AS
16049/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16050 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
16051
015dc7e1 16052static bool
39e07931
AS
16053is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16054{
16055 switch (filedata->file_header.e_machine)
16056 {
76244462 16057 case EM_LOONGARCH:
16058 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
16059 case EM_RISCV:
16060 return reloc_type == 52; /* R_RISCV_SUB6. */
16061 default:
015dc7e1 16062 return false;
39e07931
AS
16063 }
16064}
16065
2a7b2e88
JK
16066/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
16067 relocation entries (possibly formerly used for SHT_GROUP sections). */
16068
015dc7e1 16069static bool
dda8d76d 16070is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 16071{
dda8d76d 16072 switch (filedata->file_header.e_machine)
2a7b2e88 16073 {
cb8f3167 16074 case EM_386: /* R_386_NONE. */
d347c9df 16075 case EM_68K: /* R_68K_NONE. */
cfb8c092 16076 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
16077 case EM_ALPHA: /* R_ALPHA_NONE. */
16078 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 16079 case EM_ARC: /* R_ARC_NONE. */
886a2506 16080 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 16081 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
16082 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
16083 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 16084 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 16085 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
16086 case EM_FT32: /* R_FT32_NONE. */
16087 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 16088 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 16089 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
16090 case EM_L1OM: /* R_X86_64_NONE. */
16091 case EM_M32R: /* R_M32R_NONE. */
16092 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 16093 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 16094 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
16095 case EM_NIOS32: /* R_NIOS_NONE. */
16096 case EM_OR1K: /* R_OR1K_NONE. */
16097 case EM_PARISC: /* R_PARISC_NONE. */
16098 case EM_PPC64: /* R_PPC64_NONE. */
16099 case EM_PPC: /* R_PPC_NONE. */
e23eba97 16100 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
16101 case EM_S390: /* R_390_NONE. */
16102 case EM_S390_OLD:
16103 case EM_SH: /* R_SH_NONE. */
16104 case EM_SPARC32PLUS:
16105 case EM_SPARC: /* R_SPARC_NONE. */
16106 case EM_SPARCV9:
aa137e4d
NC
16107 case EM_TILEGX: /* R_TILEGX_NONE. */
16108 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
16109 case EM_TI_C6000:/* R_C6000_NONE. */
16110 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 16111 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 16112 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 16113 return reloc_type == 0;
d347c9df 16114
a06ea964
NC
16115 case EM_AARCH64:
16116 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
16117 case EM_AVR_OLD:
16118 case EM_AVR:
16119 return (reloc_type == 0 /* R_AVR_NONE. */
16120 || reloc_type == 30 /* R_AVR_DIFF8. */
16121 || reloc_type == 31 /* R_AVR_DIFF16. */
16122 || reloc_type == 32 /* R_AVR_DIFF32. */);
16123 case EM_METAG:
16124 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 16125 case EM_NDS32:
81c5e376
AM
16126 return (reloc_type == 0 /* R_NDS32_NONE. */
16127 || reloc_type == 205 /* R_NDS32_DIFF8. */
16128 || reloc_type == 206 /* R_NDS32_DIFF16. */
16129 || reloc_type == 207 /* R_NDS32_DIFF32. */
16130 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
16131 case EM_TI_PRU:
16132 return (reloc_type == 0 /* R_PRU_NONE. */
16133 || reloc_type == 65 /* R_PRU_DIFF8. */
16134 || reloc_type == 66 /* R_PRU_DIFF16. */
16135 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
16136 case EM_XTENSA_OLD:
16137 case EM_XTENSA:
4dc3c23d
AM
16138 return (reloc_type == 0 /* R_XTENSA_NONE. */
16139 || reloc_type == 17 /* R_XTENSA_DIFF8. */
16140 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
16141 || reloc_type == 19 /* R_XTENSA_DIFF32. */
16142 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
16143 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
16144 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
16145 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
16146 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
16147 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 16148 }
015dc7e1 16149 return false;
2a7b2e88
JK
16150}
16151
d1c4b12b
NC
16152/* Returns TRUE if there is a relocation against
16153 section NAME at OFFSET bytes. */
16154
015dc7e1 16155bool
31e5a3a3 16156reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
16157{
16158 Elf_Internal_Rela * relocs;
16159 Elf_Internal_Rela * rp;
16160
16161 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 16162 return false;
d1c4b12b
NC
16163
16164 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
16165
16166 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
16167 if (rp->r_offset == offset)
015dc7e1 16168 return true;
d1c4b12b 16169
015dc7e1 16170 return false;
d1c4b12b
NC
16171}
16172
cf13d699 16173/* Apply relocations to a section.
32ec8896
NC
16174 Returns TRUE upon success, FALSE otherwise.
16175 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
16176 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
16177 will be set to the number of relocs loaded.
16178
cf13d699 16179 Note: So far support has been added only for those relocations
32ec8896
NC
16180 which can be found in debug sections. FIXME: Add support for
16181 more relocations ? */
1b315056 16182
015dc7e1 16183static bool
be7d229a
AM
16184apply_relocations (Filedata *filedata,
16185 const Elf_Internal_Shdr *section,
16186 unsigned char *start,
16187 size_t size,
16188 void **relocs_return,
26c527e6 16189 uint64_t *num_relocs_return)
1b315056 16190{
cf13d699 16191 Elf_Internal_Shdr * relsec;
0d2a7a93 16192 unsigned char * end = start + size;
cb8f3167 16193
d1c4b12b
NC
16194 if (relocs_return != NULL)
16195 {
16196 * (Elf_Internal_Rela **) relocs_return = NULL;
16197 * num_relocs_return = 0;
16198 }
16199
dda8d76d 16200 if (filedata->file_header.e_type != ET_REL)
32ec8896 16201 /* No relocs to apply. */
015dc7e1 16202 return true;
1b315056 16203
cf13d699 16204 /* Find the reloc section associated with the section. */
dda8d76d
NC
16205 for (relsec = filedata->section_headers;
16206 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 16207 ++relsec)
252b5132 16208 {
015dc7e1 16209 bool is_rela;
26c527e6 16210 uint64_t num_relocs;
2cf0635d
NC
16211 Elf_Internal_Rela * relocs;
16212 Elf_Internal_Rela * rp;
16213 Elf_Internal_Shdr * symsec;
16214 Elf_Internal_Sym * symtab;
26c527e6 16215 uint64_t num_syms;
2cf0635d 16216 Elf_Internal_Sym * sym;
252b5132 16217
41e92641 16218 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16219 || relsec->sh_info >= filedata->file_header.e_shnum
16220 || filedata->section_headers + relsec->sh_info != section
c256ffe7 16221 || relsec->sh_size == 0
dda8d76d 16222 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 16223 continue;
428409d5 16224
a788aedd
AM
16225 symsec = filedata->section_headers + relsec->sh_link;
16226 if (symsec->sh_type != SHT_SYMTAB
16227 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 16228 return false;
a788aedd 16229
41e92641
NC
16230 is_rela = relsec->sh_type == SHT_RELA;
16231
16232 if (is_rela)
16233 {
dda8d76d 16234 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 16235 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 16236 return false;
41e92641
NC
16237 }
16238 else
16239 {
dda8d76d 16240 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 16241 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 16242 return false;
41e92641
NC
16243 }
16244
16245 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 16246 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 16247 is_rela = false;
428409d5 16248
4de91c10 16249 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 16250
41e92641 16251 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 16252 {
625d49fc 16253 uint64_t addend;
015dc7e1
AM
16254 unsigned int reloc_type;
16255 unsigned int reloc_size;
16256 bool reloc_inplace = false;
16257 bool reloc_subtract = false;
16258 unsigned char *rloc;
26c527e6 16259 uint64_t sym_index;
4b78141a 16260
dda8d76d 16261 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 16262
dda8d76d 16263 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 16264 continue;
dda8d76d 16265 else if (is_none_reloc (filedata, reloc_type))
98fb390a 16266 continue;
dda8d76d
NC
16267 else if (is_32bit_abs_reloc (filedata, reloc_type)
16268 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 16269 reloc_size = 4;
dda8d76d
NC
16270 else if (is_64bit_abs_reloc (filedata, reloc_type)
16271 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 16272 reloc_size = 8;
dda8d76d 16273 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 16274 reloc_size = 3;
dda8d76d 16275 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 16276 reloc_size = 2;
39e07931
AS
16277 else if (is_8bit_abs_reloc (filedata, reloc_type)
16278 || is_6bit_abs_reloc (filedata, reloc_type))
16279 reloc_size = 1;
03336641
JW
16280 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
16281 reloc_type))
16282 || is_32bit_inplace_add_reloc (filedata, reloc_type))
16283 {
16284 reloc_size = 4;
015dc7e1 16285 reloc_inplace = true;
03336641
JW
16286 }
16287 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
16288 reloc_type))
16289 || is_64bit_inplace_add_reloc (filedata, reloc_type))
16290 {
16291 reloc_size = 8;
015dc7e1 16292 reloc_inplace = true;
03336641
JW
16293 }
16294 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
16295 reloc_type))
16296 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16297 {
16298 reloc_size = 2;
015dc7e1 16299 reloc_inplace = true;
03336641
JW
16300 }
16301 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16302 reloc_type))
16303 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16304 {
16305 reloc_size = 1;
015dc7e1 16306 reloc_inplace = true;
03336641 16307 }
39e07931 16308 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 16309 reloc_type))
16310 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16311 {
16312 reloc_size = 1;
015dc7e1 16313 reloc_inplace = true;
39e07931 16314 }
aca88567 16315 else
4b78141a 16316 {
bee0ee85 16317 static unsigned int prev_reloc = 0;
dda8d76d 16318
bee0ee85
NC
16319 if (reloc_type != prev_reloc)
16320 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 16321 reloc_type, printable_section_name (filedata, section));
bee0ee85 16322 prev_reloc = reloc_type;
4b78141a
NC
16323 continue;
16324 }
103f02d3 16325
91d6fa6a 16326 rloc = start + rp->r_offset;
75802ccb 16327 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 16328 {
26c527e6
AM
16329 warn (_("skipping invalid relocation offset %#" PRIx64
16330 " in section %s\n"),
16331 rp->r_offset,
dda8d76d 16332 printable_section_name (filedata, section));
700dd8b7
L
16333 continue;
16334 }
103f02d3 16335
26c527e6 16336 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
16337 if (sym_index >= num_syms)
16338 {
26c527e6
AM
16339 warn (_("skipping invalid relocation symbol index %#" PRIx64
16340 " in section %s\n"),
dda8d76d 16341 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
16342 continue;
16343 }
16344 sym = symtab + sym_index;
41e92641
NC
16345
16346 /* If the reloc has a symbol associated with it,
55f25fc3
L
16347 make sure that it is of an appropriate type.
16348
16349 Relocations against symbols without type can happen.
16350 Gcc -feliminate-dwarf2-dups may generate symbols
16351 without type for debug info.
16352
16353 Icc generates relocations against function symbols
16354 instead of local labels.
16355
16356 Relocations against object symbols can happen, eg when
16357 referencing a global array. For an example of this see
16358 the _clz.o binary in libgcc.a. */
aca88567 16359 if (sym != symtab
b8871f35 16360 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 16361 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 16362 {
26c527e6 16363 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
16364 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16365 printable_section_name (filedata, relsec),
26c527e6 16366 rp - relocs);
aca88567 16367 continue;
5b18a4bc 16368 }
252b5132 16369
4dc3c23d
AM
16370 addend = 0;
16371 if (is_rela)
16372 addend += rp->r_addend;
c47320c3
AM
16373 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16374 partial_inplace. */
4dc3c23d 16375 if (!is_rela
dda8d76d 16376 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 16377 && reloc_type == 1)
dda8d76d
NC
16378 || ((filedata->file_header.e_machine == EM_PJ
16379 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 16380 && reloc_type == 1)
dda8d76d
NC
16381 || ((filedata->file_header.e_machine == EM_D30V
16382 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
16383 && reloc_type == 12)
16384 || reloc_inplace)
39e07931
AS
16385 {
16386 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16387 addend += byte_get (rloc, reloc_size) & 0x3f;
16388 else
16389 addend += byte_get (rloc, reloc_size);
16390 }
cb8f3167 16391
dda8d76d
NC
16392 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16393 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
16394 {
16395 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 16396 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 16397 addend -= 8;
91d6fa6a 16398 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
16399 reloc_size);
16400 }
39e07931 16401 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 16402 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16403 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16404 {
16405 if (reloc_subtract)
16406 addend -= sym->st_value;
16407 else
16408 addend += sym->st_value;
16409 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16410 byte_put (rloc, addend, reloc_size);
16411 }
03336641
JW
16412 else if (reloc_subtract)
16413 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 16414 else
91d6fa6a 16415 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 16416 }
252b5132 16417
5b18a4bc 16418 free (symtab);
f84ce13b
NC
16419 /* Let the target specific reloc processing code know that
16420 we have finished with these relocs. */
dda8d76d 16421 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
16422
16423 if (relocs_return)
16424 {
16425 * (Elf_Internal_Rela **) relocs_return = relocs;
16426 * num_relocs_return = num_relocs;
16427 }
16428 else
16429 free (relocs);
16430
5b18a4bc
NC
16431 break;
16432 }
32ec8896 16433
015dc7e1 16434 return true;
5b18a4bc 16435}
103f02d3 16436
cf13d699 16437#ifdef SUPPORT_DISASSEMBLY
015dc7e1 16438static bool
dda8d76d 16439disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16440{
dda8d76d 16441 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 16442
74e1a04b 16443 /* FIXME: XXX -- to be done --- XXX */
cf13d699 16444
015dc7e1 16445 return true;
cf13d699
NC
16446}
16447#endif
16448
16449/* Reads in the contents of SECTION from FILE, returning a pointer
16450 to a malloc'ed buffer or NULL if something went wrong. */
16451
16452static char *
dda8d76d 16453get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16454{
be7d229a 16455 uint64_t num_bytes = section->sh_size;
cf13d699
NC
16456
16457 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16458 {
c6b78c96 16459 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 16460 printable_section_name (filedata, section));
cf13d699
NC
16461 return NULL;
16462 }
16463
dda8d76d 16464 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 16465 _("section contents"));
cf13d699
NC
16466}
16467
1f5a3546 16468/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 16469
015dc7e1 16470static bool
45f5fe46
NC
16471uncompress_section_contents (bool is_zstd,
16472 unsigned char ** buffer,
16473 uint64_t uncompressed_size,
16474 uint64_t * size,
16475 uint64_t file_size)
0e602686 16476{
31e5a3a3
AM
16477 uint64_t compressed_size = *size;
16478 unsigned char *compressed_buffer = *buffer;
45f5fe46 16479 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
16480 z_stream strm;
16481 int rc;
16482
f9ee45c3 16483 /* Similar to bfd_section_size_insane() in the BFD library we expect an
45f5fe46
NC
16484 upper limit of ~10x compression. Any compression larger than that is
16485 thought to be due to fuzzing of the compression header. */
16486 if (uncompressed_size > file_size * 10)
16487 {
16488 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16489 uncompressed_size);
16490 goto fail;
16491 }
16492
16493 uncompressed_buffer = xmalloc (uncompressed_size);
5d526bdf 16494
1f5a3546
FS
16495 if (is_zstd)
16496 {
16497#ifdef HAVE_ZSTD
16498 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16499 compressed_buffer, compressed_size);
16500 if (ZSTD_isError (ret))
16501 goto fail;
16502#endif
16503 }
16504 else
16505 {
16506 /* It is possible the section consists of several compressed
16507 buffers concatenated together, so we uncompress in a loop. */
16508 /* PR 18313: The state field in the z_stream structure is supposed
16509 to be invisible to the user (ie us), but some compilers will
16510 still complain about it being used without initialisation. So
16511 we first zero the entire z_stream structure and then set the fields
16512 that we need. */
16513 memset (&strm, 0, sizeof strm);
16514 strm.avail_in = compressed_size;
16515 strm.next_in = (Bytef *)compressed_buffer;
16516 strm.avail_out = uncompressed_size;
16517
16518 rc = inflateInit (&strm);
16519 while (strm.avail_in > 0)
16520 {
16521 if (rc != Z_OK)
16522 break;
16523 strm.next_out = ((Bytef *)uncompressed_buffer
16524 + (uncompressed_size - strm.avail_out));
16525 rc = inflate (&strm, Z_FINISH);
16526 if (rc != Z_STREAM_END)
16527 break;
16528 rc = inflateReset (&strm);
16529 }
16530 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16531 goto fail;
16532 }
0e602686
NC
16533
16534 *buffer = uncompressed_buffer;
16535 *size = uncompressed_size;
015dc7e1 16536 return true;
0e602686
NC
16537
16538 fail:
16539 free (uncompressed_buffer);
16540 /* Indicate decompression failure. */
16541 *buffer = NULL;
015dc7e1 16542 return false;
0e602686 16543}
dd24e3da 16544
fab62191
NC
16545static uint64_t
16546maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16547 Filedata * filedata,
16548 unsigned char ** start_ptr,
94e2b2a7 16549 unsigned char ** decomp_buf,
fab62191 16550 bool relocate)
cf13d699 16551{
fab62191
NC
16552 uint64_t section_size = section->sh_size;
16553 unsigned char * start = * start_ptr;
5d526bdf 16554
0e602686
NC
16555 if (decompress_dumps)
16556 {
fab62191 16557 uint64_t new_size = section_size;
31e5a3a3 16558 uint64_t uncompressed_size = 0;
1f5a3546 16559 bool is_zstd = false;
0e602686
NC
16560
16561 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16562 {
16563 Elf_Internal_Chdr chdr;
16564 unsigned int compression_header_size
fab62191
NC
16565 = get_compression_header (& chdr, start, section_size);
16566
5844b465
NC
16567 if (compression_header_size == 0)
16568 /* An error message will have already been generated
16569 by get_compression_header. */
fab62191 16570 return (uint64_t) -1;
0e602686 16571
89dbeac7 16572 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16573 ;
16574#ifdef HAVE_ZSTD
89dbeac7 16575 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16576 is_zstd = true;
16577#endif
16578 else
0e602686 16579 {
813dabb9 16580 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16581 printable_section_name (filedata, section), chdr.ch_type);
fab62191 16582 return (uint64_t) -1;
813dabb9 16583 }
fab62191 16584
813dabb9
L
16585 uncompressed_size = chdr.ch_size;
16586 start += compression_header_size;
16587 new_size -= compression_header_size;
0e602686
NC
16588 }
16589 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16590 {
16591 /* Read the zlib header. In this case, it should be "ZLIB"
16592 followed by the uncompressed section size, 8 bytes in
16593 big-endian order. */
16594 uncompressed_size = start[4]; uncompressed_size <<= 8;
16595 uncompressed_size += start[5]; uncompressed_size <<= 8;
16596 uncompressed_size += start[6]; uncompressed_size <<= 8;
16597 uncompressed_size += start[7]; uncompressed_size <<= 8;
16598 uncompressed_size += start[8]; uncompressed_size <<= 8;
16599 uncompressed_size += start[9]; uncompressed_size <<= 8;
16600 uncompressed_size += start[10]; uncompressed_size <<= 8;
16601 uncompressed_size += start[11];
16602 start += 12;
16603 new_size -= 12;
16604 }
16605
1835f746
NC
16606 if (uncompressed_size)
16607 {
1f5a3546 16608 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16609 &new_size, filedata->file_size))
94e2b2a7
AM
16610 {
16611 *decomp_buf = start;
16612 section_size = new_size;
16613 }
1835f746
NC
16614 else
16615 {
16616 error (_("Unable to decompress section %s\n"),
dda8d76d 16617 printable_section_name (filedata, section));
fab62191 16618 return (uint64_t) -1;
1835f746
NC
16619 }
16620 }
bc303e5d 16621 else
fab62191
NC
16622 start = * start_ptr;
16623 }
16624 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16625 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16626 {
16627 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
0e602686 16628 }
fd8008d8 16629
fab62191 16630 if (relocate)
cf13d699 16631 {
fab62191
NC
16632 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16633 return (uint64_t) -1;
16634 }
16635 else
16636 {
16637 Elf_Internal_Shdr *relsec;
cf13d699 16638
fab62191
NC
16639 /* If the section being dumped has relocations against it the user might
16640 be expecting these relocations to have been applied. Check for this
16641 case and issue a warning message in order to avoid confusion.
16642 FIXME: Maybe we ought to have an option that dumps a section with
16643 relocs applied ? */
16644 for (relsec = filedata->section_headers;
16645 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16646 ++relsec)
16647 {
16648 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16649 || relsec->sh_info >= filedata->file_header.e_shnum
16650 || filedata->section_headers + relsec->sh_info != section
16651 || relsec->sh_size == 0
16652 || relsec->sh_link >= filedata->file_header.e_shnum)
16653 continue;
16654
16655 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16656 break;
16657 }
cf13d699
NC
16658 }
16659
fab62191
NC
16660 * start_ptr = start;
16661 return section_size;
16662}
16663
16664static bool
16665dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16666{
16667 uint64_t num_bytes;
16668 unsigned char *data;
16669 unsigned char *end;
16670 unsigned char *real_start;
16671 unsigned char *start;
94e2b2a7 16672 unsigned char *decomp_buf;
fab62191
NC
16673 bool some_strings_shown;
16674
16675 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16676 if (start == NULL)
16677 /* PR 21820: Do not fail if the section was empty. */
16678 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16679
16680 num_bytes = section->sh_size;
16681
16682 if (filedata->is_separate)
16683 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16684 printable_section_name (filedata, section),
16685 filedata->file_name);
16686 else
16687 printf (_("\nString dump of section '%s':\n"),
16688 printable_section_name (filedata, section));
16689
94e2b2a7
AM
16690 decomp_buf = NULL;
16691 num_bytes = maybe_expand_or_relocate_section (section, filedata, &start,
16692 &decomp_buf, false);
fab62191
NC
16693 if (num_bytes == (uint64_t) -1)
16694 goto error_out;
16695
cf13d699
NC
16696 data = start;
16697 end = start + num_bytes;
015dc7e1 16698 some_strings_shown = false;
cf13d699 16699
ba3265d0
NC
16700#ifdef HAVE_MBSTATE_T
16701 mbstate_t state;
16702 /* Initialise the multibyte conversion state. */
16703 memset (& state, 0, sizeof (state));
16704#endif
16705
015dc7e1 16706 bool continuing = false;
ba3265d0 16707
cf13d699
NC
16708 while (data < end)
16709 {
16710 while (!ISPRINT (* data))
16711 if (++ data >= end)
16712 break;
16713
16714 if (data < end)
16715 {
071436c6
NC
16716 size_t maxlen = end - data;
16717
ba3265d0
NC
16718 if (continuing)
16719 {
16720 printf (" ");
015dc7e1 16721 continuing = false;
ba3265d0
NC
16722 }
16723 else
16724 {
26c527e6 16725 printf (" [%6tx] ", data - start);
ba3265d0
NC
16726 }
16727
4082ef84
NC
16728 if (maxlen > 0)
16729 {
f3da8a96 16730 char c = 0;
ba3265d0
NC
16731
16732 while (maxlen)
16733 {
16734 c = *data++;
16735
16736 if (c == 0)
16737 break;
16738
16739 /* PR 25543: Treat new-lines as string-ending characters. */
16740 if (c == '\n')
16741 {
16742 printf ("\\n\n");
16743 if (*data != 0)
015dc7e1 16744 continuing = true;
ba3265d0
NC
16745 break;
16746 }
16747
16748 /* Do not print control characters directly as they can affect terminal
16749 settings. Such characters usually appear in the names generated
16750 by the assembler for local labels. */
16751 if (ISCNTRL (c))
16752 {
16753 printf ("^%c", c + 0x40);
16754 }
16755 else if (ISPRINT (c))
16756 {
16757 putchar (c);
16758 }
16759 else
16760 {
16761 size_t n;
16762#ifdef HAVE_MBSTATE_T
16763 wchar_t w;
16764#endif
16765 /* Let printf do the hard work of displaying multibyte characters. */
16766 printf ("%.1s", data - 1);
16767#ifdef HAVE_MBSTATE_T
16768 /* Try to find out how many bytes made up the character that was
16769 just printed. Advance the symbol pointer past the bytes that
16770 were displayed. */
16771 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16772#else
16773 n = 1;
16774#endif
16775 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16776 data += (n - 1);
16777 }
16778 }
16779
16780 if (c != '\n')
16781 putchar ('\n');
4082ef84
NC
16782 }
16783 else
16784 {
16785 printf (_("<corrupt>\n"));
16786 data = end;
16787 }
015dc7e1 16788 some_strings_shown = true;
cf13d699
NC
16789 }
16790 }
16791
16792 if (! some_strings_shown)
16793 printf (_(" No strings found in this section."));
16794
94e2b2a7 16795 free (decomp_buf);
0e602686 16796 free (real_start);
cf13d699
NC
16797
16798 putchar ('\n');
015dc7e1 16799 return true;
f761cb13
AM
16800
16801error_out:
94e2b2a7 16802 free (decomp_buf);
f761cb13 16803 free (real_start);
015dc7e1 16804 return false;
cf13d699
NC
16805}
16806
015dc7e1
AM
16807static bool
16808dump_section_as_bytes (Elf_Internal_Shdr *section,
16809 Filedata *filedata,
16810 bool relocate)
cf13d699 16811{
be7d229a
AM
16812 size_t bytes;
16813 uint64_t section_size;
625d49fc 16814 uint64_t addr;
be7d229a
AM
16815 unsigned char *data;
16816 unsigned char *real_start;
16817 unsigned char *start;
94e2b2a7 16818 unsigned char *decomp_buf;
0e602686 16819
dda8d76d 16820 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16821 if (start == NULL)
c6b78c96 16822 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16823 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16824
0e602686 16825 section_size = section->sh_size;
cf13d699 16826
835f2fae
NC
16827 if (filedata->is_separate)
16828 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16829 printable_section_name (filedata, section),
16830 filedata->file_name);
16831 else
16832 printf (_("\nHex dump of section '%s':\n"),
16833 printable_section_name (filedata, section));
cf13d699 16834
94e2b2a7
AM
16835 decomp_buf = NULL;
16836 section_size = maybe_expand_or_relocate_section (section, filedata, &start,
16837 &decomp_buf, relocate);
fab62191
NC
16838 if (section_size == (uint64_t) -1)
16839 goto error_out;
cf13d699
NC
16840
16841 addr = section->sh_addr;
0e602686 16842 bytes = section_size;
cf13d699
NC
16843 data = start;
16844
16845 while (bytes)
16846 {
16847 int j;
16848 int k;
16849 int lbytes;
16850
16851 lbytes = (bytes > 16 ? 16 : bytes);
16852
26c527e6 16853 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16854
16855 for (j = 0; j < 16; j++)
16856 {
16857 if (j < lbytes)
16858 printf ("%2.2x", data[j]);
16859 else
16860 printf (" ");
16861
16862 if ((j & 3) == 3)
16863 printf (" ");
16864 }
16865
16866 for (j = 0; j < lbytes; j++)
16867 {
16868 k = data[j];
16869 if (k >= ' ' && k < 0x7f)
16870 printf ("%c", k);
16871 else
16872 printf (".");
16873 }
16874
16875 putchar ('\n');
16876
16877 data += lbytes;
16878 addr += lbytes;
16879 bytes -= lbytes;
16880 }
16881
94e2b2a7 16882 free (decomp_buf);
0e602686 16883 free (real_start);
cf13d699
NC
16884
16885 putchar ('\n');
015dc7e1 16886 return true;
f761cb13
AM
16887
16888 error_out:
94e2b2a7 16889 free (decomp_buf);
f761cb13 16890 free (real_start);
015dc7e1 16891 return false;
cf13d699
NC
16892}
16893
094e34f2 16894#ifdef ENABLE_LIBCTF
7d9813f1
NA
16895static ctf_sect_t *
16896shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16897{
b6ac461a 16898 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16899 buf->cts_size = shdr->sh_size;
16900 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16901
16902 return buf;
16903}
16904
16905/* Formatting callback function passed to ctf_dump. Returns either the pointer
16906 it is passed, or a pointer to newly-allocated storage, in which case
16907 dump_ctf() will free it when it no longer needs it. */
16908
2f6ecaed
NA
16909static char *
16910dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16911 char *s, void *arg)
7d9813f1 16912{
3e50a591 16913 const char *blanks = arg;
86b26b45 16914 return xasprintf ("%s%s", blanks, s);
7d9813f1
NA
16915}
16916
926c9e76
NA
16917/* Dump CTF errors/warnings. */
16918static void
139633c3 16919dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16920{
16921 ctf_next_t *it = NULL;
16922 char *errtext;
16923 int is_warning;
16924 int err;
16925
16926 /* Dump accumulated errors and warnings. */
16927 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16928 {
5e9b84f7 16929 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16930 errtext);
16931 free (errtext);
16932 }
16933 if (err != ECTF_NEXT_END)
16934 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16935}
16936
2f6ecaed
NA
16937/* Dump one CTF archive member. */
16938
80b56fad
NA
16939static void
16940dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16941 size_t member)
2f6ecaed 16942{
2f6ecaed
NA
16943 const char *things[] = {"Header", "Labels", "Data objects",
16944 "Function objects", "Variables", "Types", "Strings",
16945 ""};
16946 const char **thing;
16947 size_t i;
16948
80b56fad
NA
16949 /* Don't print out the name of the default-named archive member if it appears
16950 first in the list. The name .ctf appears everywhere, even for things that
16951 aren't really archives, so printing it out is liable to be confusing; also,
16952 the common case by far is for only one archive member to exist, and hiding
16953 it in that case seems worthwhile. */
2f6ecaed 16954
80b56fad
NA
16955 if (strcmp (name, ".ctf") != 0 || member != 0)
16956 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16957
80b56fad
NA
16958 if (ctf_parent_name (ctf) != NULL)
16959 ctf_import (ctf, parent);
2f6ecaed
NA
16960
16961 for (i = 0, thing = things; *thing[0]; thing++, i++)
16962 {
16963 ctf_dump_state_t *s = NULL;
16964 char *item;
16965
16966 printf ("\n %s:\n", *thing);
16967 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16968 (void *) " ")) != NULL)
16969 {
16970 printf ("%s\n", item);
16971 free (item);
16972 }
16973
16974 if (ctf_errno (ctf))
16975 {
16976 error (_("Iteration failed: %s, %s\n"), *thing,
16977 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16978 break;
2f6ecaed
NA
16979 }
16980 }
8b37e7b6 16981
926c9e76 16982 dump_ctf_errs (ctf);
2f6ecaed
NA
16983}
16984
015dc7e1 16985static bool
7d9813f1
NA
16986dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16987{
7d9813f1
NA
16988 Elf_Internal_Shdr * symtab_sec = NULL;
16989 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16990 void * data = NULL;
16991 void * symdata = NULL;
16992 void * strdata = NULL;
80b56fad 16993 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16994 ctf_sect_t * symsectp = NULL;
16995 ctf_sect_t * strsectp = NULL;
2f6ecaed 16996 ctf_archive_t * ctfa = NULL;
139633c3 16997 ctf_dict_t * parent = NULL;
80b56fad 16998 ctf_dict_t * fp;
7d9813f1 16999
80b56fad
NA
17000 ctf_next_t *i = NULL;
17001 const char *name;
17002 size_t member = 0;
7d9813f1 17003 int err;
015dc7e1 17004 bool ret = false;
7d9813f1
NA
17005
17006 shdr_to_ctf_sect (&ctfsect, section, filedata);
17007 data = get_section_contents (section, filedata);
17008 ctfsect.cts_data = data;
17009
616febde 17010 if (!dump_ctf_symtab_name)
3d16b64e 17011 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
17012
17013 if (!dump_ctf_strtab_name)
3d16b64e 17014 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
17015
17016 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
17017 {
17018 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
17019 {
17020 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
17021 goto fail;
17022 }
17023 if ((symdata = (void *) get_data (NULL, filedata,
17024 symtab_sec->sh_offset, 1,
17025 symtab_sec->sh_size,
17026 _("symbols"))) == NULL)
17027 goto fail;
17028 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
17029 symsect.cts_data = symdata;
17030 }
835f2fae 17031
df16e041 17032 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
17033 {
17034 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
17035 {
17036 error (_("No string table section named %s\n"),
17037 dump_ctf_strtab_name);
17038 goto fail;
17039 }
17040 if ((strdata = (void *) get_data (NULL, filedata,
17041 strtab_sec->sh_offset, 1,
17042 strtab_sec->sh_size,
17043 _("strings"))) == NULL)
17044 goto fail;
17045 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
17046 strsect.cts_data = strdata;
17047 }
835f2fae 17048
2f6ecaed
NA
17049 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
17050 libctf papers over the difference, so we can pretend it is always an
80b56fad 17051 archive. */
7d9813f1 17052
2f6ecaed 17053 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 17054 {
926c9e76 17055 dump_ctf_errs (NULL);
7d9813f1
NA
17056 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17057 goto fail;
17058 }
17059
96c61be5
NA
17060 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
17061 != ELFDATA2MSB);
17062
80b56fad
NA
17063 /* Preload the parent dict, since it will need to be imported into every
17064 child in turn. */
17065 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 17066 {
926c9e76 17067 dump_ctf_errs (NULL);
2f6ecaed
NA
17068 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17069 goto fail;
7d9813f1
NA
17070 }
17071
015dc7e1 17072 ret = true;
7d9813f1 17073
835f2fae
NC
17074 if (filedata->is_separate)
17075 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
17076 printable_section_name (filedata, section),
17077 filedata->file_name);
17078 else
17079 printf (_("\nDump of CTF section '%s':\n"),
17080 printable_section_name (filedata, section));
7d9813f1 17081
80b56fad 17082 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
bf89fce0
NA
17083 {
17084 dump_ctf_archive_member (fp, name, parent, member++);
17085 ctf_dict_close (fp);
17086 }
80b56fad
NA
17087 if (err != ECTF_NEXT_END)
17088 {
17089 dump_ctf_errs (NULL);
17090 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
17091 ret = false;
17092 }
7d9813f1
NA
17093
17094 fail:
139633c3 17095 ctf_dict_close (parent);
2f6ecaed 17096 ctf_close (ctfa);
7d9813f1
NA
17097 free (data);
17098 free (symdata);
17099 free (strdata);
17100 return ret;
17101}
094e34f2 17102#endif
7d9813f1 17103
42b6953b
IB
17104static bool
17105dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
17106{
17107 void * data = NULL;
17108 sframe_decoder_ctx *sfd_ctx = NULL;
17109 const char *print_name = printable_section_name (filedata, section);
17110
17111 bool ret = true;
17112 size_t sf_size;
17113 int err = 0;
17114
17115 if (strcmp (print_name, "") == 0)
17116 {
17117 error (_("Section name must be provided \n"));
17118 ret = false;
17119 return ret;
17120 }
17121
17122 data = get_section_contents (section, filedata);
17123 sf_size = section->sh_size;
17124 /* Decode the contents of the section. */
17125 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
17126 if (!sfd_ctx)
17127 {
17128 ret = false;
17129 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
17130 goto fail;
17131 }
17132
17133 printf (_("Contents of the SFrame section %s:"), print_name);
17134 /* Dump the contents as text. */
17135 dump_sframe (sfd_ctx, section->sh_addr);
17136
17137 fail:
17138 free (data);
17139 return ret;
17140}
17141
015dc7e1 17142static bool
dda8d76d
NC
17143load_specific_debug_section (enum dwarf_section_display_enum debug,
17144 const Elf_Internal_Shdr * sec,
17145 void * data)
1007acb3 17146{
2cf0635d 17147 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 17148 char buf [64];
dda8d76d 17149 Filedata * filedata = (Filedata *) data;
9abca702 17150
19e6b90e 17151 if (section->start != NULL)
dda8d76d
NC
17152 {
17153 /* If it is already loaded, do nothing. */
17154 if (streq (section->filename, filedata->file_name))
015dc7e1 17155 return true;
dda8d76d
NC
17156 free (section->start);
17157 }
1007acb3 17158
19e6b90e
L
17159 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
17160 section->address = sec->sh_addr;
dda8d76d
NC
17161 section->filename = filedata->file_name;
17162 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
17163 sec->sh_offset, 1,
17164 sec->sh_size, buf);
59245841
NC
17165 if (section->start == NULL)
17166 section->size = 0;
17167 else
17168 {
77115a4a 17169 unsigned char *start = section->start;
31e5a3a3
AM
17170 uint64_t size = sec->sh_size;
17171 uint64_t uncompressed_size = 0;
1f5a3546 17172 bool is_zstd = false;
77115a4a
L
17173
17174 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
17175 {
17176 Elf_Internal_Chdr chdr;
d8024a91
NC
17177 unsigned int compression_header_size;
17178
f53be977
L
17179 if (size < (is_32bit_elf
17180 ? sizeof (Elf32_External_Chdr)
17181 : sizeof (Elf64_External_Chdr)))
d8024a91 17182 {
55be8fd0 17183 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 17184 section->name);
015dc7e1 17185 return false;
d8024a91
NC
17186 }
17187
ebdf1ebf 17188 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
17189 if (compression_header_size == 0)
17190 /* An error message will have already been generated
17191 by get_compression_header. */
015dc7e1 17192 return false;
d8024a91 17193
89dbeac7 17194 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
17195 ;
17196#ifdef HAVE_ZSTD
89dbeac7 17197 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
17198 is_zstd = true;
17199#endif
17200 else
813dabb9
L
17201 {
17202 warn (_("section '%s' has unsupported compress type: %d\n"),
17203 section->name, chdr.ch_type);
015dc7e1 17204 return false;
813dabb9 17205 }
dab394de 17206 uncompressed_size = chdr.ch_size;
77115a4a
L
17207 start += compression_header_size;
17208 size -= compression_header_size;
17209 }
dab394de
L
17210 else if (size > 12 && streq ((char *) start, "ZLIB"))
17211 {
17212 /* Read the zlib header. In this case, it should be "ZLIB"
17213 followed by the uncompressed section size, 8 bytes in
17214 big-endian order. */
17215 uncompressed_size = start[4]; uncompressed_size <<= 8;
17216 uncompressed_size += start[5]; uncompressed_size <<= 8;
17217 uncompressed_size += start[6]; uncompressed_size <<= 8;
17218 uncompressed_size += start[7]; uncompressed_size <<= 8;
17219 uncompressed_size += start[8]; uncompressed_size <<= 8;
17220 uncompressed_size += start[9]; uncompressed_size <<= 8;
17221 uncompressed_size += start[10]; uncompressed_size <<= 8;
17222 uncompressed_size += start[11];
17223 start += 12;
17224 size -= 12;
17225 }
17226
1835f746 17227 if (uncompressed_size)
77115a4a 17228 {
1f5a3546 17229 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 17230 &size, filedata->file_size))
1835f746
NC
17231 {
17232 /* Free the compressed buffer, update the section buffer
17233 and the section size if uncompress is successful. */
17234 free (section->start);
17235 section->start = start;
17236 }
17237 else
17238 {
17239 error (_("Unable to decompress section %s\n"),
dda8d76d 17240 printable_section_name (filedata, sec));
015dc7e1 17241 return false;
1835f746 17242 }
77115a4a 17243 }
bc303e5d 17244
77115a4a 17245 section->size = size;
59245841 17246 }
4a114e3e 17247
1b315056 17248 if (section->start == NULL)
015dc7e1 17249 return false;
1b315056 17250
19e6b90e 17251 if (debug_displays [debug].relocate)
32ec8896 17252 {
dda8d76d 17253 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 17254 & section->reloc_info, & section->num_relocs))
015dc7e1 17255 return false;
32ec8896 17256 }
d1c4b12b
NC
17257 else
17258 {
17259 section->reloc_info = NULL;
17260 section->num_relocs = 0;
17261 }
1007acb3 17262
015dc7e1 17263 return true;
1007acb3
L
17264}
17265
301a9420
AM
17266#if HAVE_LIBDEBUGINFOD
17267/* Return a hex string representation of the build-id. */
17268unsigned char *
17269get_build_id (void * data)
17270{
ca0e11aa 17271 Filedata * filedata = (Filedata *) data;
301a9420 17272 Elf_Internal_Shdr * shdr;
26c527e6 17273 size_t i;
301a9420 17274
55be8fd0
NC
17275 /* Iterate through notes to find note.gnu.build-id.
17276 FIXME: Only the first note in any note section is examined. */
301a9420
AM
17277 for (i = 0, shdr = filedata->section_headers;
17278 i < filedata->file_header.e_shnum && shdr != NULL;
17279 i++, shdr++)
17280 {
17281 if (shdr->sh_type != SHT_NOTE)
17282 continue;
17283
17284 char * next;
17285 char * end;
17286 size_t data_remaining;
17287 size_t min_notesz;
17288 Elf_External_Note * enote;
17289 Elf_Internal_Note inote;
17290
625d49fc
AM
17291 uint64_t offset = shdr->sh_offset;
17292 uint64_t align = shdr->sh_addralign;
17293 uint64_t length = shdr->sh_size;
301a9420
AM
17294
17295 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
17296 if (enote == NULL)
17297 continue;
17298
17299 if (align < 4)
17300 align = 4;
17301 else if (align != 4 && align != 8)
f761cb13
AM
17302 {
17303 free (enote);
17304 continue;
17305 }
301a9420
AM
17306
17307 end = (char *) enote + length;
17308 data_remaining = end - (char *) enote;
17309
17310 if (!is_ia64_vms (filedata))
17311 {
17312 min_notesz = offsetof (Elf_External_Note, name);
17313 if (data_remaining < min_notesz)
17314 {
55be8fd0
NC
17315 warn (_("\
17316malformed note encountered in section %s whilst scanning for build-id note\n"),
17317 printable_section_name (filedata, shdr));
f761cb13 17318 free (enote);
55be8fd0 17319 continue;
301a9420
AM
17320 }
17321 data_remaining -= min_notesz;
17322
17323 inote.type = BYTE_GET (enote->type);
17324 inote.namesz = BYTE_GET (enote->namesz);
17325 inote.namedata = enote->name;
17326 inote.descsz = BYTE_GET (enote->descsz);
17327 inote.descdata = ((char *) enote
17328 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17329 inote.descpos = offset + (inote.descdata - (char *) enote);
17330 next = ((char *) enote
17331 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17332 }
17333 else
17334 {
17335 Elf64_External_VMS_Note *vms_enote;
17336
17337 /* PR binutils/15191
17338 Make sure that there is enough data to read. */
17339 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17340 if (data_remaining < min_notesz)
17341 {
55be8fd0
NC
17342 warn (_("\
17343malformed note encountered in section %s whilst scanning for build-id note\n"),
17344 printable_section_name (filedata, shdr));
f761cb13 17345 free (enote);
55be8fd0 17346 continue;
301a9420
AM
17347 }
17348 data_remaining -= min_notesz;
17349
17350 vms_enote = (Elf64_External_VMS_Note *) enote;
17351 inote.type = BYTE_GET (vms_enote->type);
17352 inote.namesz = BYTE_GET (vms_enote->namesz);
17353 inote.namedata = vms_enote->name;
17354 inote.descsz = BYTE_GET (vms_enote->descsz);
17355 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17356 inote.descpos = offset + (inote.descdata - (char *) enote);
17357 next = inote.descdata + align_power (inote.descsz, 3);
17358 }
17359
17360 /* Skip malformed notes. */
17361 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17362 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17363 || (size_t) (next - inote.descdata) < inote.descsz
17364 || ((size_t) (next - inote.descdata)
17365 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17366 {
55be8fd0
NC
17367 warn (_("\
17368malformed note encountered in section %s whilst scanning for build-id note\n"),
17369 printable_section_name (filedata, shdr));
f761cb13 17370 free (enote);
301a9420
AM
17371 continue;
17372 }
17373
17374 /* Check if this is the build-id note. If so then convert the build-id
17375 bytes to a hex string. */
17376 if (inote.namesz > 0
24d127aa 17377 && startswith (inote.namedata, "GNU")
301a9420
AM
17378 && inote.type == NT_GNU_BUILD_ID)
17379 {
26c527e6 17380 size_t j;
301a9420
AM
17381 char * build_id;
17382
17383 build_id = malloc (inote.descsz * 2 + 1);
17384 if (build_id == NULL)
f761cb13
AM
17385 {
17386 free (enote);
17387 return NULL;
17388 }
301a9420
AM
17389
17390 for (j = 0; j < inote.descsz; ++j)
17391 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17392 build_id[inote.descsz * 2] = '\0';
f761cb13 17393 free (enote);
301a9420 17394
55be8fd0 17395 return (unsigned char *) build_id;
301a9420 17396 }
f761cb13 17397 free (enote);
301a9420
AM
17398 }
17399
17400 return NULL;
17401}
17402#endif /* HAVE_LIBDEBUGINFOD */
17403
657d0d47
CC
17404/* If this is not NULL, load_debug_section will only look for sections
17405 within the list of sections given here. */
32ec8896 17406static unsigned int * section_subset = NULL;
657d0d47 17407
015dc7e1 17408bool
dda8d76d 17409load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 17410{
2cf0635d
NC
17411 struct dwarf_section * section = &debug_displays [debug].section;
17412 Elf_Internal_Shdr * sec;
dda8d76d
NC
17413 Filedata * filedata = (Filedata *) data;
17414
e1dbfc17
L
17415 if (!dump_any_debugging)
17416 return false;
17417
f425ec66
NC
17418 /* Without section headers we cannot find any sections. */
17419 if (filedata->section_headers == NULL)
015dc7e1 17420 return false;
f425ec66 17421
9c1ce108
AM
17422 if (filedata->string_table == NULL
17423 && filedata->file_header.e_shstrndx != SHN_UNDEF
17424 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
17425 {
17426 Elf_Internal_Shdr * strs;
17427
17428 /* Read in the string table, so that we have section names to scan. */
17429 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17430
4dff97b2 17431 if (strs != NULL && strs->sh_size != 0)
dda8d76d 17432 {
9c1ce108
AM
17433 filedata->string_table
17434 = (char *) get_data (NULL, filedata, strs->sh_offset,
17435 1, strs->sh_size, _("string table"));
dda8d76d 17436
9c1ce108
AM
17437 filedata->string_table_length
17438 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
17439 }
17440 }
d966045b
DJ
17441
17442 /* Locate the debug section. */
dda8d76d 17443 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
17444 if (sec != NULL)
17445 section->name = section->uncompressed_name;
17446 else
17447 {
dda8d76d 17448 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
17449 if (sec != NULL)
17450 section->name = section->compressed_name;
17451 }
17452 if (sec == NULL)
015dc7e1 17453 return false;
d966045b 17454
657d0d47
CC
17455 /* If we're loading from a subset of sections, and we've loaded
17456 a section matching this name before, it's likely that it's a
17457 different one. */
17458 if (section_subset != NULL)
17459 free_debug_section (debug);
17460
dda8d76d 17461 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
17462}
17463
19e6b90e
L
17464void
17465free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 17466{
2cf0635d 17467 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 17468
19e6b90e
L
17469 if (section->start == NULL)
17470 return;
1007acb3 17471
19e6b90e
L
17472 free ((char *) section->start);
17473 section->start = NULL;
17474 section->address = 0;
17475 section->size = 0;
a788aedd 17476
9db70fc3
AM
17477 free (section->reloc_info);
17478 section->reloc_info = NULL;
17479 section->num_relocs = 0;
1007acb3
L
17480}
17481
015dc7e1 17482static bool
dda8d76d 17483display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 17484{
84714f86
AM
17485 const char *name = (section_name_valid (filedata, section)
17486 ? section_name (filedata, section) : "");
17487 const char *print_name = printable_section_name (filedata, section);
be7d229a 17488 uint64_t length;
015dc7e1 17489 bool result = true;
3f5e193b 17490 int i;
1007acb3 17491
19e6b90e
L
17492 length = section->sh_size;
17493 if (length == 0)
1007acb3 17494 {
74e1a04b 17495 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 17496 return true;
1007acb3 17497 }
5dff79d8
NC
17498 if (section->sh_type == SHT_NOBITS)
17499 {
17500 /* There is no point in dumping the contents of a debugging section
17501 which has the NOBITS type - the bits in the file will be random.
17502 This can happen when a file containing a .eh_frame section is
17503 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
17504 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17505 print_name);
015dc7e1 17506 return false;
5dff79d8 17507 }
1007acb3 17508
24d127aa 17509 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 17510 name = ".debug_info";
1007acb3 17511
19e6b90e
L
17512 /* See if we know how to display the contents of this section. */
17513 for (i = 0; i < max; i++)
d85bf2ba
NC
17514 {
17515 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17516 struct dwarf_section_display * display = debug_displays + i;
17517 struct dwarf_section * sec = & display->section;
d966045b 17518
d85bf2ba 17519 if (streq (sec->uncompressed_name, name)
24d127aa 17520 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17521 || streq (sec->compressed_name, name))
17522 {
015dc7e1 17523 bool secondary = (section != find_section (filedata, name));
1007acb3 17524
d85bf2ba
NC
17525 if (secondary)
17526 free_debug_section (id);
dda8d76d 17527
24d127aa 17528 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17529 sec->name = name;
17530 else if (streq (sec->uncompressed_name, name))
17531 sec->name = sec->uncompressed_name;
17532 else
17533 sec->name = sec->compressed_name;
657d0d47 17534
d85bf2ba
NC
17535 if (load_specific_debug_section (id, section, filedata))
17536 {
17537 /* If this debug section is part of a CU/TU set in a .dwp file,
17538 restrict load_debug_section to the sections in that set. */
17539 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17540
d85bf2ba 17541 result &= display->display (sec, filedata);
657d0d47 17542
d85bf2ba 17543 section_subset = NULL;
1007acb3 17544
44266f36 17545 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17546 free_debug_section (id);
17547 }
17548 break;
17549 }
17550 }
1007acb3 17551
19e6b90e 17552 if (i == max)
1007acb3 17553 {
74e1a04b 17554 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17555 result = false;
1007acb3
L
17556 }
17557
19e6b90e 17558 return result;
5b18a4bc 17559}
103f02d3 17560
aef1f6d0
DJ
17561/* Set DUMP_SECTS for all sections where dumps were requested
17562 based on section name. */
17563
17564static void
dda8d76d 17565initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17566{
2cf0635d 17567 struct dump_list_entry * cur;
aef1f6d0
DJ
17568
17569 for (cur = dump_sects_byname; cur; cur = cur->next)
17570 {
17571 unsigned int i;
015dc7e1 17572 bool any = false;
aef1f6d0 17573
dda8d76d 17574 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17575 if (section_name_valid (filedata, filedata->section_headers + i)
17576 && streq (section_name (filedata, filedata->section_headers + i),
17577 cur->name))
aef1f6d0 17578 {
6431e409 17579 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17580 any = true;
aef1f6d0
DJ
17581 }
17582
835f2fae
NC
17583 if (!any && !filedata->is_separate)
17584 warn (_("Section '%s' was not dumped because it does not exist\n"),
17585 cur->name);
aef1f6d0
DJ
17586 }
17587}
17588
015dc7e1 17589static bool
dda8d76d 17590process_section_contents (Filedata * filedata)
5b18a4bc 17591{
2cf0635d 17592 Elf_Internal_Shdr * section;
19e6b90e 17593 unsigned int i;
015dc7e1 17594 bool res = true;
103f02d3 17595
19e6b90e 17596 if (! do_dump)
015dc7e1 17597 return true;
103f02d3 17598
dda8d76d 17599 initialise_dumps_byname (filedata);
aef1f6d0 17600
dda8d76d 17601 for (i = 0, section = filedata->section_headers;
6431e409 17602 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17603 i++, section++)
17604 {
6431e409 17605 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17606
d6bfbc39
NC
17607 if (filedata->is_separate && ! process_links)
17608 dump &= DEBUG_DUMP;
047c3dbf 17609
8e8d0b63
NC
17610 if (dump & AUTO_DUMP)
17611 {
17612 switch (section->sh_type)
17613 {
17614 case SHT_PROGBITS:
17615 /* FIXME: There are lots of different type of section that have
17616 SHT_PROGBITS set in their header - code, debug info, etc. So
17617 we should check the section's name and interpret its contents
17618 that way, rather than just defaulting to a byte dump. */
17619#ifdef SUPPORT_DISASSEMBLY
17620 res &= disassemble_section (section, filedata);
17621#else
17622 res &= dump_section_as_bytes (section, filedata, false);
17623#endif
17624 break;
17625
17626 case SHT_DYNSYM:
17627 case SHT_SYMTAB:
17628 res &= dump_symbol_section (section, filedata);
17629 break;
17630
17631 case SHT_STRTAB:
17632 res &= dump_section_as_strings (section, filedata);
17633 break;
17634
17635 case SHT_RELA:
17636 case SHT_REL:
17637 case SHT_RELR:
17638 res &= display_relocations (section, filedata);
17639 break;
17640
17641 case SHT_NOTE:
17642 res &= process_notes_at (filedata, section, section->sh_offset,
17643 section->sh_size, section->sh_addralign);
17644 break;
17645
17646 case SHT_NULL:
17647 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17648 break;
17649
17650 case SHT_NOBITS:
17651 inform (_("Unable to display section %d - it has no contents\n"), i);
17652 break;
17653
17654 case SHT_HASH:
17655 case SHT_DYNAMIC:
17656 case SHT_GROUP:
17657 case SHT_GNU_ATTRIBUTES:
17658 /* FIXME: Implement these. */
17659 /* Fall through. */
17660 default:
17661 /* FIXME: Add Proc and OS specific section types ? */
17662 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17663 i, section->sh_type);
17664 res = false;
17665 break;
17666 }
17667 }
17668
19e6b90e 17669#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17670 if (dump & DISASS_DUMP)
17671 {
17672 if (! disassemble_section (section, filedata))
015dc7e1 17673 res = false;
dda8d76d 17674 }
19e6b90e 17675#endif
dda8d76d 17676 if (dump & HEX_DUMP)
32ec8896 17677 {
015dc7e1
AM
17678 if (! dump_section_as_bytes (section, filedata, false))
17679 res = false;
32ec8896 17680 }
103f02d3 17681
dda8d76d 17682 if (dump & RELOC_DUMP)
32ec8896 17683 {
015dc7e1
AM
17684 if (! dump_section_as_bytes (section, filedata, true))
17685 res = false;
32ec8896 17686 }
09c11c86 17687
dda8d76d 17688 if (dump & STRING_DUMP)
32ec8896 17689 {
dda8d76d 17690 if (! dump_section_as_strings (section, filedata))
015dc7e1 17691 res = false;
32ec8896 17692 }
cf13d699 17693
dda8d76d 17694 if (dump & DEBUG_DUMP)
32ec8896 17695 {
dda8d76d 17696 if (! display_debug_section (i, section, filedata))
015dc7e1 17697 res = false;
32ec8896 17698 }
7d9813f1 17699
094e34f2 17700#ifdef ENABLE_LIBCTF
7d9813f1
NA
17701 if (dump & CTF_DUMP)
17702 {
17703 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17704 res = false;
7d9813f1 17705 }
094e34f2 17706#endif
42b6953b
IB
17707 if (dump & SFRAME_DUMP)
17708 {
17709 if (! dump_section_as_sframe (section, filedata))
17710 res = false;
17711 }
5b18a4bc 17712 }
103f02d3 17713
835f2fae 17714 if (! filedata->is_separate)
0ee3043f 17715 {
835f2fae
NC
17716 /* Check to see if the user requested a
17717 dump of a section that does not exist. */
17718 for (; i < filedata->dump.num_dump_sects; i++)
17719 if (filedata->dump.dump_sects[i])
17720 {
ca0e11aa 17721 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17722 res = false;
835f2fae 17723 }
0ee3043f 17724 }
32ec8896
NC
17725
17726 return res;
5b18a4bc 17727}
103f02d3 17728
5b18a4bc 17729static void
19e6b90e 17730process_mips_fpe_exception (int mask)
5b18a4bc 17731{
19e6b90e
L
17732 if (mask)
17733 {
015dc7e1 17734 bool first = true;
32ec8896 17735
19e6b90e 17736 if (mask & OEX_FPU_INEX)
015dc7e1 17737 fputs ("INEX", stdout), first = false;
19e6b90e 17738 if (mask & OEX_FPU_UFLO)
015dc7e1 17739 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17740 if (mask & OEX_FPU_OFLO)
015dc7e1 17741 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17742 if (mask & OEX_FPU_DIV0)
015dc7e1 17743 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17744 if (mask & OEX_FPU_INVAL)
17745 printf ("%sINVAL", first ? "" : "|");
17746 }
5b18a4bc 17747 else
19e6b90e 17748 fputs ("0", stdout);
5b18a4bc 17749}
103f02d3 17750
f6f0e17b
NC
17751/* Display's the value of TAG at location P. If TAG is
17752 greater than 0 it is assumed to be an unknown tag, and
17753 a message is printed to this effect. Otherwise it is
17754 assumed that a message has already been printed.
17755
17756 If the bottom bit of TAG is set it assumed to have a
17757 string value, otherwise it is assumed to have an integer
17758 value.
17759
17760 Returns an updated P pointing to the first unread byte
17761 beyond the end of TAG's value.
17762
17763 Reads at or beyond END will not be made. */
17764
17765static unsigned char *
60abdbed 17766display_tag_value (signed int tag,
f6f0e17b
NC
17767 unsigned char * p,
17768 const unsigned char * const end)
17769{
26c527e6 17770 uint64_t val;
f6f0e17b
NC
17771
17772 if (tag > 0)
17773 printf (" Tag_unknown_%d: ", tag);
17774
17775 if (p >= end)
17776 {
4082ef84 17777 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17778 }
17779 else if (tag & 1)
17780 {
071436c6 17781 /* PR 17531 file: 027-19978-0.004. */
86a053dd 17782 size_t maxlen = end - p;
071436c6
NC
17783
17784 putchar ('"');
4082ef84
NC
17785 if (maxlen > 0)
17786 {
86a053dd 17787 maxlen -= 1; /* Remove \0 from the character count. */
b6ac461a 17788 print_symbol_name ((int) maxlen, (const char *) p);
86a053dd
ML
17789 size_t len = strnlen ((char *) p, maxlen);
17790 if (len == maxlen && p[maxlen] != '\0')
17791 printf (_("<corrupt string tag>"));
17792 p += len + 1;
4082ef84
NC
17793 }
17794 else
17795 {
17796 printf (_("<corrupt string tag>"));
17797 p = (unsigned char *) end;
17798 }
071436c6 17799 printf ("\"\n");
f6f0e17b
NC
17800 }
17801 else
17802 {
cd30bcef 17803 READ_ULEB (val, p, end);
26c527e6 17804 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17805 }
17806
4082ef84 17807 assert (p <= end);
f6f0e17b
NC
17808 return p;
17809}
17810
53a346d8
CZ
17811/* ARC ABI attributes section. */
17812
17813static unsigned char *
17814display_arc_attribute (unsigned char * p,
17815 const unsigned char * const end)
17816{
17817 unsigned int tag;
53a346d8
CZ
17818 unsigned int val;
17819
cd30bcef 17820 READ_ULEB (tag, p, end);
53a346d8
CZ
17821
17822 switch (tag)
17823 {
17824 case Tag_ARC_PCS_config:
cd30bcef 17825 READ_ULEB (val, p, end);
53a346d8
CZ
17826 printf (" Tag_ARC_PCS_config: ");
17827 switch (val)
17828 {
17829 case 0:
17830 printf (_("Absent/Non standard\n"));
17831 break;
17832 case 1:
17833 printf (_("Bare metal/mwdt\n"));
17834 break;
17835 case 2:
17836 printf (_("Bare metal/newlib\n"));
17837 break;
17838 case 3:
17839 printf (_("Linux/uclibc\n"));
17840 break;
17841 case 4:
17842 printf (_("Linux/glibc\n"));
17843 break;
17844 default:
17845 printf (_("Unknown\n"));
17846 break;
17847 }
17848 break;
17849
17850 case Tag_ARC_CPU_base:
cd30bcef 17851 READ_ULEB (val, p, end);
53a346d8
CZ
17852 printf (" Tag_ARC_CPU_base: ");
17853 switch (val)
17854 {
17855 default:
17856 case TAG_CPU_NONE:
17857 printf (_("Absent\n"));
17858 break;
17859 case TAG_CPU_ARC6xx:
17860 printf ("ARC6xx\n");
17861 break;
17862 case TAG_CPU_ARC7xx:
17863 printf ("ARC7xx\n");
17864 break;
17865 case TAG_CPU_ARCEM:
17866 printf ("ARCEM\n");
17867 break;
17868 case TAG_CPU_ARCHS:
17869 printf ("ARCHS\n");
17870 break;
17871 }
17872 break;
17873
17874 case Tag_ARC_CPU_variation:
cd30bcef 17875 READ_ULEB (val, p, end);
53a346d8
CZ
17876 printf (" Tag_ARC_CPU_variation: ");
17877 switch (val)
17878 {
17879 default:
17880 if (val > 0 && val < 16)
53a346d8 17881 printf ("Core%d\n", val);
d8cbc93b
JL
17882 else
17883 printf ("Unknown\n");
17884 break;
17885
53a346d8
CZ
17886 case 0:
17887 printf (_("Absent\n"));
17888 break;
17889 }
17890 break;
17891
17892 case Tag_ARC_CPU_name:
17893 printf (" Tag_ARC_CPU_name: ");
17894 p = display_tag_value (-1, p, end);
17895 break;
17896
17897 case Tag_ARC_ABI_rf16:
cd30bcef 17898 READ_ULEB (val, p, end);
53a346d8
CZ
17899 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17900 break;
17901
17902 case Tag_ARC_ABI_osver:
cd30bcef 17903 READ_ULEB (val, p, end);
53a346d8
CZ
17904 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17905 break;
17906
17907 case Tag_ARC_ABI_pic:
17908 case Tag_ARC_ABI_sda:
cd30bcef 17909 READ_ULEB (val, p, end);
53a346d8
CZ
17910 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17911 : " Tag_ARC_ABI_pic: ");
17912 switch (val)
17913 {
17914 case 0:
17915 printf (_("Absent\n"));
17916 break;
17917 case 1:
17918 printf ("MWDT\n");
17919 break;
17920 case 2:
17921 printf ("GNU\n");
17922 break;
17923 default:
17924 printf (_("Unknown\n"));
17925 break;
17926 }
17927 break;
17928
17929 case Tag_ARC_ABI_tls:
cd30bcef 17930 READ_ULEB (val, p, end);
53a346d8
CZ
17931 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17932 break;
17933
17934 case Tag_ARC_ABI_enumsize:
cd30bcef 17935 READ_ULEB (val, p, end);
53a346d8
CZ
17936 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17937 _("smallest"));
17938 break;
17939
17940 case Tag_ARC_ABI_exceptions:
cd30bcef 17941 READ_ULEB (val, p, end);
53a346d8
CZ
17942 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17943 : _("default"));
17944 break;
17945
17946 case Tag_ARC_ABI_double_size:
cd30bcef 17947 READ_ULEB (val, p, end);
53a346d8
CZ
17948 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17949 break;
17950
17951 case Tag_ARC_ISA_config:
17952 printf (" Tag_ARC_ISA_config: ");
17953 p = display_tag_value (-1, p, end);
17954 break;
17955
17956 case Tag_ARC_ISA_apex:
17957 printf (" Tag_ARC_ISA_apex: ");
17958 p = display_tag_value (-1, p, end);
17959 break;
17960
17961 case Tag_ARC_ISA_mpy_option:
cd30bcef 17962 READ_ULEB (val, p, end);
53a346d8
CZ
17963 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17964 break;
17965
db1e1b45 17966 case Tag_ARC_ATR_version:
cd30bcef 17967 READ_ULEB (val, p, end);
db1e1b45 17968 printf (" Tag_ARC_ATR_version: %d\n", val);
17969 break;
17970
53a346d8
CZ
17971 default:
17972 return display_tag_value (tag & 1, p, end);
17973 }
17974
17975 return p;
17976}
17977
11c1ff18
PB
17978/* ARM EABI attributes section. */
17979typedef struct
17980{
70e99720 17981 unsigned int tag;
2cf0635d 17982 const char * name;
11c1ff18 17983 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17984 unsigned int type;
288f0ba2 17985 const char *const *table;
11c1ff18
PB
17986} arm_attr_public_tag;
17987
288f0ba2 17988static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17989 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17990 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17991 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17992 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17993static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17994static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17995 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17996static const char *const arm_attr_tag_FP_arch[] =
bca38921 17997 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17998 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17999static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
18000static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
18001 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
18002 "NEON for ARMv8.1"};
288f0ba2 18003static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
18004 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
18005 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 18006static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 18007 {"V6", "SB", "TLS", "Unused"};
288f0ba2 18008static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 18009 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 18010static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 18011 {"Absolute", "PC-relative", "None"};
288f0ba2 18012static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 18013 {"None", "direct", "GOT-indirect"};
288f0ba2 18014static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 18015 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
18016static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
18017static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 18018 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
18019static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
18020static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
18021static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 18022 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 18023static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 18024 {"Unused", "small", "int", "forced to int"};
288f0ba2 18025static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 18026 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 18027static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 18028 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 18029static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 18030 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 18031static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
18032 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
18033 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 18034static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
18035 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
18036 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
18037static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
18038static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 18039 {"Not Allowed", "Allowed"};
288f0ba2 18040static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 18041 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 18042static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 18043 {"Follow architecture", "Allowed"};
288f0ba2 18044static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 18045 {"Not Allowed", "Allowed"};
288f0ba2 18046static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 18047 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 18048 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
18049static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
18050static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 18051 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 18052 "TrustZone and Virtualization Extensions"};
288f0ba2 18053static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 18054 {"Not Allowed", "Allowed"};
11c1ff18 18055
288f0ba2 18056static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
18057 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
18058
99db83d0
AC
18059static const char * arm_attr_tag_PAC_extension[] =
18060 {"No PAC/AUT instructions",
18061 "PAC/AUT instructions permitted in the NOP space",
18062 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
18063
4b535030
AC
18064static const char * arm_attr_tag_BTI_extension[] =
18065 {"BTI instructions not permitted",
18066 "BTI instructions permitted in the NOP space",
18067 "BTI instructions permitted in the NOP and in the non-NOP space"};
18068
b81ee92f
AC
18069static const char * arm_attr_tag_BTI_use[] =
18070 {"Compiled without branch target enforcement",
18071 "Compiled with branch target enforcement"};
18072
c9fed665
AC
18073static const char * arm_attr_tag_PACRET_use[] =
18074 {"Compiled without return address signing and authentication",
18075 "Compiled with return address signing and authentication"};
18076
11c1ff18
PB
18077#define LOOKUP(id, name) \
18078 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 18079static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
18080{
18081 {4, "CPU_raw_name", 1, NULL},
18082 {5, "CPU_name", 1, NULL},
18083 LOOKUP(6, CPU_arch),
18084 {7, "CPU_arch_profile", 0, NULL},
18085 LOOKUP(8, ARM_ISA_use),
18086 LOOKUP(9, THUMB_ISA_use),
75375b3e 18087 LOOKUP(10, FP_arch),
11c1ff18 18088 LOOKUP(11, WMMX_arch),
f5f53991
AS
18089 LOOKUP(12, Advanced_SIMD_arch),
18090 LOOKUP(13, PCS_config),
11c1ff18
PB
18091 LOOKUP(14, ABI_PCS_R9_use),
18092 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 18093 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
18094 LOOKUP(17, ABI_PCS_GOT_use),
18095 LOOKUP(18, ABI_PCS_wchar_t),
18096 LOOKUP(19, ABI_FP_rounding),
18097 LOOKUP(20, ABI_FP_denormal),
18098 LOOKUP(21, ABI_FP_exceptions),
18099 LOOKUP(22, ABI_FP_user_exceptions),
18100 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
18101 {24, "ABI_align_needed", 0, NULL},
18102 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
18103 LOOKUP(26, ABI_enum_size),
18104 LOOKUP(27, ABI_HardFP_use),
18105 LOOKUP(28, ABI_VFP_args),
18106 LOOKUP(29, ABI_WMMX_args),
18107 LOOKUP(30, ABI_optimization_goals),
18108 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 18109 {32, "compatibility", 0, NULL},
f5f53991 18110 LOOKUP(34, CPU_unaligned_access),
75375b3e 18111 LOOKUP(36, FP_HP_extension),
8e79c3df 18112 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
18113 LOOKUP(42, MPextension_use),
18114 LOOKUP(44, DIV_use),
15afaa63 18115 LOOKUP(46, DSP_extension),
a7ad558c 18116 LOOKUP(48, MVE_arch),
99db83d0 18117 LOOKUP(50, PAC_extension),
4b535030 18118 LOOKUP(52, BTI_extension),
b81ee92f 18119 LOOKUP(74, BTI_use),
c9fed665 18120 LOOKUP(76, PACRET_use),
f5f53991
AS
18121 {64, "nodefaults", 0, NULL},
18122 {65, "also_compatible_with", 0, NULL},
18123 LOOKUP(66, T2EE_use),
18124 {67, "conformance", 1, NULL},
18125 LOOKUP(68, Virtualization_use),
cd21e546 18126 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
18127};
18128#undef LOOKUP
18129
11c1ff18 18130static unsigned char *
f6f0e17b
NC
18131display_arm_attribute (unsigned char * p,
18132 const unsigned char * const end)
11c1ff18 18133{
70e99720 18134 unsigned int tag;
70e99720 18135 unsigned int val;
2cf0635d 18136 arm_attr_public_tag * attr;
11c1ff18 18137 unsigned i;
70e99720 18138 unsigned int type;
11c1ff18 18139
cd30bcef 18140 READ_ULEB (tag, p, end);
11c1ff18 18141 attr = NULL;
2cf0635d 18142 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
18143 {
18144 if (arm_attr_public_tags[i].tag == tag)
18145 {
18146 attr = &arm_attr_public_tags[i];
18147 break;
18148 }
18149 }
18150
18151 if (attr)
18152 {
18153 printf (" Tag_%s: ", attr->name);
18154 switch (attr->type)
18155 {
18156 case 0:
18157 switch (tag)
18158 {
18159 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 18160 READ_ULEB (val, p, end);
11c1ff18
PB
18161 switch (val)
18162 {
2b692964
NC
18163 case 0: printf (_("None\n")); break;
18164 case 'A': printf (_("Application\n")); break;
18165 case 'R': printf (_("Realtime\n")); break;
18166 case 'M': printf (_("Microcontroller\n")); break;
18167 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
18168 default: printf ("??? (%d)\n", val); break;
18169 }
18170 break;
18171
75375b3e 18172 case 24: /* Tag_align_needed. */
cd30bcef 18173 READ_ULEB (val, p, end);
75375b3e
MGD
18174 switch (val)
18175 {
2b692964
NC
18176 case 0: printf (_("None\n")); break;
18177 case 1: printf (_("8-byte\n")); break;
18178 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
18179 case 3: printf ("??? 3\n"); break;
18180 default:
18181 if (val <= 12)
dd24e3da 18182 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
18183 1 << val);
18184 else
18185 printf ("??? (%d)\n", val);
18186 break;
18187 }
18188 break;
18189
18190 case 25: /* Tag_align_preserved. */
cd30bcef 18191 READ_ULEB (val, p, end);
75375b3e
MGD
18192 switch (val)
18193 {
2b692964
NC
18194 case 0: printf (_("None\n")); break;
18195 case 1: printf (_("8-byte, except leaf SP\n")); break;
18196 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
18197 case 3: printf ("??? 3\n"); break;
18198 default:
18199 if (val <= 12)
dd24e3da 18200 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
18201 1 << val);
18202 else
18203 printf ("??? (%d)\n", val);
18204 break;
18205 }
18206 break;
18207
11c1ff18 18208 case 32: /* Tag_compatibility. */
071436c6 18209 {
cd30bcef 18210 READ_ULEB (val, p, end);
071436c6 18211 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18212 if (p < end - 1)
18213 {
18214 size_t maxlen = (end - p) - 1;
18215
b6ac461a 18216 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18217 p += strnlen ((char *) p, maxlen) + 1;
18218 }
18219 else
18220 {
18221 printf (_("<corrupt>"));
18222 p = (unsigned char *) end;
18223 }
071436c6 18224 putchar ('\n');
071436c6 18225 }
11c1ff18
PB
18226 break;
18227
f5f53991 18228 case 64: /* Tag_nodefaults. */
541a3cbd
NC
18229 /* PR 17531: file: 001-505008-0.01. */
18230 if (p < end)
18231 p++;
2b692964 18232 printf (_("True\n"));
f5f53991
AS
18233 break;
18234
18235 case 65: /* Tag_also_compatible_with. */
cd30bcef 18236 READ_ULEB (val, p, end);
f5f53991
AS
18237 if (val == 6 /* Tag_CPU_arch. */)
18238 {
cd30bcef 18239 READ_ULEB (val, p, end);
071436c6 18240 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
18241 printf ("??? (%d)\n", val);
18242 else
18243 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
18244 }
18245 else
18246 printf ("???\n");
071436c6
NC
18247 while (p < end && *(p++) != '\0' /* NUL terminator. */)
18248 ;
f5f53991
AS
18249 break;
18250
11c1ff18 18251 default:
bee0ee85
NC
18252 printf (_("<unknown: %d>\n"), tag);
18253 break;
11c1ff18
PB
18254 }
18255 return p;
18256
18257 case 1:
f6f0e17b 18258 return display_tag_value (-1, p, end);
11c1ff18 18259 case 2:
f6f0e17b 18260 return display_tag_value (0, p, end);
11c1ff18
PB
18261
18262 default:
18263 assert (attr->type & 0x80);
cd30bcef 18264 READ_ULEB (val, p, end);
11c1ff18
PB
18265 type = attr->type & 0x7f;
18266 if (val >= type)
18267 printf ("??? (%d)\n", val);
18268 else
18269 printf ("%s\n", attr->table[val]);
18270 return p;
18271 }
18272 }
11c1ff18 18273
f6f0e17b 18274 return display_tag_value (tag, p, end);
11c1ff18
PB
18275}
18276
104d59d1 18277static unsigned char *
60bca95a 18278display_gnu_attribute (unsigned char * p,
8e8d0b63
NC
18279 unsigned char * (* display_proc_gnu_attribute)
18280 (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 18281 const unsigned char * const end)
104d59d1 18282{
cd30bcef 18283 unsigned int tag;
60abdbed 18284 unsigned int val;
104d59d1 18285
cd30bcef 18286 READ_ULEB (tag, p, end);
104d59d1
JM
18287
18288 /* Tag_compatibility is the only generic GNU attribute defined at
18289 present. */
18290 if (tag == 32)
18291 {
cd30bcef 18292 READ_ULEB (val, p, end);
071436c6
NC
18293
18294 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
18295 if (p == end)
18296 {
071436c6 18297 printf (_("<corrupt>\n"));
f6f0e17b
NC
18298 warn (_("corrupt vendor attribute\n"));
18299 }
18300 else
18301 {
4082ef84
NC
18302 if (p < end - 1)
18303 {
18304 size_t maxlen = (end - p) - 1;
071436c6 18305
b6ac461a 18306 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18307 p += strnlen ((char *) p, maxlen) + 1;
18308 }
18309 else
18310 {
18311 printf (_("<corrupt>"));
18312 p = (unsigned char *) end;
18313 }
071436c6 18314 putchar ('\n');
f6f0e17b 18315 }
104d59d1
JM
18316 return p;
18317 }
18318
18319 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 18320 return display_proc_gnu_attribute (p, tag, end);
104d59d1 18321
f6f0e17b 18322 return display_tag_value (tag, p, end);
104d59d1
JM
18323}
18324
85f7484a
PB
18325static unsigned char *
18326display_m68k_gnu_attribute (unsigned char * p,
18327 unsigned int tag,
18328 const unsigned char * const end)
18329{
18330 unsigned int val;
18331
18332 if (tag == Tag_GNU_M68K_ABI_FP)
18333 {
18334 printf (" Tag_GNU_M68K_ABI_FP: ");
18335 if (p == end)
18336 {
18337 printf (_("<corrupt>\n"));
18338 return p;
18339 }
18340 READ_ULEB (val, p, end);
18341
18342 if (val > 3)
18343 printf ("(%#x), ", val);
18344
18345 switch (val & 3)
18346 {
18347 case 0:
18348 printf (_("unspecified hard/soft float\n"));
18349 break;
18350 case 1:
18351 printf (_("hard float\n"));
18352 break;
18353 case 2:
18354 printf (_("soft float\n"));
18355 break;
18356 }
18357 return p;
18358 }
18359
18360 return display_tag_value (tag & 1, p, end);
18361}
18362
34c8bcba 18363static unsigned char *
f6f0e17b 18364display_power_gnu_attribute (unsigned char * p,
60abdbed 18365 unsigned int tag,
f6f0e17b 18366 const unsigned char * const end)
34c8bcba 18367{
005d79fd 18368 unsigned int val;
34c8bcba
JM
18369
18370 if (tag == Tag_GNU_Power_ABI_FP)
18371 {
34c8bcba 18372 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 18373 if (p == end)
005d79fd
AM
18374 {
18375 printf (_("<corrupt>\n"));
18376 return p;
18377 }
cd30bcef 18378 READ_ULEB (val, p, end);
60bca95a 18379
005d79fd
AM
18380 if (val > 15)
18381 printf ("(%#x), ", val);
18382
18383 switch (val & 3)
34c8bcba
JM
18384 {
18385 case 0:
005d79fd 18386 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
18387 break;
18388 case 1:
005d79fd 18389 printf (_("hard float, "));
34c8bcba
JM
18390 break;
18391 case 2:
005d79fd 18392 printf (_("soft float, "));
34c8bcba 18393 break;
3c7b9897 18394 case 3:
005d79fd 18395 printf (_("single-precision hard float, "));
3c7b9897 18396 break;
005d79fd
AM
18397 }
18398
18399 switch (val & 0xC)
18400 {
18401 case 0:
18402 printf (_("unspecified long double\n"));
18403 break;
18404 case 4:
18405 printf (_("128-bit IBM long double\n"));
18406 break;
18407 case 8:
18408 printf (_("64-bit long double\n"));
18409 break;
18410 case 12:
18411 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
18412 break;
18413 }
18414 return p;
005d79fd 18415 }
34c8bcba 18416
c6e65352
DJ
18417 if (tag == Tag_GNU_Power_ABI_Vector)
18418 {
c6e65352 18419 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 18420 if (p == end)
005d79fd
AM
18421 {
18422 printf (_("<corrupt>\n"));
18423 return p;
18424 }
cd30bcef 18425 READ_ULEB (val, p, end);
005d79fd
AM
18426
18427 if (val > 3)
18428 printf ("(%#x), ", val);
18429
18430 switch (val & 3)
c6e65352
DJ
18431 {
18432 case 0:
005d79fd 18433 printf (_("unspecified\n"));
c6e65352
DJ
18434 break;
18435 case 1:
005d79fd 18436 printf (_("generic\n"));
c6e65352
DJ
18437 break;
18438 case 2:
18439 printf ("AltiVec\n");
18440 break;
18441 case 3:
18442 printf ("SPE\n");
18443 break;
c6e65352
DJ
18444 }
18445 return p;
005d79fd 18446 }
c6e65352 18447
f82e0623
NF
18448 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18449 {
005d79fd 18450 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 18451 if (p == end)
f6f0e17b 18452 {
005d79fd 18453 printf (_("<corrupt>\n"));
f6f0e17b
NC
18454 return p;
18455 }
cd30bcef 18456 READ_ULEB (val, p, end);
0b4362b0 18457
005d79fd
AM
18458 if (val > 2)
18459 printf ("(%#x), ", val);
18460
18461 switch (val & 3)
18462 {
18463 case 0:
18464 printf (_("unspecified\n"));
18465 break;
18466 case 1:
18467 printf ("r3/r4\n");
18468 break;
18469 case 2:
18470 printf (_("memory\n"));
18471 break;
18472 case 3:
18473 printf ("???\n");
18474 break;
18475 }
f82e0623
NF
18476 return p;
18477 }
18478
f6f0e17b 18479 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
18480}
18481
643f7afb
AK
18482static unsigned char *
18483display_s390_gnu_attribute (unsigned char * p,
60abdbed 18484 unsigned int tag,
643f7afb
AK
18485 const unsigned char * const end)
18486{
cd30bcef 18487 unsigned int val;
643f7afb
AK
18488
18489 if (tag == Tag_GNU_S390_ABI_Vector)
18490 {
643f7afb 18491 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 18492 READ_ULEB (val, p, end);
643f7afb
AK
18493
18494 switch (val)
18495 {
18496 case 0:
18497 printf (_("any\n"));
18498 break;
18499 case 1:
18500 printf (_("software\n"));
18501 break;
18502 case 2:
18503 printf (_("hardware\n"));
18504 break;
18505 default:
18506 printf ("??? (%d)\n", val);
18507 break;
18508 }
18509 return p;
18510 }
18511
18512 return display_tag_value (tag & 1, p, end);
18513}
18514
9e8c70f9 18515static void
60abdbed 18516display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
18517{
18518 if (mask)
18519 {
015dc7e1 18520 bool first = true;
071436c6 18521
9e8c70f9 18522 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 18523 fputs ("mul32", stdout), first = false;
9e8c70f9 18524 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 18525 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 18526 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 18527 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 18528 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 18529 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 18530 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 18531 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 18532 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 18533 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 18534 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 18535 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 18536 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 18537 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 18538 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 18539 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 18540 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 18541 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 18542 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 18543 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 18544 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 18545 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 18546 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 18547 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 18548 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 18549 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 18550 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 18551 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 18552 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 18553 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
18554 }
18555 else
071436c6
NC
18556 fputc ('0', stdout);
18557 fputc ('\n', stdout);
9e8c70f9
DM
18558}
18559
3d68f91c 18560static void
60abdbed 18561display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
18562{
18563 if (mask)
18564 {
015dc7e1 18565 bool first = true;
071436c6 18566
3d68f91c 18567 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 18568 fputs ("fjathplus", stdout), first = false;
3d68f91c 18569 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 18570 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 18571 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 18572 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 18573 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 18574 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 18575 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 18576 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 18577 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 18578 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 18579 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 18580 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 18581 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 18582 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 18583 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 18584 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 18585 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 18586 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 18587 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 18588 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
18589 }
18590 else
071436c6
NC
18591 fputc ('0', stdout);
18592 fputc ('\n', stdout);
3d68f91c
JM
18593}
18594
9e8c70f9 18595static unsigned char *
f6f0e17b 18596display_sparc_gnu_attribute (unsigned char * p,
60abdbed 18597 unsigned int tag,
f6f0e17b 18598 const unsigned char * const end)
9e8c70f9 18599{
cd30bcef 18600 unsigned int val;
3d68f91c 18601
9e8c70f9
DM
18602 if (tag == Tag_GNU_Sparc_HWCAPS)
18603 {
cd30bcef 18604 READ_ULEB (val, p, end);
9e8c70f9 18605 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18606 display_sparc_hwcaps (val);
18607 return p;
3d68f91c
JM
18608 }
18609 if (tag == Tag_GNU_Sparc_HWCAPS2)
18610 {
cd30bcef 18611 READ_ULEB (val, p, end);
3d68f91c
JM
18612 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18613 display_sparc_hwcaps2 (val);
18614 return p;
18615 }
9e8c70f9 18616
f6f0e17b 18617 return display_tag_value (tag, p, end);
9e8c70f9
DM
18618}
18619
351cdf24 18620static void
32ec8896 18621print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18622{
18623 switch (val)
18624 {
18625 case Val_GNU_MIPS_ABI_FP_ANY:
18626 printf (_("Hard or soft float\n"));
18627 break;
18628 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18629 printf (_("Hard float (double precision)\n"));
18630 break;
18631 case Val_GNU_MIPS_ABI_FP_SINGLE:
18632 printf (_("Hard float (single precision)\n"));
18633 break;
18634 case Val_GNU_MIPS_ABI_FP_SOFT:
18635 printf (_("Soft float\n"));
18636 break;
18637 case Val_GNU_MIPS_ABI_FP_OLD_64:
18638 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18639 break;
18640 case Val_GNU_MIPS_ABI_FP_XX:
18641 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18642 break;
18643 case Val_GNU_MIPS_ABI_FP_64:
18644 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18645 break;
18646 case Val_GNU_MIPS_ABI_FP_64A:
18647 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18648 break;
3350cc01
CM
18649 case Val_GNU_MIPS_ABI_FP_NAN2008:
18650 printf (_("NaN 2008 compatibility\n"));
18651 break;
351cdf24
MF
18652 default:
18653 printf ("??? (%d)\n", val);
18654 break;
18655 }
18656}
18657
2cf19d5c 18658static unsigned char *
f6f0e17b 18659display_mips_gnu_attribute (unsigned char * p,
60abdbed 18660 unsigned int tag,
f6f0e17b 18661 const unsigned char * const end)
2cf19d5c 18662{
2cf19d5c
JM
18663 if (tag == Tag_GNU_MIPS_ABI_FP)
18664 {
32ec8896 18665 unsigned int val;
f6f0e17b 18666
2cf19d5c 18667 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18668 READ_ULEB (val, p, end);
351cdf24 18669 print_mips_fp_abi_value (val);
2cf19d5c
JM
18670 return p;
18671 }
18672
a9f58168
CF
18673 if (tag == Tag_GNU_MIPS_ABI_MSA)
18674 {
32ec8896 18675 unsigned int val;
a9f58168 18676
a9f58168 18677 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18678 READ_ULEB (val, p, end);
a9f58168
CF
18679
18680 switch (val)
18681 {
18682 case Val_GNU_MIPS_ABI_MSA_ANY:
18683 printf (_("Any MSA or not\n"));
18684 break;
18685 case Val_GNU_MIPS_ABI_MSA_128:
18686 printf (_("128-bit MSA\n"));
18687 break;
18688 default:
18689 printf ("??? (%d)\n", val);
18690 break;
18691 }
18692 return p;
18693 }
18694
f6f0e17b 18695 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18696}
18697
59e6276b 18698static unsigned char *
f6f0e17b
NC
18699display_tic6x_attribute (unsigned char * p,
18700 const unsigned char * const end)
59e6276b 18701{
60abdbed 18702 unsigned int tag;
cd30bcef 18703 unsigned int val;
59e6276b 18704
cd30bcef 18705 READ_ULEB (tag, p, end);
59e6276b
JM
18706
18707 switch (tag)
18708 {
75fa6dc1 18709 case Tag_ISA:
75fa6dc1 18710 printf (" Tag_ISA: ");
cd30bcef 18711 READ_ULEB (val, p, end);
59e6276b
JM
18712
18713 switch (val)
18714 {
75fa6dc1 18715 case C6XABI_Tag_ISA_none:
59e6276b
JM
18716 printf (_("None\n"));
18717 break;
75fa6dc1 18718 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18719 printf ("C62x\n");
18720 break;
75fa6dc1 18721 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18722 printf ("C67x\n");
18723 break;
75fa6dc1 18724 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18725 printf ("C67x+\n");
18726 break;
75fa6dc1 18727 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18728 printf ("C64x\n");
18729 break;
75fa6dc1 18730 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18731 printf ("C64x+\n");
18732 break;
75fa6dc1 18733 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18734 printf ("C674x\n");
18735 break;
18736 default:
18737 printf ("??? (%d)\n", val);
18738 break;
18739 }
18740 return p;
18741
87779176 18742 case Tag_ABI_wchar_t:
87779176 18743 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18744 READ_ULEB (val, p, end);
87779176
JM
18745 switch (val)
18746 {
18747 case 0:
18748 printf (_("Not used\n"));
18749 break;
18750 case 1:
18751 printf (_("2 bytes\n"));
18752 break;
18753 case 2:
18754 printf (_("4 bytes\n"));
18755 break;
18756 default:
18757 printf ("??? (%d)\n", val);
18758 break;
18759 }
18760 return p;
18761
18762 case Tag_ABI_stack_align_needed:
87779176 18763 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18764 READ_ULEB (val, p, end);
87779176
JM
18765 switch (val)
18766 {
18767 case 0:
18768 printf (_("8-byte\n"));
18769 break;
18770 case 1:
18771 printf (_("16-byte\n"));
18772 break;
18773 default:
18774 printf ("??? (%d)\n", val);
18775 break;
18776 }
18777 return p;
18778
18779 case Tag_ABI_stack_align_preserved:
cd30bcef 18780 READ_ULEB (val, p, end);
87779176
JM
18781 printf (" Tag_ABI_stack_align_preserved: ");
18782 switch (val)
18783 {
18784 case 0:
18785 printf (_("8-byte\n"));
18786 break;
18787 case 1:
18788 printf (_("16-byte\n"));
18789 break;
18790 default:
18791 printf ("??? (%d)\n", val);
18792 break;
18793 }
18794 return p;
18795
b5593623 18796 case Tag_ABI_DSBT:
cd30bcef 18797 READ_ULEB (val, p, end);
b5593623
JM
18798 printf (" Tag_ABI_DSBT: ");
18799 switch (val)
18800 {
18801 case 0:
18802 printf (_("DSBT addressing not used\n"));
18803 break;
18804 case 1:
18805 printf (_("DSBT addressing used\n"));
18806 break;
18807 default:
18808 printf ("??? (%d)\n", val);
18809 break;
18810 }
18811 return p;
18812
87779176 18813 case Tag_ABI_PID:
cd30bcef 18814 READ_ULEB (val, p, end);
87779176
JM
18815 printf (" Tag_ABI_PID: ");
18816 switch (val)
18817 {
18818 case 0:
18819 printf (_("Data addressing position-dependent\n"));
18820 break;
18821 case 1:
18822 printf (_("Data addressing position-independent, GOT near DP\n"));
18823 break;
18824 case 2:
18825 printf (_("Data addressing position-independent, GOT far from DP\n"));
18826 break;
18827 default:
18828 printf ("??? (%d)\n", val);
18829 break;
18830 }
18831 return p;
18832
18833 case Tag_ABI_PIC:
cd30bcef 18834 READ_ULEB (val, p, end);
87779176
JM
18835 printf (" Tag_ABI_PIC: ");
18836 switch (val)
18837 {
18838 case 0:
18839 printf (_("Code addressing position-dependent\n"));
18840 break;
18841 case 1:
18842 printf (_("Code addressing position-independent\n"));
18843 break;
18844 default:
18845 printf ("??? (%d)\n", val);
18846 break;
18847 }
18848 return p;
18849
18850 case Tag_ABI_array_object_alignment:
cd30bcef 18851 READ_ULEB (val, p, end);
87779176
JM
18852 printf (" Tag_ABI_array_object_alignment: ");
18853 switch (val)
18854 {
18855 case 0:
18856 printf (_("8-byte\n"));
18857 break;
18858 case 1:
18859 printf (_("4-byte\n"));
18860 break;
18861 case 2:
18862 printf (_("16-byte\n"));
18863 break;
18864 default:
18865 printf ("??? (%d)\n", val);
18866 break;
18867 }
18868 return p;
18869
18870 case Tag_ABI_array_object_align_expected:
cd30bcef 18871 READ_ULEB (val, p, end);
87779176
JM
18872 printf (" Tag_ABI_array_object_align_expected: ");
18873 switch (val)
18874 {
18875 case 0:
18876 printf (_("8-byte\n"));
18877 break;
18878 case 1:
18879 printf (_("4-byte\n"));
18880 break;
18881 case 2:
18882 printf (_("16-byte\n"));
18883 break;
18884 default:
18885 printf ("??? (%d)\n", val);
18886 break;
18887 }
18888 return p;
18889
3cbd1c06 18890 case Tag_ABI_compatibility:
071436c6 18891 {
cd30bcef 18892 READ_ULEB (val, p, end);
071436c6 18893 printf (" Tag_ABI_compatibility: ");
071436c6 18894 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18895 if (p < end - 1)
18896 {
18897 size_t maxlen = (end - p) - 1;
18898
b6ac461a 18899 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18900 p += strnlen ((char *) p, maxlen) + 1;
18901 }
18902 else
18903 {
18904 printf (_("<corrupt>"));
18905 p = (unsigned char *) end;
18906 }
071436c6 18907 putchar ('\n');
071436c6
NC
18908 return p;
18909 }
87779176
JM
18910
18911 case Tag_ABI_conformance:
071436c6 18912 {
4082ef84
NC
18913 printf (" Tag_ABI_conformance: \"");
18914 if (p < end - 1)
18915 {
18916 size_t maxlen = (end - p) - 1;
071436c6 18917
b6ac461a 18918 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18919 p += strnlen ((char *) p, maxlen) + 1;
18920 }
18921 else
18922 {
18923 printf (_("<corrupt>"));
18924 p = (unsigned char *) end;
18925 }
071436c6 18926 printf ("\"\n");
071436c6
NC
18927 return p;
18928 }
59e6276b
JM
18929 }
18930
f6f0e17b
NC
18931 return display_tag_value (tag, p, end);
18932}
59e6276b 18933
f6f0e17b 18934static void
60abdbed 18935display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18936{
26c527e6 18937 uint64_t addr = 0;
f6f0e17b
NC
18938 size_t bytes = end - p;
18939
feceaa59 18940 assert (end >= p);
f6f0e17b 18941 while (bytes)
87779176 18942 {
f6f0e17b
NC
18943 int j;
18944 int k;
18945 int lbytes = (bytes > 16 ? 16 : bytes);
18946
26c527e6 18947 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18948
18949 for (j = 0; j < 16; j++)
18950 {
18951 if (j < lbytes)
18952 printf ("%2.2x", p[j]);
18953 else
18954 printf (" ");
18955
18956 if ((j & 3) == 3)
18957 printf (" ");
18958 }
18959
18960 for (j = 0; j < lbytes; j++)
18961 {
18962 k = p[j];
18963 if (k >= ' ' && k < 0x7f)
18964 printf ("%c", k);
18965 else
18966 printf (".");
18967 }
18968
18969 putchar ('\n');
18970
18971 p += lbytes;
18972 bytes -= lbytes;
18973 addr += lbytes;
87779176 18974 }
59e6276b 18975
f6f0e17b 18976 putchar ('\n');
59e6276b
JM
18977}
18978
13761a11 18979static unsigned char *
b0191216 18980display_msp430_attribute (unsigned char * p,
26c527e6 18981 const unsigned char * const end)
13761a11 18982{
26c527e6
AM
18983 uint64_t val;
18984 uint64_t tag;
13761a11 18985
cd30bcef 18986 READ_ULEB (tag, p, end);
0b4362b0 18987
13761a11
NC
18988 switch (tag)
18989 {
18990 case OFBA_MSPABI_Tag_ISA:
13761a11 18991 printf (" Tag_ISA: ");
cd30bcef 18992 READ_ULEB (val, p, end);
13761a11
NC
18993 switch (val)
18994 {
18995 case 0: printf (_("None\n")); break;
18996 case 1: printf (_("MSP430\n")); break;
18997 case 2: printf (_("MSP430X\n")); break;
26c527e6 18998 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18999 }
19000 break;
19001
19002 case OFBA_MSPABI_Tag_Code_Model:
13761a11 19003 printf (" Tag_Code_Model: ");
cd30bcef 19004 READ_ULEB (val, p, end);
13761a11
NC
19005 switch (val)
19006 {
19007 case 0: printf (_("None\n")); break;
19008 case 1: printf (_("Small\n")); break;
19009 case 2: printf (_("Large\n")); break;
26c527e6 19010 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
19011 }
19012 break;
19013
19014 case OFBA_MSPABI_Tag_Data_Model:
13761a11 19015 printf (" Tag_Data_Model: ");
cd30bcef 19016 READ_ULEB (val, p, end);
13761a11
NC
19017 switch (val)
19018 {
19019 case 0: printf (_("None\n")); break;
19020 case 1: printf (_("Small\n")); break;
19021 case 2: printf (_("Large\n")); break;
19022 case 3: printf (_("Restricted Large\n")); break;
26c527e6 19023 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
19024 }
19025 break;
19026
19027 default:
26c527e6 19028 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
19029
19030 if (tag & 1)
19031 {
071436c6 19032 putchar ('"');
4082ef84
NC
19033 if (p < end - 1)
19034 {
19035 size_t maxlen = (end - p) - 1;
19036
b6ac461a 19037 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
19038 p += strnlen ((char *) p, maxlen) + 1;
19039 }
19040 else
19041 {
19042 printf (_("<corrupt>"));
19043 p = (unsigned char *) end;
19044 }
071436c6 19045 printf ("\"\n");
13761a11
NC
19046 }
19047 else
19048 {
cd30bcef 19049 READ_ULEB (val, p, end);
26c527e6 19050 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
19051 }
19052 break;
19053 }
19054
4082ef84 19055 assert (p <= end);
13761a11
NC
19056 return p;
19057}
19058
c0ea7c52
JL
19059static unsigned char *
19060display_msp430_gnu_attribute (unsigned char * p,
19061 unsigned int tag,
19062 const unsigned char * const end)
19063{
19064 if (tag == Tag_GNU_MSP430_Data_Region)
19065 {
26c527e6 19066 uint64_t val;
c0ea7c52 19067
c0ea7c52 19068 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 19069 READ_ULEB (val, p, end);
c0ea7c52
JL
19070
19071 switch (val)
19072 {
19073 case Val_GNU_MSP430_Data_Region_Any:
19074 printf (_("Any Region\n"));
19075 break;
19076 case Val_GNU_MSP430_Data_Region_Lower:
19077 printf (_("Lower Region Only\n"));
19078 break;
19079 default:
26c527e6 19080 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
19081 }
19082 return p;
19083 }
19084 return display_tag_value (tag & 1, p, end);
19085}
19086
2dc8dd17
JW
19087struct riscv_attr_tag_t {
19088 const char *name;
cd30bcef 19089 unsigned int tag;
2dc8dd17
JW
19090};
19091
19092static struct riscv_attr_tag_t riscv_attr_tag[] =
19093{
19094#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
19095 T(arch),
19096 T(priv_spec),
19097 T(priv_spec_minor),
19098 T(priv_spec_revision),
19099 T(unaligned_access),
19100 T(stack_align),
19101#undef T
19102};
19103
19104static unsigned char *
19105display_riscv_attribute (unsigned char *p,
19106 const unsigned char * const end)
19107{
26c527e6
AM
19108 uint64_t val;
19109 uint64_t tag;
2dc8dd17
JW
19110 struct riscv_attr_tag_t *attr = NULL;
19111 unsigned i;
19112
cd30bcef 19113 READ_ULEB (tag, p, end);
2dc8dd17
JW
19114
19115 /* Find the name of attribute. */
19116 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
19117 {
19118 if (riscv_attr_tag[i].tag == tag)
19119 {
19120 attr = &riscv_attr_tag[i];
19121 break;
19122 }
19123 }
19124
19125 if (attr)
19126 printf (" %s: ", attr->name);
19127 else
19128 return display_tag_value (tag, p, end);
19129
19130 switch (tag)
19131 {
19132 case Tag_RISCV_priv_spec:
19133 case Tag_RISCV_priv_spec_minor:
19134 case Tag_RISCV_priv_spec_revision:
cd30bcef 19135 READ_ULEB (val, p, end);
26c527e6 19136 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
19137 break;
19138 case Tag_RISCV_unaligned_access:
cd30bcef 19139 READ_ULEB (val, p, end);
2dc8dd17
JW
19140 switch (val)
19141 {
19142 case 0:
19143 printf (_("No unaligned access\n"));
19144 break;
19145 case 1:
19146 printf (_("Unaligned access\n"));
19147 break;
19148 }
19149 break;
19150 case Tag_RISCV_stack_align:
cd30bcef 19151 READ_ULEB (val, p, end);
26c527e6 19152 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
19153 break;
19154 case Tag_RISCV_arch:
19155 p = display_tag_value (-1, p, end);
19156 break;
19157 default:
19158 return display_tag_value (tag, p, end);
19159 }
19160
19161 return p;
19162}
19163
0861f561
CQ
19164static unsigned char *
19165display_csky_attribute (unsigned char * p,
19166 const unsigned char * const end)
19167{
26c527e6
AM
19168 uint64_t tag;
19169 uint64_t val;
0861f561
CQ
19170 READ_ULEB (tag, p, end);
19171
19172 if (tag >= Tag_CSKY_MAX)
19173 {
19174 return display_tag_value (-1, p, end);
19175 }
19176
19177 switch (tag)
19178 {
19179 case Tag_CSKY_ARCH_NAME:
19180 printf (" Tag_CSKY_ARCH_NAME:\t\t");
19181 return display_tag_value (-1, p, end);
19182 case Tag_CSKY_CPU_NAME:
19183 printf (" Tag_CSKY_CPU_NAME:\t\t");
19184 return display_tag_value (-1, p, end);
19185
19186 case Tag_CSKY_ISA_FLAGS:
19187 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
19188 return display_tag_value (0, p, end);
19189 case Tag_CSKY_ISA_EXT_FLAGS:
19190 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
19191 return display_tag_value (0, p, end);
19192
19193 case Tag_CSKY_DSP_VERSION:
19194 printf (" Tag_CSKY_DSP_VERSION:\t\t");
19195 READ_ULEB (val, p, end);
19196 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
19197 printf ("DSP Extension\n");
19198 else if (val == VAL_CSKY_DSP_VERSION_2)
19199 printf ("DSP 2.0\n");
19200 break;
19201
19202 case Tag_CSKY_VDSP_VERSION:
19203 printf (" Tag_CSKY_VDSP_VERSION:\t");
19204 READ_ULEB (val, p, end);
26c527e6 19205 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
19206 break;
19207
19208 case Tag_CSKY_FPU_VERSION:
19209 printf (" Tag_CSKY_FPU_VERSION:\t\t");
19210 READ_ULEB (val, p, end);
19211 if (val == VAL_CSKY_FPU_VERSION_1)
19212 printf ("ABIV1 FPU Version 1\n");
19213 else if (val == VAL_CSKY_FPU_VERSION_2)
19214 printf ("FPU Version 2\n");
19215 break;
19216
19217 case Tag_CSKY_FPU_ABI:
19218 printf (" Tag_CSKY_FPU_ABI:\t\t");
19219 READ_ULEB (val, p, end);
19220 if (val == VAL_CSKY_FPU_ABI_HARD)
19221 printf ("Hard\n");
19222 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
19223 printf ("SoftFP\n");
19224 else if (val == VAL_CSKY_FPU_ABI_SOFT)
19225 printf ("Soft\n");
19226 break;
19227 case Tag_CSKY_FPU_ROUNDING:
19228 READ_ULEB (val, p, end);
f253158f
NC
19229 if (val == 1)
19230 {
19231 printf (" Tag_CSKY_FPU_ROUNDING:\t");
19232 printf ("Needed\n");
19233 }
0861f561
CQ
19234 break;
19235 case Tag_CSKY_FPU_DENORMAL:
19236 READ_ULEB (val, p, end);
f253158f
NC
19237 if (val == 1)
19238 {
19239 printf (" Tag_CSKY_FPU_DENORMAL:\t");
19240 printf ("Needed\n");
19241 }
0861f561
CQ
19242 break;
19243 case Tag_CSKY_FPU_Exception:
19244 READ_ULEB (val, p, end);
f253158f
NC
19245 if (val == 1)
19246 {
19247 printf (" Tag_CSKY_FPU_Exception:\t");
19248 printf ("Needed\n");
19249 }
0861f561
CQ
19250 break;
19251 case Tag_CSKY_FPU_NUMBER_MODULE:
19252 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
19253 return display_tag_value (-1, p, end);
19254 case Tag_CSKY_FPU_HARDFP:
19255 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
19256 READ_ULEB (val, p, end);
19257 if (val & VAL_CSKY_FPU_HARDFP_HALF)
19258 printf (" Half");
19259 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
19260 printf (" Single");
19261 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
19262 printf (" Double");
19263 printf ("\n");
19264 break;
19265 default:
19266 return display_tag_value (tag, p, end);
19267 }
19268 return p;
19269}
19270
015dc7e1 19271static bool
dda8d76d 19272process_attributes (Filedata * filedata,
60bca95a 19273 const char * public_name,
104d59d1 19274 unsigned int proc_type,
f6f0e17b 19275 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 19276 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 19277{
11c1ff18 19278 /* Find the section header so that we get the size. */
3f8f3801
ML
19279 Elf_Internal_Shdr * sect = find_section_by_type (filedata, proc_type);
19280 if (sect == NULL)
19281 sect = find_section_by_type (filedata, SHT_GNU_ATTRIBUTES);
19282
19283 if (sect == NULL)
19284 /* No section, exit without error. */
19285 return true;
19286
19287 unsigned char * contents = (unsigned char *)
19288 get_data (NULL, filedata, sect->sh_offset, 1, sect->sh_size, _("attributes"));
19289 if (contents == NULL)
19290 return false;
19291
19292 bool res = true;
19293 unsigned char * p = contents;
19294 /* The first character is the version of the attributes.
19295 Currently only version 1, (aka 'A') is recognised here. */
19296 if (*p != 'A')
11c1ff18 19297 {
3f8f3801
ML
19298 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
19299 res = false;
19300 goto free_data;
19301 }
071436c6 19302
3f8f3801
ML
19303 uint64_t section_len = sect->sh_size - 1;
19304 p++;
19305
19306 while (section_len > 0)
19307 {
19308 uint64_t attr_len;
19309 unsigned int namelen;
19310 bool public_section;
19311 bool gnu_section;
11c1ff18 19312
3f8f3801 19313 if (section_len <= 4)
32ec8896 19314 {
3f8f3801 19315 error (_("Tag section ends prematurely\n"));
015dc7e1 19316 res = false;
3f8f3801 19317 break;
32ec8896 19318 }
3f8f3801
ML
19319 attr_len = byte_get (p, 4);
19320 p += 4;
60bca95a 19321
3f8f3801 19322 if (attr_len > section_len)
32ec8896 19323 {
3f8f3801
ML
19324 error (_("Bad attribute length (%u > %u)\n"),
19325 (unsigned) attr_len, (unsigned) section_len);
19326 attr_len = section_len;
015dc7e1 19327 res = false;
32ec8896 19328 }
3f8f3801
ML
19329 /* PR 17531: file: 001-101425-0.004 */
19330 else if (attr_len < 5)
11c1ff18 19331 {
3f8f3801
ML
19332 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
19333 res = false;
19334 break;
19335 }
071436c6 19336
3f8f3801
ML
19337 section_len -= attr_len;
19338 attr_len -= 4;
60bca95a 19339
3f8f3801
ML
19340 namelen = strnlen ((char *) p, attr_len) + 1;
19341 if (namelen == 0 || namelen >= attr_len)
19342 {
19343 error (_("Corrupt attribute section name\n"));
19344 res = false;
19345 break;
19346 }
11c1ff18 19347
3f8f3801
ML
19348 printf (_("Attribute Section: "));
19349 print_symbol_name (INT_MAX, (const char *) p);
19350 putchar ('\n');
60bca95a 19351
3f8f3801
ML
19352 if (public_name && streq ((char *) p, public_name))
19353 public_section = true;
19354 else
19355 public_section = false;
e9847026 19356
3f8f3801
ML
19357 if (streq ((char *) p, "gnu"))
19358 gnu_section = true;
19359 else
19360 gnu_section = false;
071436c6 19361
3f8f3801
ML
19362 p += namelen;
19363 attr_len -= namelen;
e9847026 19364
3f8f3801
ML
19365 while (attr_len > 0 && p < contents + sect->sh_size)
19366 {
19367 int tag;
19368 unsigned int val;
19369 uint64_t size;
19370 unsigned char * end;
60bca95a 19371
3f8f3801
ML
19372 /* PR binutils/17531: Safe handling of corrupt files. */
19373 if (attr_len < 6)
19374 {
19375 error (_("Unused bytes at end of section\n"));
19376 res = false;
19377 section_len = 0;
19378 break;
19379 }
60bca95a 19380
3f8f3801
ML
19381 tag = *(p++);
19382 size = byte_get (p, 4);
19383 if (size > attr_len)
19384 {
19385 error (_("Bad subsection length (%u > %u)\n"),
19386 (unsigned) size, (unsigned) attr_len);
19387 res = false;
19388 size = attr_len;
19389 }
19390 /* PR binutils/17531: Safe handling of corrupt files. */
19391 if (size < 6)
19392 {
19393 error (_("Bad subsection length (%u < 6)\n"),
19394 (unsigned) size);
19395 res = false;
19396 section_len = 0;
19397 break;
19398 }
60bca95a 19399
3f8f3801
ML
19400 attr_len -= size;
19401 end = p + size - 1;
19402 assert (end <= contents + sect->sh_size);
19403 p += 4;
e0a31db1 19404
3f8f3801
ML
19405 switch (tag)
19406 {
19407 case 1:
19408 printf (_("File Attributes\n"));
19409 break;
19410 case 2:
19411 printf (_("Section Attributes:"));
19412 goto do_numlist;
19413 case 3:
19414 printf (_("Symbol Attributes:"));
19415 /* Fall through. */
19416 do_numlist:
19417 for (;;)
11c1ff18 19418 {
3f8f3801
ML
19419 READ_ULEB (val, p, end);
19420 if (val == 0)
19421 break;
19422 printf (" %d", val);
11c1ff18 19423 }
3f8f3801
ML
19424 printf ("\n");
19425 break;
19426 default:
19427 printf (_("Unknown tag: %d\n"), tag);
19428 public_section = false;
19429 break;
11c1ff18 19430 }
d70c5fc7 19431
3f8f3801
ML
19432 if (public_section && display_pub_attribute != NULL)
19433 {
19434 while (p < end)
19435 p = display_pub_attribute (p, end);
19436 assert (p == end);
19437 }
19438 else if (gnu_section && display_proc_gnu_attribute != NULL)
19439 {
19440 while (p < end)
19441 p = display_gnu_attribute (p,
19442 display_proc_gnu_attribute,
19443 end);
19444 assert (p == end);
19445 }
19446 else if (p < end)
19447 {
19448 printf (_(" Unknown attribute:\n"));
19449 display_raw_attribute (p, end);
19450 p = end;
19451 }
19452 else
19453 attr_len = 0;
19454 }
11c1ff18 19455 }
32ec8896 19456
3f8f3801
ML
19457free_data:
19458 free (contents);
19459
32ec8896 19460 return res;
11c1ff18
PB
19461}
19462
ccb4c951
RS
19463/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19464 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
19465 and return the VMA of the next entry, or -1 if there was a problem.
19466 Does not read from DATA_END or beyond. */
ccb4c951 19467
625d49fc
AM
19468static uint64_t
19469print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 19470 unsigned char * data_end)
ccb4c951
RS
19471{
19472 printf (" ");
19473 print_vma (addr, LONG_HEX);
19474 printf (" ");
19475 if (addr < pltgot + 0xfff0)
19476 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19477 else
19478 printf ("%10s", "");
19479 printf (" ");
19480 if (data == NULL)
2b692964 19481 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
19482 else
19483 {
625d49fc 19484 uint64_t entry;
82b1b41b 19485 unsigned char * from = data + addr - pltgot;
ccb4c951 19486
82b1b41b
NC
19487 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19488 {
19489 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19490 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 19491 return (uint64_t) -1;
82b1b41b
NC
19492 }
19493 else
19494 {
19495 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19496 print_vma (entry, LONG_HEX);
19497 }
ccb4c951
RS
19498 }
19499 return addr + (is_32bit_elf ? 4 : 8);
19500}
19501
861fb55a
DJ
19502/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19503 PLTGOT. Print the Address and Initial fields of an entry at VMA
19504 ADDR and return the VMA of the next entry. */
19505
625d49fc
AM
19506static uint64_t
19507print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
19508{
19509 printf (" ");
19510 print_vma (addr, LONG_HEX);
19511 printf (" ");
19512 if (data == NULL)
2b692964 19513 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
19514 else
19515 {
625d49fc 19516 uint64_t entry;
861fb55a
DJ
19517
19518 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19519 print_vma (entry, LONG_HEX);
19520 }
19521 return addr + (is_32bit_elf ? 4 : 8);
19522}
19523
351cdf24
MF
19524static void
19525print_mips_ases (unsigned int mask)
19526{
19527 if (mask & AFL_ASE_DSP)
19528 fputs ("\n\tDSP ASE", stdout);
19529 if (mask & AFL_ASE_DSPR2)
19530 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
19531 if (mask & AFL_ASE_DSPR3)
19532 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
19533 if (mask & AFL_ASE_EVA)
19534 fputs ("\n\tEnhanced VA Scheme", stdout);
19535 if (mask & AFL_ASE_MCU)
19536 fputs ("\n\tMCU (MicroController) ASE", stdout);
19537 if (mask & AFL_ASE_MDMX)
19538 fputs ("\n\tMDMX ASE", stdout);
19539 if (mask & AFL_ASE_MIPS3D)
19540 fputs ("\n\tMIPS-3D ASE", stdout);
19541 if (mask & AFL_ASE_MT)
19542 fputs ("\n\tMT ASE", stdout);
19543 if (mask & AFL_ASE_SMARTMIPS)
19544 fputs ("\n\tSmartMIPS ASE", stdout);
19545 if (mask & AFL_ASE_VIRT)
19546 fputs ("\n\tVZ ASE", stdout);
19547 if (mask & AFL_ASE_MSA)
19548 fputs ("\n\tMSA ASE", stdout);
19549 if (mask & AFL_ASE_MIPS16)
19550 fputs ("\n\tMIPS16 ASE", stdout);
19551 if (mask & AFL_ASE_MICROMIPS)
19552 fputs ("\n\tMICROMIPS ASE", stdout);
19553 if (mask & AFL_ASE_XPA)
19554 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
19555 if (mask & AFL_ASE_MIPS16E2)
19556 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
19557 if (mask & AFL_ASE_CRC)
19558 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
19559 if (mask & AFL_ASE_GINV)
19560 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
19561 if (mask & AFL_ASE_LOONGSON_MMI)
19562 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
19563 if (mask & AFL_ASE_LOONGSON_CAM)
19564 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
19565 if (mask & AFL_ASE_LOONGSON_EXT)
19566 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
19567 if (mask & AFL_ASE_LOONGSON_EXT2)
19568 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
19569 if (mask == 0)
19570 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
19571 else if ((mask & ~AFL_ASE_MASK) != 0)
19572 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
19573}
19574
19575static void
19576print_mips_isa_ext (unsigned int isa_ext)
19577{
19578 switch (isa_ext)
19579 {
19580 case 0:
19581 fputs (_("None"), stdout);
19582 break;
19583 case AFL_EXT_XLR:
19584 fputs ("RMI XLR", stdout);
19585 break;
2c629856
N
19586 case AFL_EXT_OCTEON3:
19587 fputs ("Cavium Networks Octeon3", stdout);
19588 break;
351cdf24
MF
19589 case AFL_EXT_OCTEON2:
19590 fputs ("Cavium Networks Octeon2", stdout);
19591 break;
19592 case AFL_EXT_OCTEONP:
19593 fputs ("Cavium Networks OcteonP", stdout);
19594 break;
351cdf24
MF
19595 case AFL_EXT_OCTEON:
19596 fputs ("Cavium Networks Octeon", stdout);
19597 break;
19598 case AFL_EXT_5900:
19599 fputs ("Toshiba R5900", stdout);
19600 break;
19601 case AFL_EXT_4650:
19602 fputs ("MIPS R4650", stdout);
19603 break;
19604 case AFL_EXT_4010:
19605 fputs ("LSI R4010", stdout);
19606 break;
19607 case AFL_EXT_4100:
19608 fputs ("NEC VR4100", stdout);
19609 break;
19610 case AFL_EXT_3900:
19611 fputs ("Toshiba R3900", stdout);
19612 break;
19613 case AFL_EXT_10000:
19614 fputs ("MIPS R10000", stdout);
19615 break;
19616 case AFL_EXT_SB1:
19617 fputs ("Broadcom SB-1", stdout);
19618 break;
19619 case AFL_EXT_4111:
19620 fputs ("NEC VR4111/VR4181", stdout);
19621 break;
19622 case AFL_EXT_4120:
19623 fputs ("NEC VR4120", stdout);
19624 break;
19625 case AFL_EXT_5400:
19626 fputs ("NEC VR5400", stdout);
19627 break;
19628 case AFL_EXT_5500:
19629 fputs ("NEC VR5500", stdout);
19630 break;
19631 case AFL_EXT_LOONGSON_2E:
19632 fputs ("ST Microelectronics Loongson 2E", stdout);
19633 break;
19634 case AFL_EXT_LOONGSON_2F:
19635 fputs ("ST Microelectronics Loongson 2F", stdout);
19636 break;
38bf472a
MR
19637 case AFL_EXT_INTERAPTIV_MR2:
19638 fputs ("Imagination interAptiv MR2", stdout);
19639 break;
351cdf24 19640 default:
00ac7aa0 19641 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19642 }
19643}
19644
32ec8896 19645static signed int
351cdf24
MF
19646get_mips_reg_size (int reg_size)
19647{
19648 return (reg_size == AFL_REG_NONE) ? 0
19649 : (reg_size == AFL_REG_32) ? 32
19650 : (reg_size == AFL_REG_64) ? 64
19651 : (reg_size == AFL_REG_128) ? 128
19652 : -1;
19653}
19654
015dc7e1 19655static bool
dda8d76d 19656process_mips_specific (Filedata * filedata)
5b18a4bc 19657{
2cf0635d 19658 Elf_Internal_Dyn * entry;
351cdf24 19659 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19660 size_t liblist_offset = 0;
19661 size_t liblistno = 0;
19662 size_t conflictsno = 0;
19663 size_t options_offset = 0;
19664 size_t conflicts_offset = 0;
861fb55a
DJ
19665 size_t pltrelsz = 0;
19666 size_t pltrel = 0;
625d49fc
AM
19667 uint64_t pltgot = 0;
19668 uint64_t mips_pltgot = 0;
19669 uint64_t jmprel = 0;
19670 uint64_t local_gotno = 0;
19671 uint64_t gotsym = 0;
19672 uint64_t symtabno = 0;
015dc7e1 19673 bool res = true;
103f02d3 19674
dda8d76d 19675 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19676 display_mips_gnu_attribute))
015dc7e1 19677 res = false;
2cf19d5c 19678
dda8d76d 19679 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19680
19681 if (sect != NULL)
19682 {
19683 Elf_External_ABIFlags_v0 *abiflags_ext;
19684 Elf_Internal_ABIFlags_v0 abiflags_in;
19685
19686 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19687 {
19688 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19689 res = false;
32ec8896 19690 }
351cdf24
MF
19691 else
19692 {
dda8d76d 19693 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19694 sect->sh_size, _("MIPS ABI Flags section"));
19695 if (abiflags_ext)
19696 {
19697 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19698 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19699 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19700 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19701 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19702 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19703 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19704 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19705 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19706 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19707 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19708
19709 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19710 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19711 if (abiflags_in.isa_rev > 1)
19712 printf ("r%d", abiflags_in.isa_rev);
19713 printf ("\nGPR size: %d",
19714 get_mips_reg_size (abiflags_in.gpr_size));
19715 printf ("\nCPR1 size: %d",
19716 get_mips_reg_size (abiflags_in.cpr1_size));
19717 printf ("\nCPR2 size: %d",
19718 get_mips_reg_size (abiflags_in.cpr2_size));
19719 fputs ("\nFP ABI: ", stdout);
19720 print_mips_fp_abi_value (abiflags_in.fp_abi);
19721 fputs ("ISA Extension: ", stdout);
19722 print_mips_isa_ext (abiflags_in.isa_ext);
19723 fputs ("\nASEs:", stdout);
19724 print_mips_ases (abiflags_in.ases);
19725 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19726 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19727 fputc ('\n', stdout);
19728 free (abiflags_ext);
19729 }
19730 }
19731 }
19732
19e6b90e 19733 /* We have a lot of special sections. Thanks SGI! */
978c4450 19734 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19735 {
19736 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19737 sect = find_section (filedata, ".got");
bbdd9a68
MR
19738 if (sect != NULL)
19739 {
19740 unsigned char *data_end;
19741 unsigned char *data;
625d49fc 19742 uint64_t ent, end;
bbdd9a68
MR
19743 int addr_size;
19744
19745 pltgot = sect->sh_addr;
19746
19747 ent = pltgot;
19748 addr_size = (is_32bit_elf ? 4 : 8);
19749 end = pltgot + sect->sh_size;
19750
dda8d76d 19751 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19752 end - pltgot, 1,
19753 _("Global Offset Table data"));
19754 /* PR 12855: Null data is handled gracefully throughout. */
19755 data_end = data + (end - pltgot);
19756
19757 printf (_("\nStatic GOT:\n"));
19758 printf (_(" Canonical gp value: "));
19759 print_vma (ent + 0x7ff0, LONG_HEX);
19760 printf ("\n\n");
19761
19762 /* In a dynamic binary GOT[0] is reserved for the dynamic
19763 loader to store the lazy resolver pointer, however in
19764 a static binary it may well have been omitted and GOT
19765 reduced to a table of addresses.
19766 PR 21344: Check for the entry being fully available
19767 before fetching it. */
19768 if (data
19769 && data + ent - pltgot + addr_size <= data_end
19770 && byte_get (data + ent - pltgot, addr_size) == 0)
19771 {
19772 printf (_(" Reserved entries:\n"));
19773 printf (_(" %*s %10s %*s\n"),
19774 addr_size * 2, _("Address"), _("Access"),
19775 addr_size * 2, _("Value"));
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 /* Check for the MSB of GOT[1] being set, identifying a
19782 GNU object. This entry will be used by some runtime
19783 loaders, to store the module pointer. Otherwise this
19784 is an ordinary local entry.
19785 PR 21344: Check for the entry being fully available
19786 before fetching it. */
19787 if (data
19788 && data + ent - pltgot + addr_size <= data_end
19789 && (byte_get (data + ent - pltgot, addr_size)
19790 >> (addr_size * 8 - 1)) != 0)
19791 {
19792 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19793 printf ("\n");
625d49fc 19794 if (ent == (uint64_t) -1)
bbdd9a68
MR
19795 goto sgot_print_fail;
19796 }
19797 printf ("\n");
19798 }
19799
f17e9d8a 19800 if (data != NULL && ent < end)
bbdd9a68
MR
19801 {
19802 printf (_(" Local entries:\n"));
19803 printf (" %*s %10s %*s\n",
19804 addr_size * 2, _("Address"), _("Access"),
19805 addr_size * 2, _("Value"));
19806 while (ent < end)
19807 {
19808 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19809 printf ("\n");
625d49fc 19810 if (ent == (uint64_t) -1)
bbdd9a68
MR
19811 goto sgot_print_fail;
19812 }
19813 printf ("\n");
19814 }
19815
19816 sgot_print_fail:
9db70fc3 19817 free (data);
bbdd9a68
MR
19818 }
19819 return res;
19820 }
252b5132 19821
978c4450 19822 for (entry = filedata->dynamic_section;
071436c6 19823 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19824 (entry < filedata->dynamic_section + filedata->dynamic_nent
19825 && entry->d_tag != DT_NULL);
071436c6 19826 ++entry)
252b5132
RH
19827 switch (entry->d_tag)
19828 {
19829 case DT_MIPS_LIBLIST:
d93f0186 19830 liblist_offset
dda8d76d 19831 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19832 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19833 break;
19834 case DT_MIPS_LIBLISTNO:
19835 liblistno = entry->d_un.d_val;
19836 break;
19837 case DT_MIPS_OPTIONS:
dda8d76d 19838 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19839 break;
19840 case DT_MIPS_CONFLICT:
d93f0186 19841 conflicts_offset
dda8d76d 19842 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19843 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19844 break;
19845 case DT_MIPS_CONFLICTNO:
19846 conflictsno = entry->d_un.d_val;
19847 break;
ccb4c951 19848 case DT_PLTGOT:
861fb55a
DJ
19849 pltgot = entry->d_un.d_ptr;
19850 break;
ccb4c951
RS
19851 case DT_MIPS_LOCAL_GOTNO:
19852 local_gotno = entry->d_un.d_val;
19853 break;
19854 case DT_MIPS_GOTSYM:
19855 gotsym = entry->d_un.d_val;
19856 break;
19857 case DT_MIPS_SYMTABNO:
19858 symtabno = entry->d_un.d_val;
19859 break;
861fb55a
DJ
19860 case DT_MIPS_PLTGOT:
19861 mips_pltgot = entry->d_un.d_ptr;
19862 break;
19863 case DT_PLTREL:
19864 pltrel = entry->d_un.d_val;
19865 break;
19866 case DT_PLTRELSZ:
19867 pltrelsz = entry->d_un.d_val;
19868 break;
19869 case DT_JMPREL:
19870 jmprel = entry->d_un.d_ptr;
19871 break;
252b5132
RH
19872 default:
19873 break;
19874 }
19875
19876 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19877 {
2cf0635d 19878 Elf32_External_Lib * elib;
252b5132
RH
19879 size_t cnt;
19880
dda8d76d 19881 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19882 sizeof (Elf32_External_Lib),
19883 liblistno,
19884 _("liblist section data"));
a6e9f9df 19885 if (elib)
252b5132 19886 {
26c527e6
AM
19887 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19888 "\nSection '.liblist' contains %zu entries:\n",
19889 liblistno),
19890 liblistno);
2b692964 19891 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19892 stdout);
19893
19894 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19895 {
a6e9f9df 19896 Elf32_Lib liblist;
91d6fa6a 19897 time_t atime;
d5b07ef4 19898 char timebuf[128];
2cf0635d 19899 struct tm * tmp;
a6e9f9df
AM
19900
19901 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19902 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19903 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19904 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19905 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19906
91d6fa6a 19907 tmp = gmtime (&atime);
e9e44622
JJ
19908 snprintf (timebuf, sizeof (timebuf),
19909 "%04u-%02u-%02uT%02u:%02u:%02u",
19910 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19911 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19912
26c527e6 19913 printf ("%3zu: ", cnt);
84714f86 19914 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19915 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19916 else
2b692964 19917 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19918 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19919 liblist.l_version);
a6e9f9df
AM
19920
19921 if (liblist.l_flags == 0)
2b692964 19922 puts (_(" NONE"));
a6e9f9df
AM
19923 else
19924 {
19925 static const struct
252b5132 19926 {
2cf0635d 19927 const char * name;
a6e9f9df 19928 int bit;
252b5132 19929 }
a6e9f9df
AM
19930 l_flags_vals[] =
19931 {
19932 { " EXACT_MATCH", LL_EXACT_MATCH },
19933 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19934 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19935 { " EXPORTS", LL_EXPORTS },
19936 { " DELAY_LOAD", LL_DELAY_LOAD },
19937 { " DELTA", LL_DELTA }
19938 };
19939 int flags = liblist.l_flags;
19940 size_t fcnt;
19941
60bca95a 19942 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19943 if ((flags & l_flags_vals[fcnt].bit) != 0)
19944 {
19945 fputs (l_flags_vals[fcnt].name, stdout);
19946 flags ^= l_flags_vals[fcnt].bit;
19947 }
19948 if (flags != 0)
19949 printf (" %#x", (unsigned int) flags);
252b5132 19950
a6e9f9df
AM
19951 puts ("");
19952 }
252b5132 19953 }
252b5132 19954
a6e9f9df
AM
19955 free (elib);
19956 }
32ec8896 19957 else
015dc7e1 19958 res = false;
252b5132
RH
19959 }
19960
19961 if (options_offset != 0)
19962 {
2cf0635d 19963 Elf_External_Options * eopt;
252b5132
RH
19964 size_t offset;
19965 int cnt;
19966
19967 /* Find the section header so that we get the size. */
dda8d76d 19968 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19969 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19970 if (sect == NULL)
19971 {
19972 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19973 return false;
071436c6 19974 }
7fc0c668
NC
19975 /* PR 24243 */
19976 if (sect->sh_size < sizeof (* eopt))
19977 {
19978 error (_("The MIPS options section is too small.\n"));
015dc7e1 19979 return false;
7fc0c668 19980 }
252b5132 19981
dda8d76d 19982 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19983 sect->sh_size, _("options"));
a6e9f9df 19984 if (eopt)
252b5132 19985 {
fd17d1e6 19986 Elf_Internal_Options option;
76da6bbe 19987
a6e9f9df 19988 offset = cnt = 0;
82b1b41b 19989 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19990 {
2cf0635d 19991 Elf_External_Options * eoption;
fd17d1e6 19992 unsigned int optsize;
252b5132 19993
a6e9f9df 19994 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19995
fd17d1e6 19996 optsize = BYTE_GET (eoption->size);
76da6bbe 19997
82b1b41b 19998 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19999 if (optsize < sizeof (* eopt)
20000 || optsize > sect->sh_size - offset)
82b1b41b 20001 {
645f43a8 20002 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 20003 optsize);
645f43a8 20004 free (eopt);
015dc7e1 20005 return false;
82b1b41b 20006 }
fd17d1e6 20007 offset += optsize;
a6e9f9df
AM
20008 ++cnt;
20009 }
252b5132 20010
d3a49aa8
AM
20011 printf (ngettext ("\nSection '%s' contains %d entry:\n",
20012 "\nSection '%s' contains %d entries:\n",
20013 cnt),
dda8d76d 20014 printable_section_name (filedata, sect), cnt);
76da6bbe 20015
82b1b41b 20016 offset = 0;
a6e9f9df 20017 while (cnt-- > 0)
252b5132 20018 {
a6e9f9df 20019 size_t len;
fd17d1e6
AM
20020 Elf_External_Options * eoption;
20021
20022 eoption = (Elf_External_Options *) ((char *) eopt + offset);
20023
20024 option.kind = BYTE_GET (eoption->kind);
20025 option.size = BYTE_GET (eoption->size);
20026 option.section = BYTE_GET (eoption->section);
20027 option.info = BYTE_GET (eoption->info);
a6e9f9df 20028
fd17d1e6 20029 switch (option.kind)
252b5132 20030 {
a6e9f9df
AM
20031 case ODK_NULL:
20032 /* This shouldn't happen. */
d0c4e780 20033 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 20034 option.section, option.info);
a6e9f9df 20035 break;
2e6be59c 20036
a6e9f9df
AM
20037 case ODK_REGINFO:
20038 printf (" REGINFO ");
dda8d76d 20039 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 20040 {
2cf0635d 20041 Elf32_External_RegInfo * ereg;
b34976b6 20042 Elf32_RegInfo reginfo;
a6e9f9df 20043
2e6be59c 20044 /* 32bit form. */
fd17d1e6
AM
20045 if (option.size < (sizeof (Elf_External_Options)
20046 + sizeof (Elf32_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 = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 20055
a6e9f9df
AM
20056 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20057 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20058 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20059 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20060 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20061 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20062
d0c4e780
AM
20063 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
20064 reginfo.ri_gprmask, reginfo.ri_gp_value);
20065 printf (" "
20066 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20067 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
20068 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20069 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20070 }
20071 else
20072 {
20073 /* 64 bit form. */
2cf0635d 20074 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
20075 Elf64_Internal_RegInfo reginfo;
20076
fd17d1e6
AM
20077 if (option.size < (sizeof (Elf_External_Options)
20078 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
20079 {
20080 printf (_("<corrupt>\n"));
20081 error (_("Truncated MIPS REGINFO option\n"));
20082 cnt = 0;
20083 break;
20084 }
20085
fd17d1e6 20086 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
20087 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20088 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20089 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20090 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20091 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 20092 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 20093
d0c4e780
AM
20094 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
20095 reginfo.ri_gprmask, reginfo.ri_gp_value);
20096 printf (" "
20097 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20098 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
20099 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20100 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20101 }
fd17d1e6 20102 offset += option.size;
a6e9f9df 20103 continue;
2e6be59c 20104
a6e9f9df
AM
20105 case ODK_EXCEPTIONS:
20106 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 20107 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 20108 fputs (") fpe_max(", stdout);
fd17d1e6 20109 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
20110 fputs (")", stdout);
20111
fd17d1e6 20112 if (option.info & OEX_PAGE0)
a6e9f9df 20113 fputs (" PAGE0", stdout);
fd17d1e6 20114 if (option.info & OEX_SMM)
a6e9f9df 20115 fputs (" SMM", stdout);
fd17d1e6 20116 if (option.info & OEX_FPDBUG)
a6e9f9df 20117 fputs (" FPDBUG", stdout);
fd17d1e6 20118 if (option.info & OEX_DISMISS)
a6e9f9df
AM
20119 fputs (" DISMISS", stdout);
20120 break;
2e6be59c 20121
a6e9f9df
AM
20122 case ODK_PAD:
20123 fputs (" PAD ", stdout);
fd17d1e6 20124 if (option.info & OPAD_PREFIX)
a6e9f9df 20125 fputs (" PREFIX", stdout);
fd17d1e6 20126 if (option.info & OPAD_POSTFIX)
a6e9f9df 20127 fputs (" POSTFIX", stdout);
fd17d1e6 20128 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
20129 fputs (" SYMBOL", stdout);
20130 break;
2e6be59c 20131
a6e9f9df
AM
20132 case ODK_HWPATCH:
20133 fputs (" HWPATCH ", stdout);
fd17d1e6 20134 if (option.info & OHW_R4KEOP)
a6e9f9df 20135 fputs (" R4KEOP", stdout);
fd17d1e6 20136 if (option.info & OHW_R8KPFETCH)
a6e9f9df 20137 fputs (" R8KPFETCH", stdout);
fd17d1e6 20138 if (option.info & OHW_R5KEOP)
a6e9f9df 20139 fputs (" R5KEOP", stdout);
fd17d1e6 20140 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
20141 fputs (" R5KCVTL", stdout);
20142 break;
2e6be59c 20143
a6e9f9df
AM
20144 case ODK_FILL:
20145 fputs (" FILL ", stdout);
20146 /* XXX Print content of info word? */
20147 break;
2e6be59c 20148
a6e9f9df
AM
20149 case ODK_TAGS:
20150 fputs (" TAGS ", stdout);
20151 /* XXX Print content of info word? */
20152 break;
2e6be59c 20153
a6e9f9df
AM
20154 case ODK_HWAND:
20155 fputs (" HWAND ", stdout);
fd17d1e6 20156 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 20157 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 20158 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
20159 fputs (" R4KEOP_CLEAN", stdout);
20160 break;
2e6be59c 20161
a6e9f9df
AM
20162 case ODK_HWOR:
20163 fputs (" HWOR ", stdout);
fd17d1e6 20164 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 20165 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 20166 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
20167 fputs (" R4KEOP_CLEAN", stdout);
20168 break;
2e6be59c 20169
a6e9f9df 20170 case ODK_GP_GROUP:
d0c4e780 20171 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
20172 option.info & OGP_GROUP,
20173 (option.info & OGP_SELF) >> 16);
a6e9f9df 20174 break;
2e6be59c 20175
a6e9f9df 20176 case ODK_IDENT:
d0c4e780 20177 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
20178 option.info & OGP_GROUP,
20179 (option.info & OGP_SELF) >> 16);
a6e9f9df 20180 break;
2e6be59c 20181
a6e9f9df
AM
20182 default:
20183 /* This shouldn't happen. */
d0c4e780 20184 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 20185 option.kind, option.section, option.info);
a6e9f9df 20186 break;
252b5132 20187 }
a6e9f9df 20188
2cf0635d 20189 len = sizeof (* eopt);
fd17d1e6 20190 while (len < option.size)
82b1b41b 20191 {
fd17d1e6 20192 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 20193
82b1b41b
NC
20194 if (ISPRINT (datum))
20195 printf ("%c", datum);
20196 else
20197 printf ("\\%03o", datum);
20198 len ++;
20199 }
a6e9f9df 20200 fputs ("\n", stdout);
82b1b41b 20201
fd17d1e6 20202 offset += option.size;
252b5132 20203 }
a6e9f9df 20204 free (eopt);
252b5132 20205 }
32ec8896 20206 else
015dc7e1 20207 res = false;
252b5132
RH
20208 }
20209
20210 if (conflicts_offset != 0 && conflictsno != 0)
20211 {
2cf0635d 20212 Elf32_Conflict * iconf;
252b5132
RH
20213 size_t cnt;
20214
978c4450 20215 if (filedata->dynamic_symbols == NULL)
252b5132 20216 {
591a748a 20217 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 20218 return false;
252b5132
RH
20219 }
20220
7296a62a
NC
20221 /* PR 21345 - print a slightly more helpful error message
20222 if we are sure that the cmalloc will fail. */
645f43a8 20223 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 20224 {
26c527e6
AM
20225 error (_("Overlarge number of conflicts detected: %zx\n"),
20226 conflictsno);
015dc7e1 20227 return false;
7296a62a
NC
20228 }
20229
3f5e193b 20230 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
20231 if (iconf == NULL)
20232 {
8b73c356 20233 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 20234 return false;
252b5132
RH
20235 }
20236
9ea033b2 20237 if (is_32bit_elf)
252b5132 20238 {
2cf0635d 20239 Elf32_External_Conflict * econf32;
a6e9f9df 20240
3f5e193b 20241 econf32 = (Elf32_External_Conflict *)
95099889
AM
20242 get_data (NULL, filedata, conflicts_offset,
20243 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 20244 if (!econf32)
5a814d6d
AM
20245 {
20246 free (iconf);
015dc7e1 20247 return false;
5a814d6d 20248 }
252b5132
RH
20249
20250 for (cnt = 0; cnt < conflictsno; ++cnt)
20251 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
20252
20253 free (econf32);
252b5132
RH
20254 }
20255 else
20256 {
2cf0635d 20257 Elf64_External_Conflict * econf64;
a6e9f9df 20258
3f5e193b 20259 econf64 = (Elf64_External_Conflict *)
95099889
AM
20260 get_data (NULL, filedata, conflicts_offset,
20261 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 20262 if (!econf64)
5a814d6d
AM
20263 {
20264 free (iconf);
015dc7e1 20265 return false;
5a814d6d 20266 }
252b5132
RH
20267
20268 for (cnt = 0; cnt < conflictsno; ++cnt)
20269 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
20270
20271 free (econf64);
252b5132
RH
20272 }
20273
26c527e6
AM
20274 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
20275 "\nSection '.conflict' contains %zu entries:\n",
20276 conflictsno),
20277 conflictsno);
252b5132
RH
20278 puts (_(" Num: Index Value Name"));
20279
20280 for (cnt = 0; cnt < conflictsno; ++cnt)
20281 {
26c527e6 20282 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 20283
978c4450 20284 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 20285 printf (_("<corrupt symbol index>"));
d79b3d50 20286 else
e0a31db1
NC
20287 {
20288 Elf_Internal_Sym * psym;
20289
978c4450 20290 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
20291 print_vma (psym->st_value, FULL_HEX);
20292 putchar (' ');
84714f86 20293 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20294 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20295 else
20296 printf (_("<corrupt: %14ld>"), psym->st_name);
20297 }
31104126 20298 putchar ('\n');
252b5132
RH
20299 }
20300
252b5132
RH
20301 free (iconf);
20302 }
20303
ccb4c951
RS
20304 if (pltgot != 0 && local_gotno != 0)
20305 {
625d49fc 20306 uint64_t ent, local_end, global_end;
bbeee7ea 20307 size_t i, offset;
2cf0635d 20308 unsigned char * data;
82b1b41b 20309 unsigned char * data_end;
bbeee7ea 20310 int addr_size;
ccb4c951 20311
91d6fa6a 20312 ent = pltgot;
ccb4c951
RS
20313 addr_size = (is_32bit_elf ? 4 : 8);
20314 local_end = pltgot + local_gotno * addr_size;
ccb4c951 20315
74e1a04b
NC
20316 /* PR binutils/17533 file: 012-111227-0.004 */
20317 if (symtabno < gotsym)
20318 {
26c527e6
AM
20319 error (_("The GOT symbol offset (%" PRIu64
20320 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20321 gotsym, symtabno);
015dc7e1 20322 return false;
74e1a04b 20323 }
82b1b41b 20324
74e1a04b 20325 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
20326 /* PR 17531: file: 54c91a34. */
20327 if (global_end < local_end)
20328 {
26c527e6 20329 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 20330 return false;
82b1b41b 20331 }
948f632f 20332
dda8d76d
NC
20333 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20334 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
20335 global_end - pltgot, 1,
20336 _("Global Offset Table data"));
919383ac 20337 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 20338 data_end = data + (global_end - pltgot);
59245841 20339
ccb4c951
RS
20340 printf (_("\nPrimary GOT:\n"));
20341 printf (_(" Canonical gp value: "));
20342 print_vma (pltgot + 0x7ff0, LONG_HEX);
20343 printf ("\n\n");
20344
20345 printf (_(" Reserved entries:\n"));
20346 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
20347 addr_size * 2, _("Address"), _("Access"),
20348 addr_size * 2, _("Initial"));
82b1b41b 20349 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 20350 printf (_(" Lazy resolver\n"));
625d49fc 20351 if (ent == (uint64_t) -1)
82b1b41b 20352 goto got_print_fail;
75ec1fdb 20353
c4ab9505
MR
20354 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20355 This entry will be used by some runtime loaders, to store the
20356 module pointer. Otherwise this is an ordinary local entry.
20357 PR 21344: Check for the entry being fully available before
20358 fetching it. */
20359 if (data
20360 && data + ent - pltgot + addr_size <= data_end
20361 && (byte_get (data + ent - pltgot, addr_size)
20362 >> (addr_size * 8 - 1)) != 0)
20363 {
20364 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20365 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 20366 if (ent == (uint64_t) -1)
c4ab9505 20367 goto got_print_fail;
ccb4c951
RS
20368 }
20369 printf ("\n");
20370
f17e9d8a 20371 if (data != NULL && ent < local_end)
ccb4c951
RS
20372 {
20373 printf (_(" Local entries:\n"));
cc5914eb 20374 printf (" %*s %10s %*s\n",
2b692964
NC
20375 addr_size * 2, _("Address"), _("Access"),
20376 addr_size * 2, _("Initial"));
91d6fa6a 20377 while (ent < local_end)
ccb4c951 20378 {
82b1b41b 20379 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20380 printf ("\n");
625d49fc 20381 if (ent == (uint64_t) -1)
82b1b41b 20382 goto got_print_fail;
ccb4c951
RS
20383 }
20384 printf ("\n");
20385 }
20386
f17e9d8a 20387 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
20388 {
20389 int sym_width;
20390
20391 printf (_(" Global entries:\n"));
cc5914eb 20392 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
20393 addr_size * 2, _("Address"),
20394 _("Access"),
2b692964 20395 addr_size * 2, _("Initial"),
9cf03b7e
NC
20396 addr_size * 2, _("Sym.Val."),
20397 _("Type"),
20398 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20399 _("Ndx"), _("Name"));
0b4362b0 20400
ccb4c951 20401 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 20402
ccb4c951
RS
20403 for (i = gotsym; i < symtabno; i++)
20404 {
82b1b41b 20405 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20406 printf (" ");
e0a31db1 20407
978c4450 20408 if (filedata->dynamic_symbols == NULL)
e0a31db1 20409 printf (_("<no dynamic symbols>"));
978c4450 20410 else if (i < filedata->num_dynamic_syms)
e0a31db1 20411 {
978c4450 20412 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
20413
20414 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
20415 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20416
20417 bool is_special;
20418 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20419 if (is_special)
20420 printf ("%3s ", s);
20421 else
20422 printf ("%3u ", psym->st_shndx);
e0a31db1 20423
84714f86 20424 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20425 print_symbol_name (sym_width,
84714f86 20426 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20427 else
20428 printf (_("<corrupt: %14ld>"), psym->st_name);
20429 }
ccb4c951 20430 else
26c527e6
AM
20431 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20432 i);
e0a31db1 20433
ccb4c951 20434 printf ("\n");
625d49fc 20435 if (ent == (uint64_t) -1)
82b1b41b 20436 break;
ccb4c951
RS
20437 }
20438 printf ("\n");
20439 }
20440
82b1b41b 20441 got_print_fail:
9db70fc3 20442 free (data);
ccb4c951
RS
20443 }
20444
861fb55a
DJ
20445 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20446 {
625d49fc 20447 uint64_t ent, end;
26c527e6
AM
20448 uint64_t offset, rel_offset;
20449 uint64_t count, i;
2cf0635d 20450 unsigned char * data;
861fb55a 20451 int addr_size, sym_width;
2cf0635d 20452 Elf_Internal_Rela * rels;
861fb55a 20453
dda8d76d 20454 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
20455 if (pltrel == DT_RELA)
20456 {
dda8d76d 20457 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20458 return false;
861fb55a
DJ
20459 }
20460 else
20461 {
dda8d76d 20462 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20463 return false;
861fb55a
DJ
20464 }
20465
91d6fa6a 20466 ent = mips_pltgot;
861fb55a
DJ
20467 addr_size = (is_32bit_elf ? 4 : 8);
20468 end = mips_pltgot + (2 + count) * addr_size;
20469
dda8d76d
NC
20470 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20471 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 20472 1, _("Procedure Linkage Table data"));
59245841 20473 if (data == NULL)
288f0ba2
AM
20474 {
20475 free (rels);
015dc7e1 20476 return false;
288f0ba2 20477 }
59245841 20478
9cf03b7e 20479 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
20480 printf (_(" Reserved entries:\n"));
20481 printf (_(" %*s %*s Purpose\n"),
2b692964 20482 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 20483 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20484 printf (_(" PLT lazy resolver\n"));
91d6fa6a 20485 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20486 printf (_(" Module pointer\n"));
861fb55a
DJ
20487 printf ("\n");
20488
20489 printf (_(" Entries:\n"));
cc5914eb 20490 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
20491 addr_size * 2, _("Address"),
20492 addr_size * 2, _("Initial"),
20493 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
20494 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20495 for (i = 0; i < count; i++)
20496 {
26c527e6 20497 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 20498
91d6fa6a 20499 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 20500 printf (" ");
e0a31db1 20501
978c4450 20502 if (idx >= filedata->num_dynamic_syms)
26c527e6 20503 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 20504 else
e0a31db1 20505 {
978c4450 20506 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
20507
20508 print_vma (psym->st_value, LONG_HEX);
20509 printf (" %-7s %3s ",
dda8d76d 20510 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 20511 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 20512 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20513 print_symbol_name (sym_width,
84714f86 20514 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20515 else
20516 printf (_("<corrupt: %14ld>"), psym->st_name);
20517 }
861fb55a
DJ
20518 printf ("\n");
20519 }
20520 printf ("\n");
20521
9db70fc3 20522 free (data);
861fb55a
DJ
20523 free (rels);
20524 }
20525
32ec8896 20526 return res;
252b5132
RH
20527}
20528
015dc7e1 20529static bool
dda8d76d 20530process_nds32_specific (Filedata * filedata)
35c08157
KLC
20531{
20532 Elf_Internal_Shdr *sect = NULL;
20533
dda8d76d 20534 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 20535 if (sect != NULL && sect->sh_size >= 4)
35c08157 20536 {
9c7b8e9b
AM
20537 unsigned char *buf;
20538 unsigned int flag;
35c08157
KLC
20539
20540 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
20541 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20542 _("NDS32 elf flags section"));
35c08157 20543
9c7b8e9b 20544 if (buf == NULL)
015dc7e1 20545 return false;
32ec8896 20546
9c7b8e9b
AM
20547 flag = byte_get (buf, 4);
20548 free (buf);
20549 switch (flag & 0x3)
35c08157
KLC
20550 {
20551 case 0:
20552 printf ("(VEC_SIZE):\tNo entry.\n");
20553 break;
20554 case 1:
20555 printf ("(VEC_SIZE):\t4 bytes\n");
20556 break;
20557 case 2:
20558 printf ("(VEC_SIZE):\t16 bytes\n");
20559 break;
20560 case 3:
20561 printf ("(VEC_SIZE):\treserved\n");
20562 break;
20563 }
20564 }
20565
015dc7e1 20566 return true;
35c08157
KLC
20567}
20568
015dc7e1 20569static bool
dda8d76d 20570process_gnu_liblist (Filedata * filedata)
047b2264 20571{
2cf0635d
NC
20572 Elf_Internal_Shdr * section;
20573 Elf_Internal_Shdr * string_sec;
20574 Elf32_External_Lib * elib;
20575 char * strtab;
c256ffe7 20576 size_t strtab_size;
047b2264 20577 size_t cnt;
26c527e6 20578 uint64_t num_liblist;
047b2264 20579 unsigned i;
015dc7e1 20580 bool res = true;
047b2264
JJ
20581
20582 if (! do_arch)
015dc7e1 20583 return true;
047b2264 20584
dda8d76d
NC
20585 for (i = 0, section = filedata->section_headers;
20586 i < filedata->file_header.e_shnum;
b34976b6 20587 i++, section++)
047b2264
JJ
20588 {
20589 switch (section->sh_type)
20590 {
20591 case SHT_GNU_LIBLIST:
dda8d76d 20592 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20593 break;
20594
3f5e193b 20595 elib = (Elf32_External_Lib *)
dda8d76d 20596 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20597 _("liblist section data"));
047b2264
JJ
20598
20599 if (elib == NULL)
32ec8896 20600 {
015dc7e1 20601 res = false;
32ec8896
NC
20602 break;
20603 }
047b2264 20604
dda8d76d
NC
20605 string_sec = filedata->section_headers + section->sh_link;
20606 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20607 string_sec->sh_size,
20608 _("liblist string table"));
047b2264
JJ
20609 if (strtab == NULL
20610 || section->sh_entsize != sizeof (Elf32_External_Lib))
20611 {
20612 free (elib);
2842702f 20613 free (strtab);
015dc7e1 20614 res = false;
047b2264
JJ
20615 break;
20616 }
59245841 20617 strtab_size = string_sec->sh_size;
047b2264 20618
d3a49aa8 20619 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20620 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20621 " entries:\n",
20622 "\nLibrary list section '%s' contains %" PRIu64
20623 " entries:\n",
d3a49aa8 20624 num_liblist),
dda8d76d 20625 printable_section_name (filedata, section),
d3a49aa8 20626 num_liblist);
047b2264 20627
2b692964 20628 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20629
20630 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20631 ++cnt)
20632 {
20633 Elf32_Lib liblist;
91d6fa6a 20634 time_t atime;
d5b07ef4 20635 char timebuf[128];
2cf0635d 20636 struct tm * tmp;
047b2264
JJ
20637
20638 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20639 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20640 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20641 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20642 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20643
91d6fa6a 20644 tmp = gmtime (&atime);
e9e44622
JJ
20645 snprintf (timebuf, sizeof (timebuf),
20646 "%04u-%02u-%02uT%02u:%02u:%02u",
20647 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20648 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20649
26c527e6 20650 printf ("%3zu: ", cnt);
047b2264 20651 if (do_wide)
c256ffe7 20652 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20653 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20654 else
c256ffe7 20655 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20656 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20657 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20658 liblist.l_version, liblist.l_flags);
20659 }
20660
20661 free (elib);
2842702f 20662 free (strtab);
047b2264
JJ
20663 }
20664 }
20665
32ec8896 20666 return res;
047b2264
JJ
20667}
20668
9437c45b 20669static const char *
dda8d76d 20670get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20671{
20672 static char buff[64];
103f02d3 20673
dda8d76d 20674 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20675 switch (e_type)
20676 {
57346661 20677 case NT_AUXV:
1ec5cd37 20678 return _("NT_AUXV (auxiliary vector)");
57346661 20679 case NT_PRSTATUS:
1ec5cd37 20680 return _("NT_PRSTATUS (prstatus structure)");
57346661 20681 case NT_FPREGSET:
1ec5cd37 20682 return _("NT_FPREGSET (floating point registers)");
57346661 20683 case NT_PRPSINFO:
1ec5cd37 20684 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20685 case NT_TASKSTRUCT:
1ec5cd37 20686 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20687 case NT_GDB_TDESC:
20688 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20689 case NT_PRXFPREG:
1ec5cd37 20690 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20691 case NT_PPC_VMX:
20692 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20693 case NT_PPC_VSX:
20694 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20695 case NT_PPC_TAR:
20696 return _("NT_PPC_TAR (ppc TAR register)");
20697 case NT_PPC_PPR:
20698 return _("NT_PPC_PPR (ppc PPR register)");
20699 case NT_PPC_DSCR:
20700 return _("NT_PPC_DSCR (ppc DSCR register)");
20701 case NT_PPC_EBB:
20702 return _("NT_PPC_EBB (ppc EBB registers)");
20703 case NT_PPC_PMU:
20704 return _("NT_PPC_PMU (ppc PMU registers)");
20705 case NT_PPC_TM_CGPR:
20706 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20707 case NT_PPC_TM_CFPR:
20708 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20709 case NT_PPC_TM_CVMX:
20710 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20711 case NT_PPC_TM_CVSX:
3fd21718 20712 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20713 case NT_PPC_TM_SPR:
20714 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20715 case NT_PPC_TM_CTAR:
20716 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20717 case NT_PPC_TM_CPPR:
20718 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20719 case NT_PPC_TM_CDSCR:
20720 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20721 case NT_386_TLS:
20722 return _("NT_386_TLS (x86 TLS information)");
20723 case NT_386_IOPERM:
20724 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20725 case NT_X86_XSTATE:
20726 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20727 case NT_X86_CET:
20728 return _("NT_X86_CET (x86 CET state)");
eccdc733
SC
20729 case NT_X86_SHSTK:
20730 return _("NT_X86_SHSTK (x86 SHSTK state)");
0675e188
UW
20731 case NT_S390_HIGH_GPRS:
20732 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20733 case NT_S390_TIMER:
20734 return _("NT_S390_TIMER (s390 timer register)");
20735 case NT_S390_TODCMP:
20736 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20737 case NT_S390_TODPREG:
20738 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20739 case NT_S390_CTRS:
20740 return _("NT_S390_CTRS (s390 control registers)");
20741 case NT_S390_PREFIX:
20742 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20743 case NT_S390_LAST_BREAK:
20744 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20745 case NT_S390_SYSTEM_CALL:
20746 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20747 case NT_S390_TDB:
20748 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20749 case NT_S390_VXRS_LOW:
20750 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20751 case NT_S390_VXRS_HIGH:
20752 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20753 case NT_S390_GS_CB:
20754 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20755 case NT_S390_GS_BC:
20756 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20757 case NT_ARM_VFP:
20758 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20759 case NT_ARM_TLS:
20760 return _("NT_ARM_TLS (AArch TLS registers)");
20761 case NT_ARM_HW_BREAK:
20762 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20763 case NT_ARM_HW_WATCH:
20764 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20765 case NT_ARM_SYSTEM_CALL:
20766 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20767 case NT_ARM_SVE:
20768 return _("NT_ARM_SVE (AArch SVE registers)");
20769 case NT_ARM_PAC_MASK:
20770 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20771 case NT_ARM_PACA_KEYS:
20772 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20773 case NT_ARM_PACG_KEYS:
20774 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20775 case NT_ARM_TAGGED_ADDR_CTRL:
20776 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20777 case NT_ARM_SSVE:
20778 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20779 case NT_ARM_ZA:
20780 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20781 case NT_ARM_ZT:
20782 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20783 case NT_ARM_PAC_ENABLED_KEYS:
20784 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20785 case NT_ARC_V2:
20786 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20787 case NT_RISCV_CSR:
20788 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20789 case NT_PSTATUS:
1ec5cd37 20790 return _("NT_PSTATUS (pstatus structure)");
57346661 20791 case NT_FPREGS:
1ec5cd37 20792 return _("NT_FPREGS (floating point registers)");
57346661 20793 case NT_PSINFO:
1ec5cd37 20794 return _("NT_PSINFO (psinfo structure)");
57346661 20795 case NT_LWPSTATUS:
1ec5cd37 20796 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20797 case NT_LWPSINFO:
1ec5cd37 20798 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20799 case NT_WIN32PSTATUS:
1ec5cd37 20800 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20801 case NT_SIGINFO:
20802 return _("NT_SIGINFO (siginfo_t data)");
20803 case NT_FILE:
20804 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20805 default:
20806 break;
20807 }
20808 else
20809 switch (e_type)
20810 {
20811 case NT_VERSION:
20812 return _("NT_VERSION (version)");
20813 case NT_ARCH:
20814 return _("NT_ARCH (architecture)");
9ef920e9 20815 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20816 return _("OPEN");
9ef920e9 20817 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20818 return _("func");
c8795e1f
NC
20819 case NT_GO_BUILDID:
20820 return _("GO BUILDID");
3ac925fc
LB
20821 case FDO_PACKAGING_METADATA:
20822 return _("FDO_PACKAGING_METADATA");
762910fb
LB
20823 case FDO_DLOPEN_METADATA:
20824 return _("FDO_DLOPEN_METADATA");
1ec5cd37
NC
20825 default:
20826 break;
20827 }
20828
e9e44622 20829 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20830 return buff;
779fe533
NC
20831}
20832
015dc7e1 20833static bool
9ece1fa9
TT
20834print_core_note (Elf_Internal_Note *pnote)
20835{
20836 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20837 uint64_t count, page_size;
9ece1fa9
TT
20838 unsigned char *descdata, *filenames, *descend;
20839
20840 if (pnote->type != NT_FILE)
04ac15ab
AS
20841 {
20842 if (do_wide)
20843 printf ("\n");
015dc7e1 20844 return true;
04ac15ab 20845 }
9ece1fa9 20846
9ece1fa9
TT
20847 if (pnote->descsz < 2 * addr_size)
20848 {
32ec8896 20849 error (_(" Malformed note - too short for header\n"));
015dc7e1 20850 return false;
9ece1fa9
TT
20851 }
20852
20853 descdata = (unsigned char *) pnote->descdata;
20854 descend = descdata + pnote->descsz;
20855
20856 if (descdata[pnote->descsz - 1] != '\0')
20857 {
32ec8896 20858 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20859 return false;
9ece1fa9
TT
20860 }
20861
20862 count = byte_get (descdata, addr_size);
20863 descdata += addr_size;
20864
20865 page_size = byte_get (descdata, addr_size);
20866 descdata += addr_size;
20867
625d49fc 20868 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20869 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20870 {
32ec8896 20871 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20872 return false;
9ece1fa9
TT
20873 }
20874
20875 printf (_(" Page size: "));
20876 print_vma (page_size, DEC);
20877 printf ("\n");
20878
20879 printf (_(" %*s%*s%*s\n"),
20880 (int) (2 + 2 * addr_size), _("Start"),
20881 (int) (4 + 2 * addr_size), _("End"),
20882 (int) (4 + 2 * addr_size), _("Page Offset"));
20883 filenames = descdata + count * 3 * addr_size;
595712bb 20884 while (count-- > 0)
9ece1fa9 20885 {
625d49fc 20886 uint64_t start, end, file_ofs;
9ece1fa9
TT
20887
20888 if (filenames == descend)
20889 {
32ec8896 20890 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20891 return false;
9ece1fa9
TT
20892 }
20893
20894 start = byte_get (descdata, addr_size);
20895 descdata += addr_size;
20896 end = byte_get (descdata, addr_size);
20897 descdata += addr_size;
20898 file_ofs = byte_get (descdata, addr_size);
20899 descdata += addr_size;
20900
20901 printf (" ");
20902 print_vma (start, FULL_HEX);
20903 printf (" ");
20904 print_vma (end, FULL_HEX);
20905 printf (" ");
20906 print_vma (file_ofs, FULL_HEX);
20907 printf ("\n %s\n", filenames);
20908
20909 filenames += 1 + strlen ((char *) filenames);
20910 }
20911
015dc7e1 20912 return true;
9ece1fa9
TT
20913}
20914
1118d252
RM
20915static const char *
20916get_gnu_elf_note_type (unsigned e_type)
20917{
1449284b 20918 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20919 switch (e_type)
20920 {
20921 case NT_GNU_ABI_TAG:
20922 return _("NT_GNU_ABI_TAG (ABI version tag)");
20923 case NT_GNU_HWCAP:
20924 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20925 case NT_GNU_BUILD_ID:
20926 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20927 case NT_GNU_GOLD_VERSION:
20928 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20929 case NT_GNU_PROPERTY_TYPE_0:
20930 return _("NT_GNU_PROPERTY_TYPE_0");
20931 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20932 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20933 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20934 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20935 default:
1449284b
NC
20936 {
20937 static char buff[64];
1118d252 20938
1449284b
NC
20939 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20940 return buff;
20941 }
20942 }
1118d252
RM
20943}
20944
a9eafb08
L
20945static void
20946decode_x86_compat_isa (unsigned int bitmask)
20947{
20948 while (bitmask)
20949 {
20950 unsigned int bit = bitmask & (- bitmask);
20951
20952 bitmask &= ~ bit;
20953 switch (bit)
20954 {
20955 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20956 printf ("i486");
20957 break;
20958 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20959 printf ("586");
20960 break;
20961 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20962 printf ("686");
20963 break;
20964 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20965 printf ("SSE");
20966 break;
20967 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20968 printf ("SSE2");
20969 break;
20970 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20971 printf ("SSE3");
20972 break;
20973 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20974 printf ("SSSE3");
20975 break;
20976 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20977 printf ("SSE4_1");
20978 break;
20979 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20980 printf ("SSE4_2");
20981 break;
20982 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20983 printf ("AVX");
20984 break;
20985 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20986 printf ("AVX2");
20987 break;
20988 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20989 printf ("AVX512F");
20990 break;
20991 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20992 printf ("AVX512CD");
20993 break;
20994 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20995 printf ("AVX512ER");
20996 break;
20997 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20998 printf ("AVX512PF");
20999 break;
21000 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
21001 printf ("AVX512VL");
21002 break;
21003 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
21004 printf ("AVX512DQ");
21005 break;
21006 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
21007 printf ("AVX512BW");
21008 break;
65b3d26e
L
21009 default:
21010 printf (_("<unknown: %x>"), bit);
21011 break;
a9eafb08
L
21012 }
21013 if (bitmask)
21014 printf (", ");
21015 }
21016}
21017
9ef920e9 21018static void
32930e4e 21019decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 21020{
0a59decb 21021 if (!bitmask)
90c745dc
L
21022 {
21023 printf (_("<None>"));
21024 return;
21025 }
90c745dc 21026
9ef920e9
NC
21027 while (bitmask)
21028 {
1fc87489 21029 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
21030
21031 bitmask &= ~ bit;
21032 switch (bit)
21033 {
32930e4e 21034 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
21035 printf ("CMOV");
21036 break;
32930e4e 21037 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
21038 printf ("SSE");
21039 break;
32930e4e 21040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
21041 printf ("SSE2");
21042 break;
32930e4e 21043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
21044 printf ("SSE3");
21045 break;
32930e4e 21046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
21047 printf ("SSSE3");
21048 break;
32930e4e 21049 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
21050 printf ("SSE4_1");
21051 break;
32930e4e 21052 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
21053 printf ("SSE4_2");
21054 break;
32930e4e 21055 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
21056 printf ("AVX");
21057 break;
32930e4e 21058 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
21059 printf ("AVX2");
21060 break;
32930e4e 21061 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
21062 printf ("FMA");
21063 break;
32930e4e 21064 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
21065 printf ("AVX512F");
21066 break;
32930e4e 21067 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
21068 printf ("AVX512CD");
21069 break;
32930e4e 21070 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
21071 printf ("AVX512ER");
21072 break;
32930e4e 21073 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
21074 printf ("AVX512PF");
21075 break;
32930e4e 21076 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
21077 printf ("AVX512VL");
21078 break;
32930e4e 21079 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
21080 printf ("AVX512DQ");
21081 break;
32930e4e 21082 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
21083 printf ("AVX512BW");
21084 break;
32930e4e 21085 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
21086 printf ("AVX512_4FMAPS");
21087 break;
32930e4e 21088 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
21089 printf ("AVX512_4VNNIW");
21090 break;
32930e4e 21091 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
21092 printf ("AVX512_BITALG");
21093 break;
32930e4e 21094 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
21095 printf ("AVX512_IFMA");
21096 break;
32930e4e 21097 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
21098 printf ("AVX512_VBMI");
21099 break;
32930e4e 21100 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
21101 printf ("AVX512_VBMI2");
21102 break;
32930e4e 21103 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
21104 printf ("AVX512_VNNI");
21105 break;
32930e4e 21106 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
21107 printf ("AVX512_BF16");
21108 break;
65b3d26e
L
21109 default:
21110 printf (_("<unknown: %x>"), bit);
21111 break;
9ef920e9
NC
21112 }
21113 if (bitmask)
21114 printf (", ");
21115 }
21116}
21117
28cdbb18
SM
21118static const char *
21119get_amdgpu_elf_note_type (unsigned int e_type)
21120{
21121 switch (e_type)
21122 {
21123 case NT_AMDGPU_METADATA:
21124 return _("NT_AMDGPU_METADATA (code object metadata)");
21125 default:
21126 {
21127 static char buf[64];
21128 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
21129 return buf;
21130 }
21131 }
21132}
21133
32930e4e
L
21134static void
21135decode_x86_isa (unsigned int bitmask)
21136{
32930e4e
L
21137 while (bitmask)
21138 {
21139 unsigned int bit = bitmask & (- bitmask);
21140
21141 bitmask &= ~ bit;
21142 switch (bit)
21143 {
b0ab0693
L
21144 case GNU_PROPERTY_X86_ISA_1_BASELINE:
21145 printf ("x86-64-baseline");
21146 break;
32930e4e
L
21147 case GNU_PROPERTY_X86_ISA_1_V2:
21148 printf ("x86-64-v2");
21149 break;
21150 case GNU_PROPERTY_X86_ISA_1_V3:
21151 printf ("x86-64-v3");
21152 break;
21153 case GNU_PROPERTY_X86_ISA_1_V4:
21154 printf ("x86-64-v4");
21155 break;
21156 default:
21157 printf (_("<unknown: %x>"), bit);
21158 break;
21159 }
21160 if (bitmask)
21161 printf (", ");
21162 }
21163}
21164
ee2fdd6f 21165static void
a9eafb08 21166decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 21167{
0a59decb 21168 if (!bitmask)
90c745dc
L
21169 {
21170 printf (_("<None>"));
21171 return;
21172 }
90c745dc 21173
ee2fdd6f
L
21174 while (bitmask)
21175 {
21176 unsigned int bit = bitmask & (- bitmask);
21177
21178 bitmask &= ~ bit;
21179 switch (bit)
21180 {
21181 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 21182 printf ("IBT");
ee2fdd6f 21183 break;
48580982 21184 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 21185 printf ("SHSTK");
48580982 21186 break;
279d901e
L
21187 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
21188 printf ("LAM_U48");
21189 break;
21190 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
21191 printf ("LAM_U57");
21192 break;
ee2fdd6f
L
21193 default:
21194 printf (_("<unknown: %x>"), bit);
21195 break;
21196 }
21197 if (bitmask)
21198 printf (", ");
21199 }
21200}
21201
a9eafb08
L
21202static void
21203decode_x86_feature_2 (unsigned int bitmask)
21204{
0a59decb 21205 if (!bitmask)
90c745dc
L
21206 {
21207 printf (_("<None>"));
21208 return;
21209 }
90c745dc 21210
a9eafb08
L
21211 while (bitmask)
21212 {
21213 unsigned int bit = bitmask & (- bitmask);
21214
21215 bitmask &= ~ bit;
21216 switch (bit)
21217 {
21218 case GNU_PROPERTY_X86_FEATURE_2_X86:
21219 printf ("x86");
21220 break;
21221 case GNU_PROPERTY_X86_FEATURE_2_X87:
21222 printf ("x87");
21223 break;
21224 case GNU_PROPERTY_X86_FEATURE_2_MMX:
21225 printf ("MMX");
21226 break;
21227 case GNU_PROPERTY_X86_FEATURE_2_XMM:
21228 printf ("XMM");
21229 break;
21230 case GNU_PROPERTY_X86_FEATURE_2_YMM:
21231 printf ("YMM");
21232 break;
21233 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
21234 printf ("ZMM");
21235 break;
a308b89d
L
21236 case GNU_PROPERTY_X86_FEATURE_2_TMM:
21237 printf ("TMM");
21238 break;
32930e4e
L
21239 case GNU_PROPERTY_X86_FEATURE_2_MASK:
21240 printf ("MASK");
21241 break;
a9eafb08
L
21242 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
21243 printf ("FXSR");
21244 break;
21245 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
21246 printf ("XSAVE");
21247 break;
21248 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
21249 printf ("XSAVEOPT");
21250 break;
21251 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
21252 printf ("XSAVEC");
21253 break;
65b3d26e
L
21254 default:
21255 printf (_("<unknown: %x>"), bit);
21256 break;
a9eafb08
L
21257 }
21258 if (bitmask)
21259 printf (", ");
21260 }
21261}
21262
cd702818
SD
21263static void
21264decode_aarch64_feature_1_and (unsigned int bitmask)
21265{
21266 while (bitmask)
21267 {
21268 unsigned int bit = bitmask & (- bitmask);
21269
21270 bitmask &= ~ bit;
21271 switch (bit)
21272 {
21273 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
21274 printf ("BTI");
21275 break;
21276
21277 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
21278 printf ("PAC");
21279 break;
21280
b75ce33f
SP
21281 case GNU_PROPERTY_AARCH64_FEATURE_1_GCS:
21282 printf ("GCS");
21283 break;
21284
cd702818
SD
21285 default:
21286 printf (_("<unknown: %x>"), bit);
21287 break;
21288 }
21289 if (bitmask)
21290 printf (", ");
21291 }
21292}
21293
4ad5217c
KC
21294static void
21295decode_riscv_feature_1_and (unsigned int bitmask)
21296{
21297 while (bitmask)
21298 {
21299 unsigned int bit = bitmask & (- bitmask);
21300
21301 bitmask &= ~ bit;
21302 switch (bit)
21303 {
21304 case GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED:
21305 printf ("CFI_LP_UNLABELED");
21306 break;
21307
21308 case GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS:
21309 printf ("CFI_SS");
21310 break;
21311
21312 default:
21313 printf (_("<unknown: %x>"), bit);
21314 break;
21315 }
21316 if (bitmask)
21317 printf (", ");
21318 }
21319}
21320
6320fd00
L
21321static void
21322decode_1_needed (unsigned int bitmask)
21323{
21324 while (bitmask)
21325 {
21326 unsigned int bit = bitmask & (- bitmask);
21327
21328 bitmask &= ~ bit;
21329 switch (bit)
21330 {
21331 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
21332 printf ("indirect external access");
21333 break;
21334 default:
21335 printf (_("<unknown: %x>"), bit);
21336 break;
21337 }
21338 if (bitmask)
21339 printf (", ");
21340 }
21341}
21342
9ef920e9 21343static void
dda8d76d 21344print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
21345{
21346 unsigned char * ptr = (unsigned char *) pnote->descdata;
21347 unsigned char * ptr_end = ptr + pnote->descsz;
21348 unsigned int size = is_32bit_elf ? 4 : 8;
21349
21350 printf (_(" Properties: "));
21351
1fc87489 21352 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
21353 {
21354 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21355 return;
21356 }
21357
6ab2c4ed 21358 while (ptr < ptr_end)
9ef920e9 21359 {
1fc87489 21360 unsigned int j;
6ab2c4ed
MC
21361 unsigned int type;
21362 unsigned int datasz;
21363
21364 if ((size_t) (ptr_end - ptr) < 8)
21365 {
21366 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21367 break;
21368 }
21369
21370 type = byte_get (ptr, 4);
21371 datasz = byte_get (ptr + 4, 4);
9ef920e9 21372
1fc87489 21373 ptr += 8;
9ef920e9 21374
6ab2c4ed 21375 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 21376 {
1fc87489
L
21377 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21378 type, datasz);
9ef920e9 21379 break;
1fc87489 21380 }
9ef920e9 21381
1fc87489
L
21382 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21383 {
dda8d76d
NC
21384 if (filedata->file_header.e_machine == EM_X86_64
21385 || filedata->file_header.e_machine == EM_IAMCU
21386 || filedata->file_header.e_machine == EM_386)
1fc87489 21387 {
aa7bca9b
L
21388 unsigned int bitmask;
21389
21390 if (datasz == 4)
0a59decb 21391 bitmask = byte_get (ptr, 4);
aa7bca9b
L
21392 else
21393 bitmask = 0;
21394
1fc87489
L
21395 switch (type)
21396 {
21397 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 21398 if (datasz != 4)
aa7bca9b
L
21399 printf (_("x86 ISA used: <corrupt length: %#x> "),
21400 datasz);
1fc87489 21401 else
aa7bca9b
L
21402 {
21403 printf ("x86 ISA used: ");
21404 decode_x86_isa (bitmask);
21405 }
1fc87489 21406 goto next;
9ef920e9 21407
1fc87489 21408 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 21409 if (datasz != 4)
aa7bca9b
L
21410 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21411 datasz);
1fc87489 21412 else
aa7bca9b
L
21413 {
21414 printf ("x86 ISA needed: ");
21415 decode_x86_isa (bitmask);
21416 }
1fc87489 21417 goto next;
9ef920e9 21418
ee2fdd6f 21419 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 21420 if (datasz != 4)
aa7bca9b
L
21421 printf (_("x86 feature: <corrupt length: %#x> "),
21422 datasz);
ee2fdd6f 21423 else
aa7bca9b
L
21424 {
21425 printf ("x86 feature: ");
a9eafb08
L
21426 decode_x86_feature_1 (bitmask);
21427 }
21428 goto next;
21429
21430 case GNU_PROPERTY_X86_FEATURE_2_USED:
21431 if (datasz != 4)
21432 printf (_("x86 feature used: <corrupt length: %#x> "),
21433 datasz);
21434 else
21435 {
21436 printf ("x86 feature used: ");
21437 decode_x86_feature_2 (bitmask);
21438 }
21439 goto next;
21440
21441 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21442 if (datasz != 4)
21443 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21444 else
21445 {
21446 printf ("x86 feature needed: ");
21447 decode_x86_feature_2 (bitmask);
21448 }
21449 goto next;
21450
21451 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21452 if (datasz != 4)
21453 printf (_("x86 ISA used: <corrupt length: %#x> "),
21454 datasz);
21455 else
21456 {
21457 printf ("x86 ISA used: ");
21458 decode_x86_compat_isa (bitmask);
21459 }
21460 goto next;
21461
21462 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21463 if (datasz != 4)
21464 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21465 datasz);
21466 else
21467 {
21468 printf ("x86 ISA needed: ");
21469 decode_x86_compat_isa (bitmask);
aa7bca9b 21470 }
ee2fdd6f
L
21471 goto next;
21472
32930e4e
L
21473 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21474 if (datasz != 4)
21475 printf (_("x86 ISA used: <corrupt length: %#x> "),
21476 datasz);
21477 else
21478 {
21479 printf ("x86 ISA used: ");
21480 decode_x86_compat_2_isa (bitmask);
21481 }
21482 goto next;
21483
21484 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21485 if (datasz != 4)
21486 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21487 datasz);
21488 else
21489 {
21490 printf ("x86 ISA needed: ");
21491 decode_x86_compat_2_isa (bitmask);
21492 }
21493 goto next;
21494
1fc87489
L
21495 default:
21496 break;
21497 }
21498 }
cd702818
SD
21499 else if (filedata->file_header.e_machine == EM_AARCH64)
21500 {
21501 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21502 {
21503 printf ("AArch64 feature: ");
21504 if (datasz != 4)
21505 printf (_("<corrupt length: %#x> "), datasz);
21506 else
21507 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21508 goto next;
21509 }
21510 }
4ad5217c
KC
21511 else if (filedata->file_header.e_machine == EM_RISCV)
21512 {
21513 if (type == GNU_PROPERTY_RISCV_FEATURE_1_AND)
21514 {
21515 printf ("RISC-V AND feature: ");
21516 if (datasz != 4)
21517 printf (_("<corrupt length: %#x> "), datasz);
21518 else
21519 decode_riscv_feature_1_and (byte_get (ptr, 4));
21520 goto next;
21521 }
21522 }
1fc87489
L
21523 }
21524 else
21525 {
21526 switch (type)
9ef920e9 21527 {
1fc87489
L
21528 case GNU_PROPERTY_STACK_SIZE:
21529 printf (_("stack size: "));
21530 if (datasz != size)
21531 printf (_("<corrupt length: %#x> "), datasz);
21532 else
26c527e6 21533 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
21534 goto next;
21535
21536 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21537 printf ("no copy on protected ");
21538 if (datasz)
21539 printf (_("<corrupt length: %#x> "), datasz);
21540 goto next;
21541
4d890484
AZ
21542 case GNU_PROPERTY_MEMORY_SEAL:
21543 printf ("memory seal ");
21544 if (datasz)
21545 printf (_("<corrupt length: %#x> "), datasz);
21546 goto next;
21547
1fc87489 21548 default:
5a767724
L
21549 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21550 && type <= GNU_PROPERTY_UINT32_AND_HI)
21551 || (type >= GNU_PROPERTY_UINT32_OR_LO
21552 && type <= GNU_PROPERTY_UINT32_OR_HI))
21553 {
6320fd00
L
21554 switch (type)
21555 {
21556 case GNU_PROPERTY_1_NEEDED:
21557 if (datasz != 4)
21558 printf (_("1_needed: <corrupt length: %#x> "),
21559 datasz);
21560 else
21561 {
21562 unsigned int bitmask = byte_get (ptr, 4);
21563 printf ("1_needed: ");
21564 decode_1_needed (bitmask);
21565 }
21566 goto next;
21567
21568 default:
21569 break;
21570 }
5a767724
L
21571 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21572 printf (_("UINT32_AND (%#x): "), type);
21573 else
21574 printf (_("UINT32_OR (%#x): "), type);
21575 if (datasz != 4)
21576 printf (_("<corrupt length: %#x> "), datasz);
21577 else
21578 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21579 goto next;
21580 }
9ef920e9
NC
21581 break;
21582 }
9ef920e9
NC
21583 }
21584
1fc87489
L
21585 if (type < GNU_PROPERTY_LOPROC)
21586 printf (_("<unknown type %#x data: "), type);
21587 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 21588 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
21589 else
21590 printf (_("<application-specific type %#x data: "), type);
21591 for (j = 0; j < datasz; ++j)
21592 printf ("%02x ", ptr[j] & 0xff);
21593 printf (">");
21594
dc1e8a47 21595 next:
9ef920e9 21596 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
21597 if (ptr == ptr_end)
21598 break;
1fc87489 21599
6ab2c4ed
MC
21600 if (do_wide)
21601 printf (", ");
21602 else
21603 printf ("\n\t");
9ef920e9
NC
21604 }
21605
21606 printf ("\n");
21607}
21608
015dc7e1 21609static bool
dda8d76d 21610print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 21611{
1449284b 21612 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
21613 switch (pnote->type)
21614 {
21615 case NT_GNU_BUILD_ID:
21616 {
26c527e6 21617 size_t i;
664f90a3
TT
21618
21619 printf (_(" Build ID: "));
21620 for (i = 0; i < pnote->descsz; ++i)
21621 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 21622 printf ("\n");
664f90a3
TT
21623 }
21624 break;
21625
21626 case NT_GNU_ABI_TAG:
21627 {
26c527e6 21628 unsigned int os, major, minor, subminor;
664f90a3
TT
21629 const char *osname;
21630
3102e897
NC
21631 /* PR 17531: file: 030-599401-0.004. */
21632 if (pnote->descsz < 16)
21633 {
21634 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21635 break;
21636 }
21637
664f90a3
TT
21638 os = byte_get ((unsigned char *) pnote->descdata, 4);
21639 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21640 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21641 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21642
21643 switch (os)
21644 {
21645 case GNU_ABI_TAG_LINUX:
21646 osname = "Linux";
21647 break;
21648 case GNU_ABI_TAG_HURD:
21649 osname = "Hurd";
21650 break;
21651 case GNU_ABI_TAG_SOLARIS:
21652 osname = "Solaris";
21653 break;
21654 case GNU_ABI_TAG_FREEBSD:
21655 osname = "FreeBSD";
21656 break;
21657 case GNU_ABI_TAG_NETBSD:
21658 osname = "NetBSD";
21659 break;
14ae95f2
RM
21660 case GNU_ABI_TAG_SYLLABLE:
21661 osname = "Syllable";
21662 break;
21663 case GNU_ABI_TAG_NACL:
21664 osname = "NaCl";
21665 break;
664f90a3
TT
21666 default:
21667 osname = "Unknown";
21668 break;
21669 }
21670
26c527e6 21671 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21672 major, minor, subminor);
21673 }
21674 break;
926c5385
CC
21675
21676 case NT_GNU_GOLD_VERSION:
21677 {
26c527e6 21678 size_t i;
926c5385
CC
21679
21680 printf (_(" Version: "));
21681 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21682 printf ("%c", pnote->descdata[i]);
21683 printf ("\n");
21684 }
21685 break;
1449284b
NC
21686
21687 case NT_GNU_HWCAP:
21688 {
26c527e6 21689 unsigned int num_entries, mask;
1449284b
NC
21690
21691 /* Hardware capabilities information. Word 0 is the number of entries.
21692 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21693 is a series of entries, where each entry is a single byte followed
21694 by a nul terminated string. The byte gives the bit number to test
21695 if enabled in the bitmask. */
21696 printf (_(" Hardware Capabilities: "));
21697 if (pnote->descsz < 8)
21698 {
32ec8896 21699 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21700 return false;
1449284b
NC
21701 }
21702 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21703 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21704 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21705 /* FIXME: Add code to display the entries... */
21706 }
21707 break;
21708
9ef920e9 21709 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21710 print_gnu_property_note (filedata, pnote);
9ef920e9 21711 break;
9abca702 21712
1449284b
NC
21713 default:
21714 /* Handle unrecognised types. An error message should have already been
21715 created by get_gnu_elf_note_type(), so all that we need to do is to
21716 display the data. */
21717 {
26c527e6 21718 size_t i;
1449284b
NC
21719
21720 printf (_(" Description data: "));
21721 for (i = 0; i < pnote->descsz; ++i)
21722 printf ("%02x ", pnote->descdata[i] & 0xff);
21723 printf ("\n");
21724 }
21725 break;
664f90a3
TT
21726 }
21727
015dc7e1 21728 return true;
664f90a3
TT
21729}
21730
685080f2
NC
21731static const char *
21732get_v850_elf_note_type (enum v850_notes n_type)
21733{
21734 static char buff[64];
21735
21736 switch (n_type)
21737 {
21738 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21739 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21740 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21741 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21742 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21743 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21744 default:
21745 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21746 return buff;
21747 }
21748}
21749
015dc7e1 21750static bool
685080f2
NC
21751print_v850_note (Elf_Internal_Note * pnote)
21752{
21753 unsigned int val;
21754
21755 if (pnote->descsz != 4)
015dc7e1 21756 return false;
32ec8896 21757
685080f2
NC
21758 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21759
21760 if (val == 0)
21761 {
21762 printf (_("not set\n"));
015dc7e1 21763 return true;
685080f2
NC
21764 }
21765
21766 switch (pnote->type)
21767 {
21768 case V850_NOTE_ALIGNMENT:
21769 switch (val)
21770 {
015dc7e1
AM
21771 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21772 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21773 }
21774 break;
14ae95f2 21775
685080f2
NC
21776 case V850_NOTE_DATA_SIZE:
21777 switch (val)
21778 {
015dc7e1
AM
21779 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21780 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21781 }
21782 break;
14ae95f2 21783
685080f2
NC
21784 case V850_NOTE_FPU_INFO:
21785 switch (val)
21786 {
015dc7e1
AM
21787 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21788 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21789 }
21790 break;
14ae95f2 21791
685080f2
NC
21792 case V850_NOTE_MMU_INFO:
21793 case V850_NOTE_CACHE_INFO:
21794 case V850_NOTE_SIMD_INFO:
21795 if (val == EF_RH850_SIMD)
21796 {
21797 printf (_("yes\n"));
015dc7e1 21798 return true;
685080f2
NC
21799 }
21800 break;
21801
21802 default:
21803 /* An 'unknown note type' message will already have been displayed. */
21804 break;
21805 }
21806
21807 printf (_("unknown value: %x\n"), val);
015dc7e1 21808 return false;
685080f2
NC
21809}
21810
015dc7e1 21811static bool
c6056a74
SF
21812process_netbsd_elf_note (Elf_Internal_Note * pnote)
21813{
21814 unsigned int version;
21815
21816 switch (pnote->type)
21817 {
21818 case NT_NETBSD_IDENT:
b966f55f
AM
21819 if (pnote->descsz < 1)
21820 break;
c6056a74
SF
21821 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21822 if ((version / 10000) % 100)
b966f55f 21823 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21824 version, version / 100000000, (version / 1000000) % 100,
21825 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21826 'A' + (version / 10000) % 26);
c6056a74
SF
21827 else
21828 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21829 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21830 (version / 100) % 100);
015dc7e1 21831 return true;
c6056a74
SF
21832
21833 case NT_NETBSD_MARCH:
9abca702 21834 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21835 pnote->descdata);
015dc7e1 21836 return true;
c6056a74 21837
9abca702 21838 case NT_NETBSD_PAX:
b966f55f
AM
21839 if (pnote->descsz < 1)
21840 break;
9abca702
CZ
21841 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21842 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21843 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21844 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21845 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21846 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21847 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21848 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21849 return true;
c6056a74 21850 }
b966f55f
AM
21851
21852 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21853 pnote->descsz, pnote->type);
015dc7e1 21854 return false;
c6056a74
SF
21855}
21856
f4ddf30f 21857static const char *
dda8d76d 21858get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21859{
f4ddf30f
JB
21860 switch (e_type)
21861 {
21862 case NT_FREEBSD_THRMISC:
21863 return _("NT_THRMISC (thrmisc structure)");
21864 case NT_FREEBSD_PROCSTAT_PROC:
21865 return _("NT_PROCSTAT_PROC (proc data)");
21866 case NT_FREEBSD_PROCSTAT_FILES:
21867 return _("NT_PROCSTAT_FILES (files data)");
21868 case NT_FREEBSD_PROCSTAT_VMMAP:
21869 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21870 case NT_FREEBSD_PROCSTAT_GROUPS:
21871 return _("NT_PROCSTAT_GROUPS (groups data)");
21872 case NT_FREEBSD_PROCSTAT_UMASK:
21873 return _("NT_PROCSTAT_UMASK (umask data)");
21874 case NT_FREEBSD_PROCSTAT_RLIMIT:
21875 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21876 case NT_FREEBSD_PROCSTAT_OSREL:
21877 return _("NT_PROCSTAT_OSREL (osreldate data)");
21878 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21879 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21880 case NT_FREEBSD_PROCSTAT_AUXV:
21881 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21882 case NT_FREEBSD_PTLWPINFO:
21883 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21884 case NT_FREEBSD_X86_SEGBASES:
21885 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21886 }
dda8d76d 21887 return get_note_type (filedata, e_type);
f4ddf30f
JB
21888}
21889
9437c45b 21890static const char *
dda8d76d 21891get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21892{
21893 static char buff[64];
21894
540e6170
CZ
21895 switch (e_type)
21896 {
21897 case NT_NETBSDCORE_PROCINFO:
21898 /* NetBSD core "procinfo" structure. */
21899 return _("NetBSD procinfo structure");
9437c45b 21900
540e6170
CZ
21901 case NT_NETBSDCORE_AUXV:
21902 return _("NetBSD ELF auxiliary vector data");
9437c45b 21903
06d949ec
KR
21904 case NT_NETBSDCORE_LWPSTATUS:
21905 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21906
540e6170 21907 default:
06d949ec 21908 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21909 defined for NetBSD core files. If the note type is less
21910 than the start of the machine-dependent note types, we don't
21911 understand it. */
21912
21913 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21914 {
21915 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21916 return buff;
21917 }
21918 break;
9437c45b
JT
21919 }
21920
dda8d76d 21921 switch (filedata->file_header.e_machine)
9437c45b
JT
21922 {
21923 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21924 and PT_GETFPREGS == mach+2. */
21925
21926 case EM_OLD_ALPHA:
21927 case EM_ALPHA:
21928 case EM_SPARC:
21929 case EM_SPARC32PLUS:
21930 case EM_SPARCV9:
21931 switch (e_type)
21932 {
2b692964 21933 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21934 return _("PT_GETREGS (reg structure)");
2b692964 21935 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21936 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21937 default:
21938 break;
21939 }
21940 break;
21941
c0d38b0e
CZ
21942 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21943 There's also old PT___GETREGS40 == mach + 1 for old reg
21944 structure which lacks GBR. */
21945 case EM_SH:
21946 switch (e_type)
21947 {
21948 case NT_NETBSDCORE_FIRSTMACH + 1:
21949 return _("PT___GETREGS40 (old reg structure)");
21950 case NT_NETBSDCORE_FIRSTMACH + 3:
21951 return _("PT_GETREGS (reg structure)");
21952 case NT_NETBSDCORE_FIRSTMACH + 5:
21953 return _("PT_GETFPREGS (fpreg structure)");
21954 default:
21955 break;
21956 }
21957 break;
21958
9437c45b
JT
21959 /* On all other arch's, PT_GETREGS == mach+1 and
21960 PT_GETFPREGS == mach+3. */
21961 default:
21962 switch (e_type)
21963 {
2b692964 21964 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21965 return _("PT_GETREGS (reg structure)");
2b692964 21966 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21967 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21968 default:
21969 break;
21970 }
21971 }
21972
9cf03b7e 21973 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21974 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21975 return buff;
21976}
21977
98ca73af
FC
21978static const char *
21979get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21980{
21981 switch (e_type)
21982 {
21983 case NT_OPENBSD_PROCINFO:
21984 return _("OpenBSD procinfo structure");
21985 case NT_OPENBSD_AUXV:
21986 return _("OpenBSD ELF auxiliary vector data");
21987 case NT_OPENBSD_REGS:
21988 return _("OpenBSD regular registers");
21989 case NT_OPENBSD_FPREGS:
21990 return _("OpenBSD floating point registers");
21991 case NT_OPENBSD_WCOOKIE:
21992 return _("OpenBSD window cookie");
21993 }
21994
21995 return get_note_type (filedata, e_type);
21996}
21997
e263a66b
CC
21998static const char *
21999get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
22000{
22001 switch (e_type)
22002 {
22003 case QNT_DEBUG_FULLPATH:
22004 return _("QNX debug fullpath");
22005 case QNT_DEBUG_RELOC:
22006 return _("QNX debug relocation");
22007 case QNT_STACK:
22008 return _("QNX stack");
22009 case QNT_GENERATOR:
22010 return _("QNX generator");
22011 case QNT_DEFAULT_LIB:
22012 return _("QNX default library");
22013 case QNT_CORE_SYSINFO:
22014 return _("QNX core sysinfo");
22015 case QNT_CORE_INFO:
22016 return _("QNX core info");
22017 case QNT_CORE_STATUS:
22018 return _("QNX core status");
22019 case QNT_CORE_GREG:
22020 return _("QNX general registers");
22021 case QNT_CORE_FPREG:
22022 return _("QNX floating point registers");
22023 case QNT_LINK_MAP:
22024 return _("QNX link map");
22025 }
22026
22027 return get_note_type (filedata, e_type);
22028}
22029
70616151
TT
22030static const char *
22031get_stapsdt_note_type (unsigned e_type)
22032{
22033 static char buff[64];
22034
22035 switch (e_type)
22036 {
22037 case NT_STAPSDT:
22038 return _("NT_STAPSDT (SystemTap probe descriptors)");
22039
22040 default:
22041 break;
22042 }
22043
22044 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22045 return buff;
22046}
22047
015dc7e1 22048static bool
c6a9fc58
TT
22049print_stapsdt_note (Elf_Internal_Note *pnote)
22050{
3ca60c57 22051 size_t len, maxlen;
26c527e6 22052 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
22053 char *data = pnote->descdata;
22054 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 22055 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
22056 char *provider, *probe, *arg_fmt;
22057
3ca60c57
NC
22058 if (pnote->descsz < (addr_size * 3))
22059 goto stapdt_note_too_small;
22060
c6a9fc58
TT
22061 pc = byte_get ((unsigned char *) data, addr_size);
22062 data += addr_size;
3ca60c57 22063
c6a9fc58
TT
22064 base_addr = byte_get ((unsigned char *) data, addr_size);
22065 data += addr_size;
3ca60c57 22066
c6a9fc58
TT
22067 semaphore = byte_get ((unsigned char *) data, addr_size);
22068 data += addr_size;
22069
3ca60c57
NC
22070 if (data >= data_end)
22071 goto stapdt_note_too_small;
22072 maxlen = data_end - data;
22073 len = strnlen (data, maxlen);
22074 if (len < maxlen)
22075 {
22076 provider = data;
22077 data += len + 1;
22078 }
22079 else
22080 goto stapdt_note_too_small;
22081
22082 if (data >= data_end)
22083 goto stapdt_note_too_small;
22084 maxlen = data_end - data;
22085 len = strnlen (data, maxlen);
22086 if (len < maxlen)
22087 {
22088 probe = data;
22089 data += len + 1;
22090 }
22091 else
22092 goto stapdt_note_too_small;
9abca702 22093
3ca60c57
NC
22094 if (data >= data_end)
22095 goto stapdt_note_too_small;
22096 maxlen = data_end - data;
22097 len = strnlen (data, maxlen);
22098 if (len < maxlen)
22099 {
22100 arg_fmt = data;
22101 data += len + 1;
22102 }
22103 else
22104 goto stapdt_note_too_small;
c6a9fc58
TT
22105
22106 printf (_(" Provider: %s\n"), provider);
22107 printf (_(" Name: %s\n"), probe);
22108 printf (_(" Location: "));
22109 print_vma (pc, FULL_HEX);
22110 printf (_(", Base: "));
22111 print_vma (base_addr, FULL_HEX);
22112 printf (_(", Semaphore: "));
22113 print_vma (semaphore, FULL_HEX);
9cf03b7e 22114 printf ("\n");
c6a9fc58
TT
22115 printf (_(" Arguments: %s\n"), arg_fmt);
22116
22117 return data == data_end;
3ca60c57
NC
22118
22119 stapdt_note_too_small:
22120 printf (_(" <corrupt - note is too small>\n"));
22121 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 22122 return false;
c6a9fc58
TT
22123}
22124
e5382207
LB
22125static bool
22126print_fdo_note (Elf_Internal_Note * pnote)
22127{
22128 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
22129 {
22130 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22131 return true;
22132 }
762910fb
LB
22133 if (pnote->descsz > 0 && pnote->type == FDO_DLOPEN_METADATA)
22134 {
22135 printf (_(" Dlopen Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22136 return true;
22137 }
e5382207
LB
22138 return false;
22139}
22140
00e98fc7
TG
22141static const char *
22142get_ia64_vms_note_type (unsigned e_type)
22143{
22144 static char buff[64];
22145
22146 switch (e_type)
22147 {
22148 case NT_VMS_MHD:
22149 return _("NT_VMS_MHD (module header)");
22150 case NT_VMS_LNM:
22151 return _("NT_VMS_LNM (language name)");
22152 case NT_VMS_SRC:
22153 return _("NT_VMS_SRC (source files)");
22154 case NT_VMS_TITLE:
9cf03b7e 22155 return "NT_VMS_TITLE";
00e98fc7
TG
22156 case NT_VMS_EIDC:
22157 return _("NT_VMS_EIDC (consistency check)");
22158 case NT_VMS_FPMODE:
22159 return _("NT_VMS_FPMODE (FP mode)");
22160 case NT_VMS_LINKTIME:
9cf03b7e 22161 return "NT_VMS_LINKTIME";
00e98fc7
TG
22162 case NT_VMS_IMGNAM:
22163 return _("NT_VMS_IMGNAM (image name)");
22164 case NT_VMS_IMGID:
22165 return _("NT_VMS_IMGID (image id)");
22166 case NT_VMS_LINKID:
22167 return _("NT_VMS_LINKID (link id)");
22168 case NT_VMS_IMGBID:
22169 return _("NT_VMS_IMGBID (build id)");
22170 case NT_VMS_GSTNAM:
22171 return _("NT_VMS_GSTNAM (sym table name)");
22172 case NT_VMS_ORIG_DYN:
9cf03b7e 22173 return "NT_VMS_ORIG_DYN";
00e98fc7 22174 case NT_VMS_PATCHTIME:
9cf03b7e 22175 return "NT_VMS_PATCHTIME";
00e98fc7
TG
22176 default:
22177 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22178 return buff;
22179 }
22180}
22181
015dc7e1 22182static bool
00e98fc7
TG
22183print_ia64_vms_note (Elf_Internal_Note * pnote)
22184{
26c527e6 22185 unsigned int maxlen = pnote->descsz;
8d18bf79 22186
26c527e6 22187 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
22188 goto desc_size_fail;
22189
00e98fc7
TG
22190 switch (pnote->type)
22191 {
22192 case NT_VMS_MHD:
8d18bf79
NC
22193 if (maxlen <= 36)
22194 goto desc_size_fail;
22195
26c527e6 22196 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
22197
22198 printf (_(" Creation date : %.17s\n"), pnote->descdata);
22199 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
22200 if (l + 34 < maxlen)
22201 {
22202 printf (_(" Module name : %s\n"), pnote->descdata + 34);
22203 if (l + 35 < maxlen)
22204 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
22205 else
22206 printf (_(" Module version : <missing>\n"));
22207 }
00e98fc7 22208 else
8d18bf79
NC
22209 {
22210 printf (_(" Module name : <missing>\n"));
22211 printf (_(" Module version : <missing>\n"));
22212 }
00e98fc7 22213 break;
8d18bf79 22214
00e98fc7 22215 case NT_VMS_LNM:
8d18bf79 22216 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22217 break;
8d18bf79 22218
00e98fc7 22219 case NT_VMS_FPMODE:
9cf03b7e 22220 printf (_(" Floating Point mode: "));
8d18bf79
NC
22221 if (maxlen < 8)
22222 goto desc_size_fail;
22223 /* FIXME: Generate an error if descsz > 8 ? */
22224
b8281767 22225 printf ("0x%016" PRIx64 "\n",
625d49fc 22226 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 22227 break;
8d18bf79 22228
00e98fc7
TG
22229 case NT_VMS_LINKTIME:
22230 printf (_(" Link time: "));
8d18bf79
NC
22231 if (maxlen < 8)
22232 goto desc_size_fail;
22233 /* FIXME: Generate an error if descsz > 8 ? */
22234
0e3c1eeb 22235 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
22236 printf ("\n");
22237 break;
8d18bf79 22238
00e98fc7
TG
22239 case NT_VMS_PATCHTIME:
22240 printf (_(" Patch time: "));
8d18bf79
NC
22241 if (maxlen < 8)
22242 goto desc_size_fail;
22243 /* FIXME: Generate an error if descsz > 8 ? */
22244
0e3c1eeb 22245 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
22246 printf ("\n");
22247 break;
8d18bf79 22248
00e98fc7 22249 case NT_VMS_ORIG_DYN:
8d18bf79
NC
22250 if (maxlen < 34)
22251 goto desc_size_fail;
22252
00e98fc7 22253 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
22254 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
22255 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 22256 printf (_(" Last modified : "));
0e3c1eeb 22257 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 22258 printf (_("\n Link flags : "));
b8281767 22259 printf ("0x%016" PRIx64 "\n",
625d49fc 22260 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 22261 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 22262 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 22263 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 22264 break;
8d18bf79 22265
00e98fc7 22266 case NT_VMS_IMGNAM:
8d18bf79 22267 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22268 break;
8d18bf79 22269
00e98fc7 22270 case NT_VMS_GSTNAM:
8d18bf79 22271 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22272 break;
8d18bf79 22273
00e98fc7 22274 case NT_VMS_IMGID:
8d18bf79 22275 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22276 break;
8d18bf79 22277
00e98fc7 22278 case NT_VMS_LINKID:
8d18bf79 22279 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 22280 break;
8d18bf79 22281
00e98fc7 22282 default:
015dc7e1 22283 return false;
00e98fc7 22284 }
8d18bf79 22285
015dc7e1 22286 return true;
8d18bf79
NC
22287
22288 desc_size_fail:
22289 printf (_(" <corrupt - data size is too small>\n"));
22290 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 22291 return false;
00e98fc7
TG
22292}
22293
fd486f32
AM
22294struct build_attr_cache {
22295 Filedata *filedata;
22296 char *strtab;
26c527e6 22297 uint64_t strtablen;
fd486f32 22298 Elf_Internal_Sym *symtab;
26c527e6 22299 uint64_t nsyms;
fd486f32
AM
22300} ba_cache;
22301
6f156d7a
NC
22302/* Find the symbol associated with a build attribute that is attached
22303 to address OFFSET. If PNAME is non-NULL then store the name of
22304 the symbol (if found) in the provided pointer, Returns NULL if a
22305 symbol could not be found. */
c799a79d 22306
6f156d7a 22307static Elf_Internal_Sym *
015dc7e1 22308get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 22309 uint64_t offset,
015dc7e1
AM
22310 bool is_open_attr,
22311 const char **pname)
9ef920e9 22312{
fd486f32
AM
22313 Elf_Internal_Sym *saved_sym = NULL;
22314 Elf_Internal_Sym *sym;
9ef920e9 22315
dda8d76d 22316 if (filedata->section_headers != NULL
fd486f32 22317 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 22318 {
c799a79d 22319 Elf_Internal_Shdr * symsec;
9ef920e9 22320
fd486f32
AM
22321 free (ba_cache.strtab);
22322 ba_cache.strtab = NULL;
22323 free (ba_cache.symtab);
22324 ba_cache.symtab = NULL;
22325
c799a79d 22326 /* Load the symbol and string sections. */
dda8d76d
NC
22327 for (symsec = filedata->section_headers;
22328 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 22329 symsec ++)
9ef920e9 22330 {
28d13567
AM
22331 if (symsec->sh_type == SHT_SYMTAB
22332 && get_symtab (filedata, symsec,
22333 &ba_cache.symtab, &ba_cache.nsyms,
22334 &ba_cache.strtab, &ba_cache.strtablen))
22335 break;
9ef920e9 22336 }
fd486f32 22337 ba_cache.filedata = filedata;
9ef920e9
NC
22338 }
22339
fd486f32 22340 if (ba_cache.symtab == NULL)
6f156d7a 22341 return NULL;
9ef920e9 22342
c799a79d 22343 /* Find a symbol whose value matches offset. */
fd486f32 22344 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
22345 if (sym->st_value == offset)
22346 {
fd486f32 22347 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
22348 /* Huh ? This should not happen. */
22349 continue;
9ef920e9 22350
fd486f32 22351 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 22352 continue;
9ef920e9 22353
9b9b1092 22354 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 22355 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
22356 if (ba_cache.strtab[sym->st_name] == '$'
22357 && ba_cache.strtab[sym->st_name + 1] != 0
22358 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
22359 continue;
22360
c799a79d
NC
22361 if (is_open_attr)
22362 {
22363 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22364 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22365 FUNC symbols entirely. */
22366 switch (ELF_ST_TYPE (sym->st_info))
22367 {
c799a79d 22368 case STT_OBJECT:
6f156d7a 22369 case STT_FILE:
c799a79d 22370 saved_sym = sym;
6f156d7a
NC
22371 if (sym->st_size)
22372 {
22373 /* If the symbol has a size associated
22374 with it then we can stop searching. */
fd486f32 22375 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 22376 }
c799a79d 22377 continue;
9ef920e9 22378
c799a79d
NC
22379 case STT_FUNC:
22380 /* Ignore function symbols. */
22381 continue;
22382
22383 default:
22384 break;
22385 }
22386
22387 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 22388 {
c799a79d
NC
22389 case STB_GLOBAL:
22390 if (saved_sym == NULL
22391 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22392 saved_sym = sym;
22393 break;
c871dade 22394
c799a79d
NC
22395 case STB_LOCAL:
22396 if (saved_sym == NULL)
22397 saved_sym = sym;
22398 break;
22399
22400 default:
9ef920e9
NC
22401 break;
22402 }
22403 }
c799a79d
NC
22404 else
22405 {
22406 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22407 continue;
22408
22409 saved_sym = sym;
22410 break;
22411 }
22412 }
22413
6f156d7a 22414 if (saved_sym && pname)
fd486f32 22415 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
22416
22417 return saved_sym;
c799a79d
NC
22418}
22419
d20e98ab
NC
22420/* Returns true iff addr1 and addr2 are in the same section. */
22421
015dc7e1 22422static bool
26c527e6 22423same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
22424{
22425 Elf_Internal_Shdr * a1;
22426 Elf_Internal_Shdr * a2;
22427
22428 a1 = find_section_by_address (filedata, addr1);
22429 a2 = find_section_by_address (filedata, addr2);
9abca702 22430
d20e98ab
NC
22431 return a1 == a2 && a1 != NULL;
22432}
22433
015dc7e1 22434static bool
dda8d76d
NC
22435print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22436 Filedata * filedata)
c799a79d 22437{
26c527e6
AM
22438 static uint64_t global_offset = 0;
22439 static uint64_t global_end = 0;
22440 static uint64_t func_offset = 0;
22441 static uint64_t func_end = 0;
c871dade 22442
015dc7e1
AM
22443 Elf_Internal_Sym *sym;
22444 const char *name;
26c527e6
AM
22445 uint64_t start;
22446 uint64_t end;
015dc7e1 22447 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
22448
22449 switch (pnote->descsz)
c799a79d 22450 {
6f156d7a
NC
22451 case 0:
22452 /* A zero-length description means that the range of
22453 the previous note of the same type should be used. */
c799a79d 22454 if (is_open_attr)
c871dade 22455 {
6f156d7a 22456 if (global_end > global_offset)
26c527e6
AM
22457 printf (_(" Applies to region from %#" PRIx64
22458 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 22459 else
26c527e6
AM
22460 printf (_(" Applies to region from %#" PRIx64
22461 "\n"), global_offset);
c799a79d
NC
22462 }
22463 else
22464 {
6f156d7a 22465 if (func_end > func_offset)
26c527e6
AM
22466 printf (_(" Applies to region from %#" PRIx64
22467 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 22468 else
26c527e6
AM
22469 printf (_(" Applies to region from %#" PRIx64
22470 "\n"), func_offset);
c871dade 22471 }
015dc7e1 22472 return true;
9ef920e9 22473
6f156d7a
NC
22474 case 4:
22475 start = byte_get ((unsigned char *) pnote->descdata, 4);
22476 end = 0;
22477 break;
22478
22479 case 8:
c74147bb
NC
22480 start = byte_get ((unsigned char *) pnote->descdata, 4);
22481 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
22482 break;
22483
22484 case 16:
22485 start = byte_get ((unsigned char *) pnote->descdata, 8);
22486 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22487 break;
9abca702 22488
6f156d7a 22489 default:
c799a79d
NC
22490 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22491 printf (_(" <invalid descsz>"));
015dc7e1 22492 return false;
c799a79d
NC
22493 }
22494
6f156d7a
NC
22495 name = NULL;
22496 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
22497 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22498 in order to avoid them being confused with the start address of the
22499 first function in the file... */
22500 if (sym == NULL && is_open_attr)
22501 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22502 & name);
6f156d7a
NC
22503
22504 if (end == 0 && sym != NULL && sym->st_size > 0)
22505 end = start + sym->st_size;
c799a79d
NC
22506
22507 if (is_open_attr)
22508 {
d20e98ab
NC
22509 /* FIXME: Need to properly allow for section alignment.
22510 16 is just the alignment used on x86_64. */
22511 if (global_end > 0
22512 && start > BFD_ALIGN (global_end, 16)
22513 /* Build notes are not guaranteed to be organised in order of
22514 increasing address, but we should find the all of the notes
22515 for one section in the same place. */
22516 && same_section (filedata, start, global_end))
26c527e6
AM
22517 warn (_("Gap in build notes detected from %#" PRIx64
22518 " to %#" PRIx64 "\n"),
6f156d7a
NC
22519 global_end + 1, start - 1);
22520
26c527e6 22521 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22522 global_offset = start;
22523
22524 if (end)
22525 {
26c527e6 22526 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22527 global_end = end;
22528 }
c799a79d
NC
22529 }
22530 else
22531 {
26c527e6 22532 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22533 func_offset = start;
22534
22535 if (end)
22536 {
26c527e6 22537 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22538 func_end = end;
22539 }
c799a79d
NC
22540 }
22541
6f156d7a
NC
22542 if (sym && name)
22543 printf (_(" (%s)"), name);
22544
22545 printf ("\n");
015dc7e1 22546 return true;
9ef920e9
NC
22547}
22548
015dc7e1 22549static bool
9ef920e9
NC
22550print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22551{
1d15e434
NC
22552 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22553 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22554 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
22555 char name_type;
22556 char name_attribute;
1d15e434 22557 const char * expected_types;
9ef920e9
NC
22558 const char * name = pnote->namedata;
22559 const char * text;
88305e1b 22560 signed int left;
9ef920e9
NC
22561
22562 if (name == NULL || pnote->namesz < 2)
22563 {
22564 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22565 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22566 return false;
9ef920e9
NC
22567 }
22568
6f156d7a
NC
22569 if (do_wide)
22570 left = 28;
22571 else
22572 left = 20;
88305e1b
NC
22573
22574 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22575 if (name[0] == 'G' && name[1] == 'A')
22576 {
6f156d7a
NC
22577 if (pnote->namesz < 4)
22578 {
22579 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22580 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22581 return false;
6f156d7a
NC
22582 }
22583
88305e1b
NC
22584 printf ("GA");
22585 name += 2;
22586 left -= 2;
22587 }
22588
9ef920e9
NC
22589 switch ((name_type = * name))
22590 {
22591 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22592 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22593 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22594 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22595 printf ("%c", * name);
88305e1b 22596 left --;
9ef920e9
NC
22597 break;
22598 default:
22599 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 22600 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 22601 return false;
9ef920e9
NC
22602 }
22603
9ef920e9
NC
22604 ++ name;
22605 text = NULL;
22606
22607 switch ((name_attribute = * name))
22608 {
22609 case GNU_BUILD_ATTRIBUTE_VERSION:
22610 text = _("<version>");
1d15e434 22611 expected_types = string_expected;
9ef920e9
NC
22612 ++ name;
22613 break;
22614 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22615 text = _("<stack prot>");
75d7d298 22616 expected_types = "!+*";
9ef920e9
NC
22617 ++ name;
22618 break;
22619 case GNU_BUILD_ATTRIBUTE_RELRO:
22620 text = _("<relro>");
1d15e434 22621 expected_types = bool_expected;
9ef920e9
NC
22622 ++ name;
22623 break;
22624 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22625 text = _("<stack size>");
1d15e434 22626 expected_types = number_expected;
9ef920e9
NC
22627 ++ name;
22628 break;
22629 case GNU_BUILD_ATTRIBUTE_TOOL:
22630 text = _("<tool>");
1d15e434 22631 expected_types = string_expected;
9ef920e9
NC
22632 ++ name;
22633 break;
22634 case GNU_BUILD_ATTRIBUTE_ABI:
22635 text = _("<ABI>");
22636 expected_types = "$*";
22637 ++ name;
22638 break;
22639 case GNU_BUILD_ATTRIBUTE_PIC:
22640 text = _("<PIC>");
1d15e434 22641 expected_types = number_expected;
9ef920e9
NC
22642 ++ name;
22643 break;
a8be5506
NC
22644 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22645 text = _("<short enum>");
1d15e434 22646 expected_types = bool_expected;
a8be5506
NC
22647 ++ name;
22648 break;
9ef920e9
NC
22649 default:
22650 if (ISPRINT (* name))
22651 {
22652 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22653
22654 if (len > left && ! do_wide)
22655 len = left;
75d7d298 22656 printf ("%.*s:", len, name);
9ef920e9 22657 left -= len;
0dd6ae21 22658 name += len;
9ef920e9
NC
22659 }
22660 else
22661 {
3e6b6445 22662 static char tmpbuf [128];
88305e1b 22663
3e6b6445
NC
22664 error (_("unrecognised byte in name field: %d\n"), * name);
22665 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22666 text = tmpbuf;
22667 name ++;
9ef920e9
NC
22668 }
22669 expected_types = "*$!+";
22670 break;
22671 }
22672
22673 if (text)
88305e1b 22674 left -= printf ("%s", text);
9ef920e9
NC
22675
22676 if (strchr (expected_types, name_type) == NULL)
75d7d298 22677 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22678
26c527e6 22679 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22680 {
26c527e6
AM
22681 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22682 pnote->namesz,
22683 name - pnote->namedata);
015dc7e1 22684 return false;
9ef920e9
NC
22685 }
22686
22687 if (left < 1 && ! do_wide)
015dc7e1 22688 return true;
9ef920e9
NC
22689
22690 switch (name_type)
22691 {
22692 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22693 {
26c527e6
AM
22694 unsigned int bytes;
22695 uint64_t val = 0;
22696 unsigned int shift = 0;
22697 char *decoded = NULL;
ddef72cd 22698
b06b2c92
NC
22699 bytes = pnote->namesz - (name - pnote->namedata);
22700 if (bytes > 0)
22701 /* The -1 is because the name field is always 0 terminated, and we
22702 want to be able to ensure that the shift in the while loop below
22703 will not overflow. */
22704 -- bytes;
22705
ddef72cd
NC
22706 if (bytes > sizeof (val))
22707 {
3e6b6445
NC
22708 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22709 bytes);
22710 bytes = sizeof (val);
ddef72cd 22711 }
3e6b6445
NC
22712 /* We do not bother to warn if bytes == 0 as this can
22713 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22714
22715 while (bytes --)
22716 {
26c527e6 22717 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22718
22719 val |= byte << shift;
9ef920e9
NC
22720 shift += 8;
22721 }
22722
75d7d298 22723 switch (name_attribute)
9ef920e9 22724 {
75d7d298 22725 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22726 switch (val)
22727 {
75d7d298
NC
22728 case 0: decoded = "static"; break;
22729 case 1: decoded = "pic"; break;
22730 case 2: decoded = "PIC"; break;
22731 case 3: decoded = "pie"; break;
22732 case 4: decoded = "PIE"; break;
22733 default: break;
9ef920e9 22734 }
75d7d298
NC
22735 break;
22736 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22737 switch (val)
9ef920e9 22738 {
75d7d298
NC
22739 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22740 case 0: decoded = "off"; break;
22741 case 1: decoded = "on"; break;
22742 case 2: decoded = "all"; break;
22743 case 3: decoded = "strong"; break;
22744 case 4: decoded = "explicit"; break;
22745 default: break;
9ef920e9 22746 }
75d7d298
NC
22747 break;
22748 default:
22749 break;
9ef920e9
NC
22750 }
22751
75d7d298 22752 if (decoded != NULL)
3e6b6445 22753 {
b6ac461a 22754 print_symbol_name (-left, decoded);
3e6b6445
NC
22755 left = 0;
22756 }
22757 else if (val == 0)
22758 {
22759 printf ("0x0");
22760 left -= 3;
22761 }
9ef920e9 22762 else
75d7d298
NC
22763 {
22764 if (do_wide)
26c527e6 22765 left -= printf ("0x%" PRIx64, val);
75d7d298 22766 else
26c527e6 22767 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22768 }
9ef920e9
NC
22769 }
22770 break;
22771 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22772 left -= print_symbol_name (- left, name);
9ef920e9
NC
22773 break;
22774 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22775 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22776 break;
22777 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22778 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22779 break;
22780 }
22781
22782 if (do_wide && left > 0)
22783 printf ("%-*s", left, " ");
9abca702 22784
015dc7e1 22785 return true;
9ef920e9
NC
22786}
22787
2952f10c
SM
22788/* Print the contents of PNOTE as hex. */
22789
22790static void
22791print_note_contents_hex (Elf_Internal_Note *pnote)
22792{
22793 if (pnote->descsz)
22794 {
26c527e6 22795 size_t i;
2952f10c
SM
22796
22797 printf (_(" description data: "));
22798 for (i = 0; i < pnote->descsz; i++)
22799 printf ("%02x ", pnote->descdata[i] & 0xff);
22800 if (!do_wide)
22801 printf ("\n");
22802 }
22803
22804 if (do_wide)
22805 printf ("\n");
22806}
22807
22808#if defined HAVE_MSGPACK
22809
22810static void
22811print_indents (int n)
22812{
22813 printf (" ");
22814
22815 for (int i = 0; i < n; i++)
22816 printf (" ");
22817}
22818
22819/* Print OBJ in human-readable form. */
22820
22821static void
22822dump_msgpack_obj (const msgpack_object *obj, int indent)
22823{
22824 switch (obj->type)
22825 {
22826 case MSGPACK_OBJECT_NIL:
22827 printf ("(nil)");
22828 break;
22829
22830 case MSGPACK_OBJECT_BOOLEAN:
22831 printf ("%s", obj->via.boolean ? "true" : "false");
22832 break;
22833
22834 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22835 printf ("%" PRIu64, obj->via.u64);
22836 break;
22837
22838 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22839 printf ("%" PRIi64, obj->via.i64);
22840 break;
22841
22842 case MSGPACK_OBJECT_FLOAT32:
22843 case MSGPACK_OBJECT_FLOAT64:
22844 printf ("%f", obj->via.f64);
22845 break;
22846
22847 case MSGPACK_OBJECT_STR:
22848 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22849 break;
22850
22851 case MSGPACK_OBJECT_ARRAY:
22852 {
22853 const msgpack_object_array *array = &obj->via.array;
22854
22855 printf ("[\n");
22856 ++indent;
22857
22858 for (uint32_t i = 0; i < array->size; ++i)
22859 {
22860 const msgpack_object *item = &array->ptr[i];
22861
22862 print_indents (indent);
22863 dump_msgpack_obj (item, indent);
22864 printf (",\n");
22865 }
22866
22867 --indent;
22868 print_indents (indent);
22869 printf ("]");
22870 break;
22871 }
22872 break;
22873
22874 case MSGPACK_OBJECT_MAP:
22875 {
22876 const msgpack_object_map *map = &obj->via.map;
22877
22878 printf ("{\n");
22879 ++indent;
22880
22881 for (uint32_t i = 0; i < map->size; ++i)
22882 {
22883 const msgpack_object_kv *kv = &map->ptr[i];
22884 const msgpack_object *key = &kv->key;
22885 const msgpack_object *val = &kv->val;
22886
22887 print_indents (indent);
22888 dump_msgpack_obj (key, indent);
22889 printf (": ");
22890 dump_msgpack_obj (val, indent);
22891
22892 printf (",\n");
22893 }
22894
22895 --indent;
22896 print_indents (indent);
22897 printf ("}");
22898
22899 break;
22900 }
22901
22902 case MSGPACK_OBJECT_BIN:
22903 printf ("(bin)");
22904 break;
22905
22906 case MSGPACK_OBJECT_EXT:
22907 printf ("(ext)");
22908 break;
22909 }
22910}
22911
22912static void
22913dump_msgpack (const msgpack_unpacked *msg)
22914{
22915 print_indents (0);
22916 dump_msgpack_obj (&msg->data, 0);
22917 printf ("\n");
22918}
22919
22920#endif /* defined HAVE_MSGPACK */
22921
22922static bool
22923print_amdgpu_note (Elf_Internal_Note *pnote)
22924{
22925#if defined HAVE_MSGPACK
22926 /* If msgpack is available, decode and dump the note's content. */
22927 bool ret;
22928 msgpack_unpacked msg;
22929 msgpack_unpack_return msgpack_ret;
22930
22931 assert (pnote->type == NT_AMDGPU_METADATA);
22932
22933 msgpack_unpacked_init (&msg);
22934 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22935 NULL);
22936
22937 switch (msgpack_ret)
22938 {
22939 case MSGPACK_UNPACK_SUCCESS:
22940 dump_msgpack (&msg);
22941 ret = true;
22942 break;
22943
22944 default:
22945 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22946 ret = false;
22947 break;
22948 }
22949
22950 msgpack_unpacked_destroy (&msg);
22951 return ret;
22952#else
22953 /* msgpack is not available, dump contents as hex. */
22954 print_note_contents_hex (pnote);
22955 return true;
22956#endif
22957}
22958
e263a66b
CC
22959static bool
22960print_qnx_note (Elf_Internal_Note *pnote)
22961{
22962 switch (pnote->type)
22963 {
22964 case QNT_STACK:
22965 if (pnote->descsz != 12)
22966 goto desc_size_fail;
22967
22968 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22969 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22970 printf (_(" Stack allocated: %" PRIx32 "\n"),
22971 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22972 printf (_(" Executable: %s\n"),
22973 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22974 break;
22975
22976 default:
22977 print_note_contents_hex(pnote);
22978 }
22979 return true;
22980
22981desc_size_fail:
22982 printf (_(" <corrupt - data size is too small>\n"));
22983 error (_("corrupt QNX note: data size is too small\n"));
22984 return false;
22985}
22986
22987
6d118b09
NC
22988/* Note that by the ELF standard, the name field is already null byte
22989 terminated, and namesz includes the terminating null byte.
22990 I.E. the value of namesz for the name "FSF" is 4.
22991
e3c8793a 22992 If the value of namesz is zero, there is no name present. */
9ef920e9 22993
015dc7e1 22994static bool
9ef920e9 22995process_note (Elf_Internal_Note * pnote,
dda8d76d 22996 Filedata * filedata)
779fe533 22997{
2cf0635d
NC
22998 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22999 const char * nt;
9437c45b
JT
23000
23001 if (pnote->namesz == 0)
1ec5cd37
NC
23002 /* If there is no note name, then use the default set of
23003 note type strings. */
dda8d76d 23004 nt = get_note_type (filedata, pnote->type);
1ec5cd37 23005
24d127aa 23006 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
23007 /* GNU-specific object file notes. */
23008 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 23009
28cdbb18
SM
23010 else if (startswith (pnote->namedata, "AMDGPU"))
23011 /* AMDGPU-specific object file notes. */
23012 nt = get_amdgpu_elf_note_type (pnote->type);
23013
24d127aa 23014 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 23015 /* FreeBSD-specific core file notes. */
dda8d76d 23016 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 23017
24d127aa 23018 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 23019 /* NetBSD-specific core file notes. */
dda8d76d 23020 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 23021
24d127aa 23022 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
23023 /* NetBSD-specific core file notes. */
23024 return process_netbsd_elf_note (pnote);
23025
24d127aa 23026 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
23027 /* NetBSD-specific core file notes. */
23028 return process_netbsd_elf_note (pnote);
23029
98ca73af
FC
23030 else if (startswith (pnote->namedata, "OpenBSD"))
23031 /* OpenBSD-specific core file notes. */
23032 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
23033
e263a66b
CC
23034 else if (startswith (pnote->namedata, "QNX"))
23035 /* QNX-specific core file notes. */
23036 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
23037
e9b095a5 23038 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
23039 {
23040 /* SPU-specific core file notes. */
23041 nt = pnote->namedata + 4;
23042 name = "SPU";
23043 }
23044
24d127aa 23045 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
23046 /* VMS/ia64-specific file notes. */
23047 nt = get_ia64_vms_note_type (pnote->type);
23048
24d127aa 23049 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
23050 nt = get_stapsdt_note_type (pnote->type);
23051
9437c45b 23052 else
1ec5cd37
NC
23053 /* Don't recognize this note name; just use the default set of
23054 note type strings. */
dda8d76d 23055 nt = get_note_type (filedata, pnote->type);
9437c45b 23056
1449284b 23057 printf (" ");
9ef920e9 23058
24d127aa 23059 if (((startswith (pnote->namedata, "GA")
483767a3
AM
23060 && strchr ("*$!+", pnote->namedata[2]) != NULL)
23061 || strchr ("*$!+", pnote->namedata[0]) != NULL)
23062 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
23063 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
23064 print_gnu_build_attribute_name (pnote);
23065 else
b6ac461a 23066 print_symbol_name (-20, name);
9ef920e9
NC
23067
23068 if (do_wide)
23069 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
23070 else
23071 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 23072
24d127aa 23073 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 23074 return print_ia64_vms_note (pnote);
24d127aa 23075 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 23076 return print_gnu_note (filedata, pnote);
24d127aa 23077 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 23078 return print_stapsdt_note (pnote);
24d127aa 23079 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 23080 return print_core_note (pnote);
e5382207
LB
23081 else if (startswith (pnote->namedata, "FDO"))
23082 return print_fdo_note (pnote);
24d127aa 23083 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
23084 && strchr ("*$!+", pnote->namedata[2]) != NULL)
23085 || strchr ("*$!+", pnote->namedata[0]) != NULL)
23086 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
23087 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 23088 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
23089 else if (startswith (pnote->namedata, "AMDGPU")
23090 && pnote->type == NT_AMDGPU_METADATA)
23091 return print_amdgpu_note (pnote);
e263a66b
CC
23092 else if (startswith (pnote->namedata, "QNX"))
23093 return print_qnx_note (pnote);
779fe533 23094
2952f10c 23095 print_note_contents_hex (pnote);
015dc7e1 23096 return true;
1449284b 23097}
6d118b09 23098
015dc7e1 23099static bool
dda8d76d
NC
23100process_notes_at (Filedata * filedata,
23101 Elf_Internal_Shdr * section,
625d49fc
AM
23102 uint64_t offset,
23103 uint64_t length,
23104 uint64_t align)
779fe533 23105{
015dc7e1
AM
23106 Elf_External_Note *pnotes;
23107 Elf_External_Note *external;
23108 char *end;
23109 bool res = true;
103f02d3 23110
779fe533 23111 if (length <= 0)
015dc7e1 23112 return false;
103f02d3 23113
1449284b
NC
23114 if (section)
23115 {
dda8d76d 23116 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 23117 if (pnotes)
32ec8896 23118 {
dda8d76d 23119 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
23120 {
23121 free (pnotes);
015dc7e1 23122 return false;
f761cb13 23123 }
32ec8896 23124 }
1449284b
NC
23125 }
23126 else
82ed9683 23127 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 23128 _("notes"));
4dff97b2 23129
dd24e3da 23130 if (pnotes == NULL)
015dc7e1 23131 return false;
779fe533 23132
103f02d3 23133 external = pnotes;
103f02d3 23134
ca0e11aa
NC
23135 if (filedata->is_separate)
23136 printf (_("In linked file '%s': "), filedata->file_name);
23137 else
23138 printf ("\n");
1449284b 23139 if (section)
ca0e11aa 23140 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 23141 else
26c527e6
AM
23142 printf (_("Displaying notes found at file offset 0x%08" PRIx64
23143 " with length 0x%08" PRIx64 ":\n"),
23144 offset, length);
1449284b 23145
82ed9683
L
23146 /* NB: Some note sections may have alignment value of 0 or 1. gABI
23147 specifies that notes should be aligned to 4 bytes in 32-bit
23148 objects and to 8 bytes in 64-bit objects. As a Linux extension,
23149 we also support 4 byte alignment in 64-bit objects. If section
23150 alignment is less than 4, we treate alignment as 4 bytes. */
23151 if (align < 4)
23152 align = 4;
23153 else if (align != 4 && align != 8)
23154 {
26c527e6
AM
23155 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
23156 align);
a788aedd 23157 free (pnotes);
015dc7e1 23158 return false;
82ed9683
L
23159 }
23160
dbe15e4e 23161 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 23162
c8071705
NC
23163 end = (char *) pnotes + length;
23164 while ((char *) external < end)
779fe533 23165 {
b34976b6 23166 Elf_Internal_Note inote;
15b42fb0 23167 size_t min_notesz;
4dff97b2 23168 char * next;
2cf0635d 23169 char * temp = NULL;
c8071705 23170 size_t data_remaining = end - (char *) external;
6d118b09 23171
dda8d76d 23172 if (!is_ia64_vms (filedata))
15b42fb0 23173 {
9dd3a467
NC
23174 /* PR binutils/15191
23175 Make sure that there is enough data to read. */
15b42fb0
AM
23176 min_notesz = offsetof (Elf_External_Note, name);
23177 if (data_remaining < min_notesz)
9dd3a467 23178 {
26c527e6 23179 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 23180 "not enough for a full note\n",
26c527e6 23181 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
23182 "not enough for a full note\n",
23183 data_remaining),
26c527e6 23184 data_remaining);
9dd3a467
NC
23185 break;
23186 }
5396a86e
AM
23187 data_remaining -= min_notesz;
23188
15b42fb0
AM
23189 inote.type = BYTE_GET (external->type);
23190 inote.namesz = BYTE_GET (external->namesz);
23191 inote.namedata = external->name;
23192 inote.descsz = BYTE_GET (external->descsz);
276da9b3 23193 inote.descdata = ((char *) external
4dff97b2 23194 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 23195 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 23196 next = ((char *) external
4dff97b2 23197 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 23198 }
00e98fc7 23199 else
15b42fb0
AM
23200 {
23201 Elf64_External_VMS_Note *vms_external;
00e98fc7 23202
9dd3a467
NC
23203 /* PR binutils/15191
23204 Make sure that there is enough data to read. */
15b42fb0
AM
23205 min_notesz = offsetof (Elf64_External_VMS_Note, name);
23206 if (data_remaining < min_notesz)
9dd3a467 23207 {
26c527e6 23208 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 23209 "not enough for a full note\n",
26c527e6 23210 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
23211 "not enough for a full note\n",
23212 data_remaining),
26c527e6 23213 data_remaining);
9dd3a467
NC
23214 break;
23215 }
5396a86e 23216 data_remaining -= min_notesz;
3e55a963 23217
15b42fb0
AM
23218 vms_external = (Elf64_External_VMS_Note *) external;
23219 inote.type = BYTE_GET (vms_external->type);
23220 inote.namesz = BYTE_GET (vms_external->namesz);
23221 inote.namedata = vms_external->name;
23222 inote.descsz = BYTE_GET (vms_external->descsz);
23223 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
23224 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23225 next = inote.descdata + align_power (inote.descsz, 3);
23226 }
23227
5396a86e
AM
23228 /* PR 17531: file: 3443835e. */
23229 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
23230 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
23231 || (size_t) (inote.descdata - inote.namedata) > data_remaining
23232 || (size_t) (next - inote.descdata) < inote.descsz
23233 || ((size_t) (next - inote.descdata)
23234 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 23235 {
26c527e6
AM
23236 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
23237 (char *) external - (char *) pnotes);
23238 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 23239 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
23240 break;
23241 }
23242
15b42fb0 23243 external = (Elf_External_Note *) next;
dd24e3da 23244
6d118b09
NC
23245 /* Verify that name is null terminated. It appears that at least
23246 one version of Linux (RedHat 6.0) generates corefiles that don't
23247 comply with the ELF spec by failing to include the null byte in
23248 namesz. */
18344509 23249 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 23250 {
5396a86e 23251 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 23252 {
5396a86e
AM
23253 temp = (char *) malloc (inote.namesz + 1);
23254 if (temp == NULL)
23255 {
23256 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 23257 res = false;
5396a86e
AM
23258 break;
23259 }
76da6bbe 23260
5396a86e
AM
23261 memcpy (temp, inote.namedata, inote.namesz);
23262 inote.namedata = temp;
23263 }
23264 inote.namedata[inote.namesz] = 0;
6d118b09
NC
23265 }
23266
dda8d76d 23267 if (! process_note (& inote, filedata))
015dc7e1 23268 res = false;
103f02d3 23269
9db70fc3
AM
23270 free (temp);
23271 temp = NULL;
779fe533
NC
23272 }
23273
23274 free (pnotes);
103f02d3 23275
779fe533
NC
23276 return res;
23277}
23278
015dc7e1 23279static bool
dda8d76d 23280process_corefile_note_segments (Filedata * filedata)
779fe533 23281{
015dc7e1 23282 Elf_Internal_Phdr *segment;
b34976b6 23283 unsigned int i;
015dc7e1 23284 bool res = true;
103f02d3 23285
dda8d76d 23286 if (! get_program_headers (filedata))
015dc7e1 23287 return true;
103f02d3 23288
dda8d76d
NC
23289 for (i = 0, segment = filedata->program_headers;
23290 i < filedata->file_header.e_phnum;
b34976b6 23291 i++, segment++)
779fe533
NC
23292 {
23293 if (segment->p_type == PT_NOTE)
625d49fc
AM
23294 if (! process_notes_at (filedata, NULL, segment->p_offset,
23295 segment->p_filesz, segment->p_align))
015dc7e1 23296 res = false;
779fe533 23297 }
103f02d3 23298
779fe533
NC
23299 return res;
23300}
23301
015dc7e1 23302static bool
625d49fc 23303process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
23304{
23305 Elf_External_Note * pnotes;
23306 Elf_External_Note * external;
c8071705 23307 char * end;
015dc7e1 23308 bool res = true;
685080f2
NC
23309
23310 if (length <= 0)
015dc7e1 23311 return false;
685080f2 23312
dda8d76d 23313 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
23314 _("v850 notes"));
23315 if (pnotes == NULL)
015dc7e1 23316 return false;
685080f2
NC
23317
23318 external = pnotes;
c8071705 23319 end = (char*) pnotes + length;
685080f2 23320
26c527e6
AM
23321 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
23322 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
23323 offset, length);
685080f2 23324
c8071705 23325 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
23326 {
23327 Elf_External_Note * next;
23328 Elf_Internal_Note inote;
23329
23330 inote.type = BYTE_GET (external->type);
23331 inote.namesz = BYTE_GET (external->namesz);
23332 inote.namedata = external->name;
23333 inote.descsz = BYTE_GET (external->descsz);
23334 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
23335 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23336
c8071705
NC
23337 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
23338 {
23339 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
23340 inote.descdata = inote.namedata;
23341 inote.namesz = 0;
23342 }
23343
685080f2
NC
23344 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
23345
c8071705 23346 if ( ((char *) next > end)
685080f2
NC
23347 || ((char *) next < (char *) pnotes))
23348 {
26c527e6
AM
23349 warn (_("corrupt descsz found in note at offset %#tx\n"),
23350 (char *) external - (char *) pnotes);
23351 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
23352 inote.type, inote.namesz, inote.descsz);
23353 break;
23354 }
23355
23356 external = next;
23357
23358 /* Prevent out-of-bounds indexing. */
c8071705 23359 if ( inote.namedata + inote.namesz > end
685080f2
NC
23360 || inote.namedata + inote.namesz < inote.namedata)
23361 {
26c527e6
AM
23362 warn (_("corrupt namesz found in note at offset %#zx\n"),
23363 (char *) external - (char *) pnotes);
23364 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
23365 inote.type, inote.namesz, inote.descsz);
23366 break;
23367 }
23368
23369 printf (" %s: ", get_v850_elf_note_type (inote.type));
23370
23371 if (! print_v850_note (& inote))
23372 {
015dc7e1 23373 res = false;
26c527e6 23374 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
23375 inote.namesz, inote.descsz);
23376 }
23377 }
23378
23379 free (pnotes);
23380
23381 return res;
23382}
23383
015dc7e1 23384static bool
dda8d76d 23385process_note_sections (Filedata * filedata)
1ec5cd37 23386{
015dc7e1 23387 Elf_Internal_Shdr *section;
26c527e6 23388 size_t i;
32ec8896 23389 unsigned int n = 0;
015dc7e1 23390 bool res = true;
1ec5cd37 23391
dda8d76d
NC
23392 for (i = 0, section = filedata->section_headers;
23393 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 23394 i++, section++)
685080f2
NC
23395 {
23396 if (section->sh_type == SHT_NOTE)
23397 {
625d49fc
AM
23398 if (! process_notes_at (filedata, section, section->sh_offset,
23399 section->sh_size, section->sh_addralign))
015dc7e1 23400 res = false;
685080f2
NC
23401 n++;
23402 }
23403
dda8d76d
NC
23404 if (( filedata->file_header.e_machine == EM_V800
23405 || filedata->file_header.e_machine == EM_V850
23406 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
23407 && section->sh_type == SHT_RENESAS_INFO)
23408 {
625d49fc
AM
23409 if (! process_v850_notes (filedata, section->sh_offset,
23410 section->sh_size))
015dc7e1 23411 res = false;
685080f2
NC
23412 n++;
23413 }
23414 }
df565f32
NC
23415
23416 if (n == 0)
23417 /* Try processing NOTE segments instead. */
dda8d76d 23418 return process_corefile_note_segments (filedata);
1ec5cd37
NC
23419
23420 return res;
23421}
23422
015dc7e1 23423static bool
dda8d76d 23424process_notes (Filedata * filedata)
779fe533
NC
23425{
23426 /* If we have not been asked to display the notes then do nothing. */
23427 if (! do_notes)
015dc7e1 23428 return true;
103f02d3 23429
dda8d76d
NC
23430 if (filedata->file_header.e_type != ET_CORE)
23431 return process_note_sections (filedata);
103f02d3 23432
779fe533 23433 /* No program headers means no NOTE segment. */
dda8d76d
NC
23434 if (filedata->file_header.e_phnum > 0)
23435 return process_corefile_note_segments (filedata);
779fe533 23436
ca0e11aa
NC
23437 if (filedata->is_separate)
23438 printf (_("No notes found in linked file '%s'.\n"),
23439 filedata->file_name);
23440 else
23441 printf (_("No notes found file.\n"));
23442
015dc7e1 23443 return true;
779fe533
NC
23444}
23445
60abdbed
NC
23446static unsigned char *
23447display_public_gnu_attributes (unsigned char * start,
23448 const unsigned char * const end)
23449{
23450 printf (_(" Unknown GNU attribute: %s\n"), start);
23451
23452 start += strnlen ((char *) start, end - start);
23453 display_raw_attribute (start, end);
23454
23455 return (unsigned char *) end;
23456}
23457
23458static unsigned char *
23459display_generic_attribute (unsigned char * start,
23460 unsigned int tag,
23461 const unsigned char * const end)
23462{
23463 if (tag == 0)
23464 return (unsigned char *) end;
23465
23466 return display_tag_value (tag, start, end);
23467}
23468
015dc7e1 23469static bool
dda8d76d 23470process_arch_specific (Filedata * filedata)
252b5132 23471{
a952a375 23472 if (! do_arch)
015dc7e1 23473 return true;
a952a375 23474
dda8d76d 23475 switch (filedata->file_header.e_machine)
252b5132 23476 {
53a346d8
CZ
23477 case EM_ARC:
23478 case EM_ARC_COMPACT:
23479 case EM_ARC_COMPACT2:
b5c37946
SJ
23480 case EM_ARC_COMPACT3:
23481 case EM_ARC_COMPACT3_64:
dda8d76d 23482 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
23483 display_arc_attribute,
23484 display_generic_attribute);
11c1ff18 23485 case EM_ARM:
dda8d76d 23486 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
23487 display_arm_attribute,
23488 display_generic_attribute);
23489
252b5132 23490 case EM_MIPS:
4fe85591 23491 case EM_MIPS_RS3_LE:
dda8d76d 23492 return process_mips_specific (filedata);
60abdbed
NC
23493
23494 case EM_MSP430:
dda8d76d 23495 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 23496 display_msp430_attribute,
c0ea7c52 23497 display_msp430_gnu_attribute);
60abdbed 23498
2dc8dd17
JW
23499 case EM_RISCV:
23500 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23501 display_riscv_attribute,
23502 display_generic_attribute);
23503
35c08157 23504 case EM_NDS32:
dda8d76d 23505 return process_nds32_specific (filedata);
60abdbed 23506
85f7484a
PB
23507 case EM_68K:
23508 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23509 display_m68k_gnu_attribute);
23510
34c8bcba 23511 case EM_PPC:
b82317dd 23512 case EM_PPC64:
dda8d76d 23513 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23514 display_power_gnu_attribute);
23515
643f7afb
AK
23516 case EM_S390:
23517 case EM_S390_OLD:
dda8d76d 23518 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23519 display_s390_gnu_attribute);
23520
9e8c70f9
DM
23521 case EM_SPARC:
23522 case EM_SPARC32PLUS:
23523 case EM_SPARCV9:
dda8d76d 23524 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23525 display_sparc_gnu_attribute);
23526
59e6276b 23527 case EM_TI_C6000:
dda8d76d 23528 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
23529 display_tic6x_attribute,
23530 display_generic_attribute);
23531
0861f561
CQ
23532 case EM_CSKY:
23533 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23534 display_csky_attribute, NULL);
23535
252b5132 23536 default:
dda8d76d 23537 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
23538 display_public_gnu_attributes,
23539 display_generic_attribute);
252b5132 23540 }
252b5132
RH
23541}
23542
015dc7e1 23543static bool
dda8d76d 23544get_file_header (Filedata * filedata)
252b5132 23545{
9ea033b2 23546 /* Read in the identity array. */
dda8d76d 23547 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23548 return false;
252b5132 23549
9ea033b2 23550 /* Determine how to read the rest of the header. */
dda8d76d 23551 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 23552 {
1a0670f3
AM
23553 default:
23554 case ELFDATANONE:
adab8cdc
AO
23555 case ELFDATA2LSB:
23556 byte_get = byte_get_little_endian;
23557 byte_put = byte_put_little_endian;
23558 break;
23559 case ELFDATA2MSB:
23560 byte_get = byte_get_big_endian;
23561 byte_put = byte_put_big_endian;
23562 break;
9ea033b2
NC
23563 }
23564
23565 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 23566 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
23567
23568 /* Read in the rest of the header. */
23569 if (is_32bit_elf)
23570 {
23571 Elf32_External_Ehdr ehdr32;
252b5132 23572
dda8d76d 23573 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23574 return false;
103f02d3 23575
dda8d76d
NC
23576 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23577 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23578 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23579 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23580 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23581 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23582 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23583 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23584 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23585 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23586 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23587 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23588 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 23589 }
252b5132 23590 else
9ea033b2
NC
23591 {
23592 Elf64_External_Ehdr ehdr64;
a952a375 23593
dda8d76d 23594 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23595 return false;
103f02d3 23596
dda8d76d
NC
23597 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23598 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23599 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23600 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23601 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23602 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23603 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23604 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23605 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23606 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23607 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23608 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23609 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 23610 }
252b5132 23611
015dc7e1 23612 return true;
252b5132
RH
23613}
23614
13acb58d
AM
23615static void
23616free_filedata (Filedata *filedata)
23617{
23618 free (filedata->program_interpreter);
13acb58d 23619 free (filedata->program_headers);
13acb58d 23620 free (filedata->section_headers);
13acb58d 23621 free (filedata->string_table);
13acb58d 23622 free (filedata->dump.dump_sects);
13acb58d 23623 free (filedata->dynamic_strings);
13acb58d 23624 free (filedata->dynamic_symbols);
13acb58d 23625 free (filedata->dynamic_syminfo);
13acb58d 23626 free (filedata->dynamic_section);
13acb58d
AM
23627
23628 while (filedata->symtab_shndx_list != NULL)
23629 {
23630 elf_section_list *next = filedata->symtab_shndx_list->next;
23631 free (filedata->symtab_shndx_list);
23632 filedata->symtab_shndx_list = next;
23633 }
23634
23635 free (filedata->section_headers_groups);
13acb58d
AM
23636
23637 if (filedata->section_groups)
23638 {
23639 size_t i;
23640 struct group_list * g;
23641 struct group_list * next;
23642
23643 for (i = 0; i < filedata->group_count; i++)
23644 {
23645 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23646 {
23647 next = g->next;
23648 free (g);
23649 }
23650 }
23651
23652 free (filedata->section_groups);
13acb58d 23653 }
066f8fbe
AM
23654 memset (&filedata->section_headers, 0,
23655 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23656}
23657
dda8d76d
NC
23658static void
23659close_file (Filedata * filedata)
23660{
23661 if (filedata)
23662 {
23663 if (filedata->handle)
23664 fclose (filedata->handle);
23665 free (filedata);
23666 }
23667}
23668
23669void
23670close_debug_file (void * data)
23671{
13acb58d 23672 free_filedata ((Filedata *) data);
dda8d76d
NC
23673 close_file ((Filedata *) data);
23674}
23675
23676static Filedata *
015dc7e1 23677open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23678{
23679 struct stat statbuf;
23680 Filedata * filedata = NULL;
23681
23682 if (stat (pathname, & statbuf) < 0
23683 || ! S_ISREG (statbuf.st_mode))
23684 goto fail;
23685
23686 filedata = calloc (1, sizeof * filedata);
23687 if (filedata == NULL)
23688 goto fail;
23689
23690 filedata->handle = fopen (pathname, "rb");
23691 if (filedata->handle == NULL)
23692 goto fail;
23693
be7d229a 23694 filedata->file_size = statbuf.st_size;
dda8d76d 23695 filedata->file_name = pathname;
ca0e11aa 23696 filedata->is_separate = is_separate;
dda8d76d
NC
23697
23698 if (! get_file_header (filedata))
23699 goto fail;
23700
4de91c10
AM
23701 if (!get_section_headers (filedata, false))
23702 goto fail;
dda8d76d
NC
23703
23704 return filedata;
23705
23706 fail:
23707 if (filedata)
23708 {
23709 if (filedata->handle)
23710 fclose (filedata->handle);
23711 free (filedata);
23712 }
23713 return NULL;
23714}
23715
23716void *
23717open_debug_file (const char * pathname)
23718{
015dc7e1 23719 return open_file (pathname, true);
dda8d76d
NC
23720}
23721
835f2fae
NC
23722static void
23723initialise_dump_sects (Filedata * filedata)
23724{
23725 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23726 Note we do this even if cmdline_dump_sects is empty because we
23727 must make sure that the dump_sets array is zeroed out before each
23728 object file is processed. */
23729 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23730 memset (filedata->dump.dump_sects, 0,
23731 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23732
23733 if (cmdline.num_dump_sects > 0)
23734 {
23735 if (filedata->dump.num_dump_sects == 0)
23736 /* A sneaky way of allocating the dump_sects array. */
23737 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23738
23739 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23740 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23741 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23742 }
23743}
23744
94585d6d
NC
23745static bool
23746might_need_separate_debug_info (Filedata * filedata)
23747{
23748 /* Debuginfo files do not need further separate file loading. */
23749 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23750 return false;
23751
23752 /* Since do_follow_links might be enabled by default, only treat it as an
23753 indication that separate files should be loaded if setting it was a
23754 deliberate user action. */
23755 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23756 return true;
5d526bdf
ML
23757
23758 if (process_links || do_syms || do_unwind
94585d6d
NC
23759 || dump_any_debugging || do_dump || do_debugging)
23760 return true;
23761
23762 return false;
23763}
23764
fb52b2f4
NC
23765/* Process one ELF object file according to the command line options.
23766 This file may actually be stored in an archive. The file is
32ec8896
NC
23767 positioned at the start of the ELF object. Returns TRUE if no
23768 problems were encountered, FALSE otherwise. */
fb52b2f4 23769
015dc7e1 23770static bool
dda8d76d 23771process_object (Filedata * filedata)
252b5132 23772{
015dc7e1 23773 bool have_separate_files;
252b5132 23774 unsigned int i;
015dc7e1 23775 bool res;
252b5132 23776
dda8d76d 23777 if (! get_file_header (filedata))
252b5132 23778 {
dda8d76d 23779 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23780 return false;
252b5132
RH
23781 }
23782
23783 /* Initialise per file variables. */
978c4450
AM
23784 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23785 filedata->version_info[i] = 0;
252b5132 23786
978c4450
AM
23787 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23788 filedata->dynamic_info[i] = 0;
23789 filedata->dynamic_info_DT_GNU_HASH = 0;
23790 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23791
23792 /* Process the file. */
23793 if (show_name)
dda8d76d 23794 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23795
835f2fae 23796 initialise_dump_sects (filedata);
d70c5fc7 23797
4de91c10
AM
23798 /* There may be some extensions in the first section header. Don't
23799 bomb if we can't read it. */
23800 get_section_headers (filedata, true);
23801
dda8d76d 23802 if (! process_file_header (filedata))
4de91c10
AM
23803 {
23804 res = false;
23805 goto out;
23806 }
252b5132 23807
e331b18d
AM
23808 /* Throw away the single section header read above, so that we
23809 re-read the entire set. */
23810 free (filedata->section_headers);
23811 filedata->section_headers = NULL;
23812
dda8d76d 23813 if (! process_section_headers (filedata))
2f62977e 23814 {
32ec8896 23815 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23816 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23817
2f62977e 23818 if (! do_using_dynamic)
015dc7e1 23819 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23820 }
252b5132 23821
dda8d76d 23822 if (! process_section_groups (filedata))
32ec8896 23823 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23824 do_unwind = false;
d1f5c6e3 23825
93df3340
AM
23826 process_program_headers (filedata);
23827
23828 res = process_dynamic_section (filedata);
252b5132 23829
dda8d76d 23830 if (! process_relocs (filedata))
015dc7e1 23831 res = false;
252b5132 23832
dda8d76d 23833 if (! process_unwind (filedata))
015dc7e1 23834 res = false;
4d6ed7c8 23835
dda8d76d 23836 if (! process_symbol_table (filedata))
015dc7e1 23837 res = false;
252b5132 23838
0f03783c 23839 if (! process_lto_symbol_tables (filedata))
015dc7e1 23840 res = false;
b9e920ec 23841
dda8d76d 23842 if (! process_syminfo (filedata))
015dc7e1 23843 res = false;
252b5132 23844
dda8d76d 23845 if (! process_version_sections (filedata))
015dc7e1 23846 res = false;
252b5132 23847
94585d6d 23848 if (might_need_separate_debug_info (filedata))
24841daa 23849 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23850 else
015dc7e1 23851 have_separate_files = false;
dda8d76d
NC
23852
23853 if (! process_section_contents (filedata))
015dc7e1 23854 res = false;
f5842774 23855
24841daa 23856 if (have_separate_files)
dda8d76d 23857 {
24841daa
NC
23858 separate_info * d;
23859
23860 for (d = first_separate_info; d != NULL; d = d->next)
23861 {
835f2fae
NC
23862 initialise_dump_sects (d->handle);
23863
ca0e11aa 23864 if (process_links && ! process_file_header (d->handle))
015dc7e1 23865 res = false;
ca0e11aa 23866 else if (! process_section_headers (d->handle))
015dc7e1 23867 res = false;
d6bfbc39 23868 else if (! process_section_contents (d->handle))
015dc7e1 23869 res = false;
ca0e11aa
NC
23870 else if (process_links)
23871 {
ca0e11aa 23872 if (! process_section_groups (d->handle))
015dc7e1 23873 res = false;
93df3340 23874 process_program_headers (d->handle);
ca0e11aa 23875 if (! process_dynamic_section (d->handle))
015dc7e1 23876 res = false;
ca0e11aa 23877 if (! process_relocs (d->handle))
015dc7e1 23878 res = false;
ca0e11aa 23879 if (! process_unwind (d->handle))
015dc7e1 23880 res = false;
ca0e11aa 23881 if (! process_symbol_table (d->handle))
015dc7e1 23882 res = false;
ca0e11aa 23883 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23884 res = false;
ca0e11aa 23885 if (! process_syminfo (d->handle))
015dc7e1 23886 res = false;
ca0e11aa 23887 if (! process_version_sections (d->handle))
015dc7e1 23888 res = false;
ca0e11aa 23889 if (! process_notes (d->handle))
015dc7e1 23890 res = false;
ca0e11aa 23891 }
24841daa
NC
23892 }
23893
23894 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23895 }
23896
23897 if (! process_notes (filedata))
015dc7e1 23898 res = false;
103f02d3 23899
dda8d76d 23900 if (! process_gnu_liblist (filedata))
015dc7e1 23901 res = false;
047b2264 23902
dda8d76d 23903 if (! process_arch_specific (filedata))
015dc7e1 23904 res = false;
252b5132 23905
4de91c10 23906 out:
13acb58d 23907 free_filedata (filedata);
e4b17d5c 23908
19e6b90e 23909 free_debug_memory ();
18bd398b 23910
32ec8896 23911 return res;
252b5132
RH
23912}
23913
2cf0635d 23914/* Process an ELF archive.
32ec8896
NC
23915 On entry the file is positioned just after the ARMAG string.
23916 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23917
015dc7e1
AM
23918static bool
23919process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23920{
23921 struct archive_info arch;
23922 struct archive_info nested_arch;
23923 size_t got;
015dc7e1 23924 bool ret = true;
2cf0635d 23925
015dc7e1 23926 show_name = true;
2cf0635d
NC
23927
23928 /* The ARCH structure is used to hold information about this archive. */
23929 arch.file_name = NULL;
23930 arch.file = NULL;
23931 arch.index_array = NULL;
23932 arch.sym_table = NULL;
23933 arch.longnames = NULL;
23934
23935 /* The NESTED_ARCH structure is used as a single-item cache of information
23936 about a nested archive (when members of a thin archive reside within
23937 another regular archive file). */
23938 nested_arch.file_name = NULL;
23939 nested_arch.file = NULL;
23940 nested_arch.index_array = NULL;
23941 nested_arch.sym_table = NULL;
23942 nested_arch.longnames = NULL;
23943
dda8d76d 23944 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23945 filedata->file_size, is_thin_archive,
23946 do_archive_index) != 0)
2cf0635d 23947 {
015dc7e1 23948 ret = false;
2cf0635d 23949 goto out;
4145f1d5 23950 }
fb52b2f4 23951
4145f1d5
NC
23952 if (do_archive_index)
23953 {
2cf0635d 23954 if (arch.sym_table == NULL)
1cb7d8b1
AM
23955 error (_("%s: unable to dump the index as none was found\n"),
23956 filedata->file_name);
4145f1d5
NC
23957 else
23958 {
26c527e6
AM
23959 uint64_t i, l;
23960 uint64_t current_pos;
4145f1d5 23961
26c527e6
AM
23962 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23963 " %#" PRIx64 " bytes in the symbol table)\n"),
23964 filedata->file_name, arch.index_num,
1cb7d8b1 23965 arch.sym_size);
dda8d76d
NC
23966
23967 current_pos = ftell (filedata->handle);
4145f1d5 23968
2cf0635d 23969 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23970 {
1cb7d8b1
AM
23971 if (i == 0
23972 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23973 {
23974 char * member_name
23975 = get_archive_member_name_at (&arch, arch.index_array[i],
23976 &nested_arch);
2cf0635d 23977
1cb7d8b1
AM
23978 if (member_name != NULL)
23979 {
23980 char * qualified_name
23981 = make_qualified_name (&arch, &nested_arch,
23982 member_name);
2cf0635d 23983
1cb7d8b1
AM
23984 if (qualified_name != NULL)
23985 {
23986 printf (_("Contents of binary %s at offset "),
23987 qualified_name);
c2a7d3f5
NC
23988 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23989 putchar ('\n');
1cb7d8b1
AM
23990 free (qualified_name);
23991 }
fd486f32 23992 free (member_name);
4145f1d5
NC
23993 }
23994 }
2cf0635d
NC
23995
23996 if (l >= arch.sym_size)
4145f1d5 23997 {
1cb7d8b1
AM
23998 error (_("%s: end of the symbol table reached "
23999 "before the end of the index\n"),
dda8d76d 24000 filedata->file_name);
015dc7e1 24001 ret = false;
cb8f3167 24002 break;
4145f1d5 24003 }
591f7597 24004 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
24005 printf ("\t%.*s\n",
24006 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 24007 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
24008 }
24009
67ce483b 24010 if (arch.uses_64bit_indices)
c2a7d3f5
NC
24011 l = (l + 7) & ~ 7;
24012 else
24013 l += l & 1;
24014
2cf0635d 24015 if (l < arch.sym_size)
32ec8896 24016 {
26c527e6 24017 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
24018 "but without corresponding entries in "
24019 "the index table\n",
26c527e6 24020 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
24021 "but without corresponding entries in "
24022 "the index table\n",
24023 arch.sym_size - l),
dda8d76d 24024 filedata->file_name, arch.sym_size - l);
015dc7e1 24025 ret = false;
32ec8896 24026 }
4145f1d5 24027
63cf857e 24028 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 24029 {
1cb7d8b1
AM
24030 error (_("%s: failed to seek back to start of object files "
24031 "in the archive\n"),
dda8d76d 24032 filedata->file_name);
015dc7e1 24033 ret = false;
2cf0635d 24034 goto out;
4145f1d5 24035 }
fb52b2f4 24036 }
4145f1d5
NC
24037
24038 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
24039 && !do_segments && !do_header && !do_dump && !do_version
24040 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 24041 && !do_section_groups && !do_dyn_syms)
2cf0635d 24042 {
015dc7e1 24043 ret = true; /* Archive index only. */
2cf0635d
NC
24044 goto out;
24045 }
fb52b2f4
NC
24046 }
24047
fb52b2f4
NC
24048 while (1)
24049 {
2cf0635d
NC
24050 char * name;
24051 size_t namelen;
24052 char * qualified_name;
24053
24054 /* Read the next archive header. */
63cf857e 24055 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
24056 {
24057 error (_("%s: failed to seek to next archive header\n"),
24058 arch.file_name);
015dc7e1 24059 ret = false;
1cb7d8b1
AM
24060 break;
24061 }
dda8d76d 24062 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 24063 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
24064 {
24065 if (got == 0)
2cf0635d 24066 break;
28e817cc
NC
24067 /* PR 24049 - we cannot use filedata->file_name as this will
24068 have already been freed. */
24069 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 24070
015dc7e1 24071 ret = false;
1cb7d8b1
AM
24072 break;
24073 }
2cf0635d 24074 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
24075 {
24076 error (_("%s: did not find a valid archive header\n"),
24077 arch.file_name);
015dc7e1 24078 ret = false;
1cb7d8b1
AM
24079 break;
24080 }
2cf0635d
NC
24081
24082 arch.next_arhdr_offset += sizeof arch.arhdr;
24083
978c4450 24084 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
24085
24086 name = get_archive_member_name (&arch, &nested_arch);
24087 if (name == NULL)
fb52b2f4 24088 {
28e817cc 24089 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 24090 ret = false;
d989285c 24091 break;
fb52b2f4 24092 }
2cf0635d 24093 namelen = strlen (name);
fb52b2f4 24094
2cf0635d
NC
24095 qualified_name = make_qualified_name (&arch, &nested_arch, name);
24096 if (qualified_name == NULL)
fb52b2f4 24097 {
28e817cc 24098 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 24099 free (name);
015dc7e1 24100 ret = false;
d989285c 24101 break;
fb52b2f4
NC
24102 }
24103
2cf0635d 24104 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
24105 {
24106 /* This is a proxy for an external member of a thin archive. */
24107 Filedata * member_filedata;
24108 char * member_file_name = adjust_relative_path
dda8d76d 24109 (filedata->file_name, name, namelen);
32ec8896 24110
fd486f32 24111 free (name);
1cb7d8b1
AM
24112 if (member_file_name == NULL)
24113 {
fd486f32 24114 free (qualified_name);
015dc7e1 24115 ret = false;
1cb7d8b1
AM
24116 break;
24117 }
2cf0635d 24118
015dc7e1 24119 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
24120 if (member_filedata == NULL)
24121 {
24122 error (_("Input file '%s' is not readable.\n"), member_file_name);
24123 free (member_file_name);
fd486f32 24124 free (qualified_name);
015dc7e1 24125 ret = false;
1cb7d8b1
AM
24126 break;
24127 }
2cf0635d 24128
978c4450 24129 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 24130 member_filedata->file_name = qualified_name;
2cf0635d 24131
75a2da57
AH
24132 /* The call to process_object() expects the file to be at the beginning. */
24133 rewind (member_filedata->handle);
24134
1cb7d8b1 24135 if (! process_object (member_filedata))
015dc7e1 24136 ret = false;
2cf0635d 24137
1cb7d8b1
AM
24138 close_file (member_filedata);
24139 free (member_file_name);
1cb7d8b1 24140 }
2cf0635d 24141 else if (is_thin_archive)
1cb7d8b1
AM
24142 {
24143 Filedata thin_filedata;
eb02c04d 24144
1cb7d8b1 24145 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 24146
a043396b
NC
24147 /* PR 15140: Allow for corrupt thin archives. */
24148 if (nested_arch.file == NULL)
24149 {
24150 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 24151 qualified_name, name);
fd486f32
AM
24152 free (qualified_name);
24153 free (name);
015dc7e1 24154 ret = false;
a043396b
NC
24155 break;
24156 }
fd486f32 24157 free (name);
a043396b 24158
1cb7d8b1 24159 /* This is a proxy for a member of a nested archive. */
978c4450
AM
24160 filedata->archive_file_offset
24161 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 24162
1cb7d8b1
AM
24163 /* The nested archive file will have been opened and setup by
24164 get_archive_member_name. */
63cf857e
AM
24165 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
24166 SEEK_SET) != 0)
1cb7d8b1
AM
24167 {
24168 error (_("%s: failed to seek to archive member.\n"),
24169 nested_arch.file_name);
fd486f32 24170 free (qualified_name);
015dc7e1 24171 ret = false;
1cb7d8b1
AM
24172 break;
24173 }
2cf0635d 24174
dda8d76d
NC
24175 thin_filedata.handle = nested_arch.file;
24176 thin_filedata.file_name = qualified_name;
9abca702 24177
1cb7d8b1 24178 if (! process_object (& thin_filedata))
015dc7e1 24179 ret = false;
1cb7d8b1 24180 }
2cf0635d 24181 else
1cb7d8b1 24182 {
fd486f32 24183 free (name);
978c4450 24184 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 24185 filedata->file_name = qualified_name;
1cb7d8b1 24186 if (! process_object (filedata))
015dc7e1 24187 ret = false;
237877b8 24188 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 24189 /* Stop looping with "negative" archive_file_size. */
978c4450 24190 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 24191 arch.next_arhdr_offset = -1ul;
1cb7d8b1 24192 }
fb52b2f4 24193
2cf0635d 24194 free (qualified_name);
fb52b2f4
NC
24195 }
24196
4145f1d5 24197 out:
2cf0635d
NC
24198 if (nested_arch.file != NULL)
24199 fclose (nested_arch.file);
24200 release_archive (&nested_arch);
24201 release_archive (&arch);
fb52b2f4 24202
d989285c 24203 return ret;
fb52b2f4
NC
24204}
24205
015dc7e1 24206static bool
2cf0635d 24207process_file (char * file_name)
fb52b2f4 24208{
dda8d76d 24209 Filedata * filedata = NULL;
fb52b2f4
NC
24210 struct stat statbuf;
24211 char armag[SARMAG];
015dc7e1 24212 bool ret = true;
fb52b2f4
NC
24213
24214 if (stat (file_name, &statbuf) < 0)
24215 {
f24ddbdd
NC
24216 if (errno == ENOENT)
24217 error (_("'%s': No such file\n"), file_name);
24218 else
24219 error (_("Could not locate '%s'. System error message: %s\n"),
24220 file_name, strerror (errno));
015dc7e1 24221 return false;
f24ddbdd
NC
24222 }
24223
24224 if (! S_ISREG (statbuf.st_mode))
24225 {
24226 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 24227 return false;
fb52b2f4
NC
24228 }
24229
dda8d76d
NC
24230 filedata = calloc (1, sizeof * filedata);
24231 if (filedata == NULL)
24232 {
24233 error (_("Out of memory allocating file data structure\n"));
015dc7e1 24234 return false;
dda8d76d
NC
24235 }
24236
24237 filedata->file_name = file_name;
24238 filedata->handle = fopen (file_name, "rb");
24239 if (filedata->handle == NULL)
fb52b2f4 24240 {
f24ddbdd 24241 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 24242 free (filedata);
015dc7e1 24243 return false;
fb52b2f4
NC
24244 }
24245
dda8d76d 24246 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 24247 {
4145f1d5 24248 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
24249 fclose (filedata->handle);
24250 free (filedata);
015dc7e1 24251 return false;
fb52b2f4
NC
24252 }
24253
be7d229a 24254 filedata->file_size = statbuf.st_size;
015dc7e1 24255 filedata->is_separate = false;
f54498b4 24256
fb52b2f4 24257 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 24258 {
015dc7e1
AM
24259 if (! process_archive (filedata, false))
24260 ret = false;
32ec8896 24261 }
2cf0635d 24262 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 24263 {
015dc7e1
AM
24264 if ( ! process_archive (filedata, true))
24265 ret = false;
32ec8896 24266 }
fb52b2f4
NC
24267 else
24268 {
1b513401 24269 if (do_archive_index && !check_all)
4145f1d5
NC
24270 error (_("File %s is not an archive so its index cannot be displayed.\n"),
24271 file_name);
24272
dda8d76d 24273 rewind (filedata->handle);
978c4450 24274 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 24275
dda8d76d 24276 if (! process_object (filedata))
015dc7e1 24277 ret = false;
fb52b2f4
NC
24278 }
24279
94e2b2a7 24280 close_debug_file (filedata);
32ec8896 24281
fd486f32 24282 free (ba_cache.strtab);
1bd6175a 24283 ba_cache.strtab = NULL;
fd486f32 24284 free (ba_cache.symtab);
1bd6175a 24285 ba_cache.symtab = NULL;
fd486f32
AM
24286 ba_cache.filedata = NULL;
24287
fb52b2f4
NC
24288 return ret;
24289}
24290
252b5132
RH
24291#ifdef SUPPORT_DISASSEMBLY
24292/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 24293 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 24294 symbols. */
252b5132
RH
24295
24296void
2cf0635d 24297print_address (unsigned int addr, FILE * outfile)
252b5132
RH
24298{
24299 fprintf (outfile,"0x%8.8x", addr);
24300}
24301
e3c8793a 24302/* Needed by the i386 disassembler. */
dda8d76d 24303
252b5132
RH
24304void
24305db_task_printsym (unsigned int addr)
24306{
24307 print_address (addr, stderr);
24308}
24309#endif
24310
24311int
2cf0635d 24312main (int argc, char ** argv)
252b5132 24313{
ff78d6d6
L
24314 int err;
24315
87b9f255 24316#ifdef HAVE_LC_MESSAGES
252b5132 24317 setlocale (LC_MESSAGES, "");
3882b010 24318#endif
3882b010 24319 setlocale (LC_CTYPE, "");
252b5132
RH
24320 bindtextdomain (PACKAGE, LOCALEDIR);
24321 textdomain (PACKAGE);
24322
869b9d07
MM
24323 expandargv (&argc, &argv);
24324
dda8d76d 24325 parse_args (& cmdline, argc, argv);
59f14fc0 24326
18bd398b 24327 if (optind < (argc - 1))
1b513401
NC
24328 /* When displaying information for more than one file,
24329 prefix the information with the file name. */
015dc7e1 24330 show_name = true;
5656ba2c
L
24331 else if (optind >= argc)
24332 {
1b513401 24333 /* Ensure that the warning is always displayed. */
015dc7e1 24334 do_checks = true;
1b513401 24335
5656ba2c
L
24336 warn (_("Nothing to do.\n"));
24337 usage (stderr);
24338 }
18bd398b 24339
015dc7e1 24340 err = false;
252b5132 24341 while (optind < argc)
32ec8896 24342 if (! process_file (argv[optind++]))
015dc7e1 24343 err = true;
252b5132 24344
9db70fc3 24345 free (cmdline.dump_sects);
252b5132 24346
7d9813f1
NA
24347 free (dump_ctf_symtab_name);
24348 free (dump_ctf_strtab_name);
24349 free (dump_ctf_parent_name);
24350
32ec8896 24351 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 24352}