]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Don't use bfd_size_type in readelf.c and dwarf.c
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
a2c58332 2 Copyright (C) 1998-2022 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>
7bfd842d 47#include <wchar.h>
252b5132 48
2952f10c
SM
49#if defined HAVE_MSGPACK
50#include <msgpack.h>
51#endif
52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
0d646226 64#include "demanguse.h"
19e6b90e 65#include "dwarf.h"
7d9813f1 66#include "ctf-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"
84e94c90 124#include "elf/lm32.h"
1c0d3aa6 125#include "elf/iq2000.h"
49f58d10 126#include "elf/m32c.h"
3b16e843
NC
127#include "elf/m32r.h"
128#include "elf/m68k.h"
75751cd9 129#include "elf/m68hc11.h"
7b4ae824 130#include "elf/s12z.h"
252b5132 131#include "elf/mcore.h"
15ab5209 132#include "elf/mep.h"
a3c62988 133#include "elf/metag.h"
7ba29e2a 134#include "elf/microblaze.h"
3b16e843 135#include "elf/mips.h"
3c3bdf30 136#include "elf/mmix.h"
3b16e843
NC
137#include "elf/mn10200.h"
138#include "elf/mn10300.h"
5506d11a 139#include "elf/moxie.h"
4970f871 140#include "elf/mt.h"
2469cfa2 141#include "elf/msp430.h"
35c08157 142#include "elf/nds32.h"
fe944acf 143#include "elf/nfp.h"
13761a11 144#include "elf/nios2.h"
73589c9d 145#include "elf/or1k.h"
7d466069 146#include "elf/pj.h"
3b16e843 147#include "elf/ppc.h"
c833c019 148#include "elf/ppc64.h"
2b100bb5 149#include "elf/pru.h"
03336641 150#include "elf/riscv.h"
99c513f6 151#include "elf/rl78.h"
c7927a3c 152#include "elf/rx.h"
a85d7ed0 153#include "elf/s390.h"
1c0d3aa6 154#include "elf/score.h"
3b16e843
NC
155#include "elf/sh.h"
156#include "elf/sparc.h"
e9f53129 157#include "elf/spu.h"
40b36596 158#include "elf/tic6x.h"
aa137e4d
NC
159#include "elf/tilegx.h"
160#include "elf/tilepro.h"
3b16e843 161#include "elf/v850.h"
179d3252 162#include "elf/vax.h"
619ed720 163#include "elf/visium.h"
f96bd6c2 164#include "elf/wasm32.h"
3b16e843 165#include "elf/x86-64.h"
f6c1a2d5 166#include "elf/xgate.h"
93fbbb04 167#include "elf/xstormy16.h"
88da6820 168#include "elf/xtensa.h"
6655dba2 169#include "elf/z80.h"
e9a0721f 170#include "elf/loongarch.h"
252b5132 171
252b5132 172#include "getopt.h"
566b0d53 173#include "libiberty.h"
09c11c86 174#include "safe-ctype.h"
2cf0635d 175#include "filenames.h"
252b5132 176
15b42fb0
AM
177#ifndef offsetof
178#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
179#endif
180
6a40cf0c
NC
181typedef struct elf_section_list
182{
dda8d76d
NC
183 Elf_Internal_Shdr * hdr;
184 struct elf_section_list * next;
6a40cf0c
NC
185} elf_section_list;
186
dda8d76d
NC
187/* Flag bits indicating particular types of dump. */
188#define HEX_DUMP (1 << 0) /* The -x command line switch. */
189#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
190#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
191#define STRING_DUMP (1 << 3) /* The -p command line switch. */
192#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 193#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
194
195typedef unsigned char dump_type;
196
197/* A linked list of the section names for which dumps were requested. */
198struct dump_list_entry
199{
200 char * name;
201 dump_type type;
202 struct dump_list_entry * next;
203};
204
6431e409
AM
205/* A dynamic array of flags indicating for which sections a dump
206 has been requested via command line switches. */
1b513401
NC
207struct dump_data
208{
6431e409
AM
209 dump_type * dump_sects;
210 unsigned int num_dump_sects;
211};
212
213static struct dump_data cmdline;
214
215static struct dump_list_entry * dump_sects_byname;
216
2cf0635d 217char * program_name = "readelf";
dda8d76d 218
015dc7e1
AM
219static bool show_name = false;
220static bool do_dynamic = false;
221static bool do_syms = false;
222static bool do_dyn_syms = false;
223static bool do_lto_syms = false;
224static bool do_reloc = false;
225static bool do_sections = false;
226static bool do_section_groups = false;
227static bool do_section_details = false;
228static bool do_segments = false;
229static bool do_unwind = false;
230static bool do_using_dynamic = false;
231static bool do_header = false;
232static bool do_dump = false;
233static bool do_version = false;
234static bool do_histogram = false;
235static bool do_debugging = false;
236static bool do_ctf = false;
237static bool do_arch = false;
238static bool do_notes = false;
239static bool do_archive_index = false;
240static bool check_all = false;
241static bool is_32bit_elf = false;
242static bool decompress_dumps = false;
243static bool do_not_show_symbol_truncation = false;
244static bool do_demangle = false; /* Pretty print C++ symbol names. */
245static bool process_links = false;
e1dbfc17 246static bool dump_any_debugging = false;
79bc120c 247static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 248static int sym_base = 0;
252b5132 249
7d9813f1
NA
250static char *dump_ctf_parent_name;
251static char *dump_ctf_symtab_name;
252static char *dump_ctf_strtab_name;
253
e4b17d5c
L
254struct group_list
255{
dda8d76d
NC
256 struct group_list * next;
257 unsigned int section_index;
e4b17d5c
L
258};
259
260struct group
261{
dda8d76d
NC
262 struct group_list * root;
263 unsigned int group_index;
e4b17d5c
L
264};
265
978c4450
AM
266typedef struct filedata
267{
268 const char * file_name;
015dc7e1 269 bool is_separate;
978c4450 270 FILE * handle;
be7d229a 271 uint64_t file_size;
978c4450 272 Elf_Internal_Ehdr file_header;
066f8fbe
AM
273 unsigned long archive_file_offset;
274 unsigned long archive_file_size;
275 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
276 Elf_Internal_Shdr * section_headers;
277 Elf_Internal_Phdr * program_headers;
278 char * string_table;
279 unsigned long string_table_length;
978c4450 280 unsigned long dynamic_addr;
be7d229a 281 uint64_t dynamic_size;
978c4450
AM
282 size_t dynamic_nent;
283 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 284 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
285 char * dynamic_strings;
286 unsigned long dynamic_strings_length;
8ac10c5b 287 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
288 unsigned long num_dynamic_syms;
289 Elf_Internal_Sym * dynamic_symbols;
290 bfd_vma version_info[16];
291 unsigned int dynamic_syminfo_nent;
292 Elf_Internal_Syminfo * dynamic_syminfo;
293 unsigned long dynamic_syminfo_offset;
be7d229a
AM
294 uint64_t nbuckets;
295 uint64_t nchains;
978c4450
AM
296 bfd_vma * buckets;
297 bfd_vma * chains;
be7d229a
AM
298 uint64_t ngnubuckets;
299 uint64_t ngnuchains;
978c4450
AM
300 bfd_vma * gnubuckets;
301 bfd_vma * gnuchains;
302 bfd_vma * mipsxlat;
303 bfd_vma gnusymidx;
13acb58d 304 char * program_interpreter;
978c4450
AM
305 bfd_vma dynamic_info[DT_ENCODING];
306 bfd_vma dynamic_info_DT_GNU_HASH;
307 bfd_vma dynamic_info_DT_MIPS_XHASH;
308 elf_section_list * symtab_shndx_list;
309 size_t group_count;
310 struct group * section_groups;
311 struct group ** section_headers_groups;
312 /* A dynamic array of flags indicating for which sections a dump of
313 some kind has been requested. It is reset on a per-object file
314 basis and then initialised from the cmdline_dump_sects array,
315 the results of interpreting the -w switch, and the
316 dump_sects_byname list. */
317 struct dump_data dump;
318} Filedata;
aef1f6d0 319
c256ffe7 320/* How to print a vma value. */
843dd992
NC
321typedef enum print_mode
322{
323 HEX,
047c3dbf 324 HEX_5,
843dd992
NC
325 DEC,
326 DEC_5,
327 UNSIGNED,
047c3dbf 328 UNSIGNED_5,
843dd992 329 PREFIX_HEX,
047c3dbf 330 PREFIX_HEX_5,
843dd992 331 FULL_HEX,
047c3dbf
NL
332 LONG_HEX,
333 OCTAL,
334 OCTAL_5
843dd992
NC
335}
336print_mode;
337
b3aa80b4
NC
338typedef enum unicode_display_type
339{
340 unicode_default = 0,
341 unicode_locale,
342 unicode_escape,
343 unicode_hex,
344 unicode_highlight,
345 unicode_invalid
346} unicode_display_type;
347
348static unicode_display_type unicode_display = unicode_default;
349
a7fd1186
FS
350typedef enum
351{
352 reltype_unknown,
353 reltype_rel,
354 reltype_rela,
355 reltype_relr
356} relocation_type;
357
bb4d2ac2
L
358/* Versioned symbol info. */
359enum versioned_symbol_info
360{
361 symbol_undefined,
362 symbol_hidden,
363 symbol_public
364};
365
32ec8896 366static const char * get_symbol_version_string
015dc7e1 367 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 368 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 369
9c19a809
NC
370#define UNKNOWN -1
371
84714f86
AM
372static inline const char *
373section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
374{
375 return filedata->string_table + hdr->sh_name;
376}
b9e920ec 377
84714f86
AM
378static inline bool
379section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
380{
381 return (hdr != NULL
382 && filedata->string_table != NULL
383 && hdr->sh_name < filedata->string_table_length);
384}
b9e920ec 385
84714f86
AM
386static inline const char *
387section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
388{
389 if (hdr == NULL)
390 return _("<none>");
391 if (filedata->string_table == NULL)
392 return _("<no-strings>");
393 if (hdr->sh_name >= filedata->string_table_length)
394 return _("<corrupt>");
395 return section_name (filedata, hdr);
396}
252b5132 397
ee42cf8c 398#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 399
84714f86
AM
400static inline bool
401valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
402{
403 return strtab != NULL && offset < strtab_size;
404}
405
406static inline bool
407valid_dynamic_name (const Filedata *filedata, uint64_t offset)
408{
409 return valid_symbol_name (filedata->dynamic_strings,
410 filedata->dynamic_strings_length, offset);
411}
412
d79b3d50
NC
413/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
414 already been called and verified that the string exists. */
84714f86
AM
415static inline const char *
416get_dynamic_name (const Filedata *filedata, size_t offset)
417{
418 return filedata->dynamic_strings + offset;
419}
18bd398b 420
61865e30
NC
421#define REMOVE_ARCH_BITS(ADDR) \
422 do \
423 { \
dda8d76d 424 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
425 (ADDR) &= ~1; \
426 } \
427 while (0)
f16a9783
MS
428
429/* Get the correct GNU hash section name. */
978c4450
AM
430#define GNU_HASH_SECTION_NAME(filedata) \
431 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 432\f
dda8d76d
NC
433/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
434 OFFSET + the offset of the current archive member, if we are examining an
435 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
436 allocate a buffer using malloc and fill that. In either case return the
437 pointer to the start of the retrieved data or NULL if something went wrong.
438 If something does go wrong and REASON is not NULL then emit an error
439 message using REASON as part of the context. */
59245841 440
c256ffe7 441static void *
be7d229a
AM
442get_data (void *var,
443 Filedata *filedata,
444 unsigned long offset,
445 uint64_t size,
446 uint64_t nmemb,
447 const char *reason)
a6e9f9df 448{
2cf0635d 449 void * mvar;
be7d229a 450 uint64_t amt = size * nmemb;
a6e9f9df 451
c256ffe7 452 if (size == 0 || nmemb == 0)
a6e9f9df
AM
453 return NULL;
454
be7d229a
AM
455 /* If size_t is smaller than uint64_t, eg because you are building
456 on a 32-bit host, then make sure that when the sizes are cast to
457 size_t no information is lost. */
7c1c1904
AM
458 if ((size_t) size != size
459 || (size_t) nmemb != nmemb
be7d229a
AM
460 || (size_t) amt != amt
461 || amt / size != nmemb
462 || (size_t) amt + 1 == 0)
57028622
NC
463 {
464 if (reason)
b8281767
AM
465 error (_("Size overflow prevents reading %" PRIu64
466 " elements of size %" PRIu64 " for %s\n"),
be7d229a 467 nmemb, size, reason);
57028622
NC
468 return NULL;
469 }
470
c22b42ce 471 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 472 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
473 if (filedata->archive_file_offset > filedata->file_size
474 || offset > filedata->file_size - filedata->archive_file_offset
475 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 476 {
049b0c3a 477 if (reason)
b8281767 478 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 479 amt, reason);
a6e9f9df
AM
480 return NULL;
481 }
482
978c4450
AM
483 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
484 SEEK_SET))
071436c6
NC
485 {
486 if (reason)
c9c1d674 487 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 488 filedata->archive_file_offset + offset, reason);
071436c6
NC
489 return NULL;
490 }
491
a6e9f9df
AM
492 mvar = var;
493 if (mvar == NULL)
494 {
7c1c1904
AM
495 /* + 1 so that we can '\0' terminate invalid string table sections. */
496 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
497
498 if (mvar == NULL)
499 {
049b0c3a 500 if (reason)
b8281767 501 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 502 amt, reason);
a6e9f9df
AM
503 return NULL;
504 }
c256ffe7 505
c9c1d674 506 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
507 }
508
dda8d76d 509 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 510 {
049b0c3a 511 if (reason)
b8281767 512 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 513 amt, reason);
a6e9f9df
AM
514 if (mvar != var)
515 free (mvar);
516 return NULL;
517 }
518
519 return mvar;
520}
521
32ec8896
NC
522/* Print a VMA value in the MODE specified.
523 Returns the number of characters displayed. */
cb8f3167 524
32ec8896 525static unsigned int
14a91970 526print_vma (bfd_vma vma, print_mode mode)
66543521 527{
32ec8896 528 unsigned int nc = 0;
66543521 529
14a91970 530 switch (mode)
66543521 531 {
14a91970
AM
532 case FULL_HEX:
533 nc = printf ("0x");
1a0670f3 534 /* Fall through. */
14a91970 535 case LONG_HEX:
f7a99963 536#ifdef BFD64
f493c217
AM
537 if (!is_32bit_elf)
538 return nc + printf ("%16.16" PRIx64, (uint64_t) vma);
f7a99963 539#endif
f493c217 540 return nc + printf ("%8.8" PRIx64, (uint64_t) vma);
b19aac67 541
14a91970
AM
542 case DEC_5:
543 if (vma <= 99999)
b8281767 544 return printf ("%5" PRId64, (int64_t) vma);
1a0670f3 545 /* Fall through. */
14a91970
AM
546 case PREFIX_HEX:
547 nc = printf ("0x");
1a0670f3 548 /* Fall through. */
14a91970 549 case HEX:
b8281767 550 return nc + printf ("%" PRIx64, (uint64_t) vma);
b19aac67 551
047c3dbf
NL
552 case PREFIX_HEX_5:
553 nc = printf ("0x");
554 /* Fall through. */
555 case HEX_5:
b8281767 556 return nc + printf ("%05" PRIx64, (uint64_t) vma);
047c3dbf 557
14a91970 558 case DEC:
b8281767 559 return printf ("%" PRId64, (int64_t) (bfd_signed_vma) vma);
b19aac67 560
14a91970 561 case UNSIGNED:
b8281767 562 return printf ("%" PRIu64, (uint64_t) vma);
32ec8896 563
047c3dbf 564 case UNSIGNED_5:
b8281767 565 return printf ("%5" PRIu64, (uint64_t) vma);
047c3dbf
NL
566
567 case OCTAL:
b8281767 568 return printf ("%" PRIo64, (uint64_t) vma);
047c3dbf
NL
569
570 case OCTAL_5:
b8281767 571 return printf ("%5" PRIo64, (uint64_t) vma);
047c3dbf 572
32ec8896
NC
573 default:
574 /* FIXME: Report unrecognised mode ? */
575 return 0;
f7a99963 576 }
f7a99963
NC
577}
578
047c3dbf 579
7bfd842d 580/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 581 multibye characters (assuming the host environment supports them).
31104126 582
7bfd842d
NC
583 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
584
0942c7ab
NC
585 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
586 abs(WIDTH) - 5 characters followed by "[...]".
587
7bfd842d
NC
588 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
589 padding as necessary.
171191ba
NC
590
591 Returns the number of emitted characters. */
592
593static unsigned int
0942c7ab 594print_symbol (signed int width, const char * symbol)
31104126 595{
015dc7e1
AM
596 bool extra_padding = false;
597 bool do_dots = false;
32ec8896 598 signed int num_printed = 0;
3bfcb652 599#ifdef HAVE_MBSTATE_T
7bfd842d 600 mbstate_t state;
3bfcb652 601#endif
32ec8896 602 unsigned int width_remaining;
79bc120c 603 const void * alloced_symbol = NULL;
961c521f 604
7bfd842d 605 if (width < 0)
961c521f 606 {
88305e1b 607 /* Keep the width positive. This helps the code below. */
961c521f 608 width = - width;
015dc7e1 609 extra_padding = true;
0b4362b0 610 }
56d8f8a9
NC
611 else if (width == 0)
612 return 0;
961c521f 613
7bfd842d
NC
614 if (do_wide)
615 /* Set the remaining width to a very large value.
616 This simplifies the code below. */
617 width_remaining = INT_MAX;
618 else
0942c7ab
NC
619 {
620 width_remaining = width;
621 if (! do_not_show_symbol_truncation
622 && (int) strlen (symbol) > width)
623 {
624 width_remaining -= 5;
625 if ((int) width_remaining < 0)
626 width_remaining = 0;
015dc7e1 627 do_dots = true;
0942c7ab
NC
628 }
629 }
cb8f3167 630
3bfcb652 631#ifdef HAVE_MBSTATE_T
7bfd842d
NC
632 /* Initialise the multibyte conversion state. */
633 memset (& state, 0, sizeof (state));
3bfcb652 634#endif
961c521f 635
79bc120c
NC
636 if (do_demangle && *symbol)
637 {
638 const char * res = cplus_demangle (symbol, demangle_flags);
639
640 if (res != NULL)
641 alloced_symbol = symbol = res;
642 }
643
7bfd842d
NC
644 while (width_remaining)
645 {
646 size_t n;
7bfd842d 647 const char c = *symbol++;
961c521f 648
7bfd842d 649 if (c == 0)
961c521f
NC
650 break;
651
b3aa80b4
NC
652 if (ISPRINT (c))
653 {
654 putchar (c);
655 width_remaining --;
656 num_printed ++;
657 }
658 else if (ISCNTRL (c))
961c521f 659 {
b3aa80b4
NC
660 /* Do not print control characters directly as they can affect terminal
661 settings. Such characters usually appear in the names generated
662 by the assembler for local labels. */
663
7bfd842d 664 if (width_remaining < 2)
961c521f
NC
665 break;
666
7bfd842d
NC
667 printf ("^%c", c + 0x40);
668 width_remaining -= 2;
171191ba 669 num_printed += 2;
961c521f 670 }
b3aa80b4 671 else if (c == 0x7f)
7bfd842d 672 {
b3aa80b4
NC
673 if (width_remaining < 5)
674 break;
675 printf ("<DEL>");
676 width_remaining -= 5;
677 num_printed += 5;
678 }
679 else if (unicode_display != unicode_locale
680 && unicode_display != unicode_default)
681 {
682 /* Display unicode characters as something else. */
683 unsigned char bytes[4];
684 bool is_utf8;
795588ae 685 unsigned int nbytes;
b3aa80b4
NC
686
687 bytes[0] = c;
688
689 if (bytes[0] < 0xc0)
690 {
691 nbytes = 1;
692 is_utf8 = false;
693 }
694 else
695 {
696 bytes[1] = *symbol++;
697
698 if ((bytes[1] & 0xc0) != 0x80)
699 {
700 is_utf8 = false;
701 /* Do not consume this character. It may only
702 be the first byte in the sequence that was
703 corrupt. */
704 --symbol;
705 nbytes = 1;
706 }
707 else if ((bytes[0] & 0x20) == 0)
708 {
709 is_utf8 = true;
710 nbytes = 2;
711 }
712 else
713 {
714 bytes[2] = *symbol++;
715
716 if ((bytes[2] & 0xc0) != 0x80)
717 {
718 is_utf8 = false;
719 symbol -= 2;
720 nbytes = 1;
721 }
722 else if ((bytes[0] & 0x10) == 0)
723 {
724 is_utf8 = true;
725 nbytes = 3;
726 }
727 else
728 {
729 bytes[3] = *symbol++;
730
731 nbytes = 4;
732
733 if ((bytes[3] & 0xc0) != 0x80)
734 {
735 is_utf8 = false;
736 symbol -= 3;
737 nbytes = 1;
738 }
739 else
740 is_utf8 = true;
741 }
742 }
743 }
744
745 if (unicode_display == unicode_invalid)
746 is_utf8 = false;
747
748 if (unicode_display == unicode_hex || ! is_utf8)
749 {
795588ae 750 unsigned int i;
b3aa80b4
NC
751
752 if (width_remaining < (nbytes * 2) + 2)
753 break;
754
755 putchar (is_utf8 ? '<' : '{');
756 printf ("0x");
757 for (i = 0; i < nbytes; i++)
758 printf ("%02x", bytes[i]);
759 putchar (is_utf8 ? '>' : '}');
760 }
761 else
762 {
763 if (unicode_display == unicode_highlight && isatty (1))
764 printf ("\x1B[31;47m"); /* Red. */
765
766 switch (nbytes)
767 {
768 case 2:
769 if (width_remaining < 6)
770 break;
771 printf ("\\u%02x%02x",
772 (bytes[0] & 0x1c) >> 2,
773 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
774 break;
775 case 3:
776 if (width_remaining < 6)
777 break;
778 printf ("\\u%02x%02x",
779 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
780 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
781 break;
782 case 4:
783 if (width_remaining < 8)
784 break;
785 printf ("\\u%02x%02x%02x",
786 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
787 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
788 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
789
790 break;
791 default:
792 /* URG. */
793 break;
794 }
795
796 if (unicode_display == unicode_highlight && isatty (1))
797 printf ("\033[0m"); /* Default colour. */
798 }
799
800 if (bytes[nbytes - 1] == 0)
801 break;
7bfd842d 802 }
961c521f
NC
803 else
804 {
3bfcb652
NC
805#ifdef HAVE_MBSTATE_T
806 wchar_t w;
807#endif
7bfd842d
NC
808 /* Let printf do the hard work of displaying multibyte characters. */
809 printf ("%.1s", symbol - 1);
810 width_remaining --;
811 num_printed ++;
812
3bfcb652 813#ifdef HAVE_MBSTATE_T
7bfd842d
NC
814 /* Try to find out how many bytes made up the character that was
815 just printed. Advance the symbol pointer past the bytes that
816 were displayed. */
817 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
818#else
819 n = 1;
820#endif
7bfd842d
NC
821 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
822 symbol += (n - 1);
961c521f 823 }
961c521f 824 }
171191ba 825
0942c7ab
NC
826 if (do_dots)
827 num_printed += printf ("[...]");
828
7bfd842d 829 if (extra_padding && num_printed < width)
171191ba
NC
830 {
831 /* Fill in the remaining spaces. */
7bfd842d
NC
832 printf ("%-*s", width - num_printed, " ");
833 num_printed = width;
171191ba
NC
834 }
835
79bc120c 836 free ((void *) alloced_symbol);
171191ba 837 return num_printed;
31104126
NC
838}
839
1449284b 840/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
841 the given section's name. Like print_symbol, except that it does not try
842 to print multibyte characters, it just interprets them as hex values. */
843
844static const char *
dda8d76d 845printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 846{
ca0e11aa 847#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 848 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 849 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
850 char * buf = sec_name_buf;
851 char c;
852 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
853
854 while ((c = * name ++) != 0)
855 {
856 if (ISCNTRL (c))
857 {
858 if (remaining < 2)
859 break;
948f632f 860
74e1a04b
NC
861 * buf ++ = '^';
862 * buf ++ = c + 0x40;
863 remaining -= 2;
864 }
865 else if (ISPRINT (c))
866 {
867 * buf ++ = c;
868 remaining -= 1;
869 }
870 else
871 {
872 static char hex[17] = "0123456789ABCDEF";
873
874 if (remaining < 4)
875 break;
876 * buf ++ = '<';
877 * buf ++ = hex[(c & 0xf0) >> 4];
878 * buf ++ = hex[c & 0x0f];
879 * buf ++ = '>';
880 remaining -= 4;
881 }
882
883 if (remaining == 0)
884 break;
885 }
886
887 * buf = 0;
888 return sec_name_buf;
889}
890
891static const char *
dda8d76d 892printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 893{
dda8d76d 894 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
895 return _("<corrupt>");
896
dda8d76d 897 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
898}
899
89fac5e3
RS
900/* Return a pointer to section NAME, or NULL if no such section exists. */
901
902static Elf_Internal_Shdr *
dda8d76d 903find_section (Filedata * filedata, const char * name)
89fac5e3
RS
904{
905 unsigned int i;
906
68807c3c
NC
907 if (filedata->section_headers == NULL)
908 return NULL;
dda8d76d
NC
909
910 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
911 if (section_name_valid (filedata, filedata->section_headers + i)
912 && streq (section_name (filedata, filedata->section_headers + i),
913 name))
dda8d76d 914 return filedata->section_headers + i;
89fac5e3
RS
915
916 return NULL;
917}
918
0b6ae522
DJ
919/* Return a pointer to a section containing ADDR, or NULL if no such
920 section exists. */
921
922static Elf_Internal_Shdr *
dda8d76d 923find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
924{
925 unsigned int i;
926
68807c3c
NC
927 if (filedata->section_headers == NULL)
928 return NULL;
929
dda8d76d 930 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 931 {
dda8d76d
NC
932 Elf_Internal_Shdr *sec = filedata->section_headers + i;
933
0b6ae522
DJ
934 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
935 return sec;
936 }
937
938 return NULL;
939}
940
071436c6 941static Elf_Internal_Shdr *
dda8d76d 942find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
943{
944 unsigned int i;
945
68807c3c
NC
946 if (filedata->section_headers == NULL)
947 return NULL;
948
dda8d76d 949 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 950 {
dda8d76d
NC
951 Elf_Internal_Shdr *sec = filedata->section_headers + i;
952
071436c6
NC
953 if (sec->sh_type == type)
954 return sec;
955 }
956
957 return NULL;
958}
959
657d0d47
CC
960/* Return a pointer to section NAME, or NULL if no such section exists,
961 restricted to the list of sections given in SET. */
962
963static Elf_Internal_Shdr *
dda8d76d 964find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
965{
966 unsigned int i;
967
68807c3c
NC
968 if (filedata->section_headers == NULL)
969 return NULL;
970
657d0d47
CC
971 if (set != NULL)
972 {
973 while ((i = *set++) > 0)
b814a36d
NC
974 {
975 /* See PR 21156 for a reproducer. */
dda8d76d 976 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
977 continue; /* FIXME: Should we issue an error message ? */
978
84714f86
AM
979 if (section_name_valid (filedata, filedata->section_headers + i)
980 && streq (section_name (filedata, filedata->section_headers + i),
981 name))
dda8d76d 982 return filedata->section_headers + i;
b814a36d 983 }
657d0d47
CC
984 }
985
dda8d76d 986 return find_section (filedata, name);
657d0d47
CC
987}
988
32ec8896 989/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
990 This OS has so many departures from the ELF standard that we test it at
991 many places. */
992
015dc7e1 993static inline bool
dda8d76d 994is_ia64_vms (Filedata * filedata)
28f997cf 995{
dda8d76d
NC
996 return filedata->file_header.e_machine == EM_IA_64
997 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
998}
999
bcedfee6 1000/* Guess the relocation size commonly used by the specific machines. */
252b5132 1001
015dc7e1 1002static bool
2dc4cec1 1003guess_is_rela (unsigned int e_machine)
252b5132 1004{
9c19a809 1005 switch (e_machine)
252b5132
RH
1006 {
1007 /* Targets that use REL relocations. */
252b5132 1008 case EM_386:
22abe556 1009 case EM_IAMCU:
f954747f 1010 case EM_960:
e9f53129 1011 case EM_ARM:
2b0337b0 1012 case EM_D10V:
252b5132 1013 case EM_CYGNUS_D10V:
e9f53129 1014 case EM_DLX:
252b5132 1015 case EM_MIPS:
4fe85591 1016 case EM_MIPS_RS3_LE:
e9f53129 1017 case EM_CYGNUS_M32R:
1c0d3aa6 1018 case EM_SCORE:
f6c1a2d5 1019 case EM_XGATE:
fe944acf 1020 case EM_NFP:
aca4efc7 1021 case EM_BPF:
015dc7e1 1022 return false;
103f02d3 1023
252b5132
RH
1024 /* Targets that use RELA relocations. */
1025 case EM_68K:
f954747f 1026 case EM_860:
a06ea964 1027 case EM_AARCH64:
cfb8c092 1028 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1029 case EM_ALPHA:
1030 case EM_ALTERA_NIOS2:
886a2506
NC
1031 case EM_ARC:
1032 case EM_ARC_COMPACT:
1033 case EM_ARC_COMPACT2:
e9f53129
AM
1034 case EM_AVR:
1035 case EM_AVR_OLD:
1036 case EM_BLACKFIN:
60bca95a 1037 case EM_CR16:
e9f53129
AM
1038 case EM_CRIS:
1039 case EM_CRX:
b8891f8d 1040 case EM_CSKY:
2b0337b0 1041 case EM_D30V:
252b5132 1042 case EM_CYGNUS_D30V:
2b0337b0 1043 case EM_FR30:
3f8107ab 1044 case EM_FT32:
252b5132 1045 case EM_CYGNUS_FR30:
5c70f934 1046 case EM_CYGNUS_FRV:
e9f53129
AM
1047 case EM_H8S:
1048 case EM_H8_300:
1049 case EM_H8_300H:
800eeca4 1050 case EM_IA_64:
1e4cf259
NC
1051 case EM_IP2K:
1052 case EM_IP2K_OLD:
3b36097d 1053 case EM_IQ2000:
84e94c90 1054 case EM_LATTICEMICO32:
ff7eeb89 1055 case EM_M32C_OLD:
49f58d10 1056 case EM_M32C:
e9f53129
AM
1057 case EM_M32R:
1058 case EM_MCORE:
15ab5209 1059 case EM_CYGNUS_MEP:
a3c62988 1060 case EM_METAG:
e9f53129
AM
1061 case EM_MMIX:
1062 case EM_MN10200:
1063 case EM_CYGNUS_MN10200:
1064 case EM_MN10300:
1065 case EM_CYGNUS_MN10300:
5506d11a 1066 case EM_MOXIE:
e9f53129
AM
1067 case EM_MSP430:
1068 case EM_MSP430_OLD:
d031aafb 1069 case EM_MT:
35c08157 1070 case EM_NDS32:
64fd6348 1071 case EM_NIOS32:
73589c9d 1072 case EM_OR1K:
e9f53129
AM
1073 case EM_PPC64:
1074 case EM_PPC:
2b100bb5 1075 case EM_TI_PRU:
e23eba97 1076 case EM_RISCV:
99c513f6 1077 case EM_RL78:
c7927a3c 1078 case EM_RX:
e9f53129
AM
1079 case EM_S390:
1080 case EM_S390_OLD:
1081 case EM_SH:
1082 case EM_SPARC:
1083 case EM_SPARC32PLUS:
1084 case EM_SPARCV9:
1085 case EM_SPU:
40b36596 1086 case EM_TI_C6000:
aa137e4d
NC
1087 case EM_TILEGX:
1088 case EM_TILEPRO:
708e2187 1089 case EM_V800:
e9f53129
AM
1090 case EM_V850:
1091 case EM_CYGNUS_V850:
1092 case EM_VAX:
619ed720 1093 case EM_VISIUM:
e9f53129 1094 case EM_X86_64:
8a9036a4 1095 case EM_L1OM:
7a9068fe 1096 case EM_K1OM:
e9f53129
AM
1097 case EM_XSTORMY16:
1098 case EM_XTENSA:
1099 case EM_XTENSA_OLD:
7ba29e2a
NC
1100 case EM_MICROBLAZE:
1101 case EM_MICROBLAZE_OLD:
f96bd6c2 1102 case EM_WEBASSEMBLY:
015dc7e1 1103 return true;
103f02d3 1104
e9f53129
AM
1105 case EM_68HC05:
1106 case EM_68HC08:
1107 case EM_68HC11:
1108 case EM_68HC16:
1109 case EM_FX66:
1110 case EM_ME16:
d1133906 1111 case EM_MMA:
d1133906
NC
1112 case EM_NCPU:
1113 case EM_NDR1:
e9f53129 1114 case EM_PCP:
d1133906 1115 case EM_ST100:
e9f53129 1116 case EM_ST19:
d1133906 1117 case EM_ST7:
e9f53129
AM
1118 case EM_ST9PLUS:
1119 case EM_STARCORE:
d1133906 1120 case EM_SVX:
e9f53129 1121 case EM_TINYJ:
9c19a809
NC
1122 default:
1123 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1124 return false;
9c19a809
NC
1125 }
1126}
252b5132 1127
dda8d76d 1128/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1129 Returns TRUE upon success, FALSE otherwise. If successful then a
1130 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1131 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1132 responsibility to free the allocated buffer. */
1133
015dc7e1 1134static bool
dda8d76d
NC
1135slurp_rela_relocs (Filedata * filedata,
1136 unsigned long rel_offset,
1137 unsigned long rel_size,
1138 Elf_Internal_Rela ** relasp,
1139 unsigned long * nrelasp)
9c19a809 1140{
2cf0635d 1141 Elf_Internal_Rela * relas;
8b73c356 1142 size_t nrelas;
4d6ed7c8 1143 unsigned int i;
252b5132 1144
4d6ed7c8
NC
1145 if (is_32bit_elf)
1146 {
2cf0635d 1147 Elf32_External_Rela * erelas;
103f02d3 1148
dda8d76d 1149 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1150 rel_size, _("32-bit relocation data"));
a6e9f9df 1151 if (!erelas)
015dc7e1 1152 return false;
252b5132 1153
4d6ed7c8 1154 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1155
3f5e193b
NC
1156 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1157 sizeof (Elf_Internal_Rela));
103f02d3 1158
4d6ed7c8
NC
1159 if (relas == NULL)
1160 {
c256ffe7 1161 free (erelas);
591a748a 1162 error (_("out of memory parsing relocs\n"));
015dc7e1 1163 return false;
4d6ed7c8 1164 }
103f02d3 1165
4d6ed7c8
NC
1166 for (i = 0; i < nrelas; i++)
1167 {
1168 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1169 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1170 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1171 }
103f02d3 1172
4d6ed7c8
NC
1173 free (erelas);
1174 }
1175 else
1176 {
2cf0635d 1177 Elf64_External_Rela * erelas;
103f02d3 1178
dda8d76d 1179 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1180 rel_size, _("64-bit relocation data"));
a6e9f9df 1181 if (!erelas)
015dc7e1 1182 return false;
4d6ed7c8
NC
1183
1184 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1185
3f5e193b
NC
1186 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1187 sizeof (Elf_Internal_Rela));
103f02d3 1188
4d6ed7c8
NC
1189 if (relas == NULL)
1190 {
c256ffe7 1191 free (erelas);
591a748a 1192 error (_("out of memory parsing relocs\n"));
015dc7e1 1193 return false;
9c19a809 1194 }
4d6ed7c8
NC
1195
1196 for (i = 0; i < nrelas; i++)
9c19a809 1197 {
66543521
AM
1198 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1199 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1200 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1201
1202 /* The #ifdef BFD64 below is to prevent a compile time
1203 warning. We know that if we do not have a 64 bit data
1204 type that we will never execute this code anyway. */
1205#ifdef BFD64
dda8d76d
NC
1206 if (filedata->file_header.e_machine == EM_MIPS
1207 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1208 {
1209 /* In little-endian objects, r_info isn't really a
1210 64-bit little-endian value: it has a 32-bit
1211 little-endian symbol index followed by four
1212 individual byte fields. Reorder INFO
1213 accordingly. */
91d6fa6a
NC
1214 bfd_vma inf = relas[i].r_info;
1215 inf = (((inf & 0xffffffff) << 32)
1216 | ((inf >> 56) & 0xff)
1217 | ((inf >> 40) & 0xff00)
1218 | ((inf >> 24) & 0xff0000)
1219 | ((inf >> 8) & 0xff000000));
1220 relas[i].r_info = inf;
861fb55a
DJ
1221 }
1222#endif /* BFD64 */
4d6ed7c8 1223 }
103f02d3 1224
4d6ed7c8
NC
1225 free (erelas);
1226 }
32ec8896 1227
4d6ed7c8
NC
1228 *relasp = relas;
1229 *nrelasp = nrelas;
015dc7e1 1230 return true;
4d6ed7c8 1231}
103f02d3 1232
dda8d76d 1233/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1234 Returns TRUE upon success, FALSE otherwise. If successful then a
1235 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1236 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1237 responsibility to free the allocated buffer. */
1238
015dc7e1 1239static bool
dda8d76d
NC
1240slurp_rel_relocs (Filedata * filedata,
1241 unsigned long rel_offset,
1242 unsigned long rel_size,
1243 Elf_Internal_Rela ** relsp,
1244 unsigned long * nrelsp)
4d6ed7c8 1245{
2cf0635d 1246 Elf_Internal_Rela * rels;
8b73c356 1247 size_t nrels;
4d6ed7c8 1248 unsigned int i;
103f02d3 1249
4d6ed7c8
NC
1250 if (is_32bit_elf)
1251 {
2cf0635d 1252 Elf32_External_Rel * erels;
103f02d3 1253
dda8d76d 1254 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1255 rel_size, _("32-bit relocation data"));
a6e9f9df 1256 if (!erels)
015dc7e1 1257 return false;
103f02d3 1258
4d6ed7c8 1259 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1260
3f5e193b 1261 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1262
4d6ed7c8
NC
1263 if (rels == NULL)
1264 {
c256ffe7 1265 free (erels);
591a748a 1266 error (_("out of memory parsing relocs\n"));
015dc7e1 1267 return false;
4d6ed7c8
NC
1268 }
1269
1270 for (i = 0; i < nrels; i++)
1271 {
1272 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1273 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1274 rels[i].r_addend = 0;
9ea033b2 1275 }
4d6ed7c8
NC
1276
1277 free (erels);
9c19a809
NC
1278 }
1279 else
1280 {
2cf0635d 1281 Elf64_External_Rel * erels;
9ea033b2 1282
dda8d76d 1283 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1284 rel_size, _("64-bit relocation data"));
a6e9f9df 1285 if (!erels)
015dc7e1 1286 return false;
103f02d3 1287
4d6ed7c8 1288 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1289
3f5e193b 1290 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1291
4d6ed7c8 1292 if (rels == NULL)
9c19a809 1293 {
c256ffe7 1294 free (erels);
591a748a 1295 error (_("out of memory parsing relocs\n"));
015dc7e1 1296 return false;
4d6ed7c8 1297 }
103f02d3 1298
4d6ed7c8
NC
1299 for (i = 0; i < nrels; i++)
1300 {
66543521
AM
1301 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1302 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1303 rels[i].r_addend = 0;
861fb55a
DJ
1304
1305 /* The #ifdef BFD64 below is to prevent a compile time
1306 warning. We know that if we do not have a 64 bit data
1307 type that we will never execute this code anyway. */
1308#ifdef BFD64
dda8d76d
NC
1309 if (filedata->file_header.e_machine == EM_MIPS
1310 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1311 {
1312 /* In little-endian objects, r_info isn't really a
1313 64-bit little-endian value: it has a 32-bit
1314 little-endian symbol index followed by four
1315 individual byte fields. Reorder INFO
1316 accordingly. */
91d6fa6a
NC
1317 bfd_vma inf = rels[i].r_info;
1318 inf = (((inf & 0xffffffff) << 32)
1319 | ((inf >> 56) & 0xff)
1320 | ((inf >> 40) & 0xff00)
1321 | ((inf >> 24) & 0xff0000)
1322 | ((inf >> 8) & 0xff000000));
1323 rels[i].r_info = inf;
861fb55a
DJ
1324 }
1325#endif /* BFD64 */
4d6ed7c8 1326 }
103f02d3 1327
4d6ed7c8
NC
1328 free (erels);
1329 }
32ec8896 1330
4d6ed7c8
NC
1331 *relsp = rels;
1332 *nrelsp = nrels;
015dc7e1 1333 return true;
4d6ed7c8 1334}
103f02d3 1335
a7fd1186
FS
1336static bool
1337slurp_relr_relocs (Filedata * filedata,
1338 unsigned long relr_offset,
1339 unsigned long relr_size,
1340 bfd_vma ** relrsp,
1341 unsigned long * nrelrsp)
1342{
1343 void *relrs;
1344 size_t size = 0, nentries, i;
1345 bfd_vma base = 0, addr, entry;
1346
1347 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1348 _("RELR relocation data"));
1349 if (!relrs)
1350 return false;
1351
1352 if (is_32bit_elf)
1353 nentries = relr_size / sizeof (Elf32_External_Relr);
1354 else
1355 nentries = relr_size / sizeof (Elf64_External_Relr);
1356 for (i = 0; i < nentries; i++)
1357 {
1358 if (is_32bit_elf)
1359 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1360 else
1361 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1362 if ((entry & 1) == 0)
1363 size++;
1364 else
1365 while ((entry >>= 1) != 0)
1366 if ((entry & 1) == 1)
1367 size++;
1368 }
1369
4491a7c1 1370 *relrsp = (bfd_vma *) malloc (size * sizeof (bfd_vma));
a7fd1186
FS
1371 if (*relrsp == NULL)
1372 {
1373 free (relrs);
1374 error (_("out of memory parsing relocs\n"));
1375 return false;
1376 }
1377
1378 size = 0;
1379 for (i = 0; i < nentries; i++)
1380 {
1381 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1382
1383 if (is_32bit_elf)
1384 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1385 else
1386 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1387 if ((entry & 1) == 0)
1388 {
1389 (*relrsp)[size++] = entry;
1390 base = entry + entry_bytes;
1391 }
1392 else
1393 {
1394 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1395 if ((entry & 1) != 0)
1396 (*relrsp)[size++] = addr;
1397 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1398 }
1399 }
1400
1401 *nrelrsp = size;
1402 free (relrs);
1403 return true;
1404}
1405
aca88567
NC
1406/* Returns the reloc type extracted from the reloc info field. */
1407
1408static unsigned int
dda8d76d 1409get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1410{
1411 if (is_32bit_elf)
1412 return ELF32_R_TYPE (reloc_info);
1413
dda8d76d 1414 switch (filedata->file_header.e_machine)
aca88567
NC
1415 {
1416 case EM_MIPS:
1417 /* Note: We assume that reloc_info has already been adjusted for us. */
1418 return ELF64_MIPS_R_TYPE (reloc_info);
1419
1420 case EM_SPARCV9:
1421 return ELF64_R_TYPE_ID (reloc_info);
1422
1423 default:
1424 return ELF64_R_TYPE (reloc_info);
1425 }
1426}
1427
1428/* Return the symbol index extracted from the reloc info field. */
1429
1430static bfd_vma
1431get_reloc_symindex (bfd_vma reloc_info)
1432{
1433 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1434}
1435
015dc7e1 1436static inline bool
dda8d76d 1437uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1438{
1439 return
dda8d76d 1440 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1441 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1442 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1443 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1444 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1445}
1446
d3ba0551
AM
1447/* Display the contents of the relocation data found at the specified
1448 offset. */
ee42cf8c 1449
015dc7e1 1450static bool
dda8d76d
NC
1451dump_relocations (Filedata * filedata,
1452 unsigned long rel_offset,
1453 unsigned long rel_size,
1454 Elf_Internal_Sym * symtab,
1455 unsigned long nsyms,
1456 char * strtab,
1457 unsigned long strtablen,
a7fd1186 1458 relocation_type rel_type,
015dc7e1 1459 bool is_dynsym)
4d6ed7c8 1460{
32ec8896 1461 unsigned long i;
2cf0635d 1462 Elf_Internal_Rela * rels;
015dc7e1 1463 bool res = true;
103f02d3 1464
a7fd1186
FS
1465 if (rel_type == reltype_unknown)
1466 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1467
a7fd1186 1468 if (rel_type == reltype_rela)
4d6ed7c8 1469 {
dda8d76d 1470 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1471 return false;
4d6ed7c8 1472 }
a7fd1186 1473 else if (rel_type == reltype_rel)
4d6ed7c8 1474 {
dda8d76d 1475 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1476 return false;
252b5132 1477 }
a7fd1186
FS
1478 else if (rel_type == reltype_relr)
1479 {
1480 bfd_vma * relrs;
1481 const char *format
b8281767 1482 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1483
1484 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1485 &rel_size))
1486 return false;
1487
b8281767
AM
1488 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size),
1489 rel_size);
a7fd1186 1490 for (i = 0; i < rel_size; i++)
b8281767 1491 printf (format, (uint64_t) relrs[i]);
a7fd1186
FS
1492 free (relrs);
1493 return true;
1494 }
252b5132 1495
410f7a12
L
1496 if (is_32bit_elf)
1497 {
a7fd1186 1498 if (rel_type == reltype_rela)
2c71103e
NC
1499 {
1500 if (do_wide)
1501 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1502 else
1503 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1504 }
410f7a12 1505 else
2c71103e
NC
1506 {
1507 if (do_wide)
1508 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1509 else
1510 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1511 }
410f7a12 1512 }
252b5132 1513 else
410f7a12 1514 {
a7fd1186 1515 if (rel_type == reltype_rela)
2c71103e
NC
1516 {
1517 if (do_wide)
8beeaeb7 1518 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1519 else
1520 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1521 }
410f7a12 1522 else
2c71103e
NC
1523 {
1524 if (do_wide)
8beeaeb7 1525 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1526 else
1527 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1528 }
410f7a12 1529 }
252b5132
RH
1530
1531 for (i = 0; i < rel_size; i++)
1532 {
2cf0635d 1533 const char * rtype;
b34976b6 1534 bfd_vma offset;
91d6fa6a 1535 bfd_vma inf;
b34976b6
AM
1536 bfd_vma symtab_index;
1537 bfd_vma type;
103f02d3 1538
b34976b6 1539 offset = rels[i].r_offset;
91d6fa6a 1540 inf = rels[i].r_info;
103f02d3 1541
dda8d76d 1542 type = get_reloc_type (filedata, inf);
91d6fa6a 1543 symtab_index = get_reloc_symindex (inf);
252b5132 1544
410f7a12
L
1545 if (is_32bit_elf)
1546 {
39dbeff8
AM
1547 printf ("%8.8lx %8.8lx ",
1548 (unsigned long) offset & 0xffffffff,
91d6fa6a 1549 (unsigned long) inf & 0xffffffff);
410f7a12
L
1550 }
1551 else
1552 {
39dbeff8 1553 printf (do_wide
b8281767
AM
1554 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1555 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
1556 (uint64_t) offset, (uint64_t) inf);
410f7a12 1557 }
103f02d3 1558
dda8d76d 1559 switch (filedata->file_header.e_machine)
252b5132
RH
1560 {
1561 default:
1562 rtype = NULL;
1563 break;
1564
a06ea964
NC
1565 case EM_AARCH64:
1566 rtype = elf_aarch64_reloc_type (type);
1567 break;
1568
2b0337b0 1569 case EM_M32R:
252b5132 1570 case EM_CYGNUS_M32R:
9ea033b2 1571 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1572 break;
1573
1574 case EM_386:
22abe556 1575 case EM_IAMCU:
9ea033b2 1576 rtype = elf_i386_reloc_type (type);
252b5132
RH
1577 break;
1578
ba2685cc
AM
1579 case EM_68HC11:
1580 case EM_68HC12:
1581 rtype = elf_m68hc11_reloc_type (type);
1582 break;
75751cd9 1583
7b4ae824
JD
1584 case EM_S12Z:
1585 rtype = elf_s12z_reloc_type (type);
1586 break;
1587
252b5132 1588 case EM_68K:
9ea033b2 1589 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1590 break;
1591
f954747f
AM
1592 case EM_960:
1593 rtype = elf_i960_reloc_type (type);
1594 break;
1595
adde6300 1596 case EM_AVR:
2b0337b0 1597 case EM_AVR_OLD:
adde6300
AM
1598 rtype = elf_avr_reloc_type (type);
1599 break;
1600
9ea033b2
NC
1601 case EM_OLD_SPARCV9:
1602 case EM_SPARC32PLUS:
1603 case EM_SPARCV9:
252b5132 1604 case EM_SPARC:
9ea033b2 1605 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1606 break;
1607
e9f53129
AM
1608 case EM_SPU:
1609 rtype = elf_spu_reloc_type (type);
1610 break;
1611
708e2187
NC
1612 case EM_V800:
1613 rtype = v800_reloc_type (type);
1614 break;
2b0337b0 1615 case EM_V850:
252b5132 1616 case EM_CYGNUS_V850:
9ea033b2 1617 rtype = v850_reloc_type (type);
252b5132
RH
1618 break;
1619
2b0337b0 1620 case EM_D10V:
252b5132 1621 case EM_CYGNUS_D10V:
9ea033b2 1622 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1623 break;
1624
2b0337b0 1625 case EM_D30V:
252b5132 1626 case EM_CYGNUS_D30V:
9ea033b2 1627 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1628 break;
1629
d172d4ba
NC
1630 case EM_DLX:
1631 rtype = elf_dlx_reloc_type (type);
1632 break;
1633
252b5132 1634 case EM_SH:
9ea033b2 1635 rtype = elf_sh_reloc_type (type);
252b5132
RH
1636 break;
1637
2b0337b0 1638 case EM_MN10300:
252b5132 1639 case EM_CYGNUS_MN10300:
9ea033b2 1640 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1641 break;
1642
2b0337b0 1643 case EM_MN10200:
252b5132 1644 case EM_CYGNUS_MN10200:
9ea033b2 1645 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1646 break;
1647
2b0337b0 1648 case EM_FR30:
252b5132 1649 case EM_CYGNUS_FR30:
9ea033b2 1650 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1651 break;
1652
ba2685cc
AM
1653 case EM_CYGNUS_FRV:
1654 rtype = elf_frv_reloc_type (type);
1655 break;
5c70f934 1656
b8891f8d
AJ
1657 case EM_CSKY:
1658 rtype = elf_csky_reloc_type (type);
1659 break;
1660
3f8107ab
AM
1661 case EM_FT32:
1662 rtype = elf_ft32_reloc_type (type);
1663 break;
1664
252b5132 1665 case EM_MCORE:
9ea033b2 1666 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1667 break;
1668
3c3bdf30
NC
1669 case EM_MMIX:
1670 rtype = elf_mmix_reloc_type (type);
1671 break;
1672
5506d11a
AM
1673 case EM_MOXIE:
1674 rtype = elf_moxie_reloc_type (type);
1675 break;
1676
2469cfa2 1677 case EM_MSP430:
dda8d76d 1678 if (uses_msp430x_relocs (filedata))
13761a11
NC
1679 {
1680 rtype = elf_msp430x_reloc_type (type);
1681 break;
1682 }
1a0670f3 1683 /* Fall through. */
2469cfa2
NC
1684 case EM_MSP430_OLD:
1685 rtype = elf_msp430_reloc_type (type);
1686 break;
1687
35c08157
KLC
1688 case EM_NDS32:
1689 rtype = elf_nds32_reloc_type (type);
1690 break;
1691
252b5132 1692 case EM_PPC:
9ea033b2 1693 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1694 break;
1695
c833c019
AM
1696 case EM_PPC64:
1697 rtype = elf_ppc64_reloc_type (type);
1698 break;
1699
252b5132 1700 case EM_MIPS:
4fe85591 1701 case EM_MIPS_RS3_LE:
9ea033b2 1702 rtype = elf_mips_reloc_type (type);
252b5132
RH
1703 break;
1704
e23eba97
NC
1705 case EM_RISCV:
1706 rtype = elf_riscv_reloc_type (type);
1707 break;
1708
252b5132 1709 case EM_ALPHA:
9ea033b2 1710 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1711 break;
1712
1713 case EM_ARM:
9ea033b2 1714 rtype = elf_arm_reloc_type (type);
252b5132
RH
1715 break;
1716
584da044 1717 case EM_ARC:
886a2506
NC
1718 case EM_ARC_COMPACT:
1719 case EM_ARC_COMPACT2:
9ea033b2 1720 rtype = elf_arc_reloc_type (type);
252b5132
RH
1721 break;
1722
1723 case EM_PARISC:
69e617ca 1724 rtype = elf_hppa_reloc_type (type);
252b5132 1725 break;
7d466069 1726
b8720f9d
JL
1727 case EM_H8_300:
1728 case EM_H8_300H:
1729 case EM_H8S:
1730 rtype = elf_h8_reloc_type (type);
1731 break;
1732
73589c9d
CS
1733 case EM_OR1K:
1734 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1735 break;
1736
7d466069 1737 case EM_PJ:
2b0337b0 1738 case EM_PJ_OLD:
7d466069
ILT
1739 rtype = elf_pj_reloc_type (type);
1740 break;
800eeca4
JW
1741 case EM_IA_64:
1742 rtype = elf_ia64_reloc_type (type);
1743 break;
1b61cf92
HPN
1744
1745 case EM_CRIS:
1746 rtype = elf_cris_reloc_type (type);
1747 break;
535c37ff 1748
f954747f
AM
1749 case EM_860:
1750 rtype = elf_i860_reloc_type (type);
1751 break;
1752
bcedfee6 1753 case EM_X86_64:
8a9036a4 1754 case EM_L1OM:
7a9068fe 1755 case EM_K1OM:
bcedfee6
NC
1756 rtype = elf_x86_64_reloc_type (type);
1757 break;
a85d7ed0 1758
f954747f
AM
1759 case EM_S370:
1760 rtype = i370_reloc_type (type);
1761 break;
1762
53c7db4b
KH
1763 case EM_S390_OLD:
1764 case EM_S390:
1765 rtype = elf_s390_reloc_type (type);
1766 break;
93fbbb04 1767
1c0d3aa6
NC
1768 case EM_SCORE:
1769 rtype = elf_score_reloc_type (type);
1770 break;
1771
93fbbb04
GK
1772 case EM_XSTORMY16:
1773 rtype = elf_xstormy16_reloc_type (type);
1774 break;
179d3252 1775
1fe1f39c
NC
1776 case EM_CRX:
1777 rtype = elf_crx_reloc_type (type);
1778 break;
1779
179d3252
JT
1780 case EM_VAX:
1781 rtype = elf_vax_reloc_type (type);
1782 break;
1e4cf259 1783
619ed720
EB
1784 case EM_VISIUM:
1785 rtype = elf_visium_reloc_type (type);
1786 break;
1787
aca4efc7
JM
1788 case EM_BPF:
1789 rtype = elf_bpf_reloc_type (type);
1790 break;
1791
cfb8c092
NC
1792 case EM_ADAPTEVA_EPIPHANY:
1793 rtype = elf_epiphany_reloc_type (type);
1794 break;
1795
1e4cf259
NC
1796 case EM_IP2K:
1797 case EM_IP2K_OLD:
1798 rtype = elf_ip2k_reloc_type (type);
1799 break;
3b36097d
SC
1800
1801 case EM_IQ2000:
1802 rtype = elf_iq2000_reloc_type (type);
1803 break;
88da6820
NC
1804
1805 case EM_XTENSA_OLD:
1806 case EM_XTENSA:
1807 rtype = elf_xtensa_reloc_type (type);
1808 break;
a34e3ecb 1809
84e94c90
NC
1810 case EM_LATTICEMICO32:
1811 rtype = elf_lm32_reloc_type (type);
1812 break;
1813
ff7eeb89 1814 case EM_M32C_OLD:
49f58d10
JB
1815 case EM_M32C:
1816 rtype = elf_m32c_reloc_type (type);
1817 break;
1818
d031aafb
NS
1819 case EM_MT:
1820 rtype = elf_mt_reloc_type (type);
a34e3ecb 1821 break;
1d65ded4
CM
1822
1823 case EM_BLACKFIN:
1824 rtype = elf_bfin_reloc_type (type);
1825 break;
15ab5209
DB
1826
1827 case EM_CYGNUS_MEP:
1828 rtype = elf_mep_reloc_type (type);
1829 break;
60bca95a
NC
1830
1831 case EM_CR16:
1832 rtype = elf_cr16_reloc_type (type);
1833 break;
dd24e3da 1834
7ba29e2a
NC
1835 case EM_MICROBLAZE:
1836 case EM_MICROBLAZE_OLD:
1837 rtype = elf_microblaze_reloc_type (type);
1838 break;
c7927a3c 1839
99c513f6
DD
1840 case EM_RL78:
1841 rtype = elf_rl78_reloc_type (type);
1842 break;
1843
c7927a3c
NC
1844 case EM_RX:
1845 rtype = elf_rx_reloc_type (type);
1846 break;
c29aca4a 1847
a3c62988
NC
1848 case EM_METAG:
1849 rtype = elf_metag_reloc_type (type);
1850 break;
1851
40b36596
JM
1852 case EM_TI_C6000:
1853 rtype = elf_tic6x_reloc_type (type);
1854 break;
aa137e4d
NC
1855
1856 case EM_TILEGX:
1857 rtype = elf_tilegx_reloc_type (type);
1858 break;
1859
1860 case EM_TILEPRO:
1861 rtype = elf_tilepro_reloc_type (type);
1862 break;
f6c1a2d5 1863
f96bd6c2
PC
1864 case EM_WEBASSEMBLY:
1865 rtype = elf_wasm32_reloc_type (type);
1866 break;
1867
f6c1a2d5
NC
1868 case EM_XGATE:
1869 rtype = elf_xgate_reloc_type (type);
1870 break;
36591ba1
SL
1871
1872 case EM_ALTERA_NIOS2:
1873 rtype = elf_nios2_reloc_type (type);
1874 break;
2b100bb5
DD
1875
1876 case EM_TI_PRU:
1877 rtype = elf_pru_reloc_type (type);
1878 break;
fe944acf
FT
1879
1880 case EM_NFP:
1881 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1882 rtype = elf_nfp3200_reloc_type (type);
1883 else
1884 rtype = elf_nfp_reloc_type (type);
1885 break;
6655dba2
SB
1886
1887 case EM_Z80:
1888 rtype = elf_z80_reloc_type (type);
1889 break;
e9a0721f 1890
1891 case EM_LOONGARCH:
1892 rtype = elf_loongarch_reloc_type (type);
1893 break;
1894
0c857ef4
SM
1895 case EM_AMDGPU:
1896 rtype = elf_amdgpu_reloc_type (type);
1897 break;
252b5132
RH
1898 }
1899
1900 if (rtype == NULL)
39dbeff8 1901 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1902 else
5c144731 1903 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1904
dda8d76d 1905 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1906 && rtype != NULL
7ace3541 1907 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1908 && rel_type == reltype_rela)
7ace3541
RH
1909 {
1910 switch (rels[i].r_addend)
1911 {
1912 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1913 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1914 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1915 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1916 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1917 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1918 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1919 default: rtype = NULL;
1920 }
32ec8896 1921
7ace3541
RH
1922 if (rtype)
1923 printf (" (%s)", rtype);
1924 else
1925 {
1926 putchar (' ');
1927 printf (_("<unknown addend: %lx>"),
1928 (unsigned long) rels[i].r_addend);
015dc7e1 1929 res = false;
7ace3541
RH
1930 }
1931 }
1932 else if (symtab_index)
252b5132 1933 {
af3fc3bc 1934 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1935 {
27a45f42
AS
1936 error (_(" bad symbol index: %08lx in reloc\n"),
1937 (unsigned long) symtab_index);
015dc7e1 1938 res = false;
32ec8896 1939 }
af3fc3bc 1940 else
19936277 1941 {
2cf0635d 1942 Elf_Internal_Sym * psym;
bb4d2ac2
L
1943 const char * version_string;
1944 enum versioned_symbol_info sym_info;
1945 unsigned short vna_other;
19936277 1946
af3fc3bc 1947 psym = symtab + symtab_index;
103f02d3 1948
bb4d2ac2 1949 version_string
dda8d76d 1950 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1951 strtab, strtablen,
1952 symtab_index,
1953 psym,
1954 &sym_info,
1955 &vna_other);
1956
af3fc3bc 1957 printf (" ");
171191ba 1958
d8045f23
NC
1959 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1960 {
1961 const char * name;
1962 unsigned int len;
1963 unsigned int width = is_32bit_elf ? 8 : 14;
1964
1965 /* Relocations against GNU_IFUNC symbols do not use the value
1966 of the symbol as the address to relocate against. Instead
1967 they invoke the function named by the symbol and use its
1968 result as the address for relocation.
1969
1970 To indicate this to the user, do not display the value of
1971 the symbol in the "Symbols's Value" field. Instead show
1972 its name followed by () as a hint that the symbol is
1973 invoked. */
1974
1975 if (strtab == NULL
1976 || psym->st_name == 0
1977 || psym->st_name >= strtablen)
1978 name = "??";
1979 else
1980 name = strtab + psym->st_name;
1981
1982 len = print_symbol (width, name);
bb4d2ac2
L
1983 if (version_string)
1984 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1985 version_string);
d8045f23
NC
1986 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1987 }
1988 else
1989 {
1990 print_vma (psym->st_value, LONG_HEX);
171191ba 1991
d8045f23
NC
1992 printf (is_32bit_elf ? " " : " ");
1993 }
103f02d3 1994
af3fc3bc 1995 if (psym->st_name == 0)
f1ef08cb 1996 {
2cf0635d 1997 const char * sec_name = "<null>";
f1ef08cb
AM
1998 char name_buf[40];
1999
2000 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2001 {
b9af6379
AM
2002 if (psym->st_shndx < filedata->file_header.e_shnum
2003 && filedata->section_headers != NULL)
84714f86
AM
2004 sec_name = section_name_print (filedata,
2005 filedata->section_headers
b9e920ec 2006 + psym->st_shndx);
f1ef08cb
AM
2007 else if (psym->st_shndx == SHN_ABS)
2008 sec_name = "ABS";
2009 else if (psym->st_shndx == SHN_COMMON)
2010 sec_name = "COMMON";
dda8d76d 2011 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2012 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2013 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2014 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2015 sec_name = "SCOMMON";
dda8d76d 2016 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2017 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2018 sec_name = "SUNDEF";
dda8d76d
NC
2019 else if ((filedata->file_header.e_machine == EM_X86_64
2020 || filedata->file_header.e_machine == EM_L1OM
2021 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2022 && psym->st_shndx == SHN_X86_64_LCOMMON)
2023 sec_name = "LARGE_COMMON";
dda8d76d
NC
2024 else if (filedata->file_header.e_machine == EM_IA_64
2025 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2026 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2027 sec_name = "ANSI_COM";
dda8d76d 2028 else if (is_ia64_vms (filedata)
148b93f2
NC
2029 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2030 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2031 else
2032 {
2033 sprintf (name_buf, "<section 0x%x>",
2034 (unsigned int) psym->st_shndx);
2035 sec_name = name_buf;
2036 }
2037 }
2038 print_symbol (22, sec_name);
2039 }
af3fc3bc 2040 else if (strtab == NULL)
d79b3d50 2041 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2042 else if (psym->st_name >= strtablen)
32ec8896 2043 {
27a45f42
AS
2044 error (_("<corrupt string table index: %3ld>\n"),
2045 psym->st_name);
015dc7e1 2046 res = false;
32ec8896 2047 }
af3fc3bc 2048 else
bb4d2ac2
L
2049 {
2050 print_symbol (22, strtab + psym->st_name);
2051 if (version_string)
2052 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2053 version_string);
2054 }
103f02d3 2055
a7fd1186 2056 if (rel_type == reltype_rela)
171191ba 2057 {
7360e63f 2058 bfd_vma off = rels[i].r_addend;
171191ba 2059
7360e63f 2060 if ((bfd_signed_vma) off < 0)
b8281767 2061 printf (" - %" PRIx64, (uint64_t) -off);
171191ba 2062 else
b8281767 2063 printf (" + %" PRIx64, (uint64_t) off);
171191ba 2064 }
19936277 2065 }
252b5132 2066 }
a7fd1186 2067 else if (rel_type == reltype_rela)
f7a99963 2068 {
7360e63f 2069 bfd_vma off = rels[i].r_addend;
e04d7088
L
2070
2071 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2072 if ((bfd_signed_vma) off < 0)
b8281767 2073 printf ("-%" PRIx64, (uint64_t) -off);
e04d7088 2074 else
b8281767 2075 printf ("%" PRIx64, (uint64_t) off);
f7a99963 2076 }
252b5132 2077
dda8d76d 2078 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2079 && rtype != NULL
2080 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2081 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2082
252b5132 2083 putchar ('\n');
2c71103e 2084
aca88567 2085#ifdef BFD64
dda8d76d 2086 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2087 {
91d6fa6a
NC
2088 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2089 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2090 const char * rtype2 = elf_mips_reloc_type (type2);
2091 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2092
2c71103e
NC
2093 printf (" Type2: ");
2094
2095 if (rtype2 == NULL)
39dbeff8
AM
2096 printf (_("unrecognized: %-7lx"),
2097 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2098 else
2099 printf ("%-17.17s", rtype2);
2100
18bd398b 2101 printf ("\n Type3: ");
2c71103e
NC
2102
2103 if (rtype3 == NULL)
39dbeff8
AM
2104 printf (_("unrecognized: %-7lx"),
2105 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2106 else
2107 printf ("%-17.17s", rtype3);
2108
53c7db4b 2109 putchar ('\n');
2c71103e 2110 }
aca88567 2111#endif /* BFD64 */
252b5132
RH
2112 }
2113
c8286bd1 2114 free (rels);
32ec8896
NC
2115
2116 return res;
252b5132
RH
2117}
2118
37c18eed
SD
2119static const char *
2120get_aarch64_dynamic_type (unsigned long type)
2121{
2122 switch (type)
2123 {
2124 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2125 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2126 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2127 default:
2128 return NULL;
2129 }
2130}
2131
252b5132 2132static const char *
d3ba0551 2133get_mips_dynamic_type (unsigned long type)
252b5132
RH
2134{
2135 switch (type)
2136 {
2137 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2138 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2139 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2140 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2141 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2142 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2143 case DT_MIPS_MSYM: return "MIPS_MSYM";
2144 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2145 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2146 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2147 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2148 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2149 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2150 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2151 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2152 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2153 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2154 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2155 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2156 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2157 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2158 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2159 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2160 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2161 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2162 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2163 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2164 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2165 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2166 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2167 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2168 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2169 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2170 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2171 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2172 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2173 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2174 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2175 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2176 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2177 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2178 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2179 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2180 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2181 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2182 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2183 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2184 default:
2185 return NULL;
2186 }
2187}
2188
9a097730 2189static const char *
d3ba0551 2190get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2191{
2192 switch (type)
2193 {
2194 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2195 default:
2196 return NULL;
2197 }
103f02d3
UD
2198}
2199
7490d522
AM
2200static const char *
2201get_ppc_dynamic_type (unsigned long type)
2202{
2203 switch (type)
2204 {
a7f2871e 2205 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2206 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2207 default:
2208 return NULL;
2209 }
2210}
2211
f1cb7e17 2212static const char *
d3ba0551 2213get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2214{
2215 switch (type)
2216 {
a7f2871e
AM
2217 case DT_PPC64_GLINK: return "PPC64_GLINK";
2218 case DT_PPC64_OPD: return "PPC64_OPD";
2219 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2220 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2221 default:
2222 return NULL;
2223 }
2224}
2225
103f02d3 2226static const char *
d3ba0551 2227get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2228{
2229 switch (type)
2230 {
2231 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2232 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2233 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2234 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2235 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2236 case DT_HP_PREINIT: return "HP_PREINIT";
2237 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2238 case DT_HP_NEEDED: return "HP_NEEDED";
2239 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2240 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2241 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2242 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2243 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2244 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2245 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2246 case DT_HP_FILTERED: return "HP_FILTERED";
2247 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2248 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2249 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2250 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2251 case DT_PLT: return "PLT";
2252 case DT_PLT_SIZE: return "PLT_SIZE";
2253 case DT_DLT: return "DLT";
2254 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2255 default:
2256 return NULL;
2257 }
2258}
9a097730 2259
ecc51f48 2260static const char *
d3ba0551 2261get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2262{
2263 switch (type)
2264 {
148b93f2
NC
2265 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2266 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2267 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2268 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2269 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2270 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2271 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2272 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2273 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2274 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2275 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2276 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2277 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2278 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2279 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2280 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2281 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2282 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2283 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2284 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2285 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2286 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2287 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2288 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2289 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2290 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2291 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2292 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2293 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2294 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2295 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2296 default:
2297 return NULL;
2298 }
2299}
2300
fd85a6a1
NC
2301static const char *
2302get_solaris_section_type (unsigned long type)
2303{
2304 switch (type)
2305 {
2306 case 0x6fffffee: return "SUNW_ancillary";
2307 case 0x6fffffef: return "SUNW_capchain";
2308 case 0x6ffffff0: return "SUNW_capinfo";
2309 case 0x6ffffff1: return "SUNW_symsort";
2310 case 0x6ffffff2: return "SUNW_tlssort";
2311 case 0x6ffffff3: return "SUNW_LDYNSYM";
2312 case 0x6ffffff4: return "SUNW_dof";
2313 case 0x6ffffff5: return "SUNW_cap";
2314 case 0x6ffffff6: return "SUNW_SIGNATURE";
2315 case 0x6ffffff7: return "SUNW_ANNOTATE";
2316 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2317 case 0x6ffffff9: return "SUNW_DEBUG";
2318 case 0x6ffffffa: return "SUNW_move";
2319 case 0x6ffffffb: return "SUNW_COMDAT";
2320 case 0x6ffffffc: return "SUNW_syminfo";
2321 case 0x6ffffffd: return "SUNW_verdef";
2322 case 0x6ffffffe: return "SUNW_verneed";
2323 case 0x6fffffff: return "SUNW_versym";
2324 case 0x70000000: return "SPARC_GOTDATA";
2325 default: return NULL;
2326 }
2327}
2328
fabcb361
RH
2329static const char *
2330get_alpha_dynamic_type (unsigned long type)
2331{
2332 switch (type)
2333 {
2334 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2335 default: return NULL;
fabcb361
RH
2336 }
2337}
2338
1c0d3aa6
NC
2339static const char *
2340get_score_dynamic_type (unsigned long type)
2341{
2342 switch (type)
2343 {
2344 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2345 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2346 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2347 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2348 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2349 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2350 default: return NULL;
1c0d3aa6
NC
2351 }
2352}
2353
40b36596
JM
2354static const char *
2355get_tic6x_dynamic_type (unsigned long type)
2356{
2357 switch (type)
2358 {
2359 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2360 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2361 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2362 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2363 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2364 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2365 default: return NULL;
40b36596
JM
2366 }
2367}
1c0d3aa6 2368
36591ba1
SL
2369static const char *
2370get_nios2_dynamic_type (unsigned long type)
2371{
2372 switch (type)
2373 {
2374 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2375 default: return NULL;
36591ba1
SL
2376 }
2377}
2378
fd85a6a1
NC
2379static const char *
2380get_solaris_dynamic_type (unsigned long type)
2381{
2382 switch (type)
2383 {
2384 case 0x6000000d: return "SUNW_AUXILIARY";
2385 case 0x6000000e: return "SUNW_RTLDINF";
2386 case 0x6000000f: return "SUNW_FILTER";
2387 case 0x60000010: return "SUNW_CAP";
2388 case 0x60000011: return "SUNW_SYMTAB";
2389 case 0x60000012: return "SUNW_SYMSZ";
2390 case 0x60000013: return "SUNW_SORTENT";
2391 case 0x60000014: return "SUNW_SYMSORT";
2392 case 0x60000015: return "SUNW_SYMSORTSZ";
2393 case 0x60000016: return "SUNW_TLSSORT";
2394 case 0x60000017: return "SUNW_TLSSORTSZ";
2395 case 0x60000018: return "SUNW_CAPINFO";
2396 case 0x60000019: return "SUNW_STRPAD";
2397 case 0x6000001a: return "SUNW_CAPCHAIN";
2398 case 0x6000001b: return "SUNW_LDMACH";
2399 case 0x6000001d: return "SUNW_CAPCHAINENT";
2400 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2401 case 0x60000021: return "SUNW_PARENT";
2402 case 0x60000023: return "SUNW_ASLR";
2403 case 0x60000025: return "SUNW_RELAX";
2404 case 0x60000029: return "SUNW_NXHEAP";
2405 case 0x6000002b: return "SUNW_NXSTACK";
2406
2407 case 0x70000001: return "SPARC_REGISTER";
2408 case 0x7ffffffd: return "AUXILIARY";
2409 case 0x7ffffffe: return "USED";
2410 case 0x7fffffff: return "FILTER";
2411
15f205b1 2412 default: return NULL;
fd85a6a1
NC
2413 }
2414}
2415
8155b853
NC
2416static const char *
2417get_riscv_dynamic_type (unsigned long type)
2418{
2419 switch (type)
2420 {
2421 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2422 default:
2423 return NULL;
2424 }
2425}
2426
252b5132 2427static const char *
dda8d76d 2428get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2429{
e9e44622 2430 static char buff[64];
252b5132
RH
2431
2432 switch (type)
2433 {
2434 case DT_NULL: return "NULL";
2435 case DT_NEEDED: return "NEEDED";
2436 case DT_PLTRELSZ: return "PLTRELSZ";
2437 case DT_PLTGOT: return "PLTGOT";
2438 case DT_HASH: return "HASH";
2439 case DT_STRTAB: return "STRTAB";
2440 case DT_SYMTAB: return "SYMTAB";
2441 case DT_RELA: return "RELA";
2442 case DT_RELASZ: return "RELASZ";
2443 case DT_RELAENT: return "RELAENT";
2444 case DT_STRSZ: return "STRSZ";
2445 case DT_SYMENT: return "SYMENT";
2446 case DT_INIT: return "INIT";
2447 case DT_FINI: return "FINI";
2448 case DT_SONAME: return "SONAME";
2449 case DT_RPATH: return "RPATH";
2450 case DT_SYMBOLIC: return "SYMBOLIC";
2451 case DT_REL: return "REL";
2452 case DT_RELSZ: return "RELSZ";
2453 case DT_RELENT: return "RELENT";
dd207c13
FS
2454 case DT_RELR: return "RELR";
2455 case DT_RELRSZ: return "RELRSZ";
2456 case DT_RELRENT: return "RELRENT";
252b5132
RH
2457 case DT_PLTREL: return "PLTREL";
2458 case DT_DEBUG: return "DEBUG";
2459 case DT_TEXTREL: return "TEXTREL";
2460 case DT_JMPREL: return "JMPREL";
2461 case DT_BIND_NOW: return "BIND_NOW";
2462 case DT_INIT_ARRAY: return "INIT_ARRAY";
2463 case DT_FINI_ARRAY: return "FINI_ARRAY";
2464 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2465 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2466 case DT_RUNPATH: return "RUNPATH";
2467 case DT_FLAGS: return "FLAGS";
2d0e6f43 2468
d1133906
NC
2469 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2470 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2471 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2472
05107a46 2473 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2474 case DT_PLTPADSZ: return "PLTPADSZ";
2475 case DT_MOVEENT: return "MOVEENT";
2476 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2477 case DT_FEATURE: return "FEATURE";
252b5132
RH
2478 case DT_POSFLAG_1: return "POSFLAG_1";
2479 case DT_SYMINSZ: return "SYMINSZ";
2480 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2481
252b5132 2482 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2483 case DT_CONFIG: return "CONFIG";
2484 case DT_DEPAUDIT: return "DEPAUDIT";
2485 case DT_AUDIT: return "AUDIT";
2486 case DT_PLTPAD: return "PLTPAD";
2487 case DT_MOVETAB: return "MOVETAB";
252b5132 2488 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2489
252b5132 2490 case DT_VERSYM: return "VERSYM";
103f02d3 2491
67a4f2b7
AO
2492 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2493 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2494 case DT_RELACOUNT: return "RELACOUNT";
2495 case DT_RELCOUNT: return "RELCOUNT";
2496 case DT_FLAGS_1: return "FLAGS_1";
2497 case DT_VERDEF: return "VERDEF";
2498 case DT_VERDEFNUM: return "VERDEFNUM";
2499 case DT_VERNEED: return "VERNEED";
2500 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2501
019148e4 2502 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2503 case DT_USED: return "USED";
2504 case DT_FILTER: return "FILTER";
103f02d3 2505
047b2264
JJ
2506 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2507 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2508 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2509 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2510 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2511 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2512 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2513
252b5132
RH
2514 default:
2515 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2516 {
2cf0635d 2517 const char * result;
103f02d3 2518
dda8d76d 2519 switch (filedata->file_header.e_machine)
252b5132 2520 {
37c18eed
SD
2521 case EM_AARCH64:
2522 result = get_aarch64_dynamic_type (type);
2523 break;
252b5132 2524 case EM_MIPS:
4fe85591 2525 case EM_MIPS_RS3_LE:
252b5132
RH
2526 result = get_mips_dynamic_type (type);
2527 break;
9a097730
RH
2528 case EM_SPARCV9:
2529 result = get_sparc64_dynamic_type (type);
2530 break;
7490d522
AM
2531 case EM_PPC:
2532 result = get_ppc_dynamic_type (type);
2533 break;
f1cb7e17
AM
2534 case EM_PPC64:
2535 result = get_ppc64_dynamic_type (type);
2536 break;
ecc51f48
NC
2537 case EM_IA_64:
2538 result = get_ia64_dynamic_type (type);
2539 break;
fabcb361
RH
2540 case EM_ALPHA:
2541 result = get_alpha_dynamic_type (type);
2542 break;
1c0d3aa6
NC
2543 case EM_SCORE:
2544 result = get_score_dynamic_type (type);
2545 break;
40b36596
JM
2546 case EM_TI_C6000:
2547 result = get_tic6x_dynamic_type (type);
2548 break;
36591ba1
SL
2549 case EM_ALTERA_NIOS2:
2550 result = get_nios2_dynamic_type (type);
2551 break;
8155b853
NC
2552 case EM_RISCV:
2553 result = get_riscv_dynamic_type (type);
2554 break;
252b5132 2555 default:
dda8d76d 2556 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2557 result = get_solaris_dynamic_type (type);
2558 else
2559 result = NULL;
252b5132
RH
2560 break;
2561 }
2562
2563 if (result != NULL)
2564 return result;
2565
e9e44622 2566 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2567 }
eec8f817 2568 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2569 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2570 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2571 {
2cf0635d 2572 const char * result;
103f02d3 2573
dda8d76d 2574 switch (filedata->file_header.e_machine)
103f02d3
UD
2575 {
2576 case EM_PARISC:
2577 result = get_parisc_dynamic_type (type);
2578 break;
148b93f2
NC
2579 case EM_IA_64:
2580 result = get_ia64_dynamic_type (type);
2581 break;
103f02d3 2582 default:
dda8d76d 2583 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2584 result = get_solaris_dynamic_type (type);
2585 else
2586 result = NULL;
103f02d3
UD
2587 break;
2588 }
2589
2590 if (result != NULL)
2591 return result;
2592
e9e44622
JJ
2593 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2594 type);
103f02d3 2595 }
252b5132 2596 else
e9e44622 2597 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2598
252b5132
RH
2599 return buff;
2600 }
2601}
2602
93df3340
AM
2603static bool get_program_headers (Filedata *);
2604static bool get_dynamic_section (Filedata *);
2605
2606static void
2607locate_dynamic_section (Filedata *filedata)
2608{
2609 unsigned long dynamic_addr = 0;
be7d229a 2610 uint64_t dynamic_size = 0;
93df3340
AM
2611
2612 if (filedata->file_header.e_phnum != 0
2613 && get_program_headers (filedata))
2614 {
2615 Elf_Internal_Phdr *segment;
2616 unsigned int i;
2617
2618 for (i = 0, segment = filedata->program_headers;
2619 i < filedata->file_header.e_phnum;
2620 i++, segment++)
2621 {
2622 if (segment->p_type == PT_DYNAMIC)
2623 {
2624 dynamic_addr = segment->p_offset;
2625 dynamic_size = segment->p_filesz;
2626
2627 if (filedata->section_headers != NULL)
2628 {
2629 Elf_Internal_Shdr *sec;
2630
2631 sec = find_section (filedata, ".dynamic");
2632 if (sec != NULL)
2633 {
2634 if (sec->sh_size == 0
2635 || sec->sh_type == SHT_NOBITS)
2636 {
2637 dynamic_addr = 0;
2638 dynamic_size = 0;
2639 }
2640 else
2641 {
2642 dynamic_addr = sec->sh_offset;
2643 dynamic_size = sec->sh_size;
2644 }
2645 }
2646 }
2647
2648 if (dynamic_addr > filedata->file_size
2649 || (dynamic_size > filedata->file_size - dynamic_addr))
2650 {
2651 dynamic_addr = 0;
2652 dynamic_size = 0;
2653 }
2654 break;
2655 }
2656 }
2657 }
2658 filedata->dynamic_addr = dynamic_addr;
2659 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2660}
2661
2662static bool
2663is_pie (Filedata *filedata)
2664{
2665 Elf_Internal_Dyn *entry;
2666
2667 if (filedata->dynamic_size == 0)
2668 locate_dynamic_section (filedata);
2669 if (filedata->dynamic_size <= 1)
2670 return false;
2671
2672 if (!get_dynamic_section (filedata))
2673 return false;
2674
2675 for (entry = filedata->dynamic_section;
2676 entry < filedata->dynamic_section + filedata->dynamic_nent;
2677 entry++)
2678 {
2679 if (entry->d_tag == DT_FLAGS_1)
2680 {
2681 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2682 return true;
2683 break;
2684 }
2685 }
2686 return false;
2687}
2688
252b5132 2689static char *
93df3340 2690get_file_type (Filedata *filedata)
252b5132 2691{
93df3340 2692 unsigned e_type = filedata->file_header.e_type;
89246a0e 2693 static char buff[64];
252b5132
RH
2694
2695 switch (e_type)
2696 {
32ec8896
NC
2697 case ET_NONE: return _("NONE (None)");
2698 case ET_REL: return _("REL (Relocatable file)");
2699 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2700 case ET_DYN:
2701 if (is_pie (filedata))
2702 return _("DYN (Position-Independent Executable file)");
2703 else
2704 return _("DYN (Shared object file)");
32ec8896 2705 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2706
2707 default:
2708 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2709 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2710 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2711 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2712 else
e9e44622 2713 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2714 return buff;
2715 }
2716}
2717
2718static char *
d3ba0551 2719get_machine_name (unsigned e_machine)
252b5132 2720{
b34976b6 2721 static char buff[64]; /* XXX */
252b5132
RH
2722
2723 switch (e_machine)
2724 {
55e22ca8
NC
2725 /* Please keep this switch table sorted by increasing EM_ value. */
2726 /* 0 */
c45021f2
NC
2727 case EM_NONE: return _("None");
2728 case EM_M32: return "WE32100";
2729 case EM_SPARC: return "Sparc";
2730 case EM_386: return "Intel 80386";
2731 case EM_68K: return "MC68000";
2732 case EM_88K: return "MC88000";
22abe556 2733 case EM_IAMCU: return "Intel MCU";
fb70ec17 2734 case EM_860: return "Intel 80860";
c45021f2
NC
2735 case EM_MIPS: return "MIPS R3000";
2736 case EM_S370: return "IBM System/370";
55e22ca8 2737 /* 10 */
7036c0e1 2738 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2739 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2740 case EM_PARISC: return "HPPA";
55e22ca8 2741 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2742 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2743 case EM_960: return "Intel 80960";
c45021f2 2744 case EM_PPC: return "PowerPC";
55e22ca8 2745 /* 20 */
285d1771 2746 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2747 case EM_S390_OLD:
2748 case EM_S390: return "IBM S/390";
2749 case EM_SPU: return "SPU";
2750 /* 30 */
2751 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2752 case EM_FR20: return "Fujitsu FR20";
2753 case EM_RH32: return "TRW RH32";
b34976b6 2754 case EM_MCORE: return "MCORE";
55e22ca8 2755 /* 40 */
7036c0e1
AJ
2756 case EM_ARM: return "ARM";
2757 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2758 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2759 case EM_SPARCV9: return "Sparc v9";
2760 case EM_TRICORE: return "Siemens Tricore";
584da044 2761 case EM_ARC: return "ARC";
c2dcd04e
NC
2762 case EM_H8_300: return "Renesas H8/300";
2763 case EM_H8_300H: return "Renesas H8/300H";
2764 case EM_H8S: return "Renesas H8S";
2765 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2766 /* 50 */
30800947 2767 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2768 case EM_MIPS_X: return "Stanford MIPS-X";
2769 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2770 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2771 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2772 case EM_PCP: return "Siemens PCP";
2773 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2774 case EM_NDR1: return "Denso NDR1 microprocesspr";
2775 case EM_STARCORE: return "Motorola Star*Core processor";
2776 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2777 /* 60 */
7036c0e1
AJ
2778 case EM_ST100: return "STMicroelectronics ST100 processor";
2779 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2780 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2781 case EM_PDSP: return "Sony DSP processor";
2782 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2783 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2784 case EM_FX66: return "Siemens FX66 microcontroller";
2785 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2786 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2787 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2788 /* 70 */
7036c0e1
AJ
2789 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2790 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2791 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2792 case EM_SVX: return "Silicon Graphics SVx";
2793 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2794 case EM_VAX: return "Digital VAX";
1b61cf92 2795 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2796 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2797 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2798 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2799 /* 80 */
b34976b6 2800 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2801 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2802 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2803 case EM_AVR_OLD:
2804 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2805 case EM_CYGNUS_FR30:
2806 case EM_FR30: return "Fujitsu FR30";
2807 case EM_CYGNUS_D10V:
2808 case EM_D10V: return "d10v";
2809 case EM_CYGNUS_D30V:
2810 case EM_D30V: return "d30v";
2811 case EM_CYGNUS_V850:
2812 case EM_V850: return "Renesas V850";
2813 case EM_CYGNUS_M32R:
2814 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2815 case EM_CYGNUS_MN10300:
2816 case EM_MN10300: return "mn10300";
2817 /* 90 */
2818 case EM_CYGNUS_MN10200:
2819 case EM_MN10200: return "mn10200";
2820 case EM_PJ: return "picoJava";
73589c9d 2821 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2822 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2823 case EM_XTENSA_OLD:
2824 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2825 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2826 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2827 case EM_NS32K: return "National Semiconductor 32000 series";
2828 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2829 case EM_SNP1K: return "Trebia SNP 1000 processor";
2830 /* 100 */
9abca702 2831 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2832 case EM_IP2K_OLD:
2833 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2834 case EM_MAX: return "MAX Processor";
2835 case EM_CR: return "National Semiconductor CompactRISC";
2836 case EM_F2MC16: return "Fujitsu F2MC16";
2837 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2838 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2839 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2840 case EM_SEP: return "Sharp embedded microprocessor";
2841 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2842 /* 110 */
11636f9e
JM
2843 case EM_UNICORE: return "Unicore";
2844 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2845 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2846 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2847 case EM_CRX: return "National Semiconductor CRX microprocessor";
2848 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2849 case EM_C166:
d70c5fc7 2850 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2851 case EM_M16C: return "Renesas M16C series microprocessors";
2852 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2853 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2854 /* 120 */
2855 case EM_M32C: return "Renesas M32c";
2856 /* 130 */
11636f9e
JM
2857 case EM_TSK3000: return "Altium TSK3000 core";
2858 case EM_RS08: return "Freescale RS08 embedded processor";
2859 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2860 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2861 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2862 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2863 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2864 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2865 /* 140 */
11636f9e
JM
2866 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2867 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2868 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2869 case EM_TI_PRU: return "TI PRU I/O processor";
2870 /* 160 */
11636f9e
JM
2871 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2872 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2873 case EM_R32C: return "Renesas R32C series microprocessors";
2874 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2875 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2876 case EM_8051: return "Intel 8051 and variants";
2877 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2878 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2879 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2880 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2881 /* 170 */
11636f9e
JM
2882 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2883 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2884 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2885 case EM_RX: return "Renesas RX";
a3c62988 2886 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2887 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2888 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2889 case EM_CR16:
2890 case EM_MICROBLAZE:
2891 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2892 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2893 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2894 /* 180 */
2895 case EM_L1OM: return "Intel L1OM";
2896 case EM_K1OM: return "Intel K1OM";
2897 case EM_INTEL182: return "Intel (reserved)";
2898 case EM_AARCH64: return "AArch64";
2899 case EM_ARM184: return "ARM (reserved)";
2900 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2901 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2902 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2903 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2904 /* 190 */
11636f9e 2905 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2906 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2907 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2908 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2909 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2910 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2911 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2912 case EM_RL78: return "Renesas RL78";
6d913794 2913 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2914 case EM_78K0R: return "Renesas 78K0R";
2915 /* 200 */
6d913794 2916 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2917 case EM_BA1: return "Beyond BA1 CPU architecture";
2918 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2919 case EM_XCORE: return "XMOS xCORE processor family";
2920 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2921 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2922 /* 210 */
6d913794
NC
2923 case EM_KM32: return "KM211 KM32 32-bit processor";
2924 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2925 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2926 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2927 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2928 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2929 case EM_COGE: return "Cognitive Smart Memory Processor";
2930 case EM_COOL: return "Bluechip Systems CoolEngine";
2931 case EM_NORC: return "Nanoradio Optimized RISC";
2932 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2933 /* 220 */
15f205b1 2934 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2935 case EM_VISIUM: return "CDS VISIUMcore processor";
2936 case EM_FT32: return "FTDI Chip FT32";
2937 case EM_MOXIE: return "Moxie";
2938 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2939 /* 230 (all reserved) */
2940 /* 240 */
55e22ca8
NC
2941 case EM_RISCV: return "RISC-V";
2942 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2943 case EM_CEVA: return "CEVA Processor Architecture Family";
2944 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2945 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2946 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2947 case EM_IMG1: return "Imagination Technologies";
2948 /* 250 */
fe944acf 2949 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2950 case EM_VE: return "NEC Vector Engine";
2951 case EM_CSKY: return "C-SKY";
2952 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2953 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2954 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2955 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2956 case EM_65816: return "WDC 65816/65C816";
01a8c731 2957 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2958 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2959
2960 /* Large numbers... */
2961 case EM_MT: return "Morpho Techologies MT processor";
2962 case EM_ALPHA: return "Alpha";
2963 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2964 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2965 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2966 case EM_IQ2000: return "Vitesse IQ2000";
2967 case EM_M32C_OLD:
2968 case EM_NIOS32: return "Altera Nios";
2969 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2970 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2971 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2972 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2973
252b5132 2974 default:
35d9dd2f 2975 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2976 return buff;
2977 }
2978}
2979
a9522a21
AB
2980static void
2981decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2982{
2983 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2984 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2985 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2986 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2987 architectures.
2988
2989 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2990 but also sets a specific architecture type in the e_flags field.
2991
2992 However, when decoding the flags we don't worry if we see an
2993 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2994 ARCEM architecture type. */
2995
2996 switch (e_flags & EF_ARC_MACH_MSK)
2997 {
2998 /* We only expect these to occur for EM_ARC_COMPACT2. */
2999 case EF_ARC_CPU_ARCV2EM:
3000 strcat (buf, ", ARC EM");
3001 break;
3002 case EF_ARC_CPU_ARCV2HS:
3003 strcat (buf, ", ARC HS");
3004 break;
3005
3006 /* We only expect these to occur for EM_ARC_COMPACT. */
3007 case E_ARC_MACH_ARC600:
3008 strcat (buf, ", ARC600");
3009 break;
3010 case E_ARC_MACH_ARC601:
3011 strcat (buf, ", ARC601");
3012 break;
3013 case E_ARC_MACH_ARC700:
3014 strcat (buf, ", ARC700");
3015 break;
3016
3017 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3018 new ELF with new architecture being read by an old version of
3019 readelf, or (c) An ELF built with non-GNU compiler that does not
3020 set the architecture in the e_flags. */
3021 default:
3022 if (e_machine == EM_ARC_COMPACT)
3023 strcat (buf, ", Unknown ARCompact");
3024 else
3025 strcat (buf, ", Unknown ARC");
3026 break;
3027 }
3028
3029 switch (e_flags & EF_ARC_OSABI_MSK)
3030 {
3031 case E_ARC_OSABI_ORIG:
3032 strcat (buf, ", (ABI:legacy)");
3033 break;
3034 case E_ARC_OSABI_V2:
3035 strcat (buf, ", (ABI:v2)");
3036 break;
3037 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3038 case E_ARC_OSABI_V3:
3039 strcat (buf, ", v3 no-legacy-syscalls ABI");
3040 break;
53a346d8
CZ
3041 case E_ARC_OSABI_V4:
3042 strcat (buf, ", v4 ABI");
3043 break;
a9522a21
AB
3044 default:
3045 strcat (buf, ", unrecognised ARC OSABI flag");
3046 break;
3047 }
3048}
3049
f3485b74 3050static void
d3ba0551 3051decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3052{
3053 unsigned eabi;
015dc7e1 3054 bool unknown = false;
f3485b74
NC
3055
3056 eabi = EF_ARM_EABI_VERSION (e_flags);
3057 e_flags &= ~ EF_ARM_EABIMASK;
3058
3059 /* Handle "generic" ARM flags. */
3060 if (e_flags & EF_ARM_RELEXEC)
3061 {
3062 strcat (buf, ", relocatable executable");
3063 e_flags &= ~ EF_ARM_RELEXEC;
3064 }
76da6bbe 3065
18a20338
CL
3066 if (e_flags & EF_ARM_PIC)
3067 {
3068 strcat (buf, ", position independent");
3069 e_flags &= ~ EF_ARM_PIC;
3070 }
3071
f3485b74
NC
3072 /* Now handle EABI specific flags. */
3073 switch (eabi)
3074 {
3075 default:
2c71103e 3076 strcat (buf, ", <unrecognized EABI>");
f3485b74 3077 if (e_flags)
015dc7e1 3078 unknown = true;
f3485b74
NC
3079 break;
3080
3081 case EF_ARM_EABI_VER1:
a5bcd848 3082 strcat (buf, ", Version1 EABI");
f3485b74
NC
3083 while (e_flags)
3084 {
3085 unsigned flag;
76da6bbe 3086
f3485b74
NC
3087 /* Process flags one bit at a time. */
3088 flag = e_flags & - e_flags;
3089 e_flags &= ~ flag;
76da6bbe 3090
f3485b74
NC
3091 switch (flag)
3092 {
a5bcd848 3093 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3094 strcat (buf, ", sorted symbol tables");
3095 break;
76da6bbe 3096
f3485b74 3097 default:
015dc7e1 3098 unknown = true;
f3485b74
NC
3099 break;
3100 }
3101 }
3102 break;
76da6bbe 3103
a5bcd848
PB
3104 case EF_ARM_EABI_VER2:
3105 strcat (buf, ", Version2 EABI");
3106 while (e_flags)
3107 {
3108 unsigned flag;
3109
3110 /* Process flags one bit at a time. */
3111 flag = e_flags & - e_flags;
3112 e_flags &= ~ flag;
3113
3114 switch (flag)
3115 {
3116 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3117 strcat (buf, ", sorted symbol tables");
3118 break;
3119
3120 case EF_ARM_DYNSYMSUSESEGIDX:
3121 strcat (buf, ", dynamic symbols use segment index");
3122 break;
3123
3124 case EF_ARM_MAPSYMSFIRST:
3125 strcat (buf, ", mapping symbols precede others");
3126 break;
3127
3128 default:
015dc7e1 3129 unknown = true;
a5bcd848
PB
3130 break;
3131 }
3132 }
3133 break;
3134
d507cf36
PB
3135 case EF_ARM_EABI_VER3:
3136 strcat (buf, ", Version3 EABI");
8cb51566
PB
3137 break;
3138
3139 case EF_ARM_EABI_VER4:
3140 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3141 while (e_flags)
3142 {
3143 unsigned flag;
3144
3145 /* Process flags one bit at a time. */
3146 flag = e_flags & - e_flags;
3147 e_flags &= ~ flag;
3148
3149 switch (flag)
3150 {
3151 case EF_ARM_BE8:
3152 strcat (buf, ", BE8");
3153 break;
3154
3155 case EF_ARM_LE8:
3156 strcat (buf, ", LE8");
3157 break;
3158
3159 default:
015dc7e1 3160 unknown = true;
3bfcb652
NC
3161 break;
3162 }
3bfcb652
NC
3163 }
3164 break;
3a4a14e9
PB
3165
3166 case EF_ARM_EABI_VER5:
3167 strcat (buf, ", Version5 EABI");
d507cf36
PB
3168 while (e_flags)
3169 {
3170 unsigned flag;
3171
3172 /* Process flags one bit at a time. */
3173 flag = e_flags & - e_flags;
3174 e_flags &= ~ flag;
3175
3176 switch (flag)
3177 {
3178 case EF_ARM_BE8:
3179 strcat (buf, ", BE8");
3180 break;
3181
3182 case EF_ARM_LE8:
3183 strcat (buf, ", LE8");
3184 break;
3185
3bfcb652
NC
3186 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3187 strcat (buf, ", soft-float ABI");
3188 break;
3189
3190 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3191 strcat (buf, ", hard-float ABI");
3192 break;
3193
d507cf36 3194 default:
015dc7e1 3195 unknown = true;
d507cf36
PB
3196 break;
3197 }
3198 }
3199 break;
3200
f3485b74 3201 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3202 strcat (buf, ", GNU EABI");
f3485b74
NC
3203 while (e_flags)
3204 {
3205 unsigned flag;
76da6bbe 3206
f3485b74
NC
3207 /* Process flags one bit at a time. */
3208 flag = e_flags & - e_flags;
3209 e_flags &= ~ flag;
76da6bbe 3210
f3485b74
NC
3211 switch (flag)
3212 {
a5bcd848 3213 case EF_ARM_INTERWORK:
f3485b74
NC
3214 strcat (buf, ", interworking enabled");
3215 break;
76da6bbe 3216
a5bcd848 3217 case EF_ARM_APCS_26:
f3485b74
NC
3218 strcat (buf, ", uses APCS/26");
3219 break;
76da6bbe 3220
a5bcd848 3221 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3222 strcat (buf, ", uses APCS/float");
3223 break;
76da6bbe 3224
a5bcd848 3225 case EF_ARM_PIC:
f3485b74
NC
3226 strcat (buf, ", position independent");
3227 break;
76da6bbe 3228
a5bcd848 3229 case EF_ARM_ALIGN8:
f3485b74
NC
3230 strcat (buf, ", 8 bit structure alignment");
3231 break;
76da6bbe 3232
a5bcd848 3233 case EF_ARM_NEW_ABI:
f3485b74
NC
3234 strcat (buf, ", uses new ABI");
3235 break;
76da6bbe 3236
a5bcd848 3237 case EF_ARM_OLD_ABI:
f3485b74
NC
3238 strcat (buf, ", uses old ABI");
3239 break;
76da6bbe 3240
a5bcd848 3241 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3242 strcat (buf, ", software FP");
3243 break;
76da6bbe 3244
90e01f86
ILT
3245 case EF_ARM_VFP_FLOAT:
3246 strcat (buf, ", VFP");
3247 break;
3248
fde78edd
NC
3249 case EF_ARM_MAVERICK_FLOAT:
3250 strcat (buf, ", Maverick FP");
3251 break;
3252
f3485b74 3253 default:
015dc7e1 3254 unknown = true;
f3485b74
NC
3255 break;
3256 }
3257 }
3258 }
f3485b74
NC
3259
3260 if (unknown)
2b692964 3261 strcat (buf,_(", <unknown>"));
f3485b74
NC
3262}
3263
343433df
AB
3264static void
3265decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3266{
3267 --size; /* Leave space for null terminator. */
3268
3269 switch (e_flags & EF_AVR_MACH)
3270 {
3271 case E_AVR_MACH_AVR1:
3272 strncat (buf, ", avr:1", size);
3273 break;
3274 case E_AVR_MACH_AVR2:
3275 strncat (buf, ", avr:2", size);
3276 break;
3277 case E_AVR_MACH_AVR25:
3278 strncat (buf, ", avr:25", size);
3279 break;
3280 case E_AVR_MACH_AVR3:
3281 strncat (buf, ", avr:3", size);
3282 break;
3283 case E_AVR_MACH_AVR31:
3284 strncat (buf, ", avr:31", size);
3285 break;
3286 case E_AVR_MACH_AVR35:
3287 strncat (buf, ", avr:35", size);
3288 break;
3289 case E_AVR_MACH_AVR4:
3290 strncat (buf, ", avr:4", size);
3291 break;
3292 case E_AVR_MACH_AVR5:
3293 strncat (buf, ", avr:5", size);
3294 break;
3295 case E_AVR_MACH_AVR51:
3296 strncat (buf, ", avr:51", size);
3297 break;
3298 case E_AVR_MACH_AVR6:
3299 strncat (buf, ", avr:6", size);
3300 break;
3301 case E_AVR_MACH_AVRTINY:
3302 strncat (buf, ", avr:100", size);
3303 break;
3304 case E_AVR_MACH_XMEGA1:
3305 strncat (buf, ", avr:101", size);
3306 break;
3307 case E_AVR_MACH_XMEGA2:
3308 strncat (buf, ", avr:102", size);
3309 break;
3310 case E_AVR_MACH_XMEGA3:
3311 strncat (buf, ", avr:103", size);
3312 break;
3313 case E_AVR_MACH_XMEGA4:
3314 strncat (buf, ", avr:104", size);
3315 break;
3316 case E_AVR_MACH_XMEGA5:
3317 strncat (buf, ", avr:105", size);
3318 break;
3319 case E_AVR_MACH_XMEGA6:
3320 strncat (buf, ", avr:106", size);
3321 break;
3322 case E_AVR_MACH_XMEGA7:
3323 strncat (buf, ", avr:107", size);
3324 break;
3325 default:
3326 strncat (buf, ", avr:<unknown>", size);
3327 break;
3328 }
3329
3330 size -= strlen (buf);
3331 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3332 strncat (buf, ", link-relax", size);
3333}
3334
35c08157
KLC
3335static void
3336decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3337{
3338 unsigned abi;
3339 unsigned arch;
3340 unsigned config;
3341 unsigned version;
015dc7e1 3342 bool has_fpu = false;
32ec8896 3343 unsigned int r = 0;
35c08157
KLC
3344
3345 static const char *ABI_STRINGS[] =
3346 {
3347 "ABI v0", /* use r5 as return register; only used in N1213HC */
3348 "ABI v1", /* use r0 as return register */
3349 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3350 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3351 "AABI",
3352 "ABI2 FP+"
35c08157
KLC
3353 };
3354 static const char *VER_STRINGS[] =
3355 {
3356 "Andes ELF V1.3 or older",
3357 "Andes ELF V1.3.1",
3358 "Andes ELF V1.4"
3359 };
3360 static const char *ARCH_STRINGS[] =
3361 {
3362 "",
3363 "Andes Star v1.0",
3364 "Andes Star v2.0",
3365 "Andes Star v3.0",
3366 "Andes Star v3.0m"
3367 };
3368
3369 abi = EF_NDS_ABI & e_flags;
3370 arch = EF_NDS_ARCH & e_flags;
3371 config = EF_NDS_INST & e_flags;
3372 version = EF_NDS32_ELF_VERSION & e_flags;
3373
3374 memset (buf, 0, size);
3375
3376 switch (abi)
3377 {
3378 case E_NDS_ABI_V0:
3379 case E_NDS_ABI_V1:
3380 case E_NDS_ABI_V2:
3381 case E_NDS_ABI_V2FP:
3382 case E_NDS_ABI_AABI:
40c7a7cb 3383 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3384 /* In case there are holes in the array. */
3385 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3386 break;
3387
3388 default:
3389 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3390 break;
3391 }
3392
3393 switch (version)
3394 {
3395 case E_NDS32_ELF_VER_1_2:
3396 case E_NDS32_ELF_VER_1_3:
3397 case E_NDS32_ELF_VER_1_4:
3398 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3399 break;
3400
3401 default:
3402 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3403 break;
3404 }
3405
3406 if (E_NDS_ABI_V0 == abi)
3407 {
3408 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3409 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3410 if (arch == E_NDS_ARCH_STAR_V1_0)
3411 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3412 return;
3413 }
3414
3415 switch (arch)
3416 {
3417 case E_NDS_ARCH_STAR_V1_0:
3418 case E_NDS_ARCH_STAR_V2_0:
3419 case E_NDS_ARCH_STAR_V3_0:
3420 case E_NDS_ARCH_STAR_V3_M:
3421 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3422 break;
3423
3424 default:
3425 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3426 /* ARCH version determines how the e_flags are interpreted.
3427 If it is unknown, we cannot proceed. */
3428 return;
3429 }
3430
3431 /* Newer ABI; Now handle architecture specific flags. */
3432 if (arch == E_NDS_ARCH_STAR_V1_0)
3433 {
3434 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3435 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3436
3437 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3438 r += snprintf (buf + r, size -r, ", MAC");
3439
3440 if (config & E_NDS32_HAS_DIV_INST)
3441 r += snprintf (buf + r, size -r, ", DIV");
3442
3443 if (config & E_NDS32_HAS_16BIT_INST)
3444 r += snprintf (buf + r, size -r, ", 16b");
3445 }
3446 else
3447 {
3448 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3449 {
3450 if (version <= E_NDS32_ELF_VER_1_3)
3451 r += snprintf (buf + r, size -r, ", [B8]");
3452 else
3453 r += snprintf (buf + r, size -r, ", EX9");
3454 }
3455
3456 if (config & E_NDS32_HAS_MAC_DX_INST)
3457 r += snprintf (buf + r, size -r, ", MAC_DX");
3458
3459 if (config & E_NDS32_HAS_DIV_DX_INST)
3460 r += snprintf (buf + r, size -r, ", DIV_DX");
3461
3462 if (config & E_NDS32_HAS_16BIT_INST)
3463 {
3464 if (version <= E_NDS32_ELF_VER_1_3)
3465 r += snprintf (buf + r, size -r, ", 16b");
3466 else
3467 r += snprintf (buf + r, size -r, ", IFC");
3468 }
3469 }
3470
3471 if (config & E_NDS32_HAS_EXT_INST)
3472 r += snprintf (buf + r, size -r, ", PERF1");
3473
3474 if (config & E_NDS32_HAS_EXT2_INST)
3475 r += snprintf (buf + r, size -r, ", PERF2");
3476
3477 if (config & E_NDS32_HAS_FPU_INST)
3478 {
015dc7e1 3479 has_fpu = true;
35c08157
KLC
3480 r += snprintf (buf + r, size -r, ", FPU_SP");
3481 }
3482
3483 if (config & E_NDS32_HAS_FPU_DP_INST)
3484 {
015dc7e1 3485 has_fpu = true;
35c08157
KLC
3486 r += snprintf (buf + r, size -r, ", FPU_DP");
3487 }
3488
3489 if (config & E_NDS32_HAS_FPU_MAC_INST)
3490 {
015dc7e1 3491 has_fpu = true;
35c08157
KLC
3492 r += snprintf (buf + r, size -r, ", FPU_MAC");
3493 }
3494
3495 if (has_fpu)
3496 {
3497 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3498 {
3499 case E_NDS32_FPU_REG_8SP_4DP:
3500 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3501 break;
3502 case E_NDS32_FPU_REG_16SP_8DP:
3503 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3504 break;
3505 case E_NDS32_FPU_REG_32SP_16DP:
3506 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3507 break;
3508 case E_NDS32_FPU_REG_32SP_32DP:
3509 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3510 break;
3511 }
3512 }
3513
3514 if (config & E_NDS32_HAS_AUDIO_INST)
3515 r += snprintf (buf + r, size -r, ", AUDIO");
3516
3517 if (config & E_NDS32_HAS_STRING_INST)
3518 r += snprintf (buf + r, size -r, ", STR");
3519
3520 if (config & E_NDS32_HAS_REDUCED_REGS)
3521 r += snprintf (buf + r, size -r, ", 16REG");
3522
3523 if (config & E_NDS32_HAS_VIDEO_INST)
3524 {
3525 if (version <= E_NDS32_ELF_VER_1_3)
3526 r += snprintf (buf + r, size -r, ", VIDEO");
3527 else
3528 r += snprintf (buf + r, size -r, ", SATURATION");
3529 }
3530
3531 if (config & E_NDS32_HAS_ENCRIPT_INST)
3532 r += snprintf (buf + r, size -r, ", ENCRP");
3533
3534 if (config & E_NDS32_HAS_L2C_INST)
3535 r += snprintf (buf + r, size -r, ", L2C");
3536}
3537
c077c580
SM
3538static void
3539decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3540 char *buf)
3541{
3542 unsigned char *e_ident = filedata->file_header.e_ident;
3543 unsigned char osabi = e_ident[EI_OSABI];
3544 unsigned char abiversion = e_ident[EI_ABIVERSION];
3545 unsigned int mach;
3546
3547 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3548 it has been deprecated for a while.
3549
3550 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3551 of writing, they use the same flags as HSA v3, so the code below uses that
3552 assumption. */
3553 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3554 return;
3555
3556 mach = e_flags & EF_AMDGPU_MACH;
3557 switch (mach)
3558 {
3559#define AMDGPU_CASE(code, string) \
3560 case code: strcat (buf, ", " string); break;
3561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3567 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3568 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3569 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3570 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3571 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3572 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3573 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3574 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3575 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3576 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3577 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3578 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3579 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3580 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3581 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3582 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3583 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3584 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3595 default:
3596 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3597 break;
3598#undef AMDGPU_CASE
3599 }
3600
3601 buf += strlen (buf);
3602 e_flags &= ~EF_AMDGPU_MACH;
3603
3604 if ((osabi == ELFOSABI_AMDGPU_HSA
3605 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3606 || osabi != ELFOSABI_AMDGPU_HSA)
3607 {
3608 /* For HSA v3 and other OS ABIs. */
3609 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3610 {
3611 strcat (buf, ", xnack on");
3612 buf += strlen (buf);
3613 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3614 }
3615
3616 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3617 {
3618 strcat (buf, ", sramecc on");
3619 buf += strlen (buf);
3620 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3621 }
3622 }
3623 else
3624 {
3625 /* For HSA v4+. */
3626 int xnack, sramecc;
3627
3628 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3629 switch (xnack)
3630 {
3631 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3632 break;
3633
3634 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3635 strcat (buf, ", xnack any");
3636 break;
3637
3638 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3639 strcat (buf, ", xnack off");
3640 break;
3641
3642 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3643 strcat (buf, ", xnack on");
3644 break;
3645
3646 default:
3647 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3648 break;
3649 }
3650
3651 buf += strlen (buf);
3652 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3653
3654 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3655 switch (sramecc)
3656 {
3657 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3658 break;
3659
3660 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3661 strcat (buf, ", sramecc any");
3662 break;
3663
3664 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3665 strcat (buf, ", sramecc off");
3666 break;
3667
3668 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3669 strcat (buf, ", sramecc on");
3670 break;
3671
3672 default:
3673 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3674 break;
3675 }
3676
3677 buf += strlen (buf);
3678 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3679 }
3680
3681 if (e_flags != 0)
3682 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3683}
3684
252b5132 3685static char *
dda8d76d 3686get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3687{
b34976b6 3688 static char buf[1024];
252b5132
RH
3689
3690 buf[0] = '\0';
76da6bbe 3691
252b5132
RH
3692 if (e_flags)
3693 {
3694 switch (e_machine)
3695 {
3696 default:
3697 break;
3698
886a2506 3699 case EM_ARC_COMPACT2:
886a2506 3700 case EM_ARC_COMPACT:
a9522a21
AB
3701 decode_ARC_machine_flags (e_flags, e_machine, buf);
3702 break;
886a2506 3703
f3485b74
NC
3704 case EM_ARM:
3705 decode_ARM_machine_flags (e_flags, buf);
3706 break;
76da6bbe 3707
343433df
AB
3708 case EM_AVR:
3709 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3710 break;
3711
781303ce
MF
3712 case EM_BLACKFIN:
3713 if (e_flags & EF_BFIN_PIC)
3714 strcat (buf, ", PIC");
3715
3716 if (e_flags & EF_BFIN_FDPIC)
3717 strcat (buf, ", FDPIC");
3718
3719 if (e_flags & EF_BFIN_CODE_IN_L1)
3720 strcat (buf, ", code in L1");
3721
3722 if (e_flags & EF_BFIN_DATA_IN_L1)
3723 strcat (buf, ", data in L1");
3724
3725 break;
3726
ec2dfb42
AO
3727 case EM_CYGNUS_FRV:
3728 switch (e_flags & EF_FRV_CPU_MASK)
3729 {
3730 case EF_FRV_CPU_GENERIC:
3731 break;
3732
3733 default:
3734 strcat (buf, ", fr???");
3735 break;
57346661 3736
ec2dfb42
AO
3737 case EF_FRV_CPU_FR300:
3738 strcat (buf, ", fr300");
3739 break;
3740
3741 case EF_FRV_CPU_FR400:
3742 strcat (buf, ", fr400");
3743 break;
3744 case EF_FRV_CPU_FR405:
3745 strcat (buf, ", fr405");
3746 break;
3747
3748 case EF_FRV_CPU_FR450:
3749 strcat (buf, ", fr450");
3750 break;
3751
3752 case EF_FRV_CPU_FR500:
3753 strcat (buf, ", fr500");
3754 break;
3755 case EF_FRV_CPU_FR550:
3756 strcat (buf, ", fr550");
3757 break;
3758
3759 case EF_FRV_CPU_SIMPLE:
3760 strcat (buf, ", simple");
3761 break;
3762 case EF_FRV_CPU_TOMCAT:
3763 strcat (buf, ", tomcat");
3764 break;
3765 }
1c877e87 3766 break;
ec2dfb42 3767
53c7db4b 3768 case EM_68K:
425c6cb0 3769 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3770 strcat (buf, ", m68000");
425c6cb0 3771 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3772 strcat (buf, ", cpu32");
3773 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3774 strcat (buf, ", fido_a");
425c6cb0 3775 else
266abb8f 3776 {
2cf0635d
NC
3777 char const * isa = _("unknown");
3778 char const * mac = _("unknown mac");
3779 char const * additional = NULL;
0112cd26 3780
c694fd50 3781 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3782 {
c694fd50 3783 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3784 isa = "A";
3785 additional = ", nodiv";
3786 break;
c694fd50 3787 case EF_M68K_CF_ISA_A:
266abb8f
NS
3788 isa = "A";
3789 break;
c694fd50 3790 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3791 isa = "A+";
3792 break;
c694fd50 3793 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3794 isa = "B";
3795 additional = ", nousp";
3796 break;
c694fd50 3797 case EF_M68K_CF_ISA_B:
266abb8f
NS
3798 isa = "B";
3799 break;
f608cd77
NS
3800 case EF_M68K_CF_ISA_C:
3801 isa = "C";
3802 break;
3803 case EF_M68K_CF_ISA_C_NODIV:
3804 isa = "C";
3805 additional = ", nodiv";
3806 break;
266abb8f
NS
3807 }
3808 strcat (buf, ", cf, isa ");
3809 strcat (buf, isa);
0b2e31dc
NS
3810 if (additional)
3811 strcat (buf, additional);
c694fd50 3812 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3813 strcat (buf, ", float");
c694fd50 3814 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3815 {
3816 case 0:
3817 mac = NULL;
3818 break;
c694fd50 3819 case EF_M68K_CF_MAC:
266abb8f
NS
3820 mac = "mac";
3821 break;
c694fd50 3822 case EF_M68K_CF_EMAC:
266abb8f
NS
3823 mac = "emac";
3824 break;
f608cd77
NS
3825 case EF_M68K_CF_EMAC_B:
3826 mac = "emac_b";
3827 break;
266abb8f
NS
3828 }
3829 if (mac)
3830 {
3831 strcat (buf, ", ");
3832 strcat (buf, mac);
3833 }
266abb8f 3834 }
53c7db4b 3835 break;
33c63f9d 3836
c077c580
SM
3837 case EM_AMDGPU:
3838 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3839 break;
3840
153a2776
NC
3841 case EM_CYGNUS_MEP:
3842 switch (e_flags & EF_MEP_CPU_MASK)
3843 {
3844 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3845 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3846 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3847 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3848 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3849 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3850 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3851 }
3852
3853 switch (e_flags & EF_MEP_COP_MASK)
3854 {
3855 case EF_MEP_COP_NONE: break;
3856 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3857 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3858 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3859 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3860 default: strcat (buf, _("<unknown MeP copro type>")); break;
3861 }
3862
3863 if (e_flags & EF_MEP_LIBRARY)
3864 strcat (buf, ", Built for Library");
3865
3866 if (e_flags & EF_MEP_INDEX_MASK)
3867 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3868 e_flags & EF_MEP_INDEX_MASK);
3869
3870 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3871 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3872 e_flags & ~ EF_MEP_ALL_FLAGS);
3873 break;
3874
252b5132
RH
3875 case EM_PPC:
3876 if (e_flags & EF_PPC_EMB)
3877 strcat (buf, ", emb");
3878
3879 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3880 strcat (buf, _(", relocatable"));
252b5132
RH
3881
3882 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3883 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3884 break;
3885
ee67d69a
AM
3886 case EM_PPC64:
3887 if (e_flags & EF_PPC64_ABI)
3888 {
3889 char abi[] = ", abiv0";
3890
3891 abi[6] += e_flags & EF_PPC64_ABI;
3892 strcat (buf, abi);
3893 }
3894 break;
3895
708e2187
NC
3896 case EM_V800:
3897 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3898 strcat (buf, ", RH850 ABI");
0b4362b0 3899
708e2187
NC
3900 if (e_flags & EF_V800_850E3)
3901 strcat (buf, ", V3 architecture");
3902
3903 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3904 strcat (buf, ", FPU not used");
3905
3906 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3907 strcat (buf, ", regmode: COMMON");
3908
3909 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3910 strcat (buf, ", r4 not used");
3911
3912 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3913 strcat (buf, ", r30 not used");
3914
3915 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3916 strcat (buf, ", r5 not used");
3917
3918 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3919 strcat (buf, ", r2 not used");
3920
3921 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3922 {
3923 switch (e_flags & - e_flags)
3924 {
3925 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3926 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3927 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3928 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3929 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3930 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3931 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3932 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3933 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3934 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3935 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3936 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3937 default: break;
3938 }
3939 }
3940 break;
3941
2b0337b0 3942 case EM_V850:
252b5132
RH
3943 case EM_CYGNUS_V850:
3944 switch (e_flags & EF_V850_ARCH)
3945 {
78c8d46c
NC
3946 case E_V850E3V5_ARCH:
3947 strcat (buf, ", v850e3v5");
3948 break;
1cd986c5
NC
3949 case E_V850E2V3_ARCH:
3950 strcat (buf, ", v850e2v3");
3951 break;
3952 case E_V850E2_ARCH:
3953 strcat (buf, ", v850e2");
3954 break;
3955 case E_V850E1_ARCH:
3956 strcat (buf, ", v850e1");
8ad30312 3957 break;
252b5132
RH
3958 case E_V850E_ARCH:
3959 strcat (buf, ", v850e");
3960 break;
252b5132
RH
3961 case E_V850_ARCH:
3962 strcat (buf, ", v850");
3963 break;
3964 default:
2b692964 3965 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3966 break;
3967 }
3968 break;
3969
2b0337b0 3970 case EM_M32R:
252b5132
RH
3971 case EM_CYGNUS_M32R:
3972 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3973 strcat (buf, ", m32r");
252b5132
RH
3974 break;
3975
3976 case EM_MIPS:
4fe85591 3977 case EM_MIPS_RS3_LE:
252b5132
RH
3978 if (e_flags & EF_MIPS_NOREORDER)
3979 strcat (buf, ", noreorder");
3980
3981 if (e_flags & EF_MIPS_PIC)
3982 strcat (buf, ", pic");
3983
3984 if (e_flags & EF_MIPS_CPIC)
3985 strcat (buf, ", cpic");
3986
d1bdd336
TS
3987 if (e_flags & EF_MIPS_UCODE)
3988 strcat (buf, ", ugen_reserved");
3989
252b5132
RH
3990 if (e_flags & EF_MIPS_ABI2)
3991 strcat (buf, ", abi2");
3992
43521d43
TS
3993 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3994 strcat (buf, ", odk first");
3995
a5d22d2a
TS
3996 if (e_flags & EF_MIPS_32BITMODE)
3997 strcat (buf, ", 32bitmode");
3998
ba92f887
MR
3999 if (e_flags & EF_MIPS_NAN2008)
4000 strcat (buf, ", nan2008");
4001
fef1b0b3
SE
4002 if (e_flags & EF_MIPS_FP64)
4003 strcat (buf, ", fp64");
4004
156c2f8b
NC
4005 switch ((e_flags & EF_MIPS_MACH))
4006 {
4007 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4008 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4009 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4010 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4011 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4012 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4013 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4014 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4015 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4016 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4017 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4018 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4019 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4020 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4021 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4022 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4023 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4024 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4025 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4026 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4027 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4028 case 0:
4029 /* We simply ignore the field in this case to avoid confusion:
4030 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4031 extension. */
4032 break;
2b692964 4033 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4034 }
43521d43
TS
4035
4036 switch ((e_flags & EF_MIPS_ABI))
4037 {
4038 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4039 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4040 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4041 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4042 case 0:
4043 /* We simply ignore the field in this case to avoid confusion:
4044 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4045 This means it is likely to be an o32 file, but not for
4046 sure. */
4047 break;
2b692964 4048 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4049 }
4050
4051 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4052 strcat (buf, ", mdmx");
4053
4054 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4055 strcat (buf, ", mips16");
4056
df58fc94
RS
4057 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4058 strcat (buf, ", micromips");
4059
43521d43
TS
4060 switch ((e_flags & EF_MIPS_ARCH))
4061 {
4062 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4063 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4064 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4065 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4066 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4067 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4068 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4069 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4070 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4071 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4072 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4073 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4074 }
252b5132 4075 break;
351b4b40 4076
35c08157
KLC
4077 case EM_NDS32:
4078 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4079 break;
4080
fe944acf
FT
4081 case EM_NFP:
4082 switch (EF_NFP_MACH (e_flags))
4083 {
4084 case E_NFP_MACH_3200:
4085 strcat (buf, ", NFP-32xx");
4086 break;
4087 case E_NFP_MACH_6000:
4088 strcat (buf, ", NFP-6xxx");
4089 break;
4090 }
4091 break;
4092
e23eba97
NC
4093 case EM_RISCV:
4094 if (e_flags & EF_RISCV_RVC)
4095 strcat (buf, ", RVC");
2922d21d 4096
7f999549
JW
4097 if (e_flags & EF_RISCV_RVE)
4098 strcat (buf, ", RVE");
4099
2922d21d
AW
4100 switch (e_flags & EF_RISCV_FLOAT_ABI)
4101 {
4102 case EF_RISCV_FLOAT_ABI_SOFT:
4103 strcat (buf, ", soft-float ABI");
4104 break;
4105
4106 case EF_RISCV_FLOAT_ABI_SINGLE:
4107 strcat (buf, ", single-float ABI");
4108 break;
4109
4110 case EF_RISCV_FLOAT_ABI_DOUBLE:
4111 strcat (buf, ", double-float ABI");
4112 break;
4113
4114 case EF_RISCV_FLOAT_ABI_QUAD:
4115 strcat (buf, ", quad-float ABI");
4116 break;
4117 }
e23eba97
NC
4118 break;
4119
ccde1100
AO
4120 case EM_SH:
4121 switch ((e_flags & EF_SH_MACH_MASK))
4122 {
4123 case EF_SH1: strcat (buf, ", sh1"); break;
4124 case EF_SH2: strcat (buf, ", sh2"); break;
4125 case EF_SH3: strcat (buf, ", sh3"); break;
4126 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4127 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4128 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4129 case EF_SH3E: strcat (buf, ", sh3e"); break;
4130 case EF_SH4: strcat (buf, ", sh4"); break;
4131 case EF_SH5: strcat (buf, ", sh5"); break;
4132 case EF_SH2E: strcat (buf, ", sh2e"); break;
4133 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4134 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4135 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4136 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4137 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4138 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4139 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4140 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4141 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4142 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4143 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4144 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4145 }
4146
cec6a5b8
MR
4147 if (e_flags & EF_SH_PIC)
4148 strcat (buf, ", pic");
4149
4150 if (e_flags & EF_SH_FDPIC)
4151 strcat (buf, ", fdpic");
ccde1100 4152 break;
948f632f 4153
73589c9d
CS
4154 case EM_OR1K:
4155 if (e_flags & EF_OR1K_NODELAY)
4156 strcat (buf, ", no delay");
4157 break;
57346661 4158
351b4b40
RH
4159 case EM_SPARCV9:
4160 if (e_flags & EF_SPARC_32PLUS)
4161 strcat (buf, ", v8+");
4162
4163 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4164 strcat (buf, ", ultrasparcI");
4165
4166 if (e_flags & EF_SPARC_SUN_US3)
4167 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4168
4169 if (e_flags & EF_SPARC_HAL_R1)
4170 strcat (buf, ", halr1");
4171
4172 if (e_flags & EF_SPARC_LEDATA)
4173 strcat (buf, ", ledata");
4174
4175 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4176 strcat (buf, ", tso");
4177
4178 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4179 strcat (buf, ", pso");
4180
4181 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4182 strcat (buf, ", rmo");
4183 break;
7d466069 4184
103f02d3
UD
4185 case EM_PARISC:
4186 switch (e_flags & EF_PARISC_ARCH)
4187 {
4188 case EFA_PARISC_1_0:
4189 strcpy (buf, ", PA-RISC 1.0");
4190 break;
4191 case EFA_PARISC_1_1:
4192 strcpy (buf, ", PA-RISC 1.1");
4193 break;
4194 case EFA_PARISC_2_0:
4195 strcpy (buf, ", PA-RISC 2.0");
4196 break;
4197 default:
4198 break;
4199 }
4200 if (e_flags & EF_PARISC_TRAPNIL)
4201 strcat (buf, ", trapnil");
4202 if (e_flags & EF_PARISC_EXT)
4203 strcat (buf, ", ext");
4204 if (e_flags & EF_PARISC_LSB)
4205 strcat (buf, ", lsb");
4206 if (e_flags & EF_PARISC_WIDE)
4207 strcat (buf, ", wide");
4208 if (e_flags & EF_PARISC_NO_KABP)
4209 strcat (buf, ", no kabp");
4210 if (e_flags & EF_PARISC_LAZYSWAP)
4211 strcat (buf, ", lazyswap");
30800947 4212 break;
76da6bbe 4213
7d466069 4214 case EM_PJ:
2b0337b0 4215 case EM_PJ_OLD:
7d466069
ILT
4216 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4217 strcat (buf, ", new calling convention");
4218
4219 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4220 strcat (buf, ", gnu calling convention");
4221 break;
4d6ed7c8
NC
4222
4223 case EM_IA_64:
4224 if ((e_flags & EF_IA_64_ABI64))
4225 strcat (buf, ", 64-bit");
4226 else
4227 strcat (buf, ", 32-bit");
4228 if ((e_flags & EF_IA_64_REDUCEDFP))
4229 strcat (buf, ", reduced fp model");
4230 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4231 strcat (buf, ", no function descriptors, constant gp");
4232 else if ((e_flags & EF_IA_64_CONS_GP))
4233 strcat (buf, ", constant gp");
4234 if ((e_flags & EF_IA_64_ABSOLUTE))
4235 strcat (buf, ", absolute");
dda8d76d 4236 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4237 {
4238 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4239 strcat (buf, ", vms_linkages");
4240 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4241 {
4242 case EF_IA_64_VMS_COMCOD_SUCCESS:
4243 break;
4244 case EF_IA_64_VMS_COMCOD_WARNING:
4245 strcat (buf, ", warning");
4246 break;
4247 case EF_IA_64_VMS_COMCOD_ERROR:
4248 strcat (buf, ", error");
4249 break;
4250 case EF_IA_64_VMS_COMCOD_ABORT:
4251 strcat (buf, ", abort");
4252 break;
4253 default:
bee0ee85
NC
4254 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4255 e_flags & EF_IA_64_VMS_COMCOD);
4256 strcat (buf, ", <unknown>");
28f997cf
TG
4257 }
4258 }
4d6ed7c8 4259 break;
179d3252
JT
4260
4261 case EM_VAX:
4262 if ((e_flags & EF_VAX_NONPIC))
4263 strcat (buf, ", non-PIC");
4264 if ((e_flags & EF_VAX_DFLOAT))
4265 strcat (buf, ", D-Float");
4266 if ((e_flags & EF_VAX_GFLOAT))
4267 strcat (buf, ", G-Float");
4268 break;
c7927a3c 4269
619ed720
EB
4270 case EM_VISIUM:
4271 if (e_flags & EF_VISIUM_ARCH_MCM)
4272 strcat (buf, ", mcm");
4273 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4274 strcat (buf, ", mcm24");
4275 if (e_flags & EF_VISIUM_ARCH_GR6)
4276 strcat (buf, ", gr6");
4277 break;
4278
4046d87a 4279 case EM_RL78:
1740ba0c
NC
4280 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4281 {
4282 case E_FLAG_RL78_ANY_CPU: break;
4283 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4284 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4285 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4286 }
856ea05c
KP
4287 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4288 strcat (buf, ", 64-bit doubles");
4046d87a 4289 break;
0b4362b0 4290
c7927a3c
NC
4291 case EM_RX:
4292 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4293 strcat (buf, ", 64-bit doubles");
4294 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4295 strcat (buf, ", dsp");
d4cb0ea0 4296 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4297 strcat (buf, ", pid");
708e2187
NC
4298 if (e_flags & E_FLAG_RX_ABI)
4299 strcat (buf, ", RX ABI");
3525236c
NC
4300 if (e_flags & E_FLAG_RX_SINSNS_SET)
4301 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4302 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4303 if (e_flags & E_FLAG_RX_V2)
4304 strcat (buf, ", V2");
f87673e0
YS
4305 if (e_flags & E_FLAG_RX_V3)
4306 strcat (buf, ", V3");
d4cb0ea0 4307 break;
55786da2
AK
4308
4309 case EM_S390:
4310 if (e_flags & EF_S390_HIGH_GPRS)
4311 strcat (buf, ", highgprs");
d4cb0ea0 4312 break;
40b36596
JM
4313
4314 case EM_TI_C6000:
4315 if ((e_flags & EF_C6000_REL))
4316 strcat (buf, ", relocatable module");
d4cb0ea0 4317 break;
13761a11
NC
4318
4319 case EM_MSP430:
4320 strcat (buf, _(": architecture variant: "));
4321 switch (e_flags & EF_MSP430_MACH)
4322 {
4323 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4324 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4325 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4326 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4327 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4328 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4329 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4330 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4331 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4332 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4333 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4334 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4335 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4336 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4337 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4338 default:
4339 strcat (buf, _(": unknown")); break;
4340 }
4341
4342 if (e_flags & ~ EF_MSP430_MACH)
4343 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4344 break;
4345
4346 case EM_Z80:
4347 switch (e_flags & EF_Z80_MACH_MSK)
4348 {
4349 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4350 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4351 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4352 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4353 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4354 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4355 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4356 default:
4357 strcat (buf, _(", unknown")); break;
4358 }
4359 break;
e9a0721f 4360 case EM_LOONGARCH:
4361 if (EF_LOONGARCH_IS_LP64 (e_flags))
4362 strcat (buf, ", LP64");
4363 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4364 strcat (buf, ", ILP32");
4365
4366 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4367 strcat (buf, ", SOFT-FLOAT");
4368 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4369 strcat (buf, ", SINGLE-FLOAT");
4370 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4371 strcat (buf, ", DOUBLE-FLOAT");
4372
4373 break;
252b5132
RH
4374 }
4375 }
4376
4377 return buf;
4378}
4379
252b5132 4380static const char *
dda8d76d 4381get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4382{
4383 static char buff[32];
4384
4385 switch (osabi)
4386 {
4387 case ELFOSABI_NONE: return "UNIX - System V";
4388 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4389 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4390 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4391 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4392 case ELFOSABI_AIX: return "UNIX - AIX";
4393 case ELFOSABI_IRIX: return "UNIX - IRIX";
4394 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4395 case ELFOSABI_TRU64: return "UNIX - TRU64";
4396 case ELFOSABI_MODESTO: return "Novell - Modesto";
4397 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4398 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4399 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4400 case ELFOSABI_AROS: return "AROS";
11636f9e 4401 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4402 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4403 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4404 default:
40b36596 4405 if (osabi >= 64)
dda8d76d 4406 switch (filedata->file_header.e_machine)
40b36596 4407 {
37870be8
SM
4408 case EM_AMDGPU:
4409 switch (osabi)
4410 {
4411 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4412 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4413 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4414 default:
4415 break;
4416 }
4417 break;
4418
40b36596
JM
4419 case EM_ARM:
4420 switch (osabi)
4421 {
4422 case ELFOSABI_ARM: return "ARM";
18a20338 4423 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4424 default:
4425 break;
4426 }
4427 break;
4428
4429 case EM_MSP430:
4430 case EM_MSP430_OLD:
619ed720 4431 case EM_VISIUM:
40b36596
JM
4432 switch (osabi)
4433 {
4434 case ELFOSABI_STANDALONE: return _("Standalone App");
4435 default:
4436 break;
4437 }
4438 break;
4439
4440 case EM_TI_C6000:
4441 switch (osabi)
4442 {
4443 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4444 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4445 default:
4446 break;
4447 }
4448 break;
4449
4450 default:
4451 break;
4452 }
e9e44622 4453 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4454 return buff;
4455 }
4456}
4457
a06ea964
NC
4458static const char *
4459get_aarch64_segment_type (unsigned long type)
4460{
4461 switch (type)
4462 {
32ec8896 4463 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4464 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4465 default: return NULL;
a06ea964 4466 }
a06ea964
NC
4467}
4468
b294bdf8
MM
4469static const char *
4470get_arm_segment_type (unsigned long type)
4471{
4472 switch (type)
4473 {
32ec8896
NC
4474 case PT_ARM_EXIDX: return "EXIDX";
4475 default: return NULL;
b294bdf8 4476 }
b294bdf8
MM
4477}
4478
b4cbbe8f
AK
4479static const char *
4480get_s390_segment_type (unsigned long type)
4481{
4482 switch (type)
4483 {
4484 case PT_S390_PGSTE: return "S390_PGSTE";
4485 default: return NULL;
4486 }
4487}
4488
d3ba0551
AM
4489static const char *
4490get_mips_segment_type (unsigned long type)
252b5132
RH
4491{
4492 switch (type)
4493 {
32ec8896
NC
4494 case PT_MIPS_REGINFO: return "REGINFO";
4495 case PT_MIPS_RTPROC: return "RTPROC";
4496 case PT_MIPS_OPTIONS: return "OPTIONS";
4497 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4498 default: return NULL;
252b5132 4499 }
252b5132
RH
4500}
4501
103f02d3 4502static const char *
d3ba0551 4503get_parisc_segment_type (unsigned long type)
103f02d3
UD
4504{
4505 switch (type)
4506 {
103f02d3
UD
4507 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4508 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4509 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4510 default: return NULL;
103f02d3 4511 }
103f02d3
UD
4512}
4513
4d6ed7c8 4514static const char *
d3ba0551 4515get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4516{
4517 switch (type)
4518 {
4519 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4520 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4521 default: return NULL;
4d6ed7c8 4522 }
4d6ed7c8
NC
4523}
4524
40b36596
JM
4525static const char *
4526get_tic6x_segment_type (unsigned long type)
4527{
4528 switch (type)
4529 {
32ec8896
NC
4530 case PT_C6000_PHATTR: return "C6000_PHATTR";
4531 default: return NULL;
40b36596 4532 }
40b36596
JM
4533}
4534
fbc95f1e
KC
4535static const char *
4536get_riscv_segment_type (unsigned long type)
4537{
4538 switch (type)
4539 {
4540 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4541 default: return NULL;
4542 }
4543}
4544
df3a023b
AM
4545static const char *
4546get_hpux_segment_type (unsigned long type, unsigned e_machine)
4547{
4548 if (e_machine == EM_PARISC)
4549 switch (type)
4550 {
4551 case PT_HP_TLS: return "HP_TLS";
4552 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4553 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4554 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4555 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4556 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4557 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4558 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4559 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4560 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4561 case PT_HP_PARALLEL: return "HP_PARALLEL";
4562 case PT_HP_FASTBIND: return "HP_FASTBIND";
4563 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4564 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4565 case PT_HP_STACK: return "HP_STACK";
4566 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4567 default: return NULL;
4568 }
4569
4570 if (e_machine == EM_IA_64)
4571 switch (type)
4572 {
4573 case PT_HP_TLS: return "HP_TLS";
4574 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4575 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4576 case PT_IA_64_HP_STACK: return "HP_STACK";
4577 default: return NULL;
4578 }
4579
4580 return NULL;
4581}
4582
5522f910
NC
4583static const char *
4584get_solaris_segment_type (unsigned long type)
4585{
4586 switch (type)
4587 {
4588 case 0x6464e550: return "PT_SUNW_UNWIND";
4589 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4590 case 0x6ffffff7: return "PT_LOSUNW";
4591 case 0x6ffffffa: return "PT_SUNWBSS";
4592 case 0x6ffffffb: return "PT_SUNWSTACK";
4593 case 0x6ffffffc: return "PT_SUNWDTRACE";
4594 case 0x6ffffffd: return "PT_SUNWCAP";
4595 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4596 default: return NULL;
5522f910
NC
4597 }
4598}
4599
252b5132 4600static const char *
dda8d76d 4601get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4602{
b34976b6 4603 static char buff[32];
252b5132
RH
4604
4605 switch (p_type)
4606 {
b34976b6
AM
4607 case PT_NULL: return "NULL";
4608 case PT_LOAD: return "LOAD";
252b5132 4609 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4610 case PT_INTERP: return "INTERP";
4611 case PT_NOTE: return "NOTE";
4612 case PT_SHLIB: return "SHLIB";
4613 case PT_PHDR: return "PHDR";
13ae64f3 4614 case PT_TLS: return "TLS";
32ec8896 4615 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4616 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4617 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4618 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4619
3eba3ef3
NC
4620 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4621 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4622 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4623
252b5132 4624 default:
df3a023b 4625 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4626 {
2cf0635d 4627 const char * result;
103f02d3 4628
dda8d76d 4629 switch (filedata->file_header.e_machine)
252b5132 4630 {
a06ea964
NC
4631 case EM_AARCH64:
4632 result = get_aarch64_segment_type (p_type);
4633 break;
b294bdf8
MM
4634 case EM_ARM:
4635 result = get_arm_segment_type (p_type);
4636 break;
252b5132 4637 case EM_MIPS:
4fe85591 4638 case EM_MIPS_RS3_LE:
252b5132
RH
4639 result = get_mips_segment_type (p_type);
4640 break;
103f02d3
UD
4641 case EM_PARISC:
4642 result = get_parisc_segment_type (p_type);
4643 break;
4d6ed7c8
NC
4644 case EM_IA_64:
4645 result = get_ia64_segment_type (p_type);
4646 break;
40b36596
JM
4647 case EM_TI_C6000:
4648 result = get_tic6x_segment_type (p_type);
4649 break;
b4cbbe8f
AK
4650 case EM_S390:
4651 case EM_S390_OLD:
4652 result = get_s390_segment_type (p_type);
4653 break;
fbc95f1e
KC
4654 case EM_RISCV:
4655 result = get_riscv_segment_type (p_type);
4656 break;
252b5132
RH
4657 default:
4658 result = NULL;
4659 break;
4660 }
103f02d3 4661
252b5132
RH
4662 if (result != NULL)
4663 return result;
103f02d3 4664
1a9ccd70 4665 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4666 }
4667 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4668 {
df3a023b 4669 const char * result = NULL;
103f02d3 4670
df3a023b 4671 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4672 {
df3a023b
AM
4673 case ELFOSABI_GNU:
4674 case ELFOSABI_FREEBSD:
4675 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4676 {
4677 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4678 result = buff;
4679 }
103f02d3 4680 break;
df3a023b
AM
4681 case ELFOSABI_HPUX:
4682 result = get_hpux_segment_type (p_type,
4683 filedata->file_header.e_machine);
4684 break;
4685 case ELFOSABI_SOLARIS:
4686 result = get_solaris_segment_type (p_type);
00428cca 4687 break;
103f02d3 4688 default:
103f02d3
UD
4689 break;
4690 }
103f02d3
UD
4691 if (result != NULL)
4692 return result;
4693
1a9ccd70 4694 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4695 }
252b5132 4696 else
e9e44622 4697 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4698
4699 return buff;
4700 }
4701}
4702
53a346d8
CZ
4703static const char *
4704get_arc_section_type_name (unsigned int sh_type)
4705{
4706 switch (sh_type)
4707 {
4708 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4709 default:
4710 break;
4711 }
4712 return NULL;
4713}
4714
252b5132 4715static const char *
d3ba0551 4716get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4717{
4718 switch (sh_type)
4719 {
b34976b6
AM
4720 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4721 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4722 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4723 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4724 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4725 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4726 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4727 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4728 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4729 case SHT_MIPS_RELD: return "MIPS_RELD";
4730 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4731 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4732 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4733 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4734 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4735 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4736 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4737 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4738 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4739 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4740 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4741 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4742 case SHT_MIPS_LINE: return "MIPS_LINE";
4743 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4744 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4745 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4746 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4747 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4748 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4749 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4750 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4751 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4752 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4753 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4754 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4755 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4756 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4757 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4758 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4759 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4760 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4761 default:
4762 break;
4763 }
4764 return NULL;
4765}
4766
103f02d3 4767static const char *
d3ba0551 4768get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4769{
4770 switch (sh_type)
4771 {
4772 case SHT_PARISC_EXT: return "PARISC_EXT";
4773 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4774 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4775 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4776 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4777 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4778 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4779 default: return NULL;
103f02d3 4780 }
103f02d3
UD
4781}
4782
4d6ed7c8 4783static const char *
dda8d76d 4784get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4785{
18bd398b 4786 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4787 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4788 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4789
4d6ed7c8
NC
4790 switch (sh_type)
4791 {
148b93f2
NC
4792 case SHT_IA_64_EXT: return "IA_64_EXT";
4793 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4794 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4795 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4796 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4797 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4798 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4799 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4800 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4801 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4802 default:
4803 break;
4804 }
4805 return NULL;
4806}
4807
d2b2c203
DJ
4808static const char *
4809get_x86_64_section_type_name (unsigned int sh_type)
4810{
4811 switch (sh_type)
4812 {
4813 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4814 default: return NULL;
d2b2c203 4815 }
d2b2c203
DJ
4816}
4817
a06ea964
NC
4818static const char *
4819get_aarch64_section_type_name (unsigned int sh_type)
4820{
4821 switch (sh_type)
4822 {
32ec8896
NC
4823 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4824 default: return NULL;
a06ea964 4825 }
a06ea964
NC
4826}
4827
40a18ebd
NC
4828static const char *
4829get_arm_section_type_name (unsigned int sh_type)
4830{
4831 switch (sh_type)
4832 {
7f6fed87
NC
4833 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4834 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4835 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4836 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4837 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4838 default: return NULL;
40a18ebd 4839 }
40a18ebd
NC
4840}
4841
40b36596
JM
4842static const char *
4843get_tic6x_section_type_name (unsigned int sh_type)
4844{
4845 switch (sh_type)
4846 {
32ec8896
NC
4847 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4848 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4849 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4850 case SHT_TI_ICODE: return "TI_ICODE";
4851 case SHT_TI_XREF: return "TI_XREF";
4852 case SHT_TI_HANDLER: return "TI_HANDLER";
4853 case SHT_TI_INITINFO: return "TI_INITINFO";
4854 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4855 default: return NULL;
40b36596 4856 }
40b36596
JM
4857}
4858
13761a11 4859static const char *
b0191216 4860get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4861{
4862 switch (sh_type)
4863 {
32ec8896
NC
4864 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4865 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4866 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4867 default: return NULL;
13761a11
NC
4868 }
4869}
4870
fe944acf
FT
4871static const char *
4872get_nfp_section_type_name (unsigned int sh_type)
4873{
4874 switch (sh_type)
4875 {
4876 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4877 case SHT_NFP_INITREG: return "NFP_INITREG";
4878 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4879 default: return NULL;
4880 }
4881}
4882
685080f2
NC
4883static const char *
4884get_v850_section_type_name (unsigned int sh_type)
4885{
4886 switch (sh_type)
4887 {
32ec8896
NC
4888 case SHT_V850_SCOMMON: return "V850 Small Common";
4889 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4890 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4891 case SHT_RENESAS_IOP: return "RENESAS IOP";
4892 case SHT_RENESAS_INFO: return "RENESAS INFO";
4893 default: return NULL;
685080f2
NC
4894 }
4895}
4896
2dc8dd17
JW
4897static const char *
4898get_riscv_section_type_name (unsigned int sh_type)
4899{
4900 switch (sh_type)
4901 {
4902 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4903 default: return NULL;
4904 }
4905}
4906
0861f561
CQ
4907static const char *
4908get_csky_section_type_name (unsigned int sh_type)
4909{
4910 switch (sh_type)
4911 {
4912 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4913 default: return NULL;
4914 }
4915}
4916
252b5132 4917static const char *
dda8d76d 4918get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4919{
b34976b6 4920 static char buff[32];
9fb71ee4 4921 const char * result;
252b5132
RH
4922
4923 switch (sh_type)
4924 {
4925 case SHT_NULL: return "NULL";
4926 case SHT_PROGBITS: return "PROGBITS";
4927 case SHT_SYMTAB: return "SYMTAB";
4928 case SHT_STRTAB: return "STRTAB";
4929 case SHT_RELA: return "RELA";
dd207c13 4930 case SHT_RELR: return "RELR";
252b5132
RH
4931 case SHT_HASH: return "HASH";
4932 case SHT_DYNAMIC: return "DYNAMIC";
4933 case SHT_NOTE: return "NOTE";
4934 case SHT_NOBITS: return "NOBITS";
4935 case SHT_REL: return "REL";
4936 case SHT_SHLIB: return "SHLIB";
4937 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4938 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4939 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4940 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4941 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4942 case SHT_GROUP: return "GROUP";
67ce483b 4943 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4944 case SHT_GNU_verdef: return "VERDEF";
4945 case SHT_GNU_verneed: return "VERNEED";
4946 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4947 case 0x6ffffff0: return "VERSYM";
4948 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4949 case 0x7ffffffd: return "AUXILIARY";
4950 case 0x7fffffff: return "FILTER";
047b2264 4951 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4952
4953 default:
4954 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4955 {
dda8d76d 4956 switch (filedata->file_header.e_machine)
252b5132 4957 {
53a346d8
CZ
4958 case EM_ARC:
4959 case EM_ARC_COMPACT:
4960 case EM_ARC_COMPACT2:
4961 result = get_arc_section_type_name (sh_type);
4962 break;
252b5132 4963 case EM_MIPS:
4fe85591 4964 case EM_MIPS_RS3_LE:
252b5132
RH
4965 result = get_mips_section_type_name (sh_type);
4966 break;
103f02d3
UD
4967 case EM_PARISC:
4968 result = get_parisc_section_type_name (sh_type);
4969 break;
4d6ed7c8 4970 case EM_IA_64:
dda8d76d 4971 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4972 break;
d2b2c203 4973 case EM_X86_64:
8a9036a4 4974 case EM_L1OM:
7a9068fe 4975 case EM_K1OM:
d2b2c203
DJ
4976 result = get_x86_64_section_type_name (sh_type);
4977 break;
a06ea964
NC
4978 case EM_AARCH64:
4979 result = get_aarch64_section_type_name (sh_type);
4980 break;
40a18ebd
NC
4981 case EM_ARM:
4982 result = get_arm_section_type_name (sh_type);
4983 break;
40b36596
JM
4984 case EM_TI_C6000:
4985 result = get_tic6x_section_type_name (sh_type);
4986 break;
13761a11 4987 case EM_MSP430:
b0191216 4988 result = get_msp430_section_type_name (sh_type);
13761a11 4989 break;
fe944acf
FT
4990 case EM_NFP:
4991 result = get_nfp_section_type_name (sh_type);
4992 break;
685080f2
NC
4993 case EM_V800:
4994 case EM_V850:
4995 case EM_CYGNUS_V850:
4996 result = get_v850_section_type_name (sh_type);
4997 break;
2dc8dd17
JW
4998 case EM_RISCV:
4999 result = get_riscv_section_type_name (sh_type);
5000 break;
0861f561
CQ
5001 case EM_CSKY:
5002 result = get_csky_section_type_name (sh_type);
5003 break;
252b5132
RH
5004 default:
5005 result = NULL;
5006 break;
5007 }
5008
5009 if (result != NULL)
5010 return result;
5011
9fb71ee4 5012 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5013 }
5014 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5015 {
dda8d76d 5016 switch (filedata->file_header.e_machine)
148b93f2
NC
5017 {
5018 case EM_IA_64:
dda8d76d 5019 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5020 break;
5021 default:
dda8d76d 5022 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5023 result = get_solaris_section_type (sh_type);
5024 else
1b4b80bf
NC
5025 {
5026 switch (sh_type)
5027 {
5028 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5029 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5030 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5031 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5032 default:
5033 result = NULL;
5034 break;
5035 }
5036 }
148b93f2
NC
5037 break;
5038 }
5039
5040 if (result != NULL)
5041 return result;
5042
9fb71ee4 5043 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5044 }
252b5132 5045 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5046 {
dda8d76d 5047 switch (filedata->file_header.e_machine)
685080f2
NC
5048 {
5049 case EM_V800:
5050 case EM_V850:
5051 case EM_CYGNUS_V850:
9fb71ee4 5052 result = get_v850_section_type_name (sh_type);
a9fb83be 5053 break;
685080f2 5054 default:
9fb71ee4 5055 result = NULL;
685080f2
NC
5056 break;
5057 }
5058
9fb71ee4
NC
5059 if (result != NULL)
5060 return result;
5061
5062 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5063 }
252b5132 5064 else
a7dbfd1c
NC
5065 /* This message is probably going to be displayed in a 15
5066 character wide field, so put the hex value first. */
5067 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5068
252b5132
RH
5069 return buff;
5070 }
5071}
5072
79bc120c
NC
5073enum long_option_values
5074{
5075 OPTION_DEBUG_DUMP = 512,
5076 OPTION_DYN_SYMS,
0f03783c 5077 OPTION_LTO_SYMS,
79bc120c
NC
5078 OPTION_DWARF_DEPTH,
5079 OPTION_DWARF_START,
5080 OPTION_DWARF_CHECK,
5081 OPTION_CTF_DUMP,
5082 OPTION_CTF_PARENT,
5083 OPTION_CTF_SYMBOLS,
5084 OPTION_CTF_STRINGS,
5085 OPTION_WITH_SYMBOL_VERSIONS,
5086 OPTION_RECURSE_LIMIT,
5087 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5088 OPTION_NO_DEMANGLING,
5089 OPTION_SYM_BASE
79bc120c 5090};
2979dc34 5091
85b1c36d 5092static struct option options[] =
252b5132 5093{
79bc120c
NC
5094 /* Note - This table is alpha-sorted on the 'val'
5095 field in order to make adding new options easier. */
5096 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5097 {"all", no_argument, 0, 'a'},
79bc120c
NC
5098 {"demangle", optional_argument, 0, 'C'},
5099 {"archive-index", no_argument, 0, 'c'},
5100 {"use-dynamic", no_argument, 0, 'D'},
5101 {"dynamic", no_argument, 0, 'd'},
b34976b6 5102 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5103 {"section-groups", no_argument, 0, 'g'},
5104 {"help", no_argument, 0, 'H'},
5105 {"file-header", no_argument, 0, 'h'},
b34976b6 5106 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5107 {"lint", no_argument, 0, 'L'},
5108 {"enable-checks", no_argument, 0, 'L'},
5109 {"program-headers", no_argument, 0, 'l'},
b34976b6 5110 {"segments", no_argument, 0, 'l'},
595cf52e 5111 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5112 {"notes", no_argument, 0, 'n'},
ca0e11aa 5113 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5114 {"string-dump", required_argument, 0, 'p'},
5115 {"relocated-dump", required_argument, 0, 'R'},
5116 {"relocs", no_argument, 0, 'r'},
5117 {"section-headers", no_argument, 0, 'S'},
5118 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5119 {"symbols", no_argument, 0, 's'},
5120 {"syms", no_argument, 0, 's'},
79bc120c
NC
5121 {"silent-truncation",no_argument, 0, 'T'},
5122 {"section-details", no_argument, 0, 't'},
b3aa80b4 5123 {"unicode", required_argument, NULL, 'U'},
09c11c86 5124 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5125 {"version-info", no_argument, 0, 'V'},
5126 {"version", no_argument, 0, 'v'},
5127 {"wide", no_argument, 0, 'W'},
b34976b6 5128 {"hex-dump", required_argument, 0, 'x'},
0e602686 5129 {"decompress", no_argument, 0, 'z'},
252b5132 5130
79bc120c
NC
5131 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5132 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5133 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5134 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5135 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5136 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5137 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5138 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5139 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5140 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5141#ifdef ENABLE_LIBCTF
d344b407 5142 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5143 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5144 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5145 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5146#endif
047c3dbf 5147 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5148
b34976b6 5149 {0, no_argument, 0, 0}
252b5132
RH
5150};
5151
5152static void
2cf0635d 5153usage (FILE * stream)
252b5132 5154{
92f01d61
JM
5155 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5156 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5157 fprintf (stream, _(" Options are:\n"));
5158 fprintf (stream, _("\
5159 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5160 fprintf (stream, _("\
5161 -h --file-header Display the ELF file header\n"));
5162 fprintf (stream, _("\
5163 -l --program-headers Display the program headers\n"));
5164 fprintf (stream, _("\
5165 --segments An alias for --program-headers\n"));
5166 fprintf (stream, _("\
5167 -S --section-headers Display the sections' header\n"));
5168 fprintf (stream, _("\
5169 --sections An alias for --section-headers\n"));
5170 fprintf (stream, _("\
5171 -g --section-groups Display the section groups\n"));
5172 fprintf (stream, _("\
5173 -t --section-details Display the section details\n"));
5174 fprintf (stream, _("\
5175 -e --headers Equivalent to: -h -l -S\n"));
5176 fprintf (stream, _("\
5177 -s --syms Display the symbol table\n"));
5178 fprintf (stream, _("\
5179 --symbols An alias for --syms\n"));
5180 fprintf (stream, _("\
5181 --dyn-syms Display the dynamic symbol table\n"));
5182 fprintf (stream, _("\
5183 --lto-syms Display LTO symbol tables\n"));
5184 fprintf (stream, _("\
047c3dbf
NL
5185 --sym-base=[0|8|10|16] \n\
5186 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5187 mixed (the default), octal, decimal, hexadecimal.\n"));
5188 fprintf (stream, _("\
0d646226
AM
5189 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5190 display_demangler_styles (stream, _("\
5191 STYLE can be "));
d6249f5f
AM
5192 fprintf (stream, _("\
5193 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5194 fprintf (stream, _("\
5195 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5196 fprintf (stream, _("\
5197 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5198 fprintf (stream, _("\
5199 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5200 Display unicode characters as determined by the current locale\n\
5201 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5202 escape sequences, or treat them as invalid and display as\n\
5203 \"{hex sequences}\"\n"));
d6249f5f
AM
5204 fprintf (stream, _("\
5205 -n --notes Display the core notes (if present)\n"));
5206 fprintf (stream, _("\
5207 -r --relocs Display the relocations (if present)\n"));
5208 fprintf (stream, _("\
5209 -u --unwind Display the unwind info (if present)\n"));
5210 fprintf (stream, _("\
5211 -d --dynamic Display the dynamic section (if present)\n"));
5212 fprintf (stream, _("\
5213 -V --version-info Display the version sections (if present)\n"));
5214 fprintf (stream, _("\
5215 -A --arch-specific Display architecture specific information (if any)\n"));
5216 fprintf (stream, _("\
5217 -c --archive-index Display the symbol/file index in an archive\n"));
5218 fprintf (stream, _("\
5219 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5220 fprintf (stream, _("\
5221 -L --lint|--enable-checks\n\
5222 Display warning messages for possible problems\n"));
5223 fprintf (stream, _("\
09c11c86 5224 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5225 Dump the contents of section <number|name> as bytes\n"));
5226 fprintf (stream, _("\
09c11c86 5227 -p --string-dump=<number|name>\n\
d6249f5f
AM
5228 Dump the contents of section <number|name> as strings\n"));
5229 fprintf (stream, _("\
cf13d699 5230 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5231 Dump the relocated contents of section <number|name>\n"));
5232 fprintf (stream, _("\
5233 -z --decompress Decompress section before dumping it\n"));
5234 fprintf (stream, _("\
5235 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5236 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5237 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5238 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5239 U/=trace_info]\n\
5240 Display the contents of DWARF debug sections\n"));
5241 fprintf (stream, _("\
5242 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5243 debuginfo files\n"));
5244 fprintf (stream, _("\
5245 -P --process-links Display the contents of non-debug sections in separate\n\
5246 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5247#if DEFAULT_FOR_FOLLOW_LINKS
5248 fprintf (stream, _("\
d6249f5f
AM
5249 -wK --debug-dump=follow-links\n\
5250 Follow links to separate debug info files (default)\n"));
5251 fprintf (stream, _("\
5252 -wN --debug-dump=no-follow-links\n\
5253 Do not follow links to separate debug info files\n"));
c46b7066
NC
5254#else
5255 fprintf (stream, _("\
d6249f5f
AM
5256 -wK --debug-dump=follow-links\n\
5257 Follow links to separate debug info files\n"));
5258 fprintf (stream, _("\
5259 -wN --debug-dump=no-follow-links\n\
5260 Do not follow links to separate debug info files\n\
5261 (default)\n"));
bed566bb
NC
5262#endif
5263#if HAVE_LIBDEBUGINFOD
5264 fprintf (stream, _("\
5265 -wD --debug-dump=use-debuginfod\n\
5266 When following links, also query debuginfod servers (default)\n"));
5267 fprintf (stream, _("\
5268 -wE --debug-dump=do-not-use-debuginfod\n\
5269 When following links, do not query debuginfod servers\n"));
c46b7066 5270#endif
fd2f0033 5271 fprintf (stream, _("\
d6249f5f
AM
5272 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5273 fprintf (stream, _("\
5274 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5275#ifdef ENABLE_LIBCTF
7d9813f1 5276 fprintf (stream, _("\
d6249f5f
AM
5277 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5278 fprintf (stream, _("\
80b56fad 5279 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5280 fprintf (stream, _("\
7d9813f1 5281 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5282 Use section <number|name> as the CTF external symtab\n"));
5283 fprintf (stream, _("\
7d9813f1 5284 --ctf-strings=<number|name>\n\
d6249f5f 5285 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5286#endif
7d9813f1 5287
252b5132 5288#ifdef SUPPORT_DISASSEMBLY
92f01d61 5289 fprintf (stream, _("\
09c11c86
NC
5290 -i --instruction-dump=<number|name>\n\
5291 Disassemble the contents of section <number|name>\n"));
252b5132 5292#endif
92f01d61 5293 fprintf (stream, _("\
d6249f5f
AM
5294 -I --histogram Display histogram of bucket list lengths\n"));
5295 fprintf (stream, _("\
5296 -W --wide Allow output width to exceed 80 characters\n"));
5297 fprintf (stream, _("\
5298 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5299 fprintf (stream, _("\
5300 @<file> Read options from <file>\n"));
5301 fprintf (stream, _("\
5302 -H --help Display this information\n"));
5303 fprintf (stream, _("\
8b53311e 5304 -v --version Display the version number of readelf\n"));
1118d252 5305
92f01d61
JM
5306 if (REPORT_BUGS_TO[0] && stream == stdout)
5307 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5308
92f01d61 5309 exit (stream == stdout ? 0 : 1);
252b5132
RH
5310}
5311
18bd398b
NC
5312/* Record the fact that the user wants the contents of section number
5313 SECTION to be displayed using the method(s) encoded as flags bits
5314 in TYPE. Note, TYPE can be zero if we are creating the array for
5315 the first time. */
5316
252b5132 5317static void
6431e409
AM
5318request_dump_bynumber (struct dump_data *dumpdata,
5319 unsigned int section, dump_type type)
252b5132 5320{
6431e409 5321 if (section >= dumpdata->num_dump_sects)
252b5132 5322 {
2cf0635d 5323 dump_type * new_dump_sects;
252b5132 5324
3f5e193b 5325 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5326 sizeof (* new_dump_sects));
252b5132
RH
5327
5328 if (new_dump_sects == NULL)
591a748a 5329 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5330 else
5331 {
6431e409 5332 if (dumpdata->dump_sects)
21b65bac
NC
5333 {
5334 /* Copy current flag settings. */
6431e409
AM
5335 memcpy (new_dump_sects, dumpdata->dump_sects,
5336 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5337
6431e409 5338 free (dumpdata->dump_sects);
21b65bac 5339 }
252b5132 5340
6431e409
AM
5341 dumpdata->dump_sects = new_dump_sects;
5342 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5343 }
5344 }
5345
6431e409
AM
5346 if (dumpdata->dump_sects)
5347 dumpdata->dump_sects[section] |= type;
252b5132
RH
5348}
5349
aef1f6d0
DJ
5350/* Request a dump by section name. */
5351
5352static void
2cf0635d 5353request_dump_byname (const char * section, dump_type type)
aef1f6d0 5354{
2cf0635d 5355 struct dump_list_entry * new_request;
aef1f6d0 5356
3f5e193b
NC
5357 new_request = (struct dump_list_entry *)
5358 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5359 if (!new_request)
591a748a 5360 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5361
5362 new_request->name = strdup (section);
5363 if (!new_request->name)
591a748a 5364 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5365
5366 new_request->type = type;
5367
5368 new_request->next = dump_sects_byname;
5369 dump_sects_byname = new_request;
5370}
5371
cf13d699 5372static inline void
6431e409 5373request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5374{
5375 int section;
5376 char * cp;
5377
015dc7e1 5378 do_dump = true;
cf13d699
NC
5379 section = strtoul (optarg, & cp, 0);
5380
5381 if (! *cp && section >= 0)
6431e409 5382 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5383 else
5384 request_dump_byname (optarg, type);
5385}
5386
252b5132 5387static void
6431e409 5388parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5389{
5390 int c;
5391
5392 if (argc < 2)
92f01d61 5393 usage (stderr);
252b5132
RH
5394
5395 while ((c = getopt_long
b3aa80b4 5396 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5397 {
252b5132
RH
5398 switch (c)
5399 {
5400 case 0:
5401 /* Long options. */
5402 break;
5403 case 'H':
92f01d61 5404 usage (stdout);
252b5132
RH
5405 break;
5406
5407 case 'a':
015dc7e1
AM
5408 do_syms = true;
5409 do_reloc = true;
5410 do_unwind = true;
5411 do_dynamic = true;
5412 do_header = true;
5413 do_sections = true;
5414 do_section_groups = true;
5415 do_segments = true;
5416 do_version = true;
5417 do_histogram = true;
5418 do_arch = true;
5419 do_notes = true;
252b5132 5420 break;
79bc120c 5421
f5842774 5422 case 'g':
015dc7e1 5423 do_section_groups = true;
f5842774 5424 break;
5477e8a0 5425 case 't':
595cf52e 5426 case 'N':
015dc7e1
AM
5427 do_sections = true;
5428 do_section_details = true;
595cf52e 5429 break;
252b5132 5430 case 'e':
015dc7e1
AM
5431 do_header = true;
5432 do_sections = true;
5433 do_segments = true;
252b5132 5434 break;
a952a375 5435 case 'A':
015dc7e1 5436 do_arch = true;
a952a375 5437 break;
252b5132 5438 case 'D':
015dc7e1 5439 do_using_dynamic = true;
252b5132
RH
5440 break;
5441 case 'r':
015dc7e1 5442 do_reloc = true;
252b5132 5443 break;
4d6ed7c8 5444 case 'u':
015dc7e1 5445 do_unwind = true;
4d6ed7c8 5446 break;
252b5132 5447 case 'h':
015dc7e1 5448 do_header = true;
252b5132
RH
5449 break;
5450 case 'l':
015dc7e1 5451 do_segments = true;
252b5132
RH
5452 break;
5453 case 's':
015dc7e1 5454 do_syms = true;
252b5132
RH
5455 break;
5456 case 'S':
015dc7e1 5457 do_sections = true;
252b5132
RH
5458 break;
5459 case 'd':
015dc7e1 5460 do_dynamic = true;
252b5132 5461 break;
a952a375 5462 case 'I':
015dc7e1 5463 do_histogram = true;
a952a375 5464 break;
779fe533 5465 case 'n':
015dc7e1 5466 do_notes = true;
779fe533 5467 break;
4145f1d5 5468 case 'c':
015dc7e1 5469 do_archive_index = true;
4145f1d5 5470 break;
1b513401 5471 case 'L':
015dc7e1 5472 do_checks = true;
1b513401 5473 break;
ca0e11aa 5474 case 'P':
015dc7e1
AM
5475 process_links = true;
5476 do_follow_links = true;
e1dbfc17 5477 dump_any_debugging = true;
ca0e11aa 5478 break;
252b5132 5479 case 'x':
6431e409 5480 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5481 break;
09c11c86 5482 case 'p':
6431e409 5483 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5484 break;
5485 case 'R':
6431e409 5486 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5487 break;
0e602686 5488 case 'z':
015dc7e1 5489 decompress_dumps = true;
0e602686 5490 break;
252b5132 5491 case 'w':
0f03783c 5492 if (optarg == NULL)
613ff48b 5493 {
015dc7e1 5494 do_debugging = true;
94585d6d
NC
5495 do_dump = true;
5496 dump_any_debugging = true;
613ff48b
CC
5497 dwarf_select_sections_all ();
5498 }
252b5132
RH
5499 else
5500 {
015dc7e1 5501 do_debugging = false;
94585d6d
NC
5502 if (dwarf_select_sections_by_letters (optarg))
5503 {
5504 do_dump = true;
5505 dump_any_debugging = true;
5506 }
252b5132
RH
5507 }
5508 break;
2979dc34 5509 case OPTION_DEBUG_DUMP:
0f03783c 5510 if (optarg == NULL)
d6249f5f 5511 {
94585d6d 5512 do_dump = true;
d6249f5f 5513 do_debugging = true;
94585d6d 5514 dump_any_debugging = true;
d6249f5f
AM
5515 dwarf_select_sections_all ();
5516 }
2979dc34
JJ
5517 else
5518 {
015dc7e1 5519 do_debugging = false;
94585d6d
NC
5520 if (dwarf_select_sections_by_names (optarg))
5521 {
5522 do_dump = true;
5523 dump_any_debugging = true;
5524 }
2979dc34
JJ
5525 }
5526 break;
fd2f0033
TT
5527 case OPTION_DWARF_DEPTH:
5528 {
5529 char *cp;
5530
5531 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5532 }
5533 break;
5534 case OPTION_DWARF_START:
5535 {
5536 char *cp;
5537
5538 dwarf_start_die = strtoul (optarg, & cp, 0);
5539 }
5540 break;
4723351a 5541 case OPTION_DWARF_CHECK:
015dc7e1 5542 dwarf_check = true;
4723351a 5543 break;
7d9813f1 5544 case OPTION_CTF_DUMP:
015dc7e1 5545 do_ctf = true;
6431e409 5546 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5547 break;
5548 case OPTION_CTF_SYMBOLS:
df16e041 5549 free (dump_ctf_symtab_name);
7d9813f1
NA
5550 dump_ctf_symtab_name = strdup (optarg);
5551 break;
5552 case OPTION_CTF_STRINGS:
df16e041 5553 free (dump_ctf_strtab_name);
7d9813f1
NA
5554 dump_ctf_strtab_name = strdup (optarg);
5555 break;
5556 case OPTION_CTF_PARENT:
df16e041 5557 free (dump_ctf_parent_name);
7d9813f1
NA
5558 dump_ctf_parent_name = strdup (optarg);
5559 break;
2c610e4b 5560 case OPTION_DYN_SYMS:
015dc7e1 5561 do_dyn_syms = true;
2c610e4b 5562 break;
0f03783c 5563 case OPTION_LTO_SYMS:
015dc7e1 5564 do_lto_syms = true;
0f03783c 5565 break;
252b5132
RH
5566#ifdef SUPPORT_DISASSEMBLY
5567 case 'i':
6431e409 5568 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5569 break;
252b5132
RH
5570#endif
5571 case 'v':
5572 print_version (program_name);
5573 break;
5574 case 'V':
015dc7e1 5575 do_version = true;
252b5132 5576 break;
d974e256 5577 case 'W':
015dc7e1 5578 do_wide = true;
d974e256 5579 break;
0942c7ab 5580 case 'T':
015dc7e1 5581 do_not_show_symbol_truncation = true;
0942c7ab 5582 break;
79bc120c 5583 case 'C':
015dc7e1 5584 do_demangle = true;
79bc120c
NC
5585 if (optarg != NULL)
5586 {
5587 enum demangling_styles style;
5588
5589 style = cplus_demangle_name_to_style (optarg);
5590 if (style == unknown_demangling)
5591 error (_("unknown demangling style `%s'"), optarg);
5592
5593 cplus_demangle_set_style (style);
5594 }
5595 break;
5596 case OPTION_NO_DEMANGLING:
015dc7e1 5597 do_demangle = false;
79bc120c
NC
5598 break;
5599 case OPTION_RECURSE_LIMIT:
5600 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5601 break;
5602 case OPTION_NO_RECURSE_LIMIT:
5603 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5604 break;
5605 case OPTION_WITH_SYMBOL_VERSIONS:
5606 /* Ignored for backward compatibility. */
5607 break;
b9e920ec 5608
b3aa80b4
NC
5609 case 'U':
5610 if (optarg == NULL)
5611 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5612 else if (streq (optarg, "default") || streq (optarg, "d"))
5613 unicode_display = unicode_default;
5614 else if (streq (optarg, "locale") || streq (optarg, "l"))
5615 unicode_display = unicode_locale;
5616 else if (streq (optarg, "escape") || streq (optarg, "e"))
5617 unicode_display = unicode_escape;
5618 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5619 unicode_display = unicode_invalid;
5620 else if (streq (optarg, "hex") || streq (optarg, "x"))
5621 unicode_display = unicode_hex;
5622 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5623 unicode_display = unicode_highlight;
5624 else
5625 error (_("invalid argument to -U/--unicode: %s"), optarg);
5626 break;
5627
047c3dbf
NL
5628 case OPTION_SYM_BASE:
5629 sym_base = 0;
5630 if (optarg != NULL)
5631 {
5632 sym_base = strtoul (optarg, NULL, 0);
5633 switch (sym_base)
5634 {
5635 case 0:
5636 case 8:
5637 case 10:
5638 case 16:
5639 break;
5640
5641 default:
5642 sym_base = 0;
5643 break;
5644 }
5645 }
5646 break;
5647
252b5132 5648 default:
252b5132
RH
5649 /* xgettext:c-format */
5650 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5651 /* Fall through. */
252b5132 5652 case '?':
92f01d61 5653 usage (stderr);
252b5132
RH
5654 }
5655 }
5656
4d6ed7c8 5657 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5658 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5659 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5660 && !do_section_groups && !do_archive_index
0f03783c 5661 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5662 {
5663 if (do_checks)
5664 {
015dc7e1
AM
5665 check_all = true;
5666 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5667 do_segments = do_header = do_dump = do_version = true;
5668 do_histogram = do_debugging = do_arch = do_notes = true;
5669 do_section_groups = do_archive_index = do_dyn_syms = true;
5670 do_lto_syms = true;
1b513401
NC
5671 }
5672 else
5673 usage (stderr);
5674 }
252b5132
RH
5675}
5676
5677static const char *
d3ba0551 5678get_elf_class (unsigned int elf_class)
252b5132 5679{
b34976b6 5680 static char buff[32];
103f02d3 5681
252b5132
RH
5682 switch (elf_class)
5683 {
5684 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5685 case ELFCLASS32: return "ELF32";
5686 case ELFCLASS64: return "ELF64";
ab5e7794 5687 default:
e9e44622 5688 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5689 return buff;
252b5132
RH
5690 }
5691}
5692
5693static const char *
d3ba0551 5694get_data_encoding (unsigned int encoding)
252b5132 5695{
b34976b6 5696 static char buff[32];
103f02d3 5697
252b5132
RH
5698 switch (encoding)
5699 {
5700 case ELFDATANONE: return _("none");
33c63f9d
CM
5701 case ELFDATA2LSB: return _("2's complement, little endian");
5702 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5703 default:
e9e44622 5704 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5705 return buff;
252b5132
RH
5706 }
5707}
5708
dda8d76d 5709/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5710
015dc7e1 5711static bool
dda8d76d 5712process_file_header (Filedata * filedata)
252b5132 5713{
dda8d76d
NC
5714 Elf_Internal_Ehdr * header = & filedata->file_header;
5715
5716 if ( header->e_ident[EI_MAG0] != ELFMAG0
5717 || header->e_ident[EI_MAG1] != ELFMAG1
5718 || header->e_ident[EI_MAG2] != ELFMAG2
5719 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5720 {
5721 error
5722 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5723 return false;
252b5132
RH
5724 }
5725
ca0e11aa
NC
5726 if (! filedata->is_separate)
5727 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5728
252b5132
RH
5729 if (do_header)
5730 {
32ec8896 5731 unsigned i;
252b5132 5732
ca0e11aa
NC
5733 if (filedata->is_separate)
5734 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5735 else
5736 printf (_("ELF Header:\n"));
252b5132 5737 printf (_(" Magic: "));
b34976b6 5738 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5739 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5740 printf ("\n");
5741 printf (_(" Class: %s\n"),
dda8d76d 5742 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5743 printf (_(" Data: %s\n"),
dda8d76d 5744 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5745 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5746 header->e_ident[EI_VERSION],
5747 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5748 ? _(" (current)")
dda8d76d 5749 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5750 ? _(" <unknown>")
789be9f7 5751 : "")));
252b5132 5752 printf (_(" OS/ABI: %s\n"),
dda8d76d 5753 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5754 printf (_(" ABI Version: %d\n"),
dda8d76d 5755 header->e_ident[EI_ABIVERSION]);
252b5132 5756 printf (_(" Type: %s\n"),
93df3340 5757 get_file_type (filedata));
252b5132 5758 printf (_(" Machine: %s\n"),
dda8d76d 5759 get_machine_name (header->e_machine));
252b5132 5760 printf (_(" Version: 0x%lx\n"),
e8a64888 5761 header->e_version);
76da6bbe 5762
f7a99963 5763 printf (_(" Entry point address: "));
e8a64888 5764 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5765 printf (_("\n Start of program headers: "));
e8a64888 5766 print_vma (header->e_phoff, DEC);
f7a99963 5767 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5768 print_vma (header->e_shoff, DEC);
f7a99963 5769 printf (_(" (bytes into file)\n"));
76da6bbe 5770
252b5132 5771 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5772 header->e_flags,
dda8d76d 5773 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5774 printf (_(" Size of this header: %u (bytes)\n"),
5775 header->e_ehsize);
5776 printf (_(" Size of program headers: %u (bytes)\n"),
5777 header->e_phentsize);
5778 printf (_(" Number of program headers: %u"),
5779 header->e_phnum);
dda8d76d
NC
5780 if (filedata->section_headers != NULL
5781 && header->e_phnum == PN_XNUM
5782 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5783 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5784 putc ('\n', stdout);
e8a64888
AM
5785 printf (_(" Size of section headers: %u (bytes)\n"),
5786 header->e_shentsize);
5787 printf (_(" Number of section headers: %u"),
5788 header->e_shnum);
dda8d76d 5789 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5790 {
5791 header->e_shnum = filedata->section_headers[0].sh_size;
5792 printf (" (%u)", header->e_shnum);
5793 }
560f3c1c 5794 putc ('\n', stdout);
e8a64888
AM
5795 printf (_(" Section header string table index: %u"),
5796 header->e_shstrndx);
dda8d76d
NC
5797 if (filedata->section_headers != NULL
5798 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5799 {
5800 header->e_shstrndx = filedata->section_headers[0].sh_link;
5801 printf (" (%u)", header->e_shstrndx);
5802 }
5803 if (header->e_shstrndx != SHN_UNDEF
5804 && header->e_shstrndx >= header->e_shnum)
5805 {
5806 header->e_shstrndx = SHN_UNDEF;
5807 printf (_(" <corrupt: out of range>"));
5808 }
560f3c1c
AM
5809 putc ('\n', stdout);
5810 }
5811
dda8d76d 5812 if (filedata->section_headers != NULL)
560f3c1c 5813 {
dda8d76d
NC
5814 if (header->e_phnum == PN_XNUM
5815 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5816 {
5817 /* Throw away any cached read of PN_XNUM headers. */
5818 free (filedata->program_headers);
5819 filedata->program_headers = NULL;
5820 header->e_phnum = filedata->section_headers[0].sh_info;
5821 }
dda8d76d
NC
5822 if (header->e_shnum == SHN_UNDEF)
5823 header->e_shnum = filedata->section_headers[0].sh_size;
5824 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5825 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5826 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5827 header->e_shstrndx = SHN_UNDEF;
252b5132 5828 }
103f02d3 5829
015dc7e1 5830 return true;
9ea033b2
NC
5831}
5832
dda8d76d
NC
5833/* Read in the program headers from FILEDATA and store them in PHEADERS.
5834 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5835
015dc7e1 5836static bool
dda8d76d 5837get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5838{
2cf0635d
NC
5839 Elf32_External_Phdr * phdrs;
5840 Elf32_External_Phdr * external;
5841 Elf_Internal_Phdr * internal;
b34976b6 5842 unsigned int i;
dda8d76d
NC
5843 unsigned int size = filedata->file_header.e_phentsize;
5844 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5845
5846 /* PR binutils/17531: Cope with unexpected section header sizes. */
5847 if (size == 0 || num == 0)
015dc7e1 5848 return false;
e0a31db1
NC
5849 if (size < sizeof * phdrs)
5850 {
5851 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5852 return false;
e0a31db1
NC
5853 }
5854 if (size > sizeof * phdrs)
5855 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5856
dda8d76d 5857 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5858 size, num, _("program headers"));
5859 if (phdrs == NULL)
015dc7e1 5860 return false;
9ea033b2 5861
91d6fa6a 5862 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5863 i < filedata->file_header.e_phnum;
b34976b6 5864 i++, internal++, external++)
252b5132 5865 {
9ea033b2
NC
5866 internal->p_type = BYTE_GET (external->p_type);
5867 internal->p_offset = BYTE_GET (external->p_offset);
5868 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5869 internal->p_paddr = BYTE_GET (external->p_paddr);
5870 internal->p_filesz = BYTE_GET (external->p_filesz);
5871 internal->p_memsz = BYTE_GET (external->p_memsz);
5872 internal->p_flags = BYTE_GET (external->p_flags);
5873 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5874 }
5875
9ea033b2 5876 free (phdrs);
015dc7e1 5877 return true;
252b5132
RH
5878}
5879
dda8d76d
NC
5880/* Read in the program headers from FILEDATA and store them in PHEADERS.
5881 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5882
015dc7e1 5883static bool
dda8d76d 5884get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5885{
2cf0635d
NC
5886 Elf64_External_Phdr * phdrs;
5887 Elf64_External_Phdr * external;
5888 Elf_Internal_Phdr * internal;
b34976b6 5889 unsigned int i;
dda8d76d
NC
5890 unsigned int size = filedata->file_header.e_phentsize;
5891 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5892
5893 /* PR binutils/17531: Cope with unexpected section header sizes. */
5894 if (size == 0 || num == 0)
015dc7e1 5895 return false;
e0a31db1
NC
5896 if (size < sizeof * phdrs)
5897 {
5898 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5899 return false;
e0a31db1
NC
5900 }
5901 if (size > sizeof * phdrs)
5902 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5903
dda8d76d 5904 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5905 size, num, _("program headers"));
a6e9f9df 5906 if (!phdrs)
015dc7e1 5907 return false;
9ea033b2 5908
91d6fa6a 5909 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5910 i < filedata->file_header.e_phnum;
b34976b6 5911 i++, internal++, external++)
9ea033b2
NC
5912 {
5913 internal->p_type = BYTE_GET (external->p_type);
5914 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5915 internal->p_offset = BYTE_GET (external->p_offset);
5916 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5917 internal->p_paddr = BYTE_GET (external->p_paddr);
5918 internal->p_filesz = BYTE_GET (external->p_filesz);
5919 internal->p_memsz = BYTE_GET (external->p_memsz);
5920 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5921 }
5922
5923 free (phdrs);
015dc7e1 5924 return true;
9ea033b2 5925}
252b5132 5926
32ec8896 5927/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5928
015dc7e1 5929static bool
dda8d76d 5930get_program_headers (Filedata * filedata)
d93f0186 5931{
2cf0635d 5932 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5933
5934 /* Check cache of prior read. */
dda8d76d 5935 if (filedata->program_headers != NULL)
015dc7e1 5936 return true;
d93f0186 5937
82156ab7
NC
5938 /* Be kind to memory checkers by looking for
5939 e_phnum values which we know must be invalid. */
dda8d76d 5940 if (filedata->file_header.e_phnum
82156ab7 5941 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5942 >= filedata->file_size)
82156ab7
NC
5943 {
5944 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5945 filedata->file_header.e_phnum);
015dc7e1 5946 return false;
82156ab7 5947 }
d93f0186 5948
dda8d76d 5949 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5950 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5951 if (phdrs == NULL)
5952 {
8b73c356 5953 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5954 filedata->file_header.e_phnum);
015dc7e1 5955 return false;
d93f0186
NC
5956 }
5957
5958 if (is_32bit_elf
dda8d76d
NC
5959 ? get_32bit_program_headers (filedata, phdrs)
5960 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5961 {
dda8d76d 5962 filedata->program_headers = phdrs;
015dc7e1 5963 return true;
d93f0186
NC
5964 }
5965
5966 free (phdrs);
015dc7e1 5967 return false;
d93f0186
NC
5968}
5969
93df3340 5970/* Print program header info and locate dynamic section. */
2f62977e 5971
93df3340 5972static void
dda8d76d 5973process_program_headers (Filedata * filedata)
252b5132 5974{
2cf0635d 5975 Elf_Internal_Phdr * segment;
b34976b6 5976 unsigned int i;
1a9ccd70 5977 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5978
dda8d76d 5979 if (filedata->file_header.e_phnum == 0)
252b5132 5980 {
82f2dbf7 5981 /* PR binutils/12467. */
dda8d76d 5982 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5983 warn (_("possibly corrupt ELF header - it has a non-zero program"
5984 " header offset, but no program headers\n"));
82f2dbf7 5985 else if (do_segments)
ca0e11aa
NC
5986 {
5987 if (filedata->is_separate)
5988 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5989 filedata->file_name);
5990 else
5991 printf (_("\nThere are no program headers in this file.\n"));
5992 }
93df3340 5993 goto no_headers;
252b5132
RH
5994 }
5995
5996 if (do_segments && !do_header)
5997 {
ca0e11aa
NC
5998 if (filedata->is_separate)
5999 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6000 filedata->file_name, get_file_type (filedata));
ca0e11aa 6001 else
93df3340 6002 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767
AM
6003 printf (_("Entry point 0x%" PRIx64 "\n"),
6004 (uint64_t) filedata->file_header.e_entry);
6005 printf (ngettext ("There is %d program header,"
6006 " starting at offset %" PRIu64 "\n",
6007 "There are %d program headers,"
6008 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6009 filedata->file_header.e_phnum),
6010 filedata->file_header.e_phnum,
b8281767 6011 (uint64_t) filedata->file_header.e_phoff);
252b5132
RH
6012 }
6013
dda8d76d 6014 if (! get_program_headers (filedata))
93df3340 6015 goto no_headers;
103f02d3 6016
252b5132
RH
6017 if (do_segments)
6018 {
dda8d76d 6019 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6020 printf (_("\nProgram Headers:\n"));
6021 else
6022 printf (_("\nProgram Headers:\n"));
76da6bbe 6023
f7a99963
NC
6024 if (is_32bit_elf)
6025 printf
6026 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6027 else if (do_wide)
6028 printf
6029 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6030 else
6031 {
6032 printf
6033 (_(" Type Offset VirtAddr PhysAddr\n"));
6034 printf
6035 (_(" FileSiz MemSiz Flags Align\n"));
6036 }
252b5132
RH
6037 }
6038
93df3340 6039 unsigned long dynamic_addr = 0;
be7d229a 6040 uint64_t dynamic_size = 0;
dda8d76d
NC
6041 for (i = 0, segment = filedata->program_headers;
6042 i < filedata->file_header.e_phnum;
b34976b6 6043 i++, segment++)
252b5132
RH
6044 {
6045 if (do_segments)
6046 {
dda8d76d 6047 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6048
6049 if (is_32bit_elf)
6050 {
6051 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6052 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6053 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6054 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6055 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6056 printf ("%c%c%c ",
6057 (segment->p_flags & PF_R ? 'R' : ' '),
6058 (segment->p_flags & PF_W ? 'W' : ' '),
6059 (segment->p_flags & PF_X ? 'E' : ' '));
6060 printf ("%#lx", (unsigned long) segment->p_align);
6061 }
d974e256
JJ
6062 else if (do_wide)
6063 {
6064 if ((unsigned long) segment->p_offset == segment->p_offset)
6065 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6066 else
6067 {
6068 print_vma (segment->p_offset, FULL_HEX);
6069 putchar (' ');
6070 }
6071
6072 print_vma (segment->p_vaddr, FULL_HEX);
6073 putchar (' ');
6074 print_vma (segment->p_paddr, FULL_HEX);
6075 putchar (' ');
6076
6077 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6078 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6079 else
6080 {
6081 print_vma (segment->p_filesz, FULL_HEX);
6082 putchar (' ');
6083 }
6084
6085 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6086 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6087 else
6088 {
f48e6c45 6089 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6090 }
6091
6092 printf (" %c%c%c ",
6093 (segment->p_flags & PF_R ? 'R' : ' '),
6094 (segment->p_flags & PF_W ? 'W' : ' '),
6095 (segment->p_flags & PF_X ? 'E' : ' '));
6096
6097 if ((unsigned long) segment->p_align == segment->p_align)
6098 printf ("%#lx", (unsigned long) segment->p_align);
6099 else
6100 {
6101 print_vma (segment->p_align, PREFIX_HEX);
6102 }
6103 }
f7a99963
NC
6104 else
6105 {
6106 print_vma (segment->p_offset, FULL_HEX);
6107 putchar (' ');
6108 print_vma (segment->p_vaddr, FULL_HEX);
6109 putchar (' ');
6110 print_vma (segment->p_paddr, FULL_HEX);
6111 printf ("\n ");
6112 print_vma (segment->p_filesz, FULL_HEX);
6113 putchar (' ');
6114 print_vma (segment->p_memsz, FULL_HEX);
6115 printf (" %c%c%c ",
6116 (segment->p_flags & PF_R ? 'R' : ' '),
6117 (segment->p_flags & PF_W ? 'W' : ' '),
6118 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6119 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6120 }
252b5132 6121
1a9ccd70
NC
6122 putc ('\n', stdout);
6123 }
f54498b4 6124
252b5132
RH
6125 switch (segment->p_type)
6126 {
1a9ccd70 6127 case PT_LOAD:
502d895c
NC
6128#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6129 required by the ELF standard, several programs, including the Linux
6130 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6131 if (previous_load
6132 && previous_load->p_vaddr > segment->p_vaddr)
6133 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6134#endif
1a9ccd70
NC
6135 if (segment->p_memsz < segment->p_filesz)
6136 error (_("the segment's file size is larger than its memory size\n"));
6137 previous_load = segment;
6138 break;
6139
6140 case PT_PHDR:
6141 /* PR 20815 - Verify that the program header is loaded into memory. */
6142 if (i > 0 && previous_load != NULL)
6143 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6144 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6145 {
6146 unsigned int j;
6147
dda8d76d 6148 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6149 {
6150 Elf_Internal_Phdr *load = filedata->program_headers + j;
6151 if (load->p_type == PT_LOAD
6152 && load->p_offset <= segment->p_offset
6153 && (load->p_offset + load->p_filesz
6154 >= segment->p_offset + segment->p_filesz)
6155 && load->p_vaddr <= segment->p_vaddr
6156 && (load->p_vaddr + load->p_filesz
6157 >= segment->p_vaddr + segment->p_filesz))
6158 break;
6159 }
dda8d76d 6160 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6161 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6162 }
6163 break;
6164
252b5132 6165 case PT_DYNAMIC:
93df3340 6166 if (dynamic_addr)
252b5132
RH
6167 error (_("more than one dynamic segment\n"));
6168
20737c13
AM
6169 /* By default, assume that the .dynamic section is the first
6170 section in the DYNAMIC segment. */
93df3340
AM
6171 dynamic_addr = segment->p_offset;
6172 dynamic_size = segment->p_filesz;
20737c13 6173
b2d38a17
NC
6174 /* Try to locate the .dynamic section. If there is
6175 a section header table, we can easily locate it. */
dda8d76d 6176 if (filedata->section_headers != NULL)
b2d38a17 6177 {
2cf0635d 6178 Elf_Internal_Shdr * sec;
b2d38a17 6179
dda8d76d 6180 sec = find_section (filedata, ".dynamic");
89fac5e3 6181 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6182 {
93df3340
AM
6183 /* A corresponding .dynamic section is expected, but on
6184 IA-64/OpenVMS it is OK for it to be missing. */
6185 if (!is_ia64_vms (filedata))
6186 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6187 break;
6188 }
6189
42bb2e33 6190 if (sec->sh_type == SHT_NOBITS)
20737c13 6191 {
93df3340
AM
6192 dynamic_addr = 0;
6193 dynamic_size = 0;
20737c13
AM
6194 break;
6195 }
42bb2e33 6196
93df3340
AM
6197 dynamic_addr = sec->sh_offset;
6198 dynamic_size = sec->sh_size;
b2d38a17 6199
8ac10c5b
L
6200 /* The PT_DYNAMIC segment, which is used by the run-time
6201 loader, should exactly match the .dynamic section. */
6202 if (do_checks
93df3340
AM
6203 && (dynamic_addr != segment->p_offset
6204 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6205 warn (_("\
6206the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6207 }
39e224f6
MW
6208
6209 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6210 segment. Check this after matching against the section headers
6211 so we don't warn on debuginfo file (which have NOBITS .dynamic
6212 sections). */
93df3340
AM
6213 if (dynamic_addr > filedata->file_size
6214 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6215 {
6216 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6217 dynamic_addr = 0;
6218 dynamic_size = 0;
39e224f6 6219 }
252b5132
RH
6220 break;
6221
6222 case PT_INTERP:
13acb58d
AM
6223 if (segment->p_offset >= filedata->file_size
6224 || segment->p_filesz > filedata->file_size - segment->p_offset
6225 || segment->p_filesz - 1 >= (size_t) -2
6226 || fseek (filedata->handle,
6227 filedata->archive_file_offset + (long) segment->p_offset,
6228 SEEK_SET))
252b5132
RH
6229 error (_("Unable to find program interpreter name\n"));
6230 else
6231 {
13acb58d
AM
6232 size_t len = segment->p_filesz;
6233 free (filedata->program_interpreter);
6234 filedata->program_interpreter = xmalloc (len + 1);
6235 len = fread (filedata->program_interpreter, 1, len,
6236 filedata->handle);
6237 filedata->program_interpreter[len] = 0;
252b5132
RH
6238
6239 if (do_segments)
f54498b4 6240 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6241 filedata->program_interpreter);
252b5132
RH
6242 }
6243 break;
6244 }
252b5132
RH
6245 }
6246
dda8d76d
NC
6247 if (do_segments
6248 && filedata->section_headers != NULL
6249 && filedata->string_table != NULL)
252b5132
RH
6250 {
6251 printf (_("\n Section to Segment mapping:\n"));
6252 printf (_(" Segment Sections...\n"));
6253
dda8d76d 6254 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6255 {
9ad5cbcf 6256 unsigned int j;
2cf0635d 6257 Elf_Internal_Shdr * section;
252b5132 6258
dda8d76d
NC
6259 segment = filedata->program_headers + i;
6260 section = filedata->section_headers + 1;
252b5132
RH
6261
6262 printf (" %2.2d ", i);
6263
dda8d76d 6264 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6265 {
f4638467
AM
6266 if (!ELF_TBSS_SPECIAL (section, segment)
6267 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6268 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6269 }
6270
6271 putc ('\n',stdout);
6272 }
6273 }
6274
93df3340
AM
6275 filedata->dynamic_addr = dynamic_addr;
6276 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6277 return;
6278
6279 no_headers:
6280 filedata->dynamic_addr = 0;
6281 filedata->dynamic_size = 1;
252b5132
RH
6282}
6283
6284
d93f0186
NC
6285/* Find the file offset corresponding to VMA by using the program headers. */
6286
6287static long
be7d229a 6288offset_from_vma (Filedata * filedata, bfd_vma vma, uint64_t size)
d93f0186 6289{
2cf0635d 6290 Elf_Internal_Phdr * seg;
d93f0186 6291
dda8d76d 6292 if (! get_program_headers (filedata))
d93f0186
NC
6293 {
6294 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6295 return (long) vma;
6296 }
6297
dda8d76d
NC
6298 for (seg = filedata->program_headers;
6299 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6300 ++seg)
6301 {
6302 if (seg->p_type != PT_LOAD)
6303 continue;
6304
6305 if (vma >= (seg->p_vaddr & -seg->p_align)
6306 && vma + size <= seg->p_vaddr + seg->p_filesz)
6307 return vma - seg->p_vaddr + seg->p_offset;
6308 }
6309
6310 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6311 (unsigned long) vma);
d93f0186
NC
6312 return (long) vma;
6313}
6314
6315
dda8d76d
NC
6316/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6317 If PROBE is true, this is just a probe and we do not generate any error
6318 messages if the load fails. */
049b0c3a 6319
015dc7e1
AM
6320static bool
6321get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6322{
2cf0635d
NC
6323 Elf32_External_Shdr * shdrs;
6324 Elf_Internal_Shdr * internal;
dda8d76d
NC
6325 unsigned int i;
6326 unsigned int size = filedata->file_header.e_shentsize;
6327 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6328
6329 /* PR binutils/17531: Cope with unexpected section header sizes. */
6330 if (size == 0 || num == 0)
015dc7e1 6331 return false;
049b0c3a
NC
6332 if (size < sizeof * shdrs)
6333 {
6334 if (! probe)
6335 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6336 return false;
049b0c3a
NC
6337 }
6338 if (!probe && size > sizeof * shdrs)
6339 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6340
dda8d76d 6341 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6342 size, num,
6343 probe ? NULL : _("section headers"));
6344 if (shdrs == NULL)
015dc7e1 6345 return false;
252b5132 6346
dda8d76d
NC
6347 filedata->section_headers = (Elf_Internal_Shdr *)
6348 cmalloc (num, sizeof (Elf_Internal_Shdr));
6349 if (filedata->section_headers == NULL)
252b5132 6350 {
049b0c3a 6351 if (!probe)
8b73c356 6352 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6353 free (shdrs);
015dc7e1 6354 return false;
252b5132
RH
6355 }
6356
dda8d76d 6357 for (i = 0, internal = filedata->section_headers;
560f3c1c 6358 i < num;
b34976b6 6359 i++, internal++)
252b5132
RH
6360 {
6361 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6362 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6363 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6364 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6365 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6366 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6367 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6368 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6369 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6370 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6371 if (!probe && internal->sh_link > num)
6372 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6373 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6374 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6375 }
6376
6377 free (shdrs);
015dc7e1 6378 return true;
252b5132
RH
6379}
6380
dda8d76d
NC
6381/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6382
015dc7e1
AM
6383static bool
6384get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6385{
dda8d76d
NC
6386 Elf64_External_Shdr * shdrs;
6387 Elf_Internal_Shdr * internal;
6388 unsigned int i;
6389 unsigned int size = filedata->file_header.e_shentsize;
6390 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6391
6392 /* PR binutils/17531: Cope with unexpected section header sizes. */
6393 if (size == 0 || num == 0)
015dc7e1 6394 return false;
dda8d76d 6395
049b0c3a
NC
6396 if (size < sizeof * shdrs)
6397 {
6398 if (! probe)
6399 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6400 return false;
049b0c3a 6401 }
dda8d76d 6402
049b0c3a
NC
6403 if (! probe && size > sizeof * shdrs)
6404 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6405
dda8d76d
NC
6406 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6407 filedata->file_header.e_shoff,
049b0c3a
NC
6408 size, num,
6409 probe ? NULL : _("section headers"));
6410 if (shdrs == NULL)
015dc7e1 6411 return false;
9ea033b2 6412
dda8d76d
NC
6413 filedata->section_headers = (Elf_Internal_Shdr *)
6414 cmalloc (num, sizeof (Elf_Internal_Shdr));
6415 if (filedata->section_headers == NULL)
9ea033b2 6416 {
049b0c3a 6417 if (! probe)
8b73c356 6418 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6419 free (shdrs);
015dc7e1 6420 return false;
9ea033b2
NC
6421 }
6422
dda8d76d 6423 for (i = 0, internal = filedata->section_headers;
560f3c1c 6424 i < num;
b34976b6 6425 i++, internal++)
9ea033b2
NC
6426 {
6427 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6428 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6429 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6430 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6431 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6432 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6433 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6434 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6435 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6436 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6437 if (!probe && internal->sh_link > num)
6438 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6439 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6440 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6441 }
6442
6443 free (shdrs);
015dc7e1 6444 return true;
9ea033b2
NC
6445}
6446
4de91c10
AM
6447static bool
6448get_section_headers (Filedata *filedata, bool probe)
6449{
6450 if (filedata->section_headers != NULL)
6451 return true;
6452
4de91c10
AM
6453 if (is_32bit_elf)
6454 return get_32bit_section_headers (filedata, probe);
6455 else
6456 return get_64bit_section_headers (filedata, probe);
6457}
6458
252b5132 6459static Elf_Internal_Sym *
dda8d76d
NC
6460get_32bit_elf_symbols (Filedata * filedata,
6461 Elf_Internal_Shdr * section,
6462 unsigned long * num_syms_return)
252b5132 6463{
ba5cdace 6464 unsigned long number = 0;
dd24e3da 6465 Elf32_External_Sym * esyms = NULL;
ba5cdace 6466 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6467 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6468 Elf_Internal_Sym * psym;
b34976b6 6469 unsigned int j;
e3d39609 6470 elf_section_list * entry;
252b5132 6471
c9c1d674
EG
6472 if (section->sh_size == 0)
6473 {
6474 if (num_syms_return != NULL)
6475 * num_syms_return = 0;
6476 return NULL;
6477 }
6478
dd24e3da 6479 /* Run some sanity checks first. */
c9c1d674 6480 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6481 {
c9c1d674 6482 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6483 printable_section_name (filedata, section),
6484 (unsigned long) section->sh_entsize);
ba5cdace 6485 goto exit_point;
dd24e3da
NC
6486 }
6487
dda8d76d 6488 if (section->sh_size > filedata->file_size)
f54498b4
NC
6489 {
6490 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6491 printable_section_name (filedata, section),
6492 (unsigned long) section->sh_size);
f54498b4
NC
6493 goto exit_point;
6494 }
6495
dd24e3da
NC
6496 number = section->sh_size / section->sh_entsize;
6497
6498 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6499 {
c9c1d674 6500 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6501 (unsigned long) section->sh_size,
dda8d76d 6502 printable_section_name (filedata, section),
8066deb1 6503 (unsigned long) section->sh_entsize);
ba5cdace 6504 goto exit_point;
dd24e3da
NC
6505 }
6506
dda8d76d 6507 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6508 section->sh_size, _("symbols"));
dd24e3da 6509 if (esyms == NULL)
ba5cdace 6510 goto exit_point;
252b5132 6511
e3d39609 6512 shndx = NULL;
978c4450 6513 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6514 {
6515 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6516 continue;
6517
6518 if (shndx != NULL)
6519 {
6520 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6521 free (shndx);
6522 }
6523
6524 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6525 entry->hdr->sh_offset,
6526 1, entry->hdr->sh_size,
6527 _("symbol table section indices"));
6528 if (shndx == NULL)
6529 goto exit_point;
6530
6531 /* PR17531: file: heap-buffer-overflow */
6532 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6533 {
6534 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6535 printable_section_name (filedata, entry->hdr),
6536 (unsigned long) entry->hdr->sh_size,
6537 (unsigned long) section->sh_size);
6538 goto exit_point;
c9c1d674 6539 }
e3d39609 6540 }
9ad5cbcf 6541
3f5e193b 6542 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6543
6544 if (isyms == NULL)
6545 {
8b73c356
NC
6546 error (_("Out of memory reading %lu symbols\n"),
6547 (unsigned long) number);
dd24e3da 6548 goto exit_point;
252b5132
RH
6549 }
6550
dd24e3da 6551 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6552 {
6553 psym->st_name = BYTE_GET (esyms[j].st_name);
6554 psym->st_value = BYTE_GET (esyms[j].st_value);
6555 psym->st_size = BYTE_GET (esyms[j].st_size);
6556 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6557 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6558 psym->st_shndx
6559 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6560 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6561 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6562 psym->st_info = BYTE_GET (esyms[j].st_info);
6563 psym->st_other = BYTE_GET (esyms[j].st_other);
6564 }
6565
dd24e3da 6566 exit_point:
e3d39609
NC
6567 free (shndx);
6568 free (esyms);
252b5132 6569
ba5cdace
NC
6570 if (num_syms_return != NULL)
6571 * num_syms_return = isyms == NULL ? 0 : number;
6572
252b5132
RH
6573 return isyms;
6574}
6575
9ea033b2 6576static Elf_Internal_Sym *
dda8d76d
NC
6577get_64bit_elf_symbols (Filedata * filedata,
6578 Elf_Internal_Shdr * section,
6579 unsigned long * num_syms_return)
9ea033b2 6580{
ba5cdace
NC
6581 unsigned long number = 0;
6582 Elf64_External_Sym * esyms = NULL;
6583 Elf_External_Sym_Shndx * shndx = NULL;
6584 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6585 Elf_Internal_Sym * psym;
b34976b6 6586 unsigned int j;
e3d39609 6587 elf_section_list * entry;
9ea033b2 6588
c9c1d674
EG
6589 if (section->sh_size == 0)
6590 {
6591 if (num_syms_return != NULL)
6592 * num_syms_return = 0;
6593 return NULL;
6594 }
6595
dd24e3da 6596 /* Run some sanity checks first. */
c9c1d674 6597 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6598 {
c9c1d674 6599 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6600 printable_section_name (filedata, section),
8066deb1 6601 (unsigned long) section->sh_entsize);
ba5cdace 6602 goto exit_point;
dd24e3da
NC
6603 }
6604
dda8d76d 6605 if (section->sh_size > filedata->file_size)
f54498b4
NC
6606 {
6607 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6608 printable_section_name (filedata, section),
8066deb1 6609 (unsigned long) section->sh_size);
f54498b4
NC
6610 goto exit_point;
6611 }
6612
dd24e3da
NC
6613 number = section->sh_size / section->sh_entsize;
6614
6615 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6616 {
c9c1d674 6617 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6618 (unsigned long) section->sh_size,
dda8d76d 6619 printable_section_name (filedata, section),
8066deb1 6620 (unsigned long) section->sh_entsize);
ba5cdace 6621 goto exit_point;
dd24e3da
NC
6622 }
6623
dda8d76d 6624 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6625 section->sh_size, _("symbols"));
a6e9f9df 6626 if (!esyms)
ba5cdace 6627 goto exit_point;
9ea033b2 6628
e3d39609 6629 shndx = NULL;
978c4450 6630 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6631 {
6632 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6633 continue;
6634
6635 if (shndx != NULL)
6636 {
6637 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6638 free (shndx);
c9c1d674 6639 }
e3d39609
NC
6640
6641 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6642 entry->hdr->sh_offset,
6643 1, entry->hdr->sh_size,
6644 _("symbol table section indices"));
6645 if (shndx == NULL)
6646 goto exit_point;
6647
6648 /* PR17531: file: heap-buffer-overflow */
6649 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6650 {
6651 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6652 printable_section_name (filedata, entry->hdr),
6653 (unsigned long) entry->hdr->sh_size,
6654 (unsigned long) section->sh_size);
6655 goto exit_point;
6656 }
6657 }
9ad5cbcf 6658
3f5e193b 6659 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6660
6661 if (isyms == NULL)
6662 {
8b73c356
NC
6663 error (_("Out of memory reading %lu symbols\n"),
6664 (unsigned long) number);
ba5cdace 6665 goto exit_point;
9ea033b2
NC
6666 }
6667
ba5cdace 6668 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6669 {
6670 psym->st_name = BYTE_GET (esyms[j].st_name);
6671 psym->st_info = BYTE_GET (esyms[j].st_info);
6672 psym->st_other = BYTE_GET (esyms[j].st_other);
6673 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6674
4fbb74a6 6675 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6676 psym->st_shndx
6677 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6678 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6679 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6680
66543521
AM
6681 psym->st_value = BYTE_GET (esyms[j].st_value);
6682 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6683 }
6684
ba5cdace 6685 exit_point:
e3d39609
NC
6686 free (shndx);
6687 free (esyms);
ba5cdace
NC
6688
6689 if (num_syms_return != NULL)
6690 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6691
6692 return isyms;
6693}
6694
4de91c10
AM
6695static Elf_Internal_Sym *
6696get_elf_symbols (Filedata *filedata,
6697 Elf_Internal_Shdr *section,
6698 unsigned long *num_syms_return)
6699{
6700 if (is_32bit_elf)
6701 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6702 else
6703 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6704}
6705
d1133906 6706static const char *
dda8d76d 6707get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6708{
5477e8a0 6709 static char buff[1024];
2cf0635d 6710 char * p = buff;
32ec8896
NC
6711 unsigned int field_size = is_32bit_elf ? 8 : 16;
6712 signed int sindex;
6713 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6714 bfd_vma os_flags = 0;
6715 bfd_vma proc_flags = 0;
6716 bfd_vma unknown_flags = 0;
148b93f2 6717 static const struct
5477e8a0 6718 {
2cf0635d 6719 const char * str;
32ec8896 6720 unsigned int len;
5477e8a0
L
6721 }
6722 flags [] =
6723 {
cfcac11d
NC
6724 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6725 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6726 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6727 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6728 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6729 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6730 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6731 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6732 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6733 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6734 /* IA-64 specific. */
6735 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6736 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6737 /* IA-64 OpenVMS specific. */
6738 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6739 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6740 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6741 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6742 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6743 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6744 /* Generic. */
cfcac11d 6745 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6746 /* SPARC specific. */
77115a4a 6747 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6748 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6749 /* ARM specific. */
6750 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6751 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6752 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6753 /* GNU specific. */
6754 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6755 /* VLE specific. */
6756 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6757 /* GNU specific. */
6758 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6759 };
6760
6761 if (do_section_details)
6762 {
8d5ff12c
L
6763 sprintf (buff, "[%*.*lx]: ",
6764 field_size, field_size, (unsigned long) sh_flags);
6765 p += field_size + 4;
5477e8a0 6766 }
76da6bbe 6767
d1133906
NC
6768 while (sh_flags)
6769 {
6770 bfd_vma flag;
6771
6772 flag = sh_flags & - sh_flags;
6773 sh_flags &= ~ flag;
76da6bbe 6774
5477e8a0 6775 if (do_section_details)
d1133906 6776 {
5477e8a0
L
6777 switch (flag)
6778 {
91d6fa6a
NC
6779 case SHF_WRITE: sindex = 0; break;
6780 case SHF_ALLOC: sindex = 1; break;
6781 case SHF_EXECINSTR: sindex = 2; break;
6782 case SHF_MERGE: sindex = 3; break;
6783 case SHF_STRINGS: sindex = 4; break;
6784 case SHF_INFO_LINK: sindex = 5; break;
6785 case SHF_LINK_ORDER: sindex = 6; break;
6786 case SHF_OS_NONCONFORMING: sindex = 7; break;
6787 case SHF_GROUP: sindex = 8; break;
6788 case SHF_TLS: sindex = 9; break;
18ae9cc1 6789 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6790 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6791
5477e8a0 6792 default:
91d6fa6a 6793 sindex = -1;
dda8d76d 6794 switch (filedata->file_header.e_machine)
148b93f2 6795 {
cfcac11d 6796 case EM_IA_64:
148b93f2 6797 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6798 sindex = 10;
148b93f2 6799 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6800 sindex = 11;
148b93f2 6801#ifdef BFD64
dda8d76d 6802 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6803 switch (flag)
6804 {
91d6fa6a
NC
6805 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6806 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6807 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6808 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6809 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6810 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6811 default: break;
6812 }
6813#endif
cfcac11d
NC
6814 break;
6815
caa83f8b 6816 case EM_386:
22abe556 6817 case EM_IAMCU:
caa83f8b 6818 case EM_X86_64:
7f502d6c 6819 case EM_L1OM:
7a9068fe 6820 case EM_K1OM:
cfcac11d
NC
6821 case EM_OLD_SPARCV9:
6822 case EM_SPARC32PLUS:
6823 case EM_SPARCV9:
6824 case EM_SPARC:
18ae9cc1 6825 if (flag == SHF_ORDERED)
91d6fa6a 6826 sindex = 19;
cfcac11d 6827 break;
ac4c9b04
MG
6828
6829 case EM_ARM:
6830 switch (flag)
6831 {
6832 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6833 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6834 case SHF_COMDEF: sindex = 23; break;
6835 default: break;
6836 }
6837 break;
83eef883
AFB
6838 case EM_PPC:
6839 if (flag == SHF_PPC_VLE)
6840 sindex = 25;
6841 break;
99fabbc9
JL
6842 default:
6843 break;
6844 }
ac4c9b04 6845
99fabbc9
JL
6846 switch (filedata->file_header.e_ident[EI_OSABI])
6847 {
6848 case ELFOSABI_GNU:
6849 case ELFOSABI_FREEBSD:
6850 if (flag == SHF_GNU_RETAIN)
6851 sindex = 26;
6852 /* Fall through */
6853 case ELFOSABI_NONE:
6854 if (flag == SHF_GNU_MBIND)
6855 /* We should not recognize SHF_GNU_MBIND for
6856 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6857 not set the EI_OSABI header byte. */
6858 sindex = 24;
6859 break;
cfcac11d
NC
6860 default:
6861 break;
148b93f2 6862 }
99fabbc9 6863 break;
5477e8a0
L
6864 }
6865
91d6fa6a 6866 if (sindex != -1)
5477e8a0 6867 {
8d5ff12c
L
6868 if (p != buff + field_size + 4)
6869 {
6870 if (size < (10 + 2))
bee0ee85
NC
6871 {
6872 warn (_("Internal error: not enough buffer room for section flag info"));
6873 return _("<unknown>");
6874 }
8d5ff12c
L
6875 size -= 2;
6876 *p++ = ',';
6877 *p++ = ' ';
6878 }
6879
91d6fa6a
NC
6880 size -= flags [sindex].len;
6881 p = stpcpy (p, flags [sindex].str);
5477e8a0 6882 }
3b22753a 6883 else if (flag & SHF_MASKOS)
8d5ff12c 6884 os_flags |= flag;
d1133906 6885 else if (flag & SHF_MASKPROC)
8d5ff12c 6886 proc_flags |= flag;
d1133906 6887 else
8d5ff12c 6888 unknown_flags |= flag;
5477e8a0
L
6889 }
6890 else
6891 {
6892 switch (flag)
6893 {
6894 case SHF_WRITE: *p = 'W'; break;
6895 case SHF_ALLOC: *p = 'A'; break;
6896 case SHF_EXECINSTR: *p = 'X'; break;
6897 case SHF_MERGE: *p = 'M'; break;
6898 case SHF_STRINGS: *p = 'S'; break;
6899 case SHF_INFO_LINK: *p = 'I'; break;
6900 case SHF_LINK_ORDER: *p = 'L'; break;
6901 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6902 case SHF_GROUP: *p = 'G'; break;
6903 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6904 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6905 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6906
6907 default:
dda8d76d
NC
6908 if ((filedata->file_header.e_machine == EM_X86_64
6909 || filedata->file_header.e_machine == EM_L1OM
6910 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6911 && flag == SHF_X86_64_LARGE)
6912 *p = 'l';
dda8d76d 6913 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6914 && flag == SHF_ARM_PURECODE)
99fabbc9 6915 *p = 'y';
dda8d76d 6916 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6917 && flag == SHF_PPC_VLE)
99fabbc9 6918 *p = 'v';
5477e8a0
L
6919 else if (flag & SHF_MASKOS)
6920 {
99fabbc9
JL
6921 switch (filedata->file_header.e_ident[EI_OSABI])
6922 {
6923 case ELFOSABI_GNU:
6924 case ELFOSABI_FREEBSD:
6925 if (flag == SHF_GNU_RETAIN)
6926 {
6927 *p = 'R';
6928 break;
6929 }
6930 /* Fall through */
6931 case ELFOSABI_NONE:
6932 if (flag == SHF_GNU_MBIND)
6933 {
6934 /* We should not recognize SHF_GNU_MBIND for
6935 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6936 not set the EI_OSABI header byte. */
6937 *p = 'D';
6938 break;
6939 }
6940 /* Fall through */
6941 default:
6942 *p = 'o';
6943 sh_flags &= ~SHF_MASKOS;
6944 break;
6945 }
5477e8a0
L
6946 }
6947 else if (flag & SHF_MASKPROC)
6948 {
6949 *p = 'p';
6950 sh_flags &= ~ SHF_MASKPROC;
6951 }
6952 else
6953 *p = 'x';
6954 break;
6955 }
6956 p++;
d1133906
NC
6957 }
6958 }
76da6bbe 6959
8d5ff12c
L
6960 if (do_section_details)
6961 {
6962 if (os_flags)
6963 {
6964 size -= 5 + field_size;
6965 if (p != buff + field_size + 4)
6966 {
6967 if (size < (2 + 1))
bee0ee85
NC
6968 {
6969 warn (_("Internal error: not enough buffer room for section flag info"));
6970 return _("<unknown>");
6971 }
8d5ff12c
L
6972 size -= 2;
6973 *p++ = ',';
6974 *p++ = ' ';
6975 }
6976 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6977 (unsigned long) os_flags);
6978 p += 5 + field_size;
6979 }
6980 if (proc_flags)
6981 {
6982 size -= 7 + field_size;
6983 if (p != buff + field_size + 4)
6984 {
6985 if (size < (2 + 1))
bee0ee85
NC
6986 {
6987 warn (_("Internal error: not enough buffer room for section flag info"));
6988 return _("<unknown>");
6989 }
8d5ff12c
L
6990 size -= 2;
6991 *p++ = ',';
6992 *p++ = ' ';
6993 }
6994 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6995 (unsigned long) proc_flags);
6996 p += 7 + field_size;
6997 }
6998 if (unknown_flags)
6999 {
7000 size -= 10 + field_size;
7001 if (p != buff + field_size + 4)
7002 {
7003 if (size < (2 + 1))
bee0ee85
NC
7004 {
7005 warn (_("Internal error: not enough buffer room for section flag info"));
7006 return _("<unknown>");
7007 }
8d5ff12c
L
7008 size -= 2;
7009 *p++ = ',';
7010 *p++ = ' ';
7011 }
2b692964 7012 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7013 (unsigned long) unknown_flags);
7014 p += 10 + field_size;
7015 }
7016 }
7017
e9e44622 7018 *p = '\0';
d1133906
NC
7019 return buff;
7020}
7021
5844b465 7022static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7023get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7024 uint64_t size)
77115a4a
L
7025{
7026 if (is_32bit_elf)
7027 {
7028 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7029
ebdf1ebf
NC
7030 if (size < sizeof (* echdr))
7031 {
7032 error (_("Compressed section is too small even for a compression header\n"));
7033 return 0;
7034 }
7035
77115a4a
L
7036 chdr->ch_type = BYTE_GET (echdr->ch_type);
7037 chdr->ch_size = BYTE_GET (echdr->ch_size);
7038 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7039 return sizeof (*echdr);
7040 }
7041 else
7042 {
7043 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7044
ebdf1ebf
NC
7045 if (size < sizeof (* echdr))
7046 {
7047 error (_("Compressed section is too small even for a compression header\n"));
7048 return 0;
7049 }
7050
77115a4a
L
7051 chdr->ch_type = BYTE_GET (echdr->ch_type);
7052 chdr->ch_size = BYTE_GET (echdr->ch_size);
7053 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7054 return sizeof (*echdr);
7055 }
7056}
7057
015dc7e1 7058static bool
dda8d76d 7059process_section_headers (Filedata * filedata)
252b5132 7060{
2cf0635d 7061 Elf_Internal_Shdr * section;
b34976b6 7062 unsigned int i;
252b5132 7063
dda8d76d 7064 if (filedata->file_header.e_shnum == 0)
252b5132 7065 {
82f2dbf7 7066 /* PR binutils/12467. */
dda8d76d 7067 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7068 {
7069 warn (_("possibly corrupt ELF file header - it has a non-zero"
7070 " section header offset, but no section headers\n"));
015dc7e1 7071 return false;
32ec8896 7072 }
82f2dbf7 7073 else if (do_sections)
252b5132
RH
7074 printf (_("\nThere are no sections in this file.\n"));
7075
015dc7e1 7076 return true;
252b5132
RH
7077 }
7078
7079 if (do_sections && !do_header)
ca0e11aa
NC
7080 {
7081 if (filedata->is_separate && process_links)
7082 printf (_("In linked file '%s': "), filedata->file_name);
7083 if (! filedata->is_separate || process_links)
7084 printf (ngettext ("There is %d section header, "
7085 "starting at offset 0x%lx:\n",
7086 "There are %d section headers, "
7087 "starting at offset 0x%lx:\n",
7088 filedata->file_header.e_shnum),
7089 filedata->file_header.e_shnum,
7090 (unsigned long) filedata->file_header.e_shoff);
7091 }
252b5132 7092
4de91c10
AM
7093 if (!get_section_headers (filedata, false))
7094 return false;
252b5132
RH
7095
7096 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7097 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7098 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7099 {
dda8d76d 7100 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7101
c256ffe7
JJ
7102 if (section->sh_size != 0)
7103 {
dda8d76d
NC
7104 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7105 1, section->sh_size,
7106 _("string table"));
0de14b54 7107
dda8d76d 7108 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7109 }
252b5132
RH
7110 }
7111
7112 /* Scan the sections for the dynamic symbol table
e3c8793a 7113 and dynamic string table and debug sections. */
89fac5e3 7114 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7115 switch (filedata->file_header.e_machine)
89fac5e3
RS
7116 {
7117 case EM_MIPS:
7118 case EM_MIPS_RS3_LE:
7119 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7120 FDE addresses. However, the ABI also has a semi-official ILP32
7121 variant for which the normal FDE address size rules apply.
7122
7123 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7124 section, where XX is the size of longs in bits. Unfortunately,
7125 earlier compilers provided no way of distinguishing ILP32 objects
7126 from LP64 objects, so if there's any doubt, we should assume that
7127 the official LP64 form is being used. */
dda8d76d
NC
7128 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7129 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7130 eh_addr_size = 8;
7131 break;
0f56a26a
DD
7132
7133 case EM_H8_300:
7134 case EM_H8_300H:
dda8d76d 7135 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7136 {
7137 case E_H8_MACH_H8300:
7138 case E_H8_MACH_H8300HN:
7139 case E_H8_MACH_H8300SN:
7140 case E_H8_MACH_H8300SXN:
7141 eh_addr_size = 2;
7142 break;
7143 case E_H8_MACH_H8300H:
7144 case E_H8_MACH_H8300S:
7145 case E_H8_MACH_H8300SX:
7146 eh_addr_size = 4;
7147 break;
7148 }
f4236fe4
DD
7149 break;
7150
ff7eeb89 7151 case EM_M32C_OLD:
f4236fe4 7152 case EM_M32C:
dda8d76d 7153 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7154 {
7155 case EF_M32C_CPU_M16C:
7156 eh_addr_size = 2;
7157 break;
7158 }
7159 break;
89fac5e3
RS
7160 }
7161
76ca31c0
NC
7162#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7163 do \
7164 { \
be7d229a 7165 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7166 if (section->sh_entsize != expected_entsize) \
9dd3a467 7167 { \
f493c217
AM
7168 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
7169 i, (uint64_t) section->sh_entsize); \
7170 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7171 expected_entsize); \
9dd3a467 7172 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7173 } \
7174 } \
08d8fa11 7175 while (0)
9dd3a467
NC
7176
7177#define CHECK_ENTSIZE(section, i, type) \
1b513401 7178 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7179 sizeof (Elf64_External_##type))
7180
dda8d76d
NC
7181 for (i = 0, section = filedata->section_headers;
7182 i < filedata->file_header.e_shnum;
b34976b6 7183 i++, section++)
252b5132 7184 {
84714f86 7185 const char *name = section_name_print (filedata, section);
252b5132 7186
1b513401
NC
7187 /* Run some sanity checks on the headers and
7188 possibly fill in some file data as well. */
7189 switch (section->sh_type)
252b5132 7190 {
1b513401 7191 case SHT_DYNSYM:
978c4450 7192 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7193 {
7194 error (_("File contains multiple dynamic symbol tables\n"));
7195 continue;
7196 }
7197
08d8fa11 7198 CHECK_ENTSIZE (section, i, Sym);
978c4450 7199 filedata->dynamic_symbols
4de91c10 7200 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7201 filedata->dynamic_symtab_section = section;
1b513401
NC
7202 break;
7203
7204 case SHT_STRTAB:
7205 if (streq (name, ".dynstr"))
252b5132 7206 {
1b513401
NC
7207 if (filedata->dynamic_strings != NULL)
7208 {
7209 error (_("File contains multiple dynamic string tables\n"));
7210 continue;
7211 }
7212
7213 filedata->dynamic_strings
7214 = (char *) get_data (NULL, filedata, section->sh_offset,
7215 1, section->sh_size, _("dynamic strings"));
7216 filedata->dynamic_strings_length
7217 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7218 filedata->dynamic_strtab_section = section;
252b5132 7219 }
1b513401
NC
7220 break;
7221
7222 case SHT_SYMTAB_SHNDX:
7223 {
7224 elf_section_list * entry = xmalloc (sizeof * entry);
7225
7226 entry->hdr = section;
7227 entry->next = filedata->symtab_shndx_list;
7228 filedata->symtab_shndx_list = entry;
7229 }
7230 break;
7231
7232 case SHT_SYMTAB:
7233 CHECK_ENTSIZE (section, i, Sym);
7234 break;
7235
7236 case SHT_GROUP:
7237 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7238 break;
252b5132 7239
1b513401
NC
7240 case SHT_REL:
7241 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7242 if (do_checks && section->sh_size == 0)
1b513401
NC
7243 warn (_("Section '%s': zero-sized relocation section\n"), name);
7244 break;
7245
7246 case SHT_RELA:
7247 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7248 if (do_checks && section->sh_size == 0)
1b513401
NC
7249 warn (_("Section '%s': zero-sized relocation section\n"), name);
7250 break;
7251
682351b9
AM
7252 case SHT_RELR:
7253 CHECK_ENTSIZE (section, i, Relr);
7254 break;
7255
1b513401
NC
7256 case SHT_NOTE:
7257 case SHT_PROGBITS:
546cb2d8
NC
7258 /* Having a zero sized section is not illegal according to the
7259 ELF standard, but it might be an indication that something
7260 is wrong. So issue a warning if we are running in lint mode. */
7261 if (do_checks && section->sh_size == 0)
1b513401
NC
7262 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7263 break;
7264
7265 default:
7266 break;
7267 }
7268
7269 if ((do_debugging || do_debug_info || do_debug_abbrevs
7270 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7271 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7272 || do_debug_str || do_debug_str_offsets || do_debug_loc
7273 || do_debug_ranges
1b513401 7274 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7275 && (startswith (name, ".debug_")
7276 || startswith (name, ".zdebug_")))
252b5132 7277 {
1b315056
CS
7278 if (name[1] == 'z')
7279 name += sizeof (".zdebug_") - 1;
7280 else
7281 name += sizeof (".debug_") - 1;
252b5132
RH
7282
7283 if (do_debugging
24d127aa
ML
7284 || (do_debug_info && startswith (name, "info"))
7285 || (do_debug_info && startswith (name, "types"))
7286 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7287 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7288 || (do_debug_lines && startswith (name, "line."))
7289 || (do_debug_pubnames && startswith (name, "pubnames"))
7290 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7291 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7292 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7293 || (do_debug_aranges && startswith (name, "aranges"))
7294 || (do_debug_ranges && startswith (name, "ranges"))
7295 || (do_debug_ranges && startswith (name, "rnglists"))
7296 || (do_debug_frames && startswith (name, "frame"))
7297 || (do_debug_macinfo && startswith (name, "macinfo"))
7298 || (do_debug_macinfo && startswith (name, "macro"))
7299 || (do_debug_str && startswith (name, "str"))
7300 || (do_debug_links && startswith (name, "sup"))
7301 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7302 || (do_debug_loc && startswith (name, "loc"))
7303 || (do_debug_loc && startswith (name, "loclists"))
7304 || (do_debug_addr && startswith (name, "addr"))
7305 || (do_debug_cu_index && startswith (name, "cu_index"))
7306 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7307 )
6431e409 7308 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7309 }
a262ae96 7310 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7311 else if ((do_debugging || do_debug_info)
24d127aa 7312 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7313 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7314 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7315 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7316 else if (do_gdb_index && (streq (name, ".gdb_index")
7317 || streq (name, ".debug_names")))
6431e409 7318 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7319 /* Trace sections for Itanium VMS. */
7320 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7321 || do_trace_aranges)
24d127aa 7322 && startswith (name, ".trace_"))
6f875884
TG
7323 {
7324 name += sizeof (".trace_") - 1;
7325
7326 if (do_debugging
7327 || (do_trace_info && streq (name, "info"))
7328 || (do_trace_abbrevs && streq (name, "abbrev"))
7329 || (do_trace_aranges && streq (name, "aranges"))
7330 )
6431e409 7331 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7332 }
dda8d76d 7333 else if ((do_debugging || do_debug_links)
24d127aa
ML
7334 && (startswith (name, ".gnu_debuglink")
7335 || startswith (name, ".gnu_debugaltlink")))
6431e409 7336 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7337 }
7338
7339 if (! do_sections)
015dc7e1 7340 return true;
252b5132 7341
ca0e11aa 7342 if (filedata->is_separate && ! process_links)
015dc7e1 7343 return true;
ca0e11aa
NC
7344
7345 if (filedata->is_separate)
7346 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7347 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7348 printf (_("\nSection Headers:\n"));
7349 else
7350 printf (_("\nSection Header:\n"));
76da6bbe 7351
f7a99963 7352 if (is_32bit_elf)
595cf52e 7353 {
5477e8a0 7354 if (do_section_details)
595cf52e
L
7355 {
7356 printf (_(" [Nr] Name\n"));
5477e8a0 7357 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7358 }
7359 else
7360 printf
7361 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7362 }
d974e256 7363 else if (do_wide)
595cf52e 7364 {
5477e8a0 7365 if (do_section_details)
595cf52e
L
7366 {
7367 printf (_(" [Nr] Name\n"));
5477e8a0 7368 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7369 }
7370 else
7371 printf
7372 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7373 }
f7a99963
NC
7374 else
7375 {
5477e8a0 7376 if (do_section_details)
595cf52e
L
7377 {
7378 printf (_(" [Nr] Name\n"));
5477e8a0
L
7379 printf (_(" Type Address Offset Link\n"));
7380 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7381 }
7382 else
7383 {
7384 printf (_(" [Nr] Name Type Address Offset\n"));
7385 printf (_(" Size EntSize Flags Link Info Align\n"));
7386 }
f7a99963 7387 }
252b5132 7388
5477e8a0
L
7389 if (do_section_details)
7390 printf (_(" Flags\n"));
7391
dda8d76d
NC
7392 for (i = 0, section = filedata->section_headers;
7393 i < filedata->file_header.e_shnum;
b34976b6 7394 i++, section++)
252b5132 7395 {
dd905818
NC
7396 /* Run some sanity checks on the section header. */
7397
7398 /* Check the sh_link field. */
7399 switch (section->sh_type)
7400 {
285e3f99
AM
7401 case SHT_REL:
7402 case SHT_RELA:
7403 if (section->sh_link == 0
7404 && (filedata->file_header.e_type == ET_EXEC
7405 || filedata->file_header.e_type == ET_DYN))
7406 /* A dynamic relocation section where all entries use a
7407 zero symbol index need not specify a symtab section. */
7408 break;
7409 /* Fall through. */
dd905818
NC
7410 case SHT_SYMTAB_SHNDX:
7411 case SHT_GROUP:
7412 case SHT_HASH:
7413 case SHT_GNU_HASH:
7414 case SHT_GNU_versym:
285e3f99 7415 if (section->sh_link == 0
dda8d76d
NC
7416 || section->sh_link >= filedata->file_header.e_shnum
7417 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7418 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7419 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7420 i, section->sh_link);
7421 break;
7422
7423 case SHT_DYNAMIC:
7424 case SHT_SYMTAB:
7425 case SHT_DYNSYM:
7426 case SHT_GNU_verneed:
7427 case SHT_GNU_verdef:
7428 case SHT_GNU_LIBLIST:
285e3f99 7429 if (section->sh_link == 0
dda8d76d
NC
7430 || section->sh_link >= filedata->file_header.e_shnum
7431 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7432 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7433 i, section->sh_link);
7434 break;
7435
7436 case SHT_INIT_ARRAY:
7437 case SHT_FINI_ARRAY:
7438 case SHT_PREINIT_ARRAY:
7439 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7440 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7441 i, section->sh_link);
7442 break;
7443
7444 default:
7445 /* FIXME: Add support for target specific section types. */
7446#if 0 /* Currently we do not check other section types as there are too
7447 many special cases. Stab sections for example have a type
7448 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7449 section. */
7450 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7451 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7452 i, section->sh_link);
7453#endif
7454 break;
7455 }
7456
7457 /* Check the sh_info field. */
7458 switch (section->sh_type)
7459 {
7460 case SHT_REL:
7461 case SHT_RELA:
285e3f99
AM
7462 if (section->sh_info == 0
7463 && (filedata->file_header.e_type == ET_EXEC
7464 || filedata->file_header.e_type == ET_DYN))
7465 /* Dynamic relocations apply to segments, so they do not
7466 need to specify the section they relocate. */
7467 break;
7468 if (section->sh_info == 0
dda8d76d
NC
7469 || section->sh_info >= filedata->file_header.e_shnum
7470 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7471 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7472 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7473 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7474 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7475 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7476 /* FIXME: Are other section types valid ? */
dda8d76d 7477 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7478 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7479 i, section->sh_info);
dd905818
NC
7480 break;
7481
7482 case SHT_DYNAMIC:
7483 case SHT_HASH:
7484 case SHT_SYMTAB_SHNDX:
7485 case SHT_INIT_ARRAY:
7486 case SHT_FINI_ARRAY:
7487 case SHT_PREINIT_ARRAY:
7488 if (section->sh_info != 0)
7489 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7490 i, section->sh_info);
7491 break;
7492
7493 case SHT_GROUP:
7494 case SHT_SYMTAB:
7495 case SHT_DYNSYM:
7496 /* A symbol index - we assume that it is valid. */
7497 break;
7498
7499 default:
7500 /* FIXME: Add support for target specific section types. */
7501 if (section->sh_type == SHT_NOBITS)
7502 /* NOBITS section headers with non-zero sh_info fields can be
7503 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7504 information. The stripped sections have their headers
7505 preserved but their types set to SHT_NOBITS. So do not check
7506 this type of section. */
dd905818
NC
7507 ;
7508 else if (section->sh_flags & SHF_INFO_LINK)
7509 {
dda8d76d 7510 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7511 warn (_("[%2u]: Expected link to another section in info field"), i);
7512 }
a91e1603
L
7513 else if (section->sh_type < SHT_LOOS
7514 && (section->sh_flags & SHF_GNU_MBIND) == 0
7515 && section->sh_info != 0)
dd905818
NC
7516 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7517 i, section->sh_info);
7518 break;
7519 }
7520
3e6b6445 7521 /* Check the sh_size field. */
dda8d76d 7522 if (section->sh_size > filedata->file_size
3e6b6445
NC
7523 && section->sh_type != SHT_NOBITS
7524 && section->sh_type != SHT_NULL
7525 && section->sh_type < SHT_LOOS)
7526 warn (_("Size of section %u is larger than the entire file!\n"), i);
7527
7bfd842d 7528 printf (" [%2u] ", i);
5477e8a0 7529 if (do_section_details)
dda8d76d 7530 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7531 else
84714f86 7532 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7533
ea52a088 7534 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7535 get_section_type_name (filedata, section->sh_type));
0b4362b0 7536
f7a99963
NC
7537 if (is_32bit_elf)
7538 {
cfcac11d
NC
7539 const char * link_too_big = NULL;
7540
f7a99963 7541 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7542
f7a99963
NC
7543 printf ( " %6.6lx %6.6lx %2.2lx",
7544 (unsigned long) section->sh_offset,
7545 (unsigned long) section->sh_size,
7546 (unsigned long) section->sh_entsize);
d1133906 7547
5477e8a0
L
7548 if (do_section_details)
7549 fputs (" ", stdout);
7550 else
dda8d76d 7551 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7552
dda8d76d 7553 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7554 {
7555 link_too_big = "";
7556 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7557 an error but it can have special values in Solaris binaries. */
dda8d76d 7558 switch (filedata->file_header.e_machine)
cfcac11d 7559 {
caa83f8b 7560 case EM_386:
22abe556 7561 case EM_IAMCU:
caa83f8b 7562 case EM_X86_64:
7f502d6c 7563 case EM_L1OM:
7a9068fe 7564 case EM_K1OM:
cfcac11d
NC
7565 case EM_OLD_SPARCV9:
7566 case EM_SPARC32PLUS:
7567 case EM_SPARCV9:
7568 case EM_SPARC:
7569 if (section->sh_link == (SHN_BEFORE & 0xffff))
7570 link_too_big = "BEFORE";
7571 else if (section->sh_link == (SHN_AFTER & 0xffff))
7572 link_too_big = "AFTER";
7573 break;
7574 default:
7575 break;
7576 }
7577 }
7578
7579 if (do_section_details)
7580 {
7581 if (link_too_big != NULL && * link_too_big)
7582 printf ("<%s> ", link_too_big);
7583 else
7584 printf ("%2u ", section->sh_link);
7585 printf ("%3u %2lu\n", section->sh_info,
7586 (unsigned long) section->sh_addralign);
7587 }
7588 else
7589 printf ("%2u %3u %2lu\n",
7590 section->sh_link,
7591 section->sh_info,
7592 (unsigned long) section->sh_addralign);
7593
7594 if (link_too_big && ! * link_too_big)
7595 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7596 i, section->sh_link);
f7a99963 7597 }
d974e256
JJ
7598 else if (do_wide)
7599 {
7600 print_vma (section->sh_addr, LONG_HEX);
7601
7602 if ((long) section->sh_offset == section->sh_offset)
7603 printf (" %6.6lx", (unsigned long) section->sh_offset);
7604 else
7605 {
7606 putchar (' ');
7607 print_vma (section->sh_offset, LONG_HEX);
7608 }
7609
7610 if ((unsigned long) section->sh_size == section->sh_size)
7611 printf (" %6.6lx", (unsigned long) section->sh_size);
7612 else
7613 {
7614 putchar (' ');
7615 print_vma (section->sh_size, LONG_HEX);
7616 }
7617
7618 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7619 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7620 else
7621 {
7622 putchar (' ');
7623 print_vma (section->sh_entsize, LONG_HEX);
7624 }
7625
5477e8a0
L
7626 if (do_section_details)
7627 fputs (" ", stdout);
7628 else
dda8d76d 7629 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7630
72de5009 7631 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7632
7633 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7634 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7635 else
7636 {
7637 print_vma (section->sh_addralign, DEC);
7638 putchar ('\n');
7639 }
7640 }
5477e8a0 7641 else if (do_section_details)
595cf52e 7642 {
55cc53e9 7643 putchar (' ');
595cf52e
L
7644 print_vma (section->sh_addr, LONG_HEX);
7645 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7646 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7647 else
7648 {
7649 printf (" ");
7650 print_vma (section->sh_offset, LONG_HEX);
7651 }
72de5009 7652 printf (" %u\n ", section->sh_link);
595cf52e 7653 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7654 putchar (' ');
595cf52e
L
7655 print_vma (section->sh_entsize, LONG_HEX);
7656
72de5009
AM
7657 printf (" %-16u %lu\n",
7658 section->sh_info,
595cf52e
L
7659 (unsigned long) section->sh_addralign);
7660 }
f7a99963
NC
7661 else
7662 {
7663 putchar (' ');
7664 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7665 if ((long) section->sh_offset == section->sh_offset)
7666 printf (" %8.8lx", (unsigned long) section->sh_offset);
7667 else
7668 {
7669 printf (" ");
7670 print_vma (section->sh_offset, LONG_HEX);
7671 }
f7a99963
NC
7672 printf ("\n ");
7673 print_vma (section->sh_size, LONG_HEX);
7674 printf (" ");
7675 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7676
dda8d76d 7677 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7678
72de5009
AM
7679 printf (" %2u %3u %lu\n",
7680 section->sh_link,
7681 section->sh_info,
f7a99963
NC
7682 (unsigned long) section->sh_addralign);
7683 }
5477e8a0
L
7684
7685 if (do_section_details)
77115a4a 7686 {
dda8d76d 7687 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7688 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7689 {
7690 /* Minimum section size is 12 bytes for 32-bit compression
7691 header + 12 bytes for compressed data header. */
7692 unsigned char buf[24];
d8024a91 7693
77115a4a 7694 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7695 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7696 sizeof (buf), _("compression header")))
7697 {
7698 Elf_Internal_Chdr chdr;
d8024a91 7699
5844b465
NC
7700 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7701 printf (_(" [<corrupt>]\n"));
77115a4a 7702 else
5844b465
NC
7703 {
7704 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7705 printf (" ZLIB, ");
1369522f
CC
7706 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7707 printf (" ZSTD, ");
5844b465
NC
7708 else
7709 printf (_(" [<unknown>: 0x%x], "),
7710 chdr.ch_type);
7711 print_vma (chdr.ch_size, LONG_HEX);
7712 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7713 }
77115a4a
L
7714 }
7715 }
7716 }
252b5132
RH
7717 }
7718
5477e8a0 7719 if (!do_section_details)
3dbcc61d 7720 {
9fb71ee4
NC
7721 /* The ordering of the letters shown here matches the ordering of the
7722 corresponding SHF_xxx values, and hence the order in which these
7723 letters will be displayed to the user. */
7724 printf (_("Key to Flags:\n\
7725 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7726 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7727 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7728 switch (filedata->file_header.e_ident[EI_OSABI])
7729 {
7730 case ELFOSABI_GNU:
7731 case ELFOSABI_FREEBSD:
7732 printf (_("R (retain), "));
7733 /* Fall through */
7734 case ELFOSABI_NONE:
7735 printf (_("D (mbind), "));
7736 break;
7737 default:
7738 break;
7739 }
dda8d76d
NC
7740 if (filedata->file_header.e_machine == EM_X86_64
7741 || filedata->file_header.e_machine == EM_L1OM
7742 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7743 printf (_("l (large), "));
dda8d76d 7744 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7745 printf (_("y (purecode), "));
dda8d76d 7746 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7747 printf (_("v (VLE), "));
9fb71ee4 7748 printf ("p (processor specific)\n");
0b4362b0 7749 }
d1133906 7750
015dc7e1 7751 return true;
252b5132
RH
7752}
7753
015dc7e1 7754static bool
28d13567
AM
7755get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7756 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7757 char **strtab, unsigned long *strtablen)
7758{
7759 *strtab = NULL;
7760 *strtablen = 0;
4de91c10 7761 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7762
7763 if (*symtab == NULL)
015dc7e1 7764 return false;
28d13567
AM
7765
7766 if (symsec->sh_link != 0)
7767 {
7768 Elf_Internal_Shdr *strsec;
7769
7770 if (symsec->sh_link >= filedata->file_header.e_shnum)
7771 {
7772 error (_("Bad sh_link in symbol table section\n"));
7773 free (*symtab);
7774 *symtab = NULL;
7775 *nsyms = 0;
015dc7e1 7776 return false;
28d13567
AM
7777 }
7778
7779 strsec = filedata->section_headers + symsec->sh_link;
7780
7781 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7782 1, strsec->sh_size, _("string table"));
7783 if (*strtab == NULL)
7784 {
7785 free (*symtab);
7786 *symtab = NULL;
7787 *nsyms = 0;
015dc7e1 7788 return false;
28d13567
AM
7789 }
7790 *strtablen = strsec->sh_size;
7791 }
015dc7e1 7792 return true;
28d13567
AM
7793}
7794
f5842774
L
7795static const char *
7796get_group_flags (unsigned int flags)
7797{
1449284b 7798 static char buff[128];
220453ec 7799
6d913794
NC
7800 if (flags == 0)
7801 return "";
7802 else if (flags == GRP_COMDAT)
7803 return "COMDAT ";
f5842774 7804
89246a0e
AM
7805 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7806 flags,
7807 flags & GRP_MASKOS ? _("<OS specific>") : "",
7808 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7809 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7810 ? _("<unknown>") : ""));
6d913794 7811
f5842774
L
7812 return buff;
7813}
7814
015dc7e1 7815static bool
dda8d76d 7816process_section_groups (Filedata * filedata)
f5842774 7817{
2cf0635d 7818 Elf_Internal_Shdr * section;
f5842774 7819 unsigned int i;
2cf0635d
NC
7820 struct group * group;
7821 Elf_Internal_Shdr * symtab_sec;
7822 Elf_Internal_Shdr * strtab_sec;
7823 Elf_Internal_Sym * symtab;
ba5cdace 7824 unsigned long num_syms;
2cf0635d 7825 char * strtab;
c256ffe7 7826 size_t strtab_size;
d1f5c6e3
L
7827
7828 /* Don't process section groups unless needed. */
7829 if (!do_unwind && !do_section_groups)
015dc7e1 7830 return true;
f5842774 7831
dda8d76d 7832 if (filedata->file_header.e_shnum == 0)
f5842774
L
7833 {
7834 if (do_section_groups)
ca0e11aa
NC
7835 {
7836 if (filedata->is_separate)
7837 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7838 filedata->file_name);
7839 else
7840 printf (_("\nThere are no section groups in this file.\n"));
7841 }
015dc7e1 7842 return true;
f5842774
L
7843 }
7844
dda8d76d 7845 if (filedata->section_headers == NULL)
f5842774
L
7846 {
7847 error (_("Section headers are not available!\n"));
fa1908fd 7848 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7849 return false;
f5842774
L
7850 }
7851
978c4450
AM
7852 filedata->section_headers_groups
7853 = (struct group **) calloc (filedata->file_header.e_shnum,
7854 sizeof (struct group *));
e4b17d5c 7855
978c4450 7856 if (filedata->section_headers_groups == NULL)
e4b17d5c 7857 {
8b73c356 7858 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7859 filedata->file_header.e_shnum);
015dc7e1 7860 return false;
e4b17d5c
L
7861 }
7862
f5842774 7863 /* Scan the sections for the group section. */
978c4450 7864 filedata->group_count = 0;
dda8d76d
NC
7865 for (i = 0, section = filedata->section_headers;
7866 i < filedata->file_header.e_shnum;
f5842774 7867 i++, section++)
e4b17d5c 7868 if (section->sh_type == SHT_GROUP)
978c4450 7869 filedata->group_count++;
e4b17d5c 7870
978c4450 7871 if (filedata->group_count == 0)
d1f5c6e3
L
7872 {
7873 if (do_section_groups)
ca0e11aa
NC
7874 {
7875 if (filedata->is_separate)
7876 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7877 filedata->file_name);
7878 else
7879 printf (_("\nThere are no section groups in this file.\n"));
7880 }
d1f5c6e3 7881
015dc7e1 7882 return true;
d1f5c6e3
L
7883 }
7884
978c4450
AM
7885 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7886 sizeof (struct group));
e4b17d5c 7887
978c4450 7888 if (filedata->section_groups == NULL)
e4b17d5c 7889 {
8b73c356 7890 error (_("Out of memory reading %lu groups\n"),
978c4450 7891 (unsigned long) filedata->group_count);
015dc7e1 7892 return false;
e4b17d5c
L
7893 }
7894
d1f5c6e3
L
7895 symtab_sec = NULL;
7896 strtab_sec = NULL;
7897 symtab = NULL;
ba5cdace 7898 num_syms = 0;
d1f5c6e3 7899 strtab = NULL;
c256ffe7 7900 strtab_size = 0;
ca0e11aa
NC
7901
7902 if (filedata->is_separate)
7903 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7904
978c4450 7905 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7906 i < filedata->file_header.e_shnum;
e4b17d5c 7907 i++, section++)
f5842774
L
7908 {
7909 if (section->sh_type == SHT_GROUP)
7910 {
dda8d76d 7911 const char * name = printable_section_name (filedata, section);
74e1a04b 7912 const char * group_name;
2cf0635d
NC
7913 unsigned char * start;
7914 unsigned char * indices;
f5842774 7915 unsigned int entry, j, size;
2cf0635d
NC
7916 Elf_Internal_Shdr * sec;
7917 Elf_Internal_Sym * sym;
f5842774
L
7918
7919 /* Get the symbol table. */
dda8d76d
NC
7920 if (section->sh_link >= filedata->file_header.e_shnum
7921 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7922 != SHT_SYMTAB))
f5842774
L
7923 {
7924 error (_("Bad sh_link in group section `%s'\n"), name);
7925 continue;
7926 }
d1f5c6e3
L
7927
7928 if (symtab_sec != sec)
7929 {
7930 symtab_sec = sec;
9db70fc3 7931 free (symtab);
4de91c10 7932 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7933 }
f5842774 7934
dd24e3da
NC
7935 if (symtab == NULL)
7936 {
7937 error (_("Corrupt header in group section `%s'\n"), name);
7938 continue;
7939 }
7940
ba5cdace
NC
7941 if (section->sh_info >= num_syms)
7942 {
7943 error (_("Bad sh_info in group section `%s'\n"), name);
7944 continue;
7945 }
7946
f5842774
L
7947 sym = symtab + section->sh_info;
7948
7949 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7950 {
4fbb74a6 7951 if (sym->st_shndx == 0
dda8d76d 7952 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7953 {
7954 error (_("Bad sh_info in group section `%s'\n"), name);
7955 continue;
7956 }
ba2685cc 7957
84714f86
AM
7958 group_name = section_name_print (filedata,
7959 filedata->section_headers
b9e920ec 7960 + sym->st_shndx);
c256ffe7 7961 strtab_sec = NULL;
9db70fc3 7962 free (strtab);
f5842774 7963 strtab = NULL;
c256ffe7 7964 strtab_size = 0;
f5842774
L
7965 }
7966 else
7967 {
7968 /* Get the string table. */
dda8d76d 7969 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7970 {
7971 strtab_sec = NULL;
9db70fc3 7972 free (strtab);
c256ffe7
JJ
7973 strtab = NULL;
7974 strtab_size = 0;
7975 }
7976 else if (strtab_sec
dda8d76d 7977 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7978 {
7979 strtab_sec = sec;
9db70fc3 7980 free (strtab);
071436c6 7981
dda8d76d 7982 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7983 1, strtab_sec->sh_size,
7984 _("string table"));
c256ffe7 7985 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7986 }
c256ffe7 7987 group_name = sym->st_name < strtab_size
2b692964 7988 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7989 }
7990
c9c1d674
EG
7991 /* PR 17531: file: loop. */
7992 if (section->sh_entsize > section->sh_size)
7993 {
7994 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7995 printable_section_name (filedata, section),
8066deb1
AM
7996 (unsigned long) section->sh_entsize,
7997 (unsigned long) section->sh_size);
61dd8e19 7998 continue;
c9c1d674
EG
7999 }
8000
dda8d76d 8001 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8002 1, section->sh_size,
8003 _("section data"));
59245841
NC
8004 if (start == NULL)
8005 continue;
f5842774
L
8006
8007 indices = start;
8008 size = (section->sh_size / section->sh_entsize) - 1;
8009 entry = byte_get (indices, 4);
8010 indices += 4;
e4b17d5c
L
8011
8012 if (do_section_groups)
8013 {
2b692964 8014 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8015 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8016
e4b17d5c
L
8017 printf (_(" [Index] Name\n"));
8018 }
8019
8020 group->group_index = i;
8021
f5842774
L
8022 for (j = 0; j < size; j++)
8023 {
2cf0635d 8024 struct group_list * g;
e4b17d5c 8025
f5842774
L
8026 entry = byte_get (indices, 4);
8027 indices += 4;
8028
dda8d76d 8029 if (entry >= filedata->file_header.e_shnum)
391cb864 8030 {
57028622
NC
8031 static unsigned num_group_errors = 0;
8032
8033 if (num_group_errors ++ < 10)
8034 {
8035 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8036 entry, i, filedata->file_header.e_shnum - 1);
57028622 8037 if (num_group_errors == 10)
67ce483b 8038 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8039 }
391cb864
L
8040 continue;
8041 }
391cb864 8042
978c4450 8043 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8044 {
d1f5c6e3
L
8045 if (entry)
8046 {
57028622
NC
8047 static unsigned num_errs = 0;
8048
8049 if (num_errs ++ < 10)
8050 {
8051 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8052 entry, i,
978c4450 8053 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8054 if (num_errs == 10)
8055 warn (_("Further error messages about already contained group sections suppressed\n"));
8056 }
d1f5c6e3
L
8057 continue;
8058 }
8059 else
8060 {
8061 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8062 section group. We just warn it the first time
d1f5c6e3 8063 and ignore it afterwards. */
015dc7e1 8064 static bool warned = false;
d1f5c6e3
L
8065 if (!warned)
8066 {
8067 error (_("section 0 in group section [%5u]\n"),
978c4450 8068 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8069 warned = true;
d1f5c6e3
L
8070 }
8071 }
e4b17d5c
L
8072 }
8073
978c4450 8074 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8075
8076 if (do_section_groups)
8077 {
dda8d76d
NC
8078 sec = filedata->section_headers + entry;
8079 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8080 }
8081
3f5e193b 8082 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8083 g->section_index = entry;
8084 g->next = group->root;
8085 group->root = g;
f5842774
L
8086 }
8087
9db70fc3 8088 free (start);
e4b17d5c
L
8089
8090 group++;
f5842774
L
8091 }
8092 }
8093
9db70fc3
AM
8094 free (symtab);
8095 free (strtab);
015dc7e1 8096 return true;
f5842774
L
8097}
8098
28f997cf
TG
8099/* Data used to display dynamic fixups. */
8100
8101struct ia64_vms_dynfixup
8102{
8103 bfd_vma needed_ident; /* Library ident number. */
8104 bfd_vma needed; /* Index in the dstrtab of the library name. */
8105 bfd_vma fixup_needed; /* Index of the library. */
8106 bfd_vma fixup_rela_cnt; /* Number of fixups. */
8107 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
8108};
8109
8110/* Data used to display dynamic relocations. */
8111
8112struct ia64_vms_dynimgrela
8113{
8114 bfd_vma img_rela_cnt; /* Number of relocations. */
8115 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
8116};
8117
8118/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8119 library). */
8120
015dc7e1 8121static bool
dda8d76d
NC
8122dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8123 struct ia64_vms_dynfixup * fixup,
8124 const char * strtab,
8125 unsigned int strtab_sz)
28f997cf 8126{
32ec8896 8127 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8128 long i;
32ec8896 8129 const char * lib_name;
28f997cf 8130
978c4450
AM
8131 imfs = get_data (NULL, filedata,
8132 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8133 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8134 _("dynamic section image fixups"));
8135 if (!imfs)
015dc7e1 8136 return false;
28f997cf
TG
8137
8138 if (fixup->needed < strtab_sz)
8139 lib_name = strtab + fixup->needed;
8140 else
8141 {
32ec8896 8142 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8143 (unsigned long) fixup->needed);
28f997cf
TG
8144 lib_name = "???";
8145 }
736990c4 8146
28f997cf
TG
8147 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8148 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8149 printf
8150 (_("Seg Offset Type SymVec DataType\n"));
8151
8152 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8153 {
8154 unsigned int type;
8155 const char *rtype;
8156
8157 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
f493c217 8158 printf ("%016" PRIx64 " ", (uint64_t) BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8159 type = BYTE_GET (imfs [i].type);
8160 rtype = elf_ia64_reloc_type (type);
8161 if (rtype == NULL)
f493c217 8162 printf ("0x%08x ", type);
28f997cf 8163 else
f493c217 8164 printf ("%-32s ", rtype);
28f997cf
TG
8165 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8166 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8167 }
8168
8169 free (imfs);
015dc7e1 8170 return true;
28f997cf
TG
8171}
8172
8173/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8174
015dc7e1 8175static bool
dda8d76d 8176dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8177{
8178 Elf64_External_VMS_IMAGE_RELA *imrs;
8179 long i;
8180
978c4450
AM
8181 imrs = get_data (NULL, filedata,
8182 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8183 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8184 _("dynamic section image relocations"));
28f997cf 8185 if (!imrs)
015dc7e1 8186 return false;
28f997cf
TG
8187
8188 printf (_("\nImage relocs\n"));
8189 printf
8190 (_("Seg Offset Type Addend Seg Sym Off\n"));
8191
8192 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8193 {
8194 unsigned int type;
8195 const char *rtype;
8196
8197 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
b8281767
AM
8198 printf ("%08" PRIx64 " ",
8199 (uint64_t) BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8200 type = BYTE_GET (imrs [i].type);
8201 rtype = elf_ia64_reloc_type (type);
8202 if (rtype == NULL)
8203 printf ("0x%08x ", type);
8204 else
8205 printf ("%-31s ", rtype);
8206 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8207 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
b8281767
AM
8208 printf ("%08" PRIx64 "\n",
8209 (uint64_t) BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8210 }
8211
8212 free (imrs);
015dc7e1 8213 return true;
28f997cf
TG
8214}
8215
8216/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8217
015dc7e1 8218static bool
dda8d76d 8219process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8220{
8221 struct ia64_vms_dynfixup fixup;
8222 struct ia64_vms_dynimgrela imgrela;
8223 Elf_Internal_Dyn *entry;
28f997cf
TG
8224 bfd_vma strtab_off = 0;
8225 bfd_vma strtab_sz = 0;
8226 char *strtab = NULL;
015dc7e1 8227 bool res = true;
28f997cf
TG
8228
8229 memset (&fixup, 0, sizeof (fixup));
8230 memset (&imgrela, 0, sizeof (imgrela));
8231
8232 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8233 for (entry = filedata->dynamic_section;
8234 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8235 entry++)
8236 {
8237 switch (entry->d_tag)
8238 {
8239 case DT_IA_64_VMS_STRTAB_OFFSET:
8240 strtab_off = entry->d_un.d_val;
8241 break;
8242 case DT_STRSZ:
8243 strtab_sz = entry->d_un.d_val;
8244 if (strtab == NULL)
978c4450
AM
8245 strtab = get_data (NULL, filedata,
8246 filedata->dynamic_addr + strtab_off,
28f997cf 8247 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8248 if (strtab == NULL)
8249 strtab_sz = 0;
28f997cf
TG
8250 break;
8251
8252 case DT_IA_64_VMS_NEEDED_IDENT:
8253 fixup.needed_ident = entry->d_un.d_val;
8254 break;
8255 case DT_NEEDED:
8256 fixup.needed = entry->d_un.d_val;
8257 break;
8258 case DT_IA_64_VMS_FIXUP_NEEDED:
8259 fixup.fixup_needed = entry->d_un.d_val;
8260 break;
8261 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8262 fixup.fixup_rela_cnt = entry->d_un.d_val;
8263 break;
8264 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8265 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8266 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8267 res = false;
28f997cf 8268 break;
28f997cf
TG
8269 case DT_IA_64_VMS_IMG_RELA_CNT:
8270 imgrela.img_rela_cnt = entry->d_un.d_val;
8271 break;
8272 case DT_IA_64_VMS_IMG_RELA_OFF:
8273 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8274 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8275 res = false;
28f997cf
TG
8276 break;
8277
8278 default:
8279 break;
8280 }
8281 }
8282
9db70fc3 8283 free (strtab);
28f997cf
TG
8284
8285 return res;
8286}
8287
85b1c36d 8288static struct
566b0d53 8289{
2cf0635d 8290 const char * name;
566b0d53
L
8291 int reloc;
8292 int size;
a7fd1186 8293 relocation_type rel_type;
32ec8896
NC
8294}
8295 dynamic_relocations [] =
566b0d53 8296{
a7fd1186
FS
8297 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8298 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8299 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8300 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8301};
8302
252b5132 8303/* Process the reloc section. */
18bd398b 8304
015dc7e1 8305static bool
dda8d76d 8306process_relocs (Filedata * filedata)
252b5132 8307{
b34976b6
AM
8308 unsigned long rel_size;
8309 unsigned long rel_offset;
252b5132 8310
252b5132 8311 if (!do_reloc)
015dc7e1 8312 return true;
252b5132
RH
8313
8314 if (do_using_dynamic)
8315 {
a7fd1186 8316 relocation_type rel_type;
2cf0635d 8317 const char * name;
015dc7e1 8318 bool has_dynamic_reloc;
566b0d53 8319 unsigned int i;
0de14b54 8320
015dc7e1 8321 has_dynamic_reloc = false;
252b5132 8322
566b0d53 8323 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8324 {
a7fd1186 8325 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8326 name = dynamic_relocations [i].name;
978c4450
AM
8327 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8328 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8329
32ec8896 8330 if (rel_size)
015dc7e1 8331 has_dynamic_reloc = true;
566b0d53 8332
a7fd1186 8333 if (rel_type == reltype_unknown)
aa903cfb 8334 {
566b0d53 8335 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8336 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8337 {
8338 case DT_REL:
a7fd1186 8339 rel_type = reltype_rel;
566b0d53
L
8340 break;
8341 case DT_RELA:
a7fd1186 8342 rel_type = reltype_rela;
566b0d53
L
8343 break;
8344 }
aa903cfb 8345 }
252b5132 8346
566b0d53
L
8347 if (rel_size)
8348 {
ca0e11aa
NC
8349 if (filedata->is_separate)
8350 printf
8351 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8352 filedata->file_name, name, rel_offset, rel_size);
8353 else
8354 printf
8355 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8356 name, rel_offset, rel_size);
252b5132 8357
dda8d76d
NC
8358 dump_relocations (filedata,
8359 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8360 rel_size,
978c4450
AM
8361 filedata->dynamic_symbols,
8362 filedata->num_dynamic_syms,
8363 filedata->dynamic_strings,
8364 filedata->dynamic_strings_length,
a7fd1186 8365 rel_type, true /* is_dynamic */);
566b0d53 8366 }
252b5132 8367 }
566b0d53 8368
dda8d76d
NC
8369 if (is_ia64_vms (filedata))
8370 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8371 has_dynamic_reloc = true;
28f997cf 8372
566b0d53 8373 if (! has_dynamic_reloc)
ca0e11aa
NC
8374 {
8375 if (filedata->is_separate)
8376 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8377 filedata->file_name);
8378 else
8379 printf (_("\nThere are no dynamic relocations in this file.\n"));
8380 }
252b5132
RH
8381 }
8382 else
8383 {
2cf0635d 8384 Elf_Internal_Shdr * section;
b34976b6 8385 unsigned long i;
015dc7e1 8386 bool found = false;
252b5132 8387
dda8d76d
NC
8388 for (i = 0, section = filedata->section_headers;
8389 i < filedata->file_header.e_shnum;
b34976b6 8390 i++, section++)
252b5132
RH
8391 {
8392 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8393 && section->sh_type != SHT_REL
8394 && section->sh_type != SHT_RELR)
252b5132
RH
8395 continue;
8396
8397 rel_offset = section->sh_offset;
8398 rel_size = section->sh_size;
8399
8400 if (rel_size)
8401 {
a7fd1186 8402 relocation_type rel_type;
d3a49aa8 8403 unsigned long num_rela;
103f02d3 8404
ca0e11aa
NC
8405 if (filedata->is_separate)
8406 printf (_("\nIn linked file '%s' relocation section "),
8407 filedata->file_name);
8408 else
8409 printf (_("\nRelocation section "));
252b5132 8410
dda8d76d 8411 if (filedata->string_table == NULL)
19936277 8412 printf ("%d", section->sh_name);
252b5132 8413 else
dda8d76d 8414 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8415
d3a49aa8
AM
8416 num_rela = rel_size / section->sh_entsize;
8417 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8418 " at offset 0x%lx contains %lu entries:\n",
8419 num_rela),
8420 rel_offset, num_rela);
252b5132 8421
a7fd1186
FS
8422 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8423 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8424
4fbb74a6 8425 if (section->sh_link != 0
dda8d76d 8426 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8427 {
2cf0635d
NC
8428 Elf_Internal_Shdr * symsec;
8429 Elf_Internal_Sym * symtab;
d79b3d50 8430 unsigned long nsyms;
c256ffe7 8431 unsigned long strtablen = 0;
2cf0635d 8432 char * strtab = NULL;
57346661 8433
dda8d76d 8434 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8435 if (symsec->sh_type != SHT_SYMTAB
8436 && symsec->sh_type != SHT_DYNSYM)
8437 continue;
8438
28d13567
AM
8439 if (!get_symtab (filedata, symsec,
8440 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8441 continue;
252b5132 8442
dda8d76d 8443 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8444 symtab, nsyms, strtab, strtablen,
a7fd1186 8445 rel_type,
bb4d2ac2 8446 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8447 free (strtab);
d79b3d50
NC
8448 free (symtab);
8449 }
8450 else
dda8d76d 8451 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8452 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8453
015dc7e1 8454 found = true;
252b5132
RH
8455 }
8456 }
8457
8458 if (! found)
45ac8f4f
NC
8459 {
8460 /* Users sometimes forget the -D option, so try to be helpful. */
8461 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8462 {
978c4450 8463 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8464 {
ca0e11aa
NC
8465 if (filedata->is_separate)
8466 printf (_("\nThere are no static relocations in linked file '%s'."),
8467 filedata->file_name);
8468 else
8469 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8470 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8471
8472 break;
8473 }
8474 }
8475 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8476 {
8477 if (filedata->is_separate)
8478 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8479 filedata->file_name);
8480 else
8481 printf (_("\nThere are no relocations in this file.\n"));
8482 }
45ac8f4f 8483 }
252b5132
RH
8484 }
8485
015dc7e1 8486 return true;
252b5132
RH
8487}
8488
4d6ed7c8
NC
8489/* An absolute address consists of a section and an offset. If the
8490 section is NULL, the offset itself is the address, otherwise, the
8491 address equals to LOAD_ADDRESS(section) + offset. */
8492
8493struct absaddr
948f632f
DA
8494{
8495 unsigned short section;
8496 bfd_vma offset;
8497};
4d6ed7c8 8498
948f632f
DA
8499/* Find the nearest symbol at or below ADDR. Returns the symbol
8500 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8501
4d6ed7c8 8502static void
dda8d76d
NC
8503find_symbol_for_address (Filedata * filedata,
8504 Elf_Internal_Sym * symtab,
8505 unsigned long nsyms,
8506 const char * strtab,
8507 unsigned long strtab_size,
8508 struct absaddr addr,
8509 const char ** symname,
8510 bfd_vma * offset)
4d6ed7c8 8511{
d3ba0551 8512 bfd_vma dist = 0x100000;
2cf0635d 8513 Elf_Internal_Sym * sym;
948f632f
DA
8514 Elf_Internal_Sym * beg;
8515 Elf_Internal_Sym * end;
2cf0635d 8516 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8517
0b6ae522 8518 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8519 beg = symtab;
8520 end = symtab + nsyms;
0b6ae522 8521
948f632f 8522 while (beg < end)
4d6ed7c8 8523 {
948f632f
DA
8524 bfd_vma value;
8525
8526 sym = beg + (end - beg) / 2;
0b6ae522 8527
948f632f 8528 value = sym->st_value;
0b6ae522
DJ
8529 REMOVE_ARCH_BITS (value);
8530
948f632f 8531 if (sym->st_name != 0
4d6ed7c8 8532 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8533 && addr.offset >= value
8534 && addr.offset - value < dist)
4d6ed7c8
NC
8535 {
8536 best = sym;
0b6ae522 8537 dist = addr.offset - value;
4d6ed7c8
NC
8538 if (!dist)
8539 break;
8540 }
948f632f
DA
8541
8542 if (addr.offset < value)
8543 end = sym;
8544 else
8545 beg = sym + 1;
4d6ed7c8 8546 }
1b31d05e 8547
4d6ed7c8
NC
8548 if (best)
8549 {
57346661 8550 *symname = (best->st_name >= strtab_size
2b692964 8551 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8552 *offset = dist;
8553 return;
8554 }
1b31d05e 8555
4d6ed7c8
NC
8556 *symname = NULL;
8557 *offset = addr.offset;
8558}
8559
32ec8896 8560static /* signed */ int
948f632f
DA
8561symcmp (const void *p, const void *q)
8562{
8563 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8564 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8565
8566 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8567}
8568
8569/* Process the unwind section. */
8570
8571#include "unwind-ia64.h"
8572
8573struct ia64_unw_table_entry
8574{
8575 struct absaddr start;
8576 struct absaddr end;
8577 struct absaddr info;
8578};
8579
8580struct ia64_unw_aux_info
8581{
32ec8896
NC
8582 struct ia64_unw_table_entry * table; /* Unwind table. */
8583 unsigned long table_len; /* Length of unwind table. */
8584 unsigned char * info; /* Unwind info. */
8585 unsigned long info_size; /* Size of unwind info. */
8586 bfd_vma info_addr; /* Starting address of unwind info. */
8587 bfd_vma seg_base; /* Starting address of segment. */
8588 Elf_Internal_Sym * symtab; /* The symbol table. */
8589 unsigned long nsyms; /* Number of symbols. */
8590 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8591 unsigned long nfuns; /* Number of entries in funtab. */
8592 char * strtab; /* The string table. */
8593 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8594};
8595
015dc7e1 8596static bool
dda8d76d 8597dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8598{
2cf0635d 8599 struct ia64_unw_table_entry * tp;
948f632f 8600 unsigned long j, nfuns;
4d6ed7c8 8601 int in_body;
015dc7e1 8602 bool res = true;
7036c0e1 8603
948f632f
DA
8604 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8605 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8606 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8607 aux->funtab[nfuns++] = aux->symtab[j];
8608 aux->nfuns = nfuns;
8609 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8610
4d6ed7c8
NC
8611 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8612 {
8613 bfd_vma stamp;
8614 bfd_vma offset;
2cf0635d
NC
8615 const unsigned char * dp;
8616 const unsigned char * head;
53774b7e 8617 const unsigned char * end;
2cf0635d 8618 const char * procname;
4d6ed7c8 8619
dda8d76d 8620 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8621 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8622
8623 fputs ("\n<", stdout);
8624
8625 if (procname)
8626 {
8627 fputs (procname, stdout);
8628
8629 if (offset)
8630 printf ("+%lx", (unsigned long) offset);
8631 }
8632
8633 fputs (">: [", stdout);
8634 print_vma (tp->start.offset, PREFIX_HEX);
8635 fputc ('-', stdout);
8636 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8637 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8638 (unsigned long) (tp->info.offset - aux->seg_base));
8639
53774b7e
NC
8640 /* PR 17531: file: 86232b32. */
8641 if (aux->info == NULL)
8642 continue;
8643
97c0a079
AM
8644 offset = tp->info.offset;
8645 if (tp->info.section)
8646 {
8647 if (tp->info.section >= filedata->file_header.e_shnum)
8648 {
8649 warn (_("Invalid section %u in table entry %ld\n"),
8650 tp->info.section, (long) (tp - aux->table));
015dc7e1 8651 res = false;
97c0a079
AM
8652 continue;
8653 }
8654 offset += filedata->section_headers[tp->info.section].sh_addr;
8655 }
8656 offset -= aux->info_addr;
53774b7e 8657 /* PR 17531: file: 0997b4d1. */
90679903
AM
8658 if (offset >= aux->info_size
8659 || aux->info_size - offset < 8)
53774b7e
NC
8660 {
8661 warn (_("Invalid offset %lx in table entry %ld\n"),
8662 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8663 res = false;
53774b7e
NC
8664 continue;
8665 }
8666
97c0a079 8667 head = aux->info + offset;
a4a00738 8668 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8669
86f55779 8670 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8671 (unsigned) UNW_VER (stamp),
8672 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8673 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8674 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8675 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8676
8677 if (UNW_VER (stamp) != 1)
8678 {
2b692964 8679 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8680 continue;
8681 }
8682
8683 in_body = 0;
53774b7e
NC
8684 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8685 /* PR 17531: file: 16ceda89. */
8686 if (end > aux->info + aux->info_size)
8687 end = aux->info + aux->info_size;
8688 for (dp = head + 8; dp < end;)
b4477bc8 8689 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8690 }
948f632f
DA
8691
8692 free (aux->funtab);
32ec8896
NC
8693
8694 return res;
4d6ed7c8
NC
8695}
8696
015dc7e1 8697static bool
dda8d76d
NC
8698slurp_ia64_unwind_table (Filedata * filedata,
8699 struct ia64_unw_aux_info * aux,
8700 Elf_Internal_Shdr * sec)
4d6ed7c8 8701{
89fac5e3 8702 unsigned long size, nrelas, i;
2cf0635d
NC
8703 Elf_Internal_Phdr * seg;
8704 struct ia64_unw_table_entry * tep;
8705 Elf_Internal_Shdr * relsec;
8706 Elf_Internal_Rela * rela;
8707 Elf_Internal_Rela * rp;
8708 unsigned char * table;
8709 unsigned char * tp;
8710 Elf_Internal_Sym * sym;
8711 const char * relname;
4d6ed7c8 8712
53774b7e
NC
8713 aux->table_len = 0;
8714
4d6ed7c8
NC
8715 /* First, find the starting address of the segment that includes
8716 this section: */
8717
dda8d76d 8718 if (filedata->file_header.e_phnum)
4d6ed7c8 8719 {
dda8d76d 8720 if (! get_program_headers (filedata))
015dc7e1 8721 return false;
4d6ed7c8 8722
dda8d76d
NC
8723 for (seg = filedata->program_headers;
8724 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8725 ++seg)
4d6ed7c8
NC
8726 {
8727 if (seg->p_type != PT_LOAD)
8728 continue;
8729
8730 if (sec->sh_addr >= seg->p_vaddr
8731 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8732 {
8733 aux->seg_base = seg->p_vaddr;
8734 break;
8735 }
8736 }
4d6ed7c8
NC
8737 }
8738
8739 /* Second, build the unwind table from the contents of the unwind section: */
8740 size = sec->sh_size;
dda8d76d 8741 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8742 _("unwind table"));
a6e9f9df 8743 if (!table)
015dc7e1 8744 return false;
4d6ed7c8 8745
53774b7e 8746 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8747 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8748 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8749 tep = aux->table;
53774b7e
NC
8750
8751 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8752 {
8753 tep->start.section = SHN_UNDEF;
8754 tep->end.section = SHN_UNDEF;
8755 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8756 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8757 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8758 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8759 tep->start.offset += aux->seg_base;
8760 tep->end.offset += aux->seg_base;
8761 tep->info.offset += aux->seg_base;
8762 }
8763 free (table);
8764
41e92641 8765 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8766 for (relsec = filedata->section_headers;
8767 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8768 ++relsec)
8769 {
8770 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8771 || relsec->sh_info >= filedata->file_header.e_shnum
8772 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8773 continue;
8774
dda8d76d 8775 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8776 & rela, & nrelas))
53774b7e
NC
8777 {
8778 free (aux->table);
8779 aux->table = NULL;
8780 aux->table_len = 0;
015dc7e1 8781 return false;
53774b7e 8782 }
4d6ed7c8
NC
8783
8784 for (rp = rela; rp < rela + nrelas; ++rp)
8785 {
4770fb94 8786 unsigned int sym_ndx;
726bd37d
AM
8787 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8788 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8789
82b1b41b
NC
8790 /* PR 17531: file: 9fa67536. */
8791 if (relname == NULL)
8792 {
726bd37d 8793 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8794 continue;
8795 }
948f632f 8796
24d127aa 8797 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8798 {
82b1b41b 8799 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8800 continue;
8801 }
8802
89fac5e3 8803 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8804
53774b7e
NC
8805 /* PR 17531: file: 5bc8d9bf. */
8806 if (i >= aux->table_len)
8807 {
8808 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8809 continue;
8810 }
8811
4770fb94
AM
8812 sym_ndx = get_reloc_symindex (rp->r_info);
8813 if (sym_ndx >= aux->nsyms)
8814 {
8815 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8816 sym_ndx);
8817 continue;
8818 }
8819 sym = aux->symtab + sym_ndx;
8820
53774b7e 8821 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8822 {
8823 case 0:
8824 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8825 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8826 break;
8827 case 1:
8828 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8829 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8830 break;
8831 case 2:
8832 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8833 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8834 break;
8835 default:
8836 break;
8837 }
8838 }
8839
8840 free (rela);
8841 }
8842
015dc7e1 8843 return true;
4d6ed7c8
NC
8844}
8845
015dc7e1 8846static bool
dda8d76d 8847ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8848{
2cf0635d
NC
8849 Elf_Internal_Shdr * sec;
8850 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8851 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8852 struct ia64_unw_aux_info aux;
015dc7e1 8853 bool res = true;
f1467e33 8854
4d6ed7c8
NC
8855 memset (& aux, 0, sizeof (aux));
8856
dda8d76d 8857 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8858 {
28d13567 8859 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8860 {
28d13567 8861 if (aux.symtab)
4082ef84 8862 {
28d13567
AM
8863 error (_("Multiple symbol tables encountered\n"));
8864 free (aux.symtab);
8865 aux.symtab = NULL;
4082ef84 8866 free (aux.strtab);
28d13567 8867 aux.strtab = NULL;
4082ef84 8868 }
28d13567
AM
8869 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8870 &aux.strtab, &aux.strtab_size))
015dc7e1 8871 return false;
4d6ed7c8
NC
8872 }
8873 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8874 unwcount++;
8875 }
8876
8877 if (!unwcount)
8878 printf (_("\nThere are no unwind sections in this file.\n"));
8879
8880 while (unwcount-- > 0)
8881 {
84714f86 8882 const char *suffix;
579f31ac
JJ
8883 size_t len, len2;
8884
dda8d76d
NC
8885 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8886 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8887 if (sec->sh_type == SHT_IA_64_UNWIND)
8888 {
8889 unwsec = sec;
8890 break;
8891 }
4082ef84
NC
8892 /* We have already counted the number of SHT_IA64_UNWIND
8893 sections so the loop above should never fail. */
8894 assert (unwsec != NULL);
579f31ac
JJ
8895
8896 unwstart = i + 1;
8897 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8898
e4b17d5c
L
8899 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8900 {
8901 /* We need to find which section group it is in. */
4082ef84 8902 struct group_list * g;
e4b17d5c 8903
978c4450
AM
8904 if (filedata->section_headers_groups == NULL
8905 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8906 i = filedata->file_header.e_shnum;
4082ef84 8907 else
e4b17d5c 8908 {
978c4450 8909 g = filedata->section_headers_groups[i]->root;
18bd398b 8910
4082ef84
NC
8911 for (; g != NULL; g = g->next)
8912 {
dda8d76d 8913 sec = filedata->section_headers + g->section_index;
e4b17d5c 8914
84714f86
AM
8915 if (section_name_valid (filedata, sec)
8916 && streq (section_name (filedata, sec),
8917 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8918 break;
8919 }
8920
8921 if (g == NULL)
dda8d76d 8922 i = filedata->file_header.e_shnum;
4082ef84 8923 }
e4b17d5c 8924 }
84714f86
AM
8925 else if (section_name_valid (filedata, unwsec)
8926 && startswith (section_name (filedata, unwsec),
e9b095a5 8927 ELF_STRING_ia64_unwind_once))
579f31ac 8928 {
18bd398b 8929 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8930 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8931 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8932 for (i = 0, sec = filedata->section_headers;
8933 i < filedata->file_header.e_shnum;
579f31ac 8934 ++i, ++sec)
84714f86
AM
8935 if (section_name_valid (filedata, sec)
8936 && startswith (section_name (filedata, sec),
e9b095a5 8937 ELF_STRING_ia64_unwind_info_once)
84714f86 8938 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8939 break;
8940 }
8941 else
8942 {
8943 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8944 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8945 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8946 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8947 suffix = "";
84714f86
AM
8948 if (section_name_valid (filedata, unwsec)
8949 && startswith (section_name (filedata, unwsec),
8950 ELF_STRING_ia64_unwind))
8951 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8952 for (i = 0, sec = filedata->section_headers;
8953 i < filedata->file_header.e_shnum;
579f31ac 8954 ++i, ++sec)
84714f86
AM
8955 if (section_name_valid (filedata, sec)
8956 && startswith (section_name (filedata, sec),
8957 ELF_STRING_ia64_unwind_info)
8958 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8959 break;
8960 }
8961
dda8d76d 8962 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8963 {
8964 printf (_("\nCould not find unwind info section for "));
8965
dda8d76d 8966 if (filedata->string_table == NULL)
579f31ac
JJ
8967 printf ("%d", unwsec->sh_name);
8968 else
dda8d76d 8969 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8970 }
8971 else
4d6ed7c8 8972 {
4d6ed7c8 8973 aux.info_addr = sec->sh_addr;
dda8d76d 8974 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8975 sec->sh_size,
8976 _("unwind info"));
59245841 8977 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8978
579f31ac 8979 printf (_("\nUnwind section "));
4d6ed7c8 8980
dda8d76d 8981 if (filedata->string_table == NULL)
579f31ac
JJ
8982 printf ("%d", unwsec->sh_name);
8983 else
dda8d76d 8984 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8985
579f31ac 8986 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8987 (unsigned long) unwsec->sh_offset,
89fac5e3 8988 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8989
dda8d76d 8990 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8991 && aux.table_len > 0)
dda8d76d 8992 dump_ia64_unwind (filedata, & aux);
579f31ac 8993
9db70fc3
AM
8994 free ((char *) aux.table);
8995 free ((char *) aux.info);
579f31ac
JJ
8996 aux.table = NULL;
8997 aux.info = NULL;
8998 }
4d6ed7c8 8999 }
4d6ed7c8 9000
9db70fc3
AM
9001 free (aux.symtab);
9002 free ((char *) aux.strtab);
32ec8896
NC
9003
9004 return res;
4d6ed7c8
NC
9005}
9006
3f5e193b 9007struct hppa_unw_table_entry
32ec8896
NC
9008{
9009 struct absaddr start;
9010 struct absaddr end;
9011 unsigned int Cannot_unwind:1; /* 0 */
9012 unsigned int Millicode:1; /* 1 */
9013 unsigned int Millicode_save_sr0:1; /* 2 */
9014 unsigned int Region_description:2; /* 3..4 */
9015 unsigned int reserved1:1; /* 5 */
9016 unsigned int Entry_SR:1; /* 6 */
9017 unsigned int Entry_FR:4; /* Number saved 7..10 */
9018 unsigned int Entry_GR:5; /* Number saved 11..15 */
9019 unsigned int Args_stored:1; /* 16 */
9020 unsigned int Variable_Frame:1; /* 17 */
9021 unsigned int Separate_Package_Body:1; /* 18 */
9022 unsigned int Frame_Extension_Millicode:1; /* 19 */
9023 unsigned int Stack_Overflow_Check:1; /* 20 */
9024 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9025 unsigned int Ada_Region:1; /* 22 */
9026 unsigned int cxx_info:1; /* 23 */
9027 unsigned int cxx_try_catch:1; /* 24 */
9028 unsigned int sched_entry_seq:1; /* 25 */
9029 unsigned int reserved2:1; /* 26 */
9030 unsigned int Save_SP:1; /* 27 */
9031 unsigned int Save_RP:1; /* 28 */
9032 unsigned int Save_MRP_in_frame:1; /* 29 */
9033 unsigned int extn_ptr_defined:1; /* 30 */
9034 unsigned int Cleanup_defined:1; /* 31 */
9035
9036 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9037 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9038 unsigned int Large_frame:1; /* 2 */
9039 unsigned int Pseudo_SP_Set:1; /* 3 */
9040 unsigned int reserved4:1; /* 4 */
9041 unsigned int Total_frame_size:27; /* 5..31 */
9042};
3f5e193b 9043
57346661 9044struct hppa_unw_aux_info
948f632f 9045{
32ec8896
NC
9046 struct hppa_unw_table_entry * table; /* Unwind table. */
9047 unsigned long table_len; /* Length of unwind table. */
9048 bfd_vma seg_base; /* Starting address of segment. */
9049 Elf_Internal_Sym * symtab; /* The symbol table. */
9050 unsigned long nsyms; /* Number of symbols. */
9051 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9052 unsigned long nfuns; /* Number of entries in funtab. */
9053 char * strtab; /* The string table. */
9054 unsigned long strtab_size; /* Size of string table. */
948f632f 9055};
57346661 9056
015dc7e1 9057static bool
dda8d76d 9058dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9059{
2cf0635d 9060 struct hppa_unw_table_entry * tp;
948f632f 9061 unsigned long j, nfuns;
015dc7e1 9062 bool res = true;
948f632f
DA
9063
9064 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9065 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9066 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9067 aux->funtab[nfuns++] = aux->symtab[j];
9068 aux->nfuns = nfuns;
9069 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9070
57346661
AM
9071 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9072 {
9073 bfd_vma offset;
2cf0635d 9074 const char * procname;
57346661 9075
dda8d76d 9076 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9077 aux->strtab_size, tp->start, &procname,
9078 &offset);
9079
9080 fputs ("\n<", stdout);
9081
9082 if (procname)
9083 {
9084 fputs (procname, stdout);
9085
9086 if (offset)
9087 printf ("+%lx", (unsigned long) offset);
9088 }
9089
9090 fputs (">: [", stdout);
9091 print_vma (tp->start.offset, PREFIX_HEX);
9092 fputc ('-', stdout);
9093 print_vma (tp->end.offset, PREFIX_HEX);
9094 printf ("]\n\t");
9095
18bd398b
NC
9096#define PF(_m) if (tp->_m) printf (#_m " ");
9097#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9098 PF(Cannot_unwind);
9099 PF(Millicode);
9100 PF(Millicode_save_sr0);
18bd398b 9101 /* PV(Region_description); */
57346661
AM
9102 PF(Entry_SR);
9103 PV(Entry_FR);
9104 PV(Entry_GR);
9105 PF(Args_stored);
9106 PF(Variable_Frame);
9107 PF(Separate_Package_Body);
9108 PF(Frame_Extension_Millicode);
9109 PF(Stack_Overflow_Check);
9110 PF(Two_Instruction_SP_Increment);
9111 PF(Ada_Region);
9112 PF(cxx_info);
9113 PF(cxx_try_catch);
9114 PF(sched_entry_seq);
9115 PF(Save_SP);
9116 PF(Save_RP);
9117 PF(Save_MRP_in_frame);
9118 PF(extn_ptr_defined);
9119 PF(Cleanup_defined);
9120 PF(MPE_XL_interrupt_marker);
9121 PF(HP_UX_interrupt_marker);
9122 PF(Large_frame);
9123 PF(Pseudo_SP_Set);
9124 PV(Total_frame_size);
9125#undef PF
9126#undef PV
9127 }
9128
18bd398b 9129 printf ("\n");
948f632f
DA
9130
9131 free (aux->funtab);
32ec8896
NC
9132
9133 return res;
57346661
AM
9134}
9135
015dc7e1 9136static bool
dda8d76d
NC
9137slurp_hppa_unwind_table (Filedata * filedata,
9138 struct hppa_unw_aux_info * aux,
9139 Elf_Internal_Shdr * sec)
57346661 9140{
1c0751b2 9141 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9142 Elf_Internal_Phdr * seg;
9143 struct hppa_unw_table_entry * tep;
9144 Elf_Internal_Shdr * relsec;
9145 Elf_Internal_Rela * rela;
9146 Elf_Internal_Rela * rp;
9147 unsigned char * table;
9148 unsigned char * tp;
9149 Elf_Internal_Sym * sym;
9150 const char * relname;
57346661 9151
57346661
AM
9152 /* First, find the starting address of the segment that includes
9153 this section. */
dda8d76d 9154 if (filedata->file_header.e_phnum)
57346661 9155 {
dda8d76d 9156 if (! get_program_headers (filedata))
015dc7e1 9157 return false;
57346661 9158
dda8d76d
NC
9159 for (seg = filedata->program_headers;
9160 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9161 ++seg)
9162 {
9163 if (seg->p_type != PT_LOAD)
9164 continue;
9165
9166 if (sec->sh_addr >= seg->p_vaddr
9167 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9168 {
9169 aux->seg_base = seg->p_vaddr;
9170 break;
9171 }
9172 }
9173 }
9174
9175 /* Second, build the unwind table from the contents of the unwind
9176 section. */
9177 size = sec->sh_size;
dda8d76d 9178 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9179 _("unwind table"));
57346661 9180 if (!table)
015dc7e1 9181 return false;
57346661 9182
1c0751b2
DA
9183 unw_ent_size = 16;
9184 nentries = size / unw_ent_size;
9185 size = unw_ent_size * nentries;
57346661 9186
e3fdc001 9187 aux->table_len = nentries;
3f5e193b
NC
9188 tep = aux->table = (struct hppa_unw_table_entry *)
9189 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9190
1c0751b2 9191 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9192 {
9193 unsigned int tmp1, tmp2;
9194
9195 tep->start.section = SHN_UNDEF;
9196 tep->end.section = SHN_UNDEF;
9197
1c0751b2
DA
9198 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9199 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9200 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9201 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9202
9203 tep->start.offset += aux->seg_base;
9204 tep->end.offset += aux->seg_base;
57346661
AM
9205
9206 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9207 tep->Millicode = (tmp1 >> 30) & 0x1;
9208 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9209 tep->Region_description = (tmp1 >> 27) & 0x3;
9210 tep->reserved1 = (tmp1 >> 26) & 0x1;
9211 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9212 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9213 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9214 tep->Args_stored = (tmp1 >> 15) & 0x1;
9215 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9216 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9217 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9218 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9219 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9220 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9221 tep->cxx_info = (tmp1 >> 8) & 0x1;
9222 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9223 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9224 tep->reserved2 = (tmp1 >> 5) & 0x1;
9225 tep->Save_SP = (tmp1 >> 4) & 0x1;
9226 tep->Save_RP = (tmp1 >> 3) & 0x1;
9227 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9228 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9229 tep->Cleanup_defined = tmp1 & 0x1;
9230
9231 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9232 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9233 tep->Large_frame = (tmp2 >> 29) & 0x1;
9234 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9235 tep->reserved4 = (tmp2 >> 27) & 0x1;
9236 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9237 }
9238 free (table);
9239
9240 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9241 for (relsec = filedata->section_headers;
9242 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9243 ++relsec)
9244 {
9245 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9246 || relsec->sh_info >= filedata->file_header.e_shnum
9247 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9248 continue;
9249
dda8d76d 9250 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9251 & rela, & nrelas))
015dc7e1 9252 return false;
57346661
AM
9253
9254 for (rp = rela; rp < rela + nrelas; ++rp)
9255 {
4770fb94 9256 unsigned int sym_ndx;
726bd37d
AM
9257 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9258 relname = elf_hppa_reloc_type (r_type);
57346661 9259
726bd37d
AM
9260 if (relname == NULL)
9261 {
9262 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9263 continue;
9264 }
9265
57346661 9266 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9267 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9268 {
726bd37d 9269 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9270 continue;
9271 }
9272
9273 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9274 if (i >= aux->table_len)
9275 {
9276 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9277 continue;
9278 }
57346661 9279
4770fb94
AM
9280 sym_ndx = get_reloc_symindex (rp->r_info);
9281 if (sym_ndx >= aux->nsyms)
9282 {
9283 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9284 sym_ndx);
9285 continue;
9286 }
9287 sym = aux->symtab + sym_ndx;
9288
43f6cd05 9289 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9290 {
9291 case 0:
9292 aux->table[i].start.section = sym->st_shndx;
1e456d54 9293 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9294 break;
9295 case 1:
9296 aux->table[i].end.section = sym->st_shndx;
1e456d54 9297 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9298 break;
9299 default:
9300 break;
9301 }
9302 }
9303
9304 free (rela);
9305 }
9306
015dc7e1 9307 return true;
57346661
AM
9308}
9309
015dc7e1 9310static bool
dda8d76d 9311hppa_process_unwind (Filedata * filedata)
57346661 9312{
57346661 9313 struct hppa_unw_aux_info aux;
2cf0635d 9314 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9315 Elf_Internal_Shdr * sec;
18bd398b 9316 unsigned long i;
015dc7e1 9317 bool res = true;
57346661 9318
dda8d76d 9319 if (filedata->string_table == NULL)
015dc7e1 9320 return false;
1b31d05e
NC
9321
9322 memset (& aux, 0, sizeof (aux));
57346661 9323
dda8d76d 9324 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9325 {
28d13567 9326 if (sec->sh_type == SHT_SYMTAB)
57346661 9327 {
28d13567 9328 if (aux.symtab)
4082ef84 9329 {
28d13567
AM
9330 error (_("Multiple symbol tables encountered\n"));
9331 free (aux.symtab);
9332 aux.symtab = NULL;
4082ef84 9333 free (aux.strtab);
28d13567 9334 aux.strtab = NULL;
4082ef84 9335 }
28d13567
AM
9336 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9337 &aux.strtab, &aux.strtab_size))
015dc7e1 9338 return false;
57346661 9339 }
84714f86
AM
9340 else if (section_name_valid (filedata, sec)
9341 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9342 unwsec = sec;
9343 }
9344
9345 if (!unwsec)
9346 printf (_("\nThere are no unwind sections in this file.\n"));
9347
dda8d76d 9348 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9349 {
84714f86
AM
9350 if (section_name_valid (filedata, sec)
9351 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9352 {
43f6cd05 9353 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9354
d3a49aa8
AM
9355 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9356 "contains %lu entry:\n",
9357 "\nUnwind section '%s' at offset 0x%lx "
9358 "contains %lu entries:\n",
9359 num_unwind),
dda8d76d 9360 printable_section_name (filedata, sec),
57346661 9361 (unsigned long) sec->sh_offset,
d3a49aa8 9362 num_unwind);
57346661 9363
dda8d76d 9364 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9365 res = false;
66b09c7e
S
9366
9367 if (res && aux.table_len > 0)
32ec8896 9368 {
dda8d76d 9369 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9370 res = false;
32ec8896 9371 }
57346661 9372
9db70fc3 9373 free ((char *) aux.table);
57346661
AM
9374 aux.table = NULL;
9375 }
9376 }
9377
9db70fc3
AM
9378 free (aux.symtab);
9379 free ((char *) aux.strtab);
32ec8896
NC
9380
9381 return res;
57346661
AM
9382}
9383
0b6ae522
DJ
9384struct arm_section
9385{
a734115a
NC
9386 unsigned char * data; /* The unwind data. */
9387 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9388 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9389 unsigned long nrelas; /* The number of relocations. */
9390 unsigned int rel_type; /* REL or RELA ? */
9391 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9392};
9393
9394struct arm_unw_aux_info
9395{
dda8d76d 9396 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9397 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9398 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9399 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9400 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9401 char * strtab; /* The file's string table. */
9402 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9403};
9404
9405static const char *
dda8d76d
NC
9406arm_print_vma_and_name (Filedata * filedata,
9407 struct arm_unw_aux_info * aux,
9408 bfd_vma fn,
9409 struct absaddr addr)
0b6ae522
DJ
9410{
9411 const char *procname;
9412 bfd_vma sym_offset;
9413
9414 if (addr.section == SHN_UNDEF)
9415 addr.offset = fn;
9416
dda8d76d 9417 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9418 aux->strtab_size, addr, &procname,
9419 &sym_offset);
9420
9421 print_vma (fn, PREFIX_HEX);
9422
9423 if (procname)
9424 {
9425 fputs (" <", stdout);
9426 fputs (procname, stdout);
9427
9428 if (sym_offset)
9429 printf ("+0x%lx", (unsigned long) sym_offset);
9430 fputc ('>', stdout);
9431 }
9432
9433 return procname;
9434}
9435
9436static void
9437arm_free_section (struct arm_section *arm_sec)
9438{
9db70fc3
AM
9439 free (arm_sec->data);
9440 free (arm_sec->rela);
0b6ae522
DJ
9441}
9442
a734115a
NC
9443/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9444 cached section and install SEC instead.
9445 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9446 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9447 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9448 relocation's offset in ADDR.
1b31d05e
NC
9449 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9450 into the string table of the symbol associated with the reloc. If no
9451 reloc was applied store -1 there.
9452 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9453
015dc7e1 9454static bool
dda8d76d
NC
9455get_unwind_section_word (Filedata * filedata,
9456 struct arm_unw_aux_info * aux,
1b31d05e
NC
9457 struct arm_section * arm_sec,
9458 Elf_Internal_Shdr * sec,
9459 bfd_vma word_offset,
9460 unsigned int * wordp,
9461 struct absaddr * addr,
9462 bfd_vma * sym_name)
0b6ae522
DJ
9463{
9464 Elf_Internal_Rela *rp;
9465 Elf_Internal_Sym *sym;
9466 const char * relname;
9467 unsigned int word;
015dc7e1 9468 bool wrapped;
0b6ae522 9469
e0a31db1 9470 if (sec == NULL || arm_sec == NULL)
015dc7e1 9471 return false;
e0a31db1 9472
0b6ae522
DJ
9473 addr->section = SHN_UNDEF;
9474 addr->offset = 0;
9475
1b31d05e
NC
9476 if (sym_name != NULL)
9477 *sym_name = (bfd_vma) -1;
9478
a734115a 9479 /* If necessary, update the section cache. */
0b6ae522
DJ
9480 if (sec != arm_sec->sec)
9481 {
9482 Elf_Internal_Shdr *relsec;
9483
9484 arm_free_section (arm_sec);
9485
9486 arm_sec->sec = sec;
dda8d76d 9487 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9488 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9489 arm_sec->rela = NULL;
9490 arm_sec->nrelas = 0;
9491
dda8d76d
NC
9492 for (relsec = filedata->section_headers;
9493 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9494 ++relsec)
9495 {
dda8d76d
NC
9496 if (relsec->sh_info >= filedata->file_header.e_shnum
9497 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9498 /* PR 15745: Check the section type as well. */
9499 || (relsec->sh_type != SHT_REL
9500 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9501 continue;
9502
a734115a 9503 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9504 if (relsec->sh_type == SHT_REL)
9505 {
dda8d76d 9506 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9507 relsec->sh_size,
9508 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9509 return false;
0b6ae522 9510 }
1ae40aa4 9511 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9512 {
dda8d76d 9513 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9514 relsec->sh_size,
9515 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9516 return false;
0b6ae522 9517 }
1ae40aa4 9518 break;
0b6ae522
DJ
9519 }
9520
9521 arm_sec->next_rela = arm_sec->rela;
9522 }
9523
a734115a 9524 /* If there is no unwind data we can do nothing. */
0b6ae522 9525 if (arm_sec->data == NULL)
015dc7e1 9526 return false;
0b6ae522 9527
e0a31db1 9528 /* If the offset is invalid then fail. */
f32ba729
NC
9529 if (/* PR 21343 *//* PR 18879 */
9530 sec->sh_size < 4
9531 || word_offset > (sec->sh_size - 4)
1a915552 9532 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9533 return false;
e0a31db1 9534
a734115a 9535 /* Get the word at the required offset. */
0b6ae522
DJ
9536 word = byte_get (arm_sec->data + word_offset, 4);
9537
0eff7165
NC
9538 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9539 if (arm_sec->rela == NULL)
9540 {
9541 * wordp = word;
015dc7e1 9542 return true;
0eff7165
NC
9543 }
9544
a734115a 9545 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9546 wrapped = false;
0b6ae522
DJ
9547 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9548 {
9549 bfd_vma prelval, offset;
9550
9551 if (rp->r_offset > word_offset && !wrapped)
9552 {
9553 rp = arm_sec->rela;
015dc7e1 9554 wrapped = true;
0b6ae522
DJ
9555 }
9556 if (rp->r_offset > word_offset)
9557 break;
9558
9559 if (rp->r_offset & 3)
9560 {
9561 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9562 (unsigned long) rp->r_offset);
9563 continue;
9564 }
9565
9566 if (rp->r_offset < word_offset)
9567 continue;
9568
74e1a04b
NC
9569 /* PR 17531: file: 027-161405-0.004 */
9570 if (aux->symtab == NULL)
9571 continue;
9572
0b6ae522
DJ
9573 if (arm_sec->rel_type == SHT_REL)
9574 {
9575 offset = word & 0x7fffffff;
9576 if (offset & 0x40000000)
9577 offset |= ~ (bfd_vma) 0x7fffffff;
9578 }
a734115a 9579 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9580 offset = rp->r_addend;
a734115a 9581 else
74e1a04b
NC
9582 {
9583 error (_("Unknown section relocation type %d encountered\n"),
9584 arm_sec->rel_type);
9585 break;
9586 }
0b6ae522 9587
071436c6
NC
9588 /* PR 17531 file: 027-1241568-0.004. */
9589 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9590 {
9591 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9592 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9593 break;
9594 }
9595
9596 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9597 offset += sym->st_value;
9598 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9599
a734115a 9600 /* Check that we are processing the expected reloc type. */
dda8d76d 9601 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9602 {
9603 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9604 if (relname == NULL)
9605 {
9606 warn (_("Skipping unknown ARM relocation type: %d\n"),
9607 (int) ELF32_R_TYPE (rp->r_info));
9608 continue;
9609 }
a734115a
NC
9610
9611 if (streq (relname, "R_ARM_NONE"))
9612 continue;
0b4362b0 9613
a734115a
NC
9614 if (! streq (relname, "R_ARM_PREL31"))
9615 {
071436c6 9616 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9617 continue;
9618 }
9619 }
dda8d76d 9620 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9621 {
9622 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9623 if (relname == NULL)
9624 {
9625 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9626 (int) ELF32_R_TYPE (rp->r_info));
9627 continue;
9628 }
0b4362b0 9629
a734115a
NC
9630 if (streq (relname, "R_C6000_NONE"))
9631 continue;
9632
9633 if (! streq (relname, "R_C6000_PREL31"))
9634 {
071436c6 9635 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9636 continue;
9637 }
9638
9639 prelval >>= 1;
9640 }
9641 else
74e1a04b
NC
9642 {
9643 /* This function currently only supports ARM and TI unwinders. */
9644 warn (_("Only TI and ARM unwinders are currently supported\n"));
9645 break;
9646 }
fa197c1c 9647
0b6ae522
DJ
9648 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9649 addr->section = sym->st_shndx;
9650 addr->offset = offset;
74e1a04b 9651
1b31d05e
NC
9652 if (sym_name)
9653 * sym_name = sym->st_name;
0b6ae522
DJ
9654 break;
9655 }
9656
9657 *wordp = word;
9658 arm_sec->next_rela = rp;
9659
015dc7e1 9660 return true;
0b6ae522
DJ
9661}
9662
a734115a
NC
9663static const char *tic6x_unwind_regnames[16] =
9664{
0b4362b0
RM
9665 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9666 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9667 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9668};
fa197c1c 9669
0b6ae522 9670static void
fa197c1c 9671decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9672{
fa197c1c
PB
9673 int i;
9674
9675 for (i = 12; mask; mask >>= 1, i--)
9676 {
9677 if (mask & 1)
9678 {
9679 fputs (tic6x_unwind_regnames[i], stdout);
9680 if (mask > 1)
9681 fputs (", ", stdout);
9682 }
9683 }
9684}
0b6ae522
DJ
9685
9686#define ADVANCE \
9687 if (remaining == 0 && more_words) \
9688 { \
9689 data_offset += 4; \
dda8d76d 9690 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9691 data_offset, & word, & addr, NULL)) \
015dc7e1 9692 return false; \
0b6ae522
DJ
9693 remaining = 4; \
9694 more_words--; \
9695 } \
9696
9697#define GET_OP(OP) \
9698 ADVANCE; \
9699 if (remaining) \
9700 { \
9701 remaining--; \
9702 (OP) = word >> 24; \
9703 word <<= 8; \
9704 } \
9705 else \
9706 { \
2b692964 9707 printf (_("[Truncated opcode]\n")); \
015dc7e1 9708 return false; \
0b6ae522 9709 } \
cc5914eb 9710 printf ("0x%02x ", OP)
0b6ae522 9711
015dc7e1 9712static bool
dda8d76d
NC
9713decode_arm_unwind_bytecode (Filedata * filedata,
9714 struct arm_unw_aux_info * aux,
948f632f
DA
9715 unsigned int word,
9716 unsigned int remaining,
9717 unsigned int more_words,
9718 bfd_vma data_offset,
9719 Elf_Internal_Shdr * data_sec,
9720 struct arm_section * data_arm_sec)
fa197c1c
PB
9721{
9722 struct absaddr addr;
015dc7e1 9723 bool res = true;
0b6ae522
DJ
9724
9725 /* Decode the unwinding instructions. */
9726 while (1)
9727 {
9728 unsigned int op, op2;
9729
9730 ADVANCE;
9731 if (remaining == 0)
9732 break;
9733 remaining--;
9734 op = word >> 24;
9735 word <<= 8;
9736
cc5914eb 9737 printf (" 0x%02x ", op);
0b6ae522
DJ
9738
9739 if ((op & 0xc0) == 0x00)
9740 {
9741 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9742
cc5914eb 9743 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9744 }
9745 else if ((op & 0xc0) == 0x40)
9746 {
9747 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9748
cc5914eb 9749 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9750 }
9751 else if ((op & 0xf0) == 0x80)
9752 {
9753 GET_OP (op2);
9754 if (op == 0x80 && op2 == 0)
9755 printf (_("Refuse to unwind"));
9756 else
9757 {
9758 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9759 bool first = true;
0b6ae522 9760 int i;
2b692964 9761
0b6ae522
DJ
9762 printf ("pop {");
9763 for (i = 0; i < 12; i++)
9764 if (mask & (1 << i))
9765 {
9766 if (first)
015dc7e1 9767 first = false;
0b6ae522
DJ
9768 else
9769 printf (", ");
9770 printf ("r%d", 4 + i);
9771 }
9772 printf ("}");
9773 }
9774 }
9775 else if ((op & 0xf0) == 0x90)
9776 {
9777 if (op == 0x9d || op == 0x9f)
9778 printf (_(" [Reserved]"));
9779 else
cc5914eb 9780 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9781 }
9782 else if ((op & 0xf0) == 0xa0)
9783 {
9784 int end = 4 + (op & 0x07);
015dc7e1 9785 bool first = true;
0b6ae522 9786 int i;
61865e30 9787
0b6ae522
DJ
9788 printf (" pop {");
9789 for (i = 4; i <= end; i++)
9790 {
9791 if (first)
015dc7e1 9792 first = false;
0b6ae522
DJ
9793 else
9794 printf (", ");
9795 printf ("r%d", i);
9796 }
9797 if (op & 0x08)
9798 {
1b31d05e 9799 if (!first)
0b6ae522
DJ
9800 printf (", ");
9801 printf ("r14");
9802 }
9803 printf ("}");
9804 }
9805 else if (op == 0xb0)
9806 printf (_(" finish"));
9807 else if (op == 0xb1)
9808 {
9809 GET_OP (op2);
9810 if (op2 == 0 || (op2 & 0xf0) != 0)
9811 printf (_("[Spare]"));
9812 else
9813 {
9814 unsigned int mask = op2 & 0x0f;
015dc7e1 9815 bool first = true;
0b6ae522 9816 int i;
61865e30 9817
0b6ae522
DJ
9818 printf ("pop {");
9819 for (i = 0; i < 12; i++)
9820 if (mask & (1 << i))
9821 {
9822 if (first)
015dc7e1 9823 first = false;
0b6ae522
DJ
9824 else
9825 printf (", ");
9826 printf ("r%d", i);
9827 }
9828 printf ("}");
9829 }
9830 }
9831 else if (op == 0xb2)
9832 {
b115cf96 9833 unsigned char buf[9];
0b6ae522
DJ
9834 unsigned int i, len;
9835 unsigned long offset;
61865e30 9836
b115cf96 9837 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9838 {
9839 GET_OP (buf[i]);
9840 if ((buf[i] & 0x80) == 0)
9841 break;
9842 }
4082ef84 9843 if (i == sizeof (buf))
32ec8896 9844 {
27a45f42 9845 error (_("corrupt change to vsp\n"));
015dc7e1 9846 res = false;
32ec8896 9847 }
4082ef84
NC
9848 else
9849 {
015dc7e1 9850 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9851 assert (len == i + 1);
9852 offset = offset * 4 + 0x204;
9853 printf ("vsp = vsp + %ld", offset);
9854 }
0b6ae522 9855 }
61865e30 9856 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9857 {
61865e30
NC
9858 unsigned int first, last;
9859
9860 GET_OP (op2);
9861 first = op2 >> 4;
9862 last = op2 & 0x0f;
9863 if (op == 0xc8)
9864 first = first + 16;
9865 printf ("pop {D%d", first);
9866 if (last)
9867 printf ("-D%d", first + last);
9868 printf ("}");
9869 }
09854a88
TB
9870 else if (op == 0xb4)
9871 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9872 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9873 {
9874 unsigned int count = op & 0x07;
9875
9876 printf ("pop {D8");
9877 if (count)
9878 printf ("-D%d", 8 + count);
9879 printf ("}");
9880 }
9881 else if (op >= 0xc0 && op <= 0xc5)
9882 {
9883 unsigned int count = op & 0x07;
9884
9885 printf (" pop {wR10");
9886 if (count)
9887 printf ("-wR%d", 10 + count);
9888 printf ("}");
9889 }
9890 else if (op == 0xc6)
9891 {
9892 unsigned int first, last;
9893
9894 GET_OP (op2);
9895 first = op2 >> 4;
9896 last = op2 & 0x0f;
9897 printf ("pop {wR%d", first);
9898 if (last)
9899 printf ("-wR%d", first + last);
9900 printf ("}");
9901 }
9902 else if (op == 0xc7)
9903 {
9904 GET_OP (op2);
9905 if (op2 == 0 || (op2 & 0xf0) != 0)
9906 printf (_("[Spare]"));
0b6ae522
DJ
9907 else
9908 {
61865e30 9909 unsigned int mask = op2 & 0x0f;
015dc7e1 9910 bool first = true;
61865e30
NC
9911 int i;
9912
9913 printf ("pop {");
9914 for (i = 0; i < 4; i++)
9915 if (mask & (1 << i))
9916 {
9917 if (first)
015dc7e1 9918 first = false;
61865e30
NC
9919 else
9920 printf (", ");
9921 printf ("wCGR%d", i);
9922 }
9923 printf ("}");
0b6ae522
DJ
9924 }
9925 }
61865e30 9926 else
32ec8896
NC
9927 {
9928 printf (_(" [unsupported opcode]"));
015dc7e1 9929 res = false;
32ec8896
NC
9930 }
9931
0b6ae522
DJ
9932 printf ("\n");
9933 }
32ec8896
NC
9934
9935 return res;
fa197c1c
PB
9936}
9937
015dc7e1 9938static bool
dda8d76d
NC
9939decode_tic6x_unwind_bytecode (Filedata * filedata,
9940 struct arm_unw_aux_info * aux,
948f632f
DA
9941 unsigned int word,
9942 unsigned int remaining,
9943 unsigned int more_words,
9944 bfd_vma data_offset,
9945 Elf_Internal_Shdr * data_sec,
9946 struct arm_section * data_arm_sec)
fa197c1c
PB
9947{
9948 struct absaddr addr;
9949
9950 /* Decode the unwinding instructions. */
9951 while (1)
9952 {
9953 unsigned int op, op2;
9954
9955 ADVANCE;
9956 if (remaining == 0)
9957 break;
9958 remaining--;
9959 op = word >> 24;
9960 word <<= 8;
9961
9cf03b7e 9962 printf (" 0x%02x ", op);
fa197c1c
PB
9963
9964 if ((op & 0xc0) == 0x00)
9965 {
9966 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9967 printf (" sp = sp + %d", offset);
fa197c1c
PB
9968 }
9969 else if ((op & 0xc0) == 0x80)
9970 {
9971 GET_OP (op2);
9972 if (op == 0x80 && op2 == 0)
9973 printf (_("Refuse to unwind"));
9974 else
9975 {
9976 unsigned int mask = ((op & 0x1f) << 8) | op2;
9977 if (op & 0x20)
9978 printf ("pop compact {");
9979 else
9980 printf ("pop {");
9981
9982 decode_tic6x_unwind_regmask (mask);
9983 printf("}");
9984 }
9985 }
9986 else if ((op & 0xf0) == 0xc0)
9987 {
9988 unsigned int reg;
9989 unsigned int nregs;
9990 unsigned int i;
9991 const char *name;
a734115a
NC
9992 struct
9993 {
32ec8896
NC
9994 unsigned int offset;
9995 unsigned int reg;
fa197c1c
PB
9996 } regpos[16];
9997
9998 /* Scan entire instruction first so that GET_OP output is not
9999 interleaved with disassembly. */
10000 nregs = 0;
10001 for (i = 0; nregs < (op & 0xf); i++)
10002 {
10003 GET_OP (op2);
10004 reg = op2 >> 4;
10005 if (reg != 0xf)
10006 {
10007 regpos[nregs].offset = i * 2;
10008 regpos[nregs].reg = reg;
10009 nregs++;
10010 }
10011
10012 reg = op2 & 0xf;
10013 if (reg != 0xf)
10014 {
10015 regpos[nregs].offset = i * 2 + 1;
10016 regpos[nregs].reg = reg;
10017 nregs++;
10018 }
10019 }
10020
10021 printf (_("pop frame {"));
18344509 10022 if (nregs == 0)
fa197c1c 10023 {
18344509
NC
10024 printf (_("*corrupt* - no registers specified"));
10025 }
10026 else
10027 {
10028 reg = nregs - 1;
10029 for (i = i * 2; i > 0; i--)
fa197c1c 10030 {
18344509
NC
10031 if (regpos[reg].offset == i - 1)
10032 {
10033 name = tic6x_unwind_regnames[regpos[reg].reg];
10034 if (reg > 0)
10035 reg--;
10036 }
10037 else
10038 name = _("[pad]");
fa197c1c 10039
18344509
NC
10040 fputs (name, stdout);
10041 if (i > 1)
10042 printf (", ");
10043 }
fa197c1c
PB
10044 }
10045
10046 printf ("}");
10047 }
10048 else if (op == 0xd0)
10049 printf (" MOV FP, SP");
10050 else if (op == 0xd1)
10051 printf (" __c6xabi_pop_rts");
10052 else if (op == 0xd2)
10053 {
10054 unsigned char buf[9];
10055 unsigned int i, len;
10056 unsigned long offset;
a734115a 10057
fa197c1c
PB
10058 for (i = 0; i < sizeof (buf); i++)
10059 {
10060 GET_OP (buf[i]);
10061 if ((buf[i] & 0x80) == 0)
10062 break;
10063 }
0eff7165
NC
10064 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10065 if (i == sizeof (buf))
10066 {
0eff7165 10067 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10068 return false;
0eff7165 10069 }
948f632f 10070
015dc7e1 10071 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10072 assert (len == i + 1);
10073 offset = offset * 8 + 0x408;
10074 printf (_("sp = sp + %ld"), offset);
10075 }
10076 else if ((op & 0xf0) == 0xe0)
10077 {
10078 if ((op & 0x0f) == 7)
10079 printf (" RETURN");
10080 else
10081 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10082 }
10083 else
10084 {
10085 printf (_(" [unsupported opcode]"));
10086 }
10087 putchar ('\n');
10088 }
32ec8896 10089
015dc7e1 10090 return true;
fa197c1c
PB
10091}
10092
10093static bfd_vma
dda8d76d 10094arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
10095{
10096 bfd_vma offset;
10097
10098 offset = word & 0x7fffffff;
10099 if (offset & 0x40000000)
10100 offset |= ~ (bfd_vma) 0x7fffffff;
10101
dda8d76d 10102 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10103 offset <<= 1;
10104
10105 return offset + where;
10106}
10107
015dc7e1 10108static bool
dda8d76d
NC
10109decode_arm_unwind (Filedata * filedata,
10110 struct arm_unw_aux_info * aux,
1b31d05e
NC
10111 unsigned int word,
10112 unsigned int remaining,
10113 bfd_vma data_offset,
10114 Elf_Internal_Shdr * data_sec,
10115 struct arm_section * data_arm_sec)
fa197c1c
PB
10116{
10117 int per_index;
10118 unsigned int more_words = 0;
37e14bc3 10119 struct absaddr addr;
1b31d05e 10120 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 10121 bool res = true;
fa197c1c
PB
10122
10123 if (remaining == 0)
10124 {
1b31d05e
NC
10125 /* Fetch the first word.
10126 Note - when decoding an object file the address extracted
10127 here will always be 0. So we also pass in the sym_name
10128 parameter so that we can find the symbol associated with
10129 the personality routine. */
dda8d76d 10130 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10131 & word, & addr, & sym_name))
015dc7e1 10132 return false;
1b31d05e 10133
fa197c1c
PB
10134 remaining = 4;
10135 }
c93dbb25
CZ
10136 else
10137 {
10138 addr.section = SHN_UNDEF;
10139 addr.offset = 0;
10140 }
fa197c1c
PB
10141
10142 if ((word & 0x80000000) == 0)
10143 {
10144 /* Expand prel31 for personality routine. */
10145 bfd_vma fn;
10146 const char *procname;
10147
dda8d76d 10148 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10149 printf (_(" Personality routine: "));
1b31d05e
NC
10150 if (fn == 0
10151 && addr.section == SHN_UNDEF && addr.offset == 0
10152 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10153 {
10154 procname = aux->strtab + sym_name;
10155 print_vma (fn, PREFIX_HEX);
10156 if (procname)
10157 {
10158 fputs (" <", stdout);
10159 fputs (procname, stdout);
10160 fputc ('>', stdout);
10161 }
10162 }
10163 else
dda8d76d 10164 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10165 fputc ('\n', stdout);
10166
10167 /* The GCC personality routines use the standard compact
10168 encoding, starting with one byte giving the number of
10169 words. */
10170 if (procname != NULL
24d127aa
ML
10171 && (startswith (procname, "__gcc_personality_v0")
10172 || startswith (procname, "__gxx_personality_v0")
10173 || startswith (procname, "__gcj_personality_v0")
10174 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10175 {
10176 remaining = 0;
10177 more_words = 1;
10178 ADVANCE;
10179 if (!remaining)
10180 {
10181 printf (_(" [Truncated data]\n"));
015dc7e1 10182 return false;
fa197c1c
PB
10183 }
10184 more_words = word >> 24;
10185 word <<= 8;
10186 remaining--;
10187 per_index = -1;
10188 }
10189 else
015dc7e1 10190 return true;
fa197c1c
PB
10191 }
10192 else
10193 {
1b31d05e 10194 /* ARM EHABI Section 6.3:
0b4362b0 10195
1b31d05e 10196 An exception-handling table entry for the compact model looks like:
0b4362b0 10197
1b31d05e
NC
10198 31 30-28 27-24 23-0
10199 -- ----- ----- ----
10200 1 0 index Data for personalityRoutine[index] */
10201
dda8d76d 10202 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10203 && (word & 0x70000000))
32ec8896
NC
10204 {
10205 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10206 res = false;
32ec8896 10207 }
1b31d05e 10208
fa197c1c 10209 per_index = (word >> 24) & 0x7f;
1b31d05e 10210 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10211 if (per_index == 0)
10212 {
10213 more_words = 0;
10214 word <<= 8;
10215 remaining--;
10216 }
10217 else if (per_index < 3)
10218 {
10219 more_words = (word >> 16) & 0xff;
10220 word <<= 16;
10221 remaining -= 2;
10222 }
10223 }
10224
dda8d76d 10225 switch (filedata->file_header.e_machine)
fa197c1c
PB
10226 {
10227 case EM_ARM:
10228 if (per_index < 3)
10229 {
dda8d76d 10230 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10231 data_offset, data_sec, data_arm_sec))
015dc7e1 10232 res = false;
fa197c1c
PB
10233 }
10234 else
1b31d05e
NC
10235 {
10236 warn (_("Unknown ARM compact model index encountered\n"));
10237 printf (_(" [reserved]\n"));
015dc7e1 10238 res = false;
1b31d05e 10239 }
fa197c1c
PB
10240 break;
10241
10242 case EM_TI_C6000:
10243 if (per_index < 3)
10244 {
dda8d76d 10245 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10246 data_offset, data_sec, data_arm_sec))
015dc7e1 10247 res = false;
fa197c1c
PB
10248 }
10249 else if (per_index < 5)
10250 {
10251 if (((word >> 17) & 0x7f) == 0x7f)
10252 printf (_(" Restore stack from frame pointer\n"));
10253 else
10254 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10255 printf (_(" Registers restored: "));
10256 if (per_index == 4)
10257 printf (" (compact) ");
10258 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10259 putchar ('\n');
10260 printf (_(" Return register: %s\n"),
10261 tic6x_unwind_regnames[word & 0xf]);
10262 }
10263 else
1b31d05e 10264 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10265 break;
10266
10267 default:
74e1a04b 10268 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10269 filedata->file_header.e_machine);
015dc7e1 10270 res = false;
fa197c1c 10271 }
0b6ae522
DJ
10272
10273 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10274
10275 return res;
0b6ae522
DJ
10276}
10277
015dc7e1 10278static bool
dda8d76d
NC
10279dump_arm_unwind (Filedata * filedata,
10280 struct arm_unw_aux_info * aux,
10281 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10282{
10283 struct arm_section exidx_arm_sec, extab_arm_sec;
10284 unsigned int i, exidx_len;
948f632f 10285 unsigned long j, nfuns;
015dc7e1 10286 bool res = true;
0b6ae522
DJ
10287
10288 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10289 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10290 exidx_len = exidx_sec->sh_size / 8;
10291
948f632f
DA
10292 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10293 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10294 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10295 aux->funtab[nfuns++] = aux->symtab[j];
10296 aux->nfuns = nfuns;
10297 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10298
0b6ae522
DJ
10299 for (i = 0; i < exidx_len; i++)
10300 {
10301 unsigned int exidx_fn, exidx_entry;
10302 struct absaddr fn_addr, entry_addr;
10303 bfd_vma fn;
10304
10305 fputc ('\n', stdout);
10306
dda8d76d 10307 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10308 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10309 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10310 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10311 {
948f632f 10312 free (aux->funtab);
1b31d05e
NC
10313 arm_free_section (& exidx_arm_sec);
10314 arm_free_section (& extab_arm_sec);
015dc7e1 10315 return false;
0b6ae522
DJ
10316 }
10317
83c257ca
NC
10318 /* ARM EHABI, Section 5:
10319 An index table entry consists of 2 words.
10320 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10321 if (exidx_fn & 0x80000000)
32ec8896
NC
10322 {
10323 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10324 res = false;
32ec8896 10325 }
83c257ca 10326
dda8d76d 10327 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10328
dda8d76d 10329 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10330 fputs (": ", stdout);
10331
10332 if (exidx_entry == 1)
10333 {
10334 print_vma (exidx_entry, PREFIX_HEX);
10335 fputs (" [cantunwind]\n", stdout);
10336 }
10337 else if (exidx_entry & 0x80000000)
10338 {
10339 print_vma (exidx_entry, PREFIX_HEX);
10340 fputc ('\n', stdout);
dda8d76d 10341 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10342 }
10343 else
10344 {
8f73510c 10345 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10346 Elf_Internal_Shdr *table_sec;
10347
10348 fputs ("@", stdout);
dda8d76d 10349 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10350 print_vma (table, PREFIX_HEX);
10351 printf ("\n");
10352
10353 /* Locate the matching .ARM.extab. */
10354 if (entry_addr.section != SHN_UNDEF
dda8d76d 10355 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10356 {
dda8d76d 10357 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10358 table_offset = entry_addr.offset;
1a915552
NC
10359 /* PR 18879 */
10360 if (table_offset > table_sec->sh_size
10361 || ((bfd_signed_vma) table_offset) < 0)
10362 {
10363 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10364 (unsigned long) table_offset,
dda8d76d 10365 printable_section_name (filedata, table_sec));
015dc7e1 10366 res = false;
1a915552
NC
10367 continue;
10368 }
0b6ae522
DJ
10369 }
10370 else
10371 {
dda8d76d 10372 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10373 if (table_sec != NULL)
10374 table_offset = table - table_sec->sh_addr;
10375 }
32ec8896 10376
0b6ae522
DJ
10377 if (table_sec == NULL)
10378 {
10379 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10380 (unsigned long) table);
015dc7e1 10381 res = false;
0b6ae522
DJ
10382 continue;
10383 }
32ec8896 10384
dda8d76d 10385 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10386 &extab_arm_sec))
015dc7e1 10387 res = false;
0b6ae522
DJ
10388 }
10389 }
10390
10391 printf ("\n");
10392
948f632f 10393 free (aux->funtab);
0b6ae522
DJ
10394 arm_free_section (&exidx_arm_sec);
10395 arm_free_section (&extab_arm_sec);
32ec8896
NC
10396
10397 return res;
0b6ae522
DJ
10398}
10399
fa197c1c 10400/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10401
015dc7e1 10402static bool
dda8d76d 10403arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10404{
10405 struct arm_unw_aux_info aux;
10406 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10407 Elf_Internal_Shdr *sec;
10408 unsigned long i;
fa197c1c 10409 unsigned int sec_type;
015dc7e1 10410 bool res = true;
0b6ae522 10411
dda8d76d 10412 switch (filedata->file_header.e_machine)
fa197c1c
PB
10413 {
10414 case EM_ARM:
10415 sec_type = SHT_ARM_EXIDX;
10416 break;
10417
10418 case EM_TI_C6000:
10419 sec_type = SHT_C6000_UNWIND;
10420 break;
10421
0b4362b0 10422 default:
74e1a04b 10423 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10424 filedata->file_header.e_machine);
015dc7e1 10425 return false;
fa197c1c
PB
10426 }
10427
dda8d76d 10428 if (filedata->string_table == NULL)
015dc7e1 10429 return false;
1b31d05e
NC
10430
10431 memset (& aux, 0, sizeof (aux));
dda8d76d 10432 aux.filedata = filedata;
0b6ae522 10433
dda8d76d 10434 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10435 {
28d13567 10436 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10437 {
28d13567 10438 if (aux.symtab)
74e1a04b 10439 {
28d13567
AM
10440 error (_("Multiple symbol tables encountered\n"));
10441 free (aux.symtab);
10442 aux.symtab = NULL;
74e1a04b 10443 free (aux.strtab);
28d13567 10444 aux.strtab = NULL;
74e1a04b 10445 }
28d13567
AM
10446 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10447 &aux.strtab, &aux.strtab_size))
015dc7e1 10448 return false;
0b6ae522 10449 }
fa197c1c 10450 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10451 unwsec = sec;
10452 }
10453
1b31d05e 10454 if (unwsec == NULL)
0b6ae522 10455 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10456 else
dda8d76d 10457 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10458 {
10459 if (sec->sh_type == sec_type)
10460 {
d3a49aa8
AM
10461 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10462 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10463 "contains %lu entry:\n",
10464 "\nUnwind section '%s' at offset 0x%lx "
10465 "contains %lu entries:\n",
10466 num_unwind),
dda8d76d 10467 printable_section_name (filedata, sec),
1b31d05e 10468 (unsigned long) sec->sh_offset,
d3a49aa8 10469 num_unwind);
0b6ae522 10470
dda8d76d 10471 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10472 res = false;
1b31d05e
NC
10473 }
10474 }
0b6ae522 10475
9db70fc3
AM
10476 free (aux.symtab);
10477 free ((char *) aux.strtab);
32ec8896
NC
10478
10479 return res;
0b6ae522
DJ
10480}
10481
3ecc00ec
NC
10482static bool
10483no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10484{
10485 printf (_("No processor specific unwind information to decode\n"));
10486 return true;
10487}
10488
015dc7e1 10489static bool
dda8d76d 10490process_unwind (Filedata * filedata)
57346661 10491{
2cf0635d
NC
10492 struct unwind_handler
10493 {
32ec8896 10494 unsigned int machtype;
015dc7e1 10495 bool (* handler)(Filedata *);
2cf0635d
NC
10496 } handlers[] =
10497 {
0b6ae522 10498 { EM_ARM, arm_process_unwind },
57346661
AM
10499 { EM_IA_64, ia64_process_unwind },
10500 { EM_PARISC, hppa_process_unwind },
fa197c1c 10501 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10502 { EM_386, no_processor_specific_unwind },
10503 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10504 { 0, NULL }
57346661
AM
10505 };
10506 int i;
10507
10508 if (!do_unwind)
015dc7e1 10509 return true;
57346661
AM
10510
10511 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10512 if (filedata->file_header.e_machine == handlers[i].machtype)
10513 return handlers[i].handler (filedata);
57346661 10514
1b31d05e 10515 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10516 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10517 return true;
57346661
AM
10518}
10519
37c18eed
SD
10520static void
10521dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10522{
10523 switch (entry->d_tag)
10524 {
10525 case DT_AARCH64_BTI_PLT:
1dbade74 10526 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10527 break;
10528 default:
10529 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10530 break;
10531 }
10532 putchar ('\n');
10533}
10534
252b5132 10535static void
978c4450 10536dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10537{
10538 switch (entry->d_tag)
10539 {
10540 case DT_MIPS_FLAGS:
10541 if (entry->d_un.d_val == 0)
4b68bca3 10542 printf (_("NONE"));
252b5132
RH
10543 else
10544 {
10545 static const char * opts[] =
10546 {
10547 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10548 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10549 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10550 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10551 "RLD_ORDER_SAFE"
10552 };
10553 unsigned int cnt;
015dc7e1 10554 bool first = true;
2b692964 10555
60bca95a 10556 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10557 if (entry->d_un.d_val & (1 << cnt))
10558 {
10559 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10560 first = false;
252b5132 10561 }
252b5132
RH
10562 }
10563 break;
103f02d3 10564
252b5132 10565 case DT_MIPS_IVERSION:
84714f86 10566 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10567 printf (_("Interface Version: %s"),
84714f86 10568 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10569 else
f493c217
AM
10570 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
10571 (uint64_t) entry->d_un.d_ptr);
252b5132 10572 break;
103f02d3 10573
252b5132
RH
10574 case DT_MIPS_TIME_STAMP:
10575 {
d5b07ef4 10576 char timebuf[128];
2cf0635d 10577 struct tm * tmp;
91d6fa6a 10578 time_t atime = entry->d_un.d_val;
82b1b41b 10579
91d6fa6a 10580 tmp = gmtime (&atime);
82b1b41b
NC
10581 /* PR 17531: file: 6accc532. */
10582 if (tmp == NULL)
10583 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10584 else
10585 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10586 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10587 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10588 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10589 }
10590 break;
103f02d3 10591
252b5132
RH
10592 case DT_MIPS_RLD_VERSION:
10593 case DT_MIPS_LOCAL_GOTNO:
10594 case DT_MIPS_CONFLICTNO:
10595 case DT_MIPS_LIBLISTNO:
10596 case DT_MIPS_SYMTABNO:
10597 case DT_MIPS_UNREFEXTNO:
10598 case DT_MIPS_HIPAGENO:
10599 case DT_MIPS_DELTA_CLASS_NO:
10600 case DT_MIPS_DELTA_INSTANCE_NO:
10601 case DT_MIPS_DELTA_RELOC_NO:
10602 case DT_MIPS_DELTA_SYM_NO:
10603 case DT_MIPS_DELTA_CLASSSYM_NO:
10604 case DT_MIPS_COMPACT_SIZE:
c69075ac 10605 print_vma (entry->d_un.d_val, DEC);
252b5132 10606 break;
103f02d3 10607
f16a9783 10608 case DT_MIPS_XHASH:
978c4450
AM
10609 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10610 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10611 /* Falls through. */
10612
103f02d3 10613 default:
4b68bca3 10614 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10615 }
4b68bca3 10616 putchar ('\n');
103f02d3
UD
10617}
10618
103f02d3 10619static void
2cf0635d 10620dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10621{
10622 switch (entry->d_tag)
10623 {
10624 case DT_HP_DLD_FLAGS:
10625 {
10626 static struct
10627 {
10628 long int bit;
2cf0635d 10629 const char * str;
5e220199
NC
10630 }
10631 flags[] =
10632 {
10633 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10634 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10635 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10636 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10637 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10638 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10639 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10640 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10641 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10642 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10643 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10644 { DT_HP_GST, "HP_GST" },
10645 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10646 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10647 { DT_HP_NODELETE, "HP_NODELETE" },
10648 { DT_HP_GROUP, "HP_GROUP" },
10649 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10650 };
015dc7e1 10651 bool first = true;
5e220199 10652 size_t cnt;
f7a99963 10653 bfd_vma val = entry->d_un.d_val;
103f02d3 10654
60bca95a 10655 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10656 if (val & flags[cnt].bit)
30800947
NC
10657 {
10658 if (! first)
10659 putchar (' ');
10660 fputs (flags[cnt].str, stdout);
015dc7e1 10661 first = false;
30800947
NC
10662 val ^= flags[cnt].bit;
10663 }
76da6bbe 10664
103f02d3 10665 if (val != 0 || first)
f7a99963
NC
10666 {
10667 if (! first)
10668 putchar (' ');
10669 print_vma (val, HEX);
10670 }
103f02d3
UD
10671 }
10672 break;
76da6bbe 10673
252b5132 10674 default:
f7a99963
NC
10675 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10676 break;
252b5132 10677 }
35b1837e 10678 putchar ('\n');
252b5132
RH
10679}
10680
28f997cf
TG
10681#ifdef BFD64
10682
10683/* VMS vs Unix time offset and factor. */
10684
10685#define VMS_EPOCH_OFFSET 35067168000000000LL
10686#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10687#ifndef INT64_MIN
10688#define INT64_MIN (-9223372036854775807LL - 1)
10689#endif
28f997cf
TG
10690
10691/* Display a VMS time in a human readable format. */
10692
10693static void
0e3c1eeb 10694print_vms_time (int64_t vmstime)
28f997cf 10695{
dccc31de 10696 struct tm *tm = NULL;
28f997cf
TG
10697 time_t unxtime;
10698
dccc31de
AM
10699 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10700 {
10701 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10702 unxtime = vmstime;
10703 if (unxtime == vmstime)
10704 tm = gmtime (&unxtime);
10705 }
10706 if (tm != NULL)
10707 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10708 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10709 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10710}
10711#endif /* BFD64 */
10712
ecc51f48 10713static void
2cf0635d 10714dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10715{
10716 switch (entry->d_tag)
10717 {
0de14b54 10718 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10719 /* First 3 slots reserved. */
ecc51f48
NC
10720 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10721 printf (" -- ");
10722 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10723 break;
10724
28f997cf
TG
10725 case DT_IA_64_VMS_LINKTIME:
10726#ifdef BFD64
10727 print_vms_time (entry->d_un.d_val);
10728#endif
10729 break;
10730
10731 case DT_IA_64_VMS_LNKFLAGS:
10732 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10733 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10734 printf (" CALL_DEBUG");
10735 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10736 printf (" NOP0BUFS");
10737 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10738 printf (" P0IMAGE");
10739 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10740 printf (" MKTHREADS");
10741 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10742 printf (" UPCALLS");
10743 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10744 printf (" IMGSTA");
10745 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10746 printf (" INITIALIZE");
10747 if (entry->d_un.d_val & VMS_LF_MAIN)
10748 printf (" MAIN");
10749 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10750 printf (" EXE_INIT");
10751 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10752 printf (" TBK_IN_IMG");
10753 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10754 printf (" DBG_IN_IMG");
10755 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10756 printf (" TBK_IN_DSF");
10757 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10758 printf (" DBG_IN_DSF");
10759 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10760 printf (" SIGNATURES");
10761 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10762 printf (" REL_SEG_OFF");
10763 break;
10764
bdf4d63a
JJ
10765 default:
10766 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10767 break;
ecc51f48 10768 }
bdf4d63a 10769 putchar ('\n');
ecc51f48
NC
10770}
10771
015dc7e1 10772static bool
dda8d76d 10773get_32bit_dynamic_section (Filedata * filedata)
252b5132 10774{
2cf0635d
NC
10775 Elf32_External_Dyn * edyn;
10776 Elf32_External_Dyn * ext;
10777 Elf_Internal_Dyn * entry;
103f02d3 10778
978c4450
AM
10779 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10780 filedata->dynamic_addr, 1,
10781 filedata->dynamic_size,
10782 _("dynamic section"));
a6e9f9df 10783 if (!edyn)
015dc7e1 10784 return false;
103f02d3 10785
071436c6
NC
10786 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10787 might not have the luxury of section headers. Look for the DT_NULL
10788 terminator to determine the number of entries. */
978c4450
AM
10789 for (ext = edyn, filedata->dynamic_nent = 0;
10790 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10791 ext++)
10792 {
978c4450 10793 filedata->dynamic_nent++;
ba2685cc
AM
10794 if (BYTE_GET (ext->d_tag) == DT_NULL)
10795 break;
10796 }
252b5132 10797
978c4450
AM
10798 filedata->dynamic_section
10799 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10800 if (filedata->dynamic_section == NULL)
252b5132 10801 {
8b73c356 10802 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10803 (unsigned long) filedata->dynamic_nent);
9ea033b2 10804 free (edyn);
015dc7e1 10805 return false;
9ea033b2 10806 }
252b5132 10807
978c4450
AM
10808 for (ext = edyn, entry = filedata->dynamic_section;
10809 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10810 ext++, entry++)
9ea033b2 10811 {
fb514b26
AM
10812 entry->d_tag = BYTE_GET (ext->d_tag);
10813 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10814 }
10815
9ea033b2
NC
10816 free (edyn);
10817
015dc7e1 10818 return true;
9ea033b2
NC
10819}
10820
015dc7e1 10821static bool
dda8d76d 10822get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10823{
2cf0635d
NC
10824 Elf64_External_Dyn * edyn;
10825 Elf64_External_Dyn * ext;
10826 Elf_Internal_Dyn * entry;
103f02d3 10827
071436c6 10828 /* Read in the data. */
978c4450
AM
10829 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10830 filedata->dynamic_addr, 1,
10831 filedata->dynamic_size,
10832 _("dynamic section"));
a6e9f9df 10833 if (!edyn)
015dc7e1 10834 return false;
103f02d3 10835
071436c6
NC
10836 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10837 might not have the luxury of section headers. Look for the DT_NULL
10838 terminator to determine the number of entries. */
978c4450 10839 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10840 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10841 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10842 ext++)
10843 {
978c4450 10844 filedata->dynamic_nent++;
66543521 10845 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10846 break;
10847 }
252b5132 10848
978c4450
AM
10849 filedata->dynamic_section
10850 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10851 if (filedata->dynamic_section == NULL)
252b5132 10852 {
8b73c356 10853 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10854 (unsigned long) filedata->dynamic_nent);
252b5132 10855 free (edyn);
015dc7e1 10856 return false;
252b5132
RH
10857 }
10858
071436c6 10859 /* Convert from external to internal formats. */
978c4450
AM
10860 for (ext = edyn, entry = filedata->dynamic_section;
10861 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10862 ext++, entry++)
252b5132 10863 {
66543521
AM
10864 entry->d_tag = BYTE_GET (ext->d_tag);
10865 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10866 }
10867
10868 free (edyn);
10869
015dc7e1 10870 return true;
9ea033b2
NC
10871}
10872
4de91c10
AM
10873static bool
10874get_dynamic_section (Filedata *filedata)
10875{
10876 if (filedata->dynamic_section)
10877 return true;
10878
10879 if (is_32bit_elf)
10880 return get_32bit_dynamic_section (filedata);
10881 else
10882 return get_64bit_dynamic_section (filedata);
10883}
10884
e9e44622
JJ
10885static void
10886print_dynamic_flags (bfd_vma flags)
d1133906 10887{
015dc7e1 10888 bool first = true;
13ae64f3 10889
d1133906
NC
10890 while (flags)
10891 {
10892 bfd_vma flag;
10893
10894 flag = flags & - flags;
10895 flags &= ~ flag;
10896
e9e44622 10897 if (first)
015dc7e1 10898 first = false;
e9e44622
JJ
10899 else
10900 putc (' ', stdout);
13ae64f3 10901
d1133906
NC
10902 switch (flag)
10903 {
e9e44622
JJ
10904 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10905 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10906 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10907 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10908 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10909 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10910 }
10911 }
e9e44622 10912 puts ("");
d1133906
NC
10913}
10914
10ca4b04 10915static bfd_vma *
be7d229a 10916get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10917{
10918 unsigned char * e_data;
10919 bfd_vma * i_data;
10920
be7d229a
AM
10921 /* If size_t is smaller than uint64_t, eg because you are building
10922 on a 32-bit host, then make sure that when number is cast to
10923 size_t no information is lost. */
10924 if ((size_t) number != number
10925 || ent_size * number / ent_size != number)
10ca4b04 10926 {
be7d229a 10927 error (_("Size overflow prevents reading %" PRIu64
b8281767 10928 " elements of size %u\n"),
be7d229a 10929 number, ent_size);
10ca4b04
L
10930 return NULL;
10931 }
10932
10933 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10934 attempting to allocate memory when the read is bound to fail. */
10935 if (ent_size * number > filedata->file_size)
10936 {
b8281767 10937 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10938 number);
10ca4b04
L
10939 return NULL;
10940 }
10941
10942 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10943 if (e_data == NULL)
10944 {
b8281767 10945 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10946 number);
10ca4b04
L
10947 return NULL;
10948 }
10949
10950 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10951 {
b8281767 10952 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10953 number * ent_size);
10ca4b04
L
10954 free (e_data);
10955 return NULL;
10956 }
10957
10958 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10959 if (i_data == NULL)
10960 {
b8281767 10961 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 10962 number);
10ca4b04
L
10963 free (e_data);
10964 return NULL;
10965 }
10966
10967 while (number--)
10968 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10969
10970 free (e_data);
10971
10972 return i_data;
10973}
10974
10975static unsigned long
10976get_num_dynamic_syms (Filedata * filedata)
10977{
10978 unsigned long num_of_syms = 0;
10979
10980 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10981 return num_of_syms;
10982
978c4450 10983 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10984 {
10985 unsigned char nb[8];
10986 unsigned char nc[8];
10987 unsigned int hash_ent_size = 4;
10988
10989 if ((filedata->file_header.e_machine == EM_ALPHA
10990 || filedata->file_header.e_machine == EM_S390
10991 || filedata->file_header.e_machine == EM_S390_OLD)
10992 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10993 hash_ent_size = 8;
10994
10995 if (fseek (filedata->handle,
978c4450
AM
10996 (filedata->archive_file_offset
10997 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10998 sizeof nb + sizeof nc)),
10999 SEEK_SET))
11000 {
11001 error (_("Unable to seek to start of dynamic information\n"));
11002 goto no_hash;
11003 }
11004
11005 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11006 {
11007 error (_("Failed to read in number of buckets\n"));
11008 goto no_hash;
11009 }
11010
11011 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11012 {
11013 error (_("Failed to read in number of chains\n"));
11014 goto no_hash;
11015 }
11016
978c4450
AM
11017 filedata->nbuckets = byte_get (nb, hash_ent_size);
11018 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11019
2482f306
AM
11020 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11021 {
11022 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11023 hash_ent_size);
11024 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11025 hash_ent_size);
001890e1 11026
2482f306
AM
11027 if (filedata->buckets != NULL && filedata->chains != NULL)
11028 num_of_syms = filedata->nchains;
11029 }
ceb9bf11 11030 no_hash:
10ca4b04
L
11031 if (num_of_syms == 0)
11032 {
9db70fc3
AM
11033 free (filedata->buckets);
11034 filedata->buckets = NULL;
11035 free (filedata->chains);
11036 filedata->chains = NULL;
978c4450 11037 filedata->nbuckets = 0;
10ca4b04
L
11038 }
11039 }
11040
978c4450 11041 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11042 {
11043 unsigned char nb[16];
11044 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11045 bfd_vma buckets_vma;
11046 unsigned long hn;
10ca4b04
L
11047
11048 if (fseek (filedata->handle,
978c4450
AM
11049 (filedata->archive_file_offset
11050 + offset_from_vma (filedata,
11051 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11052 sizeof nb)),
11053 SEEK_SET))
11054 {
11055 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11056 goto no_gnu_hash;
11057 }
11058
11059 if (fread (nb, 16, 1, filedata->handle) != 1)
11060 {
11061 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11062 goto no_gnu_hash;
11063 }
11064
978c4450
AM
11065 filedata->ngnubuckets = byte_get (nb, 4);
11066 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11067 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11068 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11069 if (is_32bit_elf)
11070 buckets_vma += bitmaskwords * 4;
11071 else
11072 buckets_vma += bitmaskwords * 8;
11073
11074 if (fseek (filedata->handle,
978c4450 11075 (filedata->archive_file_offset
10ca4b04
L
11076 + offset_from_vma (filedata, buckets_vma, 4)),
11077 SEEK_SET))
11078 {
11079 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11080 goto no_gnu_hash;
11081 }
11082
978c4450
AM
11083 filedata->gnubuckets
11084 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11085
978c4450 11086 if (filedata->gnubuckets == NULL)
90837ea7 11087 goto no_gnu_hash;
10ca4b04 11088
978c4450
AM
11089 for (i = 0; i < filedata->ngnubuckets; i++)
11090 if (filedata->gnubuckets[i] != 0)
10ca4b04 11091 {
978c4450 11092 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11093 goto no_gnu_hash;
10ca4b04 11094
978c4450
AM
11095 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11096 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11097 }
11098
11099 if (maxchain == 0xffffffff)
90837ea7 11100 goto no_gnu_hash;
10ca4b04 11101
978c4450 11102 maxchain -= filedata->gnusymidx;
10ca4b04
L
11103
11104 if (fseek (filedata->handle,
978c4450
AM
11105 (filedata->archive_file_offset
11106 + offset_from_vma (filedata,
11107 buckets_vma + 4 * (filedata->ngnubuckets
11108 + maxchain),
11109 4)),
10ca4b04
L
11110 SEEK_SET))
11111 {
11112 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11113 goto no_gnu_hash;
11114 }
11115
11116 do
11117 {
11118 if (fread (nb, 4, 1, filedata->handle) != 1)
11119 {
11120 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11121 goto no_gnu_hash;
11122 }
11123
11124 if (maxchain + 1 == 0)
90837ea7 11125 goto no_gnu_hash;
10ca4b04
L
11126
11127 ++maxchain;
11128 }
11129 while ((byte_get (nb, 4) & 1) == 0);
11130
11131 if (fseek (filedata->handle,
978c4450
AM
11132 (filedata->archive_file_offset
11133 + offset_from_vma (filedata, (buckets_vma
11134 + 4 * filedata->ngnubuckets),
11135 4)),
10ca4b04
L
11136 SEEK_SET))
11137 {
11138 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11139 goto no_gnu_hash;
11140 }
11141
978c4450
AM
11142 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11143 filedata->ngnuchains = maxchain;
10ca4b04 11144
978c4450 11145 if (filedata->gnuchains == NULL)
90837ea7 11146 goto no_gnu_hash;
10ca4b04 11147
978c4450 11148 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11149 {
11150 if (fseek (filedata->handle,
978c4450 11151 (filedata->archive_file_offset
10ca4b04 11152 + offset_from_vma (filedata, (buckets_vma
978c4450 11153 + 4 * (filedata->ngnubuckets
10ca4b04
L
11154 + maxchain)), 4)),
11155 SEEK_SET))
11156 {
11157 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11158 goto no_gnu_hash;
11159 }
11160
978c4450 11161 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11162 if (filedata->mipsxlat == NULL)
11163 goto no_gnu_hash;
10ca4b04
L
11164 }
11165
978c4450
AM
11166 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11167 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11168 {
978c4450
AM
11169 bfd_vma si = filedata->gnubuckets[hn];
11170 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11171
11172 do
11173 {
978c4450 11174 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11175 {
c31ab5a0
AM
11176 if (off < filedata->ngnuchains
11177 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11178 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11179 }
11180 else
11181 {
11182 if (si >= num_of_syms)
11183 num_of_syms = si + 1;
11184 }
11185 si++;
11186 }
978c4450
AM
11187 while (off < filedata->ngnuchains
11188 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11189 }
11190
90837ea7 11191 if (num_of_syms == 0)
10ca4b04 11192 {
90837ea7 11193 no_gnu_hash:
9db70fc3
AM
11194 free (filedata->mipsxlat);
11195 filedata->mipsxlat = NULL;
11196 free (filedata->gnuchains);
11197 filedata->gnuchains = NULL;
11198 free (filedata->gnubuckets);
11199 filedata->gnubuckets = NULL;
978c4450
AM
11200 filedata->ngnubuckets = 0;
11201 filedata->ngnuchains = 0;
10ca4b04
L
11202 }
11203 }
11204
11205 return num_of_syms;
11206}
11207
b2d38a17
NC
11208/* Parse and display the contents of the dynamic section. */
11209
015dc7e1 11210static bool
dda8d76d 11211process_dynamic_section (Filedata * filedata)
9ea033b2 11212{
2cf0635d 11213 Elf_Internal_Dyn * entry;
9ea033b2 11214
93df3340 11215 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11216 {
11217 if (do_dynamic)
ca0e11aa
NC
11218 {
11219 if (filedata->is_separate)
11220 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11221 filedata->file_name);
11222 else
11223 printf (_("\nThere is no dynamic section in this file.\n"));
11224 }
9ea033b2 11225
015dc7e1 11226 return true;
9ea033b2
NC
11227 }
11228
4de91c10
AM
11229 if (!get_dynamic_section (filedata))
11230 return false;
9ea033b2 11231
252b5132 11232 /* Find the appropriate symbol table. */
978c4450 11233 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11234 {
2482f306
AM
11235 unsigned long num_of_syms;
11236
978c4450
AM
11237 for (entry = filedata->dynamic_section;
11238 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11239 ++entry)
10ca4b04 11240 if (entry->d_tag == DT_SYMTAB)
978c4450 11241 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11242 else if (entry->d_tag == DT_SYMENT)
978c4450 11243 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11244 else if (entry->d_tag == DT_HASH)
978c4450 11245 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11246 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11247 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11248 else if ((filedata->file_header.e_machine == EM_MIPS
11249 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11250 && entry->d_tag == DT_MIPS_XHASH)
11251 {
978c4450
AM
11252 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11253 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11254 }
252b5132 11255
2482f306
AM
11256 num_of_syms = get_num_dynamic_syms (filedata);
11257
11258 if (num_of_syms != 0
11259 && filedata->dynamic_symbols == NULL
11260 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11261 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11262 {
11263 Elf_Internal_Phdr *seg;
2482f306 11264 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11265
2482f306
AM
11266 if (! get_program_headers (filedata))
11267 {
11268 error (_("Cannot interpret virtual addresses "
11269 "without program headers.\n"));
015dc7e1 11270 return false;
2482f306 11271 }
252b5132 11272
2482f306
AM
11273 for (seg = filedata->program_headers;
11274 seg < filedata->program_headers + filedata->file_header.e_phnum;
11275 ++seg)
11276 {
11277 if (seg->p_type != PT_LOAD)
11278 continue;
252b5132 11279
2482f306
AM
11280 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11281 {
11282 /* See PR 21379 for a reproducer. */
11283 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11284 return false;
2482f306 11285 }
252b5132 11286
2482f306
AM
11287 if (vma >= (seg->p_vaddr & -seg->p_align)
11288 && vma < seg->p_vaddr + seg->p_filesz)
11289 {
11290 /* Since we do not know how big the symbol table is,
11291 we default to reading in up to the end of PT_LOAD
11292 segment and processing that. This is overkill, I
11293 know, but it should work. */
11294 Elf_Internal_Shdr section;
11295 section.sh_offset = (vma - seg->p_vaddr
11296 + seg->p_offset);
11297 section.sh_size = (num_of_syms
11298 * filedata->dynamic_info[DT_SYMENT]);
11299 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11300
11301 if (do_checks
11302 && filedata->dynamic_symtab_section != NULL
11303 && ((filedata->dynamic_symtab_section->sh_offset
11304 != section.sh_offset)
11305 || (filedata->dynamic_symtab_section->sh_size
11306 != section.sh_size)
11307 || (filedata->dynamic_symtab_section->sh_entsize
11308 != section.sh_entsize)))
11309 warn (_("\
11310the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11311
2482f306
AM
11312 section.sh_name = filedata->string_table_length;
11313 filedata->dynamic_symbols
4de91c10 11314 = get_elf_symbols (filedata, &section,
2482f306
AM
11315 &filedata->num_dynamic_syms);
11316 if (filedata->dynamic_symbols == NULL
11317 || filedata->num_dynamic_syms != num_of_syms)
11318 {
11319 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11320 return false;
2482f306
AM
11321 }
11322 break;
11323 }
11324 }
11325 }
11326 }
252b5132
RH
11327
11328 /* Similarly find a string table. */
978c4450
AM
11329 if (filedata->dynamic_strings == NULL)
11330 for (entry = filedata->dynamic_section;
11331 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11332 ++entry)
11333 {
11334 if (entry->d_tag == DT_STRTAB)
978c4450 11335 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11336
10ca4b04 11337 if (entry->d_tag == DT_STRSZ)
978c4450 11338 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11339
978c4450
AM
11340 if (filedata->dynamic_info[DT_STRTAB]
11341 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11342 {
11343 unsigned long offset;
be7d229a 11344 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11345
11346 offset = offset_from_vma (filedata,
978c4450 11347 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11348 str_tab_len);
8ac10c5b
L
11349 if (do_checks
11350 && filedata->dynamic_strtab_section
11351 && ((filedata->dynamic_strtab_section->sh_offset
11352 != (file_ptr) offset)
11353 || (filedata->dynamic_strtab_section->sh_size
11354 != str_tab_len)))
11355 warn (_("\
11356the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11357
978c4450
AM
11358 filedata->dynamic_strings
11359 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11360 _("dynamic string table"));
11361 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11362 {
11363 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11364 break;
11365 }
e3d39609 11366
978c4450 11367 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11368 break;
11369 }
11370 }
252b5132
RH
11371
11372 /* And find the syminfo section if available. */
978c4450 11373 if (filedata->dynamic_syminfo == NULL)
252b5132 11374 {
3e8bba36 11375 unsigned long syminsz = 0;
252b5132 11376
978c4450
AM
11377 for (entry = filedata->dynamic_section;
11378 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11379 ++entry)
252b5132
RH
11380 {
11381 if (entry->d_tag == DT_SYMINENT)
11382 {
11383 /* Note: these braces are necessary to avoid a syntax
11384 error from the SunOS4 C compiler. */
049b0c3a
NC
11385 /* PR binutils/17531: A corrupt file can trigger this test.
11386 So do not use an assert, instead generate an error message. */
11387 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11388 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11389 (int) entry->d_un.d_val);
252b5132
RH
11390 }
11391 else if (entry->d_tag == DT_SYMINSZ)
11392 syminsz = entry->d_un.d_val;
11393 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11394 filedata->dynamic_syminfo_offset
11395 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11396 }
11397
978c4450 11398 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11399 {
2cf0635d
NC
11400 Elf_External_Syminfo * extsyminfo;
11401 Elf_External_Syminfo * extsym;
11402 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11403
11404 /* There is a syminfo section. Read the data. */
3f5e193b 11405 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11406 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11407 1, syminsz, _("symbol information"));
a6e9f9df 11408 if (!extsyminfo)
015dc7e1 11409 return false;
252b5132 11410
978c4450 11411 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11412 {
11413 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11414 free (filedata->dynamic_syminfo);
e3d39609 11415 }
978c4450
AM
11416 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11417 if (filedata->dynamic_syminfo == NULL)
252b5132 11418 {
2482f306
AM
11419 error (_("Out of memory allocating %lu bytes "
11420 "for dynamic symbol info\n"),
8b73c356 11421 (unsigned long) syminsz);
015dc7e1 11422 return false;
252b5132
RH
11423 }
11424
2482f306
AM
11425 filedata->dynamic_syminfo_nent
11426 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11427 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11428 syminfo < (filedata->dynamic_syminfo
11429 + filedata->dynamic_syminfo_nent);
86dba8ee 11430 ++syminfo, ++extsym)
252b5132 11431 {
86dba8ee
AM
11432 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11433 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11434 }
11435
11436 free (extsyminfo);
11437 }
11438 }
11439
978c4450 11440 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11441 {
f253158f
NC
11442 if (filedata->is_separate)
11443 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11444 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11445 (unsigned long) filedata->dynamic_nent),
11446 filedata->file_name,
11447 filedata->dynamic_addr,
11448 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11449 else
11450 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11451 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11452 (unsigned long) filedata->dynamic_nent),
11453 filedata->dynamic_addr,
11454 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11455 }
252b5132
RH
11456 if (do_dynamic)
11457 printf (_(" Tag Type Name/Value\n"));
11458
978c4450
AM
11459 for (entry = filedata->dynamic_section;
11460 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11461 entry++)
252b5132
RH
11462 {
11463 if (do_dynamic)
f7a99963 11464 {
2cf0635d 11465 const char * dtype;
e699b9ff 11466
f7a99963
NC
11467 putchar (' ');
11468 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11469 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11470 printf (" (%s)%*s", dtype,
32ec8896 11471 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11472 }
252b5132
RH
11473
11474 switch (entry->d_tag)
11475 {
d1133906
NC
11476 case DT_FLAGS:
11477 if (do_dynamic)
e9e44622 11478 print_dynamic_flags (entry->d_un.d_val);
d1133906 11479 break;
76da6bbe 11480
252b5132
RH
11481 case DT_AUXILIARY:
11482 case DT_FILTER:
019148e4
L
11483 case DT_CONFIG:
11484 case DT_DEPAUDIT:
11485 case DT_AUDIT:
252b5132
RH
11486 if (do_dynamic)
11487 {
019148e4 11488 switch (entry->d_tag)
b34976b6 11489 {
019148e4
L
11490 case DT_AUXILIARY:
11491 printf (_("Auxiliary library"));
11492 break;
11493
11494 case DT_FILTER:
11495 printf (_("Filter library"));
11496 break;
11497
b34976b6 11498 case DT_CONFIG:
019148e4
L
11499 printf (_("Configuration file"));
11500 break;
11501
11502 case DT_DEPAUDIT:
11503 printf (_("Dependency audit library"));
11504 break;
11505
11506 case DT_AUDIT:
11507 printf (_("Audit library"));
11508 break;
11509 }
252b5132 11510
84714f86 11511 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11512 printf (": [%s]\n",
84714f86 11513 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11514 else
f7a99963
NC
11515 {
11516 printf (": ");
11517 print_vma (entry->d_un.d_val, PREFIX_HEX);
11518 putchar ('\n');
11519 }
252b5132
RH
11520 }
11521 break;
11522
dcefbbbd 11523 case DT_FEATURE:
252b5132
RH
11524 if (do_dynamic)
11525 {
11526 printf (_("Flags:"));
86f55779 11527
252b5132
RH
11528 if (entry->d_un.d_val == 0)
11529 printf (_(" None\n"));
11530 else
11531 {
11532 unsigned long int val = entry->d_un.d_val;
86f55779 11533
252b5132
RH
11534 if (val & DTF_1_PARINIT)
11535 {
11536 printf (" PARINIT");
11537 val ^= DTF_1_PARINIT;
11538 }
dcefbbbd
L
11539 if (val & DTF_1_CONFEXP)
11540 {
11541 printf (" CONFEXP");
11542 val ^= DTF_1_CONFEXP;
11543 }
252b5132
RH
11544 if (val != 0)
11545 printf (" %lx", val);
11546 puts ("");
11547 }
11548 }
11549 break;
11550
11551 case DT_POSFLAG_1:
11552 if (do_dynamic)
11553 {
11554 printf (_("Flags:"));
86f55779 11555
252b5132
RH
11556 if (entry->d_un.d_val == 0)
11557 printf (_(" None\n"));
11558 else
11559 {
11560 unsigned long int val = entry->d_un.d_val;
86f55779 11561
252b5132
RH
11562 if (val & DF_P1_LAZYLOAD)
11563 {
11564 printf (" LAZYLOAD");
11565 val ^= DF_P1_LAZYLOAD;
11566 }
11567 if (val & DF_P1_GROUPPERM)
11568 {
11569 printf (" GROUPPERM");
11570 val ^= DF_P1_GROUPPERM;
11571 }
11572 if (val != 0)
11573 printf (" %lx", val);
11574 puts ("");
11575 }
11576 }
11577 break;
11578
11579 case DT_FLAGS_1:
11580 if (do_dynamic)
11581 {
11582 printf (_("Flags:"));
11583 if (entry->d_un.d_val == 0)
11584 printf (_(" None\n"));
11585 else
11586 {
11587 unsigned long int val = entry->d_un.d_val;
86f55779 11588
252b5132
RH
11589 if (val & DF_1_NOW)
11590 {
11591 printf (" NOW");
11592 val ^= DF_1_NOW;
11593 }
11594 if (val & DF_1_GLOBAL)
11595 {
11596 printf (" GLOBAL");
11597 val ^= DF_1_GLOBAL;
11598 }
11599 if (val & DF_1_GROUP)
11600 {
11601 printf (" GROUP");
11602 val ^= DF_1_GROUP;
11603 }
11604 if (val & DF_1_NODELETE)
11605 {
11606 printf (" NODELETE");
11607 val ^= DF_1_NODELETE;
11608 }
11609 if (val & DF_1_LOADFLTR)
11610 {
11611 printf (" LOADFLTR");
11612 val ^= DF_1_LOADFLTR;
11613 }
11614 if (val & DF_1_INITFIRST)
11615 {
11616 printf (" INITFIRST");
11617 val ^= DF_1_INITFIRST;
11618 }
11619 if (val & DF_1_NOOPEN)
11620 {
11621 printf (" NOOPEN");
11622 val ^= DF_1_NOOPEN;
11623 }
11624 if (val & DF_1_ORIGIN)
11625 {
11626 printf (" ORIGIN");
11627 val ^= DF_1_ORIGIN;
11628 }
11629 if (val & DF_1_DIRECT)
11630 {
11631 printf (" DIRECT");
11632 val ^= DF_1_DIRECT;
11633 }
11634 if (val & DF_1_TRANS)
11635 {
11636 printf (" TRANS");
11637 val ^= DF_1_TRANS;
11638 }
11639 if (val & DF_1_INTERPOSE)
11640 {
11641 printf (" INTERPOSE");
11642 val ^= DF_1_INTERPOSE;
11643 }
f7db6139 11644 if (val & DF_1_NODEFLIB)
dcefbbbd 11645 {
f7db6139
L
11646 printf (" NODEFLIB");
11647 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11648 }
11649 if (val & DF_1_NODUMP)
11650 {
11651 printf (" NODUMP");
11652 val ^= DF_1_NODUMP;
11653 }
34b60028 11654 if (val & DF_1_CONFALT)
dcefbbbd 11655 {
34b60028
L
11656 printf (" CONFALT");
11657 val ^= DF_1_CONFALT;
11658 }
11659 if (val & DF_1_ENDFILTEE)
11660 {
11661 printf (" ENDFILTEE");
11662 val ^= DF_1_ENDFILTEE;
11663 }
11664 if (val & DF_1_DISPRELDNE)
11665 {
11666 printf (" DISPRELDNE");
11667 val ^= DF_1_DISPRELDNE;
11668 }
11669 if (val & DF_1_DISPRELPND)
11670 {
11671 printf (" DISPRELPND");
11672 val ^= DF_1_DISPRELPND;
11673 }
11674 if (val & DF_1_NODIRECT)
11675 {
11676 printf (" NODIRECT");
11677 val ^= DF_1_NODIRECT;
11678 }
11679 if (val & DF_1_IGNMULDEF)
11680 {
11681 printf (" IGNMULDEF");
11682 val ^= DF_1_IGNMULDEF;
11683 }
11684 if (val & DF_1_NOKSYMS)
11685 {
11686 printf (" NOKSYMS");
11687 val ^= DF_1_NOKSYMS;
11688 }
11689 if (val & DF_1_NOHDR)
11690 {
11691 printf (" NOHDR");
11692 val ^= DF_1_NOHDR;
11693 }
11694 if (val & DF_1_EDITED)
11695 {
11696 printf (" EDITED");
11697 val ^= DF_1_EDITED;
11698 }
11699 if (val & DF_1_NORELOC)
11700 {
11701 printf (" NORELOC");
11702 val ^= DF_1_NORELOC;
11703 }
11704 if (val & DF_1_SYMINTPOSE)
11705 {
11706 printf (" SYMINTPOSE");
11707 val ^= DF_1_SYMINTPOSE;
11708 }
11709 if (val & DF_1_GLOBAUDIT)
11710 {
11711 printf (" GLOBAUDIT");
11712 val ^= DF_1_GLOBAUDIT;
11713 }
11714 if (val & DF_1_SINGLETON)
11715 {
11716 printf (" SINGLETON");
11717 val ^= DF_1_SINGLETON;
dcefbbbd 11718 }
5c383f02
RO
11719 if (val & DF_1_STUB)
11720 {
11721 printf (" STUB");
11722 val ^= DF_1_STUB;
11723 }
11724 if (val & DF_1_PIE)
11725 {
11726 printf (" PIE");
11727 val ^= DF_1_PIE;
11728 }
b1202ffa
L
11729 if (val & DF_1_KMOD)
11730 {
11731 printf (" KMOD");
11732 val ^= DF_1_KMOD;
11733 }
11734 if (val & DF_1_WEAKFILTER)
11735 {
11736 printf (" WEAKFILTER");
11737 val ^= DF_1_WEAKFILTER;
11738 }
11739 if (val & DF_1_NOCOMMON)
11740 {
11741 printf (" NOCOMMON");
11742 val ^= DF_1_NOCOMMON;
11743 }
252b5132
RH
11744 if (val != 0)
11745 printf (" %lx", val);
11746 puts ("");
11747 }
11748 }
11749 break;
11750
11751 case DT_PLTREL:
978c4450 11752 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11753 if (do_dynamic)
dda8d76d 11754 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11755 break;
11756
11757 case DT_NULL :
11758 case DT_NEEDED :
11759 case DT_PLTGOT :
11760 case DT_HASH :
11761 case DT_STRTAB :
11762 case DT_SYMTAB :
11763 case DT_RELA :
11764 case DT_INIT :
11765 case DT_FINI :
11766 case DT_SONAME :
11767 case DT_RPATH :
11768 case DT_SYMBOLIC:
11769 case DT_REL :
a7fd1186 11770 case DT_RELR :
252b5132
RH
11771 case DT_DEBUG :
11772 case DT_TEXTREL :
11773 case DT_JMPREL :
019148e4 11774 case DT_RUNPATH :
978c4450 11775 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11776
11777 if (do_dynamic)
11778 {
84714f86 11779 const char *name;
252b5132 11780
84714f86
AM
11781 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11782 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11783 else
d79b3d50 11784 name = NULL;
252b5132
RH
11785
11786 if (name)
11787 {
11788 switch (entry->d_tag)
11789 {
11790 case DT_NEEDED:
11791 printf (_("Shared library: [%s]"), name);
11792
13acb58d
AM
11793 if (filedata->program_interpreter
11794 && streq (name, filedata->program_interpreter))
f7a99963 11795 printf (_(" program interpreter"));
252b5132
RH
11796 break;
11797
11798 case DT_SONAME:
f7a99963 11799 printf (_("Library soname: [%s]"), name);
252b5132
RH
11800 break;
11801
11802 case DT_RPATH:
f7a99963 11803 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11804 break;
11805
019148e4
L
11806 case DT_RUNPATH:
11807 printf (_("Library runpath: [%s]"), name);
11808 break;
11809
252b5132 11810 default:
f7a99963
NC
11811 print_vma (entry->d_un.d_val, PREFIX_HEX);
11812 break;
252b5132
RH
11813 }
11814 }
11815 else
f7a99963
NC
11816 print_vma (entry->d_un.d_val, PREFIX_HEX);
11817
11818 putchar ('\n');
252b5132
RH
11819 }
11820 break;
11821
11822 case DT_PLTRELSZ:
11823 case DT_RELASZ :
11824 case DT_STRSZ :
11825 case DT_RELSZ :
11826 case DT_RELAENT :
a7fd1186
FS
11827 case DT_RELRENT :
11828 case DT_RELRSZ :
252b5132
RH
11829 case DT_SYMENT :
11830 case DT_RELENT :
978c4450 11831 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11832 /* Fall through. */
252b5132
RH
11833 case DT_PLTPADSZ:
11834 case DT_MOVEENT :
11835 case DT_MOVESZ :
04d8355a 11836 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11837 case DT_INIT_ARRAYSZ:
11838 case DT_FINI_ARRAYSZ:
047b2264
JJ
11839 case DT_GNU_CONFLICTSZ:
11840 case DT_GNU_LIBLISTSZ:
252b5132 11841 if (do_dynamic)
f7a99963
NC
11842 {
11843 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11844 printf (_(" (bytes)\n"));
f7a99963 11845 }
252b5132
RH
11846 break;
11847
11848 case DT_VERDEFNUM:
11849 case DT_VERNEEDNUM:
11850 case DT_RELACOUNT:
11851 case DT_RELCOUNT:
11852 if (do_dynamic)
f7a99963
NC
11853 {
11854 print_vma (entry->d_un.d_val, UNSIGNED);
11855 putchar ('\n');
11856 }
252b5132
RH
11857 break;
11858
11859 case DT_SYMINSZ:
11860 case DT_SYMINENT:
11861 case DT_SYMINFO:
11862 case DT_USED:
11863 case DT_INIT_ARRAY:
11864 case DT_FINI_ARRAY:
11865 if (do_dynamic)
11866 {
d79b3d50 11867 if (entry->d_tag == DT_USED
84714f86 11868 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11869 {
84714f86
AM
11870 const char *name
11871 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11872
b34976b6 11873 if (*name)
252b5132
RH
11874 {
11875 printf (_("Not needed object: [%s]\n"), name);
11876 break;
11877 }
11878 }
103f02d3 11879
f7a99963
NC
11880 print_vma (entry->d_un.d_val, PREFIX_HEX);
11881 putchar ('\n');
252b5132
RH
11882 }
11883 break;
11884
11885 case DT_BIND_NOW:
11886 /* The value of this entry is ignored. */
35b1837e
AM
11887 if (do_dynamic)
11888 putchar ('\n');
252b5132 11889 break;
103f02d3 11890
047b2264
JJ
11891 case DT_GNU_PRELINKED:
11892 if (do_dynamic)
11893 {
2cf0635d 11894 struct tm * tmp;
91d6fa6a 11895 time_t atime = entry->d_un.d_val;
047b2264 11896
91d6fa6a 11897 tmp = gmtime (&atime);
071436c6
NC
11898 /* PR 17533 file: 041-1244816-0.004. */
11899 if (tmp == NULL)
5a2cbcf4
L
11900 printf (_("<corrupt time val: %lx"),
11901 (unsigned long) atime);
071436c6
NC
11902 else
11903 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11904 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11905 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11906
11907 }
11908 break;
11909
fdc90cb4 11910 case DT_GNU_HASH:
978c4450 11911 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11912 if (do_dynamic)
11913 {
11914 print_vma (entry->d_un.d_val, PREFIX_HEX);
11915 putchar ('\n');
11916 }
11917 break;
11918
a5da3dee
VDM
11919 case DT_GNU_FLAGS_1:
11920 if (do_dynamic)
11921 {
11922 printf (_("Flags:"));
11923 if (entry->d_un.d_val == 0)
11924 printf (_(" None\n"));
11925 else
11926 {
11927 unsigned long int val = entry->d_un.d_val;
11928
11929 if (val & DF_GNU_1_UNIQUE)
11930 {
11931 printf (" UNIQUE");
11932 val ^= DF_GNU_1_UNIQUE;
11933 }
11934 if (val != 0)
11935 printf (" %lx", val);
11936 puts ("");
11937 }
11938 }
11939 break;
11940
252b5132
RH
11941 default:
11942 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11943 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11944 = entry->d_un.d_val;
252b5132
RH
11945
11946 if (do_dynamic)
11947 {
dda8d76d 11948 switch (filedata->file_header.e_machine)
252b5132 11949 {
37c18eed
SD
11950 case EM_AARCH64:
11951 dynamic_section_aarch64_val (entry);
11952 break;
252b5132 11953 case EM_MIPS:
4fe85591 11954 case EM_MIPS_RS3_LE:
978c4450 11955 dynamic_section_mips_val (filedata, entry);
252b5132 11956 break;
103f02d3 11957 case EM_PARISC:
b2d38a17 11958 dynamic_section_parisc_val (entry);
103f02d3 11959 break;
ecc51f48 11960 case EM_IA_64:
b2d38a17 11961 dynamic_section_ia64_val (entry);
ecc51f48 11962 break;
252b5132 11963 default:
f7a99963
NC
11964 print_vma (entry->d_un.d_val, PREFIX_HEX);
11965 putchar ('\n');
252b5132
RH
11966 }
11967 }
11968 break;
11969 }
11970 }
11971
015dc7e1 11972 return true;
252b5132
RH
11973}
11974
11975static char *
d3ba0551 11976get_ver_flags (unsigned int flags)
252b5132 11977{
6d4f21f6 11978 static char buff[128];
252b5132
RH
11979
11980 buff[0] = 0;
11981
11982 if (flags == 0)
11983 return _("none");
11984
11985 if (flags & VER_FLG_BASE)
7bb1ad17 11986 strcat (buff, "BASE");
252b5132
RH
11987
11988 if (flags & VER_FLG_WEAK)
11989 {
11990 if (flags & VER_FLG_BASE)
7bb1ad17 11991 strcat (buff, " | ");
252b5132 11992
7bb1ad17 11993 strcat (buff, "WEAK");
252b5132
RH
11994 }
11995
44ec90b9
RO
11996 if (flags & VER_FLG_INFO)
11997 {
11998 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11999 strcat (buff, " | ");
44ec90b9 12000
7bb1ad17 12001 strcat (buff, "INFO");
44ec90b9
RO
12002 }
12003
12004 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12005 {
12006 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12007 strcat (buff, " | ");
12008
12009 strcat (buff, _("<unknown>"));
12010 }
252b5132
RH
12011
12012 return buff;
12013}
12014
12015/* Display the contents of the version sections. */
98fb390a 12016
015dc7e1 12017static bool
dda8d76d 12018process_version_sections (Filedata * filedata)
252b5132 12019{
2cf0635d 12020 Elf_Internal_Shdr * section;
b34976b6 12021 unsigned i;
015dc7e1 12022 bool found = false;
252b5132
RH
12023
12024 if (! do_version)
015dc7e1 12025 return true;
252b5132 12026
dda8d76d
NC
12027 for (i = 0, section = filedata->section_headers;
12028 i < filedata->file_header.e_shnum;
b34976b6 12029 i++, section++)
252b5132
RH
12030 {
12031 switch (section->sh_type)
12032 {
12033 case SHT_GNU_verdef:
12034 {
2cf0635d 12035 Elf_External_Verdef * edefs;
452bf675
AM
12036 unsigned long idx;
12037 unsigned long cnt;
2cf0635d 12038 char * endbuf;
252b5132 12039
015dc7e1 12040 found = true;
252b5132 12041
ca0e11aa
NC
12042 if (filedata->is_separate)
12043 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12044 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12045 section->sh_info),
12046 filedata->file_name,
12047 printable_section_name (filedata, section),
12048 section->sh_info);
12049 else
12050 printf (ngettext ("\nVersion definition section '%s' "
12051 "contains %u entry:\n",
12052 "\nVersion definition section '%s' "
12053 "contains %u entries:\n",
12054 section->sh_info),
12055 printable_section_name (filedata, section),
12056 section->sh_info);
047c3dbf 12057
f493c217 12058 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
233f82cf 12059 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12060 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12061 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12062
3f5e193b 12063 edefs = (Elf_External_Verdef *)
dda8d76d 12064 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12065 _("version definition section"));
a6e9f9df
AM
12066 if (!edefs)
12067 break;
59245841 12068 endbuf = (char *) edefs + section->sh_size;
252b5132 12069
1445030f 12070 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12071 {
2cf0635d
NC
12072 char * vstart;
12073 Elf_External_Verdef * edef;
b34976b6 12074 Elf_Internal_Verdef ent;
2cf0635d 12075 Elf_External_Verdaux * eaux;
b34976b6 12076 Elf_Internal_Verdaux aux;
452bf675 12077 unsigned long isum;
b34976b6 12078 int j;
103f02d3 12079
252b5132 12080 vstart = ((char *) edefs) + idx;
54806181
AM
12081 if (vstart + sizeof (*edef) > endbuf)
12082 break;
252b5132
RH
12083
12084 edef = (Elf_External_Verdef *) vstart;
12085
12086 ent.vd_version = BYTE_GET (edef->vd_version);
12087 ent.vd_flags = BYTE_GET (edef->vd_flags);
12088 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12089 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12090 ent.vd_hash = BYTE_GET (edef->vd_hash);
12091 ent.vd_aux = BYTE_GET (edef->vd_aux);
12092 ent.vd_next = BYTE_GET (edef->vd_next);
12093
452bf675 12094 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12095 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12096
12097 printf (_(" Index: %d Cnt: %d "),
12098 ent.vd_ndx, ent.vd_cnt);
12099
452bf675 12100 /* Check for overflow. */
1445030f 12101 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12102 break;
12103
252b5132
RH
12104 vstart += ent.vd_aux;
12105
1445030f
AM
12106 if (vstart + sizeof (*eaux) > endbuf)
12107 break;
252b5132
RH
12108 eaux = (Elf_External_Verdaux *) vstart;
12109
12110 aux.vda_name = BYTE_GET (eaux->vda_name);
12111 aux.vda_next = BYTE_GET (eaux->vda_next);
12112
84714f86 12113 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12114 printf (_("Name: %s\n"),
84714f86 12115 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12116 else
12117 printf (_("Name index: %ld\n"), aux.vda_name);
12118
12119 isum = idx + ent.vd_aux;
12120
b34976b6 12121 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12122 {
1445030f
AM
12123 if (aux.vda_next < sizeof (*eaux)
12124 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12125 {
12126 warn (_("Invalid vda_next field of %lx\n"),
12127 aux.vda_next);
12128 j = ent.vd_cnt;
12129 break;
12130 }
dd24e3da 12131 /* Check for overflow. */
7e26601c 12132 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12133 break;
12134
252b5132
RH
12135 isum += aux.vda_next;
12136 vstart += aux.vda_next;
12137
54806181
AM
12138 if (vstart + sizeof (*eaux) > endbuf)
12139 break;
1445030f 12140 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12141
12142 aux.vda_name = BYTE_GET (eaux->vda_name);
12143 aux.vda_next = BYTE_GET (eaux->vda_next);
12144
84714f86 12145 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12146 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12147 isum, j,
84714f86 12148 get_dynamic_name (filedata, aux.vda_name));
252b5132 12149 else
452bf675 12150 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12151 isum, j, aux.vda_name);
12152 }
dd24e3da 12153
54806181
AM
12154 if (j < ent.vd_cnt)
12155 printf (_(" Version def aux past end of section\n"));
252b5132 12156
c9f02c3e
MR
12157 /* PR 17531:
12158 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12159 if (ent.vd_next < sizeof (*edef)
12160 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12161 {
12162 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12163 cnt = section->sh_info;
12164 break;
12165 }
452bf675 12166 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12167 break;
12168
252b5132
RH
12169 idx += ent.vd_next;
12170 }
dd24e3da 12171
54806181
AM
12172 if (cnt < section->sh_info)
12173 printf (_(" Version definition past end of section\n"));
252b5132
RH
12174
12175 free (edefs);
12176 }
12177 break;
103f02d3 12178
252b5132
RH
12179 case SHT_GNU_verneed:
12180 {
2cf0635d 12181 Elf_External_Verneed * eneed;
452bf675
AM
12182 unsigned long idx;
12183 unsigned long cnt;
2cf0635d 12184 char * endbuf;
252b5132 12185
015dc7e1 12186 found = true;
252b5132 12187
ca0e11aa
NC
12188 if (filedata->is_separate)
12189 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12190 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12191 section->sh_info),
12192 filedata->file_name,
12193 printable_section_name (filedata, section),
12194 section->sh_info);
12195 else
12196 printf (ngettext ("\nVersion needs section '%s' "
12197 "contains %u entry:\n",
12198 "\nVersion needs section '%s' "
12199 "contains %u entries:\n",
12200 section->sh_info),
12201 printable_section_name (filedata, section),
12202 section->sh_info);
047c3dbf 12203
f493c217 12204 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
72de5009 12205 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12206 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12207 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12208
dda8d76d 12209 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12210 section->sh_offset, 1,
12211 section->sh_size,
9cf03b7e 12212 _("Version Needs section"));
a6e9f9df
AM
12213 if (!eneed)
12214 break;
59245841 12215 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12216
12217 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12218 {
2cf0635d 12219 Elf_External_Verneed * entry;
b34976b6 12220 Elf_Internal_Verneed ent;
452bf675 12221 unsigned long isum;
b34976b6 12222 int j;
2cf0635d 12223 char * vstart;
252b5132
RH
12224
12225 vstart = ((char *) eneed) + idx;
54806181
AM
12226 if (vstart + sizeof (*entry) > endbuf)
12227 break;
252b5132
RH
12228
12229 entry = (Elf_External_Verneed *) vstart;
12230
12231 ent.vn_version = BYTE_GET (entry->vn_version);
12232 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12233 ent.vn_file = BYTE_GET (entry->vn_file);
12234 ent.vn_aux = BYTE_GET (entry->vn_aux);
12235 ent.vn_next = BYTE_GET (entry->vn_next);
12236
452bf675 12237 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12238
84714f86 12239 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12240 printf (_(" File: %s"),
84714f86 12241 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12242 else
12243 printf (_(" File: %lx"), ent.vn_file);
12244
12245 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12246
dd24e3da 12247 /* Check for overflow. */
7e26601c 12248 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12249 break;
252b5132
RH
12250 vstart += ent.vn_aux;
12251
12252 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12253 {
2cf0635d 12254 Elf_External_Vernaux * eaux;
b34976b6 12255 Elf_Internal_Vernaux aux;
252b5132 12256
54806181
AM
12257 if (vstart + sizeof (*eaux) > endbuf)
12258 break;
252b5132
RH
12259 eaux = (Elf_External_Vernaux *) vstart;
12260
12261 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12262 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12263 aux.vna_other = BYTE_GET (eaux->vna_other);
12264 aux.vna_name = BYTE_GET (eaux->vna_name);
12265 aux.vna_next = BYTE_GET (eaux->vna_next);
12266
84714f86 12267 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12268 printf (_(" %#06lx: Name: %s"),
84714f86 12269 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12270 else
452bf675 12271 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12272 isum, aux.vna_name);
12273
12274 printf (_(" Flags: %s Version: %d\n"),
12275 get_ver_flags (aux.vna_flags), aux.vna_other);
12276
1445030f
AM
12277 if (aux.vna_next < sizeof (*eaux)
12278 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12279 {
12280 warn (_("Invalid vna_next field of %lx\n"),
12281 aux.vna_next);
12282 j = ent.vn_cnt;
12283 break;
12284 }
1445030f
AM
12285 /* Check for overflow. */
12286 if (aux.vna_next > (size_t) (endbuf - vstart))
12287 break;
252b5132
RH
12288 isum += aux.vna_next;
12289 vstart += aux.vna_next;
12290 }
9cf03b7e 12291
54806181 12292 if (j < ent.vn_cnt)
f9a6a8f0 12293 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12294
1445030f
AM
12295 if (ent.vn_next < sizeof (*entry)
12296 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12297 {
452bf675 12298 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12299 cnt = section->sh_info;
12300 break;
12301 }
1445030f
AM
12302 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12303 break;
252b5132
RH
12304 idx += ent.vn_next;
12305 }
9cf03b7e 12306
54806181 12307 if (cnt < section->sh_info)
9cf03b7e 12308 warn (_("Missing Version Needs information\n"));
103f02d3 12309
252b5132
RH
12310 free (eneed);
12311 }
12312 break;
12313
12314 case SHT_GNU_versym:
12315 {
2cf0635d 12316 Elf_Internal_Shdr * link_section;
8b73c356
NC
12317 size_t total;
12318 unsigned int cnt;
2cf0635d
NC
12319 unsigned char * edata;
12320 unsigned short * data;
12321 char * strtab;
12322 Elf_Internal_Sym * symbols;
12323 Elf_Internal_Shdr * string_sec;
ba5cdace 12324 unsigned long num_syms;
d3ba0551 12325 long off;
252b5132 12326
dda8d76d 12327 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12328 break;
12329
dda8d76d 12330 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12331 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12332
dda8d76d 12333 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12334 break;
12335
015dc7e1 12336 found = true;
252b5132 12337
4de91c10 12338 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12339 if (symbols == NULL)
12340 break;
252b5132 12341
dda8d76d 12342 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12343
dda8d76d 12344 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12345 string_sec->sh_size,
12346 _("version string table"));
a6e9f9df 12347 if (!strtab)
0429c154
MS
12348 {
12349 free (symbols);
12350 break;
12351 }
252b5132 12352
ca0e11aa
NC
12353 if (filedata->is_separate)
12354 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12355 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12356 total),
12357 filedata->file_name,
12358 printable_section_name (filedata, section),
12359 (unsigned long) total);
12360 else
12361 printf (ngettext ("\nVersion symbols section '%s' "
12362 "contains %lu entry:\n",
12363 "\nVersion symbols section '%s' "
12364 "contains %lu entries:\n",
12365 total),
12366 printable_section_name (filedata, section),
12367 (unsigned long) total);
252b5132 12368
f493c217 12369 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
72de5009 12370 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12371 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12372 printable_section_name (filedata, link_section));
252b5132 12373
dda8d76d 12374 off = offset_from_vma (filedata,
978c4450 12375 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12376 total * sizeof (short));
95099889
AM
12377 edata = (unsigned char *) get_data (NULL, filedata, off,
12378 sizeof (short), total,
12379 _("version symbol data"));
a6e9f9df
AM
12380 if (!edata)
12381 {
12382 free (strtab);
0429c154 12383 free (symbols);
a6e9f9df
AM
12384 break;
12385 }
252b5132 12386
3f5e193b 12387 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12388
12389 for (cnt = total; cnt --;)
b34976b6
AM
12390 data[cnt] = byte_get (edata + cnt * sizeof (short),
12391 sizeof (short));
252b5132
RH
12392
12393 free (edata);
12394
12395 for (cnt = 0; cnt < total; cnt += 4)
12396 {
12397 int j, nn;
ab273396
AM
12398 char *name;
12399 char *invalid = _("*invalid*");
252b5132
RH
12400
12401 printf (" %03x:", cnt);
12402
12403 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12404 switch (data[cnt + j])
252b5132
RH
12405 {
12406 case 0:
12407 fputs (_(" 0 (*local*) "), stdout);
12408 break;
12409
12410 case 1:
12411 fputs (_(" 1 (*global*) "), stdout);
12412 break;
12413
12414 default:
c244d050
NC
12415 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12416 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12417
dd24e3da 12418 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12419 array, break to avoid an out-of-bounds read. */
12420 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12421 {
12422 warn (_("invalid index into symbol array\n"));
12423 break;
12424 }
12425
ab273396 12426 name = NULL;
978c4450 12427 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12428 {
b34976b6
AM
12429 Elf_Internal_Verneed ivn;
12430 unsigned long offset;
252b5132 12431
d93f0186 12432 offset = offset_from_vma
978c4450
AM
12433 (filedata,
12434 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12435 sizeof (Elf_External_Verneed));
252b5132 12436
b34976b6 12437 do
252b5132 12438 {
b34976b6
AM
12439 Elf_Internal_Vernaux ivna;
12440 Elf_External_Verneed evn;
12441 Elf_External_Vernaux evna;
12442 unsigned long a_off;
252b5132 12443
dda8d76d 12444 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12445 _("version need")) == NULL)
12446 break;
0b4362b0 12447
252b5132
RH
12448 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12449 ivn.vn_next = BYTE_GET (evn.vn_next);
12450
12451 a_off = offset + ivn.vn_aux;
12452
12453 do
12454 {
dda8d76d 12455 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12456 1, _("version need aux (2)")) == NULL)
12457 {
12458 ivna.vna_next = 0;
12459 ivna.vna_other = 0;
12460 }
12461 else
12462 {
12463 ivna.vna_next = BYTE_GET (evna.vna_next);
12464 ivna.vna_other = BYTE_GET (evna.vna_other);
12465 }
252b5132
RH
12466
12467 a_off += ivna.vna_next;
12468 }
b34976b6 12469 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12470 && ivna.vna_next != 0);
12471
b34976b6 12472 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12473 {
12474 ivna.vna_name = BYTE_GET (evna.vna_name);
12475
54806181 12476 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12477 name = invalid;
54806181
AM
12478 else
12479 name = strtab + ivna.vna_name;
252b5132
RH
12480 break;
12481 }
12482
12483 offset += ivn.vn_next;
12484 }
12485 while (ivn.vn_next);
12486 }
00d93f34 12487
ab273396 12488 if (data[cnt + j] != 0x8001
978c4450 12489 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12490 {
b34976b6
AM
12491 Elf_Internal_Verdef ivd;
12492 Elf_External_Verdef evd;
12493 unsigned long offset;
252b5132 12494
d93f0186 12495 offset = offset_from_vma
978c4450
AM
12496 (filedata,
12497 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12498 sizeof evd);
252b5132
RH
12499
12500 do
12501 {
dda8d76d 12502 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12503 _("version def")) == NULL)
12504 {
12505 ivd.vd_next = 0;
948f632f 12506 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12507 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12508 break;
59245841
NC
12509 }
12510 else
12511 {
12512 ivd.vd_next = BYTE_GET (evd.vd_next);
12513 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12514 }
252b5132
RH
12515
12516 offset += ivd.vd_next;
12517 }
c244d050 12518 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12519 && ivd.vd_next != 0);
12520
c244d050 12521 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12522 {
b34976b6
AM
12523 Elf_External_Verdaux evda;
12524 Elf_Internal_Verdaux ivda;
252b5132
RH
12525
12526 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12527
dda8d76d 12528 if (get_data (&evda, filedata,
59245841
NC
12529 offset - ivd.vd_next + ivd.vd_aux,
12530 sizeof (evda), 1,
12531 _("version def aux")) == NULL)
12532 break;
252b5132
RH
12533
12534 ivda.vda_name = BYTE_GET (evda.vda_name);
12535
54806181 12536 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12537 name = invalid;
12538 else if (name != NULL && name != invalid)
12539 name = _("*both*");
54806181
AM
12540 else
12541 name = strtab + ivda.vda_name;
252b5132
RH
12542 }
12543 }
ab273396
AM
12544 if (name != NULL)
12545 nn += printf ("(%s%-*s",
12546 name,
12547 12 - (int) strlen (name),
12548 ")");
252b5132
RH
12549
12550 if (nn < 18)
12551 printf ("%*c", 18 - nn, ' ');
12552 }
12553
12554 putchar ('\n');
12555 }
12556
12557 free (data);
12558 free (strtab);
12559 free (symbols);
12560 }
12561 break;
103f02d3 12562
252b5132
RH
12563 default:
12564 break;
12565 }
12566 }
12567
12568 if (! found)
ca0e11aa
NC
12569 {
12570 if (filedata->is_separate)
12571 printf (_("\nNo version information found in linked file '%s'.\n"),
12572 filedata->file_name);
12573 else
12574 printf (_("\nNo version information found in this file.\n"));
12575 }
252b5132 12576
015dc7e1 12577 return true;
252b5132
RH
12578}
12579
d1133906 12580static const char *
dda8d76d 12581get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12582{
89246a0e 12583 static char buff[64];
252b5132
RH
12584
12585 switch (binding)
12586 {
b34976b6
AM
12587 case STB_LOCAL: return "LOCAL";
12588 case STB_GLOBAL: return "GLOBAL";
12589 case STB_WEAK: return "WEAK";
252b5132
RH
12590 default:
12591 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12592 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12593 binding);
252b5132 12594 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12595 {
12596 if (binding == STB_GNU_UNIQUE
df3a023b 12597 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12598 return "UNIQUE";
12599 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12600 }
252b5132 12601 else
e9e44622 12602 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12603 return buff;
12604 }
12605}
12606
d1133906 12607static const char *
dda8d76d 12608get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12609{
89246a0e 12610 static char buff[64];
252b5132
RH
12611
12612 switch (type)
12613 {
b34976b6
AM
12614 case STT_NOTYPE: return "NOTYPE";
12615 case STT_OBJECT: return "OBJECT";
12616 case STT_FUNC: return "FUNC";
12617 case STT_SECTION: return "SECTION";
12618 case STT_FILE: return "FILE";
12619 case STT_COMMON: return "COMMON";
12620 case STT_TLS: return "TLS";
15ab5209
DB
12621 case STT_RELC: return "RELC";
12622 case STT_SRELC: return "SRELC";
252b5132
RH
12623 default:
12624 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12625 {
dda8d76d 12626 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12627 return "THUMB_FUNC";
103f02d3 12628
dda8d76d 12629 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12630 return "REGISTER";
12631
dda8d76d 12632 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12633 return "PARISC_MILLI";
12634
e9e44622 12635 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12636 }
252b5132 12637 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12638 {
dda8d76d 12639 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12640 {
12641 if (type == STT_HP_OPAQUE)
12642 return "HP_OPAQUE";
12643 if (type == STT_HP_STUB)
12644 return "HP_STUB";
12645 }
12646
d8045f23 12647 if (type == STT_GNU_IFUNC
dda8d76d 12648 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12649 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12650 return "IFUNC";
12651
e9e44622 12652 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12653 }
252b5132 12654 else
e9e44622 12655 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12656 return buff;
12657 }
12658}
12659
d1133906 12660static const char *
d3ba0551 12661get_symbol_visibility (unsigned int visibility)
d1133906
NC
12662{
12663 switch (visibility)
12664 {
b34976b6
AM
12665 case STV_DEFAULT: return "DEFAULT";
12666 case STV_INTERNAL: return "INTERNAL";
12667 case STV_HIDDEN: return "HIDDEN";
d1133906 12668 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12669 default:
27a45f42 12670 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12671 return _("<unknown>");
d1133906
NC
12672 }
12673}
12674
2057d69d
CZ
12675static const char *
12676get_alpha_symbol_other (unsigned int other)
9abca702 12677{
2057d69d
CZ
12678 switch (other)
12679 {
12680 case STO_ALPHA_NOPV: return "NOPV";
12681 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12682 default:
27a45f42 12683 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12684 return _("<unknown>");
9abca702 12685 }
2057d69d
CZ
12686}
12687
fd85a6a1
NC
12688static const char *
12689get_solaris_symbol_visibility (unsigned int visibility)
12690{
12691 switch (visibility)
12692 {
12693 case 4: return "EXPORTED";
12694 case 5: return "SINGLETON";
12695 case 6: return "ELIMINATE";
12696 default: return get_symbol_visibility (visibility);
12697 }
12698}
12699
2301ed1c
SN
12700static const char *
12701get_aarch64_symbol_other (unsigned int other)
12702{
12703 static char buf[32];
12704
12705 if (other & STO_AARCH64_VARIANT_PCS)
12706 {
12707 other &= ~STO_AARCH64_VARIANT_PCS;
12708 if (other == 0)
12709 return "VARIANT_PCS";
12710 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12711 return buf;
12712 }
12713 return NULL;
12714}
12715
5e2b0d47
NC
12716static const char *
12717get_mips_symbol_other (unsigned int other)
12718{
12719 switch (other)
12720 {
32ec8896
NC
12721 case STO_OPTIONAL: return "OPTIONAL";
12722 case STO_MIPS_PLT: return "MIPS PLT";
12723 case STO_MIPS_PIC: return "MIPS PIC";
12724 case STO_MICROMIPS: return "MICROMIPS";
12725 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12726 case STO_MIPS16: return "MIPS16";
12727 default: return NULL;
5e2b0d47
NC
12728 }
12729}
12730
28f997cf 12731static const char *
dda8d76d 12732get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12733{
dda8d76d 12734 if (is_ia64_vms (filedata))
28f997cf
TG
12735 {
12736 static char res[32];
12737
12738 res[0] = 0;
12739
12740 /* Function types is for images and .STB files only. */
dda8d76d 12741 switch (filedata->file_header.e_type)
28f997cf
TG
12742 {
12743 case ET_DYN:
12744 case ET_EXEC:
12745 switch (VMS_ST_FUNC_TYPE (other))
12746 {
12747 case VMS_SFT_CODE_ADDR:
12748 strcat (res, " CA");
12749 break;
12750 case VMS_SFT_SYMV_IDX:
12751 strcat (res, " VEC");
12752 break;
12753 case VMS_SFT_FD:
12754 strcat (res, " FD");
12755 break;
12756 case VMS_SFT_RESERVE:
12757 strcat (res, " RSV");
12758 break;
12759 default:
bee0ee85
NC
12760 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12761 VMS_ST_FUNC_TYPE (other));
12762 strcat (res, " <unknown>");
12763 break;
28f997cf
TG
12764 }
12765 break;
12766 default:
12767 break;
12768 }
12769 switch (VMS_ST_LINKAGE (other))
12770 {
12771 case VMS_STL_IGNORE:
12772 strcat (res, " IGN");
12773 break;
12774 case VMS_STL_RESERVE:
12775 strcat (res, " RSV");
12776 break;
12777 case VMS_STL_STD:
12778 strcat (res, " STD");
12779 break;
12780 case VMS_STL_LNK:
12781 strcat (res, " LNK");
12782 break;
12783 default:
bee0ee85
NC
12784 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12785 VMS_ST_LINKAGE (other));
12786 strcat (res, " <unknown>");
12787 break;
28f997cf
TG
12788 }
12789
12790 if (res[0] != 0)
12791 return res + 1;
12792 else
12793 return res;
12794 }
12795 return NULL;
12796}
12797
6911b7dc
AM
12798static const char *
12799get_ppc64_symbol_other (unsigned int other)
12800{
14732552
AM
12801 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12802 return NULL;
12803
12804 other >>= STO_PPC64_LOCAL_BIT;
12805 if (other <= 6)
6911b7dc 12806 {
89246a0e 12807 static char buf[64];
14732552
AM
12808 if (other >= 2)
12809 other = ppc64_decode_local_entry (other);
12810 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12811 return buf;
12812 }
12813 return NULL;
12814}
12815
8155b853
NC
12816static const char *
12817get_riscv_symbol_other (unsigned int other)
12818{
12819 static char buf[32];
12820 buf[0] = 0;
12821
12822 if (other & STO_RISCV_VARIANT_CC)
12823 {
12824 strcat (buf, _(" VARIANT_CC"));
12825 other &= ~STO_RISCV_VARIANT_CC;
12826 }
12827
12828 if (other != 0)
12829 snprintf (buf, sizeof buf, " %x", other);
12830
12831
12832 if (buf[0] != 0)
12833 return buf + 1;
12834 else
12835 return buf;
12836}
12837
5e2b0d47 12838static const char *
dda8d76d 12839get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12840{
12841 const char * result = NULL;
89246a0e 12842 static char buff [64];
5e2b0d47
NC
12843
12844 if (other == 0)
12845 return "";
12846
dda8d76d 12847 switch (filedata->file_header.e_machine)
5e2b0d47 12848 {
2057d69d
CZ
12849 case EM_ALPHA:
12850 result = get_alpha_symbol_other (other);
12851 break;
2301ed1c
SN
12852 case EM_AARCH64:
12853 result = get_aarch64_symbol_other (other);
12854 break;
5e2b0d47
NC
12855 case EM_MIPS:
12856 result = get_mips_symbol_other (other);
28f997cf
TG
12857 break;
12858 case EM_IA_64:
dda8d76d 12859 result = get_ia64_symbol_other (filedata, other);
28f997cf 12860 break;
6911b7dc
AM
12861 case EM_PPC64:
12862 result = get_ppc64_symbol_other (other);
12863 break;
8155b853
NC
12864 case EM_RISCV:
12865 result = get_riscv_symbol_other (other);
12866 break;
5e2b0d47 12867 default:
fd85a6a1 12868 result = NULL;
5e2b0d47
NC
12869 break;
12870 }
12871
12872 if (result)
12873 return result;
12874
12875 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12876 return buff;
12877}
12878
d1133906 12879static const char *
dda8d76d 12880get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12881{
b34976b6 12882 static char buff[32];
5cf1065c 12883
252b5132
RH
12884 switch (type)
12885 {
b34976b6
AM
12886 case SHN_UNDEF: return "UND";
12887 case SHN_ABS: return "ABS";
12888 case SHN_COMMON: return "COM";
252b5132 12889 default:
9ce701e2 12890 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12891 && filedata->file_header.e_machine == EM_IA_64
12892 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12893 return "ANSI_COM";
12894 else if ((filedata->file_header.e_machine == EM_X86_64
12895 || filedata->file_header.e_machine == EM_L1OM
12896 || filedata->file_header.e_machine == EM_K1OM)
12897 && type == SHN_X86_64_LCOMMON)
12898 return "LARGE_COM";
12899 else if ((type == SHN_MIPS_SCOMMON
12900 && filedata->file_header.e_machine == EM_MIPS)
12901 || (type == SHN_TIC6X_SCOMMON
12902 && filedata->file_header.e_machine == EM_TI_C6000))
12903 return "SCOM";
12904 else if (type == SHN_MIPS_SUNDEFINED
12905 && filedata->file_header.e_machine == EM_MIPS)
12906 return "SUND";
12907 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12908 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12909 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12910 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12911 else if (type >= SHN_LORESERVE)
12912 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12913 else if (filedata->file_header.e_shnum != 0
12914 && type >= filedata->file_header.e_shnum)
12915 sprintf (buff, _("bad section index[%3d]"), type);
12916 else
12917 sprintf (buff, "%3d", type);
12918 break;
fd85a6a1
NC
12919 }
12920
10ca4b04 12921 return buff;
6bd1a22c
L
12922}
12923
bb4d2ac2 12924static const char *
dda8d76d 12925get_symbol_version_string (Filedata * filedata,
015dc7e1 12926 bool is_dynsym,
1449284b
NC
12927 const char * strtab,
12928 unsigned long int strtab_size,
12929 unsigned int si,
12930 Elf_Internal_Sym * psym,
12931 enum versioned_symbol_info * sym_info,
12932 unsigned short * vna_other)
bb4d2ac2 12933{
ab273396
AM
12934 unsigned char data[2];
12935 unsigned short vers_data;
12936 unsigned long offset;
7a815dd5 12937 unsigned short max_vd_ndx;
bb4d2ac2 12938
ab273396 12939 if (!is_dynsym
978c4450 12940 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12941 return NULL;
bb4d2ac2 12942
978c4450
AM
12943 offset = offset_from_vma (filedata,
12944 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12945 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12946
dda8d76d 12947 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12948 sizeof (data), 1, _("version data")) == NULL)
12949 return NULL;
12950
12951 vers_data = byte_get (data, 2);
bb4d2ac2 12952
1f6f5dba 12953 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12954 return NULL;
bb4d2ac2 12955
0b8b7609 12956 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12957 max_vd_ndx = 0;
12958
ab273396
AM
12959 /* Usually we'd only see verdef for defined symbols, and verneed for
12960 undefined symbols. However, symbols defined by the linker in
12961 .dynbss for variables copied from a shared library in order to
12962 avoid text relocations are defined yet have verneed. We could
12963 use a heuristic to detect the special case, for example, check
12964 for verneed first on symbols defined in SHT_NOBITS sections, but
12965 it is simpler and more reliable to just look for both verdef and
12966 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12967
ab273396
AM
12968 if (psym->st_shndx != SHN_UNDEF
12969 && vers_data != 0x8001
978c4450 12970 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12971 {
12972 Elf_Internal_Verdef ivd;
12973 Elf_Internal_Verdaux ivda;
12974 Elf_External_Verdaux evda;
12975 unsigned long off;
bb4d2ac2 12976
dda8d76d 12977 off = offset_from_vma (filedata,
978c4450 12978 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12979 sizeof (Elf_External_Verdef));
12980
12981 do
bb4d2ac2 12982 {
ab273396
AM
12983 Elf_External_Verdef evd;
12984
dda8d76d 12985 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12986 _("version def")) == NULL)
12987 {
12988 ivd.vd_ndx = 0;
12989 ivd.vd_aux = 0;
12990 ivd.vd_next = 0;
1f6f5dba 12991 ivd.vd_flags = 0;
ab273396
AM
12992 }
12993 else
bb4d2ac2 12994 {
ab273396
AM
12995 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12996 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12997 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12998 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12999 }
bb4d2ac2 13000
7a815dd5
L
13001 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13002 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13003
ab273396
AM
13004 off += ivd.vd_next;
13005 }
13006 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13007
ab273396
AM
13008 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13009 {
9abca702 13010 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13011 return NULL;
13012
ab273396
AM
13013 off -= ivd.vd_next;
13014 off += ivd.vd_aux;
bb4d2ac2 13015
dda8d76d 13016 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13017 _("version def aux")) != NULL)
13018 {
13019 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13020
ab273396 13021 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13022 return (ivda.vda_name < strtab_size
13023 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13024 }
13025 }
13026 }
bb4d2ac2 13027
978c4450 13028 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13029 {
13030 Elf_External_Verneed evn;
13031 Elf_Internal_Verneed ivn;
13032 Elf_Internal_Vernaux ivna;
bb4d2ac2 13033
dda8d76d 13034 offset = offset_from_vma (filedata,
978c4450 13035 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13036 sizeof evn);
13037 do
13038 {
13039 unsigned long vna_off;
bb4d2ac2 13040
dda8d76d 13041 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13042 _("version need")) == NULL)
13043 {
13044 ivna.vna_next = 0;
13045 ivna.vna_other = 0;
13046 ivna.vna_name = 0;
13047 break;
13048 }
bb4d2ac2 13049
ab273396
AM
13050 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13051 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13052
ab273396 13053 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13054
ab273396
AM
13055 do
13056 {
13057 Elf_External_Vernaux evna;
bb4d2ac2 13058
dda8d76d 13059 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13060 _("version need aux (3)")) == NULL)
bb4d2ac2 13061 {
ab273396
AM
13062 ivna.vna_next = 0;
13063 ivna.vna_other = 0;
13064 ivna.vna_name = 0;
bb4d2ac2 13065 }
bb4d2ac2 13066 else
bb4d2ac2 13067 {
ab273396
AM
13068 ivna.vna_other = BYTE_GET (evna.vna_other);
13069 ivna.vna_next = BYTE_GET (evna.vna_next);
13070 ivna.vna_name = BYTE_GET (evna.vna_name);
13071 }
bb4d2ac2 13072
ab273396
AM
13073 vna_off += ivna.vna_next;
13074 }
13075 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13076
ab273396
AM
13077 if (ivna.vna_other == vers_data)
13078 break;
bb4d2ac2 13079
ab273396
AM
13080 offset += ivn.vn_next;
13081 }
13082 while (ivn.vn_next != 0);
bb4d2ac2 13083
ab273396
AM
13084 if (ivna.vna_other == vers_data)
13085 {
13086 *sym_info = symbol_undefined;
13087 *vna_other = ivna.vna_other;
13088 return (ivna.vna_name < strtab_size
13089 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13090 }
7a815dd5
L
13091 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13092 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13093 return _("<corrupt>");
bb4d2ac2 13094 }
ab273396 13095 return NULL;
bb4d2ac2
L
13096}
13097
047c3dbf
NL
13098/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13099
13100static unsigned int
13101print_dynamic_symbol_size (bfd_vma vma, int base)
13102{
13103 switch (base)
13104 {
13105 case 8:
13106 return print_vma (vma, OCTAL_5);
13107
13108 case 10:
13109 return print_vma (vma, UNSIGNED_5);
13110
13111 case 16:
13112 return print_vma (vma, PREFIX_HEX_5);
13113
13114 case 0:
13115 default:
13116 return print_vma (vma, DEC_5);
13117 }
13118}
13119
10ca4b04
L
13120static void
13121print_dynamic_symbol (Filedata *filedata, unsigned long si,
13122 Elf_Internal_Sym *symtab,
13123 Elf_Internal_Shdr *section,
13124 char *strtab, size_t strtab_size)
252b5132 13125{
10ca4b04
L
13126 const char *version_string;
13127 enum versioned_symbol_info sym_info;
13128 unsigned short vna_other;
23356397
NC
13129 bool is_valid;
13130 const char * sstr;
10ca4b04 13131 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13132
10ca4b04
L
13133 printf ("%6ld: ", si);
13134 print_vma (psym->st_value, LONG_HEX);
13135 putchar (' ');
047c3dbf 13136 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13137 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13138 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13139 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13140 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13141 else
252b5132 13142 {
10ca4b04 13143 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13144
10ca4b04
L
13145 printf (" %-7s", get_symbol_visibility (vis));
13146 /* Check to see if any other bits in the st_other field are set.
13147 Note - displaying this information disrupts the layout of the
13148 table being generated, but for the moment this case is very rare. */
13149 if (psym->st_other ^ vis)
13150 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13151 }
10ca4b04 13152 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13153
23356397
NC
13154 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13155 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13156 && filedata->section_headers != NULL
23356397
NC
13157 && psym->st_name == 0)
13158 {
84714f86
AM
13159 is_valid
13160 = section_name_valid (filedata,
13161 filedata->section_headers + psym->st_shndx);
23356397 13162 sstr = is_valid ?
84714f86
AM
13163 section_name_print (filedata,
13164 filedata->section_headers + psym->st_shndx)
23356397
NC
13165 : _("<corrupt>");
13166 }
13167 else
13168 {
84714f86 13169 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13170 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13171 }
10ca4b04
L
13172
13173 version_string
13174 = get_symbol_version_string (filedata,
13175 (section == NULL
13176 || section->sh_type == SHT_DYNSYM),
13177 strtab, strtab_size, si,
13178 psym, &sym_info, &vna_other);
b9e920ec 13179
0942c7ab
NC
13180 int len_avail = 21;
13181 if (! do_wide && version_string != NULL)
13182 {
ddb43bab 13183 char buffer[16];
0942c7ab 13184
ddb43bab 13185 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13186
13187 if (sym_info == symbol_undefined)
13188 len_avail -= sprintf (buffer," (%d)", vna_other);
13189 else if (sym_info != symbol_hidden)
13190 len_avail -= 1;
13191 }
13192
13193 print_symbol (len_avail, sstr);
b9e920ec 13194
10ca4b04
L
13195 if (version_string)
13196 {
13197 if (sym_info == symbol_undefined)
13198 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13199 else
10ca4b04
L
13200 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13201 version_string);
13202 }
6bd1a22c 13203
10ca4b04 13204 putchar ('\n');
6bd1a22c 13205
10ca4b04
L
13206 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13207 && section != NULL
13208 && si >= section->sh_info
13209 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13210 && filedata->file_header.e_machine != EM_MIPS
13211 /* Solaris binaries have been found to violate this requirement as
13212 well. Not sure if this is a bug or an ABI requirement. */
13213 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13214 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13215 si, printable_section_name (filedata, section), section->sh_info);
13216}
f16a9783 13217
0f03783c
NC
13218static const char *
13219get_lto_kind (unsigned int kind)
13220{
13221 switch (kind)
13222 {
13223 case 0: return "DEF";
13224 case 1: return "WEAKDEF";
13225 case 2: return "UNDEF";
13226 case 3: return "WEAKUNDEF";
13227 case 4: return "COMMON";
13228 default:
13229 break;
13230 }
13231
13232 static char buffer[30];
13233 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13234 sprintf (buffer, "<unknown: %u>", kind);
13235 return buffer;
13236}
13237
13238static const char *
13239get_lto_visibility (unsigned int visibility)
13240{
13241 switch (visibility)
13242 {
13243 case 0: return "DEFAULT";
13244 case 1: return "PROTECTED";
13245 case 2: return "INTERNAL";
13246 case 3: return "HIDDEN";
13247 default:
13248 break;
13249 }
13250
13251 static char buffer[30];
13252 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13253 sprintf (buffer, "<unknown: %u>", visibility);
13254 return buffer;
13255}
13256
13257static const char *
13258get_lto_sym_type (unsigned int sym_type)
13259{
13260 switch (sym_type)
13261 {
13262 case 0: return "UNKNOWN";
13263 case 1: return "FUNCTION";
13264 case 2: return "VARIABLE";
13265 default:
13266 break;
13267 }
13268
13269 static char buffer[30];
13270 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13271 sprintf (buffer, "<unknown: %u>", sym_type);
13272 return buffer;
13273}
13274
13275/* Display an LTO format symbol table.
13276 FIXME: The format of LTO symbol tables is not formalized.
13277 So this code could need changing in the future. */
13278
015dc7e1 13279static bool
0f03783c
NC
13280display_lto_symtab (Filedata * filedata,
13281 Elf_Internal_Shdr * section)
13282{
13283 if (section->sh_size == 0)
13284 {
ca0e11aa
NC
13285 if (filedata->is_separate)
13286 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13287 printable_section_name (filedata, section),
13288 filedata->file_name);
13289 else
13290 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13291 printable_section_name (filedata, section));
047c3dbf 13292
015dc7e1 13293 return true;
0f03783c
NC
13294 }
13295
13296 if (section->sh_size > filedata->file_size)
13297 {
13298 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13299 printable_section_name (filedata, section),
13300 (unsigned long) section->sh_size);
015dc7e1 13301 return false;
0f03783c
NC
13302 }
13303
13304 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13305 section->sh_size, 1, _("LTO symbols"));
13306 if (alloced_data == NULL)
015dc7e1 13307 return false;
0f03783c
NC
13308
13309 /* Look for extended data for the symbol table. */
13310 Elf_Internal_Shdr * ext;
13311 void * ext_data_orig = NULL;
13312 char * ext_data = NULL;
13313 char * ext_data_end = NULL;
13314 char * ext_name = NULL;
13315
13316 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13317 (section_name (filedata, section)
13318 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13319 && ext_name != NULL /* Paranoia. */
13320 && (ext = find_section (filedata, ext_name)) != NULL)
13321 {
13322 if (ext->sh_size < 3)
13323 error (_("LTO Symbol extension table '%s' is empty!\n"),
13324 printable_section_name (filedata, ext));
13325 else
13326 {
13327 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13328 ext->sh_size, 1,
13329 _("LTO ext symbol data"));
13330 if (ext_data != NULL)
13331 {
13332 ext_data_end = ext_data + ext->sh_size;
13333 if (* ext_data++ != 1)
13334 error (_("Unexpected version number in symbol extension table\n"));
13335 }
13336 }
13337 }
b9e920ec 13338
0f03783c
NC
13339 const unsigned char * data = (const unsigned char *) alloced_data;
13340 const unsigned char * end = data + section->sh_size;
13341
ca0e11aa
NC
13342 if (filedata->is_separate)
13343 printf (_("\nIn linked file '%s': "), filedata->file_name);
13344 else
13345 printf ("\n");
13346
0f03783c
NC
13347 if (ext_data_orig != NULL)
13348 {
13349 if (do_wide)
ca0e11aa 13350 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13351 printable_section_name (filedata, section),
13352 printable_section_name (filedata, ext));
13353 else
13354 {
ca0e11aa 13355 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13356 printable_section_name (filedata, section));
13357 printf (_(" and extension table '%s' contain:\n"),
13358 printable_section_name (filedata, ext));
13359 }
13360 }
13361 else
ca0e11aa 13362 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13363 printable_section_name (filedata, section));
b9e920ec 13364
0f03783c 13365 /* FIXME: Add a wide version. */
b9e920ec 13366 if (ext_data_orig != NULL)
0f03783c
NC
13367 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13368 else
13369 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13370
13371 /* FIXME: We do not handle style prefixes. */
13372
13373 while (data < end)
13374 {
13375 const unsigned char * sym_name = data;
13376 data += strnlen ((const char *) sym_name, end - data) + 1;
13377 if (data >= end)
13378 goto fail;
13379
13380 const unsigned char * comdat_key = data;
13381 data += strnlen ((const char *) comdat_key, end - data) + 1;
13382 if (data >= end)
13383 goto fail;
13384
13385 if (data + 2 + 8 + 4 > end)
13386 goto fail;
13387
13388 unsigned int kind = *data++;
13389 unsigned int visibility = *data++;
13390
928c411d 13391 uint64_t size = byte_get (data, 8);
0f03783c
NC
13392 data += 8;
13393
928c411d 13394 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13395 data += 4;
13396
13397 if (ext_data != NULL)
13398 {
13399 if (ext_data < (ext_data_end - 1))
13400 {
13401 unsigned int sym_type = * ext_data ++;
13402 unsigned int sec_kind = * ext_data ++;
13403
13404 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13405 * comdat_key == 0 ? "-" : (char *) comdat_key,
13406 get_lto_kind (kind),
13407 get_lto_visibility (visibility),
13408 (long) size,
13409 (long) slot,
13410 get_lto_sym_type (sym_type),
13411 (long) sec_kind);
13412 print_symbol (6, (const char *) sym_name);
13413 }
13414 else
13415 {
13416 error (_("Ran out of LTO symbol extension data\n"));
13417 ext_data = NULL;
13418 /* FIXME: return FAIL result ? */
13419 }
13420 }
13421 else
13422 {
13423 printf (" %10s %10s %11s %08lx %08lx _",
13424 * comdat_key == 0 ? "-" : (char *) comdat_key,
13425 get_lto_kind (kind),
13426 get_lto_visibility (visibility),
13427 (long) size,
13428 (long) slot);
13429 print_symbol (21, (const char *) sym_name);
13430 }
13431 putchar ('\n');
13432 }
13433
13434 if (ext_data != NULL && ext_data < ext_data_end)
13435 {
13436 error (_("Data remains in the LTO symbol extension table\n"));
13437 goto fail;
13438 }
13439
13440 free (alloced_data);
13441 free (ext_data_orig);
13442 free (ext_name);
015dc7e1 13443 return true;
b9e920ec 13444
0f03783c
NC
13445 fail:
13446 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13447 free (alloced_data);
13448 free (ext_data_orig);
13449 free (ext_name);
015dc7e1 13450 return false;
0f03783c
NC
13451}
13452
13453/* Display LTO symbol tables. */
13454
015dc7e1 13455static bool
0f03783c
NC
13456process_lto_symbol_tables (Filedata * filedata)
13457{
13458 Elf_Internal_Shdr * section;
13459 unsigned int i;
015dc7e1 13460 bool res = true;
0f03783c
NC
13461
13462 if (!do_lto_syms)
015dc7e1 13463 return true;
0f03783c
NC
13464
13465 if (filedata->section_headers == NULL)
015dc7e1 13466 return true;
0f03783c
NC
13467
13468 for (i = 0, section = filedata->section_headers;
13469 i < filedata->file_header.e_shnum;
13470 i++, section++)
84714f86
AM
13471 if (section_name_valid (filedata, section)
13472 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13473 res &= display_lto_symtab (filedata, section);
13474
b9e920ec 13475 return res;
0f03783c
NC
13476}
13477
10ca4b04 13478/* Dump the symbol table. */
0f03783c 13479
015dc7e1 13480static bool
10ca4b04
L
13481process_symbol_table (Filedata * filedata)
13482{
13483 Elf_Internal_Shdr * section;
f16a9783 13484
10ca4b04 13485 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13486 return true;
6bd1a22c 13487
978c4450 13488 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13489 && do_syms
13490 && do_using_dynamic
978c4450
AM
13491 && filedata->dynamic_strings != NULL
13492 && filedata->dynamic_symbols != NULL)
6bd1a22c 13493 {
10ca4b04 13494 unsigned long si;
6bd1a22c 13495
ca0e11aa
NC
13496 if (filedata->is_separate)
13497 {
13498 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13499 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13500 filedata->num_dynamic_syms),
13501 filedata->file_name,
13502 filedata->num_dynamic_syms);
13503 }
13504 else
13505 {
13506 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13507 "\nSymbol table for image contains %lu entries:\n",
13508 filedata->num_dynamic_syms),
13509 filedata->num_dynamic_syms);
13510 }
10ca4b04
L
13511 if (is_32bit_elf)
13512 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13513 else
13514 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13515
978c4450
AM
13516 for (si = 0; si < filedata->num_dynamic_syms; si++)
13517 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13518 filedata->dynamic_strings,
13519 filedata->dynamic_strings_length);
252b5132 13520 }
8b73c356 13521 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13522 && filedata->section_headers != NULL)
252b5132 13523 {
b34976b6 13524 unsigned int i;
252b5132 13525
dda8d76d
NC
13526 for (i = 0, section = filedata->section_headers;
13527 i < filedata->file_header.e_shnum;
252b5132
RH
13528 i++, section++)
13529 {
2cf0635d 13530 char * strtab = NULL;
c256ffe7 13531 unsigned long int strtab_size = 0;
2cf0635d 13532 Elf_Internal_Sym * symtab;
ef3df110 13533 unsigned long si, num_syms;
252b5132 13534
2c610e4b
L
13535 if ((section->sh_type != SHT_SYMTAB
13536 && section->sh_type != SHT_DYNSYM)
13537 || (!do_syms
13538 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13539 continue;
13540
dd24e3da
NC
13541 if (section->sh_entsize == 0)
13542 {
13543 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13544 printable_section_name (filedata, section));
dd24e3da
NC
13545 continue;
13546 }
13547
d3a49aa8 13548 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13549
13550 if (filedata->is_separate)
13551 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13552 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13553 num_syms),
13554 filedata->file_name,
13555 printable_section_name (filedata, section),
13556 num_syms);
13557 else
13558 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13559 "\nSymbol table '%s' contains %lu entries:\n",
13560 num_syms),
13561 printable_section_name (filedata, section),
13562 num_syms);
dd24e3da 13563
f7a99963 13564 if (is_32bit_elf)
ca47b30c 13565 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13566 else
ca47b30c 13567 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13568
4de91c10 13569 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13570 if (symtab == NULL)
13571 continue;
13572
dda8d76d 13573 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13574 {
dda8d76d
NC
13575 strtab = filedata->string_table;
13576 strtab_size = filedata->string_table_length;
c256ffe7 13577 }
dda8d76d 13578 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13579 {
2cf0635d 13580 Elf_Internal_Shdr * string_sec;
252b5132 13581
dda8d76d 13582 string_sec = filedata->section_headers + section->sh_link;
252b5132 13583
dda8d76d 13584 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13585 1, string_sec->sh_size,
13586 _("string table"));
c256ffe7 13587 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13588 }
13589
10ca4b04
L
13590 for (si = 0; si < num_syms; si++)
13591 print_dynamic_symbol (filedata, si, symtab, section,
13592 strtab, strtab_size);
252b5132
RH
13593
13594 free (symtab);
dda8d76d 13595 if (strtab != filedata->string_table)
252b5132
RH
13596 free (strtab);
13597 }
13598 }
13599 else if (do_syms)
13600 printf
13601 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13602
978c4450 13603 if (do_histogram && filedata->buckets != NULL)
252b5132 13604 {
2cf0635d
NC
13605 unsigned long * lengths;
13606 unsigned long * counts;
66543521
AM
13607 unsigned long hn;
13608 bfd_vma si;
13609 unsigned long maxlength = 0;
13610 unsigned long nzero_counts = 0;
13611 unsigned long nsyms = 0;
6bd6a03d 13612 char *visited;
252b5132 13613
d3a49aa8
AM
13614 printf (ngettext ("\nHistogram for bucket list length "
13615 "(total of %lu bucket):\n",
13616 "\nHistogram for bucket list length "
13617 "(total of %lu buckets):\n",
978c4450
AM
13618 (unsigned long) filedata->nbuckets),
13619 (unsigned long) filedata->nbuckets);
252b5132 13620
978c4450
AM
13621 lengths = (unsigned long *) calloc (filedata->nbuckets,
13622 sizeof (*lengths));
252b5132
RH
13623 if (lengths == NULL)
13624 {
8b73c356 13625 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13626 goto err_out;
252b5132 13627 }
978c4450
AM
13628 visited = xcmalloc (filedata->nchains, 1);
13629 memset (visited, 0, filedata->nchains);
8b73c356
NC
13630
13631 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13632 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13633 {
978c4450 13634 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13635 {
b34976b6 13636 ++nsyms;
252b5132 13637 if (maxlength < ++lengths[hn])
b34976b6 13638 ++maxlength;
978c4450 13639 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13640 {
13641 error (_("histogram chain is corrupt\n"));
13642 break;
13643 }
13644 visited[si] = 1;
252b5132
RH
13645 }
13646 }
6bd6a03d 13647 free (visited);
252b5132 13648
3f5e193b 13649 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13650 if (counts == NULL)
13651 {
b2e951ec 13652 free (lengths);
8b73c356 13653 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13654 goto err_out;
252b5132
RH
13655 }
13656
978c4450 13657 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13658 ++counts[lengths[hn]];
252b5132 13659
978c4450 13660 if (filedata->nbuckets > 0)
252b5132 13661 {
66543521
AM
13662 unsigned long i;
13663 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13664 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13665 for (i = 1; i <= maxlength; ++i)
103f02d3 13666 {
66543521
AM
13667 nzero_counts += counts[i] * i;
13668 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13669 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13670 (nzero_counts * 100.0) / nsyms);
13671 }
252b5132
RH
13672 }
13673
13674 free (counts);
13675 free (lengths);
13676 }
13677
978c4450
AM
13678 free (filedata->buckets);
13679 filedata->buckets = NULL;
13680 filedata->nbuckets = 0;
13681 free (filedata->chains);
13682 filedata->chains = NULL;
252b5132 13683
978c4450 13684 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13685 {
2cf0635d
NC
13686 unsigned long * lengths;
13687 unsigned long * counts;
fdc90cb4
JJ
13688 unsigned long hn;
13689 unsigned long maxlength = 0;
13690 unsigned long nzero_counts = 0;
13691 unsigned long nsyms = 0;
fdc90cb4 13692
f16a9783 13693 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13694 "(total of %lu bucket):\n",
f16a9783 13695 "\nHistogram for `%s' bucket list length "
d3a49aa8 13696 "(total of %lu buckets):\n",
978c4450
AM
13697 (unsigned long) filedata->ngnubuckets),
13698 GNU_HASH_SECTION_NAME (filedata),
13699 (unsigned long) filedata->ngnubuckets);
8b73c356 13700
978c4450
AM
13701 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13702 sizeof (*lengths));
fdc90cb4
JJ
13703 if (lengths == NULL)
13704 {
8b73c356 13705 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13706 goto err_out;
fdc90cb4
JJ
13707 }
13708
fdc90cb4
JJ
13709 printf (_(" Length Number %% of total Coverage\n"));
13710
978c4450
AM
13711 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13712 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13713 {
13714 bfd_vma off, length = 1;
13715
978c4450 13716 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13717 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13718 off < filedata->ngnuchains
13719 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13720 ++off)
fdc90cb4
JJ
13721 ++length;
13722 lengths[hn] = length;
13723 if (length > maxlength)
13724 maxlength = length;
13725 nsyms += length;
13726 }
13727
3f5e193b 13728 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13729 if (counts == NULL)
13730 {
b2e951ec 13731 free (lengths);
8b73c356 13732 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13733 goto err_out;
fdc90cb4
JJ
13734 }
13735
978c4450 13736 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13737 ++counts[lengths[hn]];
13738
978c4450 13739 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13740 {
13741 unsigned long j;
13742 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13743 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13744 for (j = 1; j <= maxlength; ++j)
13745 {
13746 nzero_counts += counts[j] * j;
13747 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13748 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13749 (nzero_counts * 100.0) / nsyms);
13750 }
13751 }
13752
13753 free (counts);
13754 free (lengths);
fdc90cb4 13755 }
978c4450
AM
13756 free (filedata->gnubuckets);
13757 filedata->gnubuckets = NULL;
13758 filedata->ngnubuckets = 0;
13759 free (filedata->gnuchains);
13760 filedata->gnuchains = NULL;
13761 filedata->ngnuchains = 0;
13762 free (filedata->mipsxlat);
13763 filedata->mipsxlat = NULL;
015dc7e1 13764 return true;
fd486f32
AM
13765
13766 err_out:
978c4450
AM
13767 free (filedata->gnubuckets);
13768 filedata->gnubuckets = NULL;
13769 filedata->ngnubuckets = 0;
13770 free (filedata->gnuchains);
13771 filedata->gnuchains = NULL;
13772 filedata->ngnuchains = 0;
13773 free (filedata->mipsxlat);
13774 filedata->mipsxlat = NULL;
13775 free (filedata->buckets);
13776 filedata->buckets = NULL;
13777 filedata->nbuckets = 0;
13778 free (filedata->chains);
13779 filedata->chains = NULL;
015dc7e1 13780 return false;
252b5132
RH
13781}
13782
015dc7e1 13783static bool
ca0e11aa 13784process_syminfo (Filedata * filedata)
252b5132 13785{
b4c96d0d 13786 unsigned int i;
252b5132 13787
978c4450 13788 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13789 || !do_dynamic)
13790 /* No syminfo, this is ok. */
015dc7e1 13791 return true;
252b5132
RH
13792
13793 /* There better should be a dynamic symbol section. */
978c4450 13794 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13795 return false;
252b5132 13796
ca0e11aa
NC
13797 if (filedata->is_separate)
13798 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13799 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13800 filedata->dynamic_syminfo_nent),
13801 filedata->file_name,
13802 filedata->dynamic_syminfo_offset,
13803 filedata->dynamic_syminfo_nent);
13804 else
d3a49aa8
AM
13805 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13806 "contains %d entry:\n",
13807 "\nDynamic info segment at offset 0x%lx "
13808 "contains %d entries:\n",
978c4450 13809 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13810 filedata->dynamic_syminfo_offset,
13811 filedata->dynamic_syminfo_nent);
252b5132
RH
13812
13813 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13814 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13815 {
978c4450 13816 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13817
31104126 13818 printf ("%4d: ", i);
978c4450 13819 if (i >= filedata->num_dynamic_syms)
4082ef84 13820 printf (_("<corrupt index>"));
84714f86
AM
13821 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13822 print_symbol (30, get_dynamic_name (filedata,
978c4450 13823 filedata->dynamic_symbols[i].st_name));
d79b3d50 13824 else
978c4450 13825 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13826 putchar (' ');
252b5132 13827
978c4450 13828 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13829 {
13830 case SYMINFO_BT_SELF:
13831 fputs ("SELF ", stdout);
13832 break;
13833 case SYMINFO_BT_PARENT:
13834 fputs ("PARENT ", stdout);
13835 break;
13836 default:
978c4450
AM
13837 if (filedata->dynamic_syminfo[i].si_boundto > 0
13838 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13839 && valid_dynamic_name (filedata,
978c4450 13840 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13841 {
84714f86 13842 print_symbol (10, get_dynamic_name (filedata,
978c4450 13843 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13844 putchar (' ' );
13845 }
252b5132 13846 else
978c4450 13847 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13848 break;
13849 }
13850
13851 if (flags & SYMINFO_FLG_DIRECT)
13852 printf (" DIRECT");
13853 if (flags & SYMINFO_FLG_PASSTHRU)
13854 printf (" PASSTHRU");
13855 if (flags & SYMINFO_FLG_COPY)
13856 printf (" COPY");
13857 if (flags & SYMINFO_FLG_LAZYLOAD)
13858 printf (" LAZYLOAD");
13859
13860 puts ("");
13861 }
13862
015dc7e1 13863 return true;
252b5132
RH
13864}
13865
75802ccb
CE
13866/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13867 is contained by the region START .. END. The types of ADDR, START
13868 and END should all be the same. Note both ADDR + NELEM and END
13869 point to just beyond the end of the regions that are being tested. */
13870#define IN_RANGE(START,END,ADDR,NELEM) \
13871 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13872
cf13d699
NC
13873/* Check to see if the given reloc needs to be handled in a target specific
13874 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13875 FALSE.
13876
13877 If called with reloc == NULL, then this is a signal that reloc processing
13878 for the current section has finished, and any saved state should be
13879 discarded. */
09c11c86 13880
015dc7e1 13881static bool
dda8d76d
NC
13882target_specific_reloc_handling (Filedata * filedata,
13883 Elf_Internal_Rela * reloc,
13884 unsigned char * start,
13885 unsigned char * end,
13886 Elf_Internal_Sym * symtab,
13887 unsigned long num_syms)
252b5132 13888{
f84ce13b
NC
13889 unsigned int reloc_type = 0;
13890 unsigned long sym_index = 0;
13891
13892 if (reloc)
13893 {
dda8d76d 13894 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13895 sym_index = get_reloc_symindex (reloc->r_info);
13896 }
252b5132 13897
dda8d76d 13898 switch (filedata->file_header.e_machine)
252b5132 13899 {
13761a11
NC
13900 case EM_MSP430:
13901 case EM_MSP430_OLD:
13902 {
13903 static Elf_Internal_Sym * saved_sym = NULL;
13904
f84ce13b
NC
13905 if (reloc == NULL)
13906 {
13907 saved_sym = NULL;
015dc7e1 13908 return true;
f84ce13b
NC
13909 }
13910
13761a11
NC
13911 switch (reloc_type)
13912 {
13913 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13914 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13915 if (uses_msp430x_relocs (filedata))
13761a11 13916 break;
1a0670f3 13917 /* Fall through. */
13761a11 13918 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13919 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13920 /* PR 21139. */
13921 if (sym_index >= num_syms)
13922 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13923 sym_index);
13924 else
13925 saved_sym = symtab + sym_index;
015dc7e1 13926 return true;
13761a11
NC
13927
13928 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13929 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13930 goto handle_sym_diff;
0b4362b0 13931
13761a11
NC
13932 case 5: /* R_MSP430_16_BYTE */
13933 case 9: /* R_MSP430_8 */
7d81bc93 13934 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13935 if (uses_msp430x_relocs (filedata))
13761a11
NC
13936 break;
13937 goto handle_sym_diff;
13938
13939 case 2: /* R_MSP430_ABS16 */
13940 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13941 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13942 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13943 break;
13944 goto handle_sym_diff;
0b4362b0 13945
13761a11
NC
13946 handle_sym_diff:
13947 if (saved_sym != NULL)
13948 {
13949 bfd_vma value;
5a805384 13950 unsigned int reloc_size = 0;
7d81bc93
JL
13951 int leb_ret = 0;
13952 switch (reloc_type)
13953 {
13954 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13955 reloc_size = 4;
13956 break;
13957 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13958 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13959 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13960 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13961 &reloc_size, &leb_ret);
7d81bc93
JL
13962 break;
13963 default:
13964 reloc_size = 2;
13965 break;
13966 }
13761a11 13967
5a805384 13968 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13969 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13970 "ULEB128 value\n"),
13971 (long) reloc->r_offset);
13972 else if (sym_index >= num_syms)
f84ce13b
NC
13973 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13974 sym_index);
03f7786e 13975 else
f84ce13b
NC
13976 {
13977 value = reloc->r_addend + (symtab[sym_index].st_value
13978 - saved_sym->st_value);
13979
b32e566b 13980 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13981 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13982 else
13983 /* PR 21137 */
13984 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13985 (long) reloc->r_offset);
f84ce13b 13986 }
13761a11
NC
13987
13988 saved_sym = NULL;
015dc7e1 13989 return true;
13761a11
NC
13990 }
13991 break;
13992
13993 default:
13994 if (saved_sym != NULL)
071436c6 13995 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13996 break;
13997 }
13998 break;
13999 }
14000
cf13d699
NC
14001 case EM_MN10300:
14002 case EM_CYGNUS_MN10300:
14003 {
14004 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14005
f84ce13b
NC
14006 if (reloc == NULL)
14007 {
14008 saved_sym = NULL;
015dc7e1 14009 return true;
f84ce13b
NC
14010 }
14011
cf13d699
NC
14012 switch (reloc_type)
14013 {
14014 case 34: /* R_MN10300_ALIGN */
015dc7e1 14015 return true;
cf13d699 14016 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14017 if (sym_index >= num_syms)
14018 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14019 sym_index);
14020 else
14021 saved_sym = symtab + sym_index;
015dc7e1 14022 return true;
f84ce13b 14023
cf13d699
NC
14024 case 1: /* R_MN10300_32 */
14025 case 2: /* R_MN10300_16 */
14026 if (saved_sym != NULL)
14027 {
03f7786e 14028 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 14029 bfd_vma value;
252b5132 14030
f84ce13b
NC
14031 if (sym_index >= num_syms)
14032 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14033 sym_index);
03f7786e 14034 else
f84ce13b
NC
14035 {
14036 value = reloc->r_addend + (symtab[sym_index].st_value
14037 - saved_sym->st_value);
14038
b32e566b 14039 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14040 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14041 else
14042 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14043 (long) reloc->r_offset);
f84ce13b 14044 }
252b5132 14045
cf13d699 14046 saved_sym = NULL;
015dc7e1 14047 return true;
cf13d699
NC
14048 }
14049 break;
14050 default:
14051 if (saved_sym != NULL)
071436c6 14052 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14053 break;
14054 }
14055 break;
14056 }
6ff71e76
NC
14057
14058 case EM_RL78:
14059 {
14060 static bfd_vma saved_sym1 = 0;
14061 static bfd_vma saved_sym2 = 0;
14062 static bfd_vma value;
14063
f84ce13b
NC
14064 if (reloc == NULL)
14065 {
14066 saved_sym1 = saved_sym2 = 0;
015dc7e1 14067 return true;
f84ce13b
NC
14068 }
14069
6ff71e76
NC
14070 switch (reloc_type)
14071 {
14072 case 0x80: /* R_RL78_SYM. */
14073 saved_sym1 = saved_sym2;
f84ce13b
NC
14074 if (sym_index >= num_syms)
14075 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14076 sym_index);
14077 else
14078 {
14079 saved_sym2 = symtab[sym_index].st_value;
14080 saved_sym2 += reloc->r_addend;
14081 }
015dc7e1 14082 return true;
6ff71e76
NC
14083
14084 case 0x83: /* R_RL78_OPsub. */
14085 value = saved_sym1 - saved_sym2;
14086 saved_sym2 = saved_sym1 = 0;
015dc7e1 14087 return true;
6ff71e76
NC
14088 break;
14089
14090 case 0x41: /* R_RL78_ABS32. */
b32e566b 14091 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14092 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14093 else
14094 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14095 (long) reloc->r_offset);
6ff71e76 14096 value = 0;
015dc7e1 14097 return true;
6ff71e76
NC
14098
14099 case 0x43: /* R_RL78_ABS16. */
b32e566b 14100 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14101 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14102 else
14103 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14104 (long) reloc->r_offset);
6ff71e76 14105 value = 0;
015dc7e1 14106 return true;
6ff71e76
NC
14107
14108 default:
14109 break;
14110 }
14111 break;
14112 }
252b5132
RH
14113 }
14114
015dc7e1 14115 return false;
252b5132
RH
14116}
14117
aca88567
NC
14118/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14119 DWARF debug sections. This is a target specific test. Note - we do not
14120 go through the whole including-target-headers-multiple-times route, (as
14121 we have already done with <elf/h8.h>) because this would become very
14122 messy and even then this function would have to contain target specific
14123 information (the names of the relocs instead of their numeric values).
14124 FIXME: This is not the correct way to solve this problem. The proper way
14125 is to have target specific reloc sizing and typing functions created by
14126 the reloc-macros.h header, in the same way that it already creates the
14127 reloc naming functions. */
14128
015dc7e1 14129static bool
dda8d76d 14130is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14131{
d347c9df 14132 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14133 switch (filedata->file_header.e_machine)
aca88567 14134 {
41e92641 14135 case EM_386:
22abe556 14136 case EM_IAMCU:
41e92641 14137 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14138 case EM_68K:
14139 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14140 case EM_860:
14141 return reloc_type == 1; /* R_860_32. */
14142 case EM_960:
14143 return reloc_type == 2; /* R_960_32. */
a06ea964 14144 case EM_AARCH64:
9282b95a
JW
14145 return (reloc_type == 258
14146 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14147 case EM_BPF:
14148 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14149 case EM_ADAPTEVA_EPIPHANY:
14150 return reloc_type == 3;
aca88567 14151 case EM_ALPHA:
137b6b5f 14152 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14153 case EM_ARC:
14154 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14155 case EM_ARC_COMPACT:
14156 case EM_ARC_COMPACT2:
14157 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14158 case EM_ARM:
14159 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14160 case EM_AVR_OLD:
aca88567
NC
14161 case EM_AVR:
14162 return reloc_type == 1;
14163 case EM_BLACKFIN:
14164 return reloc_type == 0x12; /* R_byte4_data. */
14165 case EM_CRIS:
14166 return reloc_type == 3; /* R_CRIS_32. */
14167 case EM_CR16:
14168 return reloc_type == 3; /* R_CR16_NUM32. */
14169 case EM_CRX:
14170 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14171 case EM_CSKY:
14172 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14173 case EM_CYGNUS_FRV:
14174 return reloc_type == 1;
41e92641
NC
14175 case EM_CYGNUS_D10V:
14176 case EM_D10V:
14177 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14178 case EM_CYGNUS_D30V:
14179 case EM_D30V:
14180 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14181 case EM_DLX:
14182 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14183 case EM_CYGNUS_FR30:
14184 case EM_FR30:
14185 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14186 case EM_FT32:
14187 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14188 case EM_H8S:
14189 case EM_H8_300:
14190 case EM_H8_300H:
14191 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14192 case EM_IA_64:
262cdac7
AM
14193 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14194 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14195 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14196 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14197 case EM_IP2K_OLD:
14198 case EM_IP2K:
14199 return reloc_type == 2; /* R_IP2K_32. */
14200 case EM_IQ2000:
14201 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14202 case EM_LATTICEMICO32:
14203 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14204 case EM_LOONGARCH:
14205 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14206 case EM_M32C_OLD:
aca88567
NC
14207 case EM_M32C:
14208 return reloc_type == 3; /* R_M32C_32. */
14209 case EM_M32R:
14210 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14211 case EM_68HC11:
14212 case EM_68HC12:
14213 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14214 case EM_S12Z:
2849d19f
JD
14215 return reloc_type == 7 || /* R_S12Z_EXT32 */
14216 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14217 case EM_MCORE:
14218 return reloc_type == 1; /* R_MCORE_ADDR32. */
14219 case EM_CYGNUS_MEP:
14220 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14221 case EM_METAG:
14222 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14223 case EM_MICROBLAZE:
14224 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14225 case EM_MIPS:
14226 return reloc_type == 2; /* R_MIPS_32. */
14227 case EM_MMIX:
14228 return reloc_type == 4; /* R_MMIX_32. */
14229 case EM_CYGNUS_MN10200:
14230 case EM_MN10200:
14231 return reloc_type == 1; /* R_MN10200_32. */
14232 case EM_CYGNUS_MN10300:
14233 case EM_MN10300:
14234 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14235 case EM_MOXIE:
14236 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14237 case EM_MSP430_OLD:
14238 case EM_MSP430:
13761a11 14239 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14240 case EM_MT:
14241 return reloc_type == 2; /* R_MT_32. */
35c08157 14242 case EM_NDS32:
81c5e376 14243 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14244 case EM_ALTERA_NIOS2:
36591ba1 14245 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14246 case EM_NIOS32:
14247 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14248 case EM_OR1K:
14249 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14250 case EM_PARISC:
9abca702 14251 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14252 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14253 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14254 case EM_PJ:
14255 case EM_PJ_OLD:
14256 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14257 case EM_PPC64:
14258 return reloc_type == 1; /* R_PPC64_ADDR32. */
14259 case EM_PPC:
14260 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14261 case EM_TI_PRU:
14262 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14263 case EM_RISCV:
14264 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14265 case EM_RL78:
14266 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14267 case EM_RX:
14268 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14269 case EM_S370:
14270 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14271 case EM_S390_OLD:
14272 case EM_S390:
14273 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14274 case EM_SCORE:
14275 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14276 case EM_SH:
14277 return reloc_type == 1; /* R_SH_DIR32. */
14278 case EM_SPARC32PLUS:
14279 case EM_SPARCV9:
14280 case EM_SPARC:
14281 return reloc_type == 3 /* R_SPARC_32. */
14282 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14283 case EM_SPU:
14284 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14285 case EM_TI_C6000:
14286 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14287 case EM_TILEGX:
14288 return reloc_type == 2; /* R_TILEGX_32. */
14289 case EM_TILEPRO:
14290 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14291 case EM_CYGNUS_V850:
14292 case EM_V850:
14293 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14294 case EM_V800:
14295 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14296 case EM_VAX:
14297 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14298 case EM_VISIUM:
14299 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14300 case EM_WEBASSEMBLY:
14301 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14302 case EM_X86_64:
8a9036a4 14303 case EM_L1OM:
7a9068fe 14304 case EM_K1OM:
aca88567 14305 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14306 case EM_XGATE:
14307 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14308 case EM_XSTORMY16:
14309 return reloc_type == 1; /* R_XSTROMY16_32. */
14310 case EM_XTENSA_OLD:
14311 case EM_XTENSA:
14312 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14313 case EM_Z80:
14314 return reloc_type == 6; /* R_Z80_32. */
aca88567 14315 default:
bee0ee85
NC
14316 {
14317 static unsigned int prev_warn = 0;
14318
14319 /* Avoid repeating the same warning multiple times. */
dda8d76d 14320 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14321 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14322 filedata->file_header.e_machine);
14323 prev_warn = filedata->file_header.e_machine;
015dc7e1 14324 return false;
bee0ee85 14325 }
aca88567
NC
14326 }
14327}
14328
14329/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14330 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14331
015dc7e1 14332static bool
dda8d76d 14333is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14334{
dda8d76d 14335 switch (filedata->file_header.e_machine)
d347c9df 14336 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14337 {
41e92641 14338 case EM_386:
22abe556 14339 case EM_IAMCU:
3e0873ac 14340 return reloc_type == 2; /* R_386_PC32. */
aca88567 14341 case EM_68K:
3e0873ac 14342 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14343 case EM_AARCH64:
14344 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14345 case EM_ADAPTEVA_EPIPHANY:
14346 return reloc_type == 6;
aca88567
NC
14347 case EM_ALPHA:
14348 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14349 case EM_ARC_COMPACT:
14350 case EM_ARC_COMPACT2:
14351 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14352 case EM_ARM:
3e0873ac 14353 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14354 case EM_AVR_OLD:
14355 case EM_AVR:
14356 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14357 case EM_LOONGARCH:
14358 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14359 case EM_MICROBLAZE:
14360 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14361 case EM_OR1K:
14362 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14363 case EM_PARISC:
85acf597 14364 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14365 case EM_PPC:
14366 return reloc_type == 26; /* R_PPC_REL32. */
14367 case EM_PPC64:
3e0873ac 14368 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14369 case EM_RISCV:
14370 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14371 case EM_S390_OLD:
14372 case EM_S390:
3e0873ac 14373 return reloc_type == 5; /* R_390_PC32. */
aca88567 14374 case EM_SH:
3e0873ac 14375 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14376 case EM_SPARC32PLUS:
14377 case EM_SPARCV9:
14378 case EM_SPARC:
3e0873ac 14379 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14380 case EM_SPU:
14381 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14382 case EM_TILEGX:
14383 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14384 case EM_TILEPRO:
14385 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14386 case EM_VISIUM:
14387 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14388 case EM_X86_64:
8a9036a4 14389 case EM_L1OM:
7a9068fe 14390 case EM_K1OM:
3e0873ac 14391 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14392 case EM_VAX:
14393 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14394 case EM_XTENSA_OLD:
14395 case EM_XTENSA:
14396 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14397 default:
14398 /* Do not abort or issue an error message here. Not all targets use
14399 pc-relative 32-bit relocs in their DWARF debug information and we
14400 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14401 more helpful warning message will be generated by apply_relocations
14402 anyway, so just return. */
015dc7e1 14403 return false;
aca88567
NC
14404 }
14405}
14406
14407/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14408 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14409
015dc7e1 14410static bool
dda8d76d 14411is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14412{
dda8d76d 14413 switch (filedata->file_header.e_machine)
aca88567 14414 {
a06ea964
NC
14415 case EM_AARCH64:
14416 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14417 case EM_ALPHA:
14418 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14419 case EM_IA_64:
262cdac7
AM
14420 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14421 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14422 case EM_LOONGARCH:
14423 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14424 case EM_PARISC:
14425 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14426 case EM_PPC64:
14427 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14428 case EM_RISCV:
14429 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14430 case EM_SPARC32PLUS:
14431 case EM_SPARCV9:
14432 case EM_SPARC:
714da62f
NC
14433 return reloc_type == 32 /* R_SPARC_64. */
14434 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14435 case EM_X86_64:
8a9036a4 14436 case EM_L1OM:
7a9068fe 14437 case EM_K1OM:
aca88567 14438 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14439 case EM_S390_OLD:
14440 case EM_S390:
aa137e4d
NC
14441 return reloc_type == 22; /* R_S390_64. */
14442 case EM_TILEGX:
14443 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14444 case EM_MIPS:
aa137e4d 14445 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14446 default:
015dc7e1 14447 return false;
aca88567
NC
14448 }
14449}
14450
85acf597
RH
14451/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14452 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14453
015dc7e1 14454static bool
dda8d76d 14455is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14456{
dda8d76d 14457 switch (filedata->file_header.e_machine)
85acf597 14458 {
a06ea964
NC
14459 case EM_AARCH64:
14460 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14461 case EM_ALPHA:
aa137e4d 14462 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14463 case EM_IA_64:
262cdac7
AM
14464 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14465 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14466 case EM_PARISC:
aa137e4d 14467 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14468 case EM_PPC64:
aa137e4d 14469 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14470 case EM_SPARC32PLUS:
14471 case EM_SPARCV9:
14472 case EM_SPARC:
aa137e4d 14473 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14474 case EM_X86_64:
8a9036a4 14475 case EM_L1OM:
7a9068fe 14476 case EM_K1OM:
aa137e4d 14477 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14478 case EM_S390_OLD:
14479 case EM_S390:
aa137e4d
NC
14480 return reloc_type == 23; /* R_S390_PC64. */
14481 case EM_TILEGX:
14482 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14483 default:
015dc7e1 14484 return false;
85acf597
RH
14485 }
14486}
14487
4dc3c23d
AM
14488/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14489 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14490
015dc7e1 14491static bool
dda8d76d 14492is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14493{
dda8d76d 14494 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14495 {
14496 case EM_CYGNUS_MN10200:
14497 case EM_MN10200:
14498 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14499 case EM_FT32:
14500 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14501 case EM_Z80:
14502 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14503 default:
015dc7e1 14504 return false;
4dc3c23d
AM
14505 }
14506}
14507
aca88567
NC
14508/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14509 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14510
015dc7e1 14511static bool
dda8d76d 14512is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14513{
d347c9df 14514 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14515 switch (filedata->file_header.e_machine)
4b78141a 14516 {
886a2506
NC
14517 case EM_ARC:
14518 case EM_ARC_COMPACT:
14519 case EM_ARC_COMPACT2:
14520 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14521 case EM_ADAPTEVA_EPIPHANY:
14522 return reloc_type == 5;
aca88567
NC
14523 case EM_AVR_OLD:
14524 case EM_AVR:
14525 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14526 case EM_CYGNUS_D10V:
14527 case EM_D10V:
14528 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14529 case EM_FT32:
14530 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14531 case EM_H8S:
14532 case EM_H8_300:
14533 case EM_H8_300H:
aca88567
NC
14534 return reloc_type == R_H8_DIR16;
14535 case EM_IP2K_OLD:
14536 case EM_IP2K:
14537 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14538 case EM_M32C_OLD:
f4236fe4
DD
14539 case EM_M32C:
14540 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14541 case EM_CYGNUS_MN10200:
14542 case EM_MN10200:
14543 return reloc_type == 2; /* R_MN10200_16. */
14544 case EM_CYGNUS_MN10300:
14545 case EM_MN10300:
14546 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14547 case EM_MSP430:
dda8d76d 14548 if (uses_msp430x_relocs (filedata))
13761a11 14549 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14550 /* Fall through. */
78c8d46c 14551 case EM_MSP430_OLD:
aca88567 14552 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14553 case EM_NDS32:
81c5e376 14554 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14555 case EM_ALTERA_NIOS2:
36591ba1 14556 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14557 case EM_NIOS32:
14558 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14559 case EM_OR1K:
14560 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14561 case EM_RISCV:
14562 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14563 case EM_TI_PRU:
14564 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14565 case EM_TI_C6000:
14566 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14567 case EM_VISIUM:
14568 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14569 case EM_XGATE:
14570 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14571 case EM_Z80:
14572 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14573 default:
015dc7e1 14574 return false;
4b78141a
NC
14575 }
14576}
14577
39e07931
AS
14578/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14579 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14580
015dc7e1 14581static bool
39e07931
AS
14582is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14583{
14584 switch (filedata->file_header.e_machine)
14585 {
14586 case EM_RISCV:
14587 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14588 case EM_Z80:
14589 return reloc_type == 1; /* R_Z80_8. */
39e07931 14590 default:
015dc7e1 14591 return false;
39e07931
AS
14592 }
14593}
14594
14595/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14596 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14597
015dc7e1 14598static bool
39e07931
AS
14599is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14600{
14601 switch (filedata->file_header.e_machine)
14602 {
14603 case EM_RISCV:
14604 return reloc_type == 53; /* R_RISCV_SET6. */
14605 default:
015dc7e1 14606 return false;
39e07931
AS
14607 }
14608}
14609
03336641
JW
14610/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14611 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14612
015dc7e1 14613static bool
03336641
JW
14614is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14615{
14616 /* Please keep this table alpha-sorted for ease of visual lookup. */
14617 switch (filedata->file_header.e_machine)
14618 {
14619 case EM_RISCV:
14620 return reloc_type == 35; /* R_RISCV_ADD32. */
14621 default:
015dc7e1 14622 return false;
03336641
JW
14623 }
14624}
14625
14626/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14627 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14628
015dc7e1 14629static bool
03336641
JW
14630is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14631{
14632 /* Please keep this table alpha-sorted for ease of visual lookup. */
14633 switch (filedata->file_header.e_machine)
14634 {
14635 case EM_RISCV:
14636 return reloc_type == 39; /* R_RISCV_SUB32. */
14637 default:
015dc7e1 14638 return false;
03336641
JW
14639 }
14640}
14641
14642/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14643 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14644
015dc7e1 14645static bool
03336641
JW
14646is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14647{
14648 /* Please keep this table alpha-sorted for ease of visual lookup. */
14649 switch (filedata->file_header.e_machine)
14650 {
14651 case EM_RISCV:
14652 return reloc_type == 36; /* R_RISCV_ADD64. */
14653 default:
015dc7e1 14654 return false;
03336641
JW
14655 }
14656}
14657
14658/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14659 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14660
015dc7e1 14661static bool
03336641
JW
14662is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14663{
14664 /* Please keep this table alpha-sorted for ease of visual lookup. */
14665 switch (filedata->file_header.e_machine)
14666 {
14667 case EM_RISCV:
14668 return reloc_type == 40; /* R_RISCV_SUB64. */
14669 default:
015dc7e1 14670 return false;
03336641
JW
14671 }
14672}
14673
14674/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14675 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14676
015dc7e1 14677static bool
03336641
JW
14678is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14679{
14680 /* Please keep this table alpha-sorted for ease of visual lookup. */
14681 switch (filedata->file_header.e_machine)
14682 {
14683 case EM_RISCV:
14684 return reloc_type == 34; /* R_RISCV_ADD16. */
14685 default:
015dc7e1 14686 return false;
03336641
JW
14687 }
14688}
14689
14690/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14691 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14692
015dc7e1 14693static bool
03336641
JW
14694is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14695{
14696 /* Please keep this table alpha-sorted for ease of visual lookup. */
14697 switch (filedata->file_header.e_machine)
14698 {
14699 case EM_RISCV:
14700 return reloc_type == 38; /* R_RISCV_SUB16. */
14701 default:
015dc7e1 14702 return false;
03336641
JW
14703 }
14704}
14705
14706/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14707 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14708
015dc7e1 14709static bool
03336641
JW
14710is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14711{
14712 /* Please keep this table alpha-sorted for ease of visual lookup. */
14713 switch (filedata->file_header.e_machine)
14714 {
14715 case EM_RISCV:
14716 return reloc_type == 33; /* R_RISCV_ADD8. */
14717 default:
015dc7e1 14718 return false;
03336641
JW
14719 }
14720}
14721
14722/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14723 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14724
015dc7e1 14725static bool
03336641
JW
14726is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14727{
14728 /* Please keep this table alpha-sorted for ease of visual lookup. */
14729 switch (filedata->file_header.e_machine)
14730 {
14731 case EM_RISCV:
14732 return reloc_type == 37; /* R_RISCV_SUB8. */
14733 default:
015dc7e1 14734 return false;
03336641
JW
14735 }
14736}
14737
39e07931
AS
14738/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14739 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14740
015dc7e1 14741static bool
39e07931
AS
14742is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14743{
14744 switch (filedata->file_header.e_machine)
14745 {
14746 case EM_RISCV:
14747 return reloc_type == 52; /* R_RISCV_SUB6. */
14748 default:
015dc7e1 14749 return false;
39e07931
AS
14750 }
14751}
14752
2a7b2e88
JK
14753/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14754 relocation entries (possibly formerly used for SHT_GROUP sections). */
14755
015dc7e1 14756static bool
dda8d76d 14757is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14758{
dda8d76d 14759 switch (filedata->file_header.e_machine)
2a7b2e88 14760 {
cb8f3167 14761 case EM_386: /* R_386_NONE. */
d347c9df 14762 case EM_68K: /* R_68K_NONE. */
cfb8c092 14763 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14764 case EM_ALPHA: /* R_ALPHA_NONE. */
14765 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14766 case EM_ARC: /* R_ARC_NONE. */
886a2506 14767 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14768 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14769 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14770 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14771 case EM_FT32: /* R_FT32_NONE. */
14772 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14773 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14774 case EM_L1OM: /* R_X86_64_NONE. */
14775 case EM_M32R: /* R_M32R_NONE. */
14776 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14777 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14778 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14779 case EM_NIOS32: /* R_NIOS_NONE. */
14780 case EM_OR1K: /* R_OR1K_NONE. */
14781 case EM_PARISC: /* R_PARISC_NONE. */
14782 case EM_PPC64: /* R_PPC64_NONE. */
14783 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14784 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14785 case EM_S390: /* R_390_NONE. */
14786 case EM_S390_OLD:
14787 case EM_SH: /* R_SH_NONE. */
14788 case EM_SPARC32PLUS:
14789 case EM_SPARC: /* R_SPARC_NONE. */
14790 case EM_SPARCV9:
aa137e4d
NC
14791 case EM_TILEGX: /* R_TILEGX_NONE. */
14792 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14793 case EM_TI_C6000:/* R_C6000_NONE. */
14794 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14795 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14796 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14797 return reloc_type == 0;
d347c9df 14798
a06ea964
NC
14799 case EM_AARCH64:
14800 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14801 case EM_AVR_OLD:
14802 case EM_AVR:
14803 return (reloc_type == 0 /* R_AVR_NONE. */
14804 || reloc_type == 30 /* R_AVR_DIFF8. */
14805 || reloc_type == 31 /* R_AVR_DIFF16. */
14806 || reloc_type == 32 /* R_AVR_DIFF32. */);
14807 case EM_METAG:
14808 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14809 case EM_NDS32:
81c5e376
AM
14810 return (reloc_type == 0 /* R_NDS32_NONE. */
14811 || reloc_type == 205 /* R_NDS32_DIFF8. */
14812 || reloc_type == 206 /* R_NDS32_DIFF16. */
14813 || reloc_type == 207 /* R_NDS32_DIFF32. */
14814 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14815 case EM_TI_PRU:
14816 return (reloc_type == 0 /* R_PRU_NONE. */
14817 || reloc_type == 65 /* R_PRU_DIFF8. */
14818 || reloc_type == 66 /* R_PRU_DIFF16. */
14819 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14820 case EM_XTENSA_OLD:
14821 case EM_XTENSA:
4dc3c23d
AM
14822 return (reloc_type == 0 /* R_XTENSA_NONE. */
14823 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14824 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14825 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14826 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14827 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14828 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14829 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14830 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14831 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14832 }
015dc7e1 14833 return false;
2a7b2e88
JK
14834}
14835
d1c4b12b
NC
14836/* Returns TRUE if there is a relocation against
14837 section NAME at OFFSET bytes. */
14838
015dc7e1 14839bool
d1c4b12b
NC
14840reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14841{
14842 Elf_Internal_Rela * relocs;
14843 Elf_Internal_Rela * rp;
14844
14845 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14846 return false;
d1c4b12b
NC
14847
14848 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14849
14850 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14851 if (rp->r_offset == offset)
015dc7e1 14852 return true;
d1c4b12b 14853
015dc7e1 14854 return false;
d1c4b12b
NC
14855}
14856
cf13d699 14857/* Apply relocations to a section.
32ec8896
NC
14858 Returns TRUE upon success, FALSE otherwise.
14859 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14860 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14861 will be set to the number of relocs loaded.
14862
cf13d699 14863 Note: So far support has been added only for those relocations
32ec8896
NC
14864 which can be found in debug sections. FIXME: Add support for
14865 more relocations ? */
1b315056 14866
015dc7e1 14867static bool
be7d229a
AM
14868apply_relocations (Filedata *filedata,
14869 const Elf_Internal_Shdr *section,
14870 unsigned char *start,
14871 size_t size,
14872 void **relocs_return,
14873 unsigned long *num_relocs_return)
1b315056 14874{
cf13d699 14875 Elf_Internal_Shdr * relsec;
0d2a7a93 14876 unsigned char * end = start + size;
cb8f3167 14877
d1c4b12b
NC
14878 if (relocs_return != NULL)
14879 {
14880 * (Elf_Internal_Rela **) relocs_return = NULL;
14881 * num_relocs_return = 0;
14882 }
14883
dda8d76d 14884 if (filedata->file_header.e_type != ET_REL)
32ec8896 14885 /* No relocs to apply. */
015dc7e1 14886 return true;
1b315056 14887
cf13d699 14888 /* Find the reloc section associated with the section. */
dda8d76d
NC
14889 for (relsec = filedata->section_headers;
14890 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14891 ++relsec)
252b5132 14892 {
015dc7e1 14893 bool is_rela;
41e92641 14894 unsigned long num_relocs;
2cf0635d
NC
14895 Elf_Internal_Rela * relocs;
14896 Elf_Internal_Rela * rp;
14897 Elf_Internal_Shdr * symsec;
14898 Elf_Internal_Sym * symtab;
ba5cdace 14899 unsigned long num_syms;
2cf0635d 14900 Elf_Internal_Sym * sym;
252b5132 14901
41e92641 14902 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14903 || relsec->sh_info >= filedata->file_header.e_shnum
14904 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14905 || relsec->sh_size == 0
dda8d76d 14906 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14907 continue;
428409d5 14908
a788aedd
AM
14909 symsec = filedata->section_headers + relsec->sh_link;
14910 if (symsec->sh_type != SHT_SYMTAB
14911 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14912 return false;
a788aedd 14913
41e92641
NC
14914 is_rela = relsec->sh_type == SHT_RELA;
14915
14916 if (is_rela)
14917 {
dda8d76d 14918 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14919 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14920 return false;
41e92641
NC
14921 }
14922 else
14923 {
dda8d76d 14924 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14925 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14926 return false;
41e92641
NC
14927 }
14928
14929 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14930 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14931 is_rela = false;
428409d5 14932
4de91c10 14933 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14934
41e92641 14935 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14936 {
015dc7e1
AM
14937 bfd_vma addend;
14938 unsigned int reloc_type;
14939 unsigned int reloc_size;
14940 bool reloc_inplace = false;
14941 bool reloc_subtract = false;
14942 unsigned char *rloc;
14943 unsigned long sym_index;
4b78141a 14944
dda8d76d 14945 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14946
dda8d76d 14947 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14948 continue;
dda8d76d 14949 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14950 continue;
dda8d76d
NC
14951 else if (is_32bit_abs_reloc (filedata, reloc_type)
14952 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14953 reloc_size = 4;
dda8d76d
NC
14954 else if (is_64bit_abs_reloc (filedata, reloc_type)
14955 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14956 reloc_size = 8;
dda8d76d 14957 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14958 reloc_size = 3;
dda8d76d 14959 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14960 reloc_size = 2;
39e07931
AS
14961 else if (is_8bit_abs_reloc (filedata, reloc_type)
14962 || is_6bit_abs_reloc (filedata, reloc_type))
14963 reloc_size = 1;
03336641
JW
14964 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14965 reloc_type))
14966 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14967 {
14968 reloc_size = 4;
015dc7e1 14969 reloc_inplace = true;
03336641
JW
14970 }
14971 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14972 reloc_type))
14973 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14974 {
14975 reloc_size = 8;
015dc7e1 14976 reloc_inplace = true;
03336641
JW
14977 }
14978 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14979 reloc_type))
14980 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14981 {
14982 reloc_size = 2;
015dc7e1 14983 reloc_inplace = true;
03336641
JW
14984 }
14985 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14986 reloc_type))
14987 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14988 {
14989 reloc_size = 1;
015dc7e1 14990 reloc_inplace = true;
03336641 14991 }
39e07931
AS
14992 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14993 reloc_type)))
14994 {
14995 reloc_size = 1;
015dc7e1 14996 reloc_inplace = true;
39e07931 14997 }
aca88567 14998 else
4b78141a 14999 {
bee0ee85 15000 static unsigned int prev_reloc = 0;
dda8d76d 15001
bee0ee85
NC
15002 if (reloc_type != prev_reloc)
15003 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15004 reloc_type, printable_section_name (filedata, section));
bee0ee85 15005 prev_reloc = reloc_type;
4b78141a
NC
15006 continue;
15007 }
103f02d3 15008
91d6fa6a 15009 rloc = start + rp->r_offset;
75802ccb 15010 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15011 {
15012 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15013 (unsigned long) rp->r_offset,
dda8d76d 15014 printable_section_name (filedata, section));
700dd8b7
L
15015 continue;
15016 }
103f02d3 15017
ba5cdace
NC
15018 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15019 if (sym_index >= num_syms)
15020 {
15021 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15022 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15023 continue;
15024 }
15025 sym = symtab + sym_index;
41e92641
NC
15026
15027 /* If the reloc has a symbol associated with it,
55f25fc3
L
15028 make sure that it is of an appropriate type.
15029
15030 Relocations against symbols without type can happen.
15031 Gcc -feliminate-dwarf2-dups may generate symbols
15032 without type for debug info.
15033
15034 Icc generates relocations against function symbols
15035 instead of local labels.
15036
15037 Relocations against object symbols can happen, eg when
15038 referencing a global array. For an example of this see
15039 the _clz.o binary in libgcc.a. */
aca88567 15040 if (sym != symtab
b8871f35 15041 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15042 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15043 {
d3a49aa8 15044 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15045 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15046 printable_section_name (filedata, relsec),
d3a49aa8 15047 (long int)(rp - relocs));
aca88567 15048 continue;
5b18a4bc 15049 }
252b5132 15050
4dc3c23d
AM
15051 addend = 0;
15052 if (is_rela)
15053 addend += rp->r_addend;
c47320c3
AM
15054 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15055 partial_inplace. */
4dc3c23d 15056 if (!is_rela
dda8d76d 15057 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15058 && reloc_type == 1)
dda8d76d
NC
15059 || ((filedata->file_header.e_machine == EM_PJ
15060 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15061 && reloc_type == 1)
dda8d76d
NC
15062 || ((filedata->file_header.e_machine == EM_D30V
15063 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15064 && reloc_type == 12)
15065 || reloc_inplace)
39e07931
AS
15066 {
15067 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15068 addend += byte_get (rloc, reloc_size) & 0x3f;
15069 else
15070 addend += byte_get (rloc, reloc_size);
15071 }
cb8f3167 15072
dda8d76d
NC
15073 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15074 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15075 {
15076 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15077 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15078 addend -= 8;
91d6fa6a 15079 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15080 reloc_size);
15081 }
39e07931
AS
15082 else if (is_6bit_abs_reloc (filedata, reloc_type)
15083 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15084 {
15085 if (reloc_subtract)
15086 addend -= sym->st_value;
15087 else
15088 addend += sym->st_value;
15089 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15090 byte_put (rloc, addend, reloc_size);
15091 }
03336641
JW
15092 else if (reloc_subtract)
15093 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15094 else
91d6fa6a 15095 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15096 }
252b5132 15097
5b18a4bc 15098 free (symtab);
f84ce13b
NC
15099 /* Let the target specific reloc processing code know that
15100 we have finished with these relocs. */
dda8d76d 15101 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15102
15103 if (relocs_return)
15104 {
15105 * (Elf_Internal_Rela **) relocs_return = relocs;
15106 * num_relocs_return = num_relocs;
15107 }
15108 else
15109 free (relocs);
15110
5b18a4bc
NC
15111 break;
15112 }
32ec8896 15113
015dc7e1 15114 return true;
5b18a4bc 15115}
103f02d3 15116
cf13d699 15117#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15118static bool
dda8d76d 15119disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15120{
dda8d76d 15121 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15122
74e1a04b 15123 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15124
015dc7e1 15125 return true;
cf13d699
NC
15126}
15127#endif
15128
15129/* Reads in the contents of SECTION from FILE, returning a pointer
15130 to a malloc'ed buffer or NULL if something went wrong. */
15131
15132static char *
dda8d76d 15133get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15134{
be7d229a 15135 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15136
15137 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15138 {
c6b78c96 15139 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15140 printable_section_name (filedata, section));
cf13d699
NC
15141 return NULL;
15142 }
15143
dda8d76d 15144 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15145 _("section contents"));
cf13d699
NC
15146}
15147
0e602686
NC
15148/* Uncompresses a section that was compressed using zlib, in place. */
15149
015dc7e1 15150static bool
dda8d76d
NC
15151uncompress_section_contents (unsigned char ** buffer,
15152 dwarf_size_type uncompressed_size,
15153 dwarf_size_type * size)
0e602686
NC
15154{
15155 dwarf_size_type compressed_size = *size;
15156 unsigned char * compressed_buffer = *buffer;
15157 unsigned char * uncompressed_buffer;
15158 z_stream strm;
15159 int rc;
15160
15161 /* It is possible the section consists of several compressed
15162 buffers concatenated together, so we uncompress in a loop. */
15163 /* PR 18313: The state field in the z_stream structure is supposed
15164 to be invisible to the user (ie us), but some compilers will
15165 still complain about it being used without initialisation. So
15166 we first zero the entire z_stream structure and then set the fields
15167 that we need. */
15168 memset (& strm, 0, sizeof strm);
15169 strm.avail_in = compressed_size;
15170 strm.next_in = (Bytef *) compressed_buffer;
15171 strm.avail_out = uncompressed_size;
15172 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15173
15174 rc = inflateInit (& strm);
15175 while (strm.avail_in > 0)
15176 {
15177 if (rc != Z_OK)
3624a6c1 15178 break;
0e602686
NC
15179 strm.next_out = ((Bytef *) uncompressed_buffer
15180 + (uncompressed_size - strm.avail_out));
15181 rc = inflate (&strm, Z_FINISH);
15182 if (rc != Z_STREAM_END)
3624a6c1 15183 break;
0e602686
NC
15184 rc = inflateReset (& strm);
15185 }
ad92f33d
AM
15186 if (inflateEnd (& strm) != Z_OK
15187 || rc != Z_OK
0e602686
NC
15188 || strm.avail_out != 0)
15189 goto fail;
15190
15191 *buffer = uncompressed_buffer;
15192 *size = uncompressed_size;
015dc7e1 15193 return true;
0e602686
NC
15194
15195 fail:
15196 free (uncompressed_buffer);
15197 /* Indicate decompression failure. */
15198 *buffer = NULL;
015dc7e1 15199 return false;
0e602686 15200}
dd24e3da 15201
015dc7e1 15202static bool
dda8d76d 15203dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15204{
015dc7e1 15205 Elf_Internal_Shdr *relsec;
be7d229a 15206 uint64_t num_bytes;
015dc7e1
AM
15207 unsigned char *data;
15208 unsigned char *end;
15209 unsigned char *real_start;
15210 unsigned char *start;
15211 bool some_strings_shown;
cf13d699 15212
dda8d76d 15213 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15214 if (start == NULL)
c6b78c96 15215 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15216 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15217
0e602686 15218 num_bytes = section->sh_size;
cf13d699 15219
835f2fae
NC
15220 if (filedata->is_separate)
15221 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15222 printable_section_name (filedata, section),
15223 filedata->file_name);
15224 else
15225 printf (_("\nString dump of section '%s':\n"),
15226 printable_section_name (filedata, section));
cf13d699 15227
0e602686
NC
15228 if (decompress_dumps)
15229 {
15230 dwarf_size_type new_size = num_bytes;
15231 dwarf_size_type uncompressed_size = 0;
15232
15233 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15234 {
15235 Elf_Internal_Chdr chdr;
15236 unsigned int compression_header_size
ebdf1ebf
NC
15237 = get_compression_header (& chdr, (unsigned char *) start,
15238 num_bytes);
5844b465
NC
15239 if (compression_header_size == 0)
15240 /* An error message will have already been generated
15241 by get_compression_header. */
15242 goto error_out;
0e602686 15243
813dabb9 15244 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15245 {
813dabb9 15246 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15247 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15248 goto error_out;
813dabb9 15249 }
813dabb9
L
15250 uncompressed_size = chdr.ch_size;
15251 start += compression_header_size;
15252 new_size -= compression_header_size;
0e602686
NC
15253 }
15254 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15255 {
15256 /* Read the zlib header. In this case, it should be "ZLIB"
15257 followed by the uncompressed section size, 8 bytes in
15258 big-endian order. */
15259 uncompressed_size = start[4]; uncompressed_size <<= 8;
15260 uncompressed_size += start[5]; uncompressed_size <<= 8;
15261 uncompressed_size += start[6]; uncompressed_size <<= 8;
15262 uncompressed_size += start[7]; uncompressed_size <<= 8;
15263 uncompressed_size += start[8]; uncompressed_size <<= 8;
15264 uncompressed_size += start[9]; uncompressed_size <<= 8;
15265 uncompressed_size += start[10]; uncompressed_size <<= 8;
15266 uncompressed_size += start[11];
15267 start += 12;
15268 new_size -= 12;
15269 }
15270
1835f746
NC
15271 if (uncompressed_size)
15272 {
15273 if (uncompress_section_contents (& start,
15274 uncompressed_size, & new_size))
15275 num_bytes = new_size;
15276 else
15277 {
15278 error (_("Unable to decompress section %s\n"),
dda8d76d 15279 printable_section_name (filedata, section));
f761cb13 15280 goto error_out;
1835f746
NC
15281 }
15282 }
bc303e5d
NC
15283 else
15284 start = real_start;
0e602686 15285 }
fd8008d8 15286
cf13d699
NC
15287 /* If the section being dumped has relocations against it the user might
15288 be expecting these relocations to have been applied. Check for this
15289 case and issue a warning message in order to avoid confusion.
15290 FIXME: Maybe we ought to have an option that dumps a section with
15291 relocs applied ? */
dda8d76d
NC
15292 for (relsec = filedata->section_headers;
15293 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15294 ++relsec)
15295 {
15296 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15297 || relsec->sh_info >= filedata->file_header.e_shnum
15298 || filedata->section_headers + relsec->sh_info != section
cf13d699 15299 || relsec->sh_size == 0
dda8d76d 15300 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15301 continue;
15302
15303 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15304 break;
15305 }
15306
cf13d699
NC
15307 data = start;
15308 end = start + num_bytes;
015dc7e1 15309 some_strings_shown = false;
cf13d699 15310
ba3265d0
NC
15311#ifdef HAVE_MBSTATE_T
15312 mbstate_t state;
15313 /* Initialise the multibyte conversion state. */
15314 memset (& state, 0, sizeof (state));
15315#endif
15316
015dc7e1 15317 bool continuing = false;
ba3265d0 15318
cf13d699
NC
15319 while (data < end)
15320 {
15321 while (!ISPRINT (* data))
15322 if (++ data >= end)
15323 break;
15324
15325 if (data < end)
15326 {
071436c6
NC
15327 size_t maxlen = end - data;
15328
ba3265d0
NC
15329 if (continuing)
15330 {
15331 printf (" ");
015dc7e1 15332 continuing = false;
ba3265d0
NC
15333 }
15334 else
15335 {
d1ce973e 15336 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15337 }
15338
4082ef84
NC
15339 if (maxlen > 0)
15340 {
f3da8a96 15341 char c = 0;
ba3265d0
NC
15342
15343 while (maxlen)
15344 {
15345 c = *data++;
15346
15347 if (c == 0)
15348 break;
15349
15350 /* PR 25543: Treat new-lines as string-ending characters. */
15351 if (c == '\n')
15352 {
15353 printf ("\\n\n");
15354 if (*data != 0)
015dc7e1 15355 continuing = true;
ba3265d0
NC
15356 break;
15357 }
15358
15359 /* Do not print control characters directly as they can affect terminal
15360 settings. Such characters usually appear in the names generated
15361 by the assembler for local labels. */
15362 if (ISCNTRL (c))
15363 {
15364 printf ("^%c", c + 0x40);
15365 }
15366 else if (ISPRINT (c))
15367 {
15368 putchar (c);
15369 }
15370 else
15371 {
15372 size_t n;
15373#ifdef HAVE_MBSTATE_T
15374 wchar_t w;
15375#endif
15376 /* Let printf do the hard work of displaying multibyte characters. */
15377 printf ("%.1s", data - 1);
15378#ifdef HAVE_MBSTATE_T
15379 /* Try to find out how many bytes made up the character that was
15380 just printed. Advance the symbol pointer past the bytes that
15381 were displayed. */
15382 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15383#else
15384 n = 1;
15385#endif
15386 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15387 data += (n - 1);
15388 }
15389 }
15390
15391 if (c != '\n')
15392 putchar ('\n');
4082ef84
NC
15393 }
15394 else
15395 {
15396 printf (_("<corrupt>\n"));
15397 data = end;
15398 }
015dc7e1 15399 some_strings_shown = true;
cf13d699
NC
15400 }
15401 }
15402
15403 if (! some_strings_shown)
15404 printf (_(" No strings found in this section."));
15405
0e602686 15406 free (real_start);
cf13d699
NC
15407
15408 putchar ('\n');
015dc7e1 15409 return true;
f761cb13
AM
15410
15411error_out:
15412 free (real_start);
015dc7e1 15413 return false;
cf13d699
NC
15414}
15415
015dc7e1
AM
15416static bool
15417dump_section_as_bytes (Elf_Internal_Shdr *section,
15418 Filedata *filedata,
15419 bool relocate)
cf13d699 15420{
be7d229a
AM
15421 Elf_Internal_Shdr *relsec;
15422 size_t bytes;
15423 uint64_t section_size;
15424 bfd_vma addr;
15425 unsigned char *data;
15426 unsigned char *real_start;
15427 unsigned char *start;
0e602686 15428
dda8d76d 15429 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15430 if (start == NULL)
c6b78c96 15431 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15432 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15433
0e602686 15434 section_size = section->sh_size;
cf13d699 15435
835f2fae
NC
15436 if (filedata->is_separate)
15437 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15438 printable_section_name (filedata, section),
15439 filedata->file_name);
15440 else
15441 printf (_("\nHex dump of section '%s':\n"),
15442 printable_section_name (filedata, section));
cf13d699 15443
0e602686
NC
15444 if (decompress_dumps)
15445 {
15446 dwarf_size_type new_size = section_size;
15447 dwarf_size_type uncompressed_size = 0;
15448
15449 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15450 {
15451 Elf_Internal_Chdr chdr;
15452 unsigned int compression_header_size
ebdf1ebf 15453 = get_compression_header (& chdr, start, section_size);
0e602686 15454
5844b465
NC
15455 if (compression_header_size == 0)
15456 /* An error message will have already been generated
15457 by get_compression_header. */
15458 goto error_out;
15459
813dabb9 15460 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15461 {
813dabb9 15462 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15463 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15464 goto error_out;
0e602686 15465 }
813dabb9
L
15466 uncompressed_size = chdr.ch_size;
15467 start += compression_header_size;
15468 new_size -= compression_header_size;
0e602686
NC
15469 }
15470 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15471 {
15472 /* Read the zlib header. In this case, it should be "ZLIB"
15473 followed by the uncompressed section size, 8 bytes in
15474 big-endian order. */
15475 uncompressed_size = start[4]; uncompressed_size <<= 8;
15476 uncompressed_size += start[5]; uncompressed_size <<= 8;
15477 uncompressed_size += start[6]; uncompressed_size <<= 8;
15478 uncompressed_size += start[7]; uncompressed_size <<= 8;
15479 uncompressed_size += start[8]; uncompressed_size <<= 8;
15480 uncompressed_size += start[9]; uncompressed_size <<= 8;
15481 uncompressed_size += start[10]; uncompressed_size <<= 8;
15482 uncompressed_size += start[11];
15483 start += 12;
15484 new_size -= 12;
15485 }
15486
f055032e
NC
15487 if (uncompressed_size)
15488 {
15489 if (uncompress_section_contents (& start, uncompressed_size,
15490 & new_size))
bc303e5d
NC
15491 {
15492 section_size = new_size;
15493 }
f055032e
NC
15494 else
15495 {
15496 error (_("Unable to decompress section %s\n"),
dda8d76d 15497 printable_section_name (filedata, section));
bc303e5d 15498 /* FIXME: Print the section anyway ? */
f761cb13 15499 goto error_out;
f055032e
NC
15500 }
15501 }
bc303e5d
NC
15502 else
15503 start = real_start;
0e602686 15504 }
14ae95f2 15505
cf13d699
NC
15506 if (relocate)
15507 {
dda8d76d 15508 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15509 goto error_out;
cf13d699
NC
15510 }
15511 else
15512 {
15513 /* If the section being dumped has relocations against it the user might
15514 be expecting these relocations to have been applied. Check for this
15515 case and issue a warning message in order to avoid confusion.
15516 FIXME: Maybe we ought to have an option that dumps a section with
15517 relocs applied ? */
dda8d76d
NC
15518 for (relsec = filedata->section_headers;
15519 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15520 ++relsec)
15521 {
15522 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15523 || relsec->sh_info >= filedata->file_header.e_shnum
15524 || filedata->section_headers + relsec->sh_info != section
cf13d699 15525 || relsec->sh_size == 0
dda8d76d 15526 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15527 continue;
15528
15529 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15530 break;
15531 }
15532 }
15533
15534 addr = section->sh_addr;
0e602686 15535 bytes = section_size;
cf13d699
NC
15536 data = start;
15537
15538 while (bytes)
15539 {
15540 int j;
15541 int k;
15542 int lbytes;
15543
15544 lbytes = (bytes > 16 ? 16 : bytes);
15545
15546 printf (" 0x%8.8lx ", (unsigned long) addr);
15547
15548 for (j = 0; j < 16; j++)
15549 {
15550 if (j < lbytes)
15551 printf ("%2.2x", data[j]);
15552 else
15553 printf (" ");
15554
15555 if ((j & 3) == 3)
15556 printf (" ");
15557 }
15558
15559 for (j = 0; j < lbytes; j++)
15560 {
15561 k = data[j];
15562 if (k >= ' ' && k < 0x7f)
15563 printf ("%c", k);
15564 else
15565 printf (".");
15566 }
15567
15568 putchar ('\n');
15569
15570 data += lbytes;
15571 addr += lbytes;
15572 bytes -= lbytes;
15573 }
15574
0e602686 15575 free (real_start);
cf13d699
NC
15576
15577 putchar ('\n');
015dc7e1 15578 return true;
f761cb13
AM
15579
15580 error_out:
15581 free (real_start);
015dc7e1 15582 return false;
cf13d699
NC
15583}
15584
094e34f2 15585#ifdef ENABLE_LIBCTF
7d9813f1
NA
15586static ctf_sect_t *
15587shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15588{
84714f86 15589 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15590 buf->cts_size = shdr->sh_size;
15591 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15592
15593 return buf;
15594}
15595
15596/* Formatting callback function passed to ctf_dump. Returns either the pointer
15597 it is passed, or a pointer to newly-allocated storage, in which case
15598 dump_ctf() will free it when it no longer needs it. */
15599
2f6ecaed
NA
15600static char *
15601dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15602 char *s, void *arg)
7d9813f1 15603{
3e50a591 15604 const char *blanks = arg;
7d9813f1
NA
15605 char *new_s;
15606
3e50a591 15607 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15608 return s;
15609 return new_s;
15610}
15611
926c9e76
NA
15612/* Dump CTF errors/warnings. */
15613static void
139633c3 15614dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15615{
15616 ctf_next_t *it = NULL;
15617 char *errtext;
15618 int is_warning;
15619 int err;
15620
15621 /* Dump accumulated errors and warnings. */
15622 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15623 {
5e9b84f7 15624 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15625 errtext);
15626 free (errtext);
15627 }
15628 if (err != ECTF_NEXT_END)
15629 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15630}
15631
2f6ecaed
NA
15632/* Dump one CTF archive member. */
15633
80b56fad
NA
15634static void
15635dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15636 size_t member)
2f6ecaed 15637{
2f6ecaed
NA
15638 const char *things[] = {"Header", "Labels", "Data objects",
15639 "Function objects", "Variables", "Types", "Strings",
15640 ""};
15641 const char **thing;
15642 size_t i;
15643
80b56fad
NA
15644 /* Don't print out the name of the default-named archive member if it appears
15645 first in the list. The name .ctf appears everywhere, even for things that
15646 aren't really archives, so printing it out is liable to be confusing; also,
15647 the common case by far is for only one archive member to exist, and hiding
15648 it in that case seems worthwhile. */
2f6ecaed 15649
80b56fad
NA
15650 if (strcmp (name, ".ctf") != 0 || member != 0)
15651 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15652
80b56fad
NA
15653 if (ctf_parent_name (ctf) != NULL)
15654 ctf_import (ctf, parent);
2f6ecaed
NA
15655
15656 for (i = 0, thing = things; *thing[0]; thing++, i++)
15657 {
15658 ctf_dump_state_t *s = NULL;
15659 char *item;
15660
15661 printf ("\n %s:\n", *thing);
15662 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15663 (void *) " ")) != NULL)
15664 {
15665 printf ("%s\n", item);
15666 free (item);
15667 }
15668
15669 if (ctf_errno (ctf))
15670 {
15671 error (_("Iteration failed: %s, %s\n"), *thing,
15672 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15673 break;
2f6ecaed
NA
15674 }
15675 }
8b37e7b6 15676
926c9e76 15677 dump_ctf_errs (ctf);
2f6ecaed
NA
15678}
15679
015dc7e1 15680static bool
7d9813f1
NA
15681dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15682{
7d9813f1
NA
15683 Elf_Internal_Shdr * symtab_sec = NULL;
15684 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15685 void * data = NULL;
15686 void * symdata = NULL;
15687 void * strdata = NULL;
80b56fad 15688 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15689 ctf_sect_t * symsectp = NULL;
15690 ctf_sect_t * strsectp = NULL;
2f6ecaed 15691 ctf_archive_t * ctfa = NULL;
139633c3 15692 ctf_dict_t * parent = NULL;
80b56fad 15693 ctf_dict_t * fp;
7d9813f1 15694
80b56fad
NA
15695 ctf_next_t *i = NULL;
15696 const char *name;
15697 size_t member = 0;
7d9813f1 15698 int err;
015dc7e1 15699 bool ret = false;
7d9813f1
NA
15700
15701 shdr_to_ctf_sect (&ctfsect, section, filedata);
15702 data = get_section_contents (section, filedata);
15703 ctfsect.cts_data = data;
15704
616febde 15705 if (!dump_ctf_symtab_name)
3d16b64e 15706 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15707
15708 if (!dump_ctf_strtab_name)
3d16b64e 15709 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15710
15711 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15712 {
15713 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15714 {
15715 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15716 goto fail;
15717 }
15718 if ((symdata = (void *) get_data (NULL, filedata,
15719 symtab_sec->sh_offset, 1,
15720 symtab_sec->sh_size,
15721 _("symbols"))) == NULL)
15722 goto fail;
15723 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15724 symsect.cts_data = symdata;
15725 }
835f2fae 15726
df16e041 15727 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15728 {
15729 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15730 {
15731 error (_("No string table section named %s\n"),
15732 dump_ctf_strtab_name);
15733 goto fail;
15734 }
15735 if ((strdata = (void *) get_data (NULL, filedata,
15736 strtab_sec->sh_offset, 1,
15737 strtab_sec->sh_size,
15738 _("strings"))) == NULL)
15739 goto fail;
15740 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15741 strsect.cts_data = strdata;
15742 }
835f2fae 15743
2f6ecaed
NA
15744 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15745 libctf papers over the difference, so we can pretend it is always an
80b56fad 15746 archive. */
7d9813f1 15747
2f6ecaed 15748 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15749 {
926c9e76 15750 dump_ctf_errs (NULL);
7d9813f1
NA
15751 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15752 goto fail;
15753 }
15754
96c61be5
NA
15755 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15756 != ELFDATA2MSB);
15757
80b56fad
NA
15758 /* Preload the parent dict, since it will need to be imported into every
15759 child in turn. */
15760 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15761 {
926c9e76 15762 dump_ctf_errs (NULL);
2f6ecaed
NA
15763 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15764 goto fail;
7d9813f1
NA
15765 }
15766
015dc7e1 15767 ret = true;
7d9813f1 15768
835f2fae
NC
15769 if (filedata->is_separate)
15770 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15771 printable_section_name (filedata, section),
15772 filedata->file_name);
15773 else
15774 printf (_("\nDump of CTF section '%s':\n"),
15775 printable_section_name (filedata, section));
7d9813f1 15776
80b56fad
NA
15777 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15778 dump_ctf_archive_member (fp, name, parent, member++);
15779 if (err != ECTF_NEXT_END)
15780 {
15781 dump_ctf_errs (NULL);
15782 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15783 ret = false;
15784 }
7d9813f1
NA
15785
15786 fail:
139633c3 15787 ctf_dict_close (parent);
2f6ecaed 15788 ctf_close (ctfa);
7d9813f1
NA
15789 free (data);
15790 free (symdata);
15791 free (strdata);
15792 return ret;
15793}
094e34f2 15794#endif
7d9813f1 15795
015dc7e1 15796static bool
dda8d76d
NC
15797load_specific_debug_section (enum dwarf_section_display_enum debug,
15798 const Elf_Internal_Shdr * sec,
15799 void * data)
1007acb3 15800{
2cf0635d 15801 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15802 char buf [64];
dda8d76d 15803 Filedata * filedata = (Filedata *) data;
9abca702 15804
19e6b90e 15805 if (section->start != NULL)
dda8d76d
NC
15806 {
15807 /* If it is already loaded, do nothing. */
15808 if (streq (section->filename, filedata->file_name))
015dc7e1 15809 return true;
dda8d76d
NC
15810 free (section->start);
15811 }
1007acb3 15812
19e6b90e
L
15813 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15814 section->address = sec->sh_addr;
dda8d76d
NC
15815 section->filename = filedata->file_name;
15816 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15817 sec->sh_offset, 1,
15818 sec->sh_size, buf);
59245841
NC
15819 if (section->start == NULL)
15820 section->size = 0;
15821 else
15822 {
77115a4a
L
15823 unsigned char *start = section->start;
15824 dwarf_size_type size = sec->sh_size;
dab394de 15825 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15826
15827 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15828 {
15829 Elf_Internal_Chdr chdr;
d8024a91
NC
15830 unsigned int compression_header_size;
15831
f53be977
L
15832 if (size < (is_32bit_elf
15833 ? sizeof (Elf32_External_Chdr)
15834 : sizeof (Elf64_External_Chdr)))
d8024a91 15835 {
55be8fd0 15836 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15837 section->name);
015dc7e1 15838 return false;
d8024a91
NC
15839 }
15840
ebdf1ebf 15841 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15842 if (compression_header_size == 0)
15843 /* An error message will have already been generated
15844 by get_compression_header. */
015dc7e1 15845 return false;
d8024a91 15846
813dabb9
L
15847 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15848 {
15849 warn (_("section '%s' has unsupported compress type: %d\n"),
15850 section->name, chdr.ch_type);
015dc7e1 15851 return false;
813dabb9 15852 }
dab394de 15853 uncompressed_size = chdr.ch_size;
77115a4a
L
15854 start += compression_header_size;
15855 size -= compression_header_size;
15856 }
dab394de
L
15857 else if (size > 12 && streq ((char *) start, "ZLIB"))
15858 {
15859 /* Read the zlib header. In this case, it should be "ZLIB"
15860 followed by the uncompressed section size, 8 bytes in
15861 big-endian order. */
15862 uncompressed_size = start[4]; uncompressed_size <<= 8;
15863 uncompressed_size += start[5]; uncompressed_size <<= 8;
15864 uncompressed_size += start[6]; uncompressed_size <<= 8;
15865 uncompressed_size += start[7]; uncompressed_size <<= 8;
15866 uncompressed_size += start[8]; uncompressed_size <<= 8;
15867 uncompressed_size += start[9]; uncompressed_size <<= 8;
15868 uncompressed_size += start[10]; uncompressed_size <<= 8;
15869 uncompressed_size += start[11];
15870 start += 12;
15871 size -= 12;
15872 }
15873
1835f746 15874 if (uncompressed_size)
77115a4a 15875 {
1835f746
NC
15876 if (uncompress_section_contents (&start, uncompressed_size,
15877 &size))
15878 {
15879 /* Free the compressed buffer, update the section buffer
15880 and the section size if uncompress is successful. */
15881 free (section->start);
15882 section->start = start;
15883 }
15884 else
15885 {
15886 error (_("Unable to decompress section %s\n"),
dda8d76d 15887 printable_section_name (filedata, sec));
015dc7e1 15888 return false;
1835f746 15889 }
77115a4a 15890 }
bc303e5d 15891
77115a4a 15892 section->size = size;
59245841 15893 }
4a114e3e 15894
1b315056 15895 if (section->start == NULL)
015dc7e1 15896 return false;
1b315056 15897
19e6b90e 15898 if (debug_displays [debug].relocate)
32ec8896 15899 {
dda8d76d 15900 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15901 & section->reloc_info, & section->num_relocs))
015dc7e1 15902 return false;
32ec8896 15903 }
d1c4b12b
NC
15904 else
15905 {
15906 section->reloc_info = NULL;
15907 section->num_relocs = 0;
15908 }
1007acb3 15909
015dc7e1 15910 return true;
1007acb3
L
15911}
15912
301a9420
AM
15913#if HAVE_LIBDEBUGINFOD
15914/* Return a hex string representation of the build-id. */
15915unsigned char *
15916get_build_id (void * data)
15917{
ca0e11aa 15918 Filedata * filedata = (Filedata *) data;
301a9420
AM
15919 Elf_Internal_Shdr * shdr;
15920 unsigned long i;
15921
55be8fd0
NC
15922 /* Iterate through notes to find note.gnu.build-id.
15923 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15924 for (i = 0, shdr = filedata->section_headers;
15925 i < filedata->file_header.e_shnum && shdr != NULL;
15926 i++, shdr++)
15927 {
15928 if (shdr->sh_type != SHT_NOTE)
15929 continue;
15930
15931 char * next;
15932 char * end;
15933 size_t data_remaining;
15934 size_t min_notesz;
15935 Elf_External_Note * enote;
15936 Elf_Internal_Note inote;
15937
15938 bfd_vma offset = shdr->sh_offset;
15939 bfd_vma align = shdr->sh_addralign;
15940 bfd_vma length = shdr->sh_size;
15941
15942 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15943 if (enote == NULL)
15944 continue;
15945
15946 if (align < 4)
15947 align = 4;
15948 else if (align != 4 && align != 8)
f761cb13
AM
15949 {
15950 free (enote);
15951 continue;
15952 }
301a9420
AM
15953
15954 end = (char *) enote + length;
15955 data_remaining = end - (char *) enote;
15956
15957 if (!is_ia64_vms (filedata))
15958 {
15959 min_notesz = offsetof (Elf_External_Note, name);
15960 if (data_remaining < min_notesz)
15961 {
55be8fd0
NC
15962 warn (_("\
15963malformed note encountered in section %s whilst scanning for build-id note\n"),
15964 printable_section_name (filedata, shdr));
f761cb13 15965 free (enote);
55be8fd0 15966 continue;
301a9420
AM
15967 }
15968 data_remaining -= min_notesz;
15969
15970 inote.type = BYTE_GET (enote->type);
15971 inote.namesz = BYTE_GET (enote->namesz);
15972 inote.namedata = enote->name;
15973 inote.descsz = BYTE_GET (enote->descsz);
15974 inote.descdata = ((char *) enote
15975 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15976 inote.descpos = offset + (inote.descdata - (char *) enote);
15977 next = ((char *) enote
15978 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15979 }
15980 else
15981 {
15982 Elf64_External_VMS_Note *vms_enote;
15983
15984 /* PR binutils/15191
15985 Make sure that there is enough data to read. */
15986 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15987 if (data_remaining < min_notesz)
15988 {
55be8fd0
NC
15989 warn (_("\
15990malformed note encountered in section %s whilst scanning for build-id note\n"),
15991 printable_section_name (filedata, shdr));
f761cb13 15992 free (enote);
55be8fd0 15993 continue;
301a9420
AM
15994 }
15995 data_remaining -= min_notesz;
15996
15997 vms_enote = (Elf64_External_VMS_Note *) enote;
15998 inote.type = BYTE_GET (vms_enote->type);
15999 inote.namesz = BYTE_GET (vms_enote->namesz);
16000 inote.namedata = vms_enote->name;
16001 inote.descsz = BYTE_GET (vms_enote->descsz);
16002 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16003 inote.descpos = offset + (inote.descdata - (char *) enote);
16004 next = inote.descdata + align_power (inote.descsz, 3);
16005 }
16006
16007 /* Skip malformed notes. */
16008 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16009 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16010 || (size_t) (next - inote.descdata) < inote.descsz
16011 || ((size_t) (next - inote.descdata)
16012 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16013 {
55be8fd0
NC
16014 warn (_("\
16015malformed note encountered in section %s whilst scanning for build-id note\n"),
16016 printable_section_name (filedata, shdr));
f761cb13 16017 free (enote);
301a9420
AM
16018 continue;
16019 }
16020
16021 /* Check if this is the build-id note. If so then convert the build-id
16022 bytes to a hex string. */
16023 if (inote.namesz > 0
24d127aa 16024 && startswith (inote.namedata, "GNU")
301a9420
AM
16025 && inote.type == NT_GNU_BUILD_ID)
16026 {
16027 unsigned long j;
16028 char * build_id;
16029
16030 build_id = malloc (inote.descsz * 2 + 1);
16031 if (build_id == NULL)
f761cb13
AM
16032 {
16033 free (enote);
16034 return NULL;
16035 }
301a9420
AM
16036
16037 for (j = 0; j < inote.descsz; ++j)
16038 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16039 build_id[inote.descsz * 2] = '\0';
f761cb13 16040 free (enote);
301a9420 16041
55be8fd0 16042 return (unsigned char *) build_id;
301a9420 16043 }
f761cb13 16044 free (enote);
301a9420
AM
16045 }
16046
16047 return NULL;
16048}
16049#endif /* HAVE_LIBDEBUGINFOD */
16050
657d0d47
CC
16051/* If this is not NULL, load_debug_section will only look for sections
16052 within the list of sections given here. */
32ec8896 16053static unsigned int * section_subset = NULL;
657d0d47 16054
015dc7e1 16055bool
dda8d76d 16056load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16057{
2cf0635d
NC
16058 struct dwarf_section * section = &debug_displays [debug].section;
16059 Elf_Internal_Shdr * sec;
dda8d76d
NC
16060 Filedata * filedata = (Filedata *) data;
16061
e1dbfc17
L
16062 if (!dump_any_debugging)
16063 return false;
16064
f425ec66
NC
16065 /* Without section headers we cannot find any sections. */
16066 if (filedata->section_headers == NULL)
015dc7e1 16067 return false;
f425ec66 16068
9c1ce108
AM
16069 if (filedata->string_table == NULL
16070 && filedata->file_header.e_shstrndx != SHN_UNDEF
16071 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16072 {
16073 Elf_Internal_Shdr * strs;
16074
16075 /* Read in the string table, so that we have section names to scan. */
16076 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16077
4dff97b2 16078 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16079 {
9c1ce108
AM
16080 filedata->string_table
16081 = (char *) get_data (NULL, filedata, strs->sh_offset,
16082 1, strs->sh_size, _("string table"));
dda8d76d 16083
9c1ce108
AM
16084 filedata->string_table_length
16085 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16086 }
16087 }
d966045b
DJ
16088
16089 /* Locate the debug section. */
dda8d76d 16090 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16091 if (sec != NULL)
16092 section->name = section->uncompressed_name;
16093 else
16094 {
dda8d76d 16095 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16096 if (sec != NULL)
16097 section->name = section->compressed_name;
16098 }
16099 if (sec == NULL)
015dc7e1 16100 return false;
d966045b 16101
657d0d47
CC
16102 /* If we're loading from a subset of sections, and we've loaded
16103 a section matching this name before, it's likely that it's a
16104 different one. */
16105 if (section_subset != NULL)
16106 free_debug_section (debug);
16107
dda8d76d 16108 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16109}
16110
19e6b90e
L
16111void
16112free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16113{
2cf0635d 16114 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16115
19e6b90e
L
16116 if (section->start == NULL)
16117 return;
1007acb3 16118
19e6b90e
L
16119 free ((char *) section->start);
16120 section->start = NULL;
16121 section->address = 0;
16122 section->size = 0;
a788aedd 16123
9db70fc3
AM
16124 free (section->reloc_info);
16125 section->reloc_info = NULL;
16126 section->num_relocs = 0;
1007acb3
L
16127}
16128
015dc7e1 16129static bool
dda8d76d 16130display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16131{
84714f86
AM
16132 const char *name = (section_name_valid (filedata, section)
16133 ? section_name (filedata, section) : "");
16134 const char *print_name = printable_section_name (filedata, section);
be7d229a 16135 uint64_t length;
015dc7e1 16136 bool result = true;
3f5e193b 16137 int i;
1007acb3 16138
19e6b90e
L
16139 length = section->sh_size;
16140 if (length == 0)
1007acb3 16141 {
74e1a04b 16142 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16143 return true;
1007acb3 16144 }
5dff79d8
NC
16145 if (section->sh_type == SHT_NOBITS)
16146 {
16147 /* There is no point in dumping the contents of a debugging section
16148 which has the NOBITS type - the bits in the file will be random.
16149 This can happen when a file containing a .eh_frame section is
16150 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16151 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16152 print_name);
015dc7e1 16153 return false;
5dff79d8 16154 }
1007acb3 16155
24d127aa 16156 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16157 name = ".debug_info";
1007acb3 16158
19e6b90e
L
16159 /* See if we know how to display the contents of this section. */
16160 for (i = 0; i < max; i++)
d85bf2ba
NC
16161 {
16162 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16163 struct dwarf_section_display * display = debug_displays + i;
16164 struct dwarf_section * sec = & display->section;
d966045b 16165
d85bf2ba 16166 if (streq (sec->uncompressed_name, name)
24d127aa 16167 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16168 || streq (sec->compressed_name, name))
16169 {
015dc7e1 16170 bool secondary = (section != find_section (filedata, name));
1007acb3 16171
d85bf2ba
NC
16172 if (secondary)
16173 free_debug_section (id);
dda8d76d 16174
24d127aa 16175 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16176 sec->name = name;
16177 else if (streq (sec->uncompressed_name, name))
16178 sec->name = sec->uncompressed_name;
16179 else
16180 sec->name = sec->compressed_name;
657d0d47 16181
d85bf2ba
NC
16182 if (load_specific_debug_section (id, section, filedata))
16183 {
16184 /* If this debug section is part of a CU/TU set in a .dwp file,
16185 restrict load_debug_section to the sections in that set. */
16186 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16187
d85bf2ba 16188 result &= display->display (sec, filedata);
657d0d47 16189
d85bf2ba 16190 section_subset = NULL;
1007acb3 16191
44266f36 16192 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16193 free_debug_section (id);
16194 }
16195 break;
16196 }
16197 }
1007acb3 16198
19e6b90e 16199 if (i == max)
1007acb3 16200 {
74e1a04b 16201 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16202 result = false;
1007acb3
L
16203 }
16204
19e6b90e 16205 return result;
5b18a4bc 16206}
103f02d3 16207
aef1f6d0
DJ
16208/* Set DUMP_SECTS for all sections where dumps were requested
16209 based on section name. */
16210
16211static void
dda8d76d 16212initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16213{
2cf0635d 16214 struct dump_list_entry * cur;
aef1f6d0
DJ
16215
16216 for (cur = dump_sects_byname; cur; cur = cur->next)
16217 {
16218 unsigned int i;
015dc7e1 16219 bool any = false;
aef1f6d0 16220
dda8d76d 16221 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16222 if (section_name_valid (filedata, filedata->section_headers + i)
16223 && streq (section_name (filedata, filedata->section_headers + i),
16224 cur->name))
aef1f6d0 16225 {
6431e409 16226 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16227 any = true;
aef1f6d0
DJ
16228 }
16229
835f2fae
NC
16230 if (!any && !filedata->is_separate)
16231 warn (_("Section '%s' was not dumped because it does not exist\n"),
16232 cur->name);
aef1f6d0
DJ
16233 }
16234}
16235
015dc7e1 16236static bool
dda8d76d 16237process_section_contents (Filedata * filedata)
5b18a4bc 16238{
2cf0635d 16239 Elf_Internal_Shdr * section;
19e6b90e 16240 unsigned int i;
015dc7e1 16241 bool res = true;
103f02d3 16242
19e6b90e 16243 if (! do_dump)
015dc7e1 16244 return true;
103f02d3 16245
dda8d76d 16246 initialise_dumps_byname (filedata);
aef1f6d0 16247
dda8d76d 16248 for (i = 0, section = filedata->section_headers;
6431e409 16249 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16250 i++, section++)
16251 {
6431e409 16252 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16253
d6bfbc39
NC
16254 if (filedata->is_separate && ! process_links)
16255 dump &= DEBUG_DUMP;
047c3dbf 16256
19e6b90e 16257#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16258 if (dump & DISASS_DUMP)
16259 {
16260 if (! disassemble_section (section, filedata))
015dc7e1 16261 res = false;
dda8d76d 16262 }
19e6b90e 16263#endif
dda8d76d 16264 if (dump & HEX_DUMP)
32ec8896 16265 {
015dc7e1
AM
16266 if (! dump_section_as_bytes (section, filedata, false))
16267 res = false;
32ec8896 16268 }
103f02d3 16269
dda8d76d 16270 if (dump & RELOC_DUMP)
32ec8896 16271 {
015dc7e1
AM
16272 if (! dump_section_as_bytes (section, filedata, true))
16273 res = false;
32ec8896 16274 }
09c11c86 16275
dda8d76d 16276 if (dump & STRING_DUMP)
32ec8896 16277 {
dda8d76d 16278 if (! dump_section_as_strings (section, filedata))
015dc7e1 16279 res = false;
32ec8896 16280 }
cf13d699 16281
dda8d76d 16282 if (dump & DEBUG_DUMP)
32ec8896 16283 {
dda8d76d 16284 if (! display_debug_section (i, section, filedata))
015dc7e1 16285 res = false;
32ec8896 16286 }
7d9813f1 16287
094e34f2 16288#ifdef ENABLE_LIBCTF
7d9813f1
NA
16289 if (dump & CTF_DUMP)
16290 {
16291 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16292 res = false;
7d9813f1 16293 }
094e34f2 16294#endif
5b18a4bc 16295 }
103f02d3 16296
835f2fae 16297 if (! filedata->is_separate)
0ee3043f 16298 {
835f2fae
NC
16299 /* Check to see if the user requested a
16300 dump of a section that does not exist. */
16301 for (; i < filedata->dump.num_dump_sects; i++)
16302 if (filedata->dump.dump_sects[i])
16303 {
ca0e11aa 16304 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16305 res = false;
835f2fae 16306 }
0ee3043f 16307 }
32ec8896
NC
16308
16309 return res;
5b18a4bc 16310}
103f02d3 16311
5b18a4bc 16312static void
19e6b90e 16313process_mips_fpe_exception (int mask)
5b18a4bc 16314{
19e6b90e
L
16315 if (mask)
16316 {
015dc7e1 16317 bool first = true;
32ec8896 16318
19e6b90e 16319 if (mask & OEX_FPU_INEX)
015dc7e1 16320 fputs ("INEX", stdout), first = false;
19e6b90e 16321 if (mask & OEX_FPU_UFLO)
015dc7e1 16322 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16323 if (mask & OEX_FPU_OFLO)
015dc7e1 16324 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16325 if (mask & OEX_FPU_DIV0)
015dc7e1 16326 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16327 if (mask & OEX_FPU_INVAL)
16328 printf ("%sINVAL", first ? "" : "|");
16329 }
5b18a4bc 16330 else
19e6b90e 16331 fputs ("0", stdout);
5b18a4bc 16332}
103f02d3 16333
f6f0e17b
NC
16334/* Display's the value of TAG at location P. If TAG is
16335 greater than 0 it is assumed to be an unknown tag, and
16336 a message is printed to this effect. Otherwise it is
16337 assumed that a message has already been printed.
16338
16339 If the bottom bit of TAG is set it assumed to have a
16340 string value, otherwise it is assumed to have an integer
16341 value.
16342
16343 Returns an updated P pointing to the first unread byte
16344 beyond the end of TAG's value.
16345
16346 Reads at or beyond END will not be made. */
16347
16348static unsigned char *
60abdbed 16349display_tag_value (signed int tag,
f6f0e17b
NC
16350 unsigned char * p,
16351 const unsigned char * const end)
16352{
16353 unsigned long val;
16354
16355 if (tag > 0)
16356 printf (" Tag_unknown_%d: ", tag);
16357
16358 if (p >= end)
16359 {
4082ef84 16360 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16361 }
16362 else if (tag & 1)
16363 {
071436c6
NC
16364 /* PR 17531 file: 027-19978-0.004. */
16365 size_t maxlen = (end - p) - 1;
16366
16367 putchar ('"');
4082ef84
NC
16368 if (maxlen > 0)
16369 {
16370 print_symbol ((int) maxlen, (const char *) p);
16371 p += strnlen ((char *) p, maxlen) + 1;
16372 }
16373 else
16374 {
16375 printf (_("<corrupt string tag>"));
16376 p = (unsigned char *) end;
16377 }
071436c6 16378 printf ("\"\n");
f6f0e17b
NC
16379 }
16380 else
16381 {
cd30bcef 16382 READ_ULEB (val, p, end);
f6f0e17b
NC
16383 printf ("%ld (0x%lx)\n", val, val);
16384 }
16385
4082ef84 16386 assert (p <= end);
f6f0e17b
NC
16387 return p;
16388}
16389
53a346d8
CZ
16390/* ARC ABI attributes section. */
16391
16392static unsigned char *
16393display_arc_attribute (unsigned char * p,
16394 const unsigned char * const end)
16395{
16396 unsigned int tag;
53a346d8
CZ
16397 unsigned int val;
16398
cd30bcef 16399 READ_ULEB (tag, p, end);
53a346d8
CZ
16400
16401 switch (tag)
16402 {
16403 case Tag_ARC_PCS_config:
cd30bcef 16404 READ_ULEB (val, p, end);
53a346d8
CZ
16405 printf (" Tag_ARC_PCS_config: ");
16406 switch (val)
16407 {
16408 case 0:
16409 printf (_("Absent/Non standard\n"));
16410 break;
16411 case 1:
16412 printf (_("Bare metal/mwdt\n"));
16413 break;
16414 case 2:
16415 printf (_("Bare metal/newlib\n"));
16416 break;
16417 case 3:
16418 printf (_("Linux/uclibc\n"));
16419 break;
16420 case 4:
16421 printf (_("Linux/glibc\n"));
16422 break;
16423 default:
16424 printf (_("Unknown\n"));
16425 break;
16426 }
16427 break;
16428
16429 case Tag_ARC_CPU_base:
cd30bcef 16430 READ_ULEB (val, p, end);
53a346d8
CZ
16431 printf (" Tag_ARC_CPU_base: ");
16432 switch (val)
16433 {
16434 default:
16435 case TAG_CPU_NONE:
16436 printf (_("Absent\n"));
16437 break;
16438 case TAG_CPU_ARC6xx:
16439 printf ("ARC6xx\n");
16440 break;
16441 case TAG_CPU_ARC7xx:
16442 printf ("ARC7xx\n");
16443 break;
16444 case TAG_CPU_ARCEM:
16445 printf ("ARCEM\n");
16446 break;
16447 case TAG_CPU_ARCHS:
16448 printf ("ARCHS\n");
16449 break;
16450 }
16451 break;
16452
16453 case Tag_ARC_CPU_variation:
cd30bcef 16454 READ_ULEB (val, p, end);
53a346d8
CZ
16455 printf (" Tag_ARC_CPU_variation: ");
16456 switch (val)
16457 {
16458 default:
16459 if (val > 0 && val < 16)
53a346d8 16460 printf ("Core%d\n", val);
d8cbc93b
JL
16461 else
16462 printf ("Unknown\n");
16463 break;
16464
53a346d8
CZ
16465 case 0:
16466 printf (_("Absent\n"));
16467 break;
16468 }
16469 break;
16470
16471 case Tag_ARC_CPU_name:
16472 printf (" Tag_ARC_CPU_name: ");
16473 p = display_tag_value (-1, p, end);
16474 break;
16475
16476 case Tag_ARC_ABI_rf16:
cd30bcef 16477 READ_ULEB (val, p, end);
53a346d8
CZ
16478 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16479 break;
16480
16481 case Tag_ARC_ABI_osver:
cd30bcef 16482 READ_ULEB (val, p, end);
53a346d8
CZ
16483 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16484 break;
16485
16486 case Tag_ARC_ABI_pic:
16487 case Tag_ARC_ABI_sda:
cd30bcef 16488 READ_ULEB (val, p, end);
53a346d8
CZ
16489 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16490 : " Tag_ARC_ABI_pic: ");
16491 switch (val)
16492 {
16493 case 0:
16494 printf (_("Absent\n"));
16495 break;
16496 case 1:
16497 printf ("MWDT\n");
16498 break;
16499 case 2:
16500 printf ("GNU\n");
16501 break;
16502 default:
16503 printf (_("Unknown\n"));
16504 break;
16505 }
16506 break;
16507
16508 case Tag_ARC_ABI_tls:
cd30bcef 16509 READ_ULEB (val, p, end);
53a346d8
CZ
16510 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16511 break;
16512
16513 case Tag_ARC_ABI_enumsize:
cd30bcef 16514 READ_ULEB (val, p, end);
53a346d8
CZ
16515 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16516 _("smallest"));
16517 break;
16518
16519 case Tag_ARC_ABI_exceptions:
cd30bcef 16520 READ_ULEB (val, p, end);
53a346d8
CZ
16521 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16522 : _("default"));
16523 break;
16524
16525 case Tag_ARC_ABI_double_size:
cd30bcef 16526 READ_ULEB (val, p, end);
53a346d8
CZ
16527 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16528 break;
16529
16530 case Tag_ARC_ISA_config:
16531 printf (" Tag_ARC_ISA_config: ");
16532 p = display_tag_value (-1, p, end);
16533 break;
16534
16535 case Tag_ARC_ISA_apex:
16536 printf (" Tag_ARC_ISA_apex: ");
16537 p = display_tag_value (-1, p, end);
16538 break;
16539
16540 case Tag_ARC_ISA_mpy_option:
cd30bcef 16541 READ_ULEB (val, p, end);
53a346d8
CZ
16542 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16543 break;
16544
db1e1b45 16545 case Tag_ARC_ATR_version:
cd30bcef 16546 READ_ULEB (val, p, end);
db1e1b45 16547 printf (" Tag_ARC_ATR_version: %d\n", val);
16548 break;
16549
53a346d8
CZ
16550 default:
16551 return display_tag_value (tag & 1, p, end);
16552 }
16553
16554 return p;
16555}
16556
11c1ff18
PB
16557/* ARM EABI attributes section. */
16558typedef struct
16559{
70e99720 16560 unsigned int tag;
2cf0635d 16561 const char * name;
11c1ff18 16562 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16563 unsigned int type;
288f0ba2 16564 const char *const *table;
11c1ff18
PB
16565} arm_attr_public_tag;
16566
288f0ba2 16567static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16568 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16569 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16570 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16571 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16572static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16573static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16574 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16575static const char *const arm_attr_tag_FP_arch[] =
bca38921 16576 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16577 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16578static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16579static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16580 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16581 "NEON for ARMv8.1"};
288f0ba2 16582static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16583 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16584 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16585static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16586 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16587static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16588 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16589static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16590 {"Absolute", "PC-relative", "None"};
288f0ba2 16591static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16592 {"None", "direct", "GOT-indirect"};
288f0ba2 16593static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16594 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16595static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16596static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16597 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16598static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16599static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16600static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16601 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16602static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16603 {"Unused", "small", "int", "forced to int"};
288f0ba2 16604static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16605 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16606static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16607 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16608static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16609 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16610static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16611 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16612 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16613static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16614 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16615 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16616static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16617static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16618 {"Not Allowed", "Allowed"};
288f0ba2 16619static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16620 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16621static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16622 {"Follow architecture", "Allowed"};
288f0ba2 16623static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16624 {"Not Allowed", "Allowed"};
288f0ba2 16625static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16626 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16627 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16628static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16629static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16630 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16631 "TrustZone and Virtualization Extensions"};
288f0ba2 16632static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16633 {"Not Allowed", "Allowed"};
11c1ff18 16634
288f0ba2 16635static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16636 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16637
99db83d0
AC
16638static const char * arm_attr_tag_PAC_extension[] =
16639 {"No PAC/AUT instructions",
16640 "PAC/AUT instructions permitted in the NOP space",
16641 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16642
4b535030
AC
16643static const char * arm_attr_tag_BTI_extension[] =
16644 {"BTI instructions not permitted",
16645 "BTI instructions permitted in the NOP space",
16646 "BTI instructions permitted in the NOP and in the non-NOP space"};
16647
b81ee92f
AC
16648static const char * arm_attr_tag_BTI_use[] =
16649 {"Compiled without branch target enforcement",
16650 "Compiled with branch target enforcement"};
16651
c9fed665
AC
16652static const char * arm_attr_tag_PACRET_use[] =
16653 {"Compiled without return address signing and authentication",
16654 "Compiled with return address signing and authentication"};
16655
11c1ff18
PB
16656#define LOOKUP(id, name) \
16657 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16658static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16659{
16660 {4, "CPU_raw_name", 1, NULL},
16661 {5, "CPU_name", 1, NULL},
16662 LOOKUP(6, CPU_arch),
16663 {7, "CPU_arch_profile", 0, NULL},
16664 LOOKUP(8, ARM_ISA_use),
16665 LOOKUP(9, THUMB_ISA_use),
75375b3e 16666 LOOKUP(10, FP_arch),
11c1ff18 16667 LOOKUP(11, WMMX_arch),
f5f53991
AS
16668 LOOKUP(12, Advanced_SIMD_arch),
16669 LOOKUP(13, PCS_config),
11c1ff18
PB
16670 LOOKUP(14, ABI_PCS_R9_use),
16671 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16672 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16673 LOOKUP(17, ABI_PCS_GOT_use),
16674 LOOKUP(18, ABI_PCS_wchar_t),
16675 LOOKUP(19, ABI_FP_rounding),
16676 LOOKUP(20, ABI_FP_denormal),
16677 LOOKUP(21, ABI_FP_exceptions),
16678 LOOKUP(22, ABI_FP_user_exceptions),
16679 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16680 {24, "ABI_align_needed", 0, NULL},
16681 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16682 LOOKUP(26, ABI_enum_size),
16683 LOOKUP(27, ABI_HardFP_use),
16684 LOOKUP(28, ABI_VFP_args),
16685 LOOKUP(29, ABI_WMMX_args),
16686 LOOKUP(30, ABI_optimization_goals),
16687 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16688 {32, "compatibility", 0, NULL},
f5f53991 16689 LOOKUP(34, CPU_unaligned_access),
75375b3e 16690 LOOKUP(36, FP_HP_extension),
8e79c3df 16691 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16692 LOOKUP(42, MPextension_use),
16693 LOOKUP(44, DIV_use),
15afaa63 16694 LOOKUP(46, DSP_extension),
a7ad558c 16695 LOOKUP(48, MVE_arch),
99db83d0 16696 LOOKUP(50, PAC_extension),
4b535030 16697 LOOKUP(52, BTI_extension),
b81ee92f 16698 LOOKUP(74, BTI_use),
c9fed665 16699 LOOKUP(76, PACRET_use),
f5f53991
AS
16700 {64, "nodefaults", 0, NULL},
16701 {65, "also_compatible_with", 0, NULL},
16702 LOOKUP(66, T2EE_use),
16703 {67, "conformance", 1, NULL},
16704 LOOKUP(68, Virtualization_use),
cd21e546 16705 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16706};
16707#undef LOOKUP
16708
11c1ff18 16709static unsigned char *
f6f0e17b
NC
16710display_arm_attribute (unsigned char * p,
16711 const unsigned char * const end)
11c1ff18 16712{
70e99720 16713 unsigned int tag;
70e99720 16714 unsigned int val;
2cf0635d 16715 arm_attr_public_tag * attr;
11c1ff18 16716 unsigned i;
70e99720 16717 unsigned int type;
11c1ff18 16718
cd30bcef 16719 READ_ULEB (tag, p, end);
11c1ff18 16720 attr = NULL;
2cf0635d 16721 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16722 {
16723 if (arm_attr_public_tags[i].tag == tag)
16724 {
16725 attr = &arm_attr_public_tags[i];
16726 break;
16727 }
16728 }
16729
16730 if (attr)
16731 {
16732 printf (" Tag_%s: ", attr->name);
16733 switch (attr->type)
16734 {
16735 case 0:
16736 switch (tag)
16737 {
16738 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16739 READ_ULEB (val, p, end);
11c1ff18
PB
16740 switch (val)
16741 {
2b692964
NC
16742 case 0: printf (_("None\n")); break;
16743 case 'A': printf (_("Application\n")); break;
16744 case 'R': printf (_("Realtime\n")); break;
16745 case 'M': printf (_("Microcontroller\n")); break;
16746 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16747 default: printf ("??? (%d)\n", val); break;
16748 }
16749 break;
16750
75375b3e 16751 case 24: /* Tag_align_needed. */
cd30bcef 16752 READ_ULEB (val, p, end);
75375b3e
MGD
16753 switch (val)
16754 {
2b692964
NC
16755 case 0: printf (_("None\n")); break;
16756 case 1: printf (_("8-byte\n")); break;
16757 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16758 case 3: printf ("??? 3\n"); break;
16759 default:
16760 if (val <= 12)
dd24e3da 16761 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16762 1 << val);
16763 else
16764 printf ("??? (%d)\n", val);
16765 break;
16766 }
16767 break;
16768
16769 case 25: /* Tag_align_preserved. */
cd30bcef 16770 READ_ULEB (val, p, end);
75375b3e
MGD
16771 switch (val)
16772 {
2b692964
NC
16773 case 0: printf (_("None\n")); break;
16774 case 1: printf (_("8-byte, except leaf SP\n")); break;
16775 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16776 case 3: printf ("??? 3\n"); break;
16777 default:
16778 if (val <= 12)
dd24e3da 16779 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16780 1 << val);
16781 else
16782 printf ("??? (%d)\n", val);
16783 break;
16784 }
16785 break;
16786
11c1ff18 16787 case 32: /* Tag_compatibility. */
071436c6 16788 {
cd30bcef 16789 READ_ULEB (val, p, end);
071436c6 16790 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16791 if (p < end - 1)
16792 {
16793 size_t maxlen = (end - p) - 1;
16794
16795 print_symbol ((int) maxlen, (const char *) p);
16796 p += strnlen ((char *) p, maxlen) + 1;
16797 }
16798 else
16799 {
16800 printf (_("<corrupt>"));
16801 p = (unsigned char *) end;
16802 }
071436c6 16803 putchar ('\n');
071436c6 16804 }
11c1ff18
PB
16805 break;
16806
f5f53991 16807 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16808 /* PR 17531: file: 001-505008-0.01. */
16809 if (p < end)
16810 p++;
2b692964 16811 printf (_("True\n"));
f5f53991
AS
16812 break;
16813
16814 case 65: /* Tag_also_compatible_with. */
cd30bcef 16815 READ_ULEB (val, p, end);
f5f53991
AS
16816 if (val == 6 /* Tag_CPU_arch. */)
16817 {
cd30bcef 16818 READ_ULEB (val, p, end);
071436c6 16819 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16820 printf ("??? (%d)\n", val);
16821 else
16822 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16823 }
16824 else
16825 printf ("???\n");
071436c6
NC
16826 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16827 ;
f5f53991
AS
16828 break;
16829
11c1ff18 16830 default:
bee0ee85
NC
16831 printf (_("<unknown: %d>\n"), tag);
16832 break;
11c1ff18
PB
16833 }
16834 return p;
16835
16836 case 1:
f6f0e17b 16837 return display_tag_value (-1, p, end);
11c1ff18 16838 case 2:
f6f0e17b 16839 return display_tag_value (0, p, end);
11c1ff18
PB
16840
16841 default:
16842 assert (attr->type & 0x80);
cd30bcef 16843 READ_ULEB (val, p, end);
11c1ff18
PB
16844 type = attr->type & 0x7f;
16845 if (val >= type)
16846 printf ("??? (%d)\n", val);
16847 else
16848 printf ("%s\n", attr->table[val]);
16849 return p;
16850 }
16851 }
11c1ff18 16852
f6f0e17b 16853 return display_tag_value (tag, p, end);
11c1ff18
PB
16854}
16855
104d59d1 16856static unsigned char *
60bca95a 16857display_gnu_attribute (unsigned char * p,
60abdbed 16858 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16859 const unsigned char * const end)
104d59d1 16860{
cd30bcef 16861 unsigned int tag;
60abdbed 16862 unsigned int val;
104d59d1 16863
cd30bcef 16864 READ_ULEB (tag, p, end);
104d59d1
JM
16865
16866 /* Tag_compatibility is the only generic GNU attribute defined at
16867 present. */
16868 if (tag == 32)
16869 {
cd30bcef 16870 READ_ULEB (val, p, end);
071436c6
NC
16871
16872 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16873 if (p == end)
16874 {
071436c6 16875 printf (_("<corrupt>\n"));
f6f0e17b
NC
16876 warn (_("corrupt vendor attribute\n"));
16877 }
16878 else
16879 {
4082ef84
NC
16880 if (p < end - 1)
16881 {
16882 size_t maxlen = (end - p) - 1;
071436c6 16883
4082ef84
NC
16884 print_symbol ((int) maxlen, (const char *) p);
16885 p += strnlen ((char *) p, maxlen) + 1;
16886 }
16887 else
16888 {
16889 printf (_("<corrupt>"));
16890 p = (unsigned char *) end;
16891 }
071436c6 16892 putchar ('\n');
f6f0e17b 16893 }
104d59d1
JM
16894 return p;
16895 }
16896
16897 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16898 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16899
f6f0e17b 16900 return display_tag_value (tag, p, end);
104d59d1
JM
16901}
16902
85f7484a
PB
16903static unsigned char *
16904display_m68k_gnu_attribute (unsigned char * p,
16905 unsigned int tag,
16906 const unsigned char * const end)
16907{
16908 unsigned int val;
16909
16910 if (tag == Tag_GNU_M68K_ABI_FP)
16911 {
16912 printf (" Tag_GNU_M68K_ABI_FP: ");
16913 if (p == end)
16914 {
16915 printf (_("<corrupt>\n"));
16916 return p;
16917 }
16918 READ_ULEB (val, p, end);
16919
16920 if (val > 3)
16921 printf ("(%#x), ", val);
16922
16923 switch (val & 3)
16924 {
16925 case 0:
16926 printf (_("unspecified hard/soft float\n"));
16927 break;
16928 case 1:
16929 printf (_("hard float\n"));
16930 break;
16931 case 2:
16932 printf (_("soft float\n"));
16933 break;
16934 }
16935 return p;
16936 }
16937
16938 return display_tag_value (tag & 1, p, end);
16939}
16940
34c8bcba 16941static unsigned char *
f6f0e17b 16942display_power_gnu_attribute (unsigned char * p,
60abdbed 16943 unsigned int tag,
f6f0e17b 16944 const unsigned char * const end)
34c8bcba 16945{
005d79fd 16946 unsigned int val;
34c8bcba
JM
16947
16948 if (tag == Tag_GNU_Power_ABI_FP)
16949 {
34c8bcba 16950 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16951 if (p == end)
005d79fd
AM
16952 {
16953 printf (_("<corrupt>\n"));
16954 return p;
16955 }
cd30bcef 16956 READ_ULEB (val, p, end);
60bca95a 16957
005d79fd
AM
16958 if (val > 15)
16959 printf ("(%#x), ", val);
16960
16961 switch (val & 3)
34c8bcba
JM
16962 {
16963 case 0:
005d79fd 16964 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16965 break;
16966 case 1:
005d79fd 16967 printf (_("hard float, "));
34c8bcba
JM
16968 break;
16969 case 2:
005d79fd 16970 printf (_("soft float, "));
34c8bcba 16971 break;
3c7b9897 16972 case 3:
005d79fd 16973 printf (_("single-precision hard float, "));
3c7b9897 16974 break;
005d79fd
AM
16975 }
16976
16977 switch (val & 0xC)
16978 {
16979 case 0:
16980 printf (_("unspecified long double\n"));
16981 break;
16982 case 4:
16983 printf (_("128-bit IBM long double\n"));
16984 break;
16985 case 8:
16986 printf (_("64-bit long double\n"));
16987 break;
16988 case 12:
16989 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16990 break;
16991 }
16992 return p;
005d79fd 16993 }
34c8bcba 16994
c6e65352
DJ
16995 if (tag == Tag_GNU_Power_ABI_Vector)
16996 {
c6e65352 16997 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16998 if (p == end)
005d79fd
AM
16999 {
17000 printf (_("<corrupt>\n"));
17001 return p;
17002 }
cd30bcef 17003 READ_ULEB (val, p, end);
005d79fd
AM
17004
17005 if (val > 3)
17006 printf ("(%#x), ", val);
17007
17008 switch (val & 3)
c6e65352
DJ
17009 {
17010 case 0:
005d79fd 17011 printf (_("unspecified\n"));
c6e65352
DJ
17012 break;
17013 case 1:
005d79fd 17014 printf (_("generic\n"));
c6e65352
DJ
17015 break;
17016 case 2:
17017 printf ("AltiVec\n");
17018 break;
17019 case 3:
17020 printf ("SPE\n");
17021 break;
c6e65352
DJ
17022 }
17023 return p;
005d79fd 17024 }
c6e65352 17025
f82e0623
NF
17026 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17027 {
005d79fd 17028 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17029 if (p == end)
f6f0e17b 17030 {
005d79fd 17031 printf (_("<corrupt>\n"));
f6f0e17b
NC
17032 return p;
17033 }
cd30bcef 17034 READ_ULEB (val, p, end);
0b4362b0 17035
005d79fd
AM
17036 if (val > 2)
17037 printf ("(%#x), ", val);
17038
17039 switch (val & 3)
17040 {
17041 case 0:
17042 printf (_("unspecified\n"));
17043 break;
17044 case 1:
17045 printf ("r3/r4\n");
17046 break;
17047 case 2:
17048 printf (_("memory\n"));
17049 break;
17050 case 3:
17051 printf ("???\n");
17052 break;
17053 }
f82e0623
NF
17054 return p;
17055 }
17056
f6f0e17b 17057 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17058}
17059
643f7afb
AK
17060static unsigned char *
17061display_s390_gnu_attribute (unsigned char * p,
60abdbed 17062 unsigned int tag,
643f7afb
AK
17063 const unsigned char * const end)
17064{
cd30bcef 17065 unsigned int val;
643f7afb
AK
17066
17067 if (tag == Tag_GNU_S390_ABI_Vector)
17068 {
643f7afb 17069 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17070 READ_ULEB (val, p, end);
643f7afb
AK
17071
17072 switch (val)
17073 {
17074 case 0:
17075 printf (_("any\n"));
17076 break;
17077 case 1:
17078 printf (_("software\n"));
17079 break;
17080 case 2:
17081 printf (_("hardware\n"));
17082 break;
17083 default:
17084 printf ("??? (%d)\n", val);
17085 break;
17086 }
17087 return p;
17088 }
17089
17090 return display_tag_value (tag & 1, p, end);
17091}
17092
9e8c70f9 17093static void
60abdbed 17094display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17095{
17096 if (mask)
17097 {
015dc7e1 17098 bool first = true;
071436c6 17099
9e8c70f9 17100 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17101 fputs ("mul32", stdout), first = false;
9e8c70f9 17102 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17103 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17104 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17105 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17106 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17107 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17108 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17109 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17110 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17111 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17112 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17113 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17114 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17115 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17116 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17117 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17118 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17119 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17120 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17121 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17122 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17123 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17124 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17125 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17126 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17127 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17128 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17129 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17130 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17131 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17132 }
17133 else
071436c6
NC
17134 fputc ('0', stdout);
17135 fputc ('\n', stdout);
9e8c70f9
DM
17136}
17137
3d68f91c 17138static void
60abdbed 17139display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17140{
17141 if (mask)
17142 {
015dc7e1 17143 bool first = true;
071436c6 17144
3d68f91c 17145 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17146 fputs ("fjathplus", stdout), first = false;
3d68f91c 17147 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17148 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17149 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17150 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17151 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17152 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17153 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17154 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17155 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17156 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17157 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17158 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17159 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17160 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17161 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17162 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17163 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17164 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17165 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17166 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17167 }
17168 else
071436c6
NC
17169 fputc ('0', stdout);
17170 fputc ('\n', stdout);
3d68f91c
JM
17171}
17172
9e8c70f9 17173static unsigned char *
f6f0e17b 17174display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17175 unsigned int tag,
f6f0e17b 17176 const unsigned char * const end)
9e8c70f9 17177{
cd30bcef 17178 unsigned int val;
3d68f91c 17179
9e8c70f9
DM
17180 if (tag == Tag_GNU_Sparc_HWCAPS)
17181 {
cd30bcef 17182 READ_ULEB (val, p, end);
9e8c70f9 17183 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17184 display_sparc_hwcaps (val);
17185 return p;
3d68f91c
JM
17186 }
17187 if (tag == Tag_GNU_Sparc_HWCAPS2)
17188 {
cd30bcef 17189 READ_ULEB (val, p, end);
3d68f91c
JM
17190 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17191 display_sparc_hwcaps2 (val);
17192 return p;
17193 }
9e8c70f9 17194
f6f0e17b 17195 return display_tag_value (tag, p, end);
9e8c70f9
DM
17196}
17197
351cdf24 17198static void
32ec8896 17199print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17200{
17201 switch (val)
17202 {
17203 case Val_GNU_MIPS_ABI_FP_ANY:
17204 printf (_("Hard or soft float\n"));
17205 break;
17206 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17207 printf (_("Hard float (double precision)\n"));
17208 break;
17209 case Val_GNU_MIPS_ABI_FP_SINGLE:
17210 printf (_("Hard float (single precision)\n"));
17211 break;
17212 case Val_GNU_MIPS_ABI_FP_SOFT:
17213 printf (_("Soft float\n"));
17214 break;
17215 case Val_GNU_MIPS_ABI_FP_OLD_64:
17216 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17217 break;
17218 case Val_GNU_MIPS_ABI_FP_XX:
17219 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17220 break;
17221 case Val_GNU_MIPS_ABI_FP_64:
17222 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17223 break;
17224 case Val_GNU_MIPS_ABI_FP_64A:
17225 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17226 break;
3350cc01
CM
17227 case Val_GNU_MIPS_ABI_FP_NAN2008:
17228 printf (_("NaN 2008 compatibility\n"));
17229 break;
351cdf24
MF
17230 default:
17231 printf ("??? (%d)\n", val);
17232 break;
17233 }
17234}
17235
2cf19d5c 17236static unsigned char *
f6f0e17b 17237display_mips_gnu_attribute (unsigned char * p,
60abdbed 17238 unsigned int tag,
f6f0e17b 17239 const unsigned char * const end)
2cf19d5c 17240{
2cf19d5c
JM
17241 if (tag == Tag_GNU_MIPS_ABI_FP)
17242 {
32ec8896 17243 unsigned int val;
f6f0e17b 17244
2cf19d5c 17245 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17246 READ_ULEB (val, p, end);
351cdf24 17247 print_mips_fp_abi_value (val);
2cf19d5c
JM
17248 return p;
17249 }
17250
a9f58168
CF
17251 if (tag == Tag_GNU_MIPS_ABI_MSA)
17252 {
32ec8896 17253 unsigned int val;
a9f58168 17254
a9f58168 17255 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17256 READ_ULEB (val, p, end);
a9f58168
CF
17257
17258 switch (val)
17259 {
17260 case Val_GNU_MIPS_ABI_MSA_ANY:
17261 printf (_("Any MSA or not\n"));
17262 break;
17263 case Val_GNU_MIPS_ABI_MSA_128:
17264 printf (_("128-bit MSA\n"));
17265 break;
17266 default:
17267 printf ("??? (%d)\n", val);
17268 break;
17269 }
17270 return p;
17271 }
17272
f6f0e17b 17273 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17274}
17275
59e6276b 17276static unsigned char *
f6f0e17b
NC
17277display_tic6x_attribute (unsigned char * p,
17278 const unsigned char * const end)
59e6276b 17279{
60abdbed 17280 unsigned int tag;
cd30bcef 17281 unsigned int val;
59e6276b 17282
cd30bcef 17283 READ_ULEB (tag, p, end);
59e6276b
JM
17284
17285 switch (tag)
17286 {
75fa6dc1 17287 case Tag_ISA:
75fa6dc1 17288 printf (" Tag_ISA: ");
cd30bcef 17289 READ_ULEB (val, p, end);
59e6276b
JM
17290
17291 switch (val)
17292 {
75fa6dc1 17293 case C6XABI_Tag_ISA_none:
59e6276b
JM
17294 printf (_("None\n"));
17295 break;
75fa6dc1 17296 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17297 printf ("C62x\n");
17298 break;
75fa6dc1 17299 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17300 printf ("C67x\n");
17301 break;
75fa6dc1 17302 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17303 printf ("C67x+\n");
17304 break;
75fa6dc1 17305 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17306 printf ("C64x\n");
17307 break;
75fa6dc1 17308 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17309 printf ("C64x+\n");
17310 break;
75fa6dc1 17311 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17312 printf ("C674x\n");
17313 break;
17314 default:
17315 printf ("??? (%d)\n", val);
17316 break;
17317 }
17318 return p;
17319
87779176 17320 case Tag_ABI_wchar_t:
87779176 17321 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17322 READ_ULEB (val, p, end);
87779176
JM
17323 switch (val)
17324 {
17325 case 0:
17326 printf (_("Not used\n"));
17327 break;
17328 case 1:
17329 printf (_("2 bytes\n"));
17330 break;
17331 case 2:
17332 printf (_("4 bytes\n"));
17333 break;
17334 default:
17335 printf ("??? (%d)\n", val);
17336 break;
17337 }
17338 return p;
17339
17340 case Tag_ABI_stack_align_needed:
87779176 17341 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17342 READ_ULEB (val, p, end);
87779176
JM
17343 switch (val)
17344 {
17345 case 0:
17346 printf (_("8-byte\n"));
17347 break;
17348 case 1:
17349 printf (_("16-byte\n"));
17350 break;
17351 default:
17352 printf ("??? (%d)\n", val);
17353 break;
17354 }
17355 return p;
17356
17357 case Tag_ABI_stack_align_preserved:
cd30bcef 17358 READ_ULEB (val, p, end);
87779176
JM
17359 printf (" Tag_ABI_stack_align_preserved: ");
17360 switch (val)
17361 {
17362 case 0:
17363 printf (_("8-byte\n"));
17364 break;
17365 case 1:
17366 printf (_("16-byte\n"));
17367 break;
17368 default:
17369 printf ("??? (%d)\n", val);
17370 break;
17371 }
17372 return p;
17373
b5593623 17374 case Tag_ABI_DSBT:
cd30bcef 17375 READ_ULEB (val, p, end);
b5593623
JM
17376 printf (" Tag_ABI_DSBT: ");
17377 switch (val)
17378 {
17379 case 0:
17380 printf (_("DSBT addressing not used\n"));
17381 break;
17382 case 1:
17383 printf (_("DSBT addressing used\n"));
17384 break;
17385 default:
17386 printf ("??? (%d)\n", val);
17387 break;
17388 }
17389 return p;
17390
87779176 17391 case Tag_ABI_PID:
cd30bcef 17392 READ_ULEB (val, p, end);
87779176
JM
17393 printf (" Tag_ABI_PID: ");
17394 switch (val)
17395 {
17396 case 0:
17397 printf (_("Data addressing position-dependent\n"));
17398 break;
17399 case 1:
17400 printf (_("Data addressing position-independent, GOT near DP\n"));
17401 break;
17402 case 2:
17403 printf (_("Data addressing position-independent, GOT far from DP\n"));
17404 break;
17405 default:
17406 printf ("??? (%d)\n", val);
17407 break;
17408 }
17409 return p;
17410
17411 case Tag_ABI_PIC:
cd30bcef 17412 READ_ULEB (val, p, end);
87779176
JM
17413 printf (" Tag_ABI_PIC: ");
17414 switch (val)
17415 {
17416 case 0:
17417 printf (_("Code addressing position-dependent\n"));
17418 break;
17419 case 1:
17420 printf (_("Code addressing position-independent\n"));
17421 break;
17422 default:
17423 printf ("??? (%d)\n", val);
17424 break;
17425 }
17426 return p;
17427
17428 case Tag_ABI_array_object_alignment:
cd30bcef 17429 READ_ULEB (val, p, end);
87779176
JM
17430 printf (" Tag_ABI_array_object_alignment: ");
17431 switch (val)
17432 {
17433 case 0:
17434 printf (_("8-byte\n"));
17435 break;
17436 case 1:
17437 printf (_("4-byte\n"));
17438 break;
17439 case 2:
17440 printf (_("16-byte\n"));
17441 break;
17442 default:
17443 printf ("??? (%d)\n", val);
17444 break;
17445 }
17446 return p;
17447
17448 case Tag_ABI_array_object_align_expected:
cd30bcef 17449 READ_ULEB (val, p, end);
87779176
JM
17450 printf (" Tag_ABI_array_object_align_expected: ");
17451 switch (val)
17452 {
17453 case 0:
17454 printf (_("8-byte\n"));
17455 break;
17456 case 1:
17457 printf (_("4-byte\n"));
17458 break;
17459 case 2:
17460 printf (_("16-byte\n"));
17461 break;
17462 default:
17463 printf ("??? (%d)\n", val);
17464 break;
17465 }
17466 return p;
17467
3cbd1c06 17468 case Tag_ABI_compatibility:
071436c6 17469 {
cd30bcef 17470 READ_ULEB (val, p, end);
071436c6 17471 printf (" Tag_ABI_compatibility: ");
071436c6 17472 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17473 if (p < end - 1)
17474 {
17475 size_t maxlen = (end - p) - 1;
17476
17477 print_symbol ((int) maxlen, (const char *) p);
17478 p += strnlen ((char *) p, maxlen) + 1;
17479 }
17480 else
17481 {
17482 printf (_("<corrupt>"));
17483 p = (unsigned char *) end;
17484 }
071436c6 17485 putchar ('\n');
071436c6
NC
17486 return p;
17487 }
87779176
JM
17488
17489 case Tag_ABI_conformance:
071436c6 17490 {
4082ef84
NC
17491 printf (" Tag_ABI_conformance: \"");
17492 if (p < end - 1)
17493 {
17494 size_t maxlen = (end - p) - 1;
071436c6 17495
4082ef84
NC
17496 print_symbol ((int) maxlen, (const char *) p);
17497 p += strnlen ((char *) p, maxlen) + 1;
17498 }
17499 else
17500 {
17501 printf (_("<corrupt>"));
17502 p = (unsigned char *) end;
17503 }
071436c6 17504 printf ("\"\n");
071436c6
NC
17505 return p;
17506 }
59e6276b
JM
17507 }
17508
f6f0e17b
NC
17509 return display_tag_value (tag, p, end);
17510}
59e6276b 17511
f6f0e17b 17512static void
60abdbed 17513display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17514{
17515 unsigned long addr = 0;
17516 size_t bytes = end - p;
17517
feceaa59 17518 assert (end >= p);
f6f0e17b 17519 while (bytes)
87779176 17520 {
f6f0e17b
NC
17521 int j;
17522 int k;
17523 int lbytes = (bytes > 16 ? 16 : bytes);
17524
17525 printf (" 0x%8.8lx ", addr);
17526
17527 for (j = 0; j < 16; j++)
17528 {
17529 if (j < lbytes)
17530 printf ("%2.2x", p[j]);
17531 else
17532 printf (" ");
17533
17534 if ((j & 3) == 3)
17535 printf (" ");
17536 }
17537
17538 for (j = 0; j < lbytes; j++)
17539 {
17540 k = p[j];
17541 if (k >= ' ' && k < 0x7f)
17542 printf ("%c", k);
17543 else
17544 printf (".");
17545 }
17546
17547 putchar ('\n');
17548
17549 p += lbytes;
17550 bytes -= lbytes;
17551 addr += lbytes;
87779176 17552 }
59e6276b 17553
f6f0e17b 17554 putchar ('\n');
59e6276b
JM
17555}
17556
13761a11 17557static unsigned char *
b0191216 17558display_msp430_attribute (unsigned char * p,
13761a11
NC
17559 const unsigned char * const end)
17560{
60abdbed
NC
17561 unsigned int val;
17562 unsigned int tag;
13761a11 17563
cd30bcef 17564 READ_ULEB (tag, p, end);
0b4362b0 17565
13761a11
NC
17566 switch (tag)
17567 {
17568 case OFBA_MSPABI_Tag_ISA:
13761a11 17569 printf (" Tag_ISA: ");
cd30bcef 17570 READ_ULEB (val, p, end);
13761a11
NC
17571 switch (val)
17572 {
17573 case 0: printf (_("None\n")); break;
17574 case 1: printf (_("MSP430\n")); break;
17575 case 2: printf (_("MSP430X\n")); break;
17576 default: printf ("??? (%d)\n", val); break;
17577 }
17578 break;
17579
17580 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17581 printf (" Tag_Code_Model: ");
cd30bcef 17582 READ_ULEB (val, p, end);
13761a11
NC
17583 switch (val)
17584 {
17585 case 0: printf (_("None\n")); break;
17586 case 1: printf (_("Small\n")); break;
17587 case 2: printf (_("Large\n")); break;
17588 default: printf ("??? (%d)\n", val); break;
17589 }
17590 break;
17591
17592 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17593 printf (" Tag_Data_Model: ");
cd30bcef 17594 READ_ULEB (val, p, end);
13761a11
NC
17595 switch (val)
17596 {
17597 case 0: printf (_("None\n")); break;
17598 case 1: printf (_("Small\n")); break;
17599 case 2: printf (_("Large\n")); break;
17600 case 3: printf (_("Restricted Large\n")); break;
17601 default: printf ("??? (%d)\n", val); break;
17602 }
17603 break;
17604
17605 default:
17606 printf (_(" <unknown tag %d>: "), tag);
17607
17608 if (tag & 1)
17609 {
071436c6 17610 putchar ('"');
4082ef84
NC
17611 if (p < end - 1)
17612 {
17613 size_t maxlen = (end - p) - 1;
17614
17615 print_symbol ((int) maxlen, (const char *) p);
17616 p += strnlen ((char *) p, maxlen) + 1;
17617 }
17618 else
17619 {
17620 printf (_("<corrupt>"));
17621 p = (unsigned char *) end;
17622 }
071436c6 17623 printf ("\"\n");
13761a11
NC
17624 }
17625 else
17626 {
cd30bcef 17627 READ_ULEB (val, p, end);
13761a11
NC
17628 printf ("%d (0x%x)\n", val, val);
17629 }
17630 break;
17631 }
17632
4082ef84 17633 assert (p <= end);
13761a11
NC
17634 return p;
17635}
17636
c0ea7c52
JL
17637static unsigned char *
17638display_msp430_gnu_attribute (unsigned char * p,
17639 unsigned int tag,
17640 const unsigned char * const end)
17641{
17642 if (tag == Tag_GNU_MSP430_Data_Region)
17643 {
cd30bcef 17644 unsigned int val;
c0ea7c52 17645
c0ea7c52 17646 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17647 READ_ULEB (val, p, end);
c0ea7c52
JL
17648
17649 switch (val)
17650 {
17651 case Val_GNU_MSP430_Data_Region_Any:
17652 printf (_("Any Region\n"));
17653 break;
17654 case Val_GNU_MSP430_Data_Region_Lower:
17655 printf (_("Lower Region Only\n"));
17656 break;
17657 default:
cd30bcef 17658 printf ("??? (%u)\n", val);
c0ea7c52
JL
17659 }
17660 return p;
17661 }
17662 return display_tag_value (tag & 1, p, end);
17663}
17664
2dc8dd17
JW
17665struct riscv_attr_tag_t {
17666 const char *name;
cd30bcef 17667 unsigned int tag;
2dc8dd17
JW
17668};
17669
17670static struct riscv_attr_tag_t riscv_attr_tag[] =
17671{
17672#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17673 T(arch),
17674 T(priv_spec),
17675 T(priv_spec_minor),
17676 T(priv_spec_revision),
17677 T(unaligned_access),
17678 T(stack_align),
17679#undef T
17680};
17681
17682static unsigned char *
17683display_riscv_attribute (unsigned char *p,
17684 const unsigned char * const end)
17685{
cd30bcef
AM
17686 unsigned int val;
17687 unsigned int tag;
2dc8dd17
JW
17688 struct riscv_attr_tag_t *attr = NULL;
17689 unsigned i;
17690
cd30bcef 17691 READ_ULEB (tag, p, end);
2dc8dd17
JW
17692
17693 /* Find the name of attribute. */
17694 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17695 {
17696 if (riscv_attr_tag[i].tag == tag)
17697 {
17698 attr = &riscv_attr_tag[i];
17699 break;
17700 }
17701 }
17702
17703 if (attr)
17704 printf (" %s: ", attr->name);
17705 else
17706 return display_tag_value (tag, p, end);
17707
17708 switch (tag)
17709 {
17710 case Tag_RISCV_priv_spec:
17711 case Tag_RISCV_priv_spec_minor:
17712 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17713 READ_ULEB (val, p, end);
17714 printf (_("%u\n"), val);
2dc8dd17
JW
17715 break;
17716 case Tag_RISCV_unaligned_access:
cd30bcef 17717 READ_ULEB (val, p, end);
2dc8dd17
JW
17718 switch (val)
17719 {
17720 case 0:
17721 printf (_("No unaligned access\n"));
17722 break;
17723 case 1:
17724 printf (_("Unaligned access\n"));
17725 break;
17726 }
17727 break;
17728 case Tag_RISCV_stack_align:
cd30bcef
AM
17729 READ_ULEB (val, p, end);
17730 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17731 break;
17732 case Tag_RISCV_arch:
17733 p = display_tag_value (-1, p, end);
17734 break;
17735 default:
17736 return display_tag_value (tag, p, end);
17737 }
17738
17739 return p;
17740}
17741
0861f561
CQ
17742static unsigned char *
17743display_csky_attribute (unsigned char * p,
17744 const unsigned char * const end)
17745{
17746 unsigned int tag;
17747 unsigned int val;
17748 READ_ULEB (tag, p, end);
17749
17750 if (tag >= Tag_CSKY_MAX)
17751 {
17752 return display_tag_value (-1, p, end);
17753 }
17754
17755 switch (tag)
17756 {
17757 case Tag_CSKY_ARCH_NAME:
17758 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17759 return display_tag_value (-1, p, end);
17760 case Tag_CSKY_CPU_NAME:
17761 printf (" Tag_CSKY_CPU_NAME:\t\t");
17762 return display_tag_value (-1, p, end);
17763
17764 case Tag_CSKY_ISA_FLAGS:
17765 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17766 return display_tag_value (0, p, end);
17767 case Tag_CSKY_ISA_EXT_FLAGS:
17768 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17769 return display_tag_value (0, p, end);
17770
17771 case Tag_CSKY_DSP_VERSION:
17772 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17773 READ_ULEB (val, p, end);
17774 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17775 printf ("DSP Extension\n");
17776 else if (val == VAL_CSKY_DSP_VERSION_2)
17777 printf ("DSP 2.0\n");
17778 break;
17779
17780 case Tag_CSKY_VDSP_VERSION:
17781 printf (" Tag_CSKY_VDSP_VERSION:\t");
17782 READ_ULEB (val, p, end);
17783 printf ("VDSP Version %d\n", val);
17784 break;
17785
17786 case Tag_CSKY_FPU_VERSION:
17787 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17788 READ_ULEB (val, p, end);
17789 if (val == VAL_CSKY_FPU_VERSION_1)
17790 printf ("ABIV1 FPU Version 1\n");
17791 else if (val == VAL_CSKY_FPU_VERSION_2)
17792 printf ("FPU Version 2\n");
17793 break;
17794
17795 case Tag_CSKY_FPU_ABI:
17796 printf (" Tag_CSKY_FPU_ABI:\t\t");
17797 READ_ULEB (val, p, end);
17798 if (val == VAL_CSKY_FPU_ABI_HARD)
17799 printf ("Hard\n");
17800 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17801 printf ("SoftFP\n");
17802 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17803 printf ("Soft\n");
17804 break;
17805 case Tag_CSKY_FPU_ROUNDING:
17806 READ_ULEB (val, p, end);
f253158f
NC
17807 if (val == 1)
17808 {
17809 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17810 printf ("Needed\n");
17811 }
0861f561
CQ
17812 break;
17813 case Tag_CSKY_FPU_DENORMAL:
17814 READ_ULEB (val, p, end);
f253158f
NC
17815 if (val == 1)
17816 {
17817 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17818 printf ("Needed\n");
17819 }
0861f561
CQ
17820 break;
17821 case Tag_CSKY_FPU_Exception:
17822 READ_ULEB (val, p, end);
f253158f
NC
17823 if (val == 1)
17824 {
17825 printf (" Tag_CSKY_FPU_Exception:\t");
17826 printf ("Needed\n");
17827 }
0861f561
CQ
17828 break;
17829 case Tag_CSKY_FPU_NUMBER_MODULE:
17830 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17831 return display_tag_value (-1, p, end);
17832 case Tag_CSKY_FPU_HARDFP:
17833 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17834 READ_ULEB (val, p, end);
17835 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17836 printf (" Half");
17837 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17838 printf (" Single");
17839 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17840 printf (" Double");
17841 printf ("\n");
17842 break;
17843 default:
17844 return display_tag_value (tag, p, end);
17845 }
17846 return p;
17847}
17848
015dc7e1 17849static bool
dda8d76d 17850process_attributes (Filedata * filedata,
60bca95a 17851 const char * public_name,
104d59d1 17852 unsigned int proc_type,
f6f0e17b 17853 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17854 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17855{
2cf0635d 17856 Elf_Internal_Shdr * sect;
11c1ff18 17857 unsigned i;
015dc7e1 17858 bool res = true;
11c1ff18
PB
17859
17860 /* Find the section header so that we get the size. */
dda8d76d
NC
17861 for (i = 0, sect = filedata->section_headers;
17862 i < filedata->file_header.e_shnum;
11c1ff18
PB
17863 i++, sect++)
17864 {
071436c6
NC
17865 unsigned char * contents;
17866 unsigned char * p;
17867
104d59d1 17868 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17869 continue;
17870
dda8d76d 17871 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17872 sect->sh_size, _("attributes"));
60bca95a 17873 if (contents == NULL)
32ec8896 17874 {
015dc7e1 17875 res = false;
32ec8896
NC
17876 continue;
17877 }
60bca95a 17878
11c1ff18 17879 p = contents;
60abdbed
NC
17880 /* The first character is the version of the attributes.
17881 Currently only version 1, (aka 'A') is recognised here. */
17882 if (*p != 'A')
32ec8896
NC
17883 {
17884 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17885 res = false;
32ec8896 17886 }
60abdbed 17887 else
11c1ff18 17888 {
071436c6
NC
17889 bfd_vma section_len;
17890
17891 section_len = sect->sh_size - 1;
11c1ff18 17892 p++;
60bca95a 17893
071436c6 17894 while (section_len > 0)
11c1ff18 17895 {
071436c6 17896 bfd_vma attr_len;
e9847026 17897 unsigned int namelen;
015dc7e1
AM
17898 bool public_section;
17899 bool gnu_section;
11c1ff18 17900
071436c6 17901 if (section_len <= 4)
e0a31db1
NC
17902 {
17903 error (_("Tag section ends prematurely\n"));
015dc7e1 17904 res = false;
e0a31db1
NC
17905 break;
17906 }
071436c6 17907 attr_len = byte_get (p, 4);
11c1ff18 17908 p += 4;
60bca95a 17909
071436c6 17910 if (attr_len > section_len)
11c1ff18 17911 {
071436c6
NC
17912 error (_("Bad attribute length (%u > %u)\n"),
17913 (unsigned) attr_len, (unsigned) section_len);
17914 attr_len = section_len;
015dc7e1 17915 res = false;
11c1ff18 17916 }
74e1a04b 17917 /* PR 17531: file: 001-101425-0.004 */
071436c6 17918 else if (attr_len < 5)
74e1a04b 17919 {
071436c6 17920 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17921 res = false;
74e1a04b
NC
17922 break;
17923 }
e9847026 17924
071436c6
NC
17925 section_len -= attr_len;
17926 attr_len -= 4;
17927
17928 namelen = strnlen ((char *) p, attr_len) + 1;
17929 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17930 {
17931 error (_("Corrupt attribute section name\n"));
015dc7e1 17932 res = false;
e9847026
NC
17933 break;
17934 }
17935
071436c6
NC
17936 printf (_("Attribute Section: "));
17937 print_symbol (INT_MAX, (const char *) p);
17938 putchar ('\n');
60bca95a
NC
17939
17940 if (public_name && streq ((char *) p, public_name))
015dc7e1 17941 public_section = true;
11c1ff18 17942 else
015dc7e1 17943 public_section = false;
60bca95a
NC
17944
17945 if (streq ((char *) p, "gnu"))
015dc7e1 17946 gnu_section = true;
104d59d1 17947 else
015dc7e1 17948 gnu_section = false;
60bca95a 17949
11c1ff18 17950 p += namelen;
071436c6 17951 attr_len -= namelen;
e0a31db1 17952
071436c6 17953 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17954 {
e0a31db1 17955 int tag;
cd30bcef 17956 unsigned int val;
11c1ff18 17957 bfd_vma size;
071436c6 17958 unsigned char * end;
60bca95a 17959
e0a31db1 17960 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17961 if (attr_len < 6)
e0a31db1
NC
17962 {
17963 error (_("Unused bytes at end of section\n"));
015dc7e1 17964 res = false;
e0a31db1
NC
17965 section_len = 0;
17966 break;
17967 }
17968
17969 tag = *(p++);
11c1ff18 17970 size = byte_get (p, 4);
071436c6 17971 if (size > attr_len)
11c1ff18 17972 {
e9847026 17973 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17974 (unsigned) size, (unsigned) attr_len);
015dc7e1 17975 res = false;
071436c6 17976 size = attr_len;
11c1ff18 17977 }
e0a31db1
NC
17978 /* PR binutils/17531: Safe handling of corrupt files. */
17979 if (size < 6)
17980 {
17981 error (_("Bad subsection length (%u < 6)\n"),
17982 (unsigned) size);
015dc7e1 17983 res = false;
e0a31db1
NC
17984 section_len = 0;
17985 break;
17986 }
60bca95a 17987
071436c6 17988 attr_len -= size;
11c1ff18 17989 end = p + size - 1;
071436c6 17990 assert (end <= contents + sect->sh_size);
11c1ff18 17991 p += 4;
60bca95a 17992
11c1ff18
PB
17993 switch (tag)
17994 {
17995 case 1:
2b692964 17996 printf (_("File Attributes\n"));
11c1ff18
PB
17997 break;
17998 case 2:
2b692964 17999 printf (_("Section Attributes:"));
11c1ff18
PB
18000 goto do_numlist;
18001 case 3:
2b692964 18002 printf (_("Symbol Attributes:"));
1a0670f3 18003 /* Fall through. */
11c1ff18
PB
18004 do_numlist:
18005 for (;;)
18006 {
cd30bcef 18007 READ_ULEB (val, p, end);
11c1ff18
PB
18008 if (val == 0)
18009 break;
18010 printf (" %d", val);
18011 }
18012 printf ("\n");
18013 break;
18014 default:
2b692964 18015 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18016 public_section = false;
11c1ff18
PB
18017 break;
18018 }
60bca95a 18019
071436c6 18020 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18021 {
18022 while (p < end)
f6f0e17b 18023 p = display_pub_attribute (p, end);
60abdbed 18024 assert (p == end);
104d59d1 18025 }
071436c6 18026 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18027 {
18028 while (p < end)
18029 p = display_gnu_attribute (p,
f6f0e17b
NC
18030 display_proc_gnu_attribute,
18031 end);
60abdbed 18032 assert (p == end);
11c1ff18 18033 }
071436c6 18034 else if (p < end)
11c1ff18 18035 {
071436c6 18036 printf (_(" Unknown attribute:\n"));
f6f0e17b 18037 display_raw_attribute (p, end);
11c1ff18
PB
18038 p = end;
18039 }
071436c6
NC
18040 else
18041 attr_len = 0;
11c1ff18
PB
18042 }
18043 }
18044 }
d70c5fc7 18045
60bca95a 18046 free (contents);
11c1ff18 18047 }
32ec8896
NC
18048
18049 return res;
11c1ff18
PB
18050}
18051
ccb4c951
RS
18052/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18053 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18054 and return the VMA of the next entry, or -1 if there was a problem.
18055 Does not read from DATA_END or beyond. */
ccb4c951
RS
18056
18057static bfd_vma
82b1b41b
NC
18058print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
18059 unsigned char * data_end)
ccb4c951
RS
18060{
18061 printf (" ");
18062 print_vma (addr, LONG_HEX);
18063 printf (" ");
18064 if (addr < pltgot + 0xfff0)
18065 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18066 else
18067 printf ("%10s", "");
18068 printf (" ");
18069 if (data == NULL)
2b692964 18070 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18071 else
18072 {
18073 bfd_vma entry;
82b1b41b 18074 unsigned char * from = data + addr - pltgot;
ccb4c951 18075
82b1b41b
NC
18076 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18077 {
18078 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18079 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18080 return (bfd_vma) -1;
18081 }
18082 else
18083 {
18084 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18085 print_vma (entry, LONG_HEX);
18086 }
ccb4c951
RS
18087 }
18088 return addr + (is_32bit_elf ? 4 : 8);
18089}
18090
861fb55a
DJ
18091/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18092 PLTGOT. Print the Address and Initial fields of an entry at VMA
18093 ADDR and return the VMA of the next entry. */
18094
18095static bfd_vma
2cf0635d 18096print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
18097{
18098 printf (" ");
18099 print_vma (addr, LONG_HEX);
18100 printf (" ");
18101 if (data == NULL)
2b692964 18102 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18103 else
18104 {
18105 bfd_vma entry;
18106
18107 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18108 print_vma (entry, LONG_HEX);
18109 }
18110 return addr + (is_32bit_elf ? 4 : 8);
18111}
18112
351cdf24
MF
18113static void
18114print_mips_ases (unsigned int mask)
18115{
18116 if (mask & AFL_ASE_DSP)
18117 fputs ("\n\tDSP ASE", stdout);
18118 if (mask & AFL_ASE_DSPR2)
18119 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18120 if (mask & AFL_ASE_DSPR3)
18121 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18122 if (mask & AFL_ASE_EVA)
18123 fputs ("\n\tEnhanced VA Scheme", stdout);
18124 if (mask & AFL_ASE_MCU)
18125 fputs ("\n\tMCU (MicroController) ASE", stdout);
18126 if (mask & AFL_ASE_MDMX)
18127 fputs ("\n\tMDMX ASE", stdout);
18128 if (mask & AFL_ASE_MIPS3D)
18129 fputs ("\n\tMIPS-3D ASE", stdout);
18130 if (mask & AFL_ASE_MT)
18131 fputs ("\n\tMT ASE", stdout);
18132 if (mask & AFL_ASE_SMARTMIPS)
18133 fputs ("\n\tSmartMIPS ASE", stdout);
18134 if (mask & AFL_ASE_VIRT)
18135 fputs ("\n\tVZ ASE", stdout);
18136 if (mask & AFL_ASE_MSA)
18137 fputs ("\n\tMSA ASE", stdout);
18138 if (mask & AFL_ASE_MIPS16)
18139 fputs ("\n\tMIPS16 ASE", stdout);
18140 if (mask & AFL_ASE_MICROMIPS)
18141 fputs ("\n\tMICROMIPS ASE", stdout);
18142 if (mask & AFL_ASE_XPA)
18143 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18144 if (mask & AFL_ASE_MIPS16E2)
18145 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18146 if (mask & AFL_ASE_CRC)
18147 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18148 if (mask & AFL_ASE_GINV)
18149 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18150 if (mask & AFL_ASE_LOONGSON_MMI)
18151 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18152 if (mask & AFL_ASE_LOONGSON_CAM)
18153 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18154 if (mask & AFL_ASE_LOONGSON_EXT)
18155 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18156 if (mask & AFL_ASE_LOONGSON_EXT2)
18157 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18158 if (mask == 0)
18159 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18160 else if ((mask & ~AFL_ASE_MASK) != 0)
18161 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18162}
18163
18164static void
18165print_mips_isa_ext (unsigned int isa_ext)
18166{
18167 switch (isa_ext)
18168 {
18169 case 0:
18170 fputs (_("None"), stdout);
18171 break;
18172 case AFL_EXT_XLR:
18173 fputs ("RMI XLR", stdout);
18174 break;
2c629856
N
18175 case AFL_EXT_OCTEON3:
18176 fputs ("Cavium Networks Octeon3", stdout);
18177 break;
351cdf24
MF
18178 case AFL_EXT_OCTEON2:
18179 fputs ("Cavium Networks Octeon2", stdout);
18180 break;
18181 case AFL_EXT_OCTEONP:
18182 fputs ("Cavium Networks OcteonP", stdout);
18183 break;
351cdf24
MF
18184 case AFL_EXT_OCTEON:
18185 fputs ("Cavium Networks Octeon", stdout);
18186 break;
18187 case AFL_EXT_5900:
18188 fputs ("Toshiba R5900", stdout);
18189 break;
18190 case AFL_EXT_4650:
18191 fputs ("MIPS R4650", stdout);
18192 break;
18193 case AFL_EXT_4010:
18194 fputs ("LSI R4010", stdout);
18195 break;
18196 case AFL_EXT_4100:
18197 fputs ("NEC VR4100", stdout);
18198 break;
18199 case AFL_EXT_3900:
18200 fputs ("Toshiba R3900", stdout);
18201 break;
18202 case AFL_EXT_10000:
18203 fputs ("MIPS R10000", stdout);
18204 break;
18205 case AFL_EXT_SB1:
18206 fputs ("Broadcom SB-1", stdout);
18207 break;
18208 case AFL_EXT_4111:
18209 fputs ("NEC VR4111/VR4181", stdout);
18210 break;
18211 case AFL_EXT_4120:
18212 fputs ("NEC VR4120", stdout);
18213 break;
18214 case AFL_EXT_5400:
18215 fputs ("NEC VR5400", stdout);
18216 break;
18217 case AFL_EXT_5500:
18218 fputs ("NEC VR5500", stdout);
18219 break;
18220 case AFL_EXT_LOONGSON_2E:
18221 fputs ("ST Microelectronics Loongson 2E", stdout);
18222 break;
18223 case AFL_EXT_LOONGSON_2F:
18224 fputs ("ST Microelectronics Loongson 2F", stdout);
18225 break;
38bf472a
MR
18226 case AFL_EXT_INTERAPTIV_MR2:
18227 fputs ("Imagination interAptiv MR2", stdout);
18228 break;
351cdf24 18229 default:
00ac7aa0 18230 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18231 }
18232}
18233
32ec8896 18234static signed int
351cdf24
MF
18235get_mips_reg_size (int reg_size)
18236{
18237 return (reg_size == AFL_REG_NONE) ? 0
18238 : (reg_size == AFL_REG_32) ? 32
18239 : (reg_size == AFL_REG_64) ? 64
18240 : (reg_size == AFL_REG_128) ? 128
18241 : -1;
18242}
18243
015dc7e1 18244static bool
dda8d76d 18245process_mips_specific (Filedata * filedata)
5b18a4bc 18246{
2cf0635d 18247 Elf_Internal_Dyn * entry;
351cdf24 18248 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18249 size_t liblist_offset = 0;
18250 size_t liblistno = 0;
18251 size_t conflictsno = 0;
18252 size_t options_offset = 0;
18253 size_t conflicts_offset = 0;
861fb55a
DJ
18254 size_t pltrelsz = 0;
18255 size_t pltrel = 0;
ccb4c951 18256 bfd_vma pltgot = 0;
861fb55a
DJ
18257 bfd_vma mips_pltgot = 0;
18258 bfd_vma jmprel = 0;
ccb4c951
RS
18259 bfd_vma local_gotno = 0;
18260 bfd_vma gotsym = 0;
18261 bfd_vma symtabno = 0;
015dc7e1 18262 bool res = true;
103f02d3 18263
dda8d76d 18264 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18265 display_mips_gnu_attribute))
015dc7e1 18266 res = false;
2cf19d5c 18267
dda8d76d 18268 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18269
18270 if (sect != NULL)
18271 {
18272 Elf_External_ABIFlags_v0 *abiflags_ext;
18273 Elf_Internal_ABIFlags_v0 abiflags_in;
18274
18275 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18276 {
18277 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18278 res = false;
32ec8896 18279 }
351cdf24
MF
18280 else
18281 {
dda8d76d 18282 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18283 sect->sh_size, _("MIPS ABI Flags section"));
18284 if (abiflags_ext)
18285 {
18286 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18287 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18288 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18289 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18290 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18291 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18292 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18293 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18294 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18295 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18296 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18297
18298 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18299 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18300 if (abiflags_in.isa_rev > 1)
18301 printf ("r%d", abiflags_in.isa_rev);
18302 printf ("\nGPR size: %d",
18303 get_mips_reg_size (abiflags_in.gpr_size));
18304 printf ("\nCPR1 size: %d",
18305 get_mips_reg_size (abiflags_in.cpr1_size));
18306 printf ("\nCPR2 size: %d",
18307 get_mips_reg_size (abiflags_in.cpr2_size));
18308 fputs ("\nFP ABI: ", stdout);
18309 print_mips_fp_abi_value (abiflags_in.fp_abi);
18310 fputs ("ISA Extension: ", stdout);
18311 print_mips_isa_ext (abiflags_in.isa_ext);
18312 fputs ("\nASEs:", stdout);
18313 print_mips_ases (abiflags_in.ases);
18314 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18315 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18316 fputc ('\n', stdout);
18317 free (abiflags_ext);
18318 }
18319 }
18320 }
18321
19e6b90e 18322 /* We have a lot of special sections. Thanks SGI! */
978c4450 18323 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18324 {
18325 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18326 sect = find_section (filedata, ".got");
bbdd9a68
MR
18327 if (sect != NULL)
18328 {
18329 unsigned char *data_end;
18330 unsigned char *data;
18331 bfd_vma ent, end;
18332 int addr_size;
18333
18334 pltgot = sect->sh_addr;
18335
18336 ent = pltgot;
18337 addr_size = (is_32bit_elf ? 4 : 8);
18338 end = pltgot + sect->sh_size;
18339
dda8d76d 18340 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18341 end - pltgot, 1,
18342 _("Global Offset Table data"));
18343 /* PR 12855: Null data is handled gracefully throughout. */
18344 data_end = data + (end - pltgot);
18345
18346 printf (_("\nStatic GOT:\n"));
18347 printf (_(" Canonical gp value: "));
18348 print_vma (ent + 0x7ff0, LONG_HEX);
18349 printf ("\n\n");
18350
18351 /* In a dynamic binary GOT[0] is reserved for the dynamic
18352 loader to store the lazy resolver pointer, however in
18353 a static binary it may well have been omitted and GOT
18354 reduced to a table of addresses.
18355 PR 21344: Check for the entry being fully available
18356 before fetching it. */
18357 if (data
18358 && data + ent - pltgot + addr_size <= data_end
18359 && byte_get (data + ent - pltgot, addr_size) == 0)
18360 {
18361 printf (_(" Reserved entries:\n"));
18362 printf (_(" %*s %10s %*s\n"),
18363 addr_size * 2, _("Address"), _("Access"),
18364 addr_size * 2, _("Value"));
18365 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18366 printf ("\n");
18367 if (ent == (bfd_vma) -1)
18368 goto sgot_print_fail;
18369
18370 /* Check for the MSB of GOT[1] being set, identifying a
18371 GNU object. This entry will be used by some runtime
18372 loaders, to store the module pointer. Otherwise this
18373 is an ordinary local entry.
18374 PR 21344: Check for the entry being fully available
18375 before fetching it. */
18376 if (data
18377 && data + ent - pltgot + addr_size <= data_end
18378 && (byte_get (data + ent - pltgot, addr_size)
18379 >> (addr_size * 8 - 1)) != 0)
18380 {
18381 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18382 printf ("\n");
18383 if (ent == (bfd_vma) -1)
18384 goto sgot_print_fail;
18385 }
18386 printf ("\n");
18387 }
18388
f17e9d8a 18389 if (data != NULL && ent < end)
bbdd9a68
MR
18390 {
18391 printf (_(" Local entries:\n"));
18392 printf (" %*s %10s %*s\n",
18393 addr_size * 2, _("Address"), _("Access"),
18394 addr_size * 2, _("Value"));
18395 while (ent < end)
18396 {
18397 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18398 printf ("\n");
18399 if (ent == (bfd_vma) -1)
18400 goto sgot_print_fail;
18401 }
18402 printf ("\n");
18403 }
18404
18405 sgot_print_fail:
9db70fc3 18406 free (data);
bbdd9a68
MR
18407 }
18408 return res;
18409 }
252b5132 18410
978c4450 18411 for (entry = filedata->dynamic_section;
071436c6 18412 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18413 (entry < filedata->dynamic_section + filedata->dynamic_nent
18414 && entry->d_tag != DT_NULL);
071436c6 18415 ++entry)
252b5132
RH
18416 switch (entry->d_tag)
18417 {
18418 case DT_MIPS_LIBLIST:
d93f0186 18419 liblist_offset
dda8d76d 18420 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18421 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18422 break;
18423 case DT_MIPS_LIBLISTNO:
18424 liblistno = entry->d_un.d_val;
18425 break;
18426 case DT_MIPS_OPTIONS:
dda8d76d 18427 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18428 break;
18429 case DT_MIPS_CONFLICT:
d93f0186 18430 conflicts_offset
dda8d76d 18431 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18432 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18433 break;
18434 case DT_MIPS_CONFLICTNO:
18435 conflictsno = entry->d_un.d_val;
18436 break;
ccb4c951 18437 case DT_PLTGOT:
861fb55a
DJ
18438 pltgot = entry->d_un.d_ptr;
18439 break;
ccb4c951
RS
18440 case DT_MIPS_LOCAL_GOTNO:
18441 local_gotno = entry->d_un.d_val;
18442 break;
18443 case DT_MIPS_GOTSYM:
18444 gotsym = entry->d_un.d_val;
18445 break;
18446 case DT_MIPS_SYMTABNO:
18447 symtabno = entry->d_un.d_val;
18448 break;
861fb55a
DJ
18449 case DT_MIPS_PLTGOT:
18450 mips_pltgot = entry->d_un.d_ptr;
18451 break;
18452 case DT_PLTREL:
18453 pltrel = entry->d_un.d_val;
18454 break;
18455 case DT_PLTRELSZ:
18456 pltrelsz = entry->d_un.d_val;
18457 break;
18458 case DT_JMPREL:
18459 jmprel = entry->d_un.d_ptr;
18460 break;
252b5132
RH
18461 default:
18462 break;
18463 }
18464
18465 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18466 {
2cf0635d 18467 Elf32_External_Lib * elib;
252b5132
RH
18468 size_t cnt;
18469
dda8d76d 18470 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18471 sizeof (Elf32_External_Lib),
18472 liblistno,
18473 _("liblist section data"));
a6e9f9df 18474 if (elib)
252b5132 18475 {
d3a49aa8
AM
18476 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18477 "\nSection '.liblist' contains %lu entries:\n",
18478 (unsigned long) liblistno),
a6e9f9df 18479 (unsigned long) liblistno);
2b692964 18480 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18481 stdout);
18482
18483 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18484 {
a6e9f9df 18485 Elf32_Lib liblist;
91d6fa6a 18486 time_t atime;
d5b07ef4 18487 char timebuf[128];
2cf0635d 18488 struct tm * tmp;
a6e9f9df
AM
18489
18490 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18491 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18492 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18493 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18494 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18495
91d6fa6a 18496 tmp = gmtime (&atime);
e9e44622
JJ
18497 snprintf (timebuf, sizeof (timebuf),
18498 "%04u-%02u-%02uT%02u:%02u:%02u",
18499 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18500 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18501
31104126 18502 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18503 if (valid_dynamic_name (filedata, liblist.l_name))
18504 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18505 else
2b692964 18506 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18507 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18508 liblist.l_version);
a6e9f9df
AM
18509
18510 if (liblist.l_flags == 0)
2b692964 18511 puts (_(" NONE"));
a6e9f9df
AM
18512 else
18513 {
18514 static const struct
252b5132 18515 {
2cf0635d 18516 const char * name;
a6e9f9df 18517 int bit;
252b5132 18518 }
a6e9f9df
AM
18519 l_flags_vals[] =
18520 {
18521 { " EXACT_MATCH", LL_EXACT_MATCH },
18522 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18523 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18524 { " EXPORTS", LL_EXPORTS },
18525 { " DELAY_LOAD", LL_DELAY_LOAD },
18526 { " DELTA", LL_DELTA }
18527 };
18528 int flags = liblist.l_flags;
18529 size_t fcnt;
18530
60bca95a 18531 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18532 if ((flags & l_flags_vals[fcnt].bit) != 0)
18533 {
18534 fputs (l_flags_vals[fcnt].name, stdout);
18535 flags ^= l_flags_vals[fcnt].bit;
18536 }
18537 if (flags != 0)
18538 printf (" %#x", (unsigned int) flags);
252b5132 18539
a6e9f9df
AM
18540 puts ("");
18541 }
252b5132 18542 }
252b5132 18543
a6e9f9df
AM
18544 free (elib);
18545 }
32ec8896 18546 else
015dc7e1 18547 res = false;
252b5132
RH
18548 }
18549
18550 if (options_offset != 0)
18551 {
2cf0635d 18552 Elf_External_Options * eopt;
252b5132
RH
18553 size_t offset;
18554 int cnt;
18555
18556 /* Find the section header so that we get the size. */
dda8d76d 18557 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18558 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18559 if (sect == NULL)
18560 {
18561 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18562 return false;
071436c6 18563 }
7fc0c668
NC
18564 /* PR 24243 */
18565 if (sect->sh_size < sizeof (* eopt))
18566 {
18567 error (_("The MIPS options section is too small.\n"));
015dc7e1 18568 return false;
7fc0c668 18569 }
252b5132 18570
dda8d76d 18571 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18572 sect->sh_size, _("options"));
a6e9f9df 18573 if (eopt)
252b5132 18574 {
fd17d1e6 18575 Elf_Internal_Options option;
76da6bbe 18576
a6e9f9df 18577 offset = cnt = 0;
82b1b41b 18578 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18579 {
2cf0635d 18580 Elf_External_Options * eoption;
fd17d1e6 18581 unsigned int optsize;
252b5132 18582
a6e9f9df 18583 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18584
fd17d1e6 18585 optsize = BYTE_GET (eoption->size);
76da6bbe 18586
82b1b41b 18587 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18588 if (optsize < sizeof (* eopt)
18589 || optsize > sect->sh_size - offset)
82b1b41b 18590 {
645f43a8 18591 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18592 optsize);
645f43a8 18593 free (eopt);
015dc7e1 18594 return false;
82b1b41b 18595 }
fd17d1e6 18596 offset += optsize;
a6e9f9df
AM
18597 ++cnt;
18598 }
252b5132 18599
d3a49aa8
AM
18600 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18601 "\nSection '%s' contains %d entries:\n",
18602 cnt),
dda8d76d 18603 printable_section_name (filedata, sect), cnt);
76da6bbe 18604
82b1b41b 18605 offset = 0;
a6e9f9df 18606 while (cnt-- > 0)
252b5132 18607 {
a6e9f9df 18608 size_t len;
fd17d1e6
AM
18609 Elf_External_Options * eoption;
18610
18611 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18612
18613 option.kind = BYTE_GET (eoption->kind);
18614 option.size = BYTE_GET (eoption->size);
18615 option.section = BYTE_GET (eoption->section);
18616 option.info = BYTE_GET (eoption->info);
a6e9f9df 18617
fd17d1e6 18618 switch (option.kind)
252b5132 18619 {
a6e9f9df
AM
18620 case ODK_NULL:
18621 /* This shouldn't happen. */
d0c4e780 18622 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18623 option.section, option.info);
a6e9f9df 18624 break;
2e6be59c 18625
a6e9f9df
AM
18626 case ODK_REGINFO:
18627 printf (" REGINFO ");
dda8d76d 18628 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18629 {
2cf0635d 18630 Elf32_External_RegInfo * ereg;
b34976b6 18631 Elf32_RegInfo reginfo;
a6e9f9df 18632
2e6be59c 18633 /* 32bit form. */
fd17d1e6
AM
18634 if (option.size < (sizeof (Elf_External_Options)
18635 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18636 {
18637 printf (_("<corrupt>\n"));
18638 error (_("Truncated MIPS REGINFO option\n"));
18639 cnt = 0;
18640 break;
18641 }
18642
fd17d1e6 18643 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18644
a6e9f9df
AM
18645 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18646 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18647 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18648 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18649 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18650 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18651
d0c4e780
AM
18652 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18653 reginfo.ri_gprmask, reginfo.ri_gp_value);
18654 printf (" "
18655 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18656 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18657 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18658 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18659 }
18660 else
18661 {
18662 /* 64 bit form. */
2cf0635d 18663 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18664 Elf64_Internal_RegInfo reginfo;
18665
fd17d1e6
AM
18666 if (option.size < (sizeof (Elf_External_Options)
18667 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18668 {
18669 printf (_("<corrupt>\n"));
18670 error (_("Truncated MIPS REGINFO option\n"));
18671 cnt = 0;
18672 break;
18673 }
18674
fd17d1e6 18675 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18676 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18677 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18678 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18679 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18680 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18681 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18682
d0c4e780
AM
18683 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18684 reginfo.ri_gprmask, reginfo.ri_gp_value);
18685 printf (" "
18686 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18687 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18688 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18689 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18690 }
fd17d1e6 18691 offset += option.size;
a6e9f9df 18692 continue;
2e6be59c 18693
a6e9f9df
AM
18694 case ODK_EXCEPTIONS:
18695 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18696 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18697 fputs (") fpe_max(", stdout);
fd17d1e6 18698 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18699 fputs (")", stdout);
18700
fd17d1e6 18701 if (option.info & OEX_PAGE0)
a6e9f9df 18702 fputs (" PAGE0", stdout);
fd17d1e6 18703 if (option.info & OEX_SMM)
a6e9f9df 18704 fputs (" SMM", stdout);
fd17d1e6 18705 if (option.info & OEX_FPDBUG)
a6e9f9df 18706 fputs (" FPDBUG", stdout);
fd17d1e6 18707 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18708 fputs (" DISMISS", stdout);
18709 break;
2e6be59c 18710
a6e9f9df
AM
18711 case ODK_PAD:
18712 fputs (" PAD ", stdout);
fd17d1e6 18713 if (option.info & OPAD_PREFIX)
a6e9f9df 18714 fputs (" PREFIX", stdout);
fd17d1e6 18715 if (option.info & OPAD_POSTFIX)
a6e9f9df 18716 fputs (" POSTFIX", stdout);
fd17d1e6 18717 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18718 fputs (" SYMBOL", stdout);
18719 break;
2e6be59c 18720
a6e9f9df
AM
18721 case ODK_HWPATCH:
18722 fputs (" HWPATCH ", stdout);
fd17d1e6 18723 if (option.info & OHW_R4KEOP)
a6e9f9df 18724 fputs (" R4KEOP", stdout);
fd17d1e6 18725 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18726 fputs (" R8KPFETCH", stdout);
fd17d1e6 18727 if (option.info & OHW_R5KEOP)
a6e9f9df 18728 fputs (" R5KEOP", stdout);
fd17d1e6 18729 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18730 fputs (" R5KCVTL", stdout);
18731 break;
2e6be59c 18732
a6e9f9df
AM
18733 case ODK_FILL:
18734 fputs (" FILL ", stdout);
18735 /* XXX Print content of info word? */
18736 break;
2e6be59c 18737
a6e9f9df
AM
18738 case ODK_TAGS:
18739 fputs (" TAGS ", stdout);
18740 /* XXX Print content of info word? */
18741 break;
2e6be59c 18742
a6e9f9df
AM
18743 case ODK_HWAND:
18744 fputs (" HWAND ", stdout);
fd17d1e6 18745 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18746 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18747 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18748 fputs (" R4KEOP_CLEAN", stdout);
18749 break;
2e6be59c 18750
a6e9f9df
AM
18751 case ODK_HWOR:
18752 fputs (" HWOR ", stdout);
fd17d1e6 18753 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18754 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18755 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18756 fputs (" R4KEOP_CLEAN", stdout);
18757 break;
2e6be59c 18758
a6e9f9df 18759 case ODK_GP_GROUP:
d0c4e780 18760 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18761 option.info & OGP_GROUP,
18762 (option.info & OGP_SELF) >> 16);
a6e9f9df 18763 break;
2e6be59c 18764
a6e9f9df 18765 case ODK_IDENT:
d0c4e780 18766 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18767 option.info & OGP_GROUP,
18768 (option.info & OGP_SELF) >> 16);
a6e9f9df 18769 break;
2e6be59c 18770
a6e9f9df
AM
18771 default:
18772 /* This shouldn't happen. */
d0c4e780 18773 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18774 option.kind, option.section, option.info);
a6e9f9df 18775 break;
252b5132 18776 }
a6e9f9df 18777
2cf0635d 18778 len = sizeof (* eopt);
fd17d1e6 18779 while (len < option.size)
82b1b41b 18780 {
fd17d1e6 18781 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18782
82b1b41b
NC
18783 if (ISPRINT (datum))
18784 printf ("%c", datum);
18785 else
18786 printf ("\\%03o", datum);
18787 len ++;
18788 }
a6e9f9df 18789 fputs ("\n", stdout);
82b1b41b 18790
fd17d1e6 18791 offset += option.size;
252b5132 18792 }
a6e9f9df 18793 free (eopt);
252b5132 18794 }
32ec8896 18795 else
015dc7e1 18796 res = false;
252b5132
RH
18797 }
18798
18799 if (conflicts_offset != 0 && conflictsno != 0)
18800 {
2cf0635d 18801 Elf32_Conflict * iconf;
252b5132
RH
18802 size_t cnt;
18803
978c4450 18804 if (filedata->dynamic_symbols == NULL)
252b5132 18805 {
591a748a 18806 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18807 return false;
252b5132
RH
18808 }
18809
7296a62a
NC
18810 /* PR 21345 - print a slightly more helpful error message
18811 if we are sure that the cmalloc will fail. */
645f43a8 18812 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18813 {
18814 error (_("Overlarge number of conflicts detected: %lx\n"),
18815 (long) conflictsno);
015dc7e1 18816 return false;
7296a62a
NC
18817 }
18818
3f5e193b 18819 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18820 if (iconf == NULL)
18821 {
8b73c356 18822 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18823 return false;
252b5132
RH
18824 }
18825
9ea033b2 18826 if (is_32bit_elf)
252b5132 18827 {
2cf0635d 18828 Elf32_External_Conflict * econf32;
a6e9f9df 18829
3f5e193b 18830 econf32 = (Elf32_External_Conflict *)
95099889
AM
18831 get_data (NULL, filedata, conflicts_offset,
18832 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18833 if (!econf32)
5a814d6d
AM
18834 {
18835 free (iconf);
015dc7e1 18836 return false;
5a814d6d 18837 }
252b5132
RH
18838
18839 for (cnt = 0; cnt < conflictsno; ++cnt)
18840 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18841
18842 free (econf32);
252b5132
RH
18843 }
18844 else
18845 {
2cf0635d 18846 Elf64_External_Conflict * econf64;
a6e9f9df 18847
3f5e193b 18848 econf64 = (Elf64_External_Conflict *)
95099889
AM
18849 get_data (NULL, filedata, conflicts_offset,
18850 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18851 if (!econf64)
5a814d6d
AM
18852 {
18853 free (iconf);
015dc7e1 18854 return false;
5a814d6d 18855 }
252b5132
RH
18856
18857 for (cnt = 0; cnt < conflictsno; ++cnt)
18858 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18859
18860 free (econf64);
252b5132
RH
18861 }
18862
d3a49aa8
AM
18863 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18864 "\nSection '.conflict' contains %lu entries:\n",
18865 (unsigned long) conflictsno),
c7e7ca54 18866 (unsigned long) conflictsno);
252b5132
RH
18867 puts (_(" Num: Index Value Name"));
18868
18869 for (cnt = 0; cnt < conflictsno; ++cnt)
18870 {
b34976b6 18871 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18872
978c4450 18873 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18874 printf (_("<corrupt symbol index>"));
d79b3d50 18875 else
e0a31db1
NC
18876 {
18877 Elf_Internal_Sym * psym;
18878
978c4450 18879 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18880 print_vma (psym->st_value, FULL_HEX);
18881 putchar (' ');
84714f86
AM
18882 if (valid_dynamic_name (filedata, psym->st_name))
18883 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18884 else
18885 printf (_("<corrupt: %14ld>"), psym->st_name);
18886 }
31104126 18887 putchar ('\n');
252b5132
RH
18888 }
18889
252b5132
RH
18890 free (iconf);
18891 }
18892
ccb4c951
RS
18893 if (pltgot != 0 && local_gotno != 0)
18894 {
91d6fa6a 18895 bfd_vma ent, local_end, global_end;
bbeee7ea 18896 size_t i, offset;
2cf0635d 18897 unsigned char * data;
82b1b41b 18898 unsigned char * data_end;
bbeee7ea 18899 int addr_size;
ccb4c951 18900
91d6fa6a 18901 ent = pltgot;
ccb4c951
RS
18902 addr_size = (is_32bit_elf ? 4 : 8);
18903 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18904
74e1a04b
NC
18905 /* PR binutils/17533 file: 012-111227-0.004 */
18906 if (symtabno < gotsym)
18907 {
18908 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18909 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18910 return false;
74e1a04b 18911 }
82b1b41b 18912
74e1a04b 18913 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18914 /* PR 17531: file: 54c91a34. */
18915 if (global_end < local_end)
18916 {
18917 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18918 return false;
82b1b41b 18919 }
948f632f 18920
dda8d76d
NC
18921 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18922 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18923 global_end - pltgot, 1,
18924 _("Global Offset Table data"));
919383ac 18925 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18926 data_end = data + (global_end - pltgot);
59245841 18927
ccb4c951
RS
18928 printf (_("\nPrimary GOT:\n"));
18929 printf (_(" Canonical gp value: "));
18930 print_vma (pltgot + 0x7ff0, LONG_HEX);
18931 printf ("\n\n");
18932
18933 printf (_(" Reserved entries:\n"));
18934 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18935 addr_size * 2, _("Address"), _("Access"),
18936 addr_size * 2, _("Initial"));
82b1b41b 18937 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18938 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18939 if (ent == (bfd_vma) -1)
18940 goto got_print_fail;
75ec1fdb 18941
c4ab9505
MR
18942 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18943 This entry will be used by some runtime loaders, to store the
18944 module pointer. Otherwise this is an ordinary local entry.
18945 PR 21344: Check for the entry being fully available before
18946 fetching it. */
18947 if (data
18948 && data + ent - pltgot + addr_size <= data_end
18949 && (byte_get (data + ent - pltgot, addr_size)
18950 >> (addr_size * 8 - 1)) != 0)
18951 {
18952 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18953 printf (_(" Module pointer (GNU extension)\n"));
18954 if (ent == (bfd_vma) -1)
18955 goto got_print_fail;
ccb4c951
RS
18956 }
18957 printf ("\n");
18958
f17e9d8a 18959 if (data != NULL && ent < local_end)
ccb4c951
RS
18960 {
18961 printf (_(" Local entries:\n"));
cc5914eb 18962 printf (" %*s %10s %*s\n",
2b692964
NC
18963 addr_size * 2, _("Address"), _("Access"),
18964 addr_size * 2, _("Initial"));
91d6fa6a 18965 while (ent < local_end)
ccb4c951 18966 {
82b1b41b 18967 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18968 printf ("\n");
82b1b41b
NC
18969 if (ent == (bfd_vma) -1)
18970 goto got_print_fail;
ccb4c951
RS
18971 }
18972 printf ("\n");
18973 }
18974
f17e9d8a 18975 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18976 {
18977 int sym_width;
18978
18979 printf (_(" Global entries:\n"));
cc5914eb 18980 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18981 addr_size * 2, _("Address"),
18982 _("Access"),
2b692964 18983 addr_size * 2, _("Initial"),
9cf03b7e
NC
18984 addr_size * 2, _("Sym.Val."),
18985 _("Type"),
18986 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18987 _("Ndx"), _("Name"));
0b4362b0 18988
ccb4c951 18989 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18990
ccb4c951
RS
18991 for (i = gotsym; i < symtabno; i++)
18992 {
82b1b41b 18993 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18994 printf (" ");
e0a31db1 18995
978c4450 18996 if (filedata->dynamic_symbols == NULL)
e0a31db1 18997 printf (_("<no dynamic symbols>"));
978c4450 18998 else if (i < filedata->num_dynamic_syms)
e0a31db1 18999 {
978c4450 19000 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19001
19002 print_vma (psym->st_value, LONG_HEX);
19003 printf (" %-7s %3s ",
dda8d76d
NC
19004 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19005 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19006
84714f86 19007 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19008 print_symbol (sym_width,
84714f86 19009 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19010 else
19011 printf (_("<corrupt: %14ld>"), psym->st_name);
19012 }
ccb4c951 19013 else
7fc5ac57
JBG
19014 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19015 (unsigned long) i);
e0a31db1 19016
ccb4c951 19017 printf ("\n");
82b1b41b
NC
19018 if (ent == (bfd_vma) -1)
19019 break;
ccb4c951
RS
19020 }
19021 printf ("\n");
19022 }
19023
82b1b41b 19024 got_print_fail:
9db70fc3 19025 free (data);
ccb4c951
RS
19026 }
19027
861fb55a
DJ
19028 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19029 {
91d6fa6a 19030 bfd_vma ent, end;
861fb55a
DJ
19031 size_t offset, rel_offset;
19032 unsigned long count, i;
2cf0635d 19033 unsigned char * data;
861fb55a 19034 int addr_size, sym_width;
2cf0635d 19035 Elf_Internal_Rela * rels;
861fb55a 19036
dda8d76d 19037 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19038 if (pltrel == DT_RELA)
19039 {
dda8d76d 19040 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19041 return false;
861fb55a
DJ
19042 }
19043 else
19044 {
dda8d76d 19045 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19046 return false;
861fb55a
DJ
19047 }
19048
91d6fa6a 19049 ent = mips_pltgot;
861fb55a
DJ
19050 addr_size = (is_32bit_elf ? 4 : 8);
19051 end = mips_pltgot + (2 + count) * addr_size;
19052
dda8d76d
NC
19053 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19054 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19055 1, _("Procedure Linkage Table data"));
59245841 19056 if (data == NULL)
288f0ba2
AM
19057 {
19058 free (rels);
015dc7e1 19059 return false;
288f0ba2 19060 }
59245841 19061
9cf03b7e 19062 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19063 printf (_(" Reserved entries:\n"));
19064 printf (_(" %*s %*s Purpose\n"),
2b692964 19065 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19066 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19067 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19068 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19069 printf (_(" Module pointer\n"));
861fb55a
DJ
19070 printf ("\n");
19071
19072 printf (_(" Entries:\n"));
cc5914eb 19073 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19074 addr_size * 2, _("Address"),
19075 addr_size * 2, _("Initial"),
19076 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19077 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19078 for (i = 0; i < count; i++)
19079 {
df97ab2a 19080 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19081
91d6fa6a 19082 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19083 printf (" ");
e0a31db1 19084
978c4450 19085 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19086 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19087 else
e0a31db1 19088 {
978c4450 19089 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19090
19091 print_vma (psym->st_value, LONG_HEX);
19092 printf (" %-7s %3s ",
dda8d76d
NC
19093 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19094 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19095 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19096 print_symbol (sym_width,
84714f86 19097 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19098 else
19099 printf (_("<corrupt: %14ld>"), psym->st_name);
19100 }
861fb55a
DJ
19101 printf ("\n");
19102 }
19103 printf ("\n");
19104
9db70fc3 19105 free (data);
861fb55a
DJ
19106 free (rels);
19107 }
19108
32ec8896 19109 return res;
252b5132
RH
19110}
19111
015dc7e1 19112static bool
dda8d76d 19113process_nds32_specific (Filedata * filedata)
35c08157
KLC
19114{
19115 Elf_Internal_Shdr *sect = NULL;
19116
dda8d76d 19117 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19118 if (sect != NULL && sect->sh_size >= 4)
35c08157 19119 {
9c7b8e9b
AM
19120 unsigned char *buf;
19121 unsigned int flag;
35c08157
KLC
19122
19123 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19124 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19125 _("NDS32 elf flags section"));
35c08157 19126
9c7b8e9b 19127 if (buf == NULL)
015dc7e1 19128 return false;
32ec8896 19129
9c7b8e9b
AM
19130 flag = byte_get (buf, 4);
19131 free (buf);
19132 switch (flag & 0x3)
35c08157
KLC
19133 {
19134 case 0:
19135 printf ("(VEC_SIZE):\tNo entry.\n");
19136 break;
19137 case 1:
19138 printf ("(VEC_SIZE):\t4 bytes\n");
19139 break;
19140 case 2:
19141 printf ("(VEC_SIZE):\t16 bytes\n");
19142 break;
19143 case 3:
19144 printf ("(VEC_SIZE):\treserved\n");
19145 break;
19146 }
19147 }
19148
015dc7e1 19149 return true;
35c08157
KLC
19150}
19151
015dc7e1 19152static bool
dda8d76d 19153process_gnu_liblist (Filedata * filedata)
047b2264 19154{
2cf0635d
NC
19155 Elf_Internal_Shdr * section;
19156 Elf_Internal_Shdr * string_sec;
19157 Elf32_External_Lib * elib;
19158 char * strtab;
c256ffe7 19159 size_t strtab_size;
047b2264 19160 size_t cnt;
d3a49aa8 19161 unsigned long num_liblist;
047b2264 19162 unsigned i;
015dc7e1 19163 bool res = true;
047b2264
JJ
19164
19165 if (! do_arch)
015dc7e1 19166 return true;
047b2264 19167
dda8d76d
NC
19168 for (i = 0, section = filedata->section_headers;
19169 i < filedata->file_header.e_shnum;
b34976b6 19170 i++, section++)
047b2264
JJ
19171 {
19172 switch (section->sh_type)
19173 {
19174 case SHT_GNU_LIBLIST:
dda8d76d 19175 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19176 break;
19177
3f5e193b 19178 elib = (Elf32_External_Lib *)
dda8d76d 19179 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19180 _("liblist section data"));
047b2264
JJ
19181
19182 if (elib == NULL)
32ec8896 19183 {
015dc7e1 19184 res = false;
32ec8896
NC
19185 break;
19186 }
047b2264 19187
dda8d76d
NC
19188 string_sec = filedata->section_headers + section->sh_link;
19189 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19190 string_sec->sh_size,
19191 _("liblist string table"));
047b2264
JJ
19192 if (strtab == NULL
19193 || section->sh_entsize != sizeof (Elf32_External_Lib))
19194 {
19195 free (elib);
2842702f 19196 free (strtab);
015dc7e1 19197 res = false;
047b2264
JJ
19198 break;
19199 }
59245841 19200 strtab_size = string_sec->sh_size;
047b2264 19201
d3a49aa8
AM
19202 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19203 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19204 "\nLibrary list section '%s' contains %lu entries:\n",
19205 num_liblist),
dda8d76d 19206 printable_section_name (filedata, section),
d3a49aa8 19207 num_liblist);
047b2264 19208
2b692964 19209 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19210
19211 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19212 ++cnt)
19213 {
19214 Elf32_Lib liblist;
91d6fa6a 19215 time_t atime;
d5b07ef4 19216 char timebuf[128];
2cf0635d 19217 struct tm * tmp;
047b2264
JJ
19218
19219 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19220 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19221 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19222 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19223 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19224
91d6fa6a 19225 tmp = gmtime (&atime);
e9e44622
JJ
19226 snprintf (timebuf, sizeof (timebuf),
19227 "%04u-%02u-%02uT%02u:%02u:%02u",
19228 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19229 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19230
19231 printf ("%3lu: ", (unsigned long) cnt);
19232 if (do_wide)
c256ffe7 19233 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19234 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19235 else
c256ffe7 19236 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19237 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19238 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19239 liblist.l_version, liblist.l_flags);
19240 }
19241
19242 free (elib);
2842702f 19243 free (strtab);
047b2264
JJ
19244 }
19245 }
19246
32ec8896 19247 return res;
047b2264
JJ
19248}
19249
9437c45b 19250static const char *
dda8d76d 19251get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19252{
19253 static char buff[64];
103f02d3 19254
dda8d76d 19255 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19256 switch (e_type)
19257 {
57346661 19258 case NT_AUXV:
1ec5cd37 19259 return _("NT_AUXV (auxiliary vector)");
57346661 19260 case NT_PRSTATUS:
1ec5cd37 19261 return _("NT_PRSTATUS (prstatus structure)");
57346661 19262 case NT_FPREGSET:
1ec5cd37 19263 return _("NT_FPREGSET (floating point registers)");
57346661 19264 case NT_PRPSINFO:
1ec5cd37 19265 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19266 case NT_TASKSTRUCT:
1ec5cd37 19267 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19268 case NT_GDB_TDESC:
19269 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19270 case NT_PRXFPREG:
1ec5cd37 19271 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19272 case NT_PPC_VMX:
19273 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19274 case NT_PPC_VSX:
19275 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19276 case NT_PPC_TAR:
19277 return _("NT_PPC_TAR (ppc TAR register)");
19278 case NT_PPC_PPR:
19279 return _("NT_PPC_PPR (ppc PPR register)");
19280 case NT_PPC_DSCR:
19281 return _("NT_PPC_DSCR (ppc DSCR register)");
19282 case NT_PPC_EBB:
19283 return _("NT_PPC_EBB (ppc EBB registers)");
19284 case NT_PPC_PMU:
19285 return _("NT_PPC_PMU (ppc PMU registers)");
19286 case NT_PPC_TM_CGPR:
19287 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19288 case NT_PPC_TM_CFPR:
19289 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19290 case NT_PPC_TM_CVMX:
19291 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19292 case NT_PPC_TM_CVSX:
3fd21718 19293 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19294 case NT_PPC_TM_SPR:
19295 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19296 case NT_PPC_TM_CTAR:
19297 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19298 case NT_PPC_TM_CPPR:
19299 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19300 case NT_PPC_TM_CDSCR:
19301 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19302 case NT_386_TLS:
19303 return _("NT_386_TLS (x86 TLS information)");
19304 case NT_386_IOPERM:
19305 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19306 case NT_X86_XSTATE:
19307 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19308 case NT_X86_CET:
19309 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19310 case NT_S390_HIGH_GPRS:
19311 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19312 case NT_S390_TIMER:
19313 return _("NT_S390_TIMER (s390 timer register)");
19314 case NT_S390_TODCMP:
19315 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19316 case NT_S390_TODPREG:
19317 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19318 case NT_S390_CTRS:
19319 return _("NT_S390_CTRS (s390 control registers)");
19320 case NT_S390_PREFIX:
19321 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19322 case NT_S390_LAST_BREAK:
19323 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19324 case NT_S390_SYSTEM_CALL:
19325 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19326 case NT_S390_TDB:
19327 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19328 case NT_S390_VXRS_LOW:
19329 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19330 case NT_S390_VXRS_HIGH:
19331 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19332 case NT_S390_GS_CB:
19333 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19334 case NT_S390_GS_BC:
19335 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19336 case NT_ARM_VFP:
19337 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19338 case NT_ARM_TLS:
19339 return _("NT_ARM_TLS (AArch TLS registers)");
19340 case NT_ARM_HW_BREAK:
19341 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19342 case NT_ARM_HW_WATCH:
19343 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19344 case NT_ARM_SYSTEM_CALL:
19345 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19346 case NT_ARM_SVE:
19347 return _("NT_ARM_SVE (AArch SVE registers)");
19348 case NT_ARM_PAC_MASK:
19349 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19350 case NT_ARM_PACA_KEYS:
19351 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19352 case NT_ARM_PACG_KEYS:
19353 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19354 case NT_ARM_TAGGED_ADDR_CTRL:
19355 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19356 case NT_ARM_PAC_ENABLED_KEYS:
19357 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19358 case NT_ARC_V2:
19359 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19360 case NT_RISCV_CSR:
19361 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19362 case NT_PSTATUS:
1ec5cd37 19363 return _("NT_PSTATUS (pstatus structure)");
57346661 19364 case NT_FPREGS:
1ec5cd37 19365 return _("NT_FPREGS (floating point registers)");
57346661 19366 case NT_PSINFO:
1ec5cd37 19367 return _("NT_PSINFO (psinfo structure)");
57346661 19368 case NT_LWPSTATUS:
1ec5cd37 19369 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19370 case NT_LWPSINFO:
1ec5cd37 19371 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19372 case NT_WIN32PSTATUS:
1ec5cd37 19373 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19374 case NT_SIGINFO:
19375 return _("NT_SIGINFO (siginfo_t data)");
19376 case NT_FILE:
19377 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19378 default:
19379 break;
19380 }
19381 else
19382 switch (e_type)
19383 {
19384 case NT_VERSION:
19385 return _("NT_VERSION (version)");
19386 case NT_ARCH:
19387 return _("NT_ARCH (architecture)");
9ef920e9 19388 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19389 return _("OPEN");
9ef920e9 19390 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19391 return _("func");
c8795e1f
NC
19392 case NT_GO_BUILDID:
19393 return _("GO BUILDID");
3ac925fc
LB
19394 case FDO_PACKAGING_METADATA:
19395 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19396 default:
19397 break;
19398 }
19399
e9e44622 19400 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19401 return buff;
779fe533
NC
19402}
19403
015dc7e1 19404static bool
9ece1fa9
TT
19405print_core_note (Elf_Internal_Note *pnote)
19406{
19407 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19408 bfd_vma count, page_size;
19409 unsigned char *descdata, *filenames, *descend;
19410
19411 if (pnote->type != NT_FILE)
04ac15ab
AS
19412 {
19413 if (do_wide)
19414 printf ("\n");
015dc7e1 19415 return true;
04ac15ab 19416 }
9ece1fa9
TT
19417
19418#ifndef BFD64
19419 if (!is_32bit_elf)
19420 {
19421 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19422 /* Still "successful". */
015dc7e1 19423 return true;
9ece1fa9
TT
19424 }
19425#endif
19426
19427 if (pnote->descsz < 2 * addr_size)
19428 {
32ec8896 19429 error (_(" Malformed note - too short for header\n"));
015dc7e1 19430 return false;
9ece1fa9
TT
19431 }
19432
19433 descdata = (unsigned char *) pnote->descdata;
19434 descend = descdata + pnote->descsz;
19435
19436 if (descdata[pnote->descsz - 1] != '\0')
19437 {
32ec8896 19438 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19439 return false;
9ece1fa9
TT
19440 }
19441
19442 count = byte_get (descdata, addr_size);
19443 descdata += addr_size;
19444
19445 page_size = byte_get (descdata, addr_size);
19446 descdata += addr_size;
19447
5396a86e
AM
19448 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19449 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19450 {
32ec8896 19451 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19452 return false;
9ece1fa9
TT
19453 }
19454
19455 printf (_(" Page size: "));
19456 print_vma (page_size, DEC);
19457 printf ("\n");
19458
19459 printf (_(" %*s%*s%*s\n"),
19460 (int) (2 + 2 * addr_size), _("Start"),
19461 (int) (4 + 2 * addr_size), _("End"),
19462 (int) (4 + 2 * addr_size), _("Page Offset"));
19463 filenames = descdata + count * 3 * addr_size;
595712bb 19464 while (count-- > 0)
9ece1fa9
TT
19465 {
19466 bfd_vma start, end, file_ofs;
19467
19468 if (filenames == descend)
19469 {
32ec8896 19470 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19471 return false;
9ece1fa9
TT
19472 }
19473
19474 start = byte_get (descdata, addr_size);
19475 descdata += addr_size;
19476 end = byte_get (descdata, addr_size);
19477 descdata += addr_size;
19478 file_ofs = byte_get (descdata, addr_size);
19479 descdata += addr_size;
19480
19481 printf (" ");
19482 print_vma (start, FULL_HEX);
19483 printf (" ");
19484 print_vma (end, FULL_HEX);
19485 printf (" ");
19486 print_vma (file_ofs, FULL_HEX);
19487 printf ("\n %s\n", filenames);
19488
19489 filenames += 1 + strlen ((char *) filenames);
19490 }
19491
015dc7e1 19492 return true;
9ece1fa9
TT
19493}
19494
1118d252
RM
19495static const char *
19496get_gnu_elf_note_type (unsigned e_type)
19497{
1449284b 19498 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19499 switch (e_type)
19500 {
19501 case NT_GNU_ABI_TAG:
19502 return _("NT_GNU_ABI_TAG (ABI version tag)");
19503 case NT_GNU_HWCAP:
19504 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19505 case NT_GNU_BUILD_ID:
19506 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19507 case NT_GNU_GOLD_VERSION:
19508 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19509 case NT_GNU_PROPERTY_TYPE_0:
19510 return _("NT_GNU_PROPERTY_TYPE_0");
19511 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19512 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19513 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19514 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19515 default:
1449284b
NC
19516 {
19517 static char buff[64];
1118d252 19518
1449284b
NC
19519 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19520 return buff;
19521 }
19522 }
1118d252
RM
19523}
19524
a9eafb08
L
19525static void
19526decode_x86_compat_isa (unsigned int bitmask)
19527{
19528 while (bitmask)
19529 {
19530 unsigned int bit = bitmask & (- bitmask);
19531
19532 bitmask &= ~ bit;
19533 switch (bit)
19534 {
19535 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19536 printf ("i486");
19537 break;
19538 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19539 printf ("586");
19540 break;
19541 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19542 printf ("686");
19543 break;
19544 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19545 printf ("SSE");
19546 break;
19547 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19548 printf ("SSE2");
19549 break;
19550 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19551 printf ("SSE3");
19552 break;
19553 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19554 printf ("SSSE3");
19555 break;
19556 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19557 printf ("SSE4_1");
19558 break;
19559 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19560 printf ("SSE4_2");
19561 break;
19562 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19563 printf ("AVX");
19564 break;
19565 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19566 printf ("AVX2");
19567 break;
19568 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19569 printf ("AVX512F");
19570 break;
19571 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19572 printf ("AVX512CD");
19573 break;
19574 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19575 printf ("AVX512ER");
19576 break;
19577 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19578 printf ("AVX512PF");
19579 break;
19580 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19581 printf ("AVX512VL");
19582 break;
19583 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19584 printf ("AVX512DQ");
19585 break;
19586 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19587 printf ("AVX512BW");
19588 break;
65b3d26e
L
19589 default:
19590 printf (_("<unknown: %x>"), bit);
19591 break;
a9eafb08
L
19592 }
19593 if (bitmask)
19594 printf (", ");
19595 }
19596}
19597
9ef920e9 19598static void
32930e4e 19599decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19600{
0a59decb 19601 if (!bitmask)
90c745dc
L
19602 {
19603 printf (_("<None>"));
19604 return;
19605 }
90c745dc 19606
9ef920e9
NC
19607 while (bitmask)
19608 {
1fc87489 19609 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19610
19611 bitmask &= ~ bit;
19612 switch (bit)
19613 {
32930e4e 19614 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19615 printf ("CMOV");
19616 break;
32930e4e 19617 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19618 printf ("SSE");
19619 break;
32930e4e 19620 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19621 printf ("SSE2");
19622 break;
32930e4e 19623 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19624 printf ("SSE3");
19625 break;
32930e4e 19626 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19627 printf ("SSSE3");
19628 break;
32930e4e 19629 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19630 printf ("SSE4_1");
19631 break;
32930e4e 19632 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19633 printf ("SSE4_2");
19634 break;
32930e4e 19635 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19636 printf ("AVX");
19637 break;
32930e4e 19638 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19639 printf ("AVX2");
19640 break;
32930e4e 19641 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19642 printf ("FMA");
19643 break;
32930e4e 19644 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19645 printf ("AVX512F");
19646 break;
32930e4e 19647 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19648 printf ("AVX512CD");
19649 break;
32930e4e 19650 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19651 printf ("AVX512ER");
19652 break;
32930e4e 19653 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19654 printf ("AVX512PF");
19655 break;
32930e4e 19656 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19657 printf ("AVX512VL");
19658 break;
32930e4e 19659 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19660 printf ("AVX512DQ");
19661 break;
32930e4e 19662 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19663 printf ("AVX512BW");
19664 break;
32930e4e 19665 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19666 printf ("AVX512_4FMAPS");
19667 break;
32930e4e 19668 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19669 printf ("AVX512_4VNNIW");
19670 break;
32930e4e 19671 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19672 printf ("AVX512_BITALG");
19673 break;
32930e4e 19674 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19675 printf ("AVX512_IFMA");
19676 break;
32930e4e 19677 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19678 printf ("AVX512_VBMI");
19679 break;
32930e4e 19680 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19681 printf ("AVX512_VBMI2");
19682 break;
32930e4e 19683 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19684 printf ("AVX512_VNNI");
19685 break;
32930e4e 19686 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19687 printf ("AVX512_BF16");
19688 break;
65b3d26e
L
19689 default:
19690 printf (_("<unknown: %x>"), bit);
19691 break;
9ef920e9
NC
19692 }
19693 if (bitmask)
19694 printf (", ");
19695 }
19696}
19697
28cdbb18
SM
19698static const char *
19699get_amdgpu_elf_note_type (unsigned int e_type)
19700{
19701 switch (e_type)
19702 {
19703 case NT_AMDGPU_METADATA:
19704 return _("NT_AMDGPU_METADATA (code object metadata)");
19705 default:
19706 {
19707 static char buf[64];
19708 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19709 return buf;
19710 }
19711 }
19712}
19713
32930e4e
L
19714static void
19715decode_x86_isa (unsigned int bitmask)
19716{
32930e4e
L
19717 while (bitmask)
19718 {
19719 unsigned int bit = bitmask & (- bitmask);
19720
19721 bitmask &= ~ bit;
19722 switch (bit)
19723 {
b0ab0693
L
19724 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19725 printf ("x86-64-baseline");
19726 break;
32930e4e
L
19727 case GNU_PROPERTY_X86_ISA_1_V2:
19728 printf ("x86-64-v2");
19729 break;
19730 case GNU_PROPERTY_X86_ISA_1_V3:
19731 printf ("x86-64-v3");
19732 break;
19733 case GNU_PROPERTY_X86_ISA_1_V4:
19734 printf ("x86-64-v4");
19735 break;
19736 default:
19737 printf (_("<unknown: %x>"), bit);
19738 break;
19739 }
19740 if (bitmask)
19741 printf (", ");
19742 }
19743}
19744
ee2fdd6f 19745static void
a9eafb08 19746decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19747{
0a59decb 19748 if (!bitmask)
90c745dc
L
19749 {
19750 printf (_("<None>"));
19751 return;
19752 }
90c745dc 19753
ee2fdd6f
L
19754 while (bitmask)
19755 {
19756 unsigned int bit = bitmask & (- bitmask);
19757
19758 bitmask &= ~ bit;
19759 switch (bit)
19760 {
19761 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19762 printf ("IBT");
ee2fdd6f 19763 break;
48580982 19764 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19765 printf ("SHSTK");
48580982 19766 break;
279d901e
L
19767 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19768 printf ("LAM_U48");
19769 break;
19770 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19771 printf ("LAM_U57");
19772 break;
ee2fdd6f
L
19773 default:
19774 printf (_("<unknown: %x>"), bit);
19775 break;
19776 }
19777 if (bitmask)
19778 printf (", ");
19779 }
19780}
19781
a9eafb08
L
19782static void
19783decode_x86_feature_2 (unsigned int bitmask)
19784{
0a59decb 19785 if (!bitmask)
90c745dc
L
19786 {
19787 printf (_("<None>"));
19788 return;
19789 }
90c745dc 19790
a9eafb08
L
19791 while (bitmask)
19792 {
19793 unsigned int bit = bitmask & (- bitmask);
19794
19795 bitmask &= ~ bit;
19796 switch (bit)
19797 {
19798 case GNU_PROPERTY_X86_FEATURE_2_X86:
19799 printf ("x86");
19800 break;
19801 case GNU_PROPERTY_X86_FEATURE_2_X87:
19802 printf ("x87");
19803 break;
19804 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19805 printf ("MMX");
19806 break;
19807 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19808 printf ("XMM");
19809 break;
19810 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19811 printf ("YMM");
19812 break;
19813 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19814 printf ("ZMM");
19815 break;
a308b89d
L
19816 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19817 printf ("TMM");
19818 break;
32930e4e
L
19819 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19820 printf ("MASK");
19821 break;
a9eafb08
L
19822 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19823 printf ("FXSR");
19824 break;
19825 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19826 printf ("XSAVE");
19827 break;
19828 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19829 printf ("XSAVEOPT");
19830 break;
19831 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19832 printf ("XSAVEC");
19833 break;
65b3d26e
L
19834 default:
19835 printf (_("<unknown: %x>"), bit);
19836 break;
a9eafb08
L
19837 }
19838 if (bitmask)
19839 printf (", ");
19840 }
19841}
19842
cd702818
SD
19843static void
19844decode_aarch64_feature_1_and (unsigned int bitmask)
19845{
19846 while (bitmask)
19847 {
19848 unsigned int bit = bitmask & (- bitmask);
19849
19850 bitmask &= ~ bit;
19851 switch (bit)
19852 {
19853 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19854 printf ("BTI");
19855 break;
19856
19857 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19858 printf ("PAC");
19859 break;
19860
19861 default:
19862 printf (_("<unknown: %x>"), bit);
19863 break;
19864 }
19865 if (bitmask)
19866 printf (", ");
19867 }
19868}
19869
6320fd00
L
19870static void
19871decode_1_needed (unsigned int bitmask)
19872{
19873 while (bitmask)
19874 {
19875 unsigned int bit = bitmask & (- bitmask);
19876
19877 bitmask &= ~ bit;
19878 switch (bit)
19879 {
19880 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19881 printf ("indirect external access");
19882 break;
19883 default:
19884 printf (_("<unknown: %x>"), bit);
19885 break;
19886 }
19887 if (bitmask)
19888 printf (", ");
19889 }
19890}
19891
9ef920e9 19892static void
dda8d76d 19893print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19894{
19895 unsigned char * ptr = (unsigned char *) pnote->descdata;
19896 unsigned char * ptr_end = ptr + pnote->descsz;
19897 unsigned int size = is_32bit_elf ? 4 : 8;
19898
19899 printf (_(" Properties: "));
19900
1fc87489 19901 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19902 {
19903 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19904 return;
19905 }
19906
6ab2c4ed 19907 while (ptr < ptr_end)
9ef920e9 19908 {
1fc87489 19909 unsigned int j;
6ab2c4ed
MC
19910 unsigned int type;
19911 unsigned int datasz;
19912
19913 if ((size_t) (ptr_end - ptr) < 8)
19914 {
19915 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19916 break;
19917 }
19918
19919 type = byte_get (ptr, 4);
19920 datasz = byte_get (ptr + 4, 4);
9ef920e9 19921
1fc87489 19922 ptr += 8;
9ef920e9 19923
6ab2c4ed 19924 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19925 {
1fc87489
L
19926 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19927 type, datasz);
9ef920e9 19928 break;
1fc87489 19929 }
9ef920e9 19930
1fc87489
L
19931 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19932 {
dda8d76d
NC
19933 if (filedata->file_header.e_machine == EM_X86_64
19934 || filedata->file_header.e_machine == EM_IAMCU
19935 || filedata->file_header.e_machine == EM_386)
1fc87489 19936 {
aa7bca9b
L
19937 unsigned int bitmask;
19938
19939 if (datasz == 4)
0a59decb 19940 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19941 else
19942 bitmask = 0;
19943
1fc87489
L
19944 switch (type)
19945 {
19946 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19947 if (datasz != 4)
aa7bca9b
L
19948 printf (_("x86 ISA used: <corrupt length: %#x> "),
19949 datasz);
1fc87489 19950 else
aa7bca9b
L
19951 {
19952 printf ("x86 ISA used: ");
19953 decode_x86_isa (bitmask);
19954 }
1fc87489 19955 goto next;
9ef920e9 19956
1fc87489 19957 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19958 if (datasz != 4)
aa7bca9b
L
19959 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19960 datasz);
1fc87489 19961 else
aa7bca9b
L
19962 {
19963 printf ("x86 ISA needed: ");
19964 decode_x86_isa (bitmask);
19965 }
1fc87489 19966 goto next;
9ef920e9 19967
ee2fdd6f 19968 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19969 if (datasz != 4)
aa7bca9b
L
19970 printf (_("x86 feature: <corrupt length: %#x> "),
19971 datasz);
ee2fdd6f 19972 else
aa7bca9b
L
19973 {
19974 printf ("x86 feature: ");
a9eafb08
L
19975 decode_x86_feature_1 (bitmask);
19976 }
19977 goto next;
19978
19979 case GNU_PROPERTY_X86_FEATURE_2_USED:
19980 if (datasz != 4)
19981 printf (_("x86 feature used: <corrupt length: %#x> "),
19982 datasz);
19983 else
19984 {
19985 printf ("x86 feature used: ");
19986 decode_x86_feature_2 (bitmask);
19987 }
19988 goto next;
19989
19990 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19991 if (datasz != 4)
19992 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19993 else
19994 {
19995 printf ("x86 feature needed: ");
19996 decode_x86_feature_2 (bitmask);
19997 }
19998 goto next;
19999
20000 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20001 if (datasz != 4)
20002 printf (_("x86 ISA used: <corrupt length: %#x> "),
20003 datasz);
20004 else
20005 {
20006 printf ("x86 ISA used: ");
20007 decode_x86_compat_isa (bitmask);
20008 }
20009 goto next;
20010
20011 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20012 if (datasz != 4)
20013 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20014 datasz);
20015 else
20016 {
20017 printf ("x86 ISA needed: ");
20018 decode_x86_compat_isa (bitmask);
aa7bca9b 20019 }
ee2fdd6f
L
20020 goto next;
20021
32930e4e
L
20022 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20023 if (datasz != 4)
20024 printf (_("x86 ISA used: <corrupt length: %#x> "),
20025 datasz);
20026 else
20027 {
20028 printf ("x86 ISA used: ");
20029 decode_x86_compat_2_isa (bitmask);
20030 }
20031 goto next;
20032
20033 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20034 if (datasz != 4)
20035 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20036 datasz);
20037 else
20038 {
20039 printf ("x86 ISA needed: ");
20040 decode_x86_compat_2_isa (bitmask);
20041 }
20042 goto next;
20043
1fc87489
L
20044 default:
20045 break;
20046 }
20047 }
cd702818
SD
20048 else if (filedata->file_header.e_machine == EM_AARCH64)
20049 {
20050 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20051 {
20052 printf ("AArch64 feature: ");
20053 if (datasz != 4)
20054 printf (_("<corrupt length: %#x> "), datasz);
20055 else
20056 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20057 goto next;
20058 }
20059 }
1fc87489
L
20060 }
20061 else
20062 {
20063 switch (type)
9ef920e9 20064 {
1fc87489
L
20065 case GNU_PROPERTY_STACK_SIZE:
20066 printf (_("stack size: "));
20067 if (datasz != size)
20068 printf (_("<corrupt length: %#x> "), datasz);
20069 else
20070 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20071 goto next;
20072
20073 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20074 printf ("no copy on protected ");
20075 if (datasz)
20076 printf (_("<corrupt length: %#x> "), datasz);
20077 goto next;
20078
20079 default:
5a767724
L
20080 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20081 && type <= GNU_PROPERTY_UINT32_AND_HI)
20082 || (type >= GNU_PROPERTY_UINT32_OR_LO
20083 && type <= GNU_PROPERTY_UINT32_OR_HI))
20084 {
6320fd00
L
20085 switch (type)
20086 {
20087 case GNU_PROPERTY_1_NEEDED:
20088 if (datasz != 4)
20089 printf (_("1_needed: <corrupt length: %#x> "),
20090 datasz);
20091 else
20092 {
20093 unsigned int bitmask = byte_get (ptr, 4);
20094 printf ("1_needed: ");
20095 decode_1_needed (bitmask);
20096 }
20097 goto next;
20098
20099 default:
20100 break;
20101 }
5a767724
L
20102 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20103 printf (_("UINT32_AND (%#x): "), type);
20104 else
20105 printf (_("UINT32_OR (%#x): "), type);
20106 if (datasz != 4)
20107 printf (_("<corrupt length: %#x> "), datasz);
20108 else
20109 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20110 goto next;
20111 }
9ef920e9
NC
20112 break;
20113 }
9ef920e9
NC
20114 }
20115
1fc87489
L
20116 if (type < GNU_PROPERTY_LOPROC)
20117 printf (_("<unknown type %#x data: "), type);
20118 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20119 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20120 else
20121 printf (_("<application-specific type %#x data: "), type);
20122 for (j = 0; j < datasz; ++j)
20123 printf ("%02x ", ptr[j] & 0xff);
20124 printf (">");
20125
dc1e8a47 20126 next:
9ef920e9 20127 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20128 if (ptr == ptr_end)
20129 break;
1fc87489 20130
6ab2c4ed
MC
20131 if (do_wide)
20132 printf (", ");
20133 else
20134 printf ("\n\t");
9ef920e9
NC
20135 }
20136
20137 printf ("\n");
20138}
20139
015dc7e1 20140static bool
dda8d76d 20141print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20142{
1449284b 20143 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20144 switch (pnote->type)
20145 {
20146 case NT_GNU_BUILD_ID:
20147 {
20148 unsigned long i;
20149
20150 printf (_(" Build ID: "));
20151 for (i = 0; i < pnote->descsz; ++i)
20152 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20153 printf ("\n");
664f90a3
TT
20154 }
20155 break;
20156
20157 case NT_GNU_ABI_TAG:
20158 {
20159 unsigned long os, major, minor, subminor;
20160 const char *osname;
20161
3102e897
NC
20162 /* PR 17531: file: 030-599401-0.004. */
20163 if (pnote->descsz < 16)
20164 {
20165 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20166 break;
20167 }
20168
664f90a3
TT
20169 os = byte_get ((unsigned char *) pnote->descdata, 4);
20170 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20171 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20172 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20173
20174 switch (os)
20175 {
20176 case GNU_ABI_TAG_LINUX:
20177 osname = "Linux";
20178 break;
20179 case GNU_ABI_TAG_HURD:
20180 osname = "Hurd";
20181 break;
20182 case GNU_ABI_TAG_SOLARIS:
20183 osname = "Solaris";
20184 break;
20185 case GNU_ABI_TAG_FREEBSD:
20186 osname = "FreeBSD";
20187 break;
20188 case GNU_ABI_TAG_NETBSD:
20189 osname = "NetBSD";
20190 break;
14ae95f2
RM
20191 case GNU_ABI_TAG_SYLLABLE:
20192 osname = "Syllable";
20193 break;
20194 case GNU_ABI_TAG_NACL:
20195 osname = "NaCl";
20196 break;
664f90a3
TT
20197 default:
20198 osname = "Unknown";
20199 break;
20200 }
20201
20202 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20203 major, minor, subminor);
20204 }
20205 break;
926c5385
CC
20206
20207 case NT_GNU_GOLD_VERSION:
20208 {
20209 unsigned long i;
20210
20211 printf (_(" Version: "));
20212 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20213 printf ("%c", pnote->descdata[i]);
20214 printf ("\n");
20215 }
20216 break;
1449284b
NC
20217
20218 case NT_GNU_HWCAP:
20219 {
20220 unsigned long num_entries, mask;
20221
20222 /* Hardware capabilities information. Word 0 is the number of entries.
20223 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20224 is a series of entries, where each entry is a single byte followed
20225 by a nul terminated string. The byte gives the bit number to test
20226 if enabled in the bitmask. */
20227 printf (_(" Hardware Capabilities: "));
20228 if (pnote->descsz < 8)
20229 {
32ec8896 20230 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20231 return false;
1449284b
NC
20232 }
20233 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20234 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20235 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20236 /* FIXME: Add code to display the entries... */
20237 }
20238 break;
20239
9ef920e9 20240 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20241 print_gnu_property_note (filedata, pnote);
9ef920e9 20242 break;
9abca702 20243
1449284b
NC
20244 default:
20245 /* Handle unrecognised types. An error message should have already been
20246 created by get_gnu_elf_note_type(), so all that we need to do is to
20247 display the data. */
20248 {
20249 unsigned long i;
20250
20251 printf (_(" Description data: "));
20252 for (i = 0; i < pnote->descsz; ++i)
20253 printf ("%02x ", pnote->descdata[i] & 0xff);
20254 printf ("\n");
20255 }
20256 break;
664f90a3
TT
20257 }
20258
015dc7e1 20259 return true;
664f90a3
TT
20260}
20261
685080f2
NC
20262static const char *
20263get_v850_elf_note_type (enum v850_notes n_type)
20264{
20265 static char buff[64];
20266
20267 switch (n_type)
20268 {
20269 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20270 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20271 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20272 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20273 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20274 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20275 default:
20276 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20277 return buff;
20278 }
20279}
20280
015dc7e1 20281static bool
685080f2
NC
20282print_v850_note (Elf_Internal_Note * pnote)
20283{
20284 unsigned int val;
20285
20286 if (pnote->descsz != 4)
015dc7e1 20287 return false;
32ec8896 20288
685080f2
NC
20289 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20290
20291 if (val == 0)
20292 {
20293 printf (_("not set\n"));
015dc7e1 20294 return true;
685080f2
NC
20295 }
20296
20297 switch (pnote->type)
20298 {
20299 case V850_NOTE_ALIGNMENT:
20300 switch (val)
20301 {
015dc7e1
AM
20302 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20303 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20304 }
20305 break;
14ae95f2 20306
685080f2
NC
20307 case V850_NOTE_DATA_SIZE:
20308 switch (val)
20309 {
015dc7e1
AM
20310 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20311 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20312 }
20313 break;
14ae95f2 20314
685080f2
NC
20315 case V850_NOTE_FPU_INFO:
20316 switch (val)
20317 {
015dc7e1
AM
20318 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20319 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20320 }
20321 break;
14ae95f2 20322
685080f2
NC
20323 case V850_NOTE_MMU_INFO:
20324 case V850_NOTE_CACHE_INFO:
20325 case V850_NOTE_SIMD_INFO:
20326 if (val == EF_RH850_SIMD)
20327 {
20328 printf (_("yes\n"));
015dc7e1 20329 return true;
685080f2
NC
20330 }
20331 break;
20332
20333 default:
20334 /* An 'unknown note type' message will already have been displayed. */
20335 break;
20336 }
20337
20338 printf (_("unknown value: %x\n"), val);
015dc7e1 20339 return false;
685080f2
NC
20340}
20341
015dc7e1 20342static bool
c6056a74
SF
20343process_netbsd_elf_note (Elf_Internal_Note * pnote)
20344{
20345 unsigned int version;
20346
20347 switch (pnote->type)
20348 {
20349 case NT_NETBSD_IDENT:
b966f55f
AM
20350 if (pnote->descsz < 1)
20351 break;
c6056a74
SF
20352 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20353 if ((version / 10000) % 100)
b966f55f 20354 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20355 version, version / 100000000, (version / 1000000) % 100,
20356 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20357 'A' + (version / 10000) % 26);
c6056a74
SF
20358 else
20359 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20360 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20361 (version / 100) % 100);
015dc7e1 20362 return true;
c6056a74
SF
20363
20364 case NT_NETBSD_MARCH:
9abca702 20365 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20366 pnote->descdata);
015dc7e1 20367 return true;
c6056a74 20368
9abca702 20369 case NT_NETBSD_PAX:
b966f55f
AM
20370 if (pnote->descsz < 1)
20371 break;
9abca702
CZ
20372 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20373 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20374 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20375 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20376 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20377 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20378 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20379 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20380 return true;
c6056a74 20381 }
b966f55f
AM
20382
20383 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20384 pnote->descsz, pnote->type);
015dc7e1 20385 return false;
c6056a74
SF
20386}
20387
f4ddf30f 20388static const char *
dda8d76d 20389get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20390{
f4ddf30f
JB
20391 switch (e_type)
20392 {
20393 case NT_FREEBSD_THRMISC:
20394 return _("NT_THRMISC (thrmisc structure)");
20395 case NT_FREEBSD_PROCSTAT_PROC:
20396 return _("NT_PROCSTAT_PROC (proc data)");
20397 case NT_FREEBSD_PROCSTAT_FILES:
20398 return _("NT_PROCSTAT_FILES (files data)");
20399 case NT_FREEBSD_PROCSTAT_VMMAP:
20400 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20401 case NT_FREEBSD_PROCSTAT_GROUPS:
20402 return _("NT_PROCSTAT_GROUPS (groups data)");
20403 case NT_FREEBSD_PROCSTAT_UMASK:
20404 return _("NT_PROCSTAT_UMASK (umask data)");
20405 case NT_FREEBSD_PROCSTAT_RLIMIT:
20406 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20407 case NT_FREEBSD_PROCSTAT_OSREL:
20408 return _("NT_PROCSTAT_OSREL (osreldate data)");
20409 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20410 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20411 case NT_FREEBSD_PROCSTAT_AUXV:
20412 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20413 case NT_FREEBSD_PTLWPINFO:
20414 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20415 case NT_FREEBSD_X86_SEGBASES:
20416 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20417 }
dda8d76d 20418 return get_note_type (filedata, e_type);
f4ddf30f
JB
20419}
20420
9437c45b 20421static const char *
dda8d76d 20422get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20423{
20424 static char buff[64];
20425
540e6170
CZ
20426 switch (e_type)
20427 {
20428 case NT_NETBSDCORE_PROCINFO:
20429 /* NetBSD core "procinfo" structure. */
20430 return _("NetBSD procinfo structure");
9437c45b 20431
540e6170
CZ
20432 case NT_NETBSDCORE_AUXV:
20433 return _("NetBSD ELF auxiliary vector data");
9437c45b 20434
06d949ec
KR
20435 case NT_NETBSDCORE_LWPSTATUS:
20436 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20437
540e6170 20438 default:
06d949ec 20439 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20440 defined for NetBSD core files. If the note type is less
20441 than the start of the machine-dependent note types, we don't
20442 understand it. */
20443
20444 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20445 {
20446 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20447 return buff;
20448 }
20449 break;
9437c45b
JT
20450 }
20451
dda8d76d 20452 switch (filedata->file_header.e_machine)
9437c45b
JT
20453 {
20454 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20455 and PT_GETFPREGS == mach+2. */
20456
20457 case EM_OLD_ALPHA:
20458 case EM_ALPHA:
20459 case EM_SPARC:
20460 case EM_SPARC32PLUS:
20461 case EM_SPARCV9:
20462 switch (e_type)
20463 {
2b692964 20464 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20465 return _("PT_GETREGS (reg structure)");
2b692964 20466 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20467 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20468 default:
20469 break;
20470 }
20471 break;
20472
c0d38b0e
CZ
20473 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20474 There's also old PT___GETREGS40 == mach + 1 for old reg
20475 structure which lacks GBR. */
20476 case EM_SH:
20477 switch (e_type)
20478 {
20479 case NT_NETBSDCORE_FIRSTMACH + 1:
20480 return _("PT___GETREGS40 (old reg structure)");
20481 case NT_NETBSDCORE_FIRSTMACH + 3:
20482 return _("PT_GETREGS (reg structure)");
20483 case NT_NETBSDCORE_FIRSTMACH + 5:
20484 return _("PT_GETFPREGS (fpreg structure)");
20485 default:
20486 break;
20487 }
20488 break;
20489
9437c45b
JT
20490 /* On all other arch's, PT_GETREGS == mach+1 and
20491 PT_GETFPREGS == mach+3. */
20492 default:
20493 switch (e_type)
20494 {
2b692964 20495 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20496 return _("PT_GETREGS (reg structure)");
2b692964 20497 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20498 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20499 default:
20500 break;
20501 }
20502 }
20503
9cf03b7e 20504 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20505 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20506 return buff;
20507}
20508
98ca73af
FC
20509static const char *
20510get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20511{
20512 switch (e_type)
20513 {
20514 case NT_OPENBSD_PROCINFO:
20515 return _("OpenBSD procinfo structure");
20516 case NT_OPENBSD_AUXV:
20517 return _("OpenBSD ELF auxiliary vector data");
20518 case NT_OPENBSD_REGS:
20519 return _("OpenBSD regular registers");
20520 case NT_OPENBSD_FPREGS:
20521 return _("OpenBSD floating point registers");
20522 case NT_OPENBSD_WCOOKIE:
20523 return _("OpenBSD window cookie");
20524 }
20525
20526 return get_note_type (filedata, e_type);
20527}
20528
70616151
TT
20529static const char *
20530get_stapsdt_note_type (unsigned e_type)
20531{
20532 static char buff[64];
20533
20534 switch (e_type)
20535 {
20536 case NT_STAPSDT:
20537 return _("NT_STAPSDT (SystemTap probe descriptors)");
20538
20539 default:
20540 break;
20541 }
20542
20543 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20544 return buff;
20545}
20546
015dc7e1 20547static bool
c6a9fc58
TT
20548print_stapsdt_note (Elf_Internal_Note *pnote)
20549{
3ca60c57
NC
20550 size_t len, maxlen;
20551 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20552 char *data = pnote->descdata;
20553 char *data_end = pnote->descdata + pnote->descsz;
20554 bfd_vma pc, base_addr, semaphore;
20555 char *provider, *probe, *arg_fmt;
20556
3ca60c57
NC
20557 if (pnote->descsz < (addr_size * 3))
20558 goto stapdt_note_too_small;
20559
c6a9fc58
TT
20560 pc = byte_get ((unsigned char *) data, addr_size);
20561 data += addr_size;
3ca60c57 20562
c6a9fc58
TT
20563 base_addr = byte_get ((unsigned char *) data, addr_size);
20564 data += addr_size;
3ca60c57 20565
c6a9fc58
TT
20566 semaphore = byte_get ((unsigned char *) data, addr_size);
20567 data += addr_size;
20568
3ca60c57
NC
20569 if (data >= data_end)
20570 goto stapdt_note_too_small;
20571 maxlen = data_end - data;
20572 len = strnlen (data, maxlen);
20573 if (len < maxlen)
20574 {
20575 provider = data;
20576 data += len + 1;
20577 }
20578 else
20579 goto stapdt_note_too_small;
20580
20581 if (data >= data_end)
20582 goto stapdt_note_too_small;
20583 maxlen = data_end - data;
20584 len = strnlen (data, maxlen);
20585 if (len < maxlen)
20586 {
20587 probe = data;
20588 data += len + 1;
20589 }
20590 else
20591 goto stapdt_note_too_small;
9abca702 20592
3ca60c57
NC
20593 if (data >= data_end)
20594 goto stapdt_note_too_small;
20595 maxlen = data_end - data;
20596 len = strnlen (data, maxlen);
20597 if (len < maxlen)
20598 {
20599 arg_fmt = data;
20600 data += len + 1;
20601 }
20602 else
20603 goto stapdt_note_too_small;
c6a9fc58
TT
20604
20605 printf (_(" Provider: %s\n"), provider);
20606 printf (_(" Name: %s\n"), probe);
20607 printf (_(" Location: "));
20608 print_vma (pc, FULL_HEX);
20609 printf (_(", Base: "));
20610 print_vma (base_addr, FULL_HEX);
20611 printf (_(", Semaphore: "));
20612 print_vma (semaphore, FULL_HEX);
9cf03b7e 20613 printf ("\n");
c6a9fc58
TT
20614 printf (_(" Arguments: %s\n"), arg_fmt);
20615
20616 return data == data_end;
3ca60c57
NC
20617
20618 stapdt_note_too_small:
20619 printf (_(" <corrupt - note is too small>\n"));
20620 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20621 return false;
c6a9fc58
TT
20622}
20623
e5382207
LB
20624static bool
20625print_fdo_note (Elf_Internal_Note * pnote)
20626{
20627 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20628 {
20629 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20630 return true;
20631 }
20632 return false;
20633}
20634
00e98fc7
TG
20635static const char *
20636get_ia64_vms_note_type (unsigned e_type)
20637{
20638 static char buff[64];
20639
20640 switch (e_type)
20641 {
20642 case NT_VMS_MHD:
20643 return _("NT_VMS_MHD (module header)");
20644 case NT_VMS_LNM:
20645 return _("NT_VMS_LNM (language name)");
20646 case NT_VMS_SRC:
20647 return _("NT_VMS_SRC (source files)");
20648 case NT_VMS_TITLE:
9cf03b7e 20649 return "NT_VMS_TITLE";
00e98fc7
TG
20650 case NT_VMS_EIDC:
20651 return _("NT_VMS_EIDC (consistency check)");
20652 case NT_VMS_FPMODE:
20653 return _("NT_VMS_FPMODE (FP mode)");
20654 case NT_VMS_LINKTIME:
9cf03b7e 20655 return "NT_VMS_LINKTIME";
00e98fc7
TG
20656 case NT_VMS_IMGNAM:
20657 return _("NT_VMS_IMGNAM (image name)");
20658 case NT_VMS_IMGID:
20659 return _("NT_VMS_IMGID (image id)");
20660 case NT_VMS_LINKID:
20661 return _("NT_VMS_LINKID (link id)");
20662 case NT_VMS_IMGBID:
20663 return _("NT_VMS_IMGBID (build id)");
20664 case NT_VMS_GSTNAM:
20665 return _("NT_VMS_GSTNAM (sym table name)");
20666 case NT_VMS_ORIG_DYN:
9cf03b7e 20667 return "NT_VMS_ORIG_DYN";
00e98fc7 20668 case NT_VMS_PATCHTIME:
9cf03b7e 20669 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20670 default:
20671 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20672 return buff;
20673 }
20674}
20675
015dc7e1 20676static bool
00e98fc7
TG
20677print_ia64_vms_note (Elf_Internal_Note * pnote)
20678{
8d18bf79
NC
20679 int maxlen = pnote->descsz;
20680
20681 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20682 goto desc_size_fail;
20683
00e98fc7
TG
20684 switch (pnote->type)
20685 {
20686 case NT_VMS_MHD:
8d18bf79
NC
20687 if (maxlen <= 36)
20688 goto desc_size_fail;
20689
20690 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20691
20692 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20693 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20694 if (l + 34 < maxlen)
20695 {
20696 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20697 if (l + 35 < maxlen)
20698 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20699 else
20700 printf (_(" Module version : <missing>\n"));
20701 }
00e98fc7 20702 else
8d18bf79
NC
20703 {
20704 printf (_(" Module name : <missing>\n"));
20705 printf (_(" Module version : <missing>\n"));
20706 }
00e98fc7 20707 break;
8d18bf79 20708
00e98fc7 20709 case NT_VMS_LNM:
8d18bf79 20710 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20711 break;
8d18bf79 20712
00e98fc7
TG
20713#ifdef BFD64
20714 case NT_VMS_FPMODE:
9cf03b7e 20715 printf (_(" Floating Point mode: "));
8d18bf79
NC
20716 if (maxlen < 8)
20717 goto desc_size_fail;
20718 /* FIXME: Generate an error if descsz > 8 ? */
20719
b8281767
AM
20720 printf ("0x%016" PRIx64 "\n",
20721 (uint64_t) byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20722 break;
8d18bf79 20723
00e98fc7
TG
20724 case NT_VMS_LINKTIME:
20725 printf (_(" Link time: "));
8d18bf79
NC
20726 if (maxlen < 8)
20727 goto desc_size_fail;
20728 /* FIXME: Generate an error if descsz > 8 ? */
20729
0e3c1eeb 20730 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20731 printf ("\n");
20732 break;
8d18bf79 20733
00e98fc7
TG
20734 case NT_VMS_PATCHTIME:
20735 printf (_(" Patch time: "));
8d18bf79
NC
20736 if (maxlen < 8)
20737 goto desc_size_fail;
20738 /* FIXME: Generate an error if descsz > 8 ? */
20739
0e3c1eeb 20740 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20741 printf ("\n");
20742 break;
8d18bf79 20743
00e98fc7 20744 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20745 if (maxlen < 34)
20746 goto desc_size_fail;
20747
00e98fc7 20748 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20749 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20750 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20751 printf (_(" Last modified : "));
0e3c1eeb 20752 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20753 printf (_("\n Link flags : "));
b8281767
AM
20754 printf ("0x%016" PRIx64 "\n",
20755 (uint64_t) byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20756 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20757 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20758 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20759 break;
20760#endif
8d18bf79 20761
00e98fc7 20762 case NT_VMS_IMGNAM:
8d18bf79 20763 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20764 break;
8d18bf79 20765
00e98fc7 20766 case NT_VMS_GSTNAM:
8d18bf79 20767 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20768 break;
8d18bf79 20769
00e98fc7 20770 case NT_VMS_IMGID:
8d18bf79 20771 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20772 break;
8d18bf79 20773
00e98fc7 20774 case NT_VMS_LINKID:
8d18bf79 20775 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20776 break;
8d18bf79 20777
00e98fc7 20778 default:
015dc7e1 20779 return false;
00e98fc7 20780 }
8d18bf79 20781
015dc7e1 20782 return true;
8d18bf79
NC
20783
20784 desc_size_fail:
20785 printf (_(" <corrupt - data size is too small>\n"));
20786 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20787 return false;
00e98fc7
TG
20788}
20789
fd486f32
AM
20790struct build_attr_cache {
20791 Filedata *filedata;
20792 char *strtab;
20793 unsigned long strtablen;
20794 Elf_Internal_Sym *symtab;
20795 unsigned long nsyms;
20796} ba_cache;
20797
6f156d7a
NC
20798/* Find the symbol associated with a build attribute that is attached
20799 to address OFFSET. If PNAME is non-NULL then store the name of
20800 the symbol (if found) in the provided pointer, Returns NULL if a
20801 symbol could not be found. */
c799a79d 20802
6f156d7a 20803static Elf_Internal_Sym *
015dc7e1
AM
20804get_symbol_for_build_attribute (Filedata *filedata,
20805 unsigned long offset,
20806 bool is_open_attr,
20807 const char **pname)
9ef920e9 20808{
fd486f32
AM
20809 Elf_Internal_Sym *saved_sym = NULL;
20810 Elf_Internal_Sym *sym;
9ef920e9 20811
dda8d76d 20812 if (filedata->section_headers != NULL
fd486f32 20813 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20814 {
c799a79d 20815 Elf_Internal_Shdr * symsec;
9ef920e9 20816
fd486f32
AM
20817 free (ba_cache.strtab);
20818 ba_cache.strtab = NULL;
20819 free (ba_cache.symtab);
20820 ba_cache.symtab = NULL;
20821
c799a79d 20822 /* Load the symbol and string sections. */
dda8d76d
NC
20823 for (symsec = filedata->section_headers;
20824 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20825 symsec ++)
9ef920e9 20826 {
28d13567
AM
20827 if (symsec->sh_type == SHT_SYMTAB
20828 && get_symtab (filedata, symsec,
20829 &ba_cache.symtab, &ba_cache.nsyms,
20830 &ba_cache.strtab, &ba_cache.strtablen))
20831 break;
9ef920e9 20832 }
fd486f32 20833 ba_cache.filedata = filedata;
9ef920e9
NC
20834 }
20835
fd486f32 20836 if (ba_cache.symtab == NULL)
6f156d7a 20837 return NULL;
9ef920e9 20838
c799a79d 20839 /* Find a symbol whose value matches offset. */
fd486f32 20840 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20841 if (sym->st_value == offset)
20842 {
fd486f32 20843 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20844 /* Huh ? This should not happen. */
20845 continue;
9ef920e9 20846
fd486f32 20847 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20848 continue;
9ef920e9 20849
9b9b1092 20850 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20851 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20852 if (ba_cache.strtab[sym->st_name] == '$'
20853 && ba_cache.strtab[sym->st_name + 1] != 0
20854 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20855 continue;
20856
c799a79d
NC
20857 if (is_open_attr)
20858 {
20859 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20860 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20861 FUNC symbols entirely. */
20862 switch (ELF_ST_TYPE (sym->st_info))
20863 {
c799a79d 20864 case STT_OBJECT:
6f156d7a 20865 case STT_FILE:
c799a79d 20866 saved_sym = sym;
6f156d7a
NC
20867 if (sym->st_size)
20868 {
20869 /* If the symbol has a size associated
20870 with it then we can stop searching. */
fd486f32 20871 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20872 }
c799a79d 20873 continue;
9ef920e9 20874
c799a79d
NC
20875 case STT_FUNC:
20876 /* Ignore function symbols. */
20877 continue;
20878
20879 default:
20880 break;
20881 }
20882
20883 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20884 {
c799a79d
NC
20885 case STB_GLOBAL:
20886 if (saved_sym == NULL
20887 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20888 saved_sym = sym;
20889 break;
c871dade 20890
c799a79d
NC
20891 case STB_LOCAL:
20892 if (saved_sym == NULL)
20893 saved_sym = sym;
20894 break;
20895
20896 default:
9ef920e9
NC
20897 break;
20898 }
20899 }
c799a79d
NC
20900 else
20901 {
20902 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20903 continue;
20904
20905 saved_sym = sym;
20906 break;
20907 }
20908 }
20909
6f156d7a 20910 if (saved_sym && pname)
fd486f32 20911 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20912
20913 return saved_sym;
c799a79d
NC
20914}
20915
d20e98ab
NC
20916/* Returns true iff addr1 and addr2 are in the same section. */
20917
015dc7e1 20918static bool
d20e98ab
NC
20919same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20920{
20921 Elf_Internal_Shdr * a1;
20922 Elf_Internal_Shdr * a2;
20923
20924 a1 = find_section_by_address (filedata, addr1);
20925 a2 = find_section_by_address (filedata, addr2);
9abca702 20926
d20e98ab
NC
20927 return a1 == a2 && a1 != NULL;
20928}
20929
015dc7e1 20930static bool
dda8d76d
NC
20931print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20932 Filedata * filedata)
c799a79d 20933{
015dc7e1
AM
20934 static unsigned long global_offset = 0;
20935 static unsigned long global_end = 0;
20936 static unsigned long func_offset = 0;
20937 static unsigned long func_end = 0;
c871dade 20938
015dc7e1
AM
20939 Elf_Internal_Sym *sym;
20940 const char *name;
20941 unsigned long start;
20942 unsigned long end;
20943 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20944
20945 switch (pnote->descsz)
c799a79d 20946 {
6f156d7a
NC
20947 case 0:
20948 /* A zero-length description means that the range of
20949 the previous note of the same type should be used. */
c799a79d 20950 if (is_open_attr)
c871dade 20951 {
6f156d7a
NC
20952 if (global_end > global_offset)
20953 printf (_(" Applies to region from %#lx to %#lx\n"),
20954 global_offset, global_end);
20955 else
20956 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20957 }
20958 else
20959 {
6f156d7a
NC
20960 if (func_end > func_offset)
20961 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20962 else
20963 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20964 }
015dc7e1 20965 return true;
9ef920e9 20966
6f156d7a
NC
20967 case 4:
20968 start = byte_get ((unsigned char *) pnote->descdata, 4);
20969 end = 0;
20970 break;
20971
20972 case 8:
c74147bb
NC
20973 start = byte_get ((unsigned char *) pnote->descdata, 4);
20974 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20975 break;
20976
20977 case 16:
20978 start = byte_get ((unsigned char *) pnote->descdata, 8);
20979 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20980 break;
9abca702 20981
6f156d7a 20982 default:
c799a79d
NC
20983 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20984 printf (_(" <invalid descsz>"));
015dc7e1 20985 return false;
c799a79d
NC
20986 }
20987
6f156d7a
NC
20988 name = NULL;
20989 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20990 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20991 in order to avoid them being confused with the start address of the
20992 first function in the file... */
20993 if (sym == NULL && is_open_attr)
20994 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20995 & name);
6f156d7a
NC
20996
20997 if (end == 0 && sym != NULL && sym->st_size > 0)
20998 end = start + sym->st_size;
c799a79d
NC
20999
21000 if (is_open_attr)
21001 {
d20e98ab
NC
21002 /* FIXME: Need to properly allow for section alignment.
21003 16 is just the alignment used on x86_64. */
21004 if (global_end > 0
21005 && start > BFD_ALIGN (global_end, 16)
21006 /* Build notes are not guaranteed to be organised in order of
21007 increasing address, but we should find the all of the notes
21008 for one section in the same place. */
21009 && same_section (filedata, start, global_end))
6f156d7a
NC
21010 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21011 global_end + 1, start - 1);
21012
21013 printf (_(" Applies to region from %#lx"), start);
21014 global_offset = start;
21015
21016 if (end)
21017 {
21018 printf (_(" to %#lx"), end);
21019 global_end = end;
21020 }
c799a79d
NC
21021 }
21022 else
21023 {
6f156d7a
NC
21024 printf (_(" Applies to region from %#lx"), start);
21025 func_offset = start;
21026
21027 if (end)
21028 {
21029 printf (_(" to %#lx"), end);
21030 func_end = end;
21031 }
c799a79d
NC
21032 }
21033
6f156d7a
NC
21034 if (sym && name)
21035 printf (_(" (%s)"), name);
21036
21037 printf ("\n");
015dc7e1 21038 return true;
9ef920e9
NC
21039}
21040
015dc7e1 21041static bool
9ef920e9
NC
21042print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21043{
1d15e434
NC
21044 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21045 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21046 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21047 char name_type;
21048 char name_attribute;
1d15e434 21049 const char * expected_types;
9ef920e9
NC
21050 const char * name = pnote->namedata;
21051 const char * text;
88305e1b 21052 signed int left;
9ef920e9
NC
21053
21054 if (name == NULL || pnote->namesz < 2)
21055 {
21056 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21057 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21058 return false;
9ef920e9
NC
21059 }
21060
6f156d7a
NC
21061 if (do_wide)
21062 left = 28;
21063 else
21064 left = 20;
88305e1b
NC
21065
21066 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21067 if (name[0] == 'G' && name[1] == 'A')
21068 {
6f156d7a
NC
21069 if (pnote->namesz < 4)
21070 {
21071 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21072 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21073 return false;
6f156d7a
NC
21074 }
21075
88305e1b
NC
21076 printf ("GA");
21077 name += 2;
21078 left -= 2;
21079 }
21080
9ef920e9
NC
21081 switch ((name_type = * name))
21082 {
21083 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21084 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21085 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21086 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21087 printf ("%c", * name);
88305e1b 21088 left --;
9ef920e9
NC
21089 break;
21090 default:
21091 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21092 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21093 return false;
9ef920e9
NC
21094 }
21095
9ef920e9
NC
21096 ++ name;
21097 text = NULL;
21098
21099 switch ((name_attribute = * name))
21100 {
21101 case GNU_BUILD_ATTRIBUTE_VERSION:
21102 text = _("<version>");
1d15e434 21103 expected_types = string_expected;
9ef920e9
NC
21104 ++ name;
21105 break;
21106 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21107 text = _("<stack prot>");
75d7d298 21108 expected_types = "!+*";
9ef920e9
NC
21109 ++ name;
21110 break;
21111 case GNU_BUILD_ATTRIBUTE_RELRO:
21112 text = _("<relro>");
1d15e434 21113 expected_types = bool_expected;
9ef920e9
NC
21114 ++ name;
21115 break;
21116 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21117 text = _("<stack size>");
1d15e434 21118 expected_types = number_expected;
9ef920e9
NC
21119 ++ name;
21120 break;
21121 case GNU_BUILD_ATTRIBUTE_TOOL:
21122 text = _("<tool>");
1d15e434 21123 expected_types = string_expected;
9ef920e9
NC
21124 ++ name;
21125 break;
21126 case GNU_BUILD_ATTRIBUTE_ABI:
21127 text = _("<ABI>");
21128 expected_types = "$*";
21129 ++ name;
21130 break;
21131 case GNU_BUILD_ATTRIBUTE_PIC:
21132 text = _("<PIC>");
1d15e434 21133 expected_types = number_expected;
9ef920e9
NC
21134 ++ name;
21135 break;
a8be5506
NC
21136 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21137 text = _("<short enum>");
1d15e434 21138 expected_types = bool_expected;
a8be5506
NC
21139 ++ name;
21140 break;
9ef920e9
NC
21141 default:
21142 if (ISPRINT (* name))
21143 {
21144 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21145
21146 if (len > left && ! do_wide)
21147 len = left;
75d7d298 21148 printf ("%.*s:", len, name);
9ef920e9 21149 left -= len;
0dd6ae21 21150 name += len;
9ef920e9
NC
21151 }
21152 else
21153 {
3e6b6445 21154 static char tmpbuf [128];
88305e1b 21155
3e6b6445
NC
21156 error (_("unrecognised byte in name field: %d\n"), * name);
21157 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21158 text = tmpbuf;
21159 name ++;
9ef920e9
NC
21160 }
21161 expected_types = "*$!+";
21162 break;
21163 }
21164
21165 if (text)
88305e1b 21166 left -= printf ("%s", text);
9ef920e9
NC
21167
21168 if (strchr (expected_types, name_type) == NULL)
75d7d298 21169 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21170
21171 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21172 {
21173 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21174 (unsigned long) pnote->namesz,
21175 (long) (name - pnote->namedata));
015dc7e1 21176 return false;
9ef920e9
NC
21177 }
21178
21179 if (left < 1 && ! do_wide)
015dc7e1 21180 return true;
9ef920e9
NC
21181
21182 switch (name_type)
21183 {
21184 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21185 {
b06b2c92 21186 unsigned int bytes;
ddef72cd
NC
21187 unsigned long long val = 0;
21188 unsigned int shift = 0;
21189 char * decoded = NULL;
21190
b06b2c92
NC
21191 bytes = pnote->namesz - (name - pnote->namedata);
21192 if (bytes > 0)
21193 /* The -1 is because the name field is always 0 terminated, and we
21194 want to be able to ensure that the shift in the while loop below
21195 will not overflow. */
21196 -- bytes;
21197
ddef72cd
NC
21198 if (bytes > sizeof (val))
21199 {
3e6b6445
NC
21200 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21201 bytes);
21202 bytes = sizeof (val);
ddef72cd 21203 }
3e6b6445
NC
21204 /* We do not bother to warn if bytes == 0 as this can
21205 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21206
21207 while (bytes --)
21208 {
54b8331d 21209 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21210
21211 val |= byte << shift;
9ef920e9
NC
21212 shift += 8;
21213 }
21214
75d7d298 21215 switch (name_attribute)
9ef920e9 21216 {
75d7d298 21217 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21218 switch (val)
21219 {
75d7d298
NC
21220 case 0: decoded = "static"; break;
21221 case 1: decoded = "pic"; break;
21222 case 2: decoded = "PIC"; break;
21223 case 3: decoded = "pie"; break;
21224 case 4: decoded = "PIE"; break;
21225 default: break;
9ef920e9 21226 }
75d7d298
NC
21227 break;
21228 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21229 switch (val)
9ef920e9 21230 {
75d7d298
NC
21231 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21232 case 0: decoded = "off"; break;
21233 case 1: decoded = "on"; break;
21234 case 2: decoded = "all"; break;
21235 case 3: decoded = "strong"; break;
21236 case 4: decoded = "explicit"; break;
21237 default: break;
9ef920e9 21238 }
75d7d298
NC
21239 break;
21240 default:
21241 break;
9ef920e9
NC
21242 }
21243
75d7d298 21244 if (decoded != NULL)
3e6b6445
NC
21245 {
21246 print_symbol (-left, decoded);
21247 left = 0;
21248 }
21249 else if (val == 0)
21250 {
21251 printf ("0x0");
21252 left -= 3;
21253 }
9ef920e9 21254 else
75d7d298
NC
21255 {
21256 if (do_wide)
ddef72cd 21257 left -= printf ("0x%llx", val);
75d7d298 21258 else
ddef72cd 21259 left -= printf ("0x%-.*llx", left, val);
75d7d298 21260 }
9ef920e9
NC
21261 }
21262 break;
21263 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21264 left -= print_symbol (- left, name);
21265 break;
21266 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21267 left -= print_symbol (- left, "true");
21268 break;
21269 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21270 left -= print_symbol (- left, "false");
21271 break;
21272 }
21273
21274 if (do_wide && left > 0)
21275 printf ("%-*s", left, " ");
9abca702 21276
015dc7e1 21277 return true;
9ef920e9
NC
21278}
21279
2952f10c
SM
21280/* Print the contents of PNOTE as hex. */
21281
21282static void
21283print_note_contents_hex (Elf_Internal_Note *pnote)
21284{
21285 if (pnote->descsz)
21286 {
21287 unsigned long i;
21288
21289 printf (_(" description data: "));
21290 for (i = 0; i < pnote->descsz; i++)
21291 printf ("%02x ", pnote->descdata[i] & 0xff);
21292 if (!do_wide)
21293 printf ("\n");
21294 }
21295
21296 if (do_wide)
21297 printf ("\n");
21298}
21299
21300#if defined HAVE_MSGPACK
21301
21302static void
21303print_indents (int n)
21304{
21305 printf (" ");
21306
21307 for (int i = 0; i < n; i++)
21308 printf (" ");
21309}
21310
21311/* Print OBJ in human-readable form. */
21312
21313static void
21314dump_msgpack_obj (const msgpack_object *obj, int indent)
21315{
21316 switch (obj->type)
21317 {
21318 case MSGPACK_OBJECT_NIL:
21319 printf ("(nil)");
21320 break;
21321
21322 case MSGPACK_OBJECT_BOOLEAN:
21323 printf ("%s", obj->via.boolean ? "true" : "false");
21324 break;
21325
21326 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21327 printf ("%" PRIu64, obj->via.u64);
21328 break;
21329
21330 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21331 printf ("%" PRIi64, obj->via.i64);
21332 break;
21333
21334 case MSGPACK_OBJECT_FLOAT32:
21335 case MSGPACK_OBJECT_FLOAT64:
21336 printf ("%f", obj->via.f64);
21337 break;
21338
21339 case MSGPACK_OBJECT_STR:
21340 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21341 break;
21342
21343 case MSGPACK_OBJECT_ARRAY:
21344 {
21345 const msgpack_object_array *array = &obj->via.array;
21346
21347 printf ("[\n");
21348 ++indent;
21349
21350 for (uint32_t i = 0; i < array->size; ++i)
21351 {
21352 const msgpack_object *item = &array->ptr[i];
21353
21354 print_indents (indent);
21355 dump_msgpack_obj (item, indent);
21356 printf (",\n");
21357 }
21358
21359 --indent;
21360 print_indents (indent);
21361 printf ("]");
21362 break;
21363 }
21364 break;
21365
21366 case MSGPACK_OBJECT_MAP:
21367 {
21368 const msgpack_object_map *map = &obj->via.map;
21369
21370 printf ("{\n");
21371 ++indent;
21372
21373 for (uint32_t i = 0; i < map->size; ++i)
21374 {
21375 const msgpack_object_kv *kv = &map->ptr[i];
21376 const msgpack_object *key = &kv->key;
21377 const msgpack_object *val = &kv->val;
21378
21379 print_indents (indent);
21380 dump_msgpack_obj (key, indent);
21381 printf (": ");
21382 dump_msgpack_obj (val, indent);
21383
21384 printf (",\n");
21385 }
21386
21387 --indent;
21388 print_indents (indent);
21389 printf ("}");
21390
21391 break;
21392 }
21393
21394 case MSGPACK_OBJECT_BIN:
21395 printf ("(bin)");
21396 break;
21397
21398 case MSGPACK_OBJECT_EXT:
21399 printf ("(ext)");
21400 break;
21401 }
21402}
21403
21404static void
21405dump_msgpack (const msgpack_unpacked *msg)
21406{
21407 print_indents (0);
21408 dump_msgpack_obj (&msg->data, 0);
21409 printf ("\n");
21410}
21411
21412#endif /* defined HAVE_MSGPACK */
21413
21414static bool
21415print_amdgpu_note (Elf_Internal_Note *pnote)
21416{
21417#if defined HAVE_MSGPACK
21418 /* If msgpack is available, decode and dump the note's content. */
21419 bool ret;
21420 msgpack_unpacked msg;
21421 msgpack_unpack_return msgpack_ret;
21422
21423 assert (pnote->type == NT_AMDGPU_METADATA);
21424
21425 msgpack_unpacked_init (&msg);
21426 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21427 NULL);
21428
21429 switch (msgpack_ret)
21430 {
21431 case MSGPACK_UNPACK_SUCCESS:
21432 dump_msgpack (&msg);
21433 ret = true;
21434 break;
21435
21436 default:
21437 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21438 ret = false;
21439 break;
21440 }
21441
21442 msgpack_unpacked_destroy (&msg);
21443 return ret;
21444#else
21445 /* msgpack is not available, dump contents as hex. */
21446 print_note_contents_hex (pnote);
21447 return true;
21448#endif
21449}
21450
6d118b09
NC
21451/* Note that by the ELF standard, the name field is already null byte
21452 terminated, and namesz includes the terminating null byte.
21453 I.E. the value of namesz for the name "FSF" is 4.
21454
e3c8793a 21455 If the value of namesz is zero, there is no name present. */
9ef920e9 21456
015dc7e1 21457static bool
9ef920e9 21458process_note (Elf_Internal_Note * pnote,
dda8d76d 21459 Filedata * filedata)
779fe533 21460{
2cf0635d
NC
21461 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21462 const char * nt;
9437c45b
JT
21463
21464 if (pnote->namesz == 0)
1ec5cd37
NC
21465 /* If there is no note name, then use the default set of
21466 note type strings. */
dda8d76d 21467 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21468
24d127aa 21469 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21470 /* GNU-specific object file notes. */
21471 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21472
28cdbb18
SM
21473 else if (startswith (pnote->namedata, "AMDGPU"))
21474 /* AMDGPU-specific object file notes. */
21475 nt = get_amdgpu_elf_note_type (pnote->type);
21476
24d127aa 21477 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21478 /* FreeBSD-specific core file notes. */
dda8d76d 21479 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21480
24d127aa 21481 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21482 /* NetBSD-specific core file notes. */
dda8d76d 21483 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21484
24d127aa 21485 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21486 /* NetBSD-specific core file notes. */
21487 return process_netbsd_elf_note (pnote);
21488
24d127aa 21489 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21490 /* NetBSD-specific core file notes. */
21491 return process_netbsd_elf_note (pnote);
21492
98ca73af
FC
21493 else if (startswith (pnote->namedata, "OpenBSD"))
21494 /* OpenBSD-specific core file notes. */
21495 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21496
e9b095a5 21497 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21498 {
21499 /* SPU-specific core file notes. */
21500 nt = pnote->namedata + 4;
21501 name = "SPU";
21502 }
21503
24d127aa 21504 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21505 /* VMS/ia64-specific file notes. */
21506 nt = get_ia64_vms_note_type (pnote->type);
21507
24d127aa 21508 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21509 nt = get_stapsdt_note_type (pnote->type);
21510
9437c45b 21511 else
1ec5cd37
NC
21512 /* Don't recognize this note name; just use the default set of
21513 note type strings. */
dda8d76d 21514 nt = get_note_type (filedata, pnote->type);
9437c45b 21515
1449284b 21516 printf (" ");
9ef920e9 21517
24d127aa 21518 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21519 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21520 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21521 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21522 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21523 print_gnu_build_attribute_name (pnote);
21524 else
21525 print_symbol (-20, name);
21526
21527 if (do_wide)
21528 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21529 else
21530 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21531
24d127aa 21532 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21533 return print_ia64_vms_note (pnote);
24d127aa 21534 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21535 return print_gnu_note (filedata, pnote);
24d127aa 21536 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21537 return print_stapsdt_note (pnote);
24d127aa 21538 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21539 return print_core_note (pnote);
e5382207
LB
21540 else if (startswith (pnote->namedata, "FDO"))
21541 return print_fdo_note (pnote);
24d127aa 21542 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21543 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21544 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21545 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21546 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21547 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21548 else if (startswith (pnote->namedata, "AMDGPU")
21549 && pnote->type == NT_AMDGPU_METADATA)
21550 return print_amdgpu_note (pnote);
779fe533 21551
2952f10c 21552 print_note_contents_hex (pnote);
015dc7e1 21553 return true;
1449284b 21554}
6d118b09 21555
015dc7e1 21556static bool
dda8d76d
NC
21557process_notes_at (Filedata * filedata,
21558 Elf_Internal_Shdr * section,
21559 bfd_vma offset,
82ed9683
L
21560 bfd_vma length,
21561 bfd_vma align)
779fe533 21562{
015dc7e1
AM
21563 Elf_External_Note *pnotes;
21564 Elf_External_Note *external;
21565 char *end;
21566 bool res = true;
103f02d3 21567
779fe533 21568 if (length <= 0)
015dc7e1 21569 return false;
103f02d3 21570
1449284b
NC
21571 if (section)
21572 {
dda8d76d 21573 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21574 if (pnotes)
32ec8896 21575 {
dda8d76d 21576 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21577 {
21578 free (pnotes);
015dc7e1 21579 return false;
f761cb13 21580 }
32ec8896 21581 }
1449284b
NC
21582 }
21583 else
82ed9683 21584 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21585 _("notes"));
4dff97b2 21586
dd24e3da 21587 if (pnotes == NULL)
015dc7e1 21588 return false;
779fe533 21589
103f02d3 21590 external = pnotes;
103f02d3 21591
ca0e11aa
NC
21592 if (filedata->is_separate)
21593 printf (_("In linked file '%s': "), filedata->file_name);
21594 else
21595 printf ("\n");
1449284b 21596 if (section)
ca0e11aa 21597 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21598 else
ca0e11aa 21599 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21600 (unsigned long) offset, (unsigned long) length);
21601
82ed9683
L
21602 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21603 specifies that notes should be aligned to 4 bytes in 32-bit
21604 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21605 we also support 4 byte alignment in 64-bit objects. If section
21606 alignment is less than 4, we treate alignment as 4 bytes. */
21607 if (align < 4)
21608 align = 4;
21609 else if (align != 4 && align != 8)
21610 {
21611 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21612 (long) align);
a788aedd 21613 free (pnotes);
015dc7e1 21614 return false;
82ed9683
L
21615 }
21616
dbe15e4e 21617 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21618
c8071705
NC
21619 end = (char *) pnotes + length;
21620 while ((char *) external < end)
779fe533 21621 {
b34976b6 21622 Elf_Internal_Note inote;
15b42fb0 21623 size_t min_notesz;
4dff97b2 21624 char * next;
2cf0635d 21625 char * temp = NULL;
c8071705 21626 size_t data_remaining = end - (char *) external;
6d118b09 21627
dda8d76d 21628 if (!is_ia64_vms (filedata))
15b42fb0 21629 {
9dd3a467
NC
21630 /* PR binutils/15191
21631 Make sure that there is enough data to read. */
15b42fb0
AM
21632 min_notesz = offsetof (Elf_External_Note, name);
21633 if (data_remaining < min_notesz)
9dd3a467 21634 {
d3a49aa8
AM
21635 warn (ngettext ("Corrupt note: only %ld byte remains, "
21636 "not enough for a full note\n",
21637 "Corrupt note: only %ld bytes remain, "
21638 "not enough for a full note\n",
21639 data_remaining),
21640 (long) data_remaining);
9dd3a467
NC
21641 break;
21642 }
5396a86e
AM
21643 data_remaining -= min_notesz;
21644
15b42fb0
AM
21645 inote.type = BYTE_GET (external->type);
21646 inote.namesz = BYTE_GET (external->namesz);
21647 inote.namedata = external->name;
21648 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21649 inote.descdata = ((char *) external
4dff97b2 21650 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21651 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21652 next = ((char *) external
4dff97b2 21653 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21654 }
00e98fc7 21655 else
15b42fb0
AM
21656 {
21657 Elf64_External_VMS_Note *vms_external;
00e98fc7 21658
9dd3a467
NC
21659 /* PR binutils/15191
21660 Make sure that there is enough data to read. */
15b42fb0
AM
21661 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21662 if (data_remaining < min_notesz)
9dd3a467 21663 {
d3a49aa8
AM
21664 warn (ngettext ("Corrupt note: only %ld byte remains, "
21665 "not enough for a full note\n",
21666 "Corrupt note: only %ld bytes remain, "
21667 "not enough for a full note\n",
21668 data_remaining),
21669 (long) data_remaining);
9dd3a467
NC
21670 break;
21671 }
5396a86e 21672 data_remaining -= min_notesz;
3e55a963 21673
15b42fb0
AM
21674 vms_external = (Elf64_External_VMS_Note *) external;
21675 inote.type = BYTE_GET (vms_external->type);
21676 inote.namesz = BYTE_GET (vms_external->namesz);
21677 inote.namedata = vms_external->name;
21678 inote.descsz = BYTE_GET (vms_external->descsz);
21679 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21680 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21681 next = inote.descdata + align_power (inote.descsz, 3);
21682 }
21683
5396a86e
AM
21684 /* PR 17531: file: 3443835e. */
21685 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21686 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21687 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21688 || (size_t) (next - inote.descdata) < inote.descsz
21689 || ((size_t) (next - inote.descdata)
21690 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21691 {
15b42fb0 21692 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21693 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21694 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21695 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21696 break;
21697 }
21698
15b42fb0 21699 external = (Elf_External_Note *) next;
dd24e3da 21700
6d118b09
NC
21701 /* Verify that name is null terminated. It appears that at least
21702 one version of Linux (RedHat 6.0) generates corefiles that don't
21703 comply with the ELF spec by failing to include the null byte in
21704 namesz. */
18344509 21705 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21706 {
5396a86e 21707 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21708 {
5396a86e
AM
21709 temp = (char *) malloc (inote.namesz + 1);
21710 if (temp == NULL)
21711 {
21712 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21713 res = false;
5396a86e
AM
21714 break;
21715 }
76da6bbe 21716
5396a86e
AM
21717 memcpy (temp, inote.namedata, inote.namesz);
21718 inote.namedata = temp;
21719 }
21720 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21721 }
21722
dda8d76d 21723 if (! process_note (& inote, filedata))
015dc7e1 21724 res = false;
103f02d3 21725
9db70fc3
AM
21726 free (temp);
21727 temp = NULL;
779fe533
NC
21728 }
21729
21730 free (pnotes);
103f02d3 21731
779fe533
NC
21732 return res;
21733}
21734
015dc7e1 21735static bool
dda8d76d 21736process_corefile_note_segments (Filedata * filedata)
779fe533 21737{
015dc7e1 21738 Elf_Internal_Phdr *segment;
b34976b6 21739 unsigned int i;
015dc7e1 21740 bool res = true;
103f02d3 21741
dda8d76d 21742 if (! get_program_headers (filedata))
015dc7e1 21743 return true;
103f02d3 21744
dda8d76d
NC
21745 for (i = 0, segment = filedata->program_headers;
21746 i < filedata->file_header.e_phnum;
b34976b6 21747 i++, segment++)
779fe533
NC
21748 {
21749 if (segment->p_type == PT_NOTE)
dda8d76d 21750 if (! process_notes_at (filedata, NULL,
32ec8896 21751 (bfd_vma) segment->p_offset,
82ed9683
L
21752 (bfd_vma) segment->p_filesz,
21753 (bfd_vma) segment->p_align))
015dc7e1 21754 res = false;
779fe533 21755 }
103f02d3 21756
779fe533
NC
21757 return res;
21758}
21759
015dc7e1 21760static bool
dda8d76d 21761process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21762{
21763 Elf_External_Note * pnotes;
21764 Elf_External_Note * external;
c8071705 21765 char * end;
015dc7e1 21766 bool res = true;
685080f2
NC
21767
21768 if (length <= 0)
015dc7e1 21769 return false;
685080f2 21770
dda8d76d 21771 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21772 _("v850 notes"));
21773 if (pnotes == NULL)
015dc7e1 21774 return false;
685080f2
NC
21775
21776 external = pnotes;
c8071705 21777 end = (char*) pnotes + length;
685080f2
NC
21778
21779 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21780 (unsigned long) offset, (unsigned long) length);
21781
c8071705 21782 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21783 {
21784 Elf_External_Note * next;
21785 Elf_Internal_Note inote;
21786
21787 inote.type = BYTE_GET (external->type);
21788 inote.namesz = BYTE_GET (external->namesz);
21789 inote.namedata = external->name;
21790 inote.descsz = BYTE_GET (external->descsz);
21791 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21792 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21793
c8071705
NC
21794 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21795 {
21796 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21797 inote.descdata = inote.namedata;
21798 inote.namesz = 0;
21799 }
21800
685080f2
NC
21801 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21802
c8071705 21803 if ( ((char *) next > end)
685080f2
NC
21804 || ((char *) next < (char *) pnotes))
21805 {
21806 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21807 (unsigned long) ((char *) external - (char *) pnotes));
21808 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21809 inote.type, inote.namesz, inote.descsz);
21810 break;
21811 }
21812
21813 external = next;
21814
21815 /* Prevent out-of-bounds indexing. */
c8071705 21816 if ( inote.namedata + inote.namesz > end
685080f2
NC
21817 || inote.namedata + inote.namesz < inote.namedata)
21818 {
21819 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21820 (unsigned long) ((char *) external - (char *) pnotes));
21821 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21822 inote.type, inote.namesz, inote.descsz);
21823 break;
21824 }
21825
21826 printf (" %s: ", get_v850_elf_note_type (inote.type));
21827
21828 if (! print_v850_note (& inote))
21829 {
015dc7e1 21830 res = false;
685080f2
NC
21831 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21832 inote.namesz, inote.descsz);
21833 }
21834 }
21835
21836 free (pnotes);
21837
21838 return res;
21839}
21840
015dc7e1 21841static bool
dda8d76d 21842process_note_sections (Filedata * filedata)
1ec5cd37 21843{
015dc7e1 21844 Elf_Internal_Shdr *section;
1ec5cd37 21845 unsigned long i;
32ec8896 21846 unsigned int n = 0;
015dc7e1 21847 bool res = true;
1ec5cd37 21848
dda8d76d
NC
21849 for (i = 0, section = filedata->section_headers;
21850 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21851 i++, section++)
685080f2
NC
21852 {
21853 if (section->sh_type == SHT_NOTE)
21854 {
dda8d76d 21855 if (! process_notes_at (filedata, section,
32ec8896 21856 (bfd_vma) section->sh_offset,
82ed9683
L
21857 (bfd_vma) section->sh_size,
21858 (bfd_vma) section->sh_addralign))
015dc7e1 21859 res = false;
685080f2
NC
21860 n++;
21861 }
21862
dda8d76d
NC
21863 if (( filedata->file_header.e_machine == EM_V800
21864 || filedata->file_header.e_machine == EM_V850
21865 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21866 && section->sh_type == SHT_RENESAS_INFO)
21867 {
dda8d76d 21868 if (! process_v850_notes (filedata,
32ec8896
NC
21869 (bfd_vma) section->sh_offset,
21870 (bfd_vma) section->sh_size))
015dc7e1 21871 res = false;
685080f2
NC
21872 n++;
21873 }
21874 }
df565f32
NC
21875
21876 if (n == 0)
21877 /* Try processing NOTE segments instead. */
dda8d76d 21878 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21879
21880 return res;
21881}
21882
015dc7e1 21883static bool
dda8d76d 21884process_notes (Filedata * filedata)
779fe533
NC
21885{
21886 /* If we have not been asked to display the notes then do nothing. */
21887 if (! do_notes)
015dc7e1 21888 return true;
103f02d3 21889
dda8d76d
NC
21890 if (filedata->file_header.e_type != ET_CORE)
21891 return process_note_sections (filedata);
103f02d3 21892
779fe533 21893 /* No program headers means no NOTE segment. */
dda8d76d
NC
21894 if (filedata->file_header.e_phnum > 0)
21895 return process_corefile_note_segments (filedata);
779fe533 21896
ca0e11aa
NC
21897 if (filedata->is_separate)
21898 printf (_("No notes found in linked file '%s'.\n"),
21899 filedata->file_name);
21900 else
21901 printf (_("No notes found file.\n"));
21902
015dc7e1 21903 return true;
779fe533
NC
21904}
21905
60abdbed
NC
21906static unsigned char *
21907display_public_gnu_attributes (unsigned char * start,
21908 const unsigned char * const end)
21909{
21910 printf (_(" Unknown GNU attribute: %s\n"), start);
21911
21912 start += strnlen ((char *) start, end - start);
21913 display_raw_attribute (start, end);
21914
21915 return (unsigned char *) end;
21916}
21917
21918static unsigned char *
21919display_generic_attribute (unsigned char * start,
21920 unsigned int tag,
21921 const unsigned char * const end)
21922{
21923 if (tag == 0)
21924 return (unsigned char *) end;
21925
21926 return display_tag_value (tag, start, end);
21927}
21928
015dc7e1 21929static bool
dda8d76d 21930process_arch_specific (Filedata * filedata)
252b5132 21931{
a952a375 21932 if (! do_arch)
015dc7e1 21933 return true;
a952a375 21934
dda8d76d 21935 switch (filedata->file_header.e_machine)
252b5132 21936 {
53a346d8
CZ
21937 case EM_ARC:
21938 case EM_ARC_COMPACT:
21939 case EM_ARC_COMPACT2:
dda8d76d 21940 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21941 display_arc_attribute,
21942 display_generic_attribute);
11c1ff18 21943 case EM_ARM:
dda8d76d 21944 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21945 display_arm_attribute,
21946 display_generic_attribute);
21947
252b5132 21948 case EM_MIPS:
4fe85591 21949 case EM_MIPS_RS3_LE:
dda8d76d 21950 return process_mips_specific (filedata);
60abdbed
NC
21951
21952 case EM_MSP430:
dda8d76d 21953 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21954 display_msp430_attribute,
c0ea7c52 21955 display_msp430_gnu_attribute);
60abdbed 21956
2dc8dd17
JW
21957 case EM_RISCV:
21958 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21959 display_riscv_attribute,
21960 display_generic_attribute);
21961
35c08157 21962 case EM_NDS32:
dda8d76d 21963 return process_nds32_specific (filedata);
60abdbed 21964
85f7484a
PB
21965 case EM_68K:
21966 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21967 display_m68k_gnu_attribute);
21968
34c8bcba 21969 case EM_PPC:
b82317dd 21970 case EM_PPC64:
dda8d76d 21971 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21972 display_power_gnu_attribute);
21973
643f7afb
AK
21974 case EM_S390:
21975 case EM_S390_OLD:
dda8d76d 21976 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21977 display_s390_gnu_attribute);
21978
9e8c70f9
DM
21979 case EM_SPARC:
21980 case EM_SPARC32PLUS:
21981 case EM_SPARCV9:
dda8d76d 21982 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21983 display_sparc_gnu_attribute);
21984
59e6276b 21985 case EM_TI_C6000:
dda8d76d 21986 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21987 display_tic6x_attribute,
21988 display_generic_attribute);
21989
0861f561
CQ
21990 case EM_CSKY:
21991 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21992 display_csky_attribute, NULL);
21993
252b5132 21994 default:
dda8d76d 21995 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21996 display_public_gnu_attributes,
21997 display_generic_attribute);
252b5132 21998 }
252b5132
RH
21999}
22000
015dc7e1 22001static bool
dda8d76d 22002get_file_header (Filedata * filedata)
252b5132 22003{
9ea033b2 22004 /* Read in the identity array. */
dda8d76d 22005 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22006 return false;
252b5132 22007
9ea033b2 22008 /* Determine how to read the rest of the header. */
dda8d76d 22009 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22010 {
1a0670f3
AM
22011 default:
22012 case ELFDATANONE:
adab8cdc
AO
22013 case ELFDATA2LSB:
22014 byte_get = byte_get_little_endian;
22015 byte_put = byte_put_little_endian;
22016 break;
22017 case ELFDATA2MSB:
22018 byte_get = byte_get_big_endian;
22019 byte_put = byte_put_big_endian;
22020 break;
9ea033b2
NC
22021 }
22022
22023 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22024 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22025
22026 /* Read in the rest of the header. */
22027 if (is_32bit_elf)
22028 {
22029 Elf32_External_Ehdr ehdr32;
252b5132 22030
dda8d76d 22031 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22032 return false;
103f02d3 22033
dda8d76d
NC
22034 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22035 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22036 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22037 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22038 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22039 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22040 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22041 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22042 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22043 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22044 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22045 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22046 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22047 }
252b5132 22048 else
9ea033b2
NC
22049 {
22050 Elf64_External_Ehdr ehdr64;
a952a375
NC
22051
22052 /* If we have been compiled with sizeof (bfd_vma) == 4, then
22053 we will not be able to cope with the 64bit data found in
22054 64 ELF files. Detect this now and abort before we start
50c2245b 22055 overwriting things. */
a952a375
NC
22056 if (sizeof (bfd_vma) < 8)
22057 {
e3c8793a
NC
22058 error (_("This instance of readelf has been built without support for a\n\
2205964 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 22060 return false;
a952a375 22061 }
103f02d3 22062
dda8d76d 22063 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22064 return false;
103f02d3 22065
dda8d76d
NC
22066 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22067 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22068 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22069 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22070 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22071 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22072 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22073 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22074 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22075 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22076 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22077 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22078 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22079 }
252b5132 22080
015dc7e1 22081 return true;
252b5132
RH
22082}
22083
13acb58d
AM
22084static void
22085free_filedata (Filedata *filedata)
22086{
22087 free (filedata->program_interpreter);
13acb58d 22088 free (filedata->program_headers);
13acb58d 22089 free (filedata->section_headers);
13acb58d 22090 free (filedata->string_table);
13acb58d 22091 free (filedata->dump.dump_sects);
13acb58d 22092 free (filedata->dynamic_strings);
13acb58d 22093 free (filedata->dynamic_symbols);
13acb58d 22094 free (filedata->dynamic_syminfo);
13acb58d 22095 free (filedata->dynamic_section);
13acb58d
AM
22096
22097 while (filedata->symtab_shndx_list != NULL)
22098 {
22099 elf_section_list *next = filedata->symtab_shndx_list->next;
22100 free (filedata->symtab_shndx_list);
22101 filedata->symtab_shndx_list = next;
22102 }
22103
22104 free (filedata->section_headers_groups);
13acb58d
AM
22105
22106 if (filedata->section_groups)
22107 {
22108 size_t i;
22109 struct group_list * g;
22110 struct group_list * next;
22111
22112 for (i = 0; i < filedata->group_count; i++)
22113 {
22114 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22115 {
22116 next = g->next;
22117 free (g);
22118 }
22119 }
22120
22121 free (filedata->section_groups);
13acb58d 22122 }
066f8fbe
AM
22123 memset (&filedata->section_headers, 0,
22124 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22125}
22126
dda8d76d
NC
22127static void
22128close_file (Filedata * filedata)
22129{
22130 if (filedata)
22131 {
22132 if (filedata->handle)
22133 fclose (filedata->handle);
22134 free (filedata);
22135 }
22136}
22137
22138void
22139close_debug_file (void * data)
22140{
13acb58d 22141 free_filedata ((Filedata *) data);
dda8d76d
NC
22142 close_file ((Filedata *) data);
22143}
22144
22145static Filedata *
015dc7e1 22146open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22147{
22148 struct stat statbuf;
22149 Filedata * filedata = NULL;
22150
22151 if (stat (pathname, & statbuf) < 0
22152 || ! S_ISREG (statbuf.st_mode))
22153 goto fail;
22154
22155 filedata = calloc (1, sizeof * filedata);
22156 if (filedata == NULL)
22157 goto fail;
22158
22159 filedata->handle = fopen (pathname, "rb");
22160 if (filedata->handle == NULL)
22161 goto fail;
22162
be7d229a 22163 filedata->file_size = statbuf.st_size;
dda8d76d 22164 filedata->file_name = pathname;
ca0e11aa 22165 filedata->is_separate = is_separate;
dda8d76d
NC
22166
22167 if (! get_file_header (filedata))
22168 goto fail;
22169
4de91c10
AM
22170 if (!get_section_headers (filedata, false))
22171 goto fail;
dda8d76d
NC
22172
22173 return filedata;
22174
22175 fail:
22176 if (filedata)
22177 {
22178 if (filedata->handle)
22179 fclose (filedata->handle);
22180 free (filedata);
22181 }
22182 return NULL;
22183}
22184
22185void *
22186open_debug_file (const char * pathname)
22187{
015dc7e1 22188 return open_file (pathname, true);
dda8d76d
NC
22189}
22190
835f2fae
NC
22191static void
22192initialise_dump_sects (Filedata * filedata)
22193{
22194 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22195 Note we do this even if cmdline_dump_sects is empty because we
22196 must make sure that the dump_sets array is zeroed out before each
22197 object file is processed. */
22198 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22199 memset (filedata->dump.dump_sects, 0,
22200 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22201
22202 if (cmdline.num_dump_sects > 0)
22203 {
22204 if (filedata->dump.num_dump_sects == 0)
22205 /* A sneaky way of allocating the dump_sects array. */
22206 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22207
22208 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22209 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22210 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22211 }
22212}
22213
94585d6d
NC
22214static bool
22215might_need_separate_debug_info (Filedata * filedata)
22216{
22217 /* Debuginfo files do not need further separate file loading. */
22218 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22219 return false;
22220
22221 /* Since do_follow_links might be enabled by default, only treat it as an
22222 indication that separate files should be loaded if setting it was a
22223 deliberate user action. */
22224 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22225 return true;
22226
22227 if (process_links || do_syms || do_unwind
22228 || dump_any_debugging || do_dump || do_debugging)
22229 return true;
22230
22231 return false;
22232}
22233
fb52b2f4
NC
22234/* Process one ELF object file according to the command line options.
22235 This file may actually be stored in an archive. The file is
32ec8896
NC
22236 positioned at the start of the ELF object. Returns TRUE if no
22237 problems were encountered, FALSE otherwise. */
fb52b2f4 22238
015dc7e1 22239static bool
dda8d76d 22240process_object (Filedata * filedata)
252b5132 22241{
015dc7e1 22242 bool have_separate_files;
252b5132 22243 unsigned int i;
015dc7e1 22244 bool res;
252b5132 22245
dda8d76d 22246 if (! get_file_header (filedata))
252b5132 22247 {
dda8d76d 22248 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22249 return false;
252b5132
RH
22250 }
22251
22252 /* Initialise per file variables. */
978c4450
AM
22253 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22254 filedata->version_info[i] = 0;
252b5132 22255
978c4450
AM
22256 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22257 filedata->dynamic_info[i] = 0;
22258 filedata->dynamic_info_DT_GNU_HASH = 0;
22259 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22260
22261 /* Process the file. */
22262 if (show_name)
dda8d76d 22263 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22264
835f2fae 22265 initialise_dump_sects (filedata);
d70c5fc7 22266
4de91c10
AM
22267 /* There may be some extensions in the first section header. Don't
22268 bomb if we can't read it. */
22269 get_section_headers (filedata, true);
22270
dda8d76d 22271 if (! process_file_header (filedata))
4de91c10
AM
22272 {
22273 res = false;
22274 goto out;
22275 }
252b5132 22276
e331b18d
AM
22277 /* Throw away the single section header read above, so that we
22278 re-read the entire set. */
22279 free (filedata->section_headers);
22280 filedata->section_headers = NULL;
22281
dda8d76d 22282 if (! process_section_headers (filedata))
2f62977e 22283 {
32ec8896 22284 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22285 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22286
2f62977e 22287 if (! do_using_dynamic)
015dc7e1 22288 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22289 }
252b5132 22290
dda8d76d 22291 if (! process_section_groups (filedata))
32ec8896 22292 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22293 do_unwind = false;
d1f5c6e3 22294
93df3340
AM
22295 process_program_headers (filedata);
22296
22297 res = process_dynamic_section (filedata);
252b5132 22298
dda8d76d 22299 if (! process_relocs (filedata))
015dc7e1 22300 res = false;
252b5132 22301
dda8d76d 22302 if (! process_unwind (filedata))
015dc7e1 22303 res = false;
4d6ed7c8 22304
dda8d76d 22305 if (! process_symbol_table (filedata))
015dc7e1 22306 res = false;
252b5132 22307
0f03783c 22308 if (! process_lto_symbol_tables (filedata))
015dc7e1 22309 res = false;
b9e920ec 22310
dda8d76d 22311 if (! process_syminfo (filedata))
015dc7e1 22312 res = false;
252b5132 22313
dda8d76d 22314 if (! process_version_sections (filedata))
015dc7e1 22315 res = false;
252b5132 22316
94585d6d 22317 if (might_need_separate_debug_info (filedata))
24841daa 22318 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22319 else
015dc7e1 22320 have_separate_files = false;
dda8d76d
NC
22321
22322 if (! process_section_contents (filedata))
015dc7e1 22323 res = false;
f5842774 22324
24841daa 22325 if (have_separate_files)
dda8d76d 22326 {
24841daa
NC
22327 separate_info * d;
22328
22329 for (d = first_separate_info; d != NULL; d = d->next)
22330 {
835f2fae
NC
22331 initialise_dump_sects (d->handle);
22332
ca0e11aa 22333 if (process_links && ! process_file_header (d->handle))
015dc7e1 22334 res = false;
ca0e11aa 22335 else if (! process_section_headers (d->handle))
015dc7e1 22336 res = false;
d6bfbc39 22337 else if (! process_section_contents (d->handle))
015dc7e1 22338 res = false;
ca0e11aa
NC
22339 else if (process_links)
22340 {
ca0e11aa 22341 if (! process_section_groups (d->handle))
015dc7e1 22342 res = false;
93df3340 22343 process_program_headers (d->handle);
ca0e11aa 22344 if (! process_dynamic_section (d->handle))
015dc7e1 22345 res = false;
ca0e11aa 22346 if (! process_relocs (d->handle))
015dc7e1 22347 res = false;
ca0e11aa 22348 if (! process_unwind (d->handle))
015dc7e1 22349 res = false;
ca0e11aa 22350 if (! process_symbol_table (d->handle))
015dc7e1 22351 res = false;
ca0e11aa 22352 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22353 res = false;
ca0e11aa 22354 if (! process_syminfo (d->handle))
015dc7e1 22355 res = false;
ca0e11aa 22356 if (! process_version_sections (d->handle))
015dc7e1 22357 res = false;
ca0e11aa 22358 if (! process_notes (d->handle))
015dc7e1 22359 res = false;
ca0e11aa 22360 }
24841daa
NC
22361 }
22362
22363 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22364 }
22365
22366 if (! process_notes (filedata))
015dc7e1 22367 res = false;
103f02d3 22368
dda8d76d 22369 if (! process_gnu_liblist (filedata))
015dc7e1 22370 res = false;
047b2264 22371
dda8d76d 22372 if (! process_arch_specific (filedata))
015dc7e1 22373 res = false;
252b5132 22374
4de91c10 22375 out:
13acb58d 22376 free_filedata (filedata);
e4b17d5c 22377
19e6b90e 22378 free_debug_memory ();
18bd398b 22379
32ec8896 22380 return res;
252b5132
RH
22381}
22382
2cf0635d 22383/* Process an ELF archive.
32ec8896
NC
22384 On entry the file is positioned just after the ARMAG string.
22385 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22386
015dc7e1
AM
22387static bool
22388process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22389{
22390 struct archive_info arch;
22391 struct archive_info nested_arch;
22392 size_t got;
015dc7e1 22393 bool ret = true;
2cf0635d 22394
015dc7e1 22395 show_name = true;
2cf0635d
NC
22396
22397 /* The ARCH structure is used to hold information about this archive. */
22398 arch.file_name = NULL;
22399 arch.file = NULL;
22400 arch.index_array = NULL;
22401 arch.sym_table = NULL;
22402 arch.longnames = NULL;
22403
22404 /* The NESTED_ARCH structure is used as a single-item cache of information
22405 about a nested archive (when members of a thin archive reside within
22406 another regular archive file). */
22407 nested_arch.file_name = NULL;
22408 nested_arch.file = NULL;
22409 nested_arch.index_array = NULL;
22410 nested_arch.sym_table = NULL;
22411 nested_arch.longnames = NULL;
22412
dda8d76d 22413 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22414 filedata->file_size, is_thin_archive,
22415 do_archive_index) != 0)
2cf0635d 22416 {
015dc7e1 22417 ret = false;
2cf0635d 22418 goto out;
4145f1d5 22419 }
fb52b2f4 22420
4145f1d5
NC
22421 if (do_archive_index)
22422 {
2cf0635d 22423 if (arch.sym_table == NULL)
1cb7d8b1
AM
22424 error (_("%s: unable to dump the index as none was found\n"),
22425 filedata->file_name);
4145f1d5
NC
22426 else
22427 {
591f7597 22428 unsigned long i, l;
4145f1d5
NC
22429 unsigned long current_pos;
22430
1cb7d8b1
AM
22431 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22432 "in the symbol table)\n"),
22433 filedata->file_name, (unsigned long) arch.index_num,
22434 arch.sym_size);
dda8d76d
NC
22435
22436 current_pos = ftell (filedata->handle);
4145f1d5 22437
2cf0635d 22438 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22439 {
1cb7d8b1
AM
22440 if (i == 0
22441 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22442 {
22443 char * member_name
22444 = get_archive_member_name_at (&arch, arch.index_array[i],
22445 &nested_arch);
2cf0635d 22446
1cb7d8b1
AM
22447 if (member_name != NULL)
22448 {
22449 char * qualified_name
22450 = make_qualified_name (&arch, &nested_arch,
22451 member_name);
2cf0635d 22452
1cb7d8b1
AM
22453 if (qualified_name != NULL)
22454 {
22455 printf (_("Contents of binary %s at offset "),
22456 qualified_name);
c2a7d3f5
NC
22457 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22458 putchar ('\n');
1cb7d8b1
AM
22459 free (qualified_name);
22460 }
fd486f32 22461 free (member_name);
4145f1d5
NC
22462 }
22463 }
2cf0635d
NC
22464
22465 if (l >= arch.sym_size)
4145f1d5 22466 {
1cb7d8b1
AM
22467 error (_("%s: end of the symbol table reached "
22468 "before the end of the index\n"),
dda8d76d 22469 filedata->file_name);
015dc7e1 22470 ret = false;
cb8f3167 22471 break;
4145f1d5 22472 }
591f7597 22473 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22474 printf ("\t%.*s\n",
22475 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22476 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22477 }
22478
67ce483b 22479 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22480 l = (l + 7) & ~ 7;
22481 else
22482 l += l & 1;
22483
2cf0635d 22484 if (l < arch.sym_size)
32ec8896 22485 {
d3a49aa8
AM
22486 error (ngettext ("%s: %ld byte remains in the symbol table, "
22487 "but without corresponding entries in "
22488 "the index table\n",
22489 "%s: %ld bytes remain in the symbol table, "
22490 "but without corresponding entries in "
22491 "the index table\n",
22492 arch.sym_size - l),
dda8d76d 22493 filedata->file_name, arch.sym_size - l);
015dc7e1 22494 ret = false;
32ec8896 22495 }
4145f1d5 22496
dda8d76d 22497 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22498 {
1cb7d8b1
AM
22499 error (_("%s: failed to seek back to start of object files "
22500 "in the archive\n"),
dda8d76d 22501 filedata->file_name);
015dc7e1 22502 ret = false;
2cf0635d 22503 goto out;
4145f1d5 22504 }
fb52b2f4 22505 }
4145f1d5
NC
22506
22507 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22508 && !do_segments && !do_header && !do_dump && !do_version
22509 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22510 && !do_section_groups && !do_dyn_syms)
2cf0635d 22511 {
015dc7e1 22512 ret = true; /* Archive index only. */
2cf0635d
NC
22513 goto out;
22514 }
fb52b2f4
NC
22515 }
22516
fb52b2f4
NC
22517 while (1)
22518 {
2cf0635d
NC
22519 char * name;
22520 size_t namelen;
22521 char * qualified_name;
22522
22523 /* Read the next archive header. */
dda8d76d 22524 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22525 {
22526 error (_("%s: failed to seek to next archive header\n"),
22527 arch.file_name);
015dc7e1 22528 ret = false;
1cb7d8b1
AM
22529 break;
22530 }
dda8d76d 22531 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22532 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22533 {
22534 if (got == 0)
2cf0635d 22535 break;
28e817cc
NC
22536 /* PR 24049 - we cannot use filedata->file_name as this will
22537 have already been freed. */
22538 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22539
015dc7e1 22540 ret = false;
1cb7d8b1
AM
22541 break;
22542 }
2cf0635d 22543 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22544 {
22545 error (_("%s: did not find a valid archive header\n"),
22546 arch.file_name);
015dc7e1 22547 ret = false;
1cb7d8b1
AM
22548 break;
22549 }
2cf0635d
NC
22550
22551 arch.next_arhdr_offset += sizeof arch.arhdr;
22552
978c4450 22553 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22554
22555 name = get_archive_member_name (&arch, &nested_arch);
22556 if (name == NULL)
fb52b2f4 22557 {
28e817cc 22558 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22559 ret = false;
d989285c 22560 break;
fb52b2f4 22561 }
2cf0635d 22562 namelen = strlen (name);
fb52b2f4 22563
2cf0635d
NC
22564 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22565 if (qualified_name == NULL)
fb52b2f4 22566 {
28e817cc 22567 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22568 free (name);
015dc7e1 22569 ret = false;
d989285c 22570 break;
fb52b2f4
NC
22571 }
22572
2cf0635d 22573 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22574 {
22575 /* This is a proxy for an external member of a thin archive. */
22576 Filedata * member_filedata;
22577 char * member_file_name = adjust_relative_path
dda8d76d 22578 (filedata->file_name, name, namelen);
32ec8896 22579
fd486f32 22580 free (name);
1cb7d8b1
AM
22581 if (member_file_name == NULL)
22582 {
fd486f32 22583 free (qualified_name);
015dc7e1 22584 ret = false;
1cb7d8b1
AM
22585 break;
22586 }
2cf0635d 22587
015dc7e1 22588 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22589 if (member_filedata == NULL)
22590 {
22591 error (_("Input file '%s' is not readable.\n"), member_file_name);
22592 free (member_file_name);
fd486f32 22593 free (qualified_name);
015dc7e1 22594 ret = false;
1cb7d8b1
AM
22595 break;
22596 }
2cf0635d 22597
978c4450 22598 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22599 member_filedata->file_name = qualified_name;
2cf0635d 22600
75a2da57
AH
22601 /* The call to process_object() expects the file to be at the beginning. */
22602 rewind (member_filedata->handle);
22603
1cb7d8b1 22604 if (! process_object (member_filedata))
015dc7e1 22605 ret = false;
2cf0635d 22606
1cb7d8b1
AM
22607 close_file (member_filedata);
22608 free (member_file_name);
1cb7d8b1 22609 }
2cf0635d 22610 else if (is_thin_archive)
1cb7d8b1
AM
22611 {
22612 Filedata thin_filedata;
eb02c04d 22613
1cb7d8b1 22614 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22615
a043396b
NC
22616 /* PR 15140: Allow for corrupt thin archives. */
22617 if (nested_arch.file == NULL)
22618 {
22619 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22620 qualified_name, name);
fd486f32
AM
22621 free (qualified_name);
22622 free (name);
015dc7e1 22623 ret = false;
a043396b
NC
22624 break;
22625 }
fd486f32 22626 free (name);
a043396b 22627
1cb7d8b1 22628 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22629 filedata->archive_file_offset
22630 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22631
1cb7d8b1
AM
22632 /* The nested archive file will have been opened and setup by
22633 get_archive_member_name. */
978c4450
AM
22634 if (fseek (nested_arch.file, filedata->archive_file_offset,
22635 SEEK_SET) != 0)
1cb7d8b1
AM
22636 {
22637 error (_("%s: failed to seek to archive member.\n"),
22638 nested_arch.file_name);
fd486f32 22639 free (qualified_name);
015dc7e1 22640 ret = false;
1cb7d8b1
AM
22641 break;
22642 }
2cf0635d 22643
dda8d76d
NC
22644 thin_filedata.handle = nested_arch.file;
22645 thin_filedata.file_name = qualified_name;
9abca702 22646
1cb7d8b1 22647 if (! process_object (& thin_filedata))
015dc7e1 22648 ret = false;
1cb7d8b1 22649 }
2cf0635d 22650 else
1cb7d8b1 22651 {
fd486f32 22652 free (name);
978c4450 22653 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22654 filedata->file_name = qualified_name;
1cb7d8b1 22655 if (! process_object (filedata))
015dc7e1 22656 ret = false;
237877b8 22657 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22658 /* Stop looping with "negative" archive_file_size. */
978c4450 22659 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22660 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22661 }
fb52b2f4 22662
2cf0635d 22663 free (qualified_name);
fb52b2f4
NC
22664 }
22665
4145f1d5 22666 out:
2cf0635d
NC
22667 if (nested_arch.file != NULL)
22668 fclose (nested_arch.file);
22669 release_archive (&nested_arch);
22670 release_archive (&arch);
fb52b2f4 22671
d989285c 22672 return ret;
fb52b2f4
NC
22673}
22674
015dc7e1 22675static bool
2cf0635d 22676process_file (char * file_name)
fb52b2f4 22677{
dda8d76d 22678 Filedata * filedata = NULL;
fb52b2f4
NC
22679 struct stat statbuf;
22680 char armag[SARMAG];
015dc7e1 22681 bool ret = true;
fb52b2f4
NC
22682
22683 if (stat (file_name, &statbuf) < 0)
22684 {
f24ddbdd
NC
22685 if (errno == ENOENT)
22686 error (_("'%s': No such file\n"), file_name);
22687 else
22688 error (_("Could not locate '%s'. System error message: %s\n"),
22689 file_name, strerror (errno));
015dc7e1 22690 return false;
f24ddbdd
NC
22691 }
22692
22693 if (! S_ISREG (statbuf.st_mode))
22694 {
22695 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22696 return false;
fb52b2f4
NC
22697 }
22698
dda8d76d
NC
22699 filedata = calloc (1, sizeof * filedata);
22700 if (filedata == NULL)
22701 {
22702 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22703 return false;
dda8d76d
NC
22704 }
22705
22706 filedata->file_name = file_name;
22707 filedata->handle = fopen (file_name, "rb");
22708 if (filedata->handle == NULL)
fb52b2f4 22709 {
f24ddbdd 22710 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22711 free (filedata);
015dc7e1 22712 return false;
fb52b2f4
NC
22713 }
22714
dda8d76d 22715 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22716 {
4145f1d5 22717 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22718 fclose (filedata->handle);
22719 free (filedata);
015dc7e1 22720 return false;
fb52b2f4
NC
22721 }
22722
be7d229a 22723 filedata->file_size = statbuf.st_size;
015dc7e1 22724 filedata->is_separate = false;
f54498b4 22725
fb52b2f4 22726 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22727 {
015dc7e1
AM
22728 if (! process_archive (filedata, false))
22729 ret = false;
32ec8896 22730 }
2cf0635d 22731 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22732 {
015dc7e1
AM
22733 if ( ! process_archive (filedata, true))
22734 ret = false;
32ec8896 22735 }
fb52b2f4
NC
22736 else
22737 {
1b513401 22738 if (do_archive_index && !check_all)
4145f1d5
NC
22739 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22740 file_name);
22741
dda8d76d 22742 rewind (filedata->handle);
978c4450 22743 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22744
dda8d76d 22745 if (! process_object (filedata))
015dc7e1 22746 ret = false;
fb52b2f4
NC
22747 }
22748
dda8d76d 22749 fclose (filedata->handle);
8fb879cd
AM
22750 free (filedata->section_headers);
22751 free (filedata->program_headers);
22752 free (filedata->string_table);
6431e409 22753 free (filedata->dump.dump_sects);
dda8d76d 22754 free (filedata);
32ec8896 22755
fd486f32 22756 free (ba_cache.strtab);
1bd6175a 22757 ba_cache.strtab = NULL;
fd486f32 22758 free (ba_cache.symtab);
1bd6175a 22759 ba_cache.symtab = NULL;
fd486f32
AM
22760 ba_cache.filedata = NULL;
22761
fb52b2f4
NC
22762 return ret;
22763}
22764
252b5132
RH
22765#ifdef SUPPORT_DISASSEMBLY
22766/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22767 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22768 symbols. */
252b5132
RH
22769
22770void
2cf0635d 22771print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22772{
22773 fprintf (outfile,"0x%8.8x", addr);
22774}
22775
e3c8793a 22776/* Needed by the i386 disassembler. */
dda8d76d 22777
252b5132
RH
22778void
22779db_task_printsym (unsigned int addr)
22780{
22781 print_address (addr, stderr);
22782}
22783#endif
22784
22785int
2cf0635d 22786main (int argc, char ** argv)
252b5132 22787{
ff78d6d6
L
22788 int err;
22789
87b9f255 22790#ifdef HAVE_LC_MESSAGES
252b5132 22791 setlocale (LC_MESSAGES, "");
3882b010 22792#endif
3882b010 22793 setlocale (LC_CTYPE, "");
252b5132
RH
22794 bindtextdomain (PACKAGE, LOCALEDIR);
22795 textdomain (PACKAGE);
22796
869b9d07
MM
22797 expandargv (&argc, &argv);
22798
dda8d76d 22799 parse_args (& cmdline, argc, argv);
59f14fc0 22800
18bd398b 22801 if (optind < (argc - 1))
1b513401
NC
22802 /* When displaying information for more than one file,
22803 prefix the information with the file name. */
015dc7e1 22804 show_name = true;
5656ba2c
L
22805 else if (optind >= argc)
22806 {
1b513401 22807 /* Ensure that the warning is always displayed. */
015dc7e1 22808 do_checks = true;
1b513401 22809
5656ba2c
L
22810 warn (_("Nothing to do.\n"));
22811 usage (stderr);
22812 }
18bd398b 22813
015dc7e1 22814 err = false;
252b5132 22815 while (optind < argc)
32ec8896 22816 if (! process_file (argv[optind++]))
015dc7e1 22817 err = true;
252b5132 22818
9db70fc3 22819 free (cmdline.dump_sects);
252b5132 22820
7d9813f1
NA
22821 free (dump_ctf_symtab_name);
22822 free (dump_ctf_strtab_name);
22823 free (dump_ctf_parent_name);
22824
32ec8896 22825 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22826}