]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Replace elf_vma with uint64_t
[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
AM
270 FILE * handle;
271 bfd_size_type file_size;
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
AM
280 unsigned long dynamic_addr;
281 bfd_size_type dynamic_size;
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;
294 bfd_size_type nbuckets;
295 bfd_size_type nchains;
296 bfd_vma * buckets;
297 bfd_vma * chains;
298 bfd_size_type ngnubuckets;
299 bfd_size_type ngnuchains;
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 *
dda8d76d
NC
442get_data (void * var,
443 Filedata * filedata,
444 unsigned long offset,
445 bfd_size_type size,
446 bfd_size_type nmemb,
447 const char * reason)
a6e9f9df 448{
2cf0635d 449 void * mvar;
57028622 450 bfd_size_type amt = size * nmemb;
a6e9f9df 451
c256ffe7 452 if (size == 0 || nmemb == 0)
a6e9f9df
AM
453 return NULL;
454
57028622
NC
455 /* If the size_t type is smaller than the bfd_size_type, eg because
456 you are building a 32-bit tool on a 64-bit host, then make sure
457 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
458 if ((size_t) size != size
459 || (size_t) nmemb != nmemb
460 || (size_t) amt != amt)
57028622
NC
461 {
462 if (reason)
b8281767
AM
463 error (_("Size truncation prevents reading %" PRIu64
464 " elements of size %" PRIu64 " for %s\n"),
465 (uint64_t) nmemb, (uint64_t) size, reason);
57028622
NC
466 return NULL;
467 }
468
469 /* Check for size overflow. */
7c1c1904 470 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
471 {
472 if (reason)
b8281767
AM
473 error (_("Size overflow prevents reading %" PRIu64
474 " elements of size %" PRIu64 " for %s\n"),
475 (uint64_t) nmemb, (uint64_t) size, reason);
57028622
NC
476 return NULL;
477 }
478
c22b42ce 479 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 480 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
481 if (filedata->archive_file_offset > filedata->file_size
482 || offset > filedata->file_size - filedata->archive_file_offset
483 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 484 {
049b0c3a 485 if (reason)
b8281767
AM
486 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
487 (uint64_t) amt, reason);
a6e9f9df
AM
488 return NULL;
489 }
490
978c4450
AM
491 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
492 SEEK_SET))
071436c6
NC
493 {
494 if (reason)
c9c1d674 495 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 496 filedata->archive_file_offset + offset, reason);
071436c6
NC
497 return NULL;
498 }
499
a6e9f9df
AM
500 mvar = var;
501 if (mvar == NULL)
502 {
7c1c1904
AM
503 /* + 1 so that we can '\0' terminate invalid string table sections. */
504 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
505
506 if (mvar == NULL)
507 {
049b0c3a 508 if (reason)
b8281767
AM
509 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
510 (uint64_t) amt, reason);
a6e9f9df
AM
511 return NULL;
512 }
c256ffe7 513
c9c1d674 514 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
515 }
516
dda8d76d 517 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 518 {
049b0c3a 519 if (reason)
b8281767
AM
520 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
521 (uint64_t) amt, reason);
a6e9f9df
AM
522 if (mvar != var)
523 free (mvar);
524 return NULL;
525 }
526
527 return mvar;
528}
529
32ec8896
NC
530/* Print a VMA value in the MODE specified.
531 Returns the number of characters displayed. */
cb8f3167 532
32ec8896 533static unsigned int
14a91970 534print_vma (bfd_vma vma, print_mode mode)
66543521 535{
32ec8896 536 unsigned int nc = 0;
66543521 537
14a91970 538 switch (mode)
66543521 539 {
14a91970
AM
540 case FULL_HEX:
541 nc = printf ("0x");
1a0670f3 542 /* Fall through. */
14a91970 543 case LONG_HEX:
f7a99963 544#ifdef BFD64
f493c217
AM
545 if (!is_32bit_elf)
546 return nc + printf ("%16.16" PRIx64, (uint64_t) vma);
f7a99963 547#endif
f493c217 548 return nc + printf ("%8.8" PRIx64, (uint64_t) vma);
b19aac67 549
14a91970
AM
550 case DEC_5:
551 if (vma <= 99999)
b8281767 552 return printf ("%5" PRId64, (int64_t) vma);
1a0670f3 553 /* Fall through. */
14a91970
AM
554 case PREFIX_HEX:
555 nc = printf ("0x");
1a0670f3 556 /* Fall through. */
14a91970 557 case HEX:
b8281767 558 return nc + printf ("%" PRIx64, (uint64_t) vma);
b19aac67 559
047c3dbf
NL
560 case PREFIX_HEX_5:
561 nc = printf ("0x");
562 /* Fall through. */
563 case HEX_5:
b8281767 564 return nc + printf ("%05" PRIx64, (uint64_t) vma);
047c3dbf 565
14a91970 566 case DEC:
b8281767 567 return printf ("%" PRId64, (int64_t) (bfd_signed_vma) vma);
b19aac67 568
14a91970 569 case UNSIGNED:
b8281767 570 return printf ("%" PRIu64, (uint64_t) vma);
32ec8896 571
047c3dbf 572 case UNSIGNED_5:
b8281767 573 return printf ("%5" PRIu64, (uint64_t) vma);
047c3dbf
NL
574
575 case OCTAL:
b8281767 576 return printf ("%" PRIo64, (uint64_t) vma);
047c3dbf
NL
577
578 case OCTAL_5:
b8281767 579 return printf ("%5" PRIo64, (uint64_t) vma);
047c3dbf 580
32ec8896
NC
581 default:
582 /* FIXME: Report unrecognised mode ? */
583 return 0;
f7a99963 584 }
f7a99963
NC
585}
586
047c3dbf 587
7bfd842d 588/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 589 multibye characters (assuming the host environment supports them).
31104126 590
7bfd842d
NC
591 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
592
0942c7ab
NC
593 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
594 abs(WIDTH) - 5 characters followed by "[...]".
595
7bfd842d
NC
596 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
597 padding as necessary.
171191ba
NC
598
599 Returns the number of emitted characters. */
600
601static unsigned int
0942c7ab 602print_symbol (signed int width, const char * symbol)
31104126 603{
015dc7e1
AM
604 bool extra_padding = false;
605 bool do_dots = false;
32ec8896 606 signed int num_printed = 0;
3bfcb652 607#ifdef HAVE_MBSTATE_T
7bfd842d 608 mbstate_t state;
3bfcb652 609#endif
32ec8896 610 unsigned int width_remaining;
79bc120c 611 const void * alloced_symbol = NULL;
961c521f 612
7bfd842d 613 if (width < 0)
961c521f 614 {
88305e1b 615 /* Keep the width positive. This helps the code below. */
961c521f 616 width = - width;
015dc7e1 617 extra_padding = true;
0b4362b0 618 }
56d8f8a9
NC
619 else if (width == 0)
620 return 0;
961c521f 621
7bfd842d
NC
622 if (do_wide)
623 /* Set the remaining width to a very large value.
624 This simplifies the code below. */
625 width_remaining = INT_MAX;
626 else
0942c7ab
NC
627 {
628 width_remaining = width;
629 if (! do_not_show_symbol_truncation
630 && (int) strlen (symbol) > width)
631 {
632 width_remaining -= 5;
633 if ((int) width_remaining < 0)
634 width_remaining = 0;
015dc7e1 635 do_dots = true;
0942c7ab
NC
636 }
637 }
cb8f3167 638
3bfcb652 639#ifdef HAVE_MBSTATE_T
7bfd842d
NC
640 /* Initialise the multibyte conversion state. */
641 memset (& state, 0, sizeof (state));
3bfcb652 642#endif
961c521f 643
79bc120c
NC
644 if (do_demangle && *symbol)
645 {
646 const char * res = cplus_demangle (symbol, demangle_flags);
647
648 if (res != NULL)
649 alloced_symbol = symbol = res;
650 }
651
7bfd842d
NC
652 while (width_remaining)
653 {
654 size_t n;
7bfd842d 655 const char c = *symbol++;
961c521f 656
7bfd842d 657 if (c == 0)
961c521f
NC
658 break;
659
b3aa80b4
NC
660 if (ISPRINT (c))
661 {
662 putchar (c);
663 width_remaining --;
664 num_printed ++;
665 }
666 else if (ISCNTRL (c))
961c521f 667 {
b3aa80b4
NC
668 /* Do not print control characters directly as they can affect terminal
669 settings. Such characters usually appear in the names generated
670 by the assembler for local labels. */
671
7bfd842d 672 if (width_remaining < 2)
961c521f
NC
673 break;
674
7bfd842d
NC
675 printf ("^%c", c + 0x40);
676 width_remaining -= 2;
171191ba 677 num_printed += 2;
961c521f 678 }
b3aa80b4 679 else if (c == 0x7f)
7bfd842d 680 {
b3aa80b4
NC
681 if (width_remaining < 5)
682 break;
683 printf ("<DEL>");
684 width_remaining -= 5;
685 num_printed += 5;
686 }
687 else if (unicode_display != unicode_locale
688 && unicode_display != unicode_default)
689 {
690 /* Display unicode characters as something else. */
691 unsigned char bytes[4];
692 bool is_utf8;
795588ae 693 unsigned int nbytes;
b3aa80b4
NC
694
695 bytes[0] = c;
696
697 if (bytes[0] < 0xc0)
698 {
699 nbytes = 1;
700 is_utf8 = false;
701 }
702 else
703 {
704 bytes[1] = *symbol++;
705
706 if ((bytes[1] & 0xc0) != 0x80)
707 {
708 is_utf8 = false;
709 /* Do not consume this character. It may only
710 be the first byte in the sequence that was
711 corrupt. */
712 --symbol;
713 nbytes = 1;
714 }
715 else if ((bytes[0] & 0x20) == 0)
716 {
717 is_utf8 = true;
718 nbytes = 2;
719 }
720 else
721 {
722 bytes[2] = *symbol++;
723
724 if ((bytes[2] & 0xc0) != 0x80)
725 {
726 is_utf8 = false;
727 symbol -= 2;
728 nbytes = 1;
729 }
730 else if ((bytes[0] & 0x10) == 0)
731 {
732 is_utf8 = true;
733 nbytes = 3;
734 }
735 else
736 {
737 bytes[3] = *symbol++;
738
739 nbytes = 4;
740
741 if ((bytes[3] & 0xc0) != 0x80)
742 {
743 is_utf8 = false;
744 symbol -= 3;
745 nbytes = 1;
746 }
747 else
748 is_utf8 = true;
749 }
750 }
751 }
752
753 if (unicode_display == unicode_invalid)
754 is_utf8 = false;
755
756 if (unicode_display == unicode_hex || ! is_utf8)
757 {
795588ae 758 unsigned int i;
b3aa80b4
NC
759
760 if (width_remaining < (nbytes * 2) + 2)
761 break;
762
763 putchar (is_utf8 ? '<' : '{');
764 printf ("0x");
765 for (i = 0; i < nbytes; i++)
766 printf ("%02x", bytes[i]);
767 putchar (is_utf8 ? '>' : '}');
768 }
769 else
770 {
771 if (unicode_display == unicode_highlight && isatty (1))
772 printf ("\x1B[31;47m"); /* Red. */
773
774 switch (nbytes)
775 {
776 case 2:
777 if (width_remaining < 6)
778 break;
779 printf ("\\u%02x%02x",
780 (bytes[0] & 0x1c) >> 2,
781 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
782 break;
783 case 3:
784 if (width_remaining < 6)
785 break;
786 printf ("\\u%02x%02x",
787 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
788 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
789 break;
790 case 4:
791 if (width_remaining < 8)
792 break;
793 printf ("\\u%02x%02x%02x",
794 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
795 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
796 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
797
798 break;
799 default:
800 /* URG. */
801 break;
802 }
803
804 if (unicode_display == unicode_highlight && isatty (1))
805 printf ("\033[0m"); /* Default colour. */
806 }
807
808 if (bytes[nbytes - 1] == 0)
809 break;
7bfd842d 810 }
961c521f
NC
811 else
812 {
3bfcb652
NC
813#ifdef HAVE_MBSTATE_T
814 wchar_t w;
815#endif
7bfd842d
NC
816 /* Let printf do the hard work of displaying multibyte characters. */
817 printf ("%.1s", symbol - 1);
818 width_remaining --;
819 num_printed ++;
820
3bfcb652 821#ifdef HAVE_MBSTATE_T
7bfd842d
NC
822 /* Try to find out how many bytes made up the character that was
823 just printed. Advance the symbol pointer past the bytes that
824 were displayed. */
825 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
826#else
827 n = 1;
828#endif
7bfd842d
NC
829 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
830 symbol += (n - 1);
961c521f 831 }
961c521f 832 }
171191ba 833
0942c7ab
NC
834 if (do_dots)
835 num_printed += printf ("[...]");
836
7bfd842d 837 if (extra_padding && num_printed < width)
171191ba
NC
838 {
839 /* Fill in the remaining spaces. */
7bfd842d
NC
840 printf ("%-*s", width - num_printed, " ");
841 num_printed = width;
171191ba
NC
842 }
843
79bc120c 844 free ((void *) alloced_symbol);
171191ba 845 return num_printed;
31104126
NC
846}
847
1449284b 848/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
849 the given section's name. Like print_symbol, except that it does not try
850 to print multibyte characters, it just interprets them as hex values. */
851
852static const char *
dda8d76d 853printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 854{
ca0e11aa 855#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 856 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 857 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
858 char * buf = sec_name_buf;
859 char c;
860 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
861
862 while ((c = * name ++) != 0)
863 {
864 if (ISCNTRL (c))
865 {
866 if (remaining < 2)
867 break;
948f632f 868
74e1a04b
NC
869 * buf ++ = '^';
870 * buf ++ = c + 0x40;
871 remaining -= 2;
872 }
873 else if (ISPRINT (c))
874 {
875 * buf ++ = c;
876 remaining -= 1;
877 }
878 else
879 {
880 static char hex[17] = "0123456789ABCDEF";
881
882 if (remaining < 4)
883 break;
884 * buf ++ = '<';
885 * buf ++ = hex[(c & 0xf0) >> 4];
886 * buf ++ = hex[c & 0x0f];
887 * buf ++ = '>';
888 remaining -= 4;
889 }
890
891 if (remaining == 0)
892 break;
893 }
894
895 * buf = 0;
896 return sec_name_buf;
897}
898
899static const char *
dda8d76d 900printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 901{
dda8d76d 902 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
903 return _("<corrupt>");
904
dda8d76d 905 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
906}
907
89fac5e3
RS
908/* Return a pointer to section NAME, or NULL if no such section exists. */
909
910static Elf_Internal_Shdr *
dda8d76d 911find_section (Filedata * filedata, const char * name)
89fac5e3
RS
912{
913 unsigned int i;
914
68807c3c
NC
915 if (filedata->section_headers == NULL)
916 return NULL;
dda8d76d
NC
917
918 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
919 if (section_name_valid (filedata, filedata->section_headers + i)
920 && streq (section_name (filedata, filedata->section_headers + i),
921 name))
dda8d76d 922 return filedata->section_headers + i;
89fac5e3
RS
923
924 return NULL;
925}
926
0b6ae522
DJ
927/* Return a pointer to a section containing ADDR, or NULL if no such
928 section exists. */
929
930static Elf_Internal_Shdr *
dda8d76d 931find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
932{
933 unsigned int i;
934
68807c3c
NC
935 if (filedata->section_headers == NULL)
936 return NULL;
937
dda8d76d 938 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 939 {
dda8d76d
NC
940 Elf_Internal_Shdr *sec = filedata->section_headers + i;
941
0b6ae522
DJ
942 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
943 return sec;
944 }
945
946 return NULL;
947}
948
071436c6 949static Elf_Internal_Shdr *
dda8d76d 950find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
951{
952 unsigned int i;
953
68807c3c
NC
954 if (filedata->section_headers == NULL)
955 return NULL;
956
dda8d76d 957 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 958 {
dda8d76d
NC
959 Elf_Internal_Shdr *sec = filedata->section_headers + i;
960
071436c6
NC
961 if (sec->sh_type == type)
962 return sec;
963 }
964
965 return NULL;
966}
967
657d0d47
CC
968/* Return a pointer to section NAME, or NULL if no such section exists,
969 restricted to the list of sections given in SET. */
970
971static Elf_Internal_Shdr *
dda8d76d 972find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
973{
974 unsigned int i;
975
68807c3c
NC
976 if (filedata->section_headers == NULL)
977 return NULL;
978
657d0d47
CC
979 if (set != NULL)
980 {
981 while ((i = *set++) > 0)
b814a36d
NC
982 {
983 /* See PR 21156 for a reproducer. */
dda8d76d 984 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
985 continue; /* FIXME: Should we issue an error message ? */
986
84714f86
AM
987 if (section_name_valid (filedata, filedata->section_headers + i)
988 && streq (section_name (filedata, filedata->section_headers + i),
989 name))
dda8d76d 990 return filedata->section_headers + i;
b814a36d 991 }
657d0d47
CC
992 }
993
dda8d76d 994 return find_section (filedata, name);
657d0d47
CC
995}
996
32ec8896 997/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
998 This OS has so many departures from the ELF standard that we test it at
999 many places. */
1000
015dc7e1 1001static inline bool
dda8d76d 1002is_ia64_vms (Filedata * filedata)
28f997cf 1003{
dda8d76d
NC
1004 return filedata->file_header.e_machine == EM_IA_64
1005 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1006}
1007
bcedfee6 1008/* Guess the relocation size commonly used by the specific machines. */
252b5132 1009
015dc7e1 1010static bool
2dc4cec1 1011guess_is_rela (unsigned int e_machine)
252b5132 1012{
9c19a809 1013 switch (e_machine)
252b5132
RH
1014 {
1015 /* Targets that use REL relocations. */
252b5132 1016 case EM_386:
22abe556 1017 case EM_IAMCU:
f954747f 1018 case EM_960:
e9f53129 1019 case EM_ARM:
2b0337b0 1020 case EM_D10V:
252b5132 1021 case EM_CYGNUS_D10V:
e9f53129 1022 case EM_DLX:
252b5132 1023 case EM_MIPS:
4fe85591 1024 case EM_MIPS_RS3_LE:
e9f53129 1025 case EM_CYGNUS_M32R:
1c0d3aa6 1026 case EM_SCORE:
f6c1a2d5 1027 case EM_XGATE:
fe944acf 1028 case EM_NFP:
aca4efc7 1029 case EM_BPF:
015dc7e1 1030 return false;
103f02d3 1031
252b5132
RH
1032 /* Targets that use RELA relocations. */
1033 case EM_68K:
f954747f 1034 case EM_860:
a06ea964 1035 case EM_AARCH64:
cfb8c092 1036 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1037 case EM_ALPHA:
1038 case EM_ALTERA_NIOS2:
886a2506
NC
1039 case EM_ARC:
1040 case EM_ARC_COMPACT:
1041 case EM_ARC_COMPACT2:
e9f53129
AM
1042 case EM_AVR:
1043 case EM_AVR_OLD:
1044 case EM_BLACKFIN:
60bca95a 1045 case EM_CR16:
e9f53129
AM
1046 case EM_CRIS:
1047 case EM_CRX:
b8891f8d 1048 case EM_CSKY:
2b0337b0 1049 case EM_D30V:
252b5132 1050 case EM_CYGNUS_D30V:
2b0337b0 1051 case EM_FR30:
3f8107ab 1052 case EM_FT32:
252b5132 1053 case EM_CYGNUS_FR30:
5c70f934 1054 case EM_CYGNUS_FRV:
e9f53129
AM
1055 case EM_H8S:
1056 case EM_H8_300:
1057 case EM_H8_300H:
800eeca4 1058 case EM_IA_64:
1e4cf259
NC
1059 case EM_IP2K:
1060 case EM_IP2K_OLD:
3b36097d 1061 case EM_IQ2000:
84e94c90 1062 case EM_LATTICEMICO32:
ff7eeb89 1063 case EM_M32C_OLD:
49f58d10 1064 case EM_M32C:
e9f53129
AM
1065 case EM_M32R:
1066 case EM_MCORE:
15ab5209 1067 case EM_CYGNUS_MEP:
a3c62988 1068 case EM_METAG:
e9f53129
AM
1069 case EM_MMIX:
1070 case EM_MN10200:
1071 case EM_CYGNUS_MN10200:
1072 case EM_MN10300:
1073 case EM_CYGNUS_MN10300:
5506d11a 1074 case EM_MOXIE:
e9f53129
AM
1075 case EM_MSP430:
1076 case EM_MSP430_OLD:
d031aafb 1077 case EM_MT:
35c08157 1078 case EM_NDS32:
64fd6348 1079 case EM_NIOS32:
73589c9d 1080 case EM_OR1K:
e9f53129
AM
1081 case EM_PPC64:
1082 case EM_PPC:
2b100bb5 1083 case EM_TI_PRU:
e23eba97 1084 case EM_RISCV:
99c513f6 1085 case EM_RL78:
c7927a3c 1086 case EM_RX:
e9f53129
AM
1087 case EM_S390:
1088 case EM_S390_OLD:
1089 case EM_SH:
1090 case EM_SPARC:
1091 case EM_SPARC32PLUS:
1092 case EM_SPARCV9:
1093 case EM_SPU:
40b36596 1094 case EM_TI_C6000:
aa137e4d
NC
1095 case EM_TILEGX:
1096 case EM_TILEPRO:
708e2187 1097 case EM_V800:
e9f53129
AM
1098 case EM_V850:
1099 case EM_CYGNUS_V850:
1100 case EM_VAX:
619ed720 1101 case EM_VISIUM:
e9f53129 1102 case EM_X86_64:
8a9036a4 1103 case EM_L1OM:
7a9068fe 1104 case EM_K1OM:
e9f53129
AM
1105 case EM_XSTORMY16:
1106 case EM_XTENSA:
1107 case EM_XTENSA_OLD:
7ba29e2a
NC
1108 case EM_MICROBLAZE:
1109 case EM_MICROBLAZE_OLD:
f96bd6c2 1110 case EM_WEBASSEMBLY:
015dc7e1 1111 return true;
103f02d3 1112
e9f53129
AM
1113 case EM_68HC05:
1114 case EM_68HC08:
1115 case EM_68HC11:
1116 case EM_68HC16:
1117 case EM_FX66:
1118 case EM_ME16:
d1133906 1119 case EM_MMA:
d1133906
NC
1120 case EM_NCPU:
1121 case EM_NDR1:
e9f53129 1122 case EM_PCP:
d1133906 1123 case EM_ST100:
e9f53129 1124 case EM_ST19:
d1133906 1125 case EM_ST7:
e9f53129
AM
1126 case EM_ST9PLUS:
1127 case EM_STARCORE:
d1133906 1128 case EM_SVX:
e9f53129 1129 case EM_TINYJ:
9c19a809
NC
1130 default:
1131 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1132 return false;
9c19a809
NC
1133 }
1134}
252b5132 1135
dda8d76d 1136/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1137 Returns TRUE upon success, FALSE otherwise. If successful then a
1138 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1139 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1140 responsibility to free the allocated buffer. */
1141
015dc7e1 1142static bool
dda8d76d
NC
1143slurp_rela_relocs (Filedata * filedata,
1144 unsigned long rel_offset,
1145 unsigned long rel_size,
1146 Elf_Internal_Rela ** relasp,
1147 unsigned long * nrelasp)
9c19a809 1148{
2cf0635d 1149 Elf_Internal_Rela * relas;
8b73c356 1150 size_t nrelas;
4d6ed7c8 1151 unsigned int i;
252b5132 1152
4d6ed7c8
NC
1153 if (is_32bit_elf)
1154 {
2cf0635d 1155 Elf32_External_Rela * erelas;
103f02d3 1156
dda8d76d 1157 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1158 rel_size, _("32-bit relocation data"));
a6e9f9df 1159 if (!erelas)
015dc7e1 1160 return false;
252b5132 1161
4d6ed7c8 1162 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1163
3f5e193b
NC
1164 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1165 sizeof (Elf_Internal_Rela));
103f02d3 1166
4d6ed7c8
NC
1167 if (relas == NULL)
1168 {
c256ffe7 1169 free (erelas);
591a748a 1170 error (_("out of memory parsing relocs\n"));
015dc7e1 1171 return false;
4d6ed7c8 1172 }
103f02d3 1173
4d6ed7c8
NC
1174 for (i = 0; i < nrelas; i++)
1175 {
1176 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1177 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1178 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1179 }
103f02d3 1180
4d6ed7c8
NC
1181 free (erelas);
1182 }
1183 else
1184 {
2cf0635d 1185 Elf64_External_Rela * erelas;
103f02d3 1186
dda8d76d 1187 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1188 rel_size, _("64-bit relocation data"));
a6e9f9df 1189 if (!erelas)
015dc7e1 1190 return false;
4d6ed7c8
NC
1191
1192 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1193
3f5e193b
NC
1194 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1195 sizeof (Elf_Internal_Rela));
103f02d3 1196
4d6ed7c8
NC
1197 if (relas == NULL)
1198 {
c256ffe7 1199 free (erelas);
591a748a 1200 error (_("out of memory parsing relocs\n"));
015dc7e1 1201 return false;
9c19a809 1202 }
4d6ed7c8
NC
1203
1204 for (i = 0; i < nrelas; i++)
9c19a809 1205 {
66543521
AM
1206 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1207 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1208 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1209
1210 /* The #ifdef BFD64 below is to prevent a compile time
1211 warning. We know that if we do not have a 64 bit data
1212 type that we will never execute this code anyway. */
1213#ifdef BFD64
dda8d76d
NC
1214 if (filedata->file_header.e_machine == EM_MIPS
1215 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1216 {
1217 /* In little-endian objects, r_info isn't really a
1218 64-bit little-endian value: it has a 32-bit
1219 little-endian symbol index followed by four
1220 individual byte fields. Reorder INFO
1221 accordingly. */
91d6fa6a
NC
1222 bfd_vma inf = relas[i].r_info;
1223 inf = (((inf & 0xffffffff) << 32)
1224 | ((inf >> 56) & 0xff)
1225 | ((inf >> 40) & 0xff00)
1226 | ((inf >> 24) & 0xff0000)
1227 | ((inf >> 8) & 0xff000000));
1228 relas[i].r_info = inf;
861fb55a
DJ
1229 }
1230#endif /* BFD64 */
4d6ed7c8 1231 }
103f02d3 1232
4d6ed7c8
NC
1233 free (erelas);
1234 }
32ec8896 1235
4d6ed7c8
NC
1236 *relasp = relas;
1237 *nrelasp = nrelas;
015dc7e1 1238 return true;
4d6ed7c8 1239}
103f02d3 1240
dda8d76d 1241/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1242 Returns TRUE upon success, FALSE otherwise. If successful then a
1243 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1244 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1245 responsibility to free the allocated buffer. */
1246
015dc7e1 1247static bool
dda8d76d
NC
1248slurp_rel_relocs (Filedata * filedata,
1249 unsigned long rel_offset,
1250 unsigned long rel_size,
1251 Elf_Internal_Rela ** relsp,
1252 unsigned long * nrelsp)
4d6ed7c8 1253{
2cf0635d 1254 Elf_Internal_Rela * rels;
8b73c356 1255 size_t nrels;
4d6ed7c8 1256 unsigned int i;
103f02d3 1257
4d6ed7c8
NC
1258 if (is_32bit_elf)
1259 {
2cf0635d 1260 Elf32_External_Rel * erels;
103f02d3 1261
dda8d76d 1262 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1263 rel_size, _("32-bit relocation data"));
a6e9f9df 1264 if (!erels)
015dc7e1 1265 return false;
103f02d3 1266
4d6ed7c8 1267 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1268
3f5e193b 1269 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1270
4d6ed7c8
NC
1271 if (rels == NULL)
1272 {
c256ffe7 1273 free (erels);
591a748a 1274 error (_("out of memory parsing relocs\n"));
015dc7e1 1275 return false;
4d6ed7c8
NC
1276 }
1277
1278 for (i = 0; i < nrels; i++)
1279 {
1280 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1281 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1282 rels[i].r_addend = 0;
9ea033b2 1283 }
4d6ed7c8
NC
1284
1285 free (erels);
9c19a809
NC
1286 }
1287 else
1288 {
2cf0635d 1289 Elf64_External_Rel * erels;
9ea033b2 1290
dda8d76d 1291 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1292 rel_size, _("64-bit relocation data"));
a6e9f9df 1293 if (!erels)
015dc7e1 1294 return false;
103f02d3 1295
4d6ed7c8 1296 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1297
3f5e193b 1298 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1299
4d6ed7c8 1300 if (rels == NULL)
9c19a809 1301 {
c256ffe7 1302 free (erels);
591a748a 1303 error (_("out of memory parsing relocs\n"));
015dc7e1 1304 return false;
4d6ed7c8 1305 }
103f02d3 1306
4d6ed7c8
NC
1307 for (i = 0; i < nrels; i++)
1308 {
66543521
AM
1309 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1310 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1311 rels[i].r_addend = 0;
861fb55a
DJ
1312
1313 /* The #ifdef BFD64 below is to prevent a compile time
1314 warning. We know that if we do not have a 64 bit data
1315 type that we will never execute this code anyway. */
1316#ifdef BFD64
dda8d76d
NC
1317 if (filedata->file_header.e_machine == EM_MIPS
1318 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1319 {
1320 /* In little-endian objects, r_info isn't really a
1321 64-bit little-endian value: it has a 32-bit
1322 little-endian symbol index followed by four
1323 individual byte fields. Reorder INFO
1324 accordingly. */
91d6fa6a
NC
1325 bfd_vma inf = rels[i].r_info;
1326 inf = (((inf & 0xffffffff) << 32)
1327 | ((inf >> 56) & 0xff)
1328 | ((inf >> 40) & 0xff00)
1329 | ((inf >> 24) & 0xff0000)
1330 | ((inf >> 8) & 0xff000000));
1331 rels[i].r_info = inf;
861fb55a
DJ
1332 }
1333#endif /* BFD64 */
4d6ed7c8 1334 }
103f02d3 1335
4d6ed7c8
NC
1336 free (erels);
1337 }
32ec8896 1338
4d6ed7c8
NC
1339 *relsp = rels;
1340 *nrelsp = nrels;
015dc7e1 1341 return true;
4d6ed7c8 1342}
103f02d3 1343
a7fd1186
FS
1344static bool
1345slurp_relr_relocs (Filedata * filedata,
1346 unsigned long relr_offset,
1347 unsigned long relr_size,
1348 bfd_vma ** relrsp,
1349 unsigned long * nrelrsp)
1350{
1351 void *relrs;
1352 size_t size = 0, nentries, i;
1353 bfd_vma base = 0, addr, entry;
1354
1355 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1356 _("RELR relocation data"));
1357 if (!relrs)
1358 return false;
1359
1360 if (is_32bit_elf)
1361 nentries = relr_size / sizeof (Elf32_External_Relr);
1362 else
1363 nentries = relr_size / sizeof (Elf64_External_Relr);
1364 for (i = 0; i < nentries; i++)
1365 {
1366 if (is_32bit_elf)
1367 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1368 else
1369 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1370 if ((entry & 1) == 0)
1371 size++;
1372 else
1373 while ((entry >>= 1) != 0)
1374 if ((entry & 1) == 1)
1375 size++;
1376 }
1377
4491a7c1 1378 *relrsp = (bfd_vma *) malloc (size * sizeof (bfd_vma));
a7fd1186
FS
1379 if (*relrsp == NULL)
1380 {
1381 free (relrs);
1382 error (_("out of memory parsing relocs\n"));
1383 return false;
1384 }
1385
1386 size = 0;
1387 for (i = 0; i < nentries; i++)
1388 {
1389 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1390
1391 if (is_32bit_elf)
1392 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1393 else
1394 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1395 if ((entry & 1) == 0)
1396 {
1397 (*relrsp)[size++] = entry;
1398 base = entry + entry_bytes;
1399 }
1400 else
1401 {
1402 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1403 if ((entry & 1) != 0)
1404 (*relrsp)[size++] = addr;
1405 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1406 }
1407 }
1408
1409 *nrelrsp = size;
1410 free (relrs);
1411 return true;
1412}
1413
aca88567
NC
1414/* Returns the reloc type extracted from the reloc info field. */
1415
1416static unsigned int
dda8d76d 1417get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1418{
1419 if (is_32bit_elf)
1420 return ELF32_R_TYPE (reloc_info);
1421
dda8d76d 1422 switch (filedata->file_header.e_machine)
aca88567
NC
1423 {
1424 case EM_MIPS:
1425 /* Note: We assume that reloc_info has already been adjusted for us. */
1426 return ELF64_MIPS_R_TYPE (reloc_info);
1427
1428 case EM_SPARCV9:
1429 return ELF64_R_TYPE_ID (reloc_info);
1430
1431 default:
1432 return ELF64_R_TYPE (reloc_info);
1433 }
1434}
1435
1436/* Return the symbol index extracted from the reloc info field. */
1437
1438static bfd_vma
1439get_reloc_symindex (bfd_vma reloc_info)
1440{
1441 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1442}
1443
015dc7e1 1444static inline bool
dda8d76d 1445uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1446{
1447 return
dda8d76d 1448 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1449 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1450 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1451 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1452 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1453}
1454
d3ba0551
AM
1455/* Display the contents of the relocation data found at the specified
1456 offset. */
ee42cf8c 1457
015dc7e1 1458static bool
dda8d76d
NC
1459dump_relocations (Filedata * filedata,
1460 unsigned long rel_offset,
1461 unsigned long rel_size,
1462 Elf_Internal_Sym * symtab,
1463 unsigned long nsyms,
1464 char * strtab,
1465 unsigned long strtablen,
a7fd1186 1466 relocation_type rel_type,
015dc7e1 1467 bool is_dynsym)
4d6ed7c8 1468{
32ec8896 1469 unsigned long i;
2cf0635d 1470 Elf_Internal_Rela * rels;
015dc7e1 1471 bool res = true;
103f02d3 1472
a7fd1186
FS
1473 if (rel_type == reltype_unknown)
1474 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1475
a7fd1186 1476 if (rel_type == reltype_rela)
4d6ed7c8 1477 {
dda8d76d 1478 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1479 return false;
4d6ed7c8 1480 }
a7fd1186 1481 else if (rel_type == reltype_rel)
4d6ed7c8 1482 {
dda8d76d 1483 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1484 return false;
252b5132 1485 }
a7fd1186
FS
1486 else if (rel_type == reltype_relr)
1487 {
1488 bfd_vma * relrs;
1489 const char *format
b8281767 1490 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1491
1492 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1493 &rel_size))
1494 return false;
1495
b8281767
AM
1496 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size),
1497 rel_size);
a7fd1186 1498 for (i = 0; i < rel_size; i++)
b8281767 1499 printf (format, (uint64_t) relrs[i]);
a7fd1186
FS
1500 free (relrs);
1501 return true;
1502 }
252b5132 1503
410f7a12
L
1504 if (is_32bit_elf)
1505 {
a7fd1186 1506 if (rel_type == reltype_rela)
2c71103e
NC
1507 {
1508 if (do_wide)
1509 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1510 else
1511 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1512 }
410f7a12 1513 else
2c71103e
NC
1514 {
1515 if (do_wide)
1516 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1517 else
1518 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1519 }
410f7a12 1520 }
252b5132 1521 else
410f7a12 1522 {
a7fd1186 1523 if (rel_type == reltype_rela)
2c71103e
NC
1524 {
1525 if (do_wide)
8beeaeb7 1526 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1527 else
1528 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1529 }
410f7a12 1530 else
2c71103e
NC
1531 {
1532 if (do_wide)
8beeaeb7 1533 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1534 else
1535 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1536 }
410f7a12 1537 }
252b5132
RH
1538
1539 for (i = 0; i < rel_size; i++)
1540 {
2cf0635d 1541 const char * rtype;
b34976b6 1542 bfd_vma offset;
91d6fa6a 1543 bfd_vma inf;
b34976b6
AM
1544 bfd_vma symtab_index;
1545 bfd_vma type;
103f02d3 1546
b34976b6 1547 offset = rels[i].r_offset;
91d6fa6a 1548 inf = rels[i].r_info;
103f02d3 1549
dda8d76d 1550 type = get_reloc_type (filedata, inf);
91d6fa6a 1551 symtab_index = get_reloc_symindex (inf);
252b5132 1552
410f7a12
L
1553 if (is_32bit_elf)
1554 {
39dbeff8
AM
1555 printf ("%8.8lx %8.8lx ",
1556 (unsigned long) offset & 0xffffffff,
91d6fa6a 1557 (unsigned long) inf & 0xffffffff);
410f7a12
L
1558 }
1559 else
1560 {
39dbeff8 1561 printf (do_wide
b8281767
AM
1562 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1563 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
1564 (uint64_t) offset, (uint64_t) inf);
410f7a12 1565 }
103f02d3 1566
dda8d76d 1567 switch (filedata->file_header.e_machine)
252b5132
RH
1568 {
1569 default:
1570 rtype = NULL;
1571 break;
1572
a06ea964
NC
1573 case EM_AARCH64:
1574 rtype = elf_aarch64_reloc_type (type);
1575 break;
1576
2b0337b0 1577 case EM_M32R:
252b5132 1578 case EM_CYGNUS_M32R:
9ea033b2 1579 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1580 break;
1581
1582 case EM_386:
22abe556 1583 case EM_IAMCU:
9ea033b2 1584 rtype = elf_i386_reloc_type (type);
252b5132
RH
1585 break;
1586
ba2685cc
AM
1587 case EM_68HC11:
1588 case EM_68HC12:
1589 rtype = elf_m68hc11_reloc_type (type);
1590 break;
75751cd9 1591
7b4ae824
JD
1592 case EM_S12Z:
1593 rtype = elf_s12z_reloc_type (type);
1594 break;
1595
252b5132 1596 case EM_68K:
9ea033b2 1597 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1598 break;
1599
f954747f
AM
1600 case EM_960:
1601 rtype = elf_i960_reloc_type (type);
1602 break;
1603
adde6300 1604 case EM_AVR:
2b0337b0 1605 case EM_AVR_OLD:
adde6300
AM
1606 rtype = elf_avr_reloc_type (type);
1607 break;
1608
9ea033b2
NC
1609 case EM_OLD_SPARCV9:
1610 case EM_SPARC32PLUS:
1611 case EM_SPARCV9:
252b5132 1612 case EM_SPARC:
9ea033b2 1613 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1614 break;
1615
e9f53129
AM
1616 case EM_SPU:
1617 rtype = elf_spu_reloc_type (type);
1618 break;
1619
708e2187
NC
1620 case EM_V800:
1621 rtype = v800_reloc_type (type);
1622 break;
2b0337b0 1623 case EM_V850:
252b5132 1624 case EM_CYGNUS_V850:
9ea033b2 1625 rtype = v850_reloc_type (type);
252b5132
RH
1626 break;
1627
2b0337b0 1628 case EM_D10V:
252b5132 1629 case EM_CYGNUS_D10V:
9ea033b2 1630 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1631 break;
1632
2b0337b0 1633 case EM_D30V:
252b5132 1634 case EM_CYGNUS_D30V:
9ea033b2 1635 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1636 break;
1637
d172d4ba
NC
1638 case EM_DLX:
1639 rtype = elf_dlx_reloc_type (type);
1640 break;
1641
252b5132 1642 case EM_SH:
9ea033b2 1643 rtype = elf_sh_reloc_type (type);
252b5132
RH
1644 break;
1645
2b0337b0 1646 case EM_MN10300:
252b5132 1647 case EM_CYGNUS_MN10300:
9ea033b2 1648 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1649 break;
1650
2b0337b0 1651 case EM_MN10200:
252b5132 1652 case EM_CYGNUS_MN10200:
9ea033b2 1653 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1654 break;
1655
2b0337b0 1656 case EM_FR30:
252b5132 1657 case EM_CYGNUS_FR30:
9ea033b2 1658 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1659 break;
1660
ba2685cc
AM
1661 case EM_CYGNUS_FRV:
1662 rtype = elf_frv_reloc_type (type);
1663 break;
5c70f934 1664
b8891f8d
AJ
1665 case EM_CSKY:
1666 rtype = elf_csky_reloc_type (type);
1667 break;
1668
3f8107ab
AM
1669 case EM_FT32:
1670 rtype = elf_ft32_reloc_type (type);
1671 break;
1672
252b5132 1673 case EM_MCORE:
9ea033b2 1674 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1675 break;
1676
3c3bdf30
NC
1677 case EM_MMIX:
1678 rtype = elf_mmix_reloc_type (type);
1679 break;
1680
5506d11a
AM
1681 case EM_MOXIE:
1682 rtype = elf_moxie_reloc_type (type);
1683 break;
1684
2469cfa2 1685 case EM_MSP430:
dda8d76d 1686 if (uses_msp430x_relocs (filedata))
13761a11
NC
1687 {
1688 rtype = elf_msp430x_reloc_type (type);
1689 break;
1690 }
1a0670f3 1691 /* Fall through. */
2469cfa2
NC
1692 case EM_MSP430_OLD:
1693 rtype = elf_msp430_reloc_type (type);
1694 break;
1695
35c08157
KLC
1696 case EM_NDS32:
1697 rtype = elf_nds32_reloc_type (type);
1698 break;
1699
252b5132 1700 case EM_PPC:
9ea033b2 1701 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1702 break;
1703
c833c019
AM
1704 case EM_PPC64:
1705 rtype = elf_ppc64_reloc_type (type);
1706 break;
1707
252b5132 1708 case EM_MIPS:
4fe85591 1709 case EM_MIPS_RS3_LE:
9ea033b2 1710 rtype = elf_mips_reloc_type (type);
252b5132
RH
1711 break;
1712
e23eba97
NC
1713 case EM_RISCV:
1714 rtype = elf_riscv_reloc_type (type);
1715 break;
1716
252b5132 1717 case EM_ALPHA:
9ea033b2 1718 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1719 break;
1720
1721 case EM_ARM:
9ea033b2 1722 rtype = elf_arm_reloc_type (type);
252b5132
RH
1723 break;
1724
584da044 1725 case EM_ARC:
886a2506
NC
1726 case EM_ARC_COMPACT:
1727 case EM_ARC_COMPACT2:
9ea033b2 1728 rtype = elf_arc_reloc_type (type);
252b5132
RH
1729 break;
1730
1731 case EM_PARISC:
69e617ca 1732 rtype = elf_hppa_reloc_type (type);
252b5132 1733 break;
7d466069 1734
b8720f9d
JL
1735 case EM_H8_300:
1736 case EM_H8_300H:
1737 case EM_H8S:
1738 rtype = elf_h8_reloc_type (type);
1739 break;
1740
73589c9d
CS
1741 case EM_OR1K:
1742 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1743 break;
1744
7d466069 1745 case EM_PJ:
2b0337b0 1746 case EM_PJ_OLD:
7d466069
ILT
1747 rtype = elf_pj_reloc_type (type);
1748 break;
800eeca4
JW
1749 case EM_IA_64:
1750 rtype = elf_ia64_reloc_type (type);
1751 break;
1b61cf92
HPN
1752
1753 case EM_CRIS:
1754 rtype = elf_cris_reloc_type (type);
1755 break;
535c37ff 1756
f954747f
AM
1757 case EM_860:
1758 rtype = elf_i860_reloc_type (type);
1759 break;
1760
bcedfee6 1761 case EM_X86_64:
8a9036a4 1762 case EM_L1OM:
7a9068fe 1763 case EM_K1OM:
bcedfee6
NC
1764 rtype = elf_x86_64_reloc_type (type);
1765 break;
a85d7ed0 1766
f954747f
AM
1767 case EM_S370:
1768 rtype = i370_reloc_type (type);
1769 break;
1770
53c7db4b
KH
1771 case EM_S390_OLD:
1772 case EM_S390:
1773 rtype = elf_s390_reloc_type (type);
1774 break;
93fbbb04 1775
1c0d3aa6
NC
1776 case EM_SCORE:
1777 rtype = elf_score_reloc_type (type);
1778 break;
1779
93fbbb04
GK
1780 case EM_XSTORMY16:
1781 rtype = elf_xstormy16_reloc_type (type);
1782 break;
179d3252 1783
1fe1f39c
NC
1784 case EM_CRX:
1785 rtype = elf_crx_reloc_type (type);
1786 break;
1787
179d3252
JT
1788 case EM_VAX:
1789 rtype = elf_vax_reloc_type (type);
1790 break;
1e4cf259 1791
619ed720
EB
1792 case EM_VISIUM:
1793 rtype = elf_visium_reloc_type (type);
1794 break;
1795
aca4efc7
JM
1796 case EM_BPF:
1797 rtype = elf_bpf_reloc_type (type);
1798 break;
1799
cfb8c092
NC
1800 case EM_ADAPTEVA_EPIPHANY:
1801 rtype = elf_epiphany_reloc_type (type);
1802 break;
1803
1e4cf259
NC
1804 case EM_IP2K:
1805 case EM_IP2K_OLD:
1806 rtype = elf_ip2k_reloc_type (type);
1807 break;
3b36097d
SC
1808
1809 case EM_IQ2000:
1810 rtype = elf_iq2000_reloc_type (type);
1811 break;
88da6820
NC
1812
1813 case EM_XTENSA_OLD:
1814 case EM_XTENSA:
1815 rtype = elf_xtensa_reloc_type (type);
1816 break;
a34e3ecb 1817
84e94c90
NC
1818 case EM_LATTICEMICO32:
1819 rtype = elf_lm32_reloc_type (type);
1820 break;
1821
ff7eeb89 1822 case EM_M32C_OLD:
49f58d10
JB
1823 case EM_M32C:
1824 rtype = elf_m32c_reloc_type (type);
1825 break;
1826
d031aafb
NS
1827 case EM_MT:
1828 rtype = elf_mt_reloc_type (type);
a34e3ecb 1829 break;
1d65ded4
CM
1830
1831 case EM_BLACKFIN:
1832 rtype = elf_bfin_reloc_type (type);
1833 break;
15ab5209
DB
1834
1835 case EM_CYGNUS_MEP:
1836 rtype = elf_mep_reloc_type (type);
1837 break;
60bca95a
NC
1838
1839 case EM_CR16:
1840 rtype = elf_cr16_reloc_type (type);
1841 break;
dd24e3da 1842
7ba29e2a
NC
1843 case EM_MICROBLAZE:
1844 case EM_MICROBLAZE_OLD:
1845 rtype = elf_microblaze_reloc_type (type);
1846 break;
c7927a3c 1847
99c513f6
DD
1848 case EM_RL78:
1849 rtype = elf_rl78_reloc_type (type);
1850 break;
1851
c7927a3c
NC
1852 case EM_RX:
1853 rtype = elf_rx_reloc_type (type);
1854 break;
c29aca4a 1855
a3c62988
NC
1856 case EM_METAG:
1857 rtype = elf_metag_reloc_type (type);
1858 break;
1859
40b36596
JM
1860 case EM_TI_C6000:
1861 rtype = elf_tic6x_reloc_type (type);
1862 break;
aa137e4d
NC
1863
1864 case EM_TILEGX:
1865 rtype = elf_tilegx_reloc_type (type);
1866 break;
1867
1868 case EM_TILEPRO:
1869 rtype = elf_tilepro_reloc_type (type);
1870 break;
f6c1a2d5 1871
f96bd6c2
PC
1872 case EM_WEBASSEMBLY:
1873 rtype = elf_wasm32_reloc_type (type);
1874 break;
1875
f6c1a2d5
NC
1876 case EM_XGATE:
1877 rtype = elf_xgate_reloc_type (type);
1878 break;
36591ba1
SL
1879
1880 case EM_ALTERA_NIOS2:
1881 rtype = elf_nios2_reloc_type (type);
1882 break;
2b100bb5
DD
1883
1884 case EM_TI_PRU:
1885 rtype = elf_pru_reloc_type (type);
1886 break;
fe944acf
FT
1887
1888 case EM_NFP:
1889 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1890 rtype = elf_nfp3200_reloc_type (type);
1891 else
1892 rtype = elf_nfp_reloc_type (type);
1893 break;
6655dba2
SB
1894
1895 case EM_Z80:
1896 rtype = elf_z80_reloc_type (type);
1897 break;
e9a0721f 1898
1899 case EM_LOONGARCH:
1900 rtype = elf_loongarch_reloc_type (type);
1901 break;
1902
0c857ef4
SM
1903 case EM_AMDGPU:
1904 rtype = elf_amdgpu_reloc_type (type);
1905 break;
252b5132
RH
1906 }
1907
1908 if (rtype == NULL)
39dbeff8 1909 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1910 else
5c144731 1911 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1912
dda8d76d 1913 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1914 && rtype != NULL
7ace3541 1915 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1916 && rel_type == reltype_rela)
7ace3541
RH
1917 {
1918 switch (rels[i].r_addend)
1919 {
1920 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1921 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1922 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1923 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1924 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1925 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1926 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1927 default: rtype = NULL;
1928 }
32ec8896 1929
7ace3541
RH
1930 if (rtype)
1931 printf (" (%s)", rtype);
1932 else
1933 {
1934 putchar (' ');
1935 printf (_("<unknown addend: %lx>"),
1936 (unsigned long) rels[i].r_addend);
015dc7e1 1937 res = false;
7ace3541
RH
1938 }
1939 }
1940 else if (symtab_index)
252b5132 1941 {
af3fc3bc 1942 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1943 {
27a45f42
AS
1944 error (_(" bad symbol index: %08lx in reloc\n"),
1945 (unsigned long) symtab_index);
015dc7e1 1946 res = false;
32ec8896 1947 }
af3fc3bc 1948 else
19936277 1949 {
2cf0635d 1950 Elf_Internal_Sym * psym;
bb4d2ac2
L
1951 const char * version_string;
1952 enum versioned_symbol_info sym_info;
1953 unsigned short vna_other;
19936277 1954
af3fc3bc 1955 psym = symtab + symtab_index;
103f02d3 1956
bb4d2ac2 1957 version_string
dda8d76d 1958 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1959 strtab, strtablen,
1960 symtab_index,
1961 psym,
1962 &sym_info,
1963 &vna_other);
1964
af3fc3bc 1965 printf (" ");
171191ba 1966
d8045f23
NC
1967 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1968 {
1969 const char * name;
1970 unsigned int len;
1971 unsigned int width = is_32bit_elf ? 8 : 14;
1972
1973 /* Relocations against GNU_IFUNC symbols do not use the value
1974 of the symbol as the address to relocate against. Instead
1975 they invoke the function named by the symbol and use its
1976 result as the address for relocation.
1977
1978 To indicate this to the user, do not display the value of
1979 the symbol in the "Symbols's Value" field. Instead show
1980 its name followed by () as a hint that the symbol is
1981 invoked. */
1982
1983 if (strtab == NULL
1984 || psym->st_name == 0
1985 || psym->st_name >= strtablen)
1986 name = "??";
1987 else
1988 name = strtab + psym->st_name;
1989
1990 len = print_symbol (width, name);
bb4d2ac2
L
1991 if (version_string)
1992 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1993 version_string);
d8045f23
NC
1994 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1995 }
1996 else
1997 {
1998 print_vma (psym->st_value, LONG_HEX);
171191ba 1999
d8045f23
NC
2000 printf (is_32bit_elf ? " " : " ");
2001 }
103f02d3 2002
af3fc3bc 2003 if (psym->st_name == 0)
f1ef08cb 2004 {
2cf0635d 2005 const char * sec_name = "<null>";
f1ef08cb
AM
2006 char name_buf[40];
2007
2008 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2009 {
b9af6379
AM
2010 if (psym->st_shndx < filedata->file_header.e_shnum
2011 && filedata->section_headers != NULL)
84714f86
AM
2012 sec_name = section_name_print (filedata,
2013 filedata->section_headers
b9e920ec 2014 + psym->st_shndx);
f1ef08cb
AM
2015 else if (psym->st_shndx == SHN_ABS)
2016 sec_name = "ABS";
2017 else if (psym->st_shndx == SHN_COMMON)
2018 sec_name = "COMMON";
dda8d76d 2019 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2020 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2021 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2022 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2023 sec_name = "SCOMMON";
dda8d76d 2024 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2025 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2026 sec_name = "SUNDEF";
dda8d76d
NC
2027 else if ((filedata->file_header.e_machine == EM_X86_64
2028 || filedata->file_header.e_machine == EM_L1OM
2029 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2030 && psym->st_shndx == SHN_X86_64_LCOMMON)
2031 sec_name = "LARGE_COMMON";
dda8d76d
NC
2032 else if (filedata->file_header.e_machine == EM_IA_64
2033 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2034 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2035 sec_name = "ANSI_COM";
dda8d76d 2036 else if (is_ia64_vms (filedata)
148b93f2
NC
2037 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2038 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2039 else
2040 {
2041 sprintf (name_buf, "<section 0x%x>",
2042 (unsigned int) psym->st_shndx);
2043 sec_name = name_buf;
2044 }
2045 }
2046 print_symbol (22, sec_name);
2047 }
af3fc3bc 2048 else if (strtab == NULL)
d79b3d50 2049 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2050 else if (psym->st_name >= strtablen)
32ec8896 2051 {
27a45f42
AS
2052 error (_("<corrupt string table index: %3ld>\n"),
2053 psym->st_name);
015dc7e1 2054 res = false;
32ec8896 2055 }
af3fc3bc 2056 else
bb4d2ac2
L
2057 {
2058 print_symbol (22, strtab + psym->st_name);
2059 if (version_string)
2060 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2061 version_string);
2062 }
103f02d3 2063
a7fd1186 2064 if (rel_type == reltype_rela)
171191ba 2065 {
7360e63f 2066 bfd_vma off = rels[i].r_addend;
171191ba 2067
7360e63f 2068 if ((bfd_signed_vma) off < 0)
b8281767 2069 printf (" - %" PRIx64, (uint64_t) -off);
171191ba 2070 else
b8281767 2071 printf (" + %" PRIx64, (uint64_t) off);
171191ba 2072 }
19936277 2073 }
252b5132 2074 }
a7fd1186 2075 else if (rel_type == reltype_rela)
f7a99963 2076 {
7360e63f 2077 bfd_vma off = rels[i].r_addend;
e04d7088
L
2078
2079 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2080 if ((bfd_signed_vma) off < 0)
b8281767 2081 printf ("-%" PRIx64, (uint64_t) -off);
e04d7088 2082 else
b8281767 2083 printf ("%" PRIx64, (uint64_t) off);
f7a99963 2084 }
252b5132 2085
dda8d76d 2086 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2087 && rtype != NULL
2088 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2089 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2090
252b5132 2091 putchar ('\n');
2c71103e 2092
aca88567 2093#ifdef BFD64
dda8d76d 2094 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2095 {
91d6fa6a
NC
2096 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2097 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2098 const char * rtype2 = elf_mips_reloc_type (type2);
2099 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2100
2c71103e
NC
2101 printf (" Type2: ");
2102
2103 if (rtype2 == NULL)
39dbeff8
AM
2104 printf (_("unrecognized: %-7lx"),
2105 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2106 else
2107 printf ("%-17.17s", rtype2);
2108
18bd398b 2109 printf ("\n Type3: ");
2c71103e
NC
2110
2111 if (rtype3 == NULL)
39dbeff8
AM
2112 printf (_("unrecognized: %-7lx"),
2113 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2114 else
2115 printf ("%-17.17s", rtype3);
2116
53c7db4b 2117 putchar ('\n');
2c71103e 2118 }
aca88567 2119#endif /* BFD64 */
252b5132
RH
2120 }
2121
c8286bd1 2122 free (rels);
32ec8896
NC
2123
2124 return res;
252b5132
RH
2125}
2126
37c18eed
SD
2127static const char *
2128get_aarch64_dynamic_type (unsigned long type)
2129{
2130 switch (type)
2131 {
2132 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2133 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2134 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2135 default:
2136 return NULL;
2137 }
2138}
2139
252b5132 2140static const char *
d3ba0551 2141get_mips_dynamic_type (unsigned long type)
252b5132
RH
2142{
2143 switch (type)
2144 {
2145 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2146 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2147 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2148 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2149 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2150 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2151 case DT_MIPS_MSYM: return "MIPS_MSYM";
2152 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2153 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2154 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2155 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2156 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2157 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2158 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2159 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2160 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2161 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2162 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2163 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2164 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2165 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2166 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2167 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2168 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2169 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2170 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2171 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2172 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2173 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2174 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2175 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2176 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2177 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2178 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2179 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2180 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2181 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2182 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2183 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2184 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2185 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2186 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2187 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2188 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2189 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2190 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2191 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2192 default:
2193 return NULL;
2194 }
2195}
2196
9a097730 2197static const char *
d3ba0551 2198get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2199{
2200 switch (type)
2201 {
2202 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2203 default:
2204 return NULL;
2205 }
103f02d3
UD
2206}
2207
7490d522
AM
2208static const char *
2209get_ppc_dynamic_type (unsigned long type)
2210{
2211 switch (type)
2212 {
a7f2871e 2213 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2214 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2215 default:
2216 return NULL;
2217 }
2218}
2219
f1cb7e17 2220static const char *
d3ba0551 2221get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2222{
2223 switch (type)
2224 {
a7f2871e
AM
2225 case DT_PPC64_GLINK: return "PPC64_GLINK";
2226 case DT_PPC64_OPD: return "PPC64_OPD";
2227 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2228 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2229 default:
2230 return NULL;
2231 }
2232}
2233
103f02d3 2234static const char *
d3ba0551 2235get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2236{
2237 switch (type)
2238 {
2239 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2240 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2241 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2242 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2243 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2244 case DT_HP_PREINIT: return "HP_PREINIT";
2245 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2246 case DT_HP_NEEDED: return "HP_NEEDED";
2247 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2248 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2249 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2250 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2251 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2252 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2253 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2254 case DT_HP_FILTERED: return "HP_FILTERED";
2255 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2256 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2257 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2258 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2259 case DT_PLT: return "PLT";
2260 case DT_PLT_SIZE: return "PLT_SIZE";
2261 case DT_DLT: return "DLT";
2262 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2263 default:
2264 return NULL;
2265 }
2266}
9a097730 2267
ecc51f48 2268static const char *
d3ba0551 2269get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2270{
2271 switch (type)
2272 {
148b93f2
NC
2273 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2274 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2275 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2276 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2277 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2278 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2279 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2280 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2281 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2282 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2283 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2284 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2285 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2286 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2287 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2288 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2289 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2290 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2291 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2292 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2293 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2294 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2295 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2296 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2297 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2298 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2299 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2300 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2301 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2302 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2303 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2304 default:
2305 return NULL;
2306 }
2307}
2308
fd85a6a1
NC
2309static const char *
2310get_solaris_section_type (unsigned long type)
2311{
2312 switch (type)
2313 {
2314 case 0x6fffffee: return "SUNW_ancillary";
2315 case 0x6fffffef: return "SUNW_capchain";
2316 case 0x6ffffff0: return "SUNW_capinfo";
2317 case 0x6ffffff1: return "SUNW_symsort";
2318 case 0x6ffffff2: return "SUNW_tlssort";
2319 case 0x6ffffff3: return "SUNW_LDYNSYM";
2320 case 0x6ffffff4: return "SUNW_dof";
2321 case 0x6ffffff5: return "SUNW_cap";
2322 case 0x6ffffff6: return "SUNW_SIGNATURE";
2323 case 0x6ffffff7: return "SUNW_ANNOTATE";
2324 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2325 case 0x6ffffff9: return "SUNW_DEBUG";
2326 case 0x6ffffffa: return "SUNW_move";
2327 case 0x6ffffffb: return "SUNW_COMDAT";
2328 case 0x6ffffffc: return "SUNW_syminfo";
2329 case 0x6ffffffd: return "SUNW_verdef";
2330 case 0x6ffffffe: return "SUNW_verneed";
2331 case 0x6fffffff: return "SUNW_versym";
2332 case 0x70000000: return "SPARC_GOTDATA";
2333 default: return NULL;
2334 }
2335}
2336
fabcb361
RH
2337static const char *
2338get_alpha_dynamic_type (unsigned long type)
2339{
2340 switch (type)
2341 {
2342 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2343 default: return NULL;
fabcb361
RH
2344 }
2345}
2346
1c0d3aa6
NC
2347static const char *
2348get_score_dynamic_type (unsigned long type)
2349{
2350 switch (type)
2351 {
2352 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2353 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2354 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2355 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2356 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2357 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2358 default: return NULL;
1c0d3aa6
NC
2359 }
2360}
2361
40b36596
JM
2362static const char *
2363get_tic6x_dynamic_type (unsigned long type)
2364{
2365 switch (type)
2366 {
2367 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2368 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2369 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2370 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2371 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2372 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2373 default: return NULL;
40b36596
JM
2374 }
2375}
1c0d3aa6 2376
36591ba1
SL
2377static const char *
2378get_nios2_dynamic_type (unsigned long type)
2379{
2380 switch (type)
2381 {
2382 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2383 default: return NULL;
36591ba1
SL
2384 }
2385}
2386
fd85a6a1
NC
2387static const char *
2388get_solaris_dynamic_type (unsigned long type)
2389{
2390 switch (type)
2391 {
2392 case 0x6000000d: return "SUNW_AUXILIARY";
2393 case 0x6000000e: return "SUNW_RTLDINF";
2394 case 0x6000000f: return "SUNW_FILTER";
2395 case 0x60000010: return "SUNW_CAP";
2396 case 0x60000011: return "SUNW_SYMTAB";
2397 case 0x60000012: return "SUNW_SYMSZ";
2398 case 0x60000013: return "SUNW_SORTENT";
2399 case 0x60000014: return "SUNW_SYMSORT";
2400 case 0x60000015: return "SUNW_SYMSORTSZ";
2401 case 0x60000016: return "SUNW_TLSSORT";
2402 case 0x60000017: return "SUNW_TLSSORTSZ";
2403 case 0x60000018: return "SUNW_CAPINFO";
2404 case 0x60000019: return "SUNW_STRPAD";
2405 case 0x6000001a: return "SUNW_CAPCHAIN";
2406 case 0x6000001b: return "SUNW_LDMACH";
2407 case 0x6000001d: return "SUNW_CAPCHAINENT";
2408 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2409 case 0x60000021: return "SUNW_PARENT";
2410 case 0x60000023: return "SUNW_ASLR";
2411 case 0x60000025: return "SUNW_RELAX";
2412 case 0x60000029: return "SUNW_NXHEAP";
2413 case 0x6000002b: return "SUNW_NXSTACK";
2414
2415 case 0x70000001: return "SPARC_REGISTER";
2416 case 0x7ffffffd: return "AUXILIARY";
2417 case 0x7ffffffe: return "USED";
2418 case 0x7fffffff: return "FILTER";
2419
15f205b1 2420 default: return NULL;
fd85a6a1
NC
2421 }
2422}
2423
8155b853
NC
2424static const char *
2425get_riscv_dynamic_type (unsigned long type)
2426{
2427 switch (type)
2428 {
2429 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2430 default:
2431 return NULL;
2432 }
2433}
2434
252b5132 2435static const char *
dda8d76d 2436get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2437{
e9e44622 2438 static char buff[64];
252b5132
RH
2439
2440 switch (type)
2441 {
2442 case DT_NULL: return "NULL";
2443 case DT_NEEDED: return "NEEDED";
2444 case DT_PLTRELSZ: return "PLTRELSZ";
2445 case DT_PLTGOT: return "PLTGOT";
2446 case DT_HASH: return "HASH";
2447 case DT_STRTAB: return "STRTAB";
2448 case DT_SYMTAB: return "SYMTAB";
2449 case DT_RELA: return "RELA";
2450 case DT_RELASZ: return "RELASZ";
2451 case DT_RELAENT: return "RELAENT";
2452 case DT_STRSZ: return "STRSZ";
2453 case DT_SYMENT: return "SYMENT";
2454 case DT_INIT: return "INIT";
2455 case DT_FINI: return "FINI";
2456 case DT_SONAME: return "SONAME";
2457 case DT_RPATH: return "RPATH";
2458 case DT_SYMBOLIC: return "SYMBOLIC";
2459 case DT_REL: return "REL";
2460 case DT_RELSZ: return "RELSZ";
2461 case DT_RELENT: return "RELENT";
dd207c13
FS
2462 case DT_RELR: return "RELR";
2463 case DT_RELRSZ: return "RELRSZ";
2464 case DT_RELRENT: return "RELRENT";
252b5132
RH
2465 case DT_PLTREL: return "PLTREL";
2466 case DT_DEBUG: return "DEBUG";
2467 case DT_TEXTREL: return "TEXTREL";
2468 case DT_JMPREL: return "JMPREL";
2469 case DT_BIND_NOW: return "BIND_NOW";
2470 case DT_INIT_ARRAY: return "INIT_ARRAY";
2471 case DT_FINI_ARRAY: return "FINI_ARRAY";
2472 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2473 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2474 case DT_RUNPATH: return "RUNPATH";
2475 case DT_FLAGS: return "FLAGS";
2d0e6f43 2476
d1133906
NC
2477 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2478 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2479 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2480
05107a46 2481 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2482 case DT_PLTPADSZ: return "PLTPADSZ";
2483 case DT_MOVEENT: return "MOVEENT";
2484 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2485 case DT_FEATURE: return "FEATURE";
252b5132
RH
2486 case DT_POSFLAG_1: return "POSFLAG_1";
2487 case DT_SYMINSZ: return "SYMINSZ";
2488 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2489
252b5132 2490 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2491 case DT_CONFIG: return "CONFIG";
2492 case DT_DEPAUDIT: return "DEPAUDIT";
2493 case DT_AUDIT: return "AUDIT";
2494 case DT_PLTPAD: return "PLTPAD";
2495 case DT_MOVETAB: return "MOVETAB";
252b5132 2496 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2497
252b5132 2498 case DT_VERSYM: return "VERSYM";
103f02d3 2499
67a4f2b7
AO
2500 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2501 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2502 case DT_RELACOUNT: return "RELACOUNT";
2503 case DT_RELCOUNT: return "RELCOUNT";
2504 case DT_FLAGS_1: return "FLAGS_1";
2505 case DT_VERDEF: return "VERDEF";
2506 case DT_VERDEFNUM: return "VERDEFNUM";
2507 case DT_VERNEED: return "VERNEED";
2508 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2509
019148e4 2510 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2511 case DT_USED: return "USED";
2512 case DT_FILTER: return "FILTER";
103f02d3 2513
047b2264
JJ
2514 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2515 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2516 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2517 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2518 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2519 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2520 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2521
252b5132
RH
2522 default:
2523 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2524 {
2cf0635d 2525 const char * result;
103f02d3 2526
dda8d76d 2527 switch (filedata->file_header.e_machine)
252b5132 2528 {
37c18eed
SD
2529 case EM_AARCH64:
2530 result = get_aarch64_dynamic_type (type);
2531 break;
252b5132 2532 case EM_MIPS:
4fe85591 2533 case EM_MIPS_RS3_LE:
252b5132
RH
2534 result = get_mips_dynamic_type (type);
2535 break;
9a097730
RH
2536 case EM_SPARCV9:
2537 result = get_sparc64_dynamic_type (type);
2538 break;
7490d522
AM
2539 case EM_PPC:
2540 result = get_ppc_dynamic_type (type);
2541 break;
f1cb7e17
AM
2542 case EM_PPC64:
2543 result = get_ppc64_dynamic_type (type);
2544 break;
ecc51f48
NC
2545 case EM_IA_64:
2546 result = get_ia64_dynamic_type (type);
2547 break;
fabcb361
RH
2548 case EM_ALPHA:
2549 result = get_alpha_dynamic_type (type);
2550 break;
1c0d3aa6
NC
2551 case EM_SCORE:
2552 result = get_score_dynamic_type (type);
2553 break;
40b36596
JM
2554 case EM_TI_C6000:
2555 result = get_tic6x_dynamic_type (type);
2556 break;
36591ba1
SL
2557 case EM_ALTERA_NIOS2:
2558 result = get_nios2_dynamic_type (type);
2559 break;
8155b853
NC
2560 case EM_RISCV:
2561 result = get_riscv_dynamic_type (type);
2562 break;
252b5132 2563 default:
dda8d76d 2564 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2565 result = get_solaris_dynamic_type (type);
2566 else
2567 result = NULL;
252b5132
RH
2568 break;
2569 }
2570
2571 if (result != NULL)
2572 return result;
2573
e9e44622 2574 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2575 }
eec8f817 2576 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2577 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2578 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2579 {
2cf0635d 2580 const char * result;
103f02d3 2581
dda8d76d 2582 switch (filedata->file_header.e_machine)
103f02d3
UD
2583 {
2584 case EM_PARISC:
2585 result = get_parisc_dynamic_type (type);
2586 break;
148b93f2
NC
2587 case EM_IA_64:
2588 result = get_ia64_dynamic_type (type);
2589 break;
103f02d3 2590 default:
dda8d76d 2591 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2592 result = get_solaris_dynamic_type (type);
2593 else
2594 result = NULL;
103f02d3
UD
2595 break;
2596 }
2597
2598 if (result != NULL)
2599 return result;
2600
e9e44622
JJ
2601 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2602 type);
103f02d3 2603 }
252b5132 2604 else
e9e44622 2605 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2606
252b5132
RH
2607 return buff;
2608 }
2609}
2610
93df3340
AM
2611static bool get_program_headers (Filedata *);
2612static bool get_dynamic_section (Filedata *);
2613
2614static void
2615locate_dynamic_section (Filedata *filedata)
2616{
2617 unsigned long dynamic_addr = 0;
2618 bfd_size_type dynamic_size = 0;
2619
2620 if (filedata->file_header.e_phnum != 0
2621 && get_program_headers (filedata))
2622 {
2623 Elf_Internal_Phdr *segment;
2624 unsigned int i;
2625
2626 for (i = 0, segment = filedata->program_headers;
2627 i < filedata->file_header.e_phnum;
2628 i++, segment++)
2629 {
2630 if (segment->p_type == PT_DYNAMIC)
2631 {
2632 dynamic_addr = segment->p_offset;
2633 dynamic_size = segment->p_filesz;
2634
2635 if (filedata->section_headers != NULL)
2636 {
2637 Elf_Internal_Shdr *sec;
2638
2639 sec = find_section (filedata, ".dynamic");
2640 if (sec != NULL)
2641 {
2642 if (sec->sh_size == 0
2643 || sec->sh_type == SHT_NOBITS)
2644 {
2645 dynamic_addr = 0;
2646 dynamic_size = 0;
2647 }
2648 else
2649 {
2650 dynamic_addr = sec->sh_offset;
2651 dynamic_size = sec->sh_size;
2652 }
2653 }
2654 }
2655
2656 if (dynamic_addr > filedata->file_size
2657 || (dynamic_size > filedata->file_size - dynamic_addr))
2658 {
2659 dynamic_addr = 0;
2660 dynamic_size = 0;
2661 }
2662 break;
2663 }
2664 }
2665 }
2666 filedata->dynamic_addr = dynamic_addr;
2667 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2668}
2669
2670static bool
2671is_pie (Filedata *filedata)
2672{
2673 Elf_Internal_Dyn *entry;
2674
2675 if (filedata->dynamic_size == 0)
2676 locate_dynamic_section (filedata);
2677 if (filedata->dynamic_size <= 1)
2678 return false;
2679
2680 if (!get_dynamic_section (filedata))
2681 return false;
2682
2683 for (entry = filedata->dynamic_section;
2684 entry < filedata->dynamic_section + filedata->dynamic_nent;
2685 entry++)
2686 {
2687 if (entry->d_tag == DT_FLAGS_1)
2688 {
2689 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2690 return true;
2691 break;
2692 }
2693 }
2694 return false;
2695}
2696
252b5132 2697static char *
93df3340 2698get_file_type (Filedata *filedata)
252b5132 2699{
93df3340 2700 unsigned e_type = filedata->file_header.e_type;
89246a0e 2701 static char buff[64];
252b5132
RH
2702
2703 switch (e_type)
2704 {
32ec8896
NC
2705 case ET_NONE: return _("NONE (None)");
2706 case ET_REL: return _("REL (Relocatable file)");
2707 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2708 case ET_DYN:
2709 if (is_pie (filedata))
2710 return _("DYN (Position-Independent Executable file)");
2711 else
2712 return _("DYN (Shared object file)");
32ec8896 2713 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2714
2715 default:
2716 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2717 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2718 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2719 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2720 else
e9e44622 2721 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2722 return buff;
2723 }
2724}
2725
2726static char *
d3ba0551 2727get_machine_name (unsigned e_machine)
252b5132 2728{
b34976b6 2729 static char buff[64]; /* XXX */
252b5132
RH
2730
2731 switch (e_machine)
2732 {
55e22ca8
NC
2733 /* Please keep this switch table sorted by increasing EM_ value. */
2734 /* 0 */
c45021f2
NC
2735 case EM_NONE: return _("None");
2736 case EM_M32: return "WE32100";
2737 case EM_SPARC: return "Sparc";
2738 case EM_386: return "Intel 80386";
2739 case EM_68K: return "MC68000";
2740 case EM_88K: return "MC88000";
22abe556 2741 case EM_IAMCU: return "Intel MCU";
fb70ec17 2742 case EM_860: return "Intel 80860";
c45021f2
NC
2743 case EM_MIPS: return "MIPS R3000";
2744 case EM_S370: return "IBM System/370";
55e22ca8 2745 /* 10 */
7036c0e1 2746 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2747 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2748 case EM_PARISC: return "HPPA";
55e22ca8 2749 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2750 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2751 case EM_960: return "Intel 80960";
c45021f2 2752 case EM_PPC: return "PowerPC";
55e22ca8 2753 /* 20 */
285d1771 2754 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2755 case EM_S390_OLD:
2756 case EM_S390: return "IBM S/390";
2757 case EM_SPU: return "SPU";
2758 /* 30 */
2759 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2760 case EM_FR20: return "Fujitsu FR20";
2761 case EM_RH32: return "TRW RH32";
b34976b6 2762 case EM_MCORE: return "MCORE";
55e22ca8 2763 /* 40 */
7036c0e1
AJ
2764 case EM_ARM: return "ARM";
2765 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2766 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2767 case EM_SPARCV9: return "Sparc v9";
2768 case EM_TRICORE: return "Siemens Tricore";
584da044 2769 case EM_ARC: return "ARC";
c2dcd04e
NC
2770 case EM_H8_300: return "Renesas H8/300";
2771 case EM_H8_300H: return "Renesas H8/300H";
2772 case EM_H8S: return "Renesas H8S";
2773 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2774 /* 50 */
30800947 2775 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2776 case EM_MIPS_X: return "Stanford MIPS-X";
2777 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2778 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2779 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2780 case EM_PCP: return "Siemens PCP";
2781 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2782 case EM_NDR1: return "Denso NDR1 microprocesspr";
2783 case EM_STARCORE: return "Motorola Star*Core processor";
2784 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2785 /* 60 */
7036c0e1
AJ
2786 case EM_ST100: return "STMicroelectronics ST100 processor";
2787 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2788 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2789 case EM_PDSP: return "Sony DSP processor";
2790 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2791 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2792 case EM_FX66: return "Siemens FX66 microcontroller";
2793 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2794 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2795 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2796 /* 70 */
7036c0e1
AJ
2797 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2798 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2799 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2800 case EM_SVX: return "Silicon Graphics SVx";
2801 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2802 case EM_VAX: return "Digital VAX";
1b61cf92 2803 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2804 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2805 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2806 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2807 /* 80 */
b34976b6 2808 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2809 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2810 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2811 case EM_AVR_OLD:
2812 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2813 case EM_CYGNUS_FR30:
2814 case EM_FR30: return "Fujitsu FR30";
2815 case EM_CYGNUS_D10V:
2816 case EM_D10V: return "d10v";
2817 case EM_CYGNUS_D30V:
2818 case EM_D30V: return "d30v";
2819 case EM_CYGNUS_V850:
2820 case EM_V850: return "Renesas V850";
2821 case EM_CYGNUS_M32R:
2822 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2823 case EM_CYGNUS_MN10300:
2824 case EM_MN10300: return "mn10300";
2825 /* 90 */
2826 case EM_CYGNUS_MN10200:
2827 case EM_MN10200: return "mn10200";
2828 case EM_PJ: return "picoJava";
73589c9d 2829 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2830 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2831 case EM_XTENSA_OLD:
2832 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2833 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2834 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2835 case EM_NS32K: return "National Semiconductor 32000 series";
2836 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2837 case EM_SNP1K: return "Trebia SNP 1000 processor";
2838 /* 100 */
9abca702 2839 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2840 case EM_IP2K_OLD:
2841 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2842 case EM_MAX: return "MAX Processor";
2843 case EM_CR: return "National Semiconductor CompactRISC";
2844 case EM_F2MC16: return "Fujitsu F2MC16";
2845 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2846 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2847 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2848 case EM_SEP: return "Sharp embedded microprocessor";
2849 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2850 /* 110 */
11636f9e
JM
2851 case EM_UNICORE: return "Unicore";
2852 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2853 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2854 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2855 case EM_CRX: return "National Semiconductor CRX microprocessor";
2856 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2857 case EM_C166:
d70c5fc7 2858 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2859 case EM_M16C: return "Renesas M16C series microprocessors";
2860 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2861 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2862 /* 120 */
2863 case EM_M32C: return "Renesas M32c";
2864 /* 130 */
11636f9e
JM
2865 case EM_TSK3000: return "Altium TSK3000 core";
2866 case EM_RS08: return "Freescale RS08 embedded processor";
2867 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2868 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2869 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2870 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2871 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2872 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2873 /* 140 */
11636f9e
JM
2874 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2875 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2876 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2877 case EM_TI_PRU: return "TI PRU I/O processor";
2878 /* 160 */
11636f9e
JM
2879 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2880 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2881 case EM_R32C: return "Renesas R32C series microprocessors";
2882 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2883 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2884 case EM_8051: return "Intel 8051 and variants";
2885 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2886 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2887 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2888 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2889 /* 170 */
11636f9e
JM
2890 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2891 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2892 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2893 case EM_RX: return "Renesas RX";
a3c62988 2894 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2895 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2896 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2897 case EM_CR16:
2898 case EM_MICROBLAZE:
2899 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2900 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2901 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2902 /* 180 */
2903 case EM_L1OM: return "Intel L1OM";
2904 case EM_K1OM: return "Intel K1OM";
2905 case EM_INTEL182: return "Intel (reserved)";
2906 case EM_AARCH64: return "AArch64";
2907 case EM_ARM184: return "ARM (reserved)";
2908 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2909 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2910 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2911 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2912 /* 190 */
11636f9e 2913 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2914 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2915 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2916 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2917 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2918 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2919 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2920 case EM_RL78: return "Renesas RL78";
6d913794 2921 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2922 case EM_78K0R: return "Renesas 78K0R";
2923 /* 200 */
6d913794 2924 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2925 case EM_BA1: return "Beyond BA1 CPU architecture";
2926 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2927 case EM_XCORE: return "XMOS xCORE processor family";
2928 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2929 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2930 /* 210 */
6d913794
NC
2931 case EM_KM32: return "KM211 KM32 32-bit processor";
2932 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2933 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2934 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2935 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2936 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2937 case EM_COGE: return "Cognitive Smart Memory Processor";
2938 case EM_COOL: return "Bluechip Systems CoolEngine";
2939 case EM_NORC: return "Nanoradio Optimized RISC";
2940 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2941 /* 220 */
15f205b1 2942 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2943 case EM_VISIUM: return "CDS VISIUMcore processor";
2944 case EM_FT32: return "FTDI Chip FT32";
2945 case EM_MOXIE: return "Moxie";
2946 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2947 /* 230 (all reserved) */
2948 /* 240 */
55e22ca8
NC
2949 case EM_RISCV: return "RISC-V";
2950 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2951 case EM_CEVA: return "CEVA Processor Architecture Family";
2952 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2953 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2954 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2955 case EM_IMG1: return "Imagination Technologies";
2956 /* 250 */
fe944acf 2957 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2958 case EM_VE: return "NEC Vector Engine";
2959 case EM_CSKY: return "C-SKY";
2960 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2961 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2962 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2963 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2964 case EM_65816: return "WDC 65816/65C816";
01a8c731 2965 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2966 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2967
2968 /* Large numbers... */
2969 case EM_MT: return "Morpho Techologies MT processor";
2970 case EM_ALPHA: return "Alpha";
2971 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2972 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2973 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2974 case EM_IQ2000: return "Vitesse IQ2000";
2975 case EM_M32C_OLD:
2976 case EM_NIOS32: return "Altera Nios";
2977 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2978 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2979 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2980 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2981
252b5132 2982 default:
35d9dd2f 2983 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2984 return buff;
2985 }
2986}
2987
a9522a21
AB
2988static void
2989decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2990{
2991 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2992 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2993 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2994 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2995 architectures.
2996
2997 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2998 but also sets a specific architecture type in the e_flags field.
2999
3000 However, when decoding the flags we don't worry if we see an
3001 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3002 ARCEM architecture type. */
3003
3004 switch (e_flags & EF_ARC_MACH_MSK)
3005 {
3006 /* We only expect these to occur for EM_ARC_COMPACT2. */
3007 case EF_ARC_CPU_ARCV2EM:
3008 strcat (buf, ", ARC EM");
3009 break;
3010 case EF_ARC_CPU_ARCV2HS:
3011 strcat (buf, ", ARC HS");
3012 break;
3013
3014 /* We only expect these to occur for EM_ARC_COMPACT. */
3015 case E_ARC_MACH_ARC600:
3016 strcat (buf, ", ARC600");
3017 break;
3018 case E_ARC_MACH_ARC601:
3019 strcat (buf, ", ARC601");
3020 break;
3021 case E_ARC_MACH_ARC700:
3022 strcat (buf, ", ARC700");
3023 break;
3024
3025 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3026 new ELF with new architecture being read by an old version of
3027 readelf, or (c) An ELF built with non-GNU compiler that does not
3028 set the architecture in the e_flags. */
3029 default:
3030 if (e_machine == EM_ARC_COMPACT)
3031 strcat (buf, ", Unknown ARCompact");
3032 else
3033 strcat (buf, ", Unknown ARC");
3034 break;
3035 }
3036
3037 switch (e_flags & EF_ARC_OSABI_MSK)
3038 {
3039 case E_ARC_OSABI_ORIG:
3040 strcat (buf, ", (ABI:legacy)");
3041 break;
3042 case E_ARC_OSABI_V2:
3043 strcat (buf, ", (ABI:v2)");
3044 break;
3045 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3046 case E_ARC_OSABI_V3:
3047 strcat (buf, ", v3 no-legacy-syscalls ABI");
3048 break;
53a346d8
CZ
3049 case E_ARC_OSABI_V4:
3050 strcat (buf, ", v4 ABI");
3051 break;
a9522a21
AB
3052 default:
3053 strcat (buf, ", unrecognised ARC OSABI flag");
3054 break;
3055 }
3056}
3057
f3485b74 3058static void
d3ba0551 3059decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3060{
3061 unsigned eabi;
015dc7e1 3062 bool unknown = false;
f3485b74
NC
3063
3064 eabi = EF_ARM_EABI_VERSION (e_flags);
3065 e_flags &= ~ EF_ARM_EABIMASK;
3066
3067 /* Handle "generic" ARM flags. */
3068 if (e_flags & EF_ARM_RELEXEC)
3069 {
3070 strcat (buf, ", relocatable executable");
3071 e_flags &= ~ EF_ARM_RELEXEC;
3072 }
76da6bbe 3073
18a20338
CL
3074 if (e_flags & EF_ARM_PIC)
3075 {
3076 strcat (buf, ", position independent");
3077 e_flags &= ~ EF_ARM_PIC;
3078 }
3079
f3485b74
NC
3080 /* Now handle EABI specific flags. */
3081 switch (eabi)
3082 {
3083 default:
2c71103e 3084 strcat (buf, ", <unrecognized EABI>");
f3485b74 3085 if (e_flags)
015dc7e1 3086 unknown = true;
f3485b74
NC
3087 break;
3088
3089 case EF_ARM_EABI_VER1:
a5bcd848 3090 strcat (buf, ", Version1 EABI");
f3485b74
NC
3091 while (e_flags)
3092 {
3093 unsigned flag;
76da6bbe 3094
f3485b74
NC
3095 /* Process flags one bit at a time. */
3096 flag = e_flags & - e_flags;
3097 e_flags &= ~ flag;
76da6bbe 3098
f3485b74
NC
3099 switch (flag)
3100 {
a5bcd848 3101 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3102 strcat (buf, ", sorted symbol tables");
3103 break;
76da6bbe 3104
f3485b74 3105 default:
015dc7e1 3106 unknown = true;
f3485b74
NC
3107 break;
3108 }
3109 }
3110 break;
76da6bbe 3111
a5bcd848
PB
3112 case EF_ARM_EABI_VER2:
3113 strcat (buf, ", Version2 EABI");
3114 while (e_flags)
3115 {
3116 unsigned flag;
3117
3118 /* Process flags one bit at a time. */
3119 flag = e_flags & - e_flags;
3120 e_flags &= ~ flag;
3121
3122 switch (flag)
3123 {
3124 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3125 strcat (buf, ", sorted symbol tables");
3126 break;
3127
3128 case EF_ARM_DYNSYMSUSESEGIDX:
3129 strcat (buf, ", dynamic symbols use segment index");
3130 break;
3131
3132 case EF_ARM_MAPSYMSFIRST:
3133 strcat (buf, ", mapping symbols precede others");
3134 break;
3135
3136 default:
015dc7e1 3137 unknown = true;
a5bcd848
PB
3138 break;
3139 }
3140 }
3141 break;
3142
d507cf36
PB
3143 case EF_ARM_EABI_VER3:
3144 strcat (buf, ", Version3 EABI");
8cb51566
PB
3145 break;
3146
3147 case EF_ARM_EABI_VER4:
3148 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3149 while (e_flags)
3150 {
3151 unsigned flag;
3152
3153 /* Process flags one bit at a time. */
3154 flag = e_flags & - e_flags;
3155 e_flags &= ~ flag;
3156
3157 switch (flag)
3158 {
3159 case EF_ARM_BE8:
3160 strcat (buf, ", BE8");
3161 break;
3162
3163 case EF_ARM_LE8:
3164 strcat (buf, ", LE8");
3165 break;
3166
3167 default:
015dc7e1 3168 unknown = true;
3bfcb652
NC
3169 break;
3170 }
3bfcb652
NC
3171 }
3172 break;
3a4a14e9
PB
3173
3174 case EF_ARM_EABI_VER5:
3175 strcat (buf, ", Version5 EABI");
d507cf36
PB
3176 while (e_flags)
3177 {
3178 unsigned flag;
3179
3180 /* Process flags one bit at a time. */
3181 flag = e_flags & - e_flags;
3182 e_flags &= ~ flag;
3183
3184 switch (flag)
3185 {
3186 case EF_ARM_BE8:
3187 strcat (buf, ", BE8");
3188 break;
3189
3190 case EF_ARM_LE8:
3191 strcat (buf, ", LE8");
3192 break;
3193
3bfcb652
NC
3194 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3195 strcat (buf, ", soft-float ABI");
3196 break;
3197
3198 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3199 strcat (buf, ", hard-float ABI");
3200 break;
3201
d507cf36 3202 default:
015dc7e1 3203 unknown = true;
d507cf36
PB
3204 break;
3205 }
3206 }
3207 break;
3208
f3485b74 3209 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3210 strcat (buf, ", GNU EABI");
f3485b74
NC
3211 while (e_flags)
3212 {
3213 unsigned flag;
76da6bbe 3214
f3485b74
NC
3215 /* Process flags one bit at a time. */
3216 flag = e_flags & - e_flags;
3217 e_flags &= ~ flag;
76da6bbe 3218
f3485b74
NC
3219 switch (flag)
3220 {
a5bcd848 3221 case EF_ARM_INTERWORK:
f3485b74
NC
3222 strcat (buf, ", interworking enabled");
3223 break;
76da6bbe 3224
a5bcd848 3225 case EF_ARM_APCS_26:
f3485b74
NC
3226 strcat (buf, ", uses APCS/26");
3227 break;
76da6bbe 3228
a5bcd848 3229 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3230 strcat (buf, ", uses APCS/float");
3231 break;
76da6bbe 3232
a5bcd848 3233 case EF_ARM_PIC:
f3485b74
NC
3234 strcat (buf, ", position independent");
3235 break;
76da6bbe 3236
a5bcd848 3237 case EF_ARM_ALIGN8:
f3485b74
NC
3238 strcat (buf, ", 8 bit structure alignment");
3239 break;
76da6bbe 3240
a5bcd848 3241 case EF_ARM_NEW_ABI:
f3485b74
NC
3242 strcat (buf, ", uses new ABI");
3243 break;
76da6bbe 3244
a5bcd848 3245 case EF_ARM_OLD_ABI:
f3485b74
NC
3246 strcat (buf, ", uses old ABI");
3247 break;
76da6bbe 3248
a5bcd848 3249 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3250 strcat (buf, ", software FP");
3251 break;
76da6bbe 3252
90e01f86
ILT
3253 case EF_ARM_VFP_FLOAT:
3254 strcat (buf, ", VFP");
3255 break;
3256
fde78edd
NC
3257 case EF_ARM_MAVERICK_FLOAT:
3258 strcat (buf, ", Maverick FP");
3259 break;
3260
f3485b74 3261 default:
015dc7e1 3262 unknown = true;
f3485b74
NC
3263 break;
3264 }
3265 }
3266 }
f3485b74
NC
3267
3268 if (unknown)
2b692964 3269 strcat (buf,_(", <unknown>"));
f3485b74
NC
3270}
3271
343433df
AB
3272static void
3273decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3274{
3275 --size; /* Leave space for null terminator. */
3276
3277 switch (e_flags & EF_AVR_MACH)
3278 {
3279 case E_AVR_MACH_AVR1:
3280 strncat (buf, ", avr:1", size);
3281 break;
3282 case E_AVR_MACH_AVR2:
3283 strncat (buf, ", avr:2", size);
3284 break;
3285 case E_AVR_MACH_AVR25:
3286 strncat (buf, ", avr:25", size);
3287 break;
3288 case E_AVR_MACH_AVR3:
3289 strncat (buf, ", avr:3", size);
3290 break;
3291 case E_AVR_MACH_AVR31:
3292 strncat (buf, ", avr:31", size);
3293 break;
3294 case E_AVR_MACH_AVR35:
3295 strncat (buf, ", avr:35", size);
3296 break;
3297 case E_AVR_MACH_AVR4:
3298 strncat (buf, ", avr:4", size);
3299 break;
3300 case E_AVR_MACH_AVR5:
3301 strncat (buf, ", avr:5", size);
3302 break;
3303 case E_AVR_MACH_AVR51:
3304 strncat (buf, ", avr:51", size);
3305 break;
3306 case E_AVR_MACH_AVR6:
3307 strncat (buf, ", avr:6", size);
3308 break;
3309 case E_AVR_MACH_AVRTINY:
3310 strncat (buf, ", avr:100", size);
3311 break;
3312 case E_AVR_MACH_XMEGA1:
3313 strncat (buf, ", avr:101", size);
3314 break;
3315 case E_AVR_MACH_XMEGA2:
3316 strncat (buf, ", avr:102", size);
3317 break;
3318 case E_AVR_MACH_XMEGA3:
3319 strncat (buf, ", avr:103", size);
3320 break;
3321 case E_AVR_MACH_XMEGA4:
3322 strncat (buf, ", avr:104", size);
3323 break;
3324 case E_AVR_MACH_XMEGA5:
3325 strncat (buf, ", avr:105", size);
3326 break;
3327 case E_AVR_MACH_XMEGA6:
3328 strncat (buf, ", avr:106", size);
3329 break;
3330 case E_AVR_MACH_XMEGA7:
3331 strncat (buf, ", avr:107", size);
3332 break;
3333 default:
3334 strncat (buf, ", avr:<unknown>", size);
3335 break;
3336 }
3337
3338 size -= strlen (buf);
3339 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3340 strncat (buf, ", link-relax", size);
3341}
3342
35c08157
KLC
3343static void
3344decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3345{
3346 unsigned abi;
3347 unsigned arch;
3348 unsigned config;
3349 unsigned version;
015dc7e1 3350 bool has_fpu = false;
32ec8896 3351 unsigned int r = 0;
35c08157
KLC
3352
3353 static const char *ABI_STRINGS[] =
3354 {
3355 "ABI v0", /* use r5 as return register; only used in N1213HC */
3356 "ABI v1", /* use r0 as return register */
3357 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3358 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3359 "AABI",
3360 "ABI2 FP+"
35c08157
KLC
3361 };
3362 static const char *VER_STRINGS[] =
3363 {
3364 "Andes ELF V1.3 or older",
3365 "Andes ELF V1.3.1",
3366 "Andes ELF V1.4"
3367 };
3368 static const char *ARCH_STRINGS[] =
3369 {
3370 "",
3371 "Andes Star v1.0",
3372 "Andes Star v2.0",
3373 "Andes Star v3.0",
3374 "Andes Star v3.0m"
3375 };
3376
3377 abi = EF_NDS_ABI & e_flags;
3378 arch = EF_NDS_ARCH & e_flags;
3379 config = EF_NDS_INST & e_flags;
3380 version = EF_NDS32_ELF_VERSION & e_flags;
3381
3382 memset (buf, 0, size);
3383
3384 switch (abi)
3385 {
3386 case E_NDS_ABI_V0:
3387 case E_NDS_ABI_V1:
3388 case E_NDS_ABI_V2:
3389 case E_NDS_ABI_V2FP:
3390 case E_NDS_ABI_AABI:
40c7a7cb 3391 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3392 /* In case there are holes in the array. */
3393 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3394 break;
3395
3396 default:
3397 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3398 break;
3399 }
3400
3401 switch (version)
3402 {
3403 case E_NDS32_ELF_VER_1_2:
3404 case E_NDS32_ELF_VER_1_3:
3405 case E_NDS32_ELF_VER_1_4:
3406 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3407 break;
3408
3409 default:
3410 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3411 break;
3412 }
3413
3414 if (E_NDS_ABI_V0 == abi)
3415 {
3416 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3417 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3418 if (arch == E_NDS_ARCH_STAR_V1_0)
3419 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3420 return;
3421 }
3422
3423 switch (arch)
3424 {
3425 case E_NDS_ARCH_STAR_V1_0:
3426 case E_NDS_ARCH_STAR_V2_0:
3427 case E_NDS_ARCH_STAR_V3_0:
3428 case E_NDS_ARCH_STAR_V3_M:
3429 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3430 break;
3431
3432 default:
3433 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3434 /* ARCH version determines how the e_flags are interpreted.
3435 If it is unknown, we cannot proceed. */
3436 return;
3437 }
3438
3439 /* Newer ABI; Now handle architecture specific flags. */
3440 if (arch == E_NDS_ARCH_STAR_V1_0)
3441 {
3442 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3443 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3444
3445 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3446 r += snprintf (buf + r, size -r, ", MAC");
3447
3448 if (config & E_NDS32_HAS_DIV_INST)
3449 r += snprintf (buf + r, size -r, ", DIV");
3450
3451 if (config & E_NDS32_HAS_16BIT_INST)
3452 r += snprintf (buf + r, size -r, ", 16b");
3453 }
3454 else
3455 {
3456 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3457 {
3458 if (version <= E_NDS32_ELF_VER_1_3)
3459 r += snprintf (buf + r, size -r, ", [B8]");
3460 else
3461 r += snprintf (buf + r, size -r, ", EX9");
3462 }
3463
3464 if (config & E_NDS32_HAS_MAC_DX_INST)
3465 r += snprintf (buf + r, size -r, ", MAC_DX");
3466
3467 if (config & E_NDS32_HAS_DIV_DX_INST)
3468 r += snprintf (buf + r, size -r, ", DIV_DX");
3469
3470 if (config & E_NDS32_HAS_16BIT_INST)
3471 {
3472 if (version <= E_NDS32_ELF_VER_1_3)
3473 r += snprintf (buf + r, size -r, ", 16b");
3474 else
3475 r += snprintf (buf + r, size -r, ", IFC");
3476 }
3477 }
3478
3479 if (config & E_NDS32_HAS_EXT_INST)
3480 r += snprintf (buf + r, size -r, ", PERF1");
3481
3482 if (config & E_NDS32_HAS_EXT2_INST)
3483 r += snprintf (buf + r, size -r, ", PERF2");
3484
3485 if (config & E_NDS32_HAS_FPU_INST)
3486 {
015dc7e1 3487 has_fpu = true;
35c08157
KLC
3488 r += snprintf (buf + r, size -r, ", FPU_SP");
3489 }
3490
3491 if (config & E_NDS32_HAS_FPU_DP_INST)
3492 {
015dc7e1 3493 has_fpu = true;
35c08157
KLC
3494 r += snprintf (buf + r, size -r, ", FPU_DP");
3495 }
3496
3497 if (config & E_NDS32_HAS_FPU_MAC_INST)
3498 {
015dc7e1 3499 has_fpu = true;
35c08157
KLC
3500 r += snprintf (buf + r, size -r, ", FPU_MAC");
3501 }
3502
3503 if (has_fpu)
3504 {
3505 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3506 {
3507 case E_NDS32_FPU_REG_8SP_4DP:
3508 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3509 break;
3510 case E_NDS32_FPU_REG_16SP_8DP:
3511 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3512 break;
3513 case E_NDS32_FPU_REG_32SP_16DP:
3514 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3515 break;
3516 case E_NDS32_FPU_REG_32SP_32DP:
3517 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3518 break;
3519 }
3520 }
3521
3522 if (config & E_NDS32_HAS_AUDIO_INST)
3523 r += snprintf (buf + r, size -r, ", AUDIO");
3524
3525 if (config & E_NDS32_HAS_STRING_INST)
3526 r += snprintf (buf + r, size -r, ", STR");
3527
3528 if (config & E_NDS32_HAS_REDUCED_REGS)
3529 r += snprintf (buf + r, size -r, ", 16REG");
3530
3531 if (config & E_NDS32_HAS_VIDEO_INST)
3532 {
3533 if (version <= E_NDS32_ELF_VER_1_3)
3534 r += snprintf (buf + r, size -r, ", VIDEO");
3535 else
3536 r += snprintf (buf + r, size -r, ", SATURATION");
3537 }
3538
3539 if (config & E_NDS32_HAS_ENCRIPT_INST)
3540 r += snprintf (buf + r, size -r, ", ENCRP");
3541
3542 if (config & E_NDS32_HAS_L2C_INST)
3543 r += snprintf (buf + r, size -r, ", L2C");
3544}
3545
c077c580
SM
3546static void
3547decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3548 char *buf)
3549{
3550 unsigned char *e_ident = filedata->file_header.e_ident;
3551 unsigned char osabi = e_ident[EI_OSABI];
3552 unsigned char abiversion = e_ident[EI_ABIVERSION];
3553 unsigned int mach;
3554
3555 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3556 it has been deprecated for a while.
3557
3558 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3559 of writing, they use the same flags as HSA v3, so the code below uses that
3560 assumption. */
3561 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3562 return;
3563
3564 mach = e_flags & EF_AMDGPU_MACH;
3565 switch (mach)
3566 {
3567#define AMDGPU_CASE(code, string) \
3568 case code: strcat (buf, ", " string); break;
3569 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3570 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3571 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3572 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3573 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3574 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3575 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3576 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3577 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3578 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3579 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3580 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3581 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3582 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3583 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3584 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3585 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3586 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3587 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3588 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3589 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3590 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3591 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3603 default:
3604 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3605 break;
3606#undef AMDGPU_CASE
3607 }
3608
3609 buf += strlen (buf);
3610 e_flags &= ~EF_AMDGPU_MACH;
3611
3612 if ((osabi == ELFOSABI_AMDGPU_HSA
3613 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3614 || osabi != ELFOSABI_AMDGPU_HSA)
3615 {
3616 /* For HSA v3 and other OS ABIs. */
3617 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3618 {
3619 strcat (buf, ", xnack on");
3620 buf += strlen (buf);
3621 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3622 }
3623
3624 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3625 {
3626 strcat (buf, ", sramecc on");
3627 buf += strlen (buf);
3628 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3629 }
3630 }
3631 else
3632 {
3633 /* For HSA v4+. */
3634 int xnack, sramecc;
3635
3636 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3637 switch (xnack)
3638 {
3639 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3640 break;
3641
3642 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3643 strcat (buf, ", xnack any");
3644 break;
3645
3646 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3647 strcat (buf, ", xnack off");
3648 break;
3649
3650 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3651 strcat (buf, ", xnack on");
3652 break;
3653
3654 default:
3655 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3656 break;
3657 }
3658
3659 buf += strlen (buf);
3660 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3661
3662 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3663 switch (sramecc)
3664 {
3665 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3666 break;
3667
3668 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3669 strcat (buf, ", sramecc any");
3670 break;
3671
3672 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3673 strcat (buf, ", sramecc off");
3674 break;
3675
3676 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3677 strcat (buf, ", sramecc on");
3678 break;
3679
3680 default:
3681 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3682 break;
3683 }
3684
3685 buf += strlen (buf);
3686 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3687 }
3688
3689 if (e_flags != 0)
3690 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3691}
3692
252b5132 3693static char *
dda8d76d 3694get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3695{
b34976b6 3696 static char buf[1024];
252b5132
RH
3697
3698 buf[0] = '\0';
76da6bbe 3699
252b5132
RH
3700 if (e_flags)
3701 {
3702 switch (e_machine)
3703 {
3704 default:
3705 break;
3706
886a2506 3707 case EM_ARC_COMPACT2:
886a2506 3708 case EM_ARC_COMPACT:
a9522a21
AB
3709 decode_ARC_machine_flags (e_flags, e_machine, buf);
3710 break;
886a2506 3711
f3485b74
NC
3712 case EM_ARM:
3713 decode_ARM_machine_flags (e_flags, buf);
3714 break;
76da6bbe 3715
343433df
AB
3716 case EM_AVR:
3717 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3718 break;
3719
781303ce
MF
3720 case EM_BLACKFIN:
3721 if (e_flags & EF_BFIN_PIC)
3722 strcat (buf, ", PIC");
3723
3724 if (e_flags & EF_BFIN_FDPIC)
3725 strcat (buf, ", FDPIC");
3726
3727 if (e_flags & EF_BFIN_CODE_IN_L1)
3728 strcat (buf, ", code in L1");
3729
3730 if (e_flags & EF_BFIN_DATA_IN_L1)
3731 strcat (buf, ", data in L1");
3732
3733 break;
3734
ec2dfb42
AO
3735 case EM_CYGNUS_FRV:
3736 switch (e_flags & EF_FRV_CPU_MASK)
3737 {
3738 case EF_FRV_CPU_GENERIC:
3739 break;
3740
3741 default:
3742 strcat (buf, ", fr???");
3743 break;
57346661 3744
ec2dfb42
AO
3745 case EF_FRV_CPU_FR300:
3746 strcat (buf, ", fr300");
3747 break;
3748
3749 case EF_FRV_CPU_FR400:
3750 strcat (buf, ", fr400");
3751 break;
3752 case EF_FRV_CPU_FR405:
3753 strcat (buf, ", fr405");
3754 break;
3755
3756 case EF_FRV_CPU_FR450:
3757 strcat (buf, ", fr450");
3758 break;
3759
3760 case EF_FRV_CPU_FR500:
3761 strcat (buf, ", fr500");
3762 break;
3763 case EF_FRV_CPU_FR550:
3764 strcat (buf, ", fr550");
3765 break;
3766
3767 case EF_FRV_CPU_SIMPLE:
3768 strcat (buf, ", simple");
3769 break;
3770 case EF_FRV_CPU_TOMCAT:
3771 strcat (buf, ", tomcat");
3772 break;
3773 }
1c877e87 3774 break;
ec2dfb42 3775
53c7db4b 3776 case EM_68K:
425c6cb0 3777 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3778 strcat (buf, ", m68000");
425c6cb0 3779 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3780 strcat (buf, ", cpu32");
3781 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3782 strcat (buf, ", fido_a");
425c6cb0 3783 else
266abb8f 3784 {
2cf0635d
NC
3785 char const * isa = _("unknown");
3786 char const * mac = _("unknown mac");
3787 char const * additional = NULL;
0112cd26 3788
c694fd50 3789 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3790 {
c694fd50 3791 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3792 isa = "A";
3793 additional = ", nodiv";
3794 break;
c694fd50 3795 case EF_M68K_CF_ISA_A:
266abb8f
NS
3796 isa = "A";
3797 break;
c694fd50 3798 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3799 isa = "A+";
3800 break;
c694fd50 3801 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3802 isa = "B";
3803 additional = ", nousp";
3804 break;
c694fd50 3805 case EF_M68K_CF_ISA_B:
266abb8f
NS
3806 isa = "B";
3807 break;
f608cd77
NS
3808 case EF_M68K_CF_ISA_C:
3809 isa = "C";
3810 break;
3811 case EF_M68K_CF_ISA_C_NODIV:
3812 isa = "C";
3813 additional = ", nodiv";
3814 break;
266abb8f
NS
3815 }
3816 strcat (buf, ", cf, isa ");
3817 strcat (buf, isa);
0b2e31dc
NS
3818 if (additional)
3819 strcat (buf, additional);
c694fd50 3820 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3821 strcat (buf, ", float");
c694fd50 3822 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3823 {
3824 case 0:
3825 mac = NULL;
3826 break;
c694fd50 3827 case EF_M68K_CF_MAC:
266abb8f
NS
3828 mac = "mac";
3829 break;
c694fd50 3830 case EF_M68K_CF_EMAC:
266abb8f
NS
3831 mac = "emac";
3832 break;
f608cd77
NS
3833 case EF_M68K_CF_EMAC_B:
3834 mac = "emac_b";
3835 break;
266abb8f
NS
3836 }
3837 if (mac)
3838 {
3839 strcat (buf, ", ");
3840 strcat (buf, mac);
3841 }
266abb8f 3842 }
53c7db4b 3843 break;
33c63f9d 3844
c077c580
SM
3845 case EM_AMDGPU:
3846 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3847 break;
3848
153a2776
NC
3849 case EM_CYGNUS_MEP:
3850 switch (e_flags & EF_MEP_CPU_MASK)
3851 {
3852 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3853 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3854 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3855 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3856 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3857 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3858 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3859 }
3860
3861 switch (e_flags & EF_MEP_COP_MASK)
3862 {
3863 case EF_MEP_COP_NONE: break;
3864 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3865 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3866 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3867 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3868 default: strcat (buf, _("<unknown MeP copro type>")); break;
3869 }
3870
3871 if (e_flags & EF_MEP_LIBRARY)
3872 strcat (buf, ", Built for Library");
3873
3874 if (e_flags & EF_MEP_INDEX_MASK)
3875 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3876 e_flags & EF_MEP_INDEX_MASK);
3877
3878 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3879 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3880 e_flags & ~ EF_MEP_ALL_FLAGS);
3881 break;
3882
252b5132
RH
3883 case EM_PPC:
3884 if (e_flags & EF_PPC_EMB)
3885 strcat (buf, ", emb");
3886
3887 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3888 strcat (buf, _(", relocatable"));
252b5132
RH
3889
3890 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3891 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3892 break;
3893
ee67d69a
AM
3894 case EM_PPC64:
3895 if (e_flags & EF_PPC64_ABI)
3896 {
3897 char abi[] = ", abiv0";
3898
3899 abi[6] += e_flags & EF_PPC64_ABI;
3900 strcat (buf, abi);
3901 }
3902 break;
3903
708e2187
NC
3904 case EM_V800:
3905 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3906 strcat (buf, ", RH850 ABI");
0b4362b0 3907
708e2187
NC
3908 if (e_flags & EF_V800_850E3)
3909 strcat (buf, ", V3 architecture");
3910
3911 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3912 strcat (buf, ", FPU not used");
3913
3914 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3915 strcat (buf, ", regmode: COMMON");
3916
3917 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3918 strcat (buf, ", r4 not used");
3919
3920 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3921 strcat (buf, ", r30 not used");
3922
3923 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3924 strcat (buf, ", r5 not used");
3925
3926 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3927 strcat (buf, ", r2 not used");
3928
3929 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3930 {
3931 switch (e_flags & - e_flags)
3932 {
3933 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3934 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3935 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3936 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3937 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3938 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3939 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3940 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3941 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3942 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3943 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3944 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3945 default: break;
3946 }
3947 }
3948 break;
3949
2b0337b0 3950 case EM_V850:
252b5132
RH
3951 case EM_CYGNUS_V850:
3952 switch (e_flags & EF_V850_ARCH)
3953 {
78c8d46c
NC
3954 case E_V850E3V5_ARCH:
3955 strcat (buf, ", v850e3v5");
3956 break;
1cd986c5
NC
3957 case E_V850E2V3_ARCH:
3958 strcat (buf, ", v850e2v3");
3959 break;
3960 case E_V850E2_ARCH:
3961 strcat (buf, ", v850e2");
3962 break;
3963 case E_V850E1_ARCH:
3964 strcat (buf, ", v850e1");
8ad30312 3965 break;
252b5132
RH
3966 case E_V850E_ARCH:
3967 strcat (buf, ", v850e");
3968 break;
252b5132
RH
3969 case E_V850_ARCH:
3970 strcat (buf, ", v850");
3971 break;
3972 default:
2b692964 3973 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3974 break;
3975 }
3976 break;
3977
2b0337b0 3978 case EM_M32R:
252b5132
RH
3979 case EM_CYGNUS_M32R:
3980 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3981 strcat (buf, ", m32r");
252b5132
RH
3982 break;
3983
3984 case EM_MIPS:
4fe85591 3985 case EM_MIPS_RS3_LE:
252b5132
RH
3986 if (e_flags & EF_MIPS_NOREORDER)
3987 strcat (buf, ", noreorder");
3988
3989 if (e_flags & EF_MIPS_PIC)
3990 strcat (buf, ", pic");
3991
3992 if (e_flags & EF_MIPS_CPIC)
3993 strcat (buf, ", cpic");
3994
d1bdd336
TS
3995 if (e_flags & EF_MIPS_UCODE)
3996 strcat (buf, ", ugen_reserved");
3997
252b5132
RH
3998 if (e_flags & EF_MIPS_ABI2)
3999 strcat (buf, ", abi2");
4000
43521d43
TS
4001 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4002 strcat (buf, ", odk first");
4003
a5d22d2a
TS
4004 if (e_flags & EF_MIPS_32BITMODE)
4005 strcat (buf, ", 32bitmode");
4006
ba92f887
MR
4007 if (e_flags & EF_MIPS_NAN2008)
4008 strcat (buf, ", nan2008");
4009
fef1b0b3
SE
4010 if (e_flags & EF_MIPS_FP64)
4011 strcat (buf, ", fp64");
4012
156c2f8b
NC
4013 switch ((e_flags & EF_MIPS_MACH))
4014 {
4015 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4016 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4017 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4018 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4019 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4020 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4021 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4022 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4023 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4024 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4025 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4026 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4027 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4028 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4029 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4030 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4031 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4032 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4033 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4034 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4035 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4036 case 0:
4037 /* We simply ignore the field in this case to avoid confusion:
4038 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4039 extension. */
4040 break;
2b692964 4041 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4042 }
43521d43
TS
4043
4044 switch ((e_flags & EF_MIPS_ABI))
4045 {
4046 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4047 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4048 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4049 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4050 case 0:
4051 /* We simply ignore the field in this case to avoid confusion:
4052 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4053 This means it is likely to be an o32 file, but not for
4054 sure. */
4055 break;
2b692964 4056 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4057 }
4058
4059 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4060 strcat (buf, ", mdmx");
4061
4062 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4063 strcat (buf, ", mips16");
4064
df58fc94
RS
4065 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4066 strcat (buf, ", micromips");
4067
43521d43
TS
4068 switch ((e_flags & EF_MIPS_ARCH))
4069 {
4070 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4071 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4072 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4073 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4074 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4075 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4076 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4077 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4078 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4079 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4080 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4081 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4082 }
252b5132 4083 break;
351b4b40 4084
35c08157
KLC
4085 case EM_NDS32:
4086 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4087 break;
4088
fe944acf
FT
4089 case EM_NFP:
4090 switch (EF_NFP_MACH (e_flags))
4091 {
4092 case E_NFP_MACH_3200:
4093 strcat (buf, ", NFP-32xx");
4094 break;
4095 case E_NFP_MACH_6000:
4096 strcat (buf, ", NFP-6xxx");
4097 break;
4098 }
4099 break;
4100
e23eba97
NC
4101 case EM_RISCV:
4102 if (e_flags & EF_RISCV_RVC)
4103 strcat (buf, ", RVC");
2922d21d 4104
7f999549
JW
4105 if (e_flags & EF_RISCV_RVE)
4106 strcat (buf, ", RVE");
4107
2922d21d
AW
4108 switch (e_flags & EF_RISCV_FLOAT_ABI)
4109 {
4110 case EF_RISCV_FLOAT_ABI_SOFT:
4111 strcat (buf, ", soft-float ABI");
4112 break;
4113
4114 case EF_RISCV_FLOAT_ABI_SINGLE:
4115 strcat (buf, ", single-float ABI");
4116 break;
4117
4118 case EF_RISCV_FLOAT_ABI_DOUBLE:
4119 strcat (buf, ", double-float ABI");
4120 break;
4121
4122 case EF_RISCV_FLOAT_ABI_QUAD:
4123 strcat (buf, ", quad-float ABI");
4124 break;
4125 }
e23eba97
NC
4126 break;
4127
ccde1100
AO
4128 case EM_SH:
4129 switch ((e_flags & EF_SH_MACH_MASK))
4130 {
4131 case EF_SH1: strcat (buf, ", sh1"); break;
4132 case EF_SH2: strcat (buf, ", sh2"); break;
4133 case EF_SH3: strcat (buf, ", sh3"); break;
4134 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4135 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4136 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4137 case EF_SH3E: strcat (buf, ", sh3e"); break;
4138 case EF_SH4: strcat (buf, ", sh4"); break;
4139 case EF_SH5: strcat (buf, ", sh5"); break;
4140 case EF_SH2E: strcat (buf, ", sh2e"); break;
4141 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4142 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4143 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4144 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4145 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4146 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4147 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4148 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4149 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4150 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4151 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4152 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4153 }
4154
cec6a5b8
MR
4155 if (e_flags & EF_SH_PIC)
4156 strcat (buf, ", pic");
4157
4158 if (e_flags & EF_SH_FDPIC)
4159 strcat (buf, ", fdpic");
ccde1100 4160 break;
948f632f 4161
73589c9d
CS
4162 case EM_OR1K:
4163 if (e_flags & EF_OR1K_NODELAY)
4164 strcat (buf, ", no delay");
4165 break;
57346661 4166
351b4b40
RH
4167 case EM_SPARCV9:
4168 if (e_flags & EF_SPARC_32PLUS)
4169 strcat (buf, ", v8+");
4170
4171 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4172 strcat (buf, ", ultrasparcI");
4173
4174 if (e_flags & EF_SPARC_SUN_US3)
4175 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4176
4177 if (e_flags & EF_SPARC_HAL_R1)
4178 strcat (buf, ", halr1");
4179
4180 if (e_flags & EF_SPARC_LEDATA)
4181 strcat (buf, ", ledata");
4182
4183 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4184 strcat (buf, ", tso");
4185
4186 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4187 strcat (buf, ", pso");
4188
4189 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4190 strcat (buf, ", rmo");
4191 break;
7d466069 4192
103f02d3
UD
4193 case EM_PARISC:
4194 switch (e_flags & EF_PARISC_ARCH)
4195 {
4196 case EFA_PARISC_1_0:
4197 strcpy (buf, ", PA-RISC 1.0");
4198 break;
4199 case EFA_PARISC_1_1:
4200 strcpy (buf, ", PA-RISC 1.1");
4201 break;
4202 case EFA_PARISC_2_0:
4203 strcpy (buf, ", PA-RISC 2.0");
4204 break;
4205 default:
4206 break;
4207 }
4208 if (e_flags & EF_PARISC_TRAPNIL)
4209 strcat (buf, ", trapnil");
4210 if (e_flags & EF_PARISC_EXT)
4211 strcat (buf, ", ext");
4212 if (e_flags & EF_PARISC_LSB)
4213 strcat (buf, ", lsb");
4214 if (e_flags & EF_PARISC_WIDE)
4215 strcat (buf, ", wide");
4216 if (e_flags & EF_PARISC_NO_KABP)
4217 strcat (buf, ", no kabp");
4218 if (e_flags & EF_PARISC_LAZYSWAP)
4219 strcat (buf, ", lazyswap");
30800947 4220 break;
76da6bbe 4221
7d466069 4222 case EM_PJ:
2b0337b0 4223 case EM_PJ_OLD:
7d466069
ILT
4224 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4225 strcat (buf, ", new calling convention");
4226
4227 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4228 strcat (buf, ", gnu calling convention");
4229 break;
4d6ed7c8
NC
4230
4231 case EM_IA_64:
4232 if ((e_flags & EF_IA_64_ABI64))
4233 strcat (buf, ", 64-bit");
4234 else
4235 strcat (buf, ", 32-bit");
4236 if ((e_flags & EF_IA_64_REDUCEDFP))
4237 strcat (buf, ", reduced fp model");
4238 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4239 strcat (buf, ", no function descriptors, constant gp");
4240 else if ((e_flags & EF_IA_64_CONS_GP))
4241 strcat (buf, ", constant gp");
4242 if ((e_flags & EF_IA_64_ABSOLUTE))
4243 strcat (buf, ", absolute");
dda8d76d 4244 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4245 {
4246 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4247 strcat (buf, ", vms_linkages");
4248 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4249 {
4250 case EF_IA_64_VMS_COMCOD_SUCCESS:
4251 break;
4252 case EF_IA_64_VMS_COMCOD_WARNING:
4253 strcat (buf, ", warning");
4254 break;
4255 case EF_IA_64_VMS_COMCOD_ERROR:
4256 strcat (buf, ", error");
4257 break;
4258 case EF_IA_64_VMS_COMCOD_ABORT:
4259 strcat (buf, ", abort");
4260 break;
4261 default:
bee0ee85
NC
4262 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4263 e_flags & EF_IA_64_VMS_COMCOD);
4264 strcat (buf, ", <unknown>");
28f997cf
TG
4265 }
4266 }
4d6ed7c8 4267 break;
179d3252
JT
4268
4269 case EM_VAX:
4270 if ((e_flags & EF_VAX_NONPIC))
4271 strcat (buf, ", non-PIC");
4272 if ((e_flags & EF_VAX_DFLOAT))
4273 strcat (buf, ", D-Float");
4274 if ((e_flags & EF_VAX_GFLOAT))
4275 strcat (buf, ", G-Float");
4276 break;
c7927a3c 4277
619ed720
EB
4278 case EM_VISIUM:
4279 if (e_flags & EF_VISIUM_ARCH_MCM)
4280 strcat (buf, ", mcm");
4281 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4282 strcat (buf, ", mcm24");
4283 if (e_flags & EF_VISIUM_ARCH_GR6)
4284 strcat (buf, ", gr6");
4285 break;
4286
4046d87a 4287 case EM_RL78:
1740ba0c
NC
4288 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4289 {
4290 case E_FLAG_RL78_ANY_CPU: break;
4291 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4292 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4293 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4294 }
856ea05c
KP
4295 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4296 strcat (buf, ", 64-bit doubles");
4046d87a 4297 break;
0b4362b0 4298
c7927a3c
NC
4299 case EM_RX:
4300 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4301 strcat (buf, ", 64-bit doubles");
4302 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4303 strcat (buf, ", dsp");
d4cb0ea0 4304 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4305 strcat (buf, ", pid");
708e2187
NC
4306 if (e_flags & E_FLAG_RX_ABI)
4307 strcat (buf, ", RX ABI");
3525236c
NC
4308 if (e_flags & E_FLAG_RX_SINSNS_SET)
4309 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4310 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4311 if (e_flags & E_FLAG_RX_V2)
4312 strcat (buf, ", V2");
f87673e0
YS
4313 if (e_flags & E_FLAG_RX_V3)
4314 strcat (buf, ", V3");
d4cb0ea0 4315 break;
55786da2
AK
4316
4317 case EM_S390:
4318 if (e_flags & EF_S390_HIGH_GPRS)
4319 strcat (buf, ", highgprs");
d4cb0ea0 4320 break;
40b36596
JM
4321
4322 case EM_TI_C6000:
4323 if ((e_flags & EF_C6000_REL))
4324 strcat (buf, ", relocatable module");
d4cb0ea0 4325 break;
13761a11
NC
4326
4327 case EM_MSP430:
4328 strcat (buf, _(": architecture variant: "));
4329 switch (e_flags & EF_MSP430_MACH)
4330 {
4331 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4332 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4333 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4334 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4335 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4336 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4337 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4338 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4339 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4340 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4341 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4342 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4343 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4344 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4345 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4346 default:
4347 strcat (buf, _(": unknown")); break;
4348 }
4349
4350 if (e_flags & ~ EF_MSP430_MACH)
4351 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4352 break;
4353
4354 case EM_Z80:
4355 switch (e_flags & EF_Z80_MACH_MSK)
4356 {
4357 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4358 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4359 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4360 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4361 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4362 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4363 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4364 default:
4365 strcat (buf, _(", unknown")); break;
4366 }
4367 break;
e9a0721f 4368 case EM_LOONGARCH:
4369 if (EF_LOONGARCH_IS_LP64 (e_flags))
4370 strcat (buf, ", LP64");
4371 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4372 strcat (buf, ", ILP32");
4373
4374 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4375 strcat (buf, ", SOFT-FLOAT");
4376 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4377 strcat (buf, ", SINGLE-FLOAT");
4378 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4379 strcat (buf, ", DOUBLE-FLOAT");
4380
4381 break;
252b5132
RH
4382 }
4383 }
4384
4385 return buf;
4386}
4387
252b5132 4388static const char *
dda8d76d 4389get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4390{
4391 static char buff[32];
4392
4393 switch (osabi)
4394 {
4395 case ELFOSABI_NONE: return "UNIX - System V";
4396 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4397 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4398 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4399 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4400 case ELFOSABI_AIX: return "UNIX - AIX";
4401 case ELFOSABI_IRIX: return "UNIX - IRIX";
4402 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4403 case ELFOSABI_TRU64: return "UNIX - TRU64";
4404 case ELFOSABI_MODESTO: return "Novell - Modesto";
4405 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4406 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4407 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4408 case ELFOSABI_AROS: return "AROS";
11636f9e 4409 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4410 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4411 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4412 default:
40b36596 4413 if (osabi >= 64)
dda8d76d 4414 switch (filedata->file_header.e_machine)
40b36596 4415 {
37870be8
SM
4416 case EM_AMDGPU:
4417 switch (osabi)
4418 {
4419 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4420 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4421 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4422 default:
4423 break;
4424 }
4425 break;
4426
40b36596
JM
4427 case EM_ARM:
4428 switch (osabi)
4429 {
4430 case ELFOSABI_ARM: return "ARM";
18a20338 4431 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4432 default:
4433 break;
4434 }
4435 break;
4436
4437 case EM_MSP430:
4438 case EM_MSP430_OLD:
619ed720 4439 case EM_VISIUM:
40b36596
JM
4440 switch (osabi)
4441 {
4442 case ELFOSABI_STANDALONE: return _("Standalone App");
4443 default:
4444 break;
4445 }
4446 break;
4447
4448 case EM_TI_C6000:
4449 switch (osabi)
4450 {
4451 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4452 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4453 default:
4454 break;
4455 }
4456 break;
4457
4458 default:
4459 break;
4460 }
e9e44622 4461 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4462 return buff;
4463 }
4464}
4465
a06ea964
NC
4466static const char *
4467get_aarch64_segment_type (unsigned long type)
4468{
4469 switch (type)
4470 {
32ec8896 4471 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4472 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4473 default: return NULL;
a06ea964 4474 }
a06ea964
NC
4475}
4476
b294bdf8
MM
4477static const char *
4478get_arm_segment_type (unsigned long type)
4479{
4480 switch (type)
4481 {
32ec8896
NC
4482 case PT_ARM_EXIDX: return "EXIDX";
4483 default: return NULL;
b294bdf8 4484 }
b294bdf8
MM
4485}
4486
b4cbbe8f
AK
4487static const char *
4488get_s390_segment_type (unsigned long type)
4489{
4490 switch (type)
4491 {
4492 case PT_S390_PGSTE: return "S390_PGSTE";
4493 default: return NULL;
4494 }
4495}
4496
d3ba0551
AM
4497static const char *
4498get_mips_segment_type (unsigned long type)
252b5132
RH
4499{
4500 switch (type)
4501 {
32ec8896
NC
4502 case PT_MIPS_REGINFO: return "REGINFO";
4503 case PT_MIPS_RTPROC: return "RTPROC";
4504 case PT_MIPS_OPTIONS: return "OPTIONS";
4505 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4506 default: return NULL;
252b5132 4507 }
252b5132
RH
4508}
4509
103f02d3 4510static const char *
d3ba0551 4511get_parisc_segment_type (unsigned long type)
103f02d3
UD
4512{
4513 switch (type)
4514 {
103f02d3
UD
4515 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4516 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4517 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4518 default: return NULL;
103f02d3 4519 }
103f02d3
UD
4520}
4521
4d6ed7c8 4522static const char *
d3ba0551 4523get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4524{
4525 switch (type)
4526 {
4527 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4528 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4529 default: return NULL;
4d6ed7c8 4530 }
4d6ed7c8
NC
4531}
4532
40b36596
JM
4533static const char *
4534get_tic6x_segment_type (unsigned long type)
4535{
4536 switch (type)
4537 {
32ec8896
NC
4538 case PT_C6000_PHATTR: return "C6000_PHATTR";
4539 default: return NULL;
40b36596 4540 }
40b36596
JM
4541}
4542
fbc95f1e
KC
4543static const char *
4544get_riscv_segment_type (unsigned long type)
4545{
4546 switch (type)
4547 {
4548 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4549 default: return NULL;
4550 }
4551}
4552
df3a023b
AM
4553static const char *
4554get_hpux_segment_type (unsigned long type, unsigned e_machine)
4555{
4556 if (e_machine == EM_PARISC)
4557 switch (type)
4558 {
4559 case PT_HP_TLS: return "HP_TLS";
4560 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4561 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4562 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4563 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4564 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4565 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4566 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4567 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4568 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4569 case PT_HP_PARALLEL: return "HP_PARALLEL";
4570 case PT_HP_FASTBIND: return "HP_FASTBIND";
4571 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4572 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4573 case PT_HP_STACK: return "HP_STACK";
4574 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4575 default: return NULL;
4576 }
4577
4578 if (e_machine == EM_IA_64)
4579 switch (type)
4580 {
4581 case PT_HP_TLS: return "HP_TLS";
4582 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4583 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4584 case PT_IA_64_HP_STACK: return "HP_STACK";
4585 default: return NULL;
4586 }
4587
4588 return NULL;
4589}
4590
5522f910
NC
4591static const char *
4592get_solaris_segment_type (unsigned long type)
4593{
4594 switch (type)
4595 {
4596 case 0x6464e550: return "PT_SUNW_UNWIND";
4597 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4598 case 0x6ffffff7: return "PT_LOSUNW";
4599 case 0x6ffffffa: return "PT_SUNWBSS";
4600 case 0x6ffffffb: return "PT_SUNWSTACK";
4601 case 0x6ffffffc: return "PT_SUNWDTRACE";
4602 case 0x6ffffffd: return "PT_SUNWCAP";
4603 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4604 default: return NULL;
5522f910
NC
4605 }
4606}
4607
252b5132 4608static const char *
dda8d76d 4609get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4610{
b34976b6 4611 static char buff[32];
252b5132
RH
4612
4613 switch (p_type)
4614 {
b34976b6
AM
4615 case PT_NULL: return "NULL";
4616 case PT_LOAD: return "LOAD";
252b5132 4617 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4618 case PT_INTERP: return "INTERP";
4619 case PT_NOTE: return "NOTE";
4620 case PT_SHLIB: return "SHLIB";
4621 case PT_PHDR: return "PHDR";
13ae64f3 4622 case PT_TLS: return "TLS";
32ec8896 4623 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4624 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4625 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4626 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4627
3eba3ef3
NC
4628 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4629 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4630 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4631
252b5132 4632 default:
df3a023b 4633 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4634 {
2cf0635d 4635 const char * result;
103f02d3 4636
dda8d76d 4637 switch (filedata->file_header.e_machine)
252b5132 4638 {
a06ea964
NC
4639 case EM_AARCH64:
4640 result = get_aarch64_segment_type (p_type);
4641 break;
b294bdf8
MM
4642 case EM_ARM:
4643 result = get_arm_segment_type (p_type);
4644 break;
252b5132 4645 case EM_MIPS:
4fe85591 4646 case EM_MIPS_RS3_LE:
252b5132
RH
4647 result = get_mips_segment_type (p_type);
4648 break;
103f02d3
UD
4649 case EM_PARISC:
4650 result = get_parisc_segment_type (p_type);
4651 break;
4d6ed7c8
NC
4652 case EM_IA_64:
4653 result = get_ia64_segment_type (p_type);
4654 break;
40b36596
JM
4655 case EM_TI_C6000:
4656 result = get_tic6x_segment_type (p_type);
4657 break;
b4cbbe8f
AK
4658 case EM_S390:
4659 case EM_S390_OLD:
4660 result = get_s390_segment_type (p_type);
4661 break;
fbc95f1e
KC
4662 case EM_RISCV:
4663 result = get_riscv_segment_type (p_type);
4664 break;
252b5132
RH
4665 default:
4666 result = NULL;
4667 break;
4668 }
103f02d3 4669
252b5132
RH
4670 if (result != NULL)
4671 return result;
103f02d3 4672
1a9ccd70 4673 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4674 }
4675 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4676 {
df3a023b 4677 const char * result = NULL;
103f02d3 4678
df3a023b 4679 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4680 {
df3a023b
AM
4681 case ELFOSABI_GNU:
4682 case ELFOSABI_FREEBSD:
4683 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4684 {
4685 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4686 result = buff;
4687 }
103f02d3 4688 break;
df3a023b
AM
4689 case ELFOSABI_HPUX:
4690 result = get_hpux_segment_type (p_type,
4691 filedata->file_header.e_machine);
4692 break;
4693 case ELFOSABI_SOLARIS:
4694 result = get_solaris_segment_type (p_type);
00428cca 4695 break;
103f02d3 4696 default:
103f02d3
UD
4697 break;
4698 }
103f02d3
UD
4699 if (result != NULL)
4700 return result;
4701
1a9ccd70 4702 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4703 }
252b5132 4704 else
e9e44622 4705 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4706
4707 return buff;
4708 }
4709}
4710
53a346d8
CZ
4711static const char *
4712get_arc_section_type_name (unsigned int sh_type)
4713{
4714 switch (sh_type)
4715 {
4716 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4717 default:
4718 break;
4719 }
4720 return NULL;
4721}
4722
252b5132 4723static const char *
d3ba0551 4724get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4725{
4726 switch (sh_type)
4727 {
b34976b6
AM
4728 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4729 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4730 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4731 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4732 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4733 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4734 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4735 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4736 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4737 case SHT_MIPS_RELD: return "MIPS_RELD";
4738 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4739 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4740 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4741 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4742 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4743 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4744 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4745 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4746 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4747 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4748 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4749 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4750 case SHT_MIPS_LINE: return "MIPS_LINE";
4751 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4752 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4753 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4754 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4755 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4756 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4757 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4758 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4759 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4760 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4761 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4762 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4763 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4764 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4765 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4766 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4767 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4768 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4769 default:
4770 break;
4771 }
4772 return NULL;
4773}
4774
103f02d3 4775static const char *
d3ba0551 4776get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4777{
4778 switch (sh_type)
4779 {
4780 case SHT_PARISC_EXT: return "PARISC_EXT";
4781 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4782 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4783 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4784 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4785 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4786 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4787 default: return NULL;
103f02d3 4788 }
103f02d3
UD
4789}
4790
4d6ed7c8 4791static const char *
dda8d76d 4792get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4793{
18bd398b 4794 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4795 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4796 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4797
4d6ed7c8
NC
4798 switch (sh_type)
4799 {
148b93f2
NC
4800 case SHT_IA_64_EXT: return "IA_64_EXT";
4801 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4802 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4803 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4804 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4805 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4806 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4807 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4808 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4809 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4810 default:
4811 break;
4812 }
4813 return NULL;
4814}
4815
d2b2c203
DJ
4816static const char *
4817get_x86_64_section_type_name (unsigned int sh_type)
4818{
4819 switch (sh_type)
4820 {
4821 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4822 default: return NULL;
d2b2c203 4823 }
d2b2c203
DJ
4824}
4825
a06ea964
NC
4826static const char *
4827get_aarch64_section_type_name (unsigned int sh_type)
4828{
4829 switch (sh_type)
4830 {
32ec8896
NC
4831 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4832 default: return NULL;
a06ea964 4833 }
a06ea964
NC
4834}
4835
40a18ebd
NC
4836static const char *
4837get_arm_section_type_name (unsigned int sh_type)
4838{
4839 switch (sh_type)
4840 {
7f6fed87
NC
4841 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4842 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4843 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4844 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4845 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4846 default: return NULL;
40a18ebd 4847 }
40a18ebd
NC
4848}
4849
40b36596
JM
4850static const char *
4851get_tic6x_section_type_name (unsigned int sh_type)
4852{
4853 switch (sh_type)
4854 {
32ec8896
NC
4855 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4856 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4857 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4858 case SHT_TI_ICODE: return "TI_ICODE";
4859 case SHT_TI_XREF: return "TI_XREF";
4860 case SHT_TI_HANDLER: return "TI_HANDLER";
4861 case SHT_TI_INITINFO: return "TI_INITINFO";
4862 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4863 default: return NULL;
40b36596 4864 }
40b36596
JM
4865}
4866
13761a11 4867static const char *
b0191216 4868get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4869{
4870 switch (sh_type)
4871 {
32ec8896
NC
4872 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4873 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4874 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4875 default: return NULL;
13761a11
NC
4876 }
4877}
4878
fe944acf
FT
4879static const char *
4880get_nfp_section_type_name (unsigned int sh_type)
4881{
4882 switch (sh_type)
4883 {
4884 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4885 case SHT_NFP_INITREG: return "NFP_INITREG";
4886 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4887 default: return NULL;
4888 }
4889}
4890
685080f2
NC
4891static const char *
4892get_v850_section_type_name (unsigned int sh_type)
4893{
4894 switch (sh_type)
4895 {
32ec8896
NC
4896 case SHT_V850_SCOMMON: return "V850 Small Common";
4897 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4898 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4899 case SHT_RENESAS_IOP: return "RENESAS IOP";
4900 case SHT_RENESAS_INFO: return "RENESAS INFO";
4901 default: return NULL;
685080f2
NC
4902 }
4903}
4904
2dc8dd17
JW
4905static const char *
4906get_riscv_section_type_name (unsigned int sh_type)
4907{
4908 switch (sh_type)
4909 {
4910 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4911 default: return NULL;
4912 }
4913}
4914
0861f561
CQ
4915static const char *
4916get_csky_section_type_name (unsigned int sh_type)
4917{
4918 switch (sh_type)
4919 {
4920 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4921 default: return NULL;
4922 }
4923}
4924
252b5132 4925static const char *
dda8d76d 4926get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4927{
b34976b6 4928 static char buff[32];
9fb71ee4 4929 const char * result;
252b5132
RH
4930
4931 switch (sh_type)
4932 {
4933 case SHT_NULL: return "NULL";
4934 case SHT_PROGBITS: return "PROGBITS";
4935 case SHT_SYMTAB: return "SYMTAB";
4936 case SHT_STRTAB: return "STRTAB";
4937 case SHT_RELA: return "RELA";
dd207c13 4938 case SHT_RELR: return "RELR";
252b5132
RH
4939 case SHT_HASH: return "HASH";
4940 case SHT_DYNAMIC: return "DYNAMIC";
4941 case SHT_NOTE: return "NOTE";
4942 case SHT_NOBITS: return "NOBITS";
4943 case SHT_REL: return "REL";
4944 case SHT_SHLIB: return "SHLIB";
4945 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4946 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4947 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4948 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4949 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4950 case SHT_GROUP: return "GROUP";
67ce483b 4951 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4952 case SHT_GNU_verdef: return "VERDEF";
4953 case SHT_GNU_verneed: return "VERNEED";
4954 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4955 case 0x6ffffff0: return "VERSYM";
4956 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4957 case 0x7ffffffd: return "AUXILIARY";
4958 case 0x7fffffff: return "FILTER";
047b2264 4959 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4960
4961 default:
4962 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4963 {
dda8d76d 4964 switch (filedata->file_header.e_machine)
252b5132 4965 {
53a346d8
CZ
4966 case EM_ARC:
4967 case EM_ARC_COMPACT:
4968 case EM_ARC_COMPACT2:
4969 result = get_arc_section_type_name (sh_type);
4970 break;
252b5132 4971 case EM_MIPS:
4fe85591 4972 case EM_MIPS_RS3_LE:
252b5132
RH
4973 result = get_mips_section_type_name (sh_type);
4974 break;
103f02d3
UD
4975 case EM_PARISC:
4976 result = get_parisc_section_type_name (sh_type);
4977 break;
4d6ed7c8 4978 case EM_IA_64:
dda8d76d 4979 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4980 break;
d2b2c203 4981 case EM_X86_64:
8a9036a4 4982 case EM_L1OM:
7a9068fe 4983 case EM_K1OM:
d2b2c203
DJ
4984 result = get_x86_64_section_type_name (sh_type);
4985 break;
a06ea964
NC
4986 case EM_AARCH64:
4987 result = get_aarch64_section_type_name (sh_type);
4988 break;
40a18ebd
NC
4989 case EM_ARM:
4990 result = get_arm_section_type_name (sh_type);
4991 break;
40b36596
JM
4992 case EM_TI_C6000:
4993 result = get_tic6x_section_type_name (sh_type);
4994 break;
13761a11 4995 case EM_MSP430:
b0191216 4996 result = get_msp430_section_type_name (sh_type);
13761a11 4997 break;
fe944acf
FT
4998 case EM_NFP:
4999 result = get_nfp_section_type_name (sh_type);
5000 break;
685080f2
NC
5001 case EM_V800:
5002 case EM_V850:
5003 case EM_CYGNUS_V850:
5004 result = get_v850_section_type_name (sh_type);
5005 break;
2dc8dd17
JW
5006 case EM_RISCV:
5007 result = get_riscv_section_type_name (sh_type);
5008 break;
0861f561
CQ
5009 case EM_CSKY:
5010 result = get_csky_section_type_name (sh_type);
5011 break;
252b5132
RH
5012 default:
5013 result = NULL;
5014 break;
5015 }
5016
5017 if (result != NULL)
5018 return result;
5019
9fb71ee4 5020 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5021 }
5022 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5023 {
dda8d76d 5024 switch (filedata->file_header.e_machine)
148b93f2
NC
5025 {
5026 case EM_IA_64:
dda8d76d 5027 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5028 break;
5029 default:
dda8d76d 5030 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5031 result = get_solaris_section_type (sh_type);
5032 else
1b4b80bf
NC
5033 {
5034 switch (sh_type)
5035 {
5036 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5037 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5038 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5039 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5040 default:
5041 result = NULL;
5042 break;
5043 }
5044 }
148b93f2
NC
5045 break;
5046 }
5047
5048 if (result != NULL)
5049 return result;
5050
9fb71ee4 5051 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5052 }
252b5132 5053 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5054 {
dda8d76d 5055 switch (filedata->file_header.e_machine)
685080f2
NC
5056 {
5057 case EM_V800:
5058 case EM_V850:
5059 case EM_CYGNUS_V850:
9fb71ee4 5060 result = get_v850_section_type_name (sh_type);
a9fb83be 5061 break;
685080f2 5062 default:
9fb71ee4 5063 result = NULL;
685080f2
NC
5064 break;
5065 }
5066
9fb71ee4
NC
5067 if (result != NULL)
5068 return result;
5069
5070 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5071 }
252b5132 5072 else
a7dbfd1c
NC
5073 /* This message is probably going to be displayed in a 15
5074 character wide field, so put the hex value first. */
5075 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5076
252b5132
RH
5077 return buff;
5078 }
5079}
5080
79bc120c
NC
5081enum long_option_values
5082{
5083 OPTION_DEBUG_DUMP = 512,
5084 OPTION_DYN_SYMS,
0f03783c 5085 OPTION_LTO_SYMS,
79bc120c
NC
5086 OPTION_DWARF_DEPTH,
5087 OPTION_DWARF_START,
5088 OPTION_DWARF_CHECK,
5089 OPTION_CTF_DUMP,
5090 OPTION_CTF_PARENT,
5091 OPTION_CTF_SYMBOLS,
5092 OPTION_CTF_STRINGS,
5093 OPTION_WITH_SYMBOL_VERSIONS,
5094 OPTION_RECURSE_LIMIT,
5095 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5096 OPTION_NO_DEMANGLING,
5097 OPTION_SYM_BASE
79bc120c 5098};
2979dc34 5099
85b1c36d 5100static struct option options[] =
252b5132 5101{
79bc120c
NC
5102 /* Note - This table is alpha-sorted on the 'val'
5103 field in order to make adding new options easier. */
5104 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5105 {"all", no_argument, 0, 'a'},
79bc120c
NC
5106 {"demangle", optional_argument, 0, 'C'},
5107 {"archive-index", no_argument, 0, 'c'},
5108 {"use-dynamic", no_argument, 0, 'D'},
5109 {"dynamic", no_argument, 0, 'd'},
b34976b6 5110 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5111 {"section-groups", no_argument, 0, 'g'},
5112 {"help", no_argument, 0, 'H'},
5113 {"file-header", no_argument, 0, 'h'},
b34976b6 5114 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5115 {"lint", no_argument, 0, 'L'},
5116 {"enable-checks", no_argument, 0, 'L'},
5117 {"program-headers", no_argument, 0, 'l'},
b34976b6 5118 {"segments", no_argument, 0, 'l'},
595cf52e 5119 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5120 {"notes", no_argument, 0, 'n'},
ca0e11aa 5121 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5122 {"string-dump", required_argument, 0, 'p'},
5123 {"relocated-dump", required_argument, 0, 'R'},
5124 {"relocs", no_argument, 0, 'r'},
5125 {"section-headers", no_argument, 0, 'S'},
5126 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5127 {"symbols", no_argument, 0, 's'},
5128 {"syms", no_argument, 0, 's'},
79bc120c
NC
5129 {"silent-truncation",no_argument, 0, 'T'},
5130 {"section-details", no_argument, 0, 't'},
b3aa80b4 5131 {"unicode", required_argument, NULL, 'U'},
09c11c86 5132 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5133 {"version-info", no_argument, 0, 'V'},
5134 {"version", no_argument, 0, 'v'},
5135 {"wide", no_argument, 0, 'W'},
b34976b6 5136 {"hex-dump", required_argument, 0, 'x'},
0e602686 5137 {"decompress", no_argument, 0, 'z'},
252b5132 5138
79bc120c
NC
5139 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5140 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5141 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5142 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5143 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5144 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5145 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5146 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5147 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5148 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5149#ifdef ENABLE_LIBCTF
d344b407 5150 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5151 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5152 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5153 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5154#endif
047c3dbf 5155 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5156
b34976b6 5157 {0, no_argument, 0, 0}
252b5132
RH
5158};
5159
5160static void
2cf0635d 5161usage (FILE * stream)
252b5132 5162{
92f01d61
JM
5163 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5164 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5165 fprintf (stream, _(" Options are:\n"));
5166 fprintf (stream, _("\
5167 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5168 fprintf (stream, _("\
5169 -h --file-header Display the ELF file header\n"));
5170 fprintf (stream, _("\
5171 -l --program-headers Display the program headers\n"));
5172 fprintf (stream, _("\
5173 --segments An alias for --program-headers\n"));
5174 fprintf (stream, _("\
5175 -S --section-headers Display the sections' header\n"));
5176 fprintf (stream, _("\
5177 --sections An alias for --section-headers\n"));
5178 fprintf (stream, _("\
5179 -g --section-groups Display the section groups\n"));
5180 fprintf (stream, _("\
5181 -t --section-details Display the section details\n"));
5182 fprintf (stream, _("\
5183 -e --headers Equivalent to: -h -l -S\n"));
5184 fprintf (stream, _("\
5185 -s --syms Display the symbol table\n"));
5186 fprintf (stream, _("\
5187 --symbols An alias for --syms\n"));
5188 fprintf (stream, _("\
5189 --dyn-syms Display the dynamic symbol table\n"));
5190 fprintf (stream, _("\
5191 --lto-syms Display LTO symbol tables\n"));
5192 fprintf (stream, _("\
047c3dbf
NL
5193 --sym-base=[0|8|10|16] \n\
5194 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5195 mixed (the default), octal, decimal, hexadecimal.\n"));
5196 fprintf (stream, _("\
0d646226
AM
5197 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5198 display_demangler_styles (stream, _("\
5199 STYLE can be "));
d6249f5f
AM
5200 fprintf (stream, _("\
5201 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5202 fprintf (stream, _("\
5203 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5204 fprintf (stream, _("\
5205 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5206 fprintf (stream, _("\
5207 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5208 Display unicode characters as determined by the current locale\n\
5209 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5210 escape sequences, or treat them as invalid and display as\n\
5211 \"{hex sequences}\"\n"));
d6249f5f
AM
5212 fprintf (stream, _("\
5213 -n --notes Display the core notes (if present)\n"));
5214 fprintf (stream, _("\
5215 -r --relocs Display the relocations (if present)\n"));
5216 fprintf (stream, _("\
5217 -u --unwind Display the unwind info (if present)\n"));
5218 fprintf (stream, _("\
5219 -d --dynamic Display the dynamic section (if present)\n"));
5220 fprintf (stream, _("\
5221 -V --version-info Display the version sections (if present)\n"));
5222 fprintf (stream, _("\
5223 -A --arch-specific Display architecture specific information (if any)\n"));
5224 fprintf (stream, _("\
5225 -c --archive-index Display the symbol/file index in an archive\n"));
5226 fprintf (stream, _("\
5227 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5228 fprintf (stream, _("\
5229 -L --lint|--enable-checks\n\
5230 Display warning messages for possible problems\n"));
5231 fprintf (stream, _("\
09c11c86 5232 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5233 Dump the contents of section <number|name> as bytes\n"));
5234 fprintf (stream, _("\
09c11c86 5235 -p --string-dump=<number|name>\n\
d6249f5f
AM
5236 Dump the contents of section <number|name> as strings\n"));
5237 fprintf (stream, _("\
cf13d699 5238 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5239 Dump the relocated contents of section <number|name>\n"));
5240 fprintf (stream, _("\
5241 -z --decompress Decompress section before dumping it\n"));
5242 fprintf (stream, _("\
5243 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5244 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5245 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5246 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5247 U/=trace_info]\n\
5248 Display the contents of DWARF debug sections\n"));
5249 fprintf (stream, _("\
5250 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5251 debuginfo files\n"));
5252 fprintf (stream, _("\
5253 -P --process-links Display the contents of non-debug sections in separate\n\
5254 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5255#if DEFAULT_FOR_FOLLOW_LINKS
5256 fprintf (stream, _("\
d6249f5f
AM
5257 -wK --debug-dump=follow-links\n\
5258 Follow links to separate debug info files (default)\n"));
5259 fprintf (stream, _("\
5260 -wN --debug-dump=no-follow-links\n\
5261 Do not follow links to separate debug info files\n"));
c46b7066
NC
5262#else
5263 fprintf (stream, _("\
d6249f5f
AM
5264 -wK --debug-dump=follow-links\n\
5265 Follow links to separate debug info files\n"));
5266 fprintf (stream, _("\
5267 -wN --debug-dump=no-follow-links\n\
5268 Do not follow links to separate debug info files\n\
5269 (default)\n"));
bed566bb
NC
5270#endif
5271#if HAVE_LIBDEBUGINFOD
5272 fprintf (stream, _("\
5273 -wD --debug-dump=use-debuginfod\n\
5274 When following links, also query debuginfod servers (default)\n"));
5275 fprintf (stream, _("\
5276 -wE --debug-dump=do-not-use-debuginfod\n\
5277 When following links, do not query debuginfod servers\n"));
c46b7066 5278#endif
fd2f0033 5279 fprintf (stream, _("\
d6249f5f
AM
5280 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5281 fprintf (stream, _("\
5282 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5283#ifdef ENABLE_LIBCTF
7d9813f1 5284 fprintf (stream, _("\
d6249f5f
AM
5285 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5286 fprintf (stream, _("\
80b56fad 5287 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5288 fprintf (stream, _("\
7d9813f1 5289 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5290 Use section <number|name> as the CTF external symtab\n"));
5291 fprintf (stream, _("\
7d9813f1 5292 --ctf-strings=<number|name>\n\
d6249f5f 5293 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5294#endif
7d9813f1 5295
252b5132 5296#ifdef SUPPORT_DISASSEMBLY
92f01d61 5297 fprintf (stream, _("\
09c11c86
NC
5298 -i --instruction-dump=<number|name>\n\
5299 Disassemble the contents of section <number|name>\n"));
252b5132 5300#endif
92f01d61 5301 fprintf (stream, _("\
d6249f5f
AM
5302 -I --histogram Display histogram of bucket list lengths\n"));
5303 fprintf (stream, _("\
5304 -W --wide Allow output width to exceed 80 characters\n"));
5305 fprintf (stream, _("\
5306 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5307 fprintf (stream, _("\
5308 @<file> Read options from <file>\n"));
5309 fprintf (stream, _("\
5310 -H --help Display this information\n"));
5311 fprintf (stream, _("\
8b53311e 5312 -v --version Display the version number of readelf\n"));
1118d252 5313
92f01d61
JM
5314 if (REPORT_BUGS_TO[0] && stream == stdout)
5315 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5316
92f01d61 5317 exit (stream == stdout ? 0 : 1);
252b5132
RH
5318}
5319
18bd398b
NC
5320/* Record the fact that the user wants the contents of section number
5321 SECTION to be displayed using the method(s) encoded as flags bits
5322 in TYPE. Note, TYPE can be zero if we are creating the array for
5323 the first time. */
5324
252b5132 5325static void
6431e409
AM
5326request_dump_bynumber (struct dump_data *dumpdata,
5327 unsigned int section, dump_type type)
252b5132 5328{
6431e409 5329 if (section >= dumpdata->num_dump_sects)
252b5132 5330 {
2cf0635d 5331 dump_type * new_dump_sects;
252b5132 5332
3f5e193b 5333 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5334 sizeof (* new_dump_sects));
252b5132
RH
5335
5336 if (new_dump_sects == NULL)
591a748a 5337 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5338 else
5339 {
6431e409 5340 if (dumpdata->dump_sects)
21b65bac
NC
5341 {
5342 /* Copy current flag settings. */
6431e409
AM
5343 memcpy (new_dump_sects, dumpdata->dump_sects,
5344 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5345
6431e409 5346 free (dumpdata->dump_sects);
21b65bac 5347 }
252b5132 5348
6431e409
AM
5349 dumpdata->dump_sects = new_dump_sects;
5350 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5351 }
5352 }
5353
6431e409
AM
5354 if (dumpdata->dump_sects)
5355 dumpdata->dump_sects[section] |= type;
252b5132
RH
5356}
5357
aef1f6d0
DJ
5358/* Request a dump by section name. */
5359
5360static void
2cf0635d 5361request_dump_byname (const char * section, dump_type type)
aef1f6d0 5362{
2cf0635d 5363 struct dump_list_entry * new_request;
aef1f6d0 5364
3f5e193b
NC
5365 new_request = (struct dump_list_entry *)
5366 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5367 if (!new_request)
591a748a 5368 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5369
5370 new_request->name = strdup (section);
5371 if (!new_request->name)
591a748a 5372 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5373
5374 new_request->type = type;
5375
5376 new_request->next = dump_sects_byname;
5377 dump_sects_byname = new_request;
5378}
5379
cf13d699 5380static inline void
6431e409 5381request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5382{
5383 int section;
5384 char * cp;
5385
015dc7e1 5386 do_dump = true;
cf13d699
NC
5387 section = strtoul (optarg, & cp, 0);
5388
5389 if (! *cp && section >= 0)
6431e409 5390 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5391 else
5392 request_dump_byname (optarg, type);
5393}
5394
252b5132 5395static void
6431e409 5396parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5397{
5398 int c;
5399
5400 if (argc < 2)
92f01d61 5401 usage (stderr);
252b5132
RH
5402
5403 while ((c = getopt_long
b3aa80b4 5404 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5405 {
252b5132
RH
5406 switch (c)
5407 {
5408 case 0:
5409 /* Long options. */
5410 break;
5411 case 'H':
92f01d61 5412 usage (stdout);
252b5132
RH
5413 break;
5414
5415 case 'a':
015dc7e1
AM
5416 do_syms = true;
5417 do_reloc = true;
5418 do_unwind = true;
5419 do_dynamic = true;
5420 do_header = true;
5421 do_sections = true;
5422 do_section_groups = true;
5423 do_segments = true;
5424 do_version = true;
5425 do_histogram = true;
5426 do_arch = true;
5427 do_notes = true;
252b5132 5428 break;
79bc120c 5429
f5842774 5430 case 'g':
015dc7e1 5431 do_section_groups = true;
f5842774 5432 break;
5477e8a0 5433 case 't':
595cf52e 5434 case 'N':
015dc7e1
AM
5435 do_sections = true;
5436 do_section_details = true;
595cf52e 5437 break;
252b5132 5438 case 'e':
015dc7e1
AM
5439 do_header = true;
5440 do_sections = true;
5441 do_segments = true;
252b5132 5442 break;
a952a375 5443 case 'A':
015dc7e1 5444 do_arch = true;
a952a375 5445 break;
252b5132 5446 case 'D':
015dc7e1 5447 do_using_dynamic = true;
252b5132
RH
5448 break;
5449 case 'r':
015dc7e1 5450 do_reloc = true;
252b5132 5451 break;
4d6ed7c8 5452 case 'u':
015dc7e1 5453 do_unwind = true;
4d6ed7c8 5454 break;
252b5132 5455 case 'h':
015dc7e1 5456 do_header = true;
252b5132
RH
5457 break;
5458 case 'l':
015dc7e1 5459 do_segments = true;
252b5132
RH
5460 break;
5461 case 's':
015dc7e1 5462 do_syms = true;
252b5132
RH
5463 break;
5464 case 'S':
015dc7e1 5465 do_sections = true;
252b5132
RH
5466 break;
5467 case 'd':
015dc7e1 5468 do_dynamic = true;
252b5132 5469 break;
a952a375 5470 case 'I':
015dc7e1 5471 do_histogram = true;
a952a375 5472 break;
779fe533 5473 case 'n':
015dc7e1 5474 do_notes = true;
779fe533 5475 break;
4145f1d5 5476 case 'c':
015dc7e1 5477 do_archive_index = true;
4145f1d5 5478 break;
1b513401 5479 case 'L':
015dc7e1 5480 do_checks = true;
1b513401 5481 break;
ca0e11aa 5482 case 'P':
015dc7e1
AM
5483 process_links = true;
5484 do_follow_links = true;
e1dbfc17 5485 dump_any_debugging = true;
ca0e11aa 5486 break;
252b5132 5487 case 'x':
6431e409 5488 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5489 break;
09c11c86 5490 case 'p':
6431e409 5491 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5492 break;
5493 case 'R':
6431e409 5494 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5495 break;
0e602686 5496 case 'z':
015dc7e1 5497 decompress_dumps = true;
0e602686 5498 break;
252b5132 5499 case 'w':
0f03783c 5500 if (optarg == NULL)
613ff48b 5501 {
015dc7e1 5502 do_debugging = true;
94585d6d
NC
5503 do_dump = true;
5504 dump_any_debugging = true;
613ff48b
CC
5505 dwarf_select_sections_all ();
5506 }
252b5132
RH
5507 else
5508 {
015dc7e1 5509 do_debugging = false;
94585d6d
NC
5510 if (dwarf_select_sections_by_letters (optarg))
5511 {
5512 do_dump = true;
5513 dump_any_debugging = true;
5514 }
252b5132
RH
5515 }
5516 break;
2979dc34 5517 case OPTION_DEBUG_DUMP:
0f03783c 5518 if (optarg == NULL)
d6249f5f 5519 {
94585d6d 5520 do_dump = true;
d6249f5f 5521 do_debugging = true;
94585d6d 5522 dump_any_debugging = true;
d6249f5f
AM
5523 dwarf_select_sections_all ();
5524 }
2979dc34
JJ
5525 else
5526 {
015dc7e1 5527 do_debugging = false;
94585d6d
NC
5528 if (dwarf_select_sections_by_names (optarg))
5529 {
5530 do_dump = true;
5531 dump_any_debugging = true;
5532 }
2979dc34
JJ
5533 }
5534 break;
fd2f0033
TT
5535 case OPTION_DWARF_DEPTH:
5536 {
5537 char *cp;
5538
5539 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5540 }
5541 break;
5542 case OPTION_DWARF_START:
5543 {
5544 char *cp;
5545
5546 dwarf_start_die = strtoul (optarg, & cp, 0);
5547 }
5548 break;
4723351a 5549 case OPTION_DWARF_CHECK:
015dc7e1 5550 dwarf_check = true;
4723351a 5551 break;
7d9813f1 5552 case OPTION_CTF_DUMP:
015dc7e1 5553 do_ctf = true;
6431e409 5554 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5555 break;
5556 case OPTION_CTF_SYMBOLS:
df16e041 5557 free (dump_ctf_symtab_name);
7d9813f1
NA
5558 dump_ctf_symtab_name = strdup (optarg);
5559 break;
5560 case OPTION_CTF_STRINGS:
df16e041 5561 free (dump_ctf_strtab_name);
7d9813f1
NA
5562 dump_ctf_strtab_name = strdup (optarg);
5563 break;
5564 case OPTION_CTF_PARENT:
df16e041 5565 free (dump_ctf_parent_name);
7d9813f1
NA
5566 dump_ctf_parent_name = strdup (optarg);
5567 break;
2c610e4b 5568 case OPTION_DYN_SYMS:
015dc7e1 5569 do_dyn_syms = true;
2c610e4b 5570 break;
0f03783c 5571 case OPTION_LTO_SYMS:
015dc7e1 5572 do_lto_syms = true;
0f03783c 5573 break;
252b5132
RH
5574#ifdef SUPPORT_DISASSEMBLY
5575 case 'i':
6431e409 5576 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5577 break;
252b5132
RH
5578#endif
5579 case 'v':
5580 print_version (program_name);
5581 break;
5582 case 'V':
015dc7e1 5583 do_version = true;
252b5132 5584 break;
d974e256 5585 case 'W':
015dc7e1 5586 do_wide = true;
d974e256 5587 break;
0942c7ab 5588 case 'T':
015dc7e1 5589 do_not_show_symbol_truncation = true;
0942c7ab 5590 break;
79bc120c 5591 case 'C':
015dc7e1 5592 do_demangle = true;
79bc120c
NC
5593 if (optarg != NULL)
5594 {
5595 enum demangling_styles style;
5596
5597 style = cplus_demangle_name_to_style (optarg);
5598 if (style == unknown_demangling)
5599 error (_("unknown demangling style `%s'"), optarg);
5600
5601 cplus_demangle_set_style (style);
5602 }
5603 break;
5604 case OPTION_NO_DEMANGLING:
015dc7e1 5605 do_demangle = false;
79bc120c
NC
5606 break;
5607 case OPTION_RECURSE_LIMIT:
5608 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5609 break;
5610 case OPTION_NO_RECURSE_LIMIT:
5611 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5612 break;
5613 case OPTION_WITH_SYMBOL_VERSIONS:
5614 /* Ignored for backward compatibility. */
5615 break;
b9e920ec 5616
b3aa80b4
NC
5617 case 'U':
5618 if (optarg == NULL)
5619 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5620 else if (streq (optarg, "default") || streq (optarg, "d"))
5621 unicode_display = unicode_default;
5622 else if (streq (optarg, "locale") || streq (optarg, "l"))
5623 unicode_display = unicode_locale;
5624 else if (streq (optarg, "escape") || streq (optarg, "e"))
5625 unicode_display = unicode_escape;
5626 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5627 unicode_display = unicode_invalid;
5628 else if (streq (optarg, "hex") || streq (optarg, "x"))
5629 unicode_display = unicode_hex;
5630 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5631 unicode_display = unicode_highlight;
5632 else
5633 error (_("invalid argument to -U/--unicode: %s"), optarg);
5634 break;
5635
047c3dbf
NL
5636 case OPTION_SYM_BASE:
5637 sym_base = 0;
5638 if (optarg != NULL)
5639 {
5640 sym_base = strtoul (optarg, NULL, 0);
5641 switch (sym_base)
5642 {
5643 case 0:
5644 case 8:
5645 case 10:
5646 case 16:
5647 break;
5648
5649 default:
5650 sym_base = 0;
5651 break;
5652 }
5653 }
5654 break;
5655
252b5132 5656 default:
252b5132
RH
5657 /* xgettext:c-format */
5658 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5659 /* Fall through. */
252b5132 5660 case '?':
92f01d61 5661 usage (stderr);
252b5132
RH
5662 }
5663 }
5664
4d6ed7c8 5665 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5666 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5667 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5668 && !do_section_groups && !do_archive_index
0f03783c 5669 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5670 {
5671 if (do_checks)
5672 {
015dc7e1
AM
5673 check_all = true;
5674 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5675 do_segments = do_header = do_dump = do_version = true;
5676 do_histogram = do_debugging = do_arch = do_notes = true;
5677 do_section_groups = do_archive_index = do_dyn_syms = true;
5678 do_lto_syms = true;
1b513401
NC
5679 }
5680 else
5681 usage (stderr);
5682 }
252b5132
RH
5683}
5684
5685static const char *
d3ba0551 5686get_elf_class (unsigned int elf_class)
252b5132 5687{
b34976b6 5688 static char buff[32];
103f02d3 5689
252b5132
RH
5690 switch (elf_class)
5691 {
5692 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5693 case ELFCLASS32: return "ELF32";
5694 case ELFCLASS64: return "ELF64";
ab5e7794 5695 default:
e9e44622 5696 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5697 return buff;
252b5132
RH
5698 }
5699}
5700
5701static const char *
d3ba0551 5702get_data_encoding (unsigned int encoding)
252b5132 5703{
b34976b6 5704 static char buff[32];
103f02d3 5705
252b5132
RH
5706 switch (encoding)
5707 {
5708 case ELFDATANONE: return _("none");
33c63f9d
CM
5709 case ELFDATA2LSB: return _("2's complement, little endian");
5710 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5711 default:
e9e44622 5712 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5713 return buff;
252b5132
RH
5714 }
5715}
5716
dda8d76d 5717/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5718
015dc7e1 5719static bool
dda8d76d 5720process_file_header (Filedata * filedata)
252b5132 5721{
dda8d76d
NC
5722 Elf_Internal_Ehdr * header = & filedata->file_header;
5723
5724 if ( header->e_ident[EI_MAG0] != ELFMAG0
5725 || header->e_ident[EI_MAG1] != ELFMAG1
5726 || header->e_ident[EI_MAG2] != ELFMAG2
5727 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5728 {
5729 error
5730 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5731 return false;
252b5132
RH
5732 }
5733
ca0e11aa
NC
5734 if (! filedata->is_separate)
5735 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5736
252b5132
RH
5737 if (do_header)
5738 {
32ec8896 5739 unsigned i;
252b5132 5740
ca0e11aa
NC
5741 if (filedata->is_separate)
5742 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5743 else
5744 printf (_("ELF Header:\n"));
252b5132 5745 printf (_(" Magic: "));
b34976b6 5746 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5747 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5748 printf ("\n");
5749 printf (_(" Class: %s\n"),
dda8d76d 5750 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5751 printf (_(" Data: %s\n"),
dda8d76d 5752 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5753 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5754 header->e_ident[EI_VERSION],
5755 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5756 ? _(" (current)")
dda8d76d 5757 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5758 ? _(" <unknown>")
789be9f7 5759 : "")));
252b5132 5760 printf (_(" OS/ABI: %s\n"),
dda8d76d 5761 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5762 printf (_(" ABI Version: %d\n"),
dda8d76d 5763 header->e_ident[EI_ABIVERSION]);
252b5132 5764 printf (_(" Type: %s\n"),
93df3340 5765 get_file_type (filedata));
252b5132 5766 printf (_(" Machine: %s\n"),
dda8d76d 5767 get_machine_name (header->e_machine));
252b5132 5768 printf (_(" Version: 0x%lx\n"),
e8a64888 5769 header->e_version);
76da6bbe 5770
f7a99963 5771 printf (_(" Entry point address: "));
e8a64888 5772 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5773 printf (_("\n Start of program headers: "));
e8a64888 5774 print_vma (header->e_phoff, DEC);
f7a99963 5775 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5776 print_vma (header->e_shoff, DEC);
f7a99963 5777 printf (_(" (bytes into file)\n"));
76da6bbe 5778
252b5132 5779 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5780 header->e_flags,
dda8d76d 5781 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5782 printf (_(" Size of this header: %u (bytes)\n"),
5783 header->e_ehsize);
5784 printf (_(" Size of program headers: %u (bytes)\n"),
5785 header->e_phentsize);
5786 printf (_(" Number of program headers: %u"),
5787 header->e_phnum);
dda8d76d
NC
5788 if (filedata->section_headers != NULL
5789 && header->e_phnum == PN_XNUM
5790 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5791 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5792 putc ('\n', stdout);
e8a64888
AM
5793 printf (_(" Size of section headers: %u (bytes)\n"),
5794 header->e_shentsize);
5795 printf (_(" Number of section headers: %u"),
5796 header->e_shnum);
dda8d76d 5797 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5798 {
5799 header->e_shnum = filedata->section_headers[0].sh_size;
5800 printf (" (%u)", header->e_shnum);
5801 }
560f3c1c 5802 putc ('\n', stdout);
e8a64888
AM
5803 printf (_(" Section header string table index: %u"),
5804 header->e_shstrndx);
dda8d76d
NC
5805 if (filedata->section_headers != NULL
5806 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5807 {
5808 header->e_shstrndx = filedata->section_headers[0].sh_link;
5809 printf (" (%u)", header->e_shstrndx);
5810 }
5811 if (header->e_shstrndx != SHN_UNDEF
5812 && header->e_shstrndx >= header->e_shnum)
5813 {
5814 header->e_shstrndx = SHN_UNDEF;
5815 printf (_(" <corrupt: out of range>"));
5816 }
560f3c1c
AM
5817 putc ('\n', stdout);
5818 }
5819
dda8d76d 5820 if (filedata->section_headers != NULL)
560f3c1c 5821 {
dda8d76d
NC
5822 if (header->e_phnum == PN_XNUM
5823 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5824 {
5825 /* Throw away any cached read of PN_XNUM headers. */
5826 free (filedata->program_headers);
5827 filedata->program_headers = NULL;
5828 header->e_phnum = filedata->section_headers[0].sh_info;
5829 }
dda8d76d
NC
5830 if (header->e_shnum == SHN_UNDEF)
5831 header->e_shnum = filedata->section_headers[0].sh_size;
5832 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5833 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5834 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5835 header->e_shstrndx = SHN_UNDEF;
252b5132 5836 }
103f02d3 5837
015dc7e1 5838 return true;
9ea033b2
NC
5839}
5840
dda8d76d
NC
5841/* Read in the program headers from FILEDATA and store them in PHEADERS.
5842 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5843
015dc7e1 5844static bool
dda8d76d 5845get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5846{
2cf0635d
NC
5847 Elf32_External_Phdr * phdrs;
5848 Elf32_External_Phdr * external;
5849 Elf_Internal_Phdr * internal;
b34976b6 5850 unsigned int i;
dda8d76d
NC
5851 unsigned int size = filedata->file_header.e_phentsize;
5852 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5853
5854 /* PR binutils/17531: Cope with unexpected section header sizes. */
5855 if (size == 0 || num == 0)
015dc7e1 5856 return false;
e0a31db1
NC
5857 if (size < sizeof * phdrs)
5858 {
5859 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5860 return false;
e0a31db1
NC
5861 }
5862 if (size > sizeof * phdrs)
5863 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5864
dda8d76d 5865 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5866 size, num, _("program headers"));
5867 if (phdrs == NULL)
015dc7e1 5868 return false;
9ea033b2 5869
91d6fa6a 5870 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5871 i < filedata->file_header.e_phnum;
b34976b6 5872 i++, internal++, external++)
252b5132 5873 {
9ea033b2
NC
5874 internal->p_type = BYTE_GET (external->p_type);
5875 internal->p_offset = BYTE_GET (external->p_offset);
5876 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5877 internal->p_paddr = BYTE_GET (external->p_paddr);
5878 internal->p_filesz = BYTE_GET (external->p_filesz);
5879 internal->p_memsz = BYTE_GET (external->p_memsz);
5880 internal->p_flags = BYTE_GET (external->p_flags);
5881 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5882 }
5883
9ea033b2 5884 free (phdrs);
015dc7e1 5885 return true;
252b5132
RH
5886}
5887
dda8d76d
NC
5888/* Read in the program headers from FILEDATA and store them in PHEADERS.
5889 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5890
015dc7e1 5891static bool
dda8d76d 5892get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5893{
2cf0635d
NC
5894 Elf64_External_Phdr * phdrs;
5895 Elf64_External_Phdr * external;
5896 Elf_Internal_Phdr * internal;
b34976b6 5897 unsigned int i;
dda8d76d
NC
5898 unsigned int size = filedata->file_header.e_phentsize;
5899 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5900
5901 /* PR binutils/17531: Cope with unexpected section header sizes. */
5902 if (size == 0 || num == 0)
015dc7e1 5903 return false;
e0a31db1
NC
5904 if (size < sizeof * phdrs)
5905 {
5906 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5907 return false;
e0a31db1
NC
5908 }
5909 if (size > sizeof * phdrs)
5910 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5911
dda8d76d 5912 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5913 size, num, _("program headers"));
a6e9f9df 5914 if (!phdrs)
015dc7e1 5915 return false;
9ea033b2 5916
91d6fa6a 5917 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5918 i < filedata->file_header.e_phnum;
b34976b6 5919 i++, internal++, external++)
9ea033b2
NC
5920 {
5921 internal->p_type = BYTE_GET (external->p_type);
5922 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5923 internal->p_offset = BYTE_GET (external->p_offset);
5924 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5925 internal->p_paddr = BYTE_GET (external->p_paddr);
5926 internal->p_filesz = BYTE_GET (external->p_filesz);
5927 internal->p_memsz = BYTE_GET (external->p_memsz);
5928 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5929 }
5930
5931 free (phdrs);
015dc7e1 5932 return true;
9ea033b2 5933}
252b5132 5934
32ec8896 5935/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5936
015dc7e1 5937static bool
dda8d76d 5938get_program_headers (Filedata * filedata)
d93f0186 5939{
2cf0635d 5940 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5941
5942 /* Check cache of prior read. */
dda8d76d 5943 if (filedata->program_headers != NULL)
015dc7e1 5944 return true;
d93f0186 5945
82156ab7
NC
5946 /* Be kind to memory checkers by looking for
5947 e_phnum values which we know must be invalid. */
dda8d76d 5948 if (filedata->file_header.e_phnum
82156ab7 5949 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5950 >= filedata->file_size)
82156ab7
NC
5951 {
5952 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5953 filedata->file_header.e_phnum);
015dc7e1 5954 return false;
82156ab7 5955 }
d93f0186 5956
dda8d76d 5957 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5958 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5959 if (phdrs == NULL)
5960 {
8b73c356 5961 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5962 filedata->file_header.e_phnum);
015dc7e1 5963 return false;
d93f0186
NC
5964 }
5965
5966 if (is_32bit_elf
dda8d76d
NC
5967 ? get_32bit_program_headers (filedata, phdrs)
5968 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5969 {
dda8d76d 5970 filedata->program_headers = phdrs;
015dc7e1 5971 return true;
d93f0186
NC
5972 }
5973
5974 free (phdrs);
015dc7e1 5975 return false;
d93f0186
NC
5976}
5977
93df3340 5978/* Print program header info and locate dynamic section. */
2f62977e 5979
93df3340 5980static void
dda8d76d 5981process_program_headers (Filedata * filedata)
252b5132 5982{
2cf0635d 5983 Elf_Internal_Phdr * segment;
b34976b6 5984 unsigned int i;
1a9ccd70 5985 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5986
dda8d76d 5987 if (filedata->file_header.e_phnum == 0)
252b5132 5988 {
82f2dbf7 5989 /* PR binutils/12467. */
dda8d76d 5990 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5991 warn (_("possibly corrupt ELF header - it has a non-zero program"
5992 " header offset, but no program headers\n"));
82f2dbf7 5993 else if (do_segments)
ca0e11aa
NC
5994 {
5995 if (filedata->is_separate)
5996 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5997 filedata->file_name);
5998 else
5999 printf (_("\nThere are no program headers in this file.\n"));
6000 }
93df3340 6001 goto no_headers;
252b5132
RH
6002 }
6003
6004 if (do_segments && !do_header)
6005 {
ca0e11aa
NC
6006 if (filedata->is_separate)
6007 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6008 filedata->file_name, get_file_type (filedata));
ca0e11aa 6009 else
93df3340 6010 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767
AM
6011 printf (_("Entry point 0x%" PRIx64 "\n"),
6012 (uint64_t) filedata->file_header.e_entry);
6013 printf (ngettext ("There is %d program header,"
6014 " starting at offset %" PRIu64 "\n",
6015 "There are %d program headers,"
6016 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6017 filedata->file_header.e_phnum),
6018 filedata->file_header.e_phnum,
b8281767 6019 (uint64_t) filedata->file_header.e_phoff);
252b5132
RH
6020 }
6021
dda8d76d 6022 if (! get_program_headers (filedata))
93df3340 6023 goto no_headers;
103f02d3 6024
252b5132
RH
6025 if (do_segments)
6026 {
dda8d76d 6027 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6028 printf (_("\nProgram Headers:\n"));
6029 else
6030 printf (_("\nProgram Headers:\n"));
76da6bbe 6031
f7a99963
NC
6032 if (is_32bit_elf)
6033 printf
6034 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6035 else if (do_wide)
6036 printf
6037 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6038 else
6039 {
6040 printf
6041 (_(" Type Offset VirtAddr PhysAddr\n"));
6042 printf
6043 (_(" FileSiz MemSiz Flags Align\n"));
6044 }
252b5132
RH
6045 }
6046
93df3340
AM
6047 unsigned long dynamic_addr = 0;
6048 bfd_size_type dynamic_size = 0;
dda8d76d
NC
6049 for (i = 0, segment = filedata->program_headers;
6050 i < filedata->file_header.e_phnum;
b34976b6 6051 i++, segment++)
252b5132
RH
6052 {
6053 if (do_segments)
6054 {
dda8d76d 6055 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6056
6057 if (is_32bit_elf)
6058 {
6059 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6060 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6061 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6062 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6063 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6064 printf ("%c%c%c ",
6065 (segment->p_flags & PF_R ? 'R' : ' '),
6066 (segment->p_flags & PF_W ? 'W' : ' '),
6067 (segment->p_flags & PF_X ? 'E' : ' '));
6068 printf ("%#lx", (unsigned long) segment->p_align);
6069 }
d974e256
JJ
6070 else if (do_wide)
6071 {
6072 if ((unsigned long) segment->p_offset == segment->p_offset)
6073 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6074 else
6075 {
6076 print_vma (segment->p_offset, FULL_HEX);
6077 putchar (' ');
6078 }
6079
6080 print_vma (segment->p_vaddr, FULL_HEX);
6081 putchar (' ');
6082 print_vma (segment->p_paddr, FULL_HEX);
6083 putchar (' ');
6084
6085 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6086 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6087 else
6088 {
6089 print_vma (segment->p_filesz, FULL_HEX);
6090 putchar (' ');
6091 }
6092
6093 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6094 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6095 else
6096 {
f48e6c45 6097 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6098 }
6099
6100 printf (" %c%c%c ",
6101 (segment->p_flags & PF_R ? 'R' : ' '),
6102 (segment->p_flags & PF_W ? 'W' : ' '),
6103 (segment->p_flags & PF_X ? 'E' : ' '));
6104
6105 if ((unsigned long) segment->p_align == segment->p_align)
6106 printf ("%#lx", (unsigned long) segment->p_align);
6107 else
6108 {
6109 print_vma (segment->p_align, PREFIX_HEX);
6110 }
6111 }
f7a99963
NC
6112 else
6113 {
6114 print_vma (segment->p_offset, FULL_HEX);
6115 putchar (' ');
6116 print_vma (segment->p_vaddr, FULL_HEX);
6117 putchar (' ');
6118 print_vma (segment->p_paddr, FULL_HEX);
6119 printf ("\n ");
6120 print_vma (segment->p_filesz, FULL_HEX);
6121 putchar (' ');
6122 print_vma (segment->p_memsz, FULL_HEX);
6123 printf (" %c%c%c ",
6124 (segment->p_flags & PF_R ? 'R' : ' '),
6125 (segment->p_flags & PF_W ? 'W' : ' '),
6126 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6127 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6128 }
252b5132 6129
1a9ccd70
NC
6130 putc ('\n', stdout);
6131 }
f54498b4 6132
252b5132
RH
6133 switch (segment->p_type)
6134 {
1a9ccd70 6135 case PT_LOAD:
502d895c
NC
6136#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6137 required by the ELF standard, several programs, including the Linux
6138 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6139 if (previous_load
6140 && previous_load->p_vaddr > segment->p_vaddr)
6141 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6142#endif
1a9ccd70
NC
6143 if (segment->p_memsz < segment->p_filesz)
6144 error (_("the segment's file size is larger than its memory size\n"));
6145 previous_load = segment;
6146 break;
6147
6148 case PT_PHDR:
6149 /* PR 20815 - Verify that the program header is loaded into memory. */
6150 if (i > 0 && previous_load != NULL)
6151 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6152 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6153 {
6154 unsigned int j;
6155
dda8d76d 6156 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6157 {
6158 Elf_Internal_Phdr *load = filedata->program_headers + j;
6159 if (load->p_type == PT_LOAD
6160 && load->p_offset <= segment->p_offset
6161 && (load->p_offset + load->p_filesz
6162 >= segment->p_offset + segment->p_filesz)
6163 && load->p_vaddr <= segment->p_vaddr
6164 && (load->p_vaddr + load->p_filesz
6165 >= segment->p_vaddr + segment->p_filesz))
6166 break;
6167 }
dda8d76d 6168 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6169 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6170 }
6171 break;
6172
252b5132 6173 case PT_DYNAMIC:
93df3340 6174 if (dynamic_addr)
252b5132
RH
6175 error (_("more than one dynamic segment\n"));
6176
20737c13
AM
6177 /* By default, assume that the .dynamic section is the first
6178 section in the DYNAMIC segment. */
93df3340
AM
6179 dynamic_addr = segment->p_offset;
6180 dynamic_size = segment->p_filesz;
20737c13 6181
b2d38a17
NC
6182 /* Try to locate the .dynamic section. If there is
6183 a section header table, we can easily locate it. */
dda8d76d 6184 if (filedata->section_headers != NULL)
b2d38a17 6185 {
2cf0635d 6186 Elf_Internal_Shdr * sec;
b2d38a17 6187
dda8d76d 6188 sec = find_section (filedata, ".dynamic");
89fac5e3 6189 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6190 {
93df3340
AM
6191 /* A corresponding .dynamic section is expected, but on
6192 IA-64/OpenVMS it is OK for it to be missing. */
6193 if (!is_ia64_vms (filedata))
6194 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6195 break;
6196 }
6197
42bb2e33 6198 if (sec->sh_type == SHT_NOBITS)
20737c13 6199 {
93df3340
AM
6200 dynamic_addr = 0;
6201 dynamic_size = 0;
20737c13
AM
6202 break;
6203 }
42bb2e33 6204
93df3340
AM
6205 dynamic_addr = sec->sh_offset;
6206 dynamic_size = sec->sh_size;
b2d38a17 6207
8ac10c5b
L
6208 /* The PT_DYNAMIC segment, which is used by the run-time
6209 loader, should exactly match the .dynamic section. */
6210 if (do_checks
93df3340
AM
6211 && (dynamic_addr != segment->p_offset
6212 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6213 warn (_("\
6214the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6215 }
39e224f6
MW
6216
6217 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6218 segment. Check this after matching against the section headers
6219 so we don't warn on debuginfo file (which have NOBITS .dynamic
6220 sections). */
93df3340
AM
6221 if (dynamic_addr > filedata->file_size
6222 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6223 {
6224 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6225 dynamic_addr = 0;
6226 dynamic_size = 0;
39e224f6 6227 }
252b5132
RH
6228 break;
6229
6230 case PT_INTERP:
13acb58d
AM
6231 if (segment->p_offset >= filedata->file_size
6232 || segment->p_filesz > filedata->file_size - segment->p_offset
6233 || segment->p_filesz - 1 >= (size_t) -2
6234 || fseek (filedata->handle,
6235 filedata->archive_file_offset + (long) segment->p_offset,
6236 SEEK_SET))
252b5132
RH
6237 error (_("Unable to find program interpreter name\n"));
6238 else
6239 {
13acb58d
AM
6240 size_t len = segment->p_filesz;
6241 free (filedata->program_interpreter);
6242 filedata->program_interpreter = xmalloc (len + 1);
6243 len = fread (filedata->program_interpreter, 1, len,
6244 filedata->handle);
6245 filedata->program_interpreter[len] = 0;
252b5132
RH
6246
6247 if (do_segments)
f54498b4 6248 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6249 filedata->program_interpreter);
252b5132
RH
6250 }
6251 break;
6252 }
252b5132
RH
6253 }
6254
dda8d76d
NC
6255 if (do_segments
6256 && filedata->section_headers != NULL
6257 && filedata->string_table != NULL)
252b5132
RH
6258 {
6259 printf (_("\n Section to Segment mapping:\n"));
6260 printf (_(" Segment Sections...\n"));
6261
dda8d76d 6262 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6263 {
9ad5cbcf 6264 unsigned int j;
2cf0635d 6265 Elf_Internal_Shdr * section;
252b5132 6266
dda8d76d
NC
6267 segment = filedata->program_headers + i;
6268 section = filedata->section_headers + 1;
252b5132
RH
6269
6270 printf (" %2.2d ", i);
6271
dda8d76d 6272 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6273 {
f4638467
AM
6274 if (!ELF_TBSS_SPECIAL (section, segment)
6275 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6276 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6277 }
6278
6279 putc ('\n',stdout);
6280 }
6281 }
6282
93df3340
AM
6283 filedata->dynamic_addr = dynamic_addr;
6284 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6285 return;
6286
6287 no_headers:
6288 filedata->dynamic_addr = 0;
6289 filedata->dynamic_size = 1;
252b5132
RH
6290}
6291
6292
d93f0186
NC
6293/* Find the file offset corresponding to VMA by using the program headers. */
6294
6295static long
dda8d76d 6296offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6297{
2cf0635d 6298 Elf_Internal_Phdr * seg;
d93f0186 6299
dda8d76d 6300 if (! get_program_headers (filedata))
d93f0186
NC
6301 {
6302 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6303 return (long) vma;
6304 }
6305
dda8d76d
NC
6306 for (seg = filedata->program_headers;
6307 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6308 ++seg)
6309 {
6310 if (seg->p_type != PT_LOAD)
6311 continue;
6312
6313 if (vma >= (seg->p_vaddr & -seg->p_align)
6314 && vma + size <= seg->p_vaddr + seg->p_filesz)
6315 return vma - seg->p_vaddr + seg->p_offset;
6316 }
6317
6318 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6319 (unsigned long) vma);
d93f0186
NC
6320 return (long) vma;
6321}
6322
6323
dda8d76d
NC
6324/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6325 If PROBE is true, this is just a probe and we do not generate any error
6326 messages if the load fails. */
049b0c3a 6327
015dc7e1
AM
6328static bool
6329get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6330{
2cf0635d
NC
6331 Elf32_External_Shdr * shdrs;
6332 Elf_Internal_Shdr * internal;
dda8d76d
NC
6333 unsigned int i;
6334 unsigned int size = filedata->file_header.e_shentsize;
6335 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6336
6337 /* PR binutils/17531: Cope with unexpected section header sizes. */
6338 if (size == 0 || num == 0)
015dc7e1 6339 return false;
049b0c3a
NC
6340 if (size < sizeof * shdrs)
6341 {
6342 if (! probe)
6343 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6344 return false;
049b0c3a
NC
6345 }
6346 if (!probe && size > sizeof * shdrs)
6347 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6348
dda8d76d 6349 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6350 size, num,
6351 probe ? NULL : _("section headers"));
6352 if (shdrs == NULL)
015dc7e1 6353 return false;
252b5132 6354
dda8d76d
NC
6355 filedata->section_headers = (Elf_Internal_Shdr *)
6356 cmalloc (num, sizeof (Elf_Internal_Shdr));
6357 if (filedata->section_headers == NULL)
252b5132 6358 {
049b0c3a 6359 if (!probe)
8b73c356 6360 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6361 free (shdrs);
015dc7e1 6362 return false;
252b5132
RH
6363 }
6364
dda8d76d 6365 for (i = 0, internal = filedata->section_headers;
560f3c1c 6366 i < num;
b34976b6 6367 i++, internal++)
252b5132
RH
6368 {
6369 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6370 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6371 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6372 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6373 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6374 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6375 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6376 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6377 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6378 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6379 if (!probe && internal->sh_link > num)
6380 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6381 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6382 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6383 }
6384
6385 free (shdrs);
015dc7e1 6386 return true;
252b5132
RH
6387}
6388
dda8d76d
NC
6389/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6390
015dc7e1
AM
6391static bool
6392get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6393{
dda8d76d
NC
6394 Elf64_External_Shdr * shdrs;
6395 Elf_Internal_Shdr * internal;
6396 unsigned int i;
6397 unsigned int size = filedata->file_header.e_shentsize;
6398 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6399
6400 /* PR binutils/17531: Cope with unexpected section header sizes. */
6401 if (size == 0 || num == 0)
015dc7e1 6402 return false;
dda8d76d 6403
049b0c3a
NC
6404 if (size < sizeof * shdrs)
6405 {
6406 if (! probe)
6407 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6408 return false;
049b0c3a 6409 }
dda8d76d 6410
049b0c3a
NC
6411 if (! probe && size > sizeof * shdrs)
6412 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6413
dda8d76d
NC
6414 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6415 filedata->file_header.e_shoff,
049b0c3a
NC
6416 size, num,
6417 probe ? NULL : _("section headers"));
6418 if (shdrs == NULL)
015dc7e1 6419 return false;
9ea033b2 6420
dda8d76d
NC
6421 filedata->section_headers = (Elf_Internal_Shdr *)
6422 cmalloc (num, sizeof (Elf_Internal_Shdr));
6423 if (filedata->section_headers == NULL)
9ea033b2 6424 {
049b0c3a 6425 if (! probe)
8b73c356 6426 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6427 free (shdrs);
015dc7e1 6428 return false;
9ea033b2
NC
6429 }
6430
dda8d76d 6431 for (i = 0, internal = filedata->section_headers;
560f3c1c 6432 i < num;
b34976b6 6433 i++, internal++)
9ea033b2
NC
6434 {
6435 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6436 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6437 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6438 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6439 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6440 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6441 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6442 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6443 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6444 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6445 if (!probe && internal->sh_link > num)
6446 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6447 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6448 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6449 }
6450
6451 free (shdrs);
015dc7e1 6452 return true;
9ea033b2
NC
6453}
6454
4de91c10
AM
6455static bool
6456get_section_headers (Filedata *filedata, bool probe)
6457{
6458 if (filedata->section_headers != NULL)
6459 return true;
6460
4de91c10
AM
6461 if (is_32bit_elf)
6462 return get_32bit_section_headers (filedata, probe);
6463 else
6464 return get_64bit_section_headers (filedata, probe);
6465}
6466
252b5132 6467static Elf_Internal_Sym *
dda8d76d
NC
6468get_32bit_elf_symbols (Filedata * filedata,
6469 Elf_Internal_Shdr * section,
6470 unsigned long * num_syms_return)
252b5132 6471{
ba5cdace 6472 unsigned long number = 0;
dd24e3da 6473 Elf32_External_Sym * esyms = NULL;
ba5cdace 6474 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6475 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6476 Elf_Internal_Sym * psym;
b34976b6 6477 unsigned int j;
e3d39609 6478 elf_section_list * entry;
252b5132 6479
c9c1d674
EG
6480 if (section->sh_size == 0)
6481 {
6482 if (num_syms_return != NULL)
6483 * num_syms_return = 0;
6484 return NULL;
6485 }
6486
dd24e3da 6487 /* Run some sanity checks first. */
c9c1d674 6488 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6489 {
c9c1d674 6490 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6491 printable_section_name (filedata, section),
6492 (unsigned long) section->sh_entsize);
ba5cdace 6493 goto exit_point;
dd24e3da
NC
6494 }
6495
dda8d76d 6496 if (section->sh_size > filedata->file_size)
f54498b4
NC
6497 {
6498 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6499 printable_section_name (filedata, section),
6500 (unsigned long) section->sh_size);
f54498b4
NC
6501 goto exit_point;
6502 }
6503
dd24e3da
NC
6504 number = section->sh_size / section->sh_entsize;
6505
6506 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6507 {
c9c1d674 6508 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6509 (unsigned long) section->sh_size,
dda8d76d 6510 printable_section_name (filedata, section),
8066deb1 6511 (unsigned long) section->sh_entsize);
ba5cdace 6512 goto exit_point;
dd24e3da
NC
6513 }
6514
dda8d76d 6515 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6516 section->sh_size, _("symbols"));
dd24e3da 6517 if (esyms == NULL)
ba5cdace 6518 goto exit_point;
252b5132 6519
e3d39609 6520 shndx = NULL;
978c4450 6521 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6522 {
6523 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6524 continue;
6525
6526 if (shndx != NULL)
6527 {
6528 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6529 free (shndx);
6530 }
6531
6532 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6533 entry->hdr->sh_offset,
6534 1, entry->hdr->sh_size,
6535 _("symbol table section indices"));
6536 if (shndx == NULL)
6537 goto exit_point;
6538
6539 /* PR17531: file: heap-buffer-overflow */
6540 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6541 {
6542 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6543 printable_section_name (filedata, entry->hdr),
6544 (unsigned long) entry->hdr->sh_size,
6545 (unsigned long) section->sh_size);
6546 goto exit_point;
c9c1d674 6547 }
e3d39609 6548 }
9ad5cbcf 6549
3f5e193b 6550 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6551
6552 if (isyms == NULL)
6553 {
8b73c356
NC
6554 error (_("Out of memory reading %lu symbols\n"),
6555 (unsigned long) number);
dd24e3da 6556 goto exit_point;
252b5132
RH
6557 }
6558
dd24e3da 6559 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6560 {
6561 psym->st_name = BYTE_GET (esyms[j].st_name);
6562 psym->st_value = BYTE_GET (esyms[j].st_value);
6563 psym->st_size = BYTE_GET (esyms[j].st_size);
6564 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6565 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6566 psym->st_shndx
6567 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6568 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6569 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6570 psym->st_info = BYTE_GET (esyms[j].st_info);
6571 psym->st_other = BYTE_GET (esyms[j].st_other);
6572 }
6573
dd24e3da 6574 exit_point:
e3d39609
NC
6575 free (shndx);
6576 free (esyms);
252b5132 6577
ba5cdace
NC
6578 if (num_syms_return != NULL)
6579 * num_syms_return = isyms == NULL ? 0 : number;
6580
252b5132
RH
6581 return isyms;
6582}
6583
9ea033b2 6584static Elf_Internal_Sym *
dda8d76d
NC
6585get_64bit_elf_symbols (Filedata * filedata,
6586 Elf_Internal_Shdr * section,
6587 unsigned long * num_syms_return)
9ea033b2 6588{
ba5cdace
NC
6589 unsigned long number = 0;
6590 Elf64_External_Sym * esyms = NULL;
6591 Elf_External_Sym_Shndx * shndx = NULL;
6592 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6593 Elf_Internal_Sym * psym;
b34976b6 6594 unsigned int j;
e3d39609 6595 elf_section_list * entry;
9ea033b2 6596
c9c1d674
EG
6597 if (section->sh_size == 0)
6598 {
6599 if (num_syms_return != NULL)
6600 * num_syms_return = 0;
6601 return NULL;
6602 }
6603
dd24e3da 6604 /* Run some sanity checks first. */
c9c1d674 6605 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6606 {
c9c1d674 6607 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6608 printable_section_name (filedata, section),
8066deb1 6609 (unsigned long) section->sh_entsize);
ba5cdace 6610 goto exit_point;
dd24e3da
NC
6611 }
6612
dda8d76d 6613 if (section->sh_size > filedata->file_size)
f54498b4
NC
6614 {
6615 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6616 printable_section_name (filedata, section),
8066deb1 6617 (unsigned long) section->sh_size);
f54498b4
NC
6618 goto exit_point;
6619 }
6620
dd24e3da
NC
6621 number = section->sh_size / section->sh_entsize;
6622
6623 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6624 {
c9c1d674 6625 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6626 (unsigned long) section->sh_size,
dda8d76d 6627 printable_section_name (filedata, section),
8066deb1 6628 (unsigned long) section->sh_entsize);
ba5cdace 6629 goto exit_point;
dd24e3da
NC
6630 }
6631
dda8d76d 6632 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6633 section->sh_size, _("symbols"));
a6e9f9df 6634 if (!esyms)
ba5cdace 6635 goto exit_point;
9ea033b2 6636
e3d39609 6637 shndx = NULL;
978c4450 6638 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6639 {
6640 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6641 continue;
6642
6643 if (shndx != NULL)
6644 {
6645 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6646 free (shndx);
c9c1d674 6647 }
e3d39609
NC
6648
6649 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6650 entry->hdr->sh_offset,
6651 1, entry->hdr->sh_size,
6652 _("symbol table section indices"));
6653 if (shndx == NULL)
6654 goto exit_point;
6655
6656 /* PR17531: file: heap-buffer-overflow */
6657 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6658 {
6659 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6660 printable_section_name (filedata, entry->hdr),
6661 (unsigned long) entry->hdr->sh_size,
6662 (unsigned long) section->sh_size);
6663 goto exit_point;
6664 }
6665 }
9ad5cbcf 6666
3f5e193b 6667 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6668
6669 if (isyms == NULL)
6670 {
8b73c356
NC
6671 error (_("Out of memory reading %lu symbols\n"),
6672 (unsigned long) number);
ba5cdace 6673 goto exit_point;
9ea033b2
NC
6674 }
6675
ba5cdace 6676 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6677 {
6678 psym->st_name = BYTE_GET (esyms[j].st_name);
6679 psym->st_info = BYTE_GET (esyms[j].st_info);
6680 psym->st_other = BYTE_GET (esyms[j].st_other);
6681 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6682
4fbb74a6 6683 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6684 psym->st_shndx
6685 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6686 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6687 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6688
66543521
AM
6689 psym->st_value = BYTE_GET (esyms[j].st_value);
6690 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6691 }
6692
ba5cdace 6693 exit_point:
e3d39609
NC
6694 free (shndx);
6695 free (esyms);
ba5cdace
NC
6696
6697 if (num_syms_return != NULL)
6698 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6699
6700 return isyms;
6701}
6702
4de91c10
AM
6703static Elf_Internal_Sym *
6704get_elf_symbols (Filedata *filedata,
6705 Elf_Internal_Shdr *section,
6706 unsigned long *num_syms_return)
6707{
6708 if (is_32bit_elf)
6709 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6710 else
6711 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6712}
6713
d1133906 6714static const char *
dda8d76d 6715get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6716{
5477e8a0 6717 static char buff[1024];
2cf0635d 6718 char * p = buff;
32ec8896
NC
6719 unsigned int field_size = is_32bit_elf ? 8 : 16;
6720 signed int sindex;
6721 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6722 bfd_vma os_flags = 0;
6723 bfd_vma proc_flags = 0;
6724 bfd_vma unknown_flags = 0;
148b93f2 6725 static const struct
5477e8a0 6726 {
2cf0635d 6727 const char * str;
32ec8896 6728 unsigned int len;
5477e8a0
L
6729 }
6730 flags [] =
6731 {
cfcac11d
NC
6732 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6733 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6734 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6735 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6736 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6737 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6738 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6739 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6740 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6741 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6742 /* IA-64 specific. */
6743 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6744 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6745 /* IA-64 OpenVMS specific. */
6746 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6747 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6748 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6749 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6750 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6751 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6752 /* Generic. */
cfcac11d 6753 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6754 /* SPARC specific. */
77115a4a 6755 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6756 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6757 /* ARM specific. */
6758 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6759 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6760 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6761 /* GNU specific. */
6762 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6763 /* VLE specific. */
6764 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6765 /* GNU specific. */
6766 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6767 };
6768
6769 if (do_section_details)
6770 {
8d5ff12c
L
6771 sprintf (buff, "[%*.*lx]: ",
6772 field_size, field_size, (unsigned long) sh_flags);
6773 p += field_size + 4;
5477e8a0 6774 }
76da6bbe 6775
d1133906
NC
6776 while (sh_flags)
6777 {
6778 bfd_vma flag;
6779
6780 flag = sh_flags & - sh_flags;
6781 sh_flags &= ~ flag;
76da6bbe 6782
5477e8a0 6783 if (do_section_details)
d1133906 6784 {
5477e8a0
L
6785 switch (flag)
6786 {
91d6fa6a
NC
6787 case SHF_WRITE: sindex = 0; break;
6788 case SHF_ALLOC: sindex = 1; break;
6789 case SHF_EXECINSTR: sindex = 2; break;
6790 case SHF_MERGE: sindex = 3; break;
6791 case SHF_STRINGS: sindex = 4; break;
6792 case SHF_INFO_LINK: sindex = 5; break;
6793 case SHF_LINK_ORDER: sindex = 6; break;
6794 case SHF_OS_NONCONFORMING: sindex = 7; break;
6795 case SHF_GROUP: sindex = 8; break;
6796 case SHF_TLS: sindex = 9; break;
18ae9cc1 6797 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6798 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6799
5477e8a0 6800 default:
91d6fa6a 6801 sindex = -1;
dda8d76d 6802 switch (filedata->file_header.e_machine)
148b93f2 6803 {
cfcac11d 6804 case EM_IA_64:
148b93f2 6805 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6806 sindex = 10;
148b93f2 6807 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6808 sindex = 11;
148b93f2 6809#ifdef BFD64
dda8d76d 6810 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6811 switch (flag)
6812 {
91d6fa6a
NC
6813 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6814 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6815 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6816 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6817 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6818 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6819 default: break;
6820 }
6821#endif
cfcac11d
NC
6822 break;
6823
caa83f8b 6824 case EM_386:
22abe556 6825 case EM_IAMCU:
caa83f8b 6826 case EM_X86_64:
7f502d6c 6827 case EM_L1OM:
7a9068fe 6828 case EM_K1OM:
cfcac11d
NC
6829 case EM_OLD_SPARCV9:
6830 case EM_SPARC32PLUS:
6831 case EM_SPARCV9:
6832 case EM_SPARC:
18ae9cc1 6833 if (flag == SHF_ORDERED)
91d6fa6a 6834 sindex = 19;
cfcac11d 6835 break;
ac4c9b04
MG
6836
6837 case EM_ARM:
6838 switch (flag)
6839 {
6840 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6841 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6842 case SHF_COMDEF: sindex = 23; break;
6843 default: break;
6844 }
6845 break;
83eef883
AFB
6846 case EM_PPC:
6847 if (flag == SHF_PPC_VLE)
6848 sindex = 25;
6849 break;
99fabbc9
JL
6850 default:
6851 break;
6852 }
ac4c9b04 6853
99fabbc9
JL
6854 switch (filedata->file_header.e_ident[EI_OSABI])
6855 {
6856 case ELFOSABI_GNU:
6857 case ELFOSABI_FREEBSD:
6858 if (flag == SHF_GNU_RETAIN)
6859 sindex = 26;
6860 /* Fall through */
6861 case ELFOSABI_NONE:
6862 if (flag == SHF_GNU_MBIND)
6863 /* We should not recognize SHF_GNU_MBIND for
6864 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6865 not set the EI_OSABI header byte. */
6866 sindex = 24;
6867 break;
cfcac11d
NC
6868 default:
6869 break;
148b93f2 6870 }
99fabbc9 6871 break;
5477e8a0
L
6872 }
6873
91d6fa6a 6874 if (sindex != -1)
5477e8a0 6875 {
8d5ff12c
L
6876 if (p != buff + field_size + 4)
6877 {
6878 if (size < (10 + 2))
bee0ee85
NC
6879 {
6880 warn (_("Internal error: not enough buffer room for section flag info"));
6881 return _("<unknown>");
6882 }
8d5ff12c
L
6883 size -= 2;
6884 *p++ = ',';
6885 *p++ = ' ';
6886 }
6887
91d6fa6a
NC
6888 size -= flags [sindex].len;
6889 p = stpcpy (p, flags [sindex].str);
5477e8a0 6890 }
3b22753a 6891 else if (flag & SHF_MASKOS)
8d5ff12c 6892 os_flags |= flag;
d1133906 6893 else if (flag & SHF_MASKPROC)
8d5ff12c 6894 proc_flags |= flag;
d1133906 6895 else
8d5ff12c 6896 unknown_flags |= flag;
5477e8a0
L
6897 }
6898 else
6899 {
6900 switch (flag)
6901 {
6902 case SHF_WRITE: *p = 'W'; break;
6903 case SHF_ALLOC: *p = 'A'; break;
6904 case SHF_EXECINSTR: *p = 'X'; break;
6905 case SHF_MERGE: *p = 'M'; break;
6906 case SHF_STRINGS: *p = 'S'; break;
6907 case SHF_INFO_LINK: *p = 'I'; break;
6908 case SHF_LINK_ORDER: *p = 'L'; break;
6909 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6910 case SHF_GROUP: *p = 'G'; break;
6911 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6912 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6913 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6914
6915 default:
dda8d76d
NC
6916 if ((filedata->file_header.e_machine == EM_X86_64
6917 || filedata->file_header.e_machine == EM_L1OM
6918 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6919 && flag == SHF_X86_64_LARGE)
6920 *p = 'l';
dda8d76d 6921 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6922 && flag == SHF_ARM_PURECODE)
99fabbc9 6923 *p = 'y';
dda8d76d 6924 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6925 && flag == SHF_PPC_VLE)
99fabbc9 6926 *p = 'v';
5477e8a0
L
6927 else if (flag & SHF_MASKOS)
6928 {
99fabbc9
JL
6929 switch (filedata->file_header.e_ident[EI_OSABI])
6930 {
6931 case ELFOSABI_GNU:
6932 case ELFOSABI_FREEBSD:
6933 if (flag == SHF_GNU_RETAIN)
6934 {
6935 *p = 'R';
6936 break;
6937 }
6938 /* Fall through */
6939 case ELFOSABI_NONE:
6940 if (flag == SHF_GNU_MBIND)
6941 {
6942 /* We should not recognize SHF_GNU_MBIND for
6943 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6944 not set the EI_OSABI header byte. */
6945 *p = 'D';
6946 break;
6947 }
6948 /* Fall through */
6949 default:
6950 *p = 'o';
6951 sh_flags &= ~SHF_MASKOS;
6952 break;
6953 }
5477e8a0
L
6954 }
6955 else if (flag & SHF_MASKPROC)
6956 {
6957 *p = 'p';
6958 sh_flags &= ~ SHF_MASKPROC;
6959 }
6960 else
6961 *p = 'x';
6962 break;
6963 }
6964 p++;
d1133906
NC
6965 }
6966 }
76da6bbe 6967
8d5ff12c
L
6968 if (do_section_details)
6969 {
6970 if (os_flags)
6971 {
6972 size -= 5 + field_size;
6973 if (p != buff + field_size + 4)
6974 {
6975 if (size < (2 + 1))
bee0ee85
NC
6976 {
6977 warn (_("Internal error: not enough buffer room for section flag info"));
6978 return _("<unknown>");
6979 }
8d5ff12c
L
6980 size -= 2;
6981 *p++ = ',';
6982 *p++ = ' ';
6983 }
6984 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6985 (unsigned long) os_flags);
6986 p += 5 + field_size;
6987 }
6988 if (proc_flags)
6989 {
6990 size -= 7 + field_size;
6991 if (p != buff + field_size + 4)
6992 {
6993 if (size < (2 + 1))
bee0ee85
NC
6994 {
6995 warn (_("Internal error: not enough buffer room for section flag info"));
6996 return _("<unknown>");
6997 }
8d5ff12c
L
6998 size -= 2;
6999 *p++ = ',';
7000 *p++ = ' ';
7001 }
7002 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7003 (unsigned long) proc_flags);
7004 p += 7 + field_size;
7005 }
7006 if (unknown_flags)
7007 {
7008 size -= 10 + field_size;
7009 if (p != buff + field_size + 4)
7010 {
7011 if (size < (2 + 1))
bee0ee85
NC
7012 {
7013 warn (_("Internal error: not enough buffer room for section flag info"));
7014 return _("<unknown>");
7015 }
8d5ff12c
L
7016 size -= 2;
7017 *p++ = ',';
7018 *p++ = ' ';
7019 }
2b692964 7020 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7021 (unsigned long) unknown_flags);
7022 p += 10 + field_size;
7023 }
7024 }
7025
e9e44622 7026 *p = '\0';
d1133906
NC
7027 return buff;
7028}
7029
5844b465 7030static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 7031get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
7032{
7033 if (is_32bit_elf)
7034 {
7035 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7036
ebdf1ebf
NC
7037 if (size < sizeof (* echdr))
7038 {
7039 error (_("Compressed section is too small even for a compression header\n"));
7040 return 0;
7041 }
7042
77115a4a
L
7043 chdr->ch_type = BYTE_GET (echdr->ch_type);
7044 chdr->ch_size = BYTE_GET (echdr->ch_size);
7045 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7046 return sizeof (*echdr);
7047 }
7048 else
7049 {
7050 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7051
ebdf1ebf
NC
7052 if (size < sizeof (* echdr))
7053 {
7054 error (_("Compressed section is too small even for a compression header\n"));
7055 return 0;
7056 }
7057
77115a4a
L
7058 chdr->ch_type = BYTE_GET (echdr->ch_type);
7059 chdr->ch_size = BYTE_GET (echdr->ch_size);
7060 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7061 return sizeof (*echdr);
7062 }
7063}
7064
015dc7e1 7065static bool
dda8d76d 7066process_section_headers (Filedata * filedata)
252b5132 7067{
2cf0635d 7068 Elf_Internal_Shdr * section;
b34976b6 7069 unsigned int i;
252b5132 7070
dda8d76d 7071 if (filedata->file_header.e_shnum == 0)
252b5132 7072 {
82f2dbf7 7073 /* PR binutils/12467. */
dda8d76d 7074 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7075 {
7076 warn (_("possibly corrupt ELF file header - it has a non-zero"
7077 " section header offset, but no section headers\n"));
015dc7e1 7078 return false;
32ec8896 7079 }
82f2dbf7 7080 else if (do_sections)
252b5132
RH
7081 printf (_("\nThere are no sections in this file.\n"));
7082
015dc7e1 7083 return true;
252b5132
RH
7084 }
7085
7086 if (do_sections && !do_header)
ca0e11aa
NC
7087 {
7088 if (filedata->is_separate && process_links)
7089 printf (_("In linked file '%s': "), filedata->file_name);
7090 if (! filedata->is_separate || process_links)
7091 printf (ngettext ("There is %d section header, "
7092 "starting at offset 0x%lx:\n",
7093 "There are %d section headers, "
7094 "starting at offset 0x%lx:\n",
7095 filedata->file_header.e_shnum),
7096 filedata->file_header.e_shnum,
7097 (unsigned long) filedata->file_header.e_shoff);
7098 }
252b5132 7099
4de91c10
AM
7100 if (!get_section_headers (filedata, false))
7101 return false;
252b5132
RH
7102
7103 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7104 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7105 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7106 {
dda8d76d 7107 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7108
c256ffe7
JJ
7109 if (section->sh_size != 0)
7110 {
dda8d76d
NC
7111 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7112 1, section->sh_size,
7113 _("string table"));
0de14b54 7114
dda8d76d 7115 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7116 }
252b5132
RH
7117 }
7118
7119 /* Scan the sections for the dynamic symbol table
e3c8793a 7120 and dynamic string table and debug sections. */
89fac5e3 7121 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7122 switch (filedata->file_header.e_machine)
89fac5e3
RS
7123 {
7124 case EM_MIPS:
7125 case EM_MIPS_RS3_LE:
7126 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7127 FDE addresses. However, the ABI also has a semi-official ILP32
7128 variant for which the normal FDE address size rules apply.
7129
7130 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7131 section, where XX is the size of longs in bits. Unfortunately,
7132 earlier compilers provided no way of distinguishing ILP32 objects
7133 from LP64 objects, so if there's any doubt, we should assume that
7134 the official LP64 form is being used. */
dda8d76d
NC
7135 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7136 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7137 eh_addr_size = 8;
7138 break;
0f56a26a
DD
7139
7140 case EM_H8_300:
7141 case EM_H8_300H:
dda8d76d 7142 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7143 {
7144 case E_H8_MACH_H8300:
7145 case E_H8_MACH_H8300HN:
7146 case E_H8_MACH_H8300SN:
7147 case E_H8_MACH_H8300SXN:
7148 eh_addr_size = 2;
7149 break;
7150 case E_H8_MACH_H8300H:
7151 case E_H8_MACH_H8300S:
7152 case E_H8_MACH_H8300SX:
7153 eh_addr_size = 4;
7154 break;
7155 }
f4236fe4
DD
7156 break;
7157
ff7eeb89 7158 case EM_M32C_OLD:
f4236fe4 7159 case EM_M32C:
dda8d76d 7160 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7161 {
7162 case EF_M32C_CPU_M16C:
7163 eh_addr_size = 2;
7164 break;
7165 }
7166 break;
89fac5e3
RS
7167 }
7168
76ca31c0
NC
7169#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7170 do \
7171 { \
7172 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7173 if (section->sh_entsize != expected_entsize) \
9dd3a467 7174 { \
f493c217
AM
7175 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
7176 i, (uint64_t) section->sh_entsize); \
7177 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
7178 (uint64_t) expected_entsize); \
9dd3a467 7179 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7180 } \
7181 } \
08d8fa11 7182 while (0)
9dd3a467
NC
7183
7184#define CHECK_ENTSIZE(section, i, type) \
1b513401 7185 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7186 sizeof (Elf64_External_##type))
7187
dda8d76d
NC
7188 for (i = 0, section = filedata->section_headers;
7189 i < filedata->file_header.e_shnum;
b34976b6 7190 i++, section++)
252b5132 7191 {
84714f86 7192 const char *name = section_name_print (filedata, section);
252b5132 7193
1b513401
NC
7194 /* Run some sanity checks on the headers and
7195 possibly fill in some file data as well. */
7196 switch (section->sh_type)
252b5132 7197 {
1b513401 7198 case SHT_DYNSYM:
978c4450 7199 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7200 {
7201 error (_("File contains multiple dynamic symbol tables\n"));
7202 continue;
7203 }
7204
08d8fa11 7205 CHECK_ENTSIZE (section, i, Sym);
978c4450 7206 filedata->dynamic_symbols
4de91c10 7207 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7208 filedata->dynamic_symtab_section = section;
1b513401
NC
7209 break;
7210
7211 case SHT_STRTAB:
7212 if (streq (name, ".dynstr"))
252b5132 7213 {
1b513401
NC
7214 if (filedata->dynamic_strings != NULL)
7215 {
7216 error (_("File contains multiple dynamic string tables\n"));
7217 continue;
7218 }
7219
7220 filedata->dynamic_strings
7221 = (char *) get_data (NULL, filedata, section->sh_offset,
7222 1, section->sh_size, _("dynamic strings"));
7223 filedata->dynamic_strings_length
7224 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7225 filedata->dynamic_strtab_section = section;
252b5132 7226 }
1b513401
NC
7227 break;
7228
7229 case SHT_SYMTAB_SHNDX:
7230 {
7231 elf_section_list * entry = xmalloc (sizeof * entry);
7232
7233 entry->hdr = section;
7234 entry->next = filedata->symtab_shndx_list;
7235 filedata->symtab_shndx_list = entry;
7236 }
7237 break;
7238
7239 case SHT_SYMTAB:
7240 CHECK_ENTSIZE (section, i, Sym);
7241 break;
7242
7243 case SHT_GROUP:
7244 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7245 break;
252b5132 7246
1b513401
NC
7247 case SHT_REL:
7248 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7249 if (do_checks && section->sh_size == 0)
1b513401
NC
7250 warn (_("Section '%s': zero-sized relocation section\n"), name);
7251 break;
7252
7253 case SHT_RELA:
7254 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7255 if (do_checks && section->sh_size == 0)
1b513401
NC
7256 warn (_("Section '%s': zero-sized relocation section\n"), name);
7257 break;
7258
682351b9
AM
7259 case SHT_RELR:
7260 CHECK_ENTSIZE (section, i, Relr);
7261 break;
7262
1b513401
NC
7263 case SHT_NOTE:
7264 case SHT_PROGBITS:
546cb2d8
NC
7265 /* Having a zero sized section is not illegal according to the
7266 ELF standard, but it might be an indication that something
7267 is wrong. So issue a warning if we are running in lint mode. */
7268 if (do_checks && section->sh_size == 0)
1b513401
NC
7269 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7270 break;
7271
7272 default:
7273 break;
7274 }
7275
7276 if ((do_debugging || do_debug_info || do_debug_abbrevs
7277 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7278 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7279 || do_debug_str || do_debug_str_offsets || do_debug_loc
7280 || do_debug_ranges
1b513401 7281 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7282 && (startswith (name, ".debug_")
7283 || startswith (name, ".zdebug_")))
252b5132 7284 {
1b315056
CS
7285 if (name[1] == 'z')
7286 name += sizeof (".zdebug_") - 1;
7287 else
7288 name += sizeof (".debug_") - 1;
252b5132
RH
7289
7290 if (do_debugging
24d127aa
ML
7291 || (do_debug_info && startswith (name, "info"))
7292 || (do_debug_info && startswith (name, "types"))
7293 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7294 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7295 || (do_debug_lines && startswith (name, "line."))
7296 || (do_debug_pubnames && startswith (name, "pubnames"))
7297 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7298 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7299 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7300 || (do_debug_aranges && startswith (name, "aranges"))
7301 || (do_debug_ranges && startswith (name, "ranges"))
7302 || (do_debug_ranges && startswith (name, "rnglists"))
7303 || (do_debug_frames && startswith (name, "frame"))
7304 || (do_debug_macinfo && startswith (name, "macinfo"))
7305 || (do_debug_macinfo && startswith (name, "macro"))
7306 || (do_debug_str && startswith (name, "str"))
7307 || (do_debug_links && startswith (name, "sup"))
7308 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7309 || (do_debug_loc && startswith (name, "loc"))
7310 || (do_debug_loc && startswith (name, "loclists"))
7311 || (do_debug_addr && startswith (name, "addr"))
7312 || (do_debug_cu_index && startswith (name, "cu_index"))
7313 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7314 )
6431e409 7315 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7316 }
a262ae96 7317 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7318 else if ((do_debugging || do_debug_info)
24d127aa 7319 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7320 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7321 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7322 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7323 else if (do_gdb_index && (streq (name, ".gdb_index")
7324 || streq (name, ".debug_names")))
6431e409 7325 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7326 /* Trace sections for Itanium VMS. */
7327 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7328 || do_trace_aranges)
24d127aa 7329 && startswith (name, ".trace_"))
6f875884
TG
7330 {
7331 name += sizeof (".trace_") - 1;
7332
7333 if (do_debugging
7334 || (do_trace_info && streq (name, "info"))
7335 || (do_trace_abbrevs && streq (name, "abbrev"))
7336 || (do_trace_aranges && streq (name, "aranges"))
7337 )
6431e409 7338 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7339 }
dda8d76d 7340 else if ((do_debugging || do_debug_links)
24d127aa
ML
7341 && (startswith (name, ".gnu_debuglink")
7342 || startswith (name, ".gnu_debugaltlink")))
6431e409 7343 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7344 }
7345
7346 if (! do_sections)
015dc7e1 7347 return true;
252b5132 7348
ca0e11aa 7349 if (filedata->is_separate && ! process_links)
015dc7e1 7350 return true;
ca0e11aa
NC
7351
7352 if (filedata->is_separate)
7353 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7354 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7355 printf (_("\nSection Headers:\n"));
7356 else
7357 printf (_("\nSection Header:\n"));
76da6bbe 7358
f7a99963 7359 if (is_32bit_elf)
595cf52e 7360 {
5477e8a0 7361 if (do_section_details)
595cf52e
L
7362 {
7363 printf (_(" [Nr] Name\n"));
5477e8a0 7364 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7365 }
7366 else
7367 printf
7368 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7369 }
d974e256 7370 else if (do_wide)
595cf52e 7371 {
5477e8a0 7372 if (do_section_details)
595cf52e
L
7373 {
7374 printf (_(" [Nr] Name\n"));
5477e8a0 7375 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7376 }
7377 else
7378 printf
7379 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7380 }
f7a99963
NC
7381 else
7382 {
5477e8a0 7383 if (do_section_details)
595cf52e
L
7384 {
7385 printf (_(" [Nr] Name\n"));
5477e8a0
L
7386 printf (_(" Type Address Offset Link\n"));
7387 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7388 }
7389 else
7390 {
7391 printf (_(" [Nr] Name Type Address Offset\n"));
7392 printf (_(" Size EntSize Flags Link Info Align\n"));
7393 }
f7a99963 7394 }
252b5132 7395
5477e8a0
L
7396 if (do_section_details)
7397 printf (_(" Flags\n"));
7398
dda8d76d
NC
7399 for (i = 0, section = filedata->section_headers;
7400 i < filedata->file_header.e_shnum;
b34976b6 7401 i++, section++)
252b5132 7402 {
dd905818
NC
7403 /* Run some sanity checks on the section header. */
7404
7405 /* Check the sh_link field. */
7406 switch (section->sh_type)
7407 {
285e3f99
AM
7408 case SHT_REL:
7409 case SHT_RELA:
7410 if (section->sh_link == 0
7411 && (filedata->file_header.e_type == ET_EXEC
7412 || filedata->file_header.e_type == ET_DYN))
7413 /* A dynamic relocation section where all entries use a
7414 zero symbol index need not specify a symtab section. */
7415 break;
7416 /* Fall through. */
dd905818
NC
7417 case SHT_SYMTAB_SHNDX:
7418 case SHT_GROUP:
7419 case SHT_HASH:
7420 case SHT_GNU_HASH:
7421 case SHT_GNU_versym:
285e3f99 7422 if (section->sh_link == 0
dda8d76d
NC
7423 || section->sh_link >= filedata->file_header.e_shnum
7424 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7425 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7426 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7427 i, section->sh_link);
7428 break;
7429
7430 case SHT_DYNAMIC:
7431 case SHT_SYMTAB:
7432 case SHT_DYNSYM:
7433 case SHT_GNU_verneed:
7434 case SHT_GNU_verdef:
7435 case SHT_GNU_LIBLIST:
285e3f99 7436 if (section->sh_link == 0
dda8d76d
NC
7437 || section->sh_link >= filedata->file_header.e_shnum
7438 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7439 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7440 i, section->sh_link);
7441 break;
7442
7443 case SHT_INIT_ARRAY:
7444 case SHT_FINI_ARRAY:
7445 case SHT_PREINIT_ARRAY:
7446 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7447 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7448 i, section->sh_link);
7449 break;
7450
7451 default:
7452 /* FIXME: Add support for target specific section types. */
7453#if 0 /* Currently we do not check other section types as there are too
7454 many special cases. Stab sections for example have a type
7455 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7456 section. */
7457 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7458 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7459 i, section->sh_link);
7460#endif
7461 break;
7462 }
7463
7464 /* Check the sh_info field. */
7465 switch (section->sh_type)
7466 {
7467 case SHT_REL:
7468 case SHT_RELA:
285e3f99
AM
7469 if (section->sh_info == 0
7470 && (filedata->file_header.e_type == ET_EXEC
7471 || filedata->file_header.e_type == ET_DYN))
7472 /* Dynamic relocations apply to segments, so they do not
7473 need to specify the section they relocate. */
7474 break;
7475 if (section->sh_info == 0
dda8d76d
NC
7476 || section->sh_info >= filedata->file_header.e_shnum
7477 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7478 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7479 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7480 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7481 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7482 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7483 /* FIXME: Are other section types valid ? */
dda8d76d 7484 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7485 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7486 i, section->sh_info);
dd905818
NC
7487 break;
7488
7489 case SHT_DYNAMIC:
7490 case SHT_HASH:
7491 case SHT_SYMTAB_SHNDX:
7492 case SHT_INIT_ARRAY:
7493 case SHT_FINI_ARRAY:
7494 case SHT_PREINIT_ARRAY:
7495 if (section->sh_info != 0)
7496 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7497 i, section->sh_info);
7498 break;
7499
7500 case SHT_GROUP:
7501 case SHT_SYMTAB:
7502 case SHT_DYNSYM:
7503 /* A symbol index - we assume that it is valid. */
7504 break;
7505
7506 default:
7507 /* FIXME: Add support for target specific section types. */
7508 if (section->sh_type == SHT_NOBITS)
7509 /* NOBITS section headers with non-zero sh_info fields can be
7510 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7511 information. The stripped sections have their headers
7512 preserved but their types set to SHT_NOBITS. So do not check
7513 this type of section. */
dd905818
NC
7514 ;
7515 else if (section->sh_flags & SHF_INFO_LINK)
7516 {
dda8d76d 7517 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7518 warn (_("[%2u]: Expected link to another section in info field"), i);
7519 }
a91e1603
L
7520 else if (section->sh_type < SHT_LOOS
7521 && (section->sh_flags & SHF_GNU_MBIND) == 0
7522 && section->sh_info != 0)
dd905818
NC
7523 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7524 i, section->sh_info);
7525 break;
7526 }
7527
3e6b6445 7528 /* Check the sh_size field. */
dda8d76d 7529 if (section->sh_size > filedata->file_size
3e6b6445
NC
7530 && section->sh_type != SHT_NOBITS
7531 && section->sh_type != SHT_NULL
7532 && section->sh_type < SHT_LOOS)
7533 warn (_("Size of section %u is larger than the entire file!\n"), i);
7534
7bfd842d 7535 printf (" [%2u] ", i);
5477e8a0 7536 if (do_section_details)
dda8d76d 7537 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7538 else
84714f86 7539 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7540
ea52a088 7541 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7542 get_section_type_name (filedata, section->sh_type));
0b4362b0 7543
f7a99963
NC
7544 if (is_32bit_elf)
7545 {
cfcac11d
NC
7546 const char * link_too_big = NULL;
7547
f7a99963 7548 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7549
f7a99963
NC
7550 printf ( " %6.6lx %6.6lx %2.2lx",
7551 (unsigned long) section->sh_offset,
7552 (unsigned long) section->sh_size,
7553 (unsigned long) section->sh_entsize);
d1133906 7554
5477e8a0
L
7555 if (do_section_details)
7556 fputs (" ", stdout);
7557 else
dda8d76d 7558 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7559
dda8d76d 7560 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7561 {
7562 link_too_big = "";
7563 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7564 an error but it can have special values in Solaris binaries. */
dda8d76d 7565 switch (filedata->file_header.e_machine)
cfcac11d 7566 {
caa83f8b 7567 case EM_386:
22abe556 7568 case EM_IAMCU:
caa83f8b 7569 case EM_X86_64:
7f502d6c 7570 case EM_L1OM:
7a9068fe 7571 case EM_K1OM:
cfcac11d
NC
7572 case EM_OLD_SPARCV9:
7573 case EM_SPARC32PLUS:
7574 case EM_SPARCV9:
7575 case EM_SPARC:
7576 if (section->sh_link == (SHN_BEFORE & 0xffff))
7577 link_too_big = "BEFORE";
7578 else if (section->sh_link == (SHN_AFTER & 0xffff))
7579 link_too_big = "AFTER";
7580 break;
7581 default:
7582 break;
7583 }
7584 }
7585
7586 if (do_section_details)
7587 {
7588 if (link_too_big != NULL && * link_too_big)
7589 printf ("<%s> ", link_too_big);
7590 else
7591 printf ("%2u ", section->sh_link);
7592 printf ("%3u %2lu\n", section->sh_info,
7593 (unsigned long) section->sh_addralign);
7594 }
7595 else
7596 printf ("%2u %3u %2lu\n",
7597 section->sh_link,
7598 section->sh_info,
7599 (unsigned long) section->sh_addralign);
7600
7601 if (link_too_big && ! * link_too_big)
7602 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7603 i, section->sh_link);
f7a99963 7604 }
d974e256
JJ
7605 else if (do_wide)
7606 {
7607 print_vma (section->sh_addr, LONG_HEX);
7608
7609 if ((long) section->sh_offset == section->sh_offset)
7610 printf (" %6.6lx", (unsigned long) section->sh_offset);
7611 else
7612 {
7613 putchar (' ');
7614 print_vma (section->sh_offset, LONG_HEX);
7615 }
7616
7617 if ((unsigned long) section->sh_size == section->sh_size)
7618 printf (" %6.6lx", (unsigned long) section->sh_size);
7619 else
7620 {
7621 putchar (' ');
7622 print_vma (section->sh_size, LONG_HEX);
7623 }
7624
7625 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7626 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7627 else
7628 {
7629 putchar (' ');
7630 print_vma (section->sh_entsize, LONG_HEX);
7631 }
7632
5477e8a0
L
7633 if (do_section_details)
7634 fputs (" ", stdout);
7635 else
dda8d76d 7636 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7637
72de5009 7638 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7639
7640 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7641 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7642 else
7643 {
7644 print_vma (section->sh_addralign, DEC);
7645 putchar ('\n');
7646 }
7647 }
5477e8a0 7648 else if (do_section_details)
595cf52e 7649 {
55cc53e9 7650 putchar (' ');
595cf52e
L
7651 print_vma (section->sh_addr, LONG_HEX);
7652 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7653 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7654 else
7655 {
7656 printf (" ");
7657 print_vma (section->sh_offset, LONG_HEX);
7658 }
72de5009 7659 printf (" %u\n ", section->sh_link);
595cf52e 7660 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7661 putchar (' ');
595cf52e
L
7662 print_vma (section->sh_entsize, LONG_HEX);
7663
72de5009
AM
7664 printf (" %-16u %lu\n",
7665 section->sh_info,
595cf52e
L
7666 (unsigned long) section->sh_addralign);
7667 }
f7a99963
NC
7668 else
7669 {
7670 putchar (' ');
7671 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7672 if ((long) section->sh_offset == section->sh_offset)
7673 printf (" %8.8lx", (unsigned long) section->sh_offset);
7674 else
7675 {
7676 printf (" ");
7677 print_vma (section->sh_offset, LONG_HEX);
7678 }
f7a99963
NC
7679 printf ("\n ");
7680 print_vma (section->sh_size, LONG_HEX);
7681 printf (" ");
7682 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7683
dda8d76d 7684 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7685
72de5009
AM
7686 printf (" %2u %3u %lu\n",
7687 section->sh_link,
7688 section->sh_info,
f7a99963
NC
7689 (unsigned long) section->sh_addralign);
7690 }
5477e8a0
L
7691
7692 if (do_section_details)
77115a4a 7693 {
dda8d76d 7694 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7695 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7696 {
7697 /* Minimum section size is 12 bytes for 32-bit compression
7698 header + 12 bytes for compressed data header. */
7699 unsigned char buf[24];
d8024a91 7700
77115a4a 7701 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7702 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7703 sizeof (buf), _("compression header")))
7704 {
7705 Elf_Internal_Chdr chdr;
d8024a91 7706
5844b465
NC
7707 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7708 printf (_(" [<corrupt>]\n"));
77115a4a 7709 else
5844b465
NC
7710 {
7711 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7712 printf (" ZLIB, ");
1369522f
CC
7713 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7714 printf (" ZSTD, ");
5844b465
NC
7715 else
7716 printf (_(" [<unknown>: 0x%x], "),
7717 chdr.ch_type);
7718 print_vma (chdr.ch_size, LONG_HEX);
7719 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7720 }
77115a4a
L
7721 }
7722 }
7723 }
252b5132
RH
7724 }
7725
5477e8a0 7726 if (!do_section_details)
3dbcc61d 7727 {
9fb71ee4
NC
7728 /* The ordering of the letters shown here matches the ordering of the
7729 corresponding SHF_xxx values, and hence the order in which these
7730 letters will be displayed to the user. */
7731 printf (_("Key to Flags:\n\
7732 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7733 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7734 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7735 switch (filedata->file_header.e_ident[EI_OSABI])
7736 {
7737 case ELFOSABI_GNU:
7738 case ELFOSABI_FREEBSD:
7739 printf (_("R (retain), "));
7740 /* Fall through */
7741 case ELFOSABI_NONE:
7742 printf (_("D (mbind), "));
7743 break;
7744 default:
7745 break;
7746 }
dda8d76d
NC
7747 if (filedata->file_header.e_machine == EM_X86_64
7748 || filedata->file_header.e_machine == EM_L1OM
7749 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7750 printf (_("l (large), "));
dda8d76d 7751 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7752 printf (_("y (purecode), "));
dda8d76d 7753 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7754 printf (_("v (VLE), "));
9fb71ee4 7755 printf ("p (processor specific)\n");
0b4362b0 7756 }
d1133906 7757
015dc7e1 7758 return true;
252b5132
RH
7759}
7760
015dc7e1 7761static bool
28d13567
AM
7762get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7763 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7764 char **strtab, unsigned long *strtablen)
7765{
7766 *strtab = NULL;
7767 *strtablen = 0;
4de91c10 7768 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7769
7770 if (*symtab == NULL)
015dc7e1 7771 return false;
28d13567
AM
7772
7773 if (symsec->sh_link != 0)
7774 {
7775 Elf_Internal_Shdr *strsec;
7776
7777 if (symsec->sh_link >= filedata->file_header.e_shnum)
7778 {
7779 error (_("Bad sh_link in symbol table section\n"));
7780 free (*symtab);
7781 *symtab = NULL;
7782 *nsyms = 0;
015dc7e1 7783 return false;
28d13567
AM
7784 }
7785
7786 strsec = filedata->section_headers + symsec->sh_link;
7787
7788 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7789 1, strsec->sh_size, _("string table"));
7790 if (*strtab == NULL)
7791 {
7792 free (*symtab);
7793 *symtab = NULL;
7794 *nsyms = 0;
015dc7e1 7795 return false;
28d13567
AM
7796 }
7797 *strtablen = strsec->sh_size;
7798 }
015dc7e1 7799 return true;
28d13567
AM
7800}
7801
f5842774
L
7802static const char *
7803get_group_flags (unsigned int flags)
7804{
1449284b 7805 static char buff[128];
220453ec 7806
6d913794
NC
7807 if (flags == 0)
7808 return "";
7809 else if (flags == GRP_COMDAT)
7810 return "COMDAT ";
f5842774 7811
89246a0e
AM
7812 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7813 flags,
7814 flags & GRP_MASKOS ? _("<OS specific>") : "",
7815 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7816 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7817 ? _("<unknown>") : ""));
6d913794 7818
f5842774
L
7819 return buff;
7820}
7821
015dc7e1 7822static bool
dda8d76d 7823process_section_groups (Filedata * filedata)
f5842774 7824{
2cf0635d 7825 Elf_Internal_Shdr * section;
f5842774 7826 unsigned int i;
2cf0635d
NC
7827 struct group * group;
7828 Elf_Internal_Shdr * symtab_sec;
7829 Elf_Internal_Shdr * strtab_sec;
7830 Elf_Internal_Sym * symtab;
ba5cdace 7831 unsigned long num_syms;
2cf0635d 7832 char * strtab;
c256ffe7 7833 size_t strtab_size;
d1f5c6e3
L
7834
7835 /* Don't process section groups unless needed. */
7836 if (!do_unwind && !do_section_groups)
015dc7e1 7837 return true;
f5842774 7838
dda8d76d 7839 if (filedata->file_header.e_shnum == 0)
f5842774
L
7840 {
7841 if (do_section_groups)
ca0e11aa
NC
7842 {
7843 if (filedata->is_separate)
7844 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7845 filedata->file_name);
7846 else
7847 printf (_("\nThere are no section groups in this file.\n"));
7848 }
015dc7e1 7849 return true;
f5842774
L
7850 }
7851
dda8d76d 7852 if (filedata->section_headers == NULL)
f5842774
L
7853 {
7854 error (_("Section headers are not available!\n"));
fa1908fd 7855 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7856 return false;
f5842774
L
7857 }
7858
978c4450
AM
7859 filedata->section_headers_groups
7860 = (struct group **) calloc (filedata->file_header.e_shnum,
7861 sizeof (struct group *));
e4b17d5c 7862
978c4450 7863 if (filedata->section_headers_groups == NULL)
e4b17d5c 7864 {
8b73c356 7865 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7866 filedata->file_header.e_shnum);
015dc7e1 7867 return false;
e4b17d5c
L
7868 }
7869
f5842774 7870 /* Scan the sections for the group section. */
978c4450 7871 filedata->group_count = 0;
dda8d76d
NC
7872 for (i = 0, section = filedata->section_headers;
7873 i < filedata->file_header.e_shnum;
f5842774 7874 i++, section++)
e4b17d5c 7875 if (section->sh_type == SHT_GROUP)
978c4450 7876 filedata->group_count++;
e4b17d5c 7877
978c4450 7878 if (filedata->group_count == 0)
d1f5c6e3
L
7879 {
7880 if (do_section_groups)
ca0e11aa
NC
7881 {
7882 if (filedata->is_separate)
7883 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7884 filedata->file_name);
7885 else
7886 printf (_("\nThere are no section groups in this file.\n"));
7887 }
d1f5c6e3 7888
015dc7e1 7889 return true;
d1f5c6e3
L
7890 }
7891
978c4450
AM
7892 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7893 sizeof (struct group));
e4b17d5c 7894
978c4450 7895 if (filedata->section_groups == NULL)
e4b17d5c 7896 {
8b73c356 7897 error (_("Out of memory reading %lu groups\n"),
978c4450 7898 (unsigned long) filedata->group_count);
015dc7e1 7899 return false;
e4b17d5c
L
7900 }
7901
d1f5c6e3
L
7902 symtab_sec = NULL;
7903 strtab_sec = NULL;
7904 symtab = NULL;
ba5cdace 7905 num_syms = 0;
d1f5c6e3 7906 strtab = NULL;
c256ffe7 7907 strtab_size = 0;
ca0e11aa
NC
7908
7909 if (filedata->is_separate)
7910 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7911
978c4450 7912 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7913 i < filedata->file_header.e_shnum;
e4b17d5c 7914 i++, section++)
f5842774
L
7915 {
7916 if (section->sh_type == SHT_GROUP)
7917 {
dda8d76d 7918 const char * name = printable_section_name (filedata, section);
74e1a04b 7919 const char * group_name;
2cf0635d
NC
7920 unsigned char * start;
7921 unsigned char * indices;
f5842774 7922 unsigned int entry, j, size;
2cf0635d
NC
7923 Elf_Internal_Shdr * sec;
7924 Elf_Internal_Sym * sym;
f5842774
L
7925
7926 /* Get the symbol table. */
dda8d76d
NC
7927 if (section->sh_link >= filedata->file_header.e_shnum
7928 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7929 != SHT_SYMTAB))
f5842774
L
7930 {
7931 error (_("Bad sh_link in group section `%s'\n"), name);
7932 continue;
7933 }
d1f5c6e3
L
7934
7935 if (symtab_sec != sec)
7936 {
7937 symtab_sec = sec;
9db70fc3 7938 free (symtab);
4de91c10 7939 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7940 }
f5842774 7941
dd24e3da
NC
7942 if (symtab == NULL)
7943 {
7944 error (_("Corrupt header in group section `%s'\n"), name);
7945 continue;
7946 }
7947
ba5cdace
NC
7948 if (section->sh_info >= num_syms)
7949 {
7950 error (_("Bad sh_info in group section `%s'\n"), name);
7951 continue;
7952 }
7953
f5842774
L
7954 sym = symtab + section->sh_info;
7955
7956 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7957 {
4fbb74a6 7958 if (sym->st_shndx == 0
dda8d76d 7959 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7960 {
7961 error (_("Bad sh_info in group section `%s'\n"), name);
7962 continue;
7963 }
ba2685cc 7964
84714f86
AM
7965 group_name = section_name_print (filedata,
7966 filedata->section_headers
b9e920ec 7967 + sym->st_shndx);
c256ffe7 7968 strtab_sec = NULL;
9db70fc3 7969 free (strtab);
f5842774 7970 strtab = NULL;
c256ffe7 7971 strtab_size = 0;
f5842774
L
7972 }
7973 else
7974 {
7975 /* Get the string table. */
dda8d76d 7976 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7977 {
7978 strtab_sec = NULL;
9db70fc3 7979 free (strtab);
c256ffe7
JJ
7980 strtab = NULL;
7981 strtab_size = 0;
7982 }
7983 else if (strtab_sec
dda8d76d 7984 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7985 {
7986 strtab_sec = sec;
9db70fc3 7987 free (strtab);
071436c6 7988
dda8d76d 7989 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7990 1, strtab_sec->sh_size,
7991 _("string table"));
c256ffe7 7992 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7993 }
c256ffe7 7994 group_name = sym->st_name < strtab_size
2b692964 7995 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7996 }
7997
c9c1d674
EG
7998 /* PR 17531: file: loop. */
7999 if (section->sh_entsize > section->sh_size)
8000 {
8001 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8002 printable_section_name (filedata, section),
8066deb1
AM
8003 (unsigned long) section->sh_entsize,
8004 (unsigned long) section->sh_size);
61dd8e19 8005 continue;
c9c1d674
EG
8006 }
8007
dda8d76d 8008 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8009 1, section->sh_size,
8010 _("section data"));
59245841
NC
8011 if (start == NULL)
8012 continue;
f5842774
L
8013
8014 indices = start;
8015 size = (section->sh_size / section->sh_entsize) - 1;
8016 entry = byte_get (indices, 4);
8017 indices += 4;
e4b17d5c
L
8018
8019 if (do_section_groups)
8020 {
2b692964 8021 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8022 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8023
e4b17d5c
L
8024 printf (_(" [Index] Name\n"));
8025 }
8026
8027 group->group_index = i;
8028
f5842774
L
8029 for (j = 0; j < size; j++)
8030 {
2cf0635d 8031 struct group_list * g;
e4b17d5c 8032
f5842774
L
8033 entry = byte_get (indices, 4);
8034 indices += 4;
8035
dda8d76d 8036 if (entry >= filedata->file_header.e_shnum)
391cb864 8037 {
57028622
NC
8038 static unsigned num_group_errors = 0;
8039
8040 if (num_group_errors ++ < 10)
8041 {
8042 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8043 entry, i, filedata->file_header.e_shnum - 1);
57028622 8044 if (num_group_errors == 10)
67ce483b 8045 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8046 }
391cb864
L
8047 continue;
8048 }
391cb864 8049
978c4450 8050 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8051 {
d1f5c6e3
L
8052 if (entry)
8053 {
57028622
NC
8054 static unsigned num_errs = 0;
8055
8056 if (num_errs ++ < 10)
8057 {
8058 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8059 entry, i,
978c4450 8060 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8061 if (num_errs == 10)
8062 warn (_("Further error messages about already contained group sections suppressed\n"));
8063 }
d1f5c6e3
L
8064 continue;
8065 }
8066 else
8067 {
8068 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8069 section group. We just warn it the first time
d1f5c6e3 8070 and ignore it afterwards. */
015dc7e1 8071 static bool warned = false;
d1f5c6e3
L
8072 if (!warned)
8073 {
8074 error (_("section 0 in group section [%5u]\n"),
978c4450 8075 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8076 warned = true;
d1f5c6e3
L
8077 }
8078 }
e4b17d5c
L
8079 }
8080
978c4450 8081 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8082
8083 if (do_section_groups)
8084 {
dda8d76d
NC
8085 sec = filedata->section_headers + entry;
8086 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8087 }
8088
3f5e193b 8089 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8090 g->section_index = entry;
8091 g->next = group->root;
8092 group->root = g;
f5842774
L
8093 }
8094
9db70fc3 8095 free (start);
e4b17d5c
L
8096
8097 group++;
f5842774
L
8098 }
8099 }
8100
9db70fc3
AM
8101 free (symtab);
8102 free (strtab);
015dc7e1 8103 return true;
f5842774
L
8104}
8105
28f997cf
TG
8106/* Data used to display dynamic fixups. */
8107
8108struct ia64_vms_dynfixup
8109{
8110 bfd_vma needed_ident; /* Library ident number. */
8111 bfd_vma needed; /* Index in the dstrtab of the library name. */
8112 bfd_vma fixup_needed; /* Index of the library. */
8113 bfd_vma fixup_rela_cnt; /* Number of fixups. */
8114 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
8115};
8116
8117/* Data used to display dynamic relocations. */
8118
8119struct ia64_vms_dynimgrela
8120{
8121 bfd_vma img_rela_cnt; /* Number of relocations. */
8122 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
8123};
8124
8125/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8126 library). */
8127
015dc7e1 8128static bool
dda8d76d
NC
8129dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8130 struct ia64_vms_dynfixup * fixup,
8131 const char * strtab,
8132 unsigned int strtab_sz)
28f997cf 8133{
32ec8896 8134 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8135 long i;
32ec8896 8136 const char * lib_name;
28f997cf 8137
978c4450
AM
8138 imfs = get_data (NULL, filedata,
8139 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8140 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8141 _("dynamic section image fixups"));
8142 if (!imfs)
015dc7e1 8143 return false;
28f997cf
TG
8144
8145 if (fixup->needed < strtab_sz)
8146 lib_name = strtab + fixup->needed;
8147 else
8148 {
32ec8896 8149 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8150 (unsigned long) fixup->needed);
28f997cf
TG
8151 lib_name = "???";
8152 }
736990c4 8153
28f997cf
TG
8154 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8155 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8156 printf
8157 (_("Seg Offset Type SymVec DataType\n"));
8158
8159 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8160 {
8161 unsigned int type;
8162 const char *rtype;
8163
8164 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
f493c217 8165 printf ("%016" PRIx64 " ", (uint64_t) BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8166 type = BYTE_GET (imfs [i].type);
8167 rtype = elf_ia64_reloc_type (type);
8168 if (rtype == NULL)
f493c217 8169 printf ("0x%08x ", type);
28f997cf 8170 else
f493c217 8171 printf ("%-32s ", rtype);
28f997cf
TG
8172 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8173 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8174 }
8175
8176 free (imfs);
015dc7e1 8177 return true;
28f997cf
TG
8178}
8179
8180/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8181
015dc7e1 8182static bool
dda8d76d 8183dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8184{
8185 Elf64_External_VMS_IMAGE_RELA *imrs;
8186 long i;
8187
978c4450
AM
8188 imrs = get_data (NULL, filedata,
8189 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8190 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8191 _("dynamic section image relocations"));
28f997cf 8192 if (!imrs)
015dc7e1 8193 return false;
28f997cf
TG
8194
8195 printf (_("\nImage relocs\n"));
8196 printf
8197 (_("Seg Offset Type Addend Seg Sym Off\n"));
8198
8199 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8200 {
8201 unsigned int type;
8202 const char *rtype;
8203
8204 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
b8281767
AM
8205 printf ("%08" PRIx64 " ",
8206 (uint64_t) BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8207 type = BYTE_GET (imrs [i].type);
8208 rtype = elf_ia64_reloc_type (type);
8209 if (rtype == NULL)
8210 printf ("0x%08x ", type);
8211 else
8212 printf ("%-31s ", rtype);
8213 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8214 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
b8281767
AM
8215 printf ("%08" PRIx64 "\n",
8216 (uint64_t) BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8217 }
8218
8219 free (imrs);
015dc7e1 8220 return true;
28f997cf
TG
8221}
8222
8223/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8224
015dc7e1 8225static bool
dda8d76d 8226process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8227{
8228 struct ia64_vms_dynfixup fixup;
8229 struct ia64_vms_dynimgrela imgrela;
8230 Elf_Internal_Dyn *entry;
28f997cf
TG
8231 bfd_vma strtab_off = 0;
8232 bfd_vma strtab_sz = 0;
8233 char *strtab = NULL;
015dc7e1 8234 bool res = true;
28f997cf
TG
8235
8236 memset (&fixup, 0, sizeof (fixup));
8237 memset (&imgrela, 0, sizeof (imgrela));
8238
8239 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8240 for (entry = filedata->dynamic_section;
8241 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8242 entry++)
8243 {
8244 switch (entry->d_tag)
8245 {
8246 case DT_IA_64_VMS_STRTAB_OFFSET:
8247 strtab_off = entry->d_un.d_val;
8248 break;
8249 case DT_STRSZ:
8250 strtab_sz = entry->d_un.d_val;
8251 if (strtab == NULL)
978c4450
AM
8252 strtab = get_data (NULL, filedata,
8253 filedata->dynamic_addr + strtab_off,
28f997cf 8254 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8255 if (strtab == NULL)
8256 strtab_sz = 0;
28f997cf
TG
8257 break;
8258
8259 case DT_IA_64_VMS_NEEDED_IDENT:
8260 fixup.needed_ident = entry->d_un.d_val;
8261 break;
8262 case DT_NEEDED:
8263 fixup.needed = entry->d_un.d_val;
8264 break;
8265 case DT_IA_64_VMS_FIXUP_NEEDED:
8266 fixup.fixup_needed = entry->d_un.d_val;
8267 break;
8268 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8269 fixup.fixup_rela_cnt = entry->d_un.d_val;
8270 break;
8271 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8272 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8273 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8274 res = false;
28f997cf 8275 break;
28f997cf
TG
8276 case DT_IA_64_VMS_IMG_RELA_CNT:
8277 imgrela.img_rela_cnt = entry->d_un.d_val;
8278 break;
8279 case DT_IA_64_VMS_IMG_RELA_OFF:
8280 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8281 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8282 res = false;
28f997cf
TG
8283 break;
8284
8285 default:
8286 break;
8287 }
8288 }
8289
9db70fc3 8290 free (strtab);
28f997cf
TG
8291
8292 return res;
8293}
8294
85b1c36d 8295static struct
566b0d53 8296{
2cf0635d 8297 const char * name;
566b0d53
L
8298 int reloc;
8299 int size;
a7fd1186 8300 relocation_type rel_type;
32ec8896
NC
8301}
8302 dynamic_relocations [] =
566b0d53 8303{
a7fd1186
FS
8304 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8305 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8306 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8307 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8308};
8309
252b5132 8310/* Process the reloc section. */
18bd398b 8311
015dc7e1 8312static bool
dda8d76d 8313process_relocs (Filedata * filedata)
252b5132 8314{
b34976b6
AM
8315 unsigned long rel_size;
8316 unsigned long rel_offset;
252b5132 8317
252b5132 8318 if (!do_reloc)
015dc7e1 8319 return true;
252b5132
RH
8320
8321 if (do_using_dynamic)
8322 {
a7fd1186 8323 relocation_type rel_type;
2cf0635d 8324 const char * name;
015dc7e1 8325 bool has_dynamic_reloc;
566b0d53 8326 unsigned int i;
0de14b54 8327
015dc7e1 8328 has_dynamic_reloc = false;
252b5132 8329
566b0d53 8330 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8331 {
a7fd1186 8332 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8333 name = dynamic_relocations [i].name;
978c4450
AM
8334 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8335 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8336
32ec8896 8337 if (rel_size)
015dc7e1 8338 has_dynamic_reloc = true;
566b0d53 8339
a7fd1186 8340 if (rel_type == reltype_unknown)
aa903cfb 8341 {
566b0d53 8342 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8343 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8344 {
8345 case DT_REL:
a7fd1186 8346 rel_type = reltype_rel;
566b0d53
L
8347 break;
8348 case DT_RELA:
a7fd1186 8349 rel_type = reltype_rela;
566b0d53
L
8350 break;
8351 }
aa903cfb 8352 }
252b5132 8353
566b0d53
L
8354 if (rel_size)
8355 {
ca0e11aa
NC
8356 if (filedata->is_separate)
8357 printf
8358 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8359 filedata->file_name, name, rel_offset, rel_size);
8360 else
8361 printf
8362 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8363 name, rel_offset, rel_size);
252b5132 8364
dda8d76d
NC
8365 dump_relocations (filedata,
8366 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8367 rel_size,
978c4450
AM
8368 filedata->dynamic_symbols,
8369 filedata->num_dynamic_syms,
8370 filedata->dynamic_strings,
8371 filedata->dynamic_strings_length,
a7fd1186 8372 rel_type, true /* is_dynamic */);
566b0d53 8373 }
252b5132 8374 }
566b0d53 8375
dda8d76d
NC
8376 if (is_ia64_vms (filedata))
8377 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8378 has_dynamic_reloc = true;
28f997cf 8379
566b0d53 8380 if (! has_dynamic_reloc)
ca0e11aa
NC
8381 {
8382 if (filedata->is_separate)
8383 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8384 filedata->file_name);
8385 else
8386 printf (_("\nThere are no dynamic relocations in this file.\n"));
8387 }
252b5132
RH
8388 }
8389 else
8390 {
2cf0635d 8391 Elf_Internal_Shdr * section;
b34976b6 8392 unsigned long i;
015dc7e1 8393 bool found = false;
252b5132 8394
dda8d76d
NC
8395 for (i = 0, section = filedata->section_headers;
8396 i < filedata->file_header.e_shnum;
b34976b6 8397 i++, section++)
252b5132
RH
8398 {
8399 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8400 && section->sh_type != SHT_REL
8401 && section->sh_type != SHT_RELR)
252b5132
RH
8402 continue;
8403
8404 rel_offset = section->sh_offset;
8405 rel_size = section->sh_size;
8406
8407 if (rel_size)
8408 {
a7fd1186 8409 relocation_type rel_type;
d3a49aa8 8410 unsigned long num_rela;
103f02d3 8411
ca0e11aa
NC
8412 if (filedata->is_separate)
8413 printf (_("\nIn linked file '%s' relocation section "),
8414 filedata->file_name);
8415 else
8416 printf (_("\nRelocation section "));
252b5132 8417
dda8d76d 8418 if (filedata->string_table == NULL)
19936277 8419 printf ("%d", section->sh_name);
252b5132 8420 else
dda8d76d 8421 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8422
d3a49aa8
AM
8423 num_rela = rel_size / section->sh_entsize;
8424 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8425 " at offset 0x%lx contains %lu entries:\n",
8426 num_rela),
8427 rel_offset, num_rela);
252b5132 8428
a7fd1186
FS
8429 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8430 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8431
4fbb74a6 8432 if (section->sh_link != 0
dda8d76d 8433 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8434 {
2cf0635d
NC
8435 Elf_Internal_Shdr * symsec;
8436 Elf_Internal_Sym * symtab;
d79b3d50 8437 unsigned long nsyms;
c256ffe7 8438 unsigned long strtablen = 0;
2cf0635d 8439 char * strtab = NULL;
57346661 8440
dda8d76d 8441 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8442 if (symsec->sh_type != SHT_SYMTAB
8443 && symsec->sh_type != SHT_DYNSYM)
8444 continue;
8445
28d13567
AM
8446 if (!get_symtab (filedata, symsec,
8447 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8448 continue;
252b5132 8449
dda8d76d 8450 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8451 symtab, nsyms, strtab, strtablen,
a7fd1186 8452 rel_type,
bb4d2ac2 8453 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8454 free (strtab);
d79b3d50
NC
8455 free (symtab);
8456 }
8457 else
dda8d76d 8458 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8459 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8460
015dc7e1 8461 found = true;
252b5132
RH
8462 }
8463 }
8464
8465 if (! found)
45ac8f4f
NC
8466 {
8467 /* Users sometimes forget the -D option, so try to be helpful. */
8468 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8469 {
978c4450 8470 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8471 {
ca0e11aa
NC
8472 if (filedata->is_separate)
8473 printf (_("\nThere are no static relocations in linked file '%s'."),
8474 filedata->file_name);
8475 else
8476 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8477 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8478
8479 break;
8480 }
8481 }
8482 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8483 {
8484 if (filedata->is_separate)
8485 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8486 filedata->file_name);
8487 else
8488 printf (_("\nThere are no relocations in this file.\n"));
8489 }
45ac8f4f 8490 }
252b5132
RH
8491 }
8492
015dc7e1 8493 return true;
252b5132
RH
8494}
8495
4d6ed7c8
NC
8496/* An absolute address consists of a section and an offset. If the
8497 section is NULL, the offset itself is the address, otherwise, the
8498 address equals to LOAD_ADDRESS(section) + offset. */
8499
8500struct absaddr
948f632f
DA
8501{
8502 unsigned short section;
8503 bfd_vma offset;
8504};
4d6ed7c8 8505
948f632f
DA
8506/* Find the nearest symbol at or below ADDR. Returns the symbol
8507 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8508
4d6ed7c8 8509static void
dda8d76d
NC
8510find_symbol_for_address (Filedata * filedata,
8511 Elf_Internal_Sym * symtab,
8512 unsigned long nsyms,
8513 const char * strtab,
8514 unsigned long strtab_size,
8515 struct absaddr addr,
8516 const char ** symname,
8517 bfd_vma * offset)
4d6ed7c8 8518{
d3ba0551 8519 bfd_vma dist = 0x100000;
2cf0635d 8520 Elf_Internal_Sym * sym;
948f632f
DA
8521 Elf_Internal_Sym * beg;
8522 Elf_Internal_Sym * end;
2cf0635d 8523 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8524
0b6ae522 8525 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8526 beg = symtab;
8527 end = symtab + nsyms;
0b6ae522 8528
948f632f 8529 while (beg < end)
4d6ed7c8 8530 {
948f632f
DA
8531 bfd_vma value;
8532
8533 sym = beg + (end - beg) / 2;
0b6ae522 8534
948f632f 8535 value = sym->st_value;
0b6ae522
DJ
8536 REMOVE_ARCH_BITS (value);
8537
948f632f 8538 if (sym->st_name != 0
4d6ed7c8 8539 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8540 && addr.offset >= value
8541 && addr.offset - value < dist)
4d6ed7c8
NC
8542 {
8543 best = sym;
0b6ae522 8544 dist = addr.offset - value;
4d6ed7c8
NC
8545 if (!dist)
8546 break;
8547 }
948f632f
DA
8548
8549 if (addr.offset < value)
8550 end = sym;
8551 else
8552 beg = sym + 1;
4d6ed7c8 8553 }
1b31d05e 8554
4d6ed7c8
NC
8555 if (best)
8556 {
57346661 8557 *symname = (best->st_name >= strtab_size
2b692964 8558 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8559 *offset = dist;
8560 return;
8561 }
1b31d05e 8562
4d6ed7c8
NC
8563 *symname = NULL;
8564 *offset = addr.offset;
8565}
8566
32ec8896 8567static /* signed */ int
948f632f
DA
8568symcmp (const void *p, const void *q)
8569{
8570 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8571 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8572
8573 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8574}
8575
8576/* Process the unwind section. */
8577
8578#include "unwind-ia64.h"
8579
8580struct ia64_unw_table_entry
8581{
8582 struct absaddr start;
8583 struct absaddr end;
8584 struct absaddr info;
8585};
8586
8587struct ia64_unw_aux_info
8588{
32ec8896
NC
8589 struct ia64_unw_table_entry * table; /* Unwind table. */
8590 unsigned long table_len; /* Length of unwind table. */
8591 unsigned char * info; /* Unwind info. */
8592 unsigned long info_size; /* Size of unwind info. */
8593 bfd_vma info_addr; /* Starting address of unwind info. */
8594 bfd_vma seg_base; /* Starting address of segment. */
8595 Elf_Internal_Sym * symtab; /* The symbol table. */
8596 unsigned long nsyms; /* Number of symbols. */
8597 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8598 unsigned long nfuns; /* Number of entries in funtab. */
8599 char * strtab; /* The string table. */
8600 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8601};
8602
015dc7e1 8603static bool
dda8d76d 8604dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8605{
2cf0635d 8606 struct ia64_unw_table_entry * tp;
948f632f 8607 unsigned long j, nfuns;
4d6ed7c8 8608 int in_body;
015dc7e1 8609 bool res = true;
7036c0e1 8610
948f632f
DA
8611 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8612 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8613 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8614 aux->funtab[nfuns++] = aux->symtab[j];
8615 aux->nfuns = nfuns;
8616 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8617
4d6ed7c8
NC
8618 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8619 {
8620 bfd_vma stamp;
8621 bfd_vma offset;
2cf0635d
NC
8622 const unsigned char * dp;
8623 const unsigned char * head;
53774b7e 8624 const unsigned char * end;
2cf0635d 8625 const char * procname;
4d6ed7c8 8626
dda8d76d 8627 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8628 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8629
8630 fputs ("\n<", stdout);
8631
8632 if (procname)
8633 {
8634 fputs (procname, stdout);
8635
8636 if (offset)
8637 printf ("+%lx", (unsigned long) offset);
8638 }
8639
8640 fputs (">: [", stdout);
8641 print_vma (tp->start.offset, PREFIX_HEX);
8642 fputc ('-', stdout);
8643 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8644 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8645 (unsigned long) (tp->info.offset - aux->seg_base));
8646
53774b7e
NC
8647 /* PR 17531: file: 86232b32. */
8648 if (aux->info == NULL)
8649 continue;
8650
97c0a079
AM
8651 offset = tp->info.offset;
8652 if (tp->info.section)
8653 {
8654 if (tp->info.section >= filedata->file_header.e_shnum)
8655 {
8656 warn (_("Invalid section %u in table entry %ld\n"),
8657 tp->info.section, (long) (tp - aux->table));
015dc7e1 8658 res = false;
97c0a079
AM
8659 continue;
8660 }
8661 offset += filedata->section_headers[tp->info.section].sh_addr;
8662 }
8663 offset -= aux->info_addr;
53774b7e 8664 /* PR 17531: file: 0997b4d1. */
90679903
AM
8665 if (offset >= aux->info_size
8666 || aux->info_size - offset < 8)
53774b7e
NC
8667 {
8668 warn (_("Invalid offset %lx in table entry %ld\n"),
8669 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8670 res = false;
53774b7e
NC
8671 continue;
8672 }
8673
97c0a079 8674 head = aux->info + offset;
a4a00738 8675 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8676
86f55779 8677 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8678 (unsigned) UNW_VER (stamp),
8679 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8680 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8681 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8682 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8683
8684 if (UNW_VER (stamp) != 1)
8685 {
2b692964 8686 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8687 continue;
8688 }
8689
8690 in_body = 0;
53774b7e
NC
8691 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8692 /* PR 17531: file: 16ceda89. */
8693 if (end > aux->info + aux->info_size)
8694 end = aux->info + aux->info_size;
8695 for (dp = head + 8; dp < end;)
b4477bc8 8696 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8697 }
948f632f
DA
8698
8699 free (aux->funtab);
32ec8896
NC
8700
8701 return res;
4d6ed7c8
NC
8702}
8703
015dc7e1 8704static bool
dda8d76d
NC
8705slurp_ia64_unwind_table (Filedata * filedata,
8706 struct ia64_unw_aux_info * aux,
8707 Elf_Internal_Shdr * sec)
4d6ed7c8 8708{
89fac5e3 8709 unsigned long size, nrelas, i;
2cf0635d
NC
8710 Elf_Internal_Phdr * seg;
8711 struct ia64_unw_table_entry * tep;
8712 Elf_Internal_Shdr * relsec;
8713 Elf_Internal_Rela * rela;
8714 Elf_Internal_Rela * rp;
8715 unsigned char * table;
8716 unsigned char * tp;
8717 Elf_Internal_Sym * sym;
8718 const char * relname;
4d6ed7c8 8719
53774b7e
NC
8720 aux->table_len = 0;
8721
4d6ed7c8
NC
8722 /* First, find the starting address of the segment that includes
8723 this section: */
8724
dda8d76d 8725 if (filedata->file_header.e_phnum)
4d6ed7c8 8726 {
dda8d76d 8727 if (! get_program_headers (filedata))
015dc7e1 8728 return false;
4d6ed7c8 8729
dda8d76d
NC
8730 for (seg = filedata->program_headers;
8731 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8732 ++seg)
4d6ed7c8
NC
8733 {
8734 if (seg->p_type != PT_LOAD)
8735 continue;
8736
8737 if (sec->sh_addr >= seg->p_vaddr
8738 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8739 {
8740 aux->seg_base = seg->p_vaddr;
8741 break;
8742 }
8743 }
4d6ed7c8
NC
8744 }
8745
8746 /* Second, build the unwind table from the contents of the unwind section: */
8747 size = sec->sh_size;
dda8d76d 8748 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8749 _("unwind table"));
a6e9f9df 8750 if (!table)
015dc7e1 8751 return false;
4d6ed7c8 8752
53774b7e 8753 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8754 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8755 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8756 tep = aux->table;
53774b7e
NC
8757
8758 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8759 {
8760 tep->start.section = SHN_UNDEF;
8761 tep->end.section = SHN_UNDEF;
8762 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8763 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8764 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8765 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8766 tep->start.offset += aux->seg_base;
8767 tep->end.offset += aux->seg_base;
8768 tep->info.offset += aux->seg_base;
8769 }
8770 free (table);
8771
41e92641 8772 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8773 for (relsec = filedata->section_headers;
8774 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8775 ++relsec)
8776 {
8777 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8778 || relsec->sh_info >= filedata->file_header.e_shnum
8779 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8780 continue;
8781
dda8d76d 8782 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8783 & rela, & nrelas))
53774b7e
NC
8784 {
8785 free (aux->table);
8786 aux->table = NULL;
8787 aux->table_len = 0;
015dc7e1 8788 return false;
53774b7e 8789 }
4d6ed7c8
NC
8790
8791 for (rp = rela; rp < rela + nrelas; ++rp)
8792 {
4770fb94 8793 unsigned int sym_ndx;
726bd37d
AM
8794 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8795 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8796
82b1b41b
NC
8797 /* PR 17531: file: 9fa67536. */
8798 if (relname == NULL)
8799 {
726bd37d 8800 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8801 continue;
8802 }
948f632f 8803
24d127aa 8804 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8805 {
82b1b41b 8806 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8807 continue;
8808 }
8809
89fac5e3 8810 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8811
53774b7e
NC
8812 /* PR 17531: file: 5bc8d9bf. */
8813 if (i >= aux->table_len)
8814 {
8815 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8816 continue;
8817 }
8818
4770fb94
AM
8819 sym_ndx = get_reloc_symindex (rp->r_info);
8820 if (sym_ndx >= aux->nsyms)
8821 {
8822 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8823 sym_ndx);
8824 continue;
8825 }
8826 sym = aux->symtab + sym_ndx;
8827
53774b7e 8828 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8829 {
8830 case 0:
8831 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8832 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8833 break;
8834 case 1:
8835 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8836 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8837 break;
8838 case 2:
8839 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8840 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8841 break;
8842 default:
8843 break;
8844 }
8845 }
8846
8847 free (rela);
8848 }
8849
015dc7e1 8850 return true;
4d6ed7c8
NC
8851}
8852
015dc7e1 8853static bool
dda8d76d 8854ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8855{
2cf0635d
NC
8856 Elf_Internal_Shdr * sec;
8857 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8858 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8859 struct ia64_unw_aux_info aux;
015dc7e1 8860 bool res = true;
f1467e33 8861
4d6ed7c8
NC
8862 memset (& aux, 0, sizeof (aux));
8863
dda8d76d 8864 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8865 {
28d13567 8866 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8867 {
28d13567 8868 if (aux.symtab)
4082ef84 8869 {
28d13567
AM
8870 error (_("Multiple symbol tables encountered\n"));
8871 free (aux.symtab);
8872 aux.symtab = NULL;
4082ef84 8873 free (aux.strtab);
28d13567 8874 aux.strtab = NULL;
4082ef84 8875 }
28d13567
AM
8876 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8877 &aux.strtab, &aux.strtab_size))
015dc7e1 8878 return false;
4d6ed7c8
NC
8879 }
8880 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8881 unwcount++;
8882 }
8883
8884 if (!unwcount)
8885 printf (_("\nThere are no unwind sections in this file.\n"));
8886
8887 while (unwcount-- > 0)
8888 {
84714f86 8889 const char *suffix;
579f31ac
JJ
8890 size_t len, len2;
8891
dda8d76d
NC
8892 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8893 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8894 if (sec->sh_type == SHT_IA_64_UNWIND)
8895 {
8896 unwsec = sec;
8897 break;
8898 }
4082ef84
NC
8899 /* We have already counted the number of SHT_IA64_UNWIND
8900 sections so the loop above should never fail. */
8901 assert (unwsec != NULL);
579f31ac
JJ
8902
8903 unwstart = i + 1;
8904 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8905
e4b17d5c
L
8906 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8907 {
8908 /* We need to find which section group it is in. */
4082ef84 8909 struct group_list * g;
e4b17d5c 8910
978c4450
AM
8911 if (filedata->section_headers_groups == NULL
8912 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8913 i = filedata->file_header.e_shnum;
4082ef84 8914 else
e4b17d5c 8915 {
978c4450 8916 g = filedata->section_headers_groups[i]->root;
18bd398b 8917
4082ef84
NC
8918 for (; g != NULL; g = g->next)
8919 {
dda8d76d 8920 sec = filedata->section_headers + g->section_index;
e4b17d5c 8921
84714f86
AM
8922 if (section_name_valid (filedata, sec)
8923 && streq (section_name (filedata, sec),
8924 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8925 break;
8926 }
8927
8928 if (g == NULL)
dda8d76d 8929 i = filedata->file_header.e_shnum;
4082ef84 8930 }
e4b17d5c 8931 }
84714f86
AM
8932 else if (section_name_valid (filedata, unwsec)
8933 && startswith (section_name (filedata, unwsec),
e9b095a5 8934 ELF_STRING_ia64_unwind_once))
579f31ac 8935 {
18bd398b 8936 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8937 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8938 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8939 for (i = 0, sec = filedata->section_headers;
8940 i < filedata->file_header.e_shnum;
579f31ac 8941 ++i, ++sec)
84714f86
AM
8942 if (section_name_valid (filedata, sec)
8943 && startswith (section_name (filedata, sec),
e9b095a5 8944 ELF_STRING_ia64_unwind_info_once)
84714f86 8945 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8946 break;
8947 }
8948 else
8949 {
8950 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8951 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8952 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8953 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8954 suffix = "";
84714f86
AM
8955 if (section_name_valid (filedata, unwsec)
8956 && startswith (section_name (filedata, unwsec),
8957 ELF_STRING_ia64_unwind))
8958 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8959 for (i = 0, sec = filedata->section_headers;
8960 i < filedata->file_header.e_shnum;
579f31ac 8961 ++i, ++sec)
84714f86
AM
8962 if (section_name_valid (filedata, sec)
8963 && startswith (section_name (filedata, sec),
8964 ELF_STRING_ia64_unwind_info)
8965 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8966 break;
8967 }
8968
dda8d76d 8969 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8970 {
8971 printf (_("\nCould not find unwind info section for "));
8972
dda8d76d 8973 if (filedata->string_table == NULL)
579f31ac
JJ
8974 printf ("%d", unwsec->sh_name);
8975 else
dda8d76d 8976 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8977 }
8978 else
4d6ed7c8 8979 {
4d6ed7c8 8980 aux.info_addr = sec->sh_addr;
dda8d76d 8981 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8982 sec->sh_size,
8983 _("unwind info"));
59245841 8984 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8985
579f31ac 8986 printf (_("\nUnwind section "));
4d6ed7c8 8987
dda8d76d 8988 if (filedata->string_table == NULL)
579f31ac
JJ
8989 printf ("%d", unwsec->sh_name);
8990 else
dda8d76d 8991 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8992
579f31ac 8993 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8994 (unsigned long) unwsec->sh_offset,
89fac5e3 8995 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8996
dda8d76d 8997 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8998 && aux.table_len > 0)
dda8d76d 8999 dump_ia64_unwind (filedata, & aux);
579f31ac 9000
9db70fc3
AM
9001 free ((char *) aux.table);
9002 free ((char *) aux.info);
579f31ac
JJ
9003 aux.table = NULL;
9004 aux.info = NULL;
9005 }
4d6ed7c8 9006 }
4d6ed7c8 9007
9db70fc3
AM
9008 free (aux.symtab);
9009 free ((char *) aux.strtab);
32ec8896
NC
9010
9011 return res;
4d6ed7c8
NC
9012}
9013
3f5e193b 9014struct hppa_unw_table_entry
32ec8896
NC
9015{
9016 struct absaddr start;
9017 struct absaddr end;
9018 unsigned int Cannot_unwind:1; /* 0 */
9019 unsigned int Millicode:1; /* 1 */
9020 unsigned int Millicode_save_sr0:1; /* 2 */
9021 unsigned int Region_description:2; /* 3..4 */
9022 unsigned int reserved1:1; /* 5 */
9023 unsigned int Entry_SR:1; /* 6 */
9024 unsigned int Entry_FR:4; /* Number saved 7..10 */
9025 unsigned int Entry_GR:5; /* Number saved 11..15 */
9026 unsigned int Args_stored:1; /* 16 */
9027 unsigned int Variable_Frame:1; /* 17 */
9028 unsigned int Separate_Package_Body:1; /* 18 */
9029 unsigned int Frame_Extension_Millicode:1; /* 19 */
9030 unsigned int Stack_Overflow_Check:1; /* 20 */
9031 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9032 unsigned int Ada_Region:1; /* 22 */
9033 unsigned int cxx_info:1; /* 23 */
9034 unsigned int cxx_try_catch:1; /* 24 */
9035 unsigned int sched_entry_seq:1; /* 25 */
9036 unsigned int reserved2:1; /* 26 */
9037 unsigned int Save_SP:1; /* 27 */
9038 unsigned int Save_RP:1; /* 28 */
9039 unsigned int Save_MRP_in_frame:1; /* 29 */
9040 unsigned int extn_ptr_defined:1; /* 30 */
9041 unsigned int Cleanup_defined:1; /* 31 */
9042
9043 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9044 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9045 unsigned int Large_frame:1; /* 2 */
9046 unsigned int Pseudo_SP_Set:1; /* 3 */
9047 unsigned int reserved4:1; /* 4 */
9048 unsigned int Total_frame_size:27; /* 5..31 */
9049};
3f5e193b 9050
57346661 9051struct hppa_unw_aux_info
948f632f 9052{
32ec8896
NC
9053 struct hppa_unw_table_entry * table; /* Unwind table. */
9054 unsigned long table_len; /* Length of unwind table. */
9055 bfd_vma seg_base; /* Starting address of segment. */
9056 Elf_Internal_Sym * symtab; /* The symbol table. */
9057 unsigned long nsyms; /* Number of symbols. */
9058 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9059 unsigned long nfuns; /* Number of entries in funtab. */
9060 char * strtab; /* The string table. */
9061 unsigned long strtab_size; /* Size of string table. */
948f632f 9062};
57346661 9063
015dc7e1 9064static bool
dda8d76d 9065dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9066{
2cf0635d 9067 struct hppa_unw_table_entry * tp;
948f632f 9068 unsigned long j, nfuns;
015dc7e1 9069 bool res = true;
948f632f
DA
9070
9071 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9072 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9073 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9074 aux->funtab[nfuns++] = aux->symtab[j];
9075 aux->nfuns = nfuns;
9076 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9077
57346661
AM
9078 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9079 {
9080 bfd_vma offset;
2cf0635d 9081 const char * procname;
57346661 9082
dda8d76d 9083 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9084 aux->strtab_size, tp->start, &procname,
9085 &offset);
9086
9087 fputs ("\n<", stdout);
9088
9089 if (procname)
9090 {
9091 fputs (procname, stdout);
9092
9093 if (offset)
9094 printf ("+%lx", (unsigned long) offset);
9095 }
9096
9097 fputs (">: [", stdout);
9098 print_vma (tp->start.offset, PREFIX_HEX);
9099 fputc ('-', stdout);
9100 print_vma (tp->end.offset, PREFIX_HEX);
9101 printf ("]\n\t");
9102
18bd398b
NC
9103#define PF(_m) if (tp->_m) printf (#_m " ");
9104#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9105 PF(Cannot_unwind);
9106 PF(Millicode);
9107 PF(Millicode_save_sr0);
18bd398b 9108 /* PV(Region_description); */
57346661
AM
9109 PF(Entry_SR);
9110 PV(Entry_FR);
9111 PV(Entry_GR);
9112 PF(Args_stored);
9113 PF(Variable_Frame);
9114 PF(Separate_Package_Body);
9115 PF(Frame_Extension_Millicode);
9116 PF(Stack_Overflow_Check);
9117 PF(Two_Instruction_SP_Increment);
9118 PF(Ada_Region);
9119 PF(cxx_info);
9120 PF(cxx_try_catch);
9121 PF(sched_entry_seq);
9122 PF(Save_SP);
9123 PF(Save_RP);
9124 PF(Save_MRP_in_frame);
9125 PF(extn_ptr_defined);
9126 PF(Cleanup_defined);
9127 PF(MPE_XL_interrupt_marker);
9128 PF(HP_UX_interrupt_marker);
9129 PF(Large_frame);
9130 PF(Pseudo_SP_Set);
9131 PV(Total_frame_size);
9132#undef PF
9133#undef PV
9134 }
9135
18bd398b 9136 printf ("\n");
948f632f
DA
9137
9138 free (aux->funtab);
32ec8896
NC
9139
9140 return res;
57346661
AM
9141}
9142
015dc7e1 9143static bool
dda8d76d
NC
9144slurp_hppa_unwind_table (Filedata * filedata,
9145 struct hppa_unw_aux_info * aux,
9146 Elf_Internal_Shdr * sec)
57346661 9147{
1c0751b2 9148 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9149 Elf_Internal_Phdr * seg;
9150 struct hppa_unw_table_entry * tep;
9151 Elf_Internal_Shdr * relsec;
9152 Elf_Internal_Rela * rela;
9153 Elf_Internal_Rela * rp;
9154 unsigned char * table;
9155 unsigned char * tp;
9156 Elf_Internal_Sym * sym;
9157 const char * relname;
57346661 9158
57346661
AM
9159 /* First, find the starting address of the segment that includes
9160 this section. */
dda8d76d 9161 if (filedata->file_header.e_phnum)
57346661 9162 {
dda8d76d 9163 if (! get_program_headers (filedata))
015dc7e1 9164 return false;
57346661 9165
dda8d76d
NC
9166 for (seg = filedata->program_headers;
9167 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9168 ++seg)
9169 {
9170 if (seg->p_type != PT_LOAD)
9171 continue;
9172
9173 if (sec->sh_addr >= seg->p_vaddr
9174 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9175 {
9176 aux->seg_base = seg->p_vaddr;
9177 break;
9178 }
9179 }
9180 }
9181
9182 /* Second, build the unwind table from the contents of the unwind
9183 section. */
9184 size = sec->sh_size;
dda8d76d 9185 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9186 _("unwind table"));
57346661 9187 if (!table)
015dc7e1 9188 return false;
57346661 9189
1c0751b2
DA
9190 unw_ent_size = 16;
9191 nentries = size / unw_ent_size;
9192 size = unw_ent_size * nentries;
57346661 9193
e3fdc001 9194 aux->table_len = nentries;
3f5e193b
NC
9195 tep = aux->table = (struct hppa_unw_table_entry *)
9196 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9197
1c0751b2 9198 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9199 {
9200 unsigned int tmp1, tmp2;
9201
9202 tep->start.section = SHN_UNDEF;
9203 tep->end.section = SHN_UNDEF;
9204
1c0751b2
DA
9205 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9206 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9207 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9208 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9209
9210 tep->start.offset += aux->seg_base;
9211 tep->end.offset += aux->seg_base;
57346661
AM
9212
9213 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9214 tep->Millicode = (tmp1 >> 30) & 0x1;
9215 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9216 tep->Region_description = (tmp1 >> 27) & 0x3;
9217 tep->reserved1 = (tmp1 >> 26) & 0x1;
9218 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9219 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9220 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9221 tep->Args_stored = (tmp1 >> 15) & 0x1;
9222 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9223 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9224 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9225 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9226 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9227 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9228 tep->cxx_info = (tmp1 >> 8) & 0x1;
9229 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9230 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9231 tep->reserved2 = (tmp1 >> 5) & 0x1;
9232 tep->Save_SP = (tmp1 >> 4) & 0x1;
9233 tep->Save_RP = (tmp1 >> 3) & 0x1;
9234 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9235 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9236 tep->Cleanup_defined = tmp1 & 0x1;
9237
9238 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9239 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9240 tep->Large_frame = (tmp2 >> 29) & 0x1;
9241 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9242 tep->reserved4 = (tmp2 >> 27) & 0x1;
9243 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9244 }
9245 free (table);
9246
9247 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9248 for (relsec = filedata->section_headers;
9249 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9250 ++relsec)
9251 {
9252 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9253 || relsec->sh_info >= filedata->file_header.e_shnum
9254 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9255 continue;
9256
dda8d76d 9257 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9258 & rela, & nrelas))
015dc7e1 9259 return false;
57346661
AM
9260
9261 for (rp = rela; rp < rela + nrelas; ++rp)
9262 {
4770fb94 9263 unsigned int sym_ndx;
726bd37d
AM
9264 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9265 relname = elf_hppa_reloc_type (r_type);
57346661 9266
726bd37d
AM
9267 if (relname == NULL)
9268 {
9269 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9270 continue;
9271 }
9272
57346661 9273 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9274 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9275 {
726bd37d 9276 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9277 continue;
9278 }
9279
9280 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9281 if (i >= aux->table_len)
9282 {
9283 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9284 continue;
9285 }
57346661 9286
4770fb94
AM
9287 sym_ndx = get_reloc_symindex (rp->r_info);
9288 if (sym_ndx >= aux->nsyms)
9289 {
9290 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9291 sym_ndx);
9292 continue;
9293 }
9294 sym = aux->symtab + sym_ndx;
9295
43f6cd05 9296 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9297 {
9298 case 0:
9299 aux->table[i].start.section = sym->st_shndx;
1e456d54 9300 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9301 break;
9302 case 1:
9303 aux->table[i].end.section = sym->st_shndx;
1e456d54 9304 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9305 break;
9306 default:
9307 break;
9308 }
9309 }
9310
9311 free (rela);
9312 }
9313
015dc7e1 9314 return true;
57346661
AM
9315}
9316
015dc7e1 9317static bool
dda8d76d 9318hppa_process_unwind (Filedata * filedata)
57346661 9319{
57346661 9320 struct hppa_unw_aux_info aux;
2cf0635d 9321 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9322 Elf_Internal_Shdr * sec;
18bd398b 9323 unsigned long i;
015dc7e1 9324 bool res = true;
57346661 9325
dda8d76d 9326 if (filedata->string_table == NULL)
015dc7e1 9327 return false;
1b31d05e
NC
9328
9329 memset (& aux, 0, sizeof (aux));
57346661 9330
dda8d76d 9331 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9332 {
28d13567 9333 if (sec->sh_type == SHT_SYMTAB)
57346661 9334 {
28d13567 9335 if (aux.symtab)
4082ef84 9336 {
28d13567
AM
9337 error (_("Multiple symbol tables encountered\n"));
9338 free (aux.symtab);
9339 aux.symtab = NULL;
4082ef84 9340 free (aux.strtab);
28d13567 9341 aux.strtab = NULL;
4082ef84 9342 }
28d13567
AM
9343 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9344 &aux.strtab, &aux.strtab_size))
015dc7e1 9345 return false;
57346661 9346 }
84714f86
AM
9347 else if (section_name_valid (filedata, sec)
9348 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9349 unwsec = sec;
9350 }
9351
9352 if (!unwsec)
9353 printf (_("\nThere are no unwind sections in this file.\n"));
9354
dda8d76d 9355 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9356 {
84714f86
AM
9357 if (section_name_valid (filedata, sec)
9358 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9359 {
43f6cd05 9360 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9361
d3a49aa8
AM
9362 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9363 "contains %lu entry:\n",
9364 "\nUnwind section '%s' at offset 0x%lx "
9365 "contains %lu entries:\n",
9366 num_unwind),
dda8d76d 9367 printable_section_name (filedata, sec),
57346661 9368 (unsigned long) sec->sh_offset,
d3a49aa8 9369 num_unwind);
57346661 9370
dda8d76d 9371 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9372 res = false;
66b09c7e
S
9373
9374 if (res && aux.table_len > 0)
32ec8896 9375 {
dda8d76d 9376 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9377 res = false;
32ec8896 9378 }
57346661 9379
9db70fc3 9380 free ((char *) aux.table);
57346661
AM
9381 aux.table = NULL;
9382 }
9383 }
9384
9db70fc3
AM
9385 free (aux.symtab);
9386 free ((char *) aux.strtab);
32ec8896
NC
9387
9388 return res;
57346661
AM
9389}
9390
0b6ae522
DJ
9391struct arm_section
9392{
a734115a
NC
9393 unsigned char * data; /* The unwind data. */
9394 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9395 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9396 unsigned long nrelas; /* The number of relocations. */
9397 unsigned int rel_type; /* REL or RELA ? */
9398 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9399};
9400
9401struct arm_unw_aux_info
9402{
dda8d76d 9403 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9404 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9405 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9406 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9407 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9408 char * strtab; /* The file's string table. */
9409 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9410};
9411
9412static const char *
dda8d76d
NC
9413arm_print_vma_and_name (Filedata * filedata,
9414 struct arm_unw_aux_info * aux,
9415 bfd_vma fn,
9416 struct absaddr addr)
0b6ae522
DJ
9417{
9418 const char *procname;
9419 bfd_vma sym_offset;
9420
9421 if (addr.section == SHN_UNDEF)
9422 addr.offset = fn;
9423
dda8d76d 9424 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9425 aux->strtab_size, addr, &procname,
9426 &sym_offset);
9427
9428 print_vma (fn, PREFIX_HEX);
9429
9430 if (procname)
9431 {
9432 fputs (" <", stdout);
9433 fputs (procname, stdout);
9434
9435 if (sym_offset)
9436 printf ("+0x%lx", (unsigned long) sym_offset);
9437 fputc ('>', stdout);
9438 }
9439
9440 return procname;
9441}
9442
9443static void
9444arm_free_section (struct arm_section *arm_sec)
9445{
9db70fc3
AM
9446 free (arm_sec->data);
9447 free (arm_sec->rela);
0b6ae522
DJ
9448}
9449
a734115a
NC
9450/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9451 cached section and install SEC instead.
9452 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9453 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9454 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9455 relocation's offset in ADDR.
1b31d05e
NC
9456 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9457 into the string table of the symbol associated with the reloc. If no
9458 reloc was applied store -1 there.
9459 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9460
015dc7e1 9461static bool
dda8d76d
NC
9462get_unwind_section_word (Filedata * filedata,
9463 struct arm_unw_aux_info * aux,
1b31d05e
NC
9464 struct arm_section * arm_sec,
9465 Elf_Internal_Shdr * sec,
9466 bfd_vma word_offset,
9467 unsigned int * wordp,
9468 struct absaddr * addr,
9469 bfd_vma * sym_name)
0b6ae522
DJ
9470{
9471 Elf_Internal_Rela *rp;
9472 Elf_Internal_Sym *sym;
9473 const char * relname;
9474 unsigned int word;
015dc7e1 9475 bool wrapped;
0b6ae522 9476
e0a31db1 9477 if (sec == NULL || arm_sec == NULL)
015dc7e1 9478 return false;
e0a31db1 9479
0b6ae522
DJ
9480 addr->section = SHN_UNDEF;
9481 addr->offset = 0;
9482
1b31d05e
NC
9483 if (sym_name != NULL)
9484 *sym_name = (bfd_vma) -1;
9485
a734115a 9486 /* If necessary, update the section cache. */
0b6ae522
DJ
9487 if (sec != arm_sec->sec)
9488 {
9489 Elf_Internal_Shdr *relsec;
9490
9491 arm_free_section (arm_sec);
9492
9493 arm_sec->sec = sec;
dda8d76d 9494 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9495 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9496 arm_sec->rela = NULL;
9497 arm_sec->nrelas = 0;
9498
dda8d76d
NC
9499 for (relsec = filedata->section_headers;
9500 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9501 ++relsec)
9502 {
dda8d76d
NC
9503 if (relsec->sh_info >= filedata->file_header.e_shnum
9504 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9505 /* PR 15745: Check the section type as well. */
9506 || (relsec->sh_type != SHT_REL
9507 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9508 continue;
9509
a734115a 9510 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9511 if (relsec->sh_type == SHT_REL)
9512 {
dda8d76d 9513 if (!slurp_rel_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 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9519 {
dda8d76d 9520 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9521 relsec->sh_size,
9522 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9523 return false;
0b6ae522 9524 }
1ae40aa4 9525 break;
0b6ae522
DJ
9526 }
9527
9528 arm_sec->next_rela = arm_sec->rela;
9529 }
9530
a734115a 9531 /* If there is no unwind data we can do nothing. */
0b6ae522 9532 if (arm_sec->data == NULL)
015dc7e1 9533 return false;
0b6ae522 9534
e0a31db1 9535 /* If the offset is invalid then fail. */
f32ba729
NC
9536 if (/* PR 21343 *//* PR 18879 */
9537 sec->sh_size < 4
9538 || word_offset > (sec->sh_size - 4)
1a915552 9539 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9540 return false;
e0a31db1 9541
a734115a 9542 /* Get the word at the required offset. */
0b6ae522
DJ
9543 word = byte_get (arm_sec->data + word_offset, 4);
9544
0eff7165
NC
9545 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9546 if (arm_sec->rela == NULL)
9547 {
9548 * wordp = word;
015dc7e1 9549 return true;
0eff7165
NC
9550 }
9551
a734115a 9552 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9553 wrapped = false;
0b6ae522
DJ
9554 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9555 {
9556 bfd_vma prelval, offset;
9557
9558 if (rp->r_offset > word_offset && !wrapped)
9559 {
9560 rp = arm_sec->rela;
015dc7e1 9561 wrapped = true;
0b6ae522
DJ
9562 }
9563 if (rp->r_offset > word_offset)
9564 break;
9565
9566 if (rp->r_offset & 3)
9567 {
9568 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9569 (unsigned long) rp->r_offset);
9570 continue;
9571 }
9572
9573 if (rp->r_offset < word_offset)
9574 continue;
9575
74e1a04b
NC
9576 /* PR 17531: file: 027-161405-0.004 */
9577 if (aux->symtab == NULL)
9578 continue;
9579
0b6ae522
DJ
9580 if (arm_sec->rel_type == SHT_REL)
9581 {
9582 offset = word & 0x7fffffff;
9583 if (offset & 0x40000000)
9584 offset |= ~ (bfd_vma) 0x7fffffff;
9585 }
a734115a 9586 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9587 offset = rp->r_addend;
a734115a 9588 else
74e1a04b
NC
9589 {
9590 error (_("Unknown section relocation type %d encountered\n"),
9591 arm_sec->rel_type);
9592 break;
9593 }
0b6ae522 9594
071436c6
NC
9595 /* PR 17531 file: 027-1241568-0.004. */
9596 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9597 {
9598 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9599 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9600 break;
9601 }
9602
9603 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9604 offset += sym->st_value;
9605 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9606
a734115a 9607 /* Check that we are processing the expected reloc type. */
dda8d76d 9608 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9609 {
9610 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9611 if (relname == NULL)
9612 {
9613 warn (_("Skipping unknown ARM relocation type: %d\n"),
9614 (int) ELF32_R_TYPE (rp->r_info));
9615 continue;
9616 }
a734115a
NC
9617
9618 if (streq (relname, "R_ARM_NONE"))
9619 continue;
0b4362b0 9620
a734115a
NC
9621 if (! streq (relname, "R_ARM_PREL31"))
9622 {
071436c6 9623 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9624 continue;
9625 }
9626 }
dda8d76d 9627 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9628 {
9629 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9630 if (relname == NULL)
9631 {
9632 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9633 (int) ELF32_R_TYPE (rp->r_info));
9634 continue;
9635 }
0b4362b0 9636
a734115a
NC
9637 if (streq (relname, "R_C6000_NONE"))
9638 continue;
9639
9640 if (! streq (relname, "R_C6000_PREL31"))
9641 {
071436c6 9642 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9643 continue;
9644 }
9645
9646 prelval >>= 1;
9647 }
9648 else
74e1a04b
NC
9649 {
9650 /* This function currently only supports ARM and TI unwinders. */
9651 warn (_("Only TI and ARM unwinders are currently supported\n"));
9652 break;
9653 }
fa197c1c 9654
0b6ae522
DJ
9655 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9656 addr->section = sym->st_shndx;
9657 addr->offset = offset;
74e1a04b 9658
1b31d05e
NC
9659 if (sym_name)
9660 * sym_name = sym->st_name;
0b6ae522
DJ
9661 break;
9662 }
9663
9664 *wordp = word;
9665 arm_sec->next_rela = rp;
9666
015dc7e1 9667 return true;
0b6ae522
DJ
9668}
9669
a734115a
NC
9670static const char *tic6x_unwind_regnames[16] =
9671{
0b4362b0
RM
9672 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9673 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9674 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9675};
fa197c1c 9676
0b6ae522 9677static void
fa197c1c 9678decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9679{
fa197c1c
PB
9680 int i;
9681
9682 for (i = 12; mask; mask >>= 1, i--)
9683 {
9684 if (mask & 1)
9685 {
9686 fputs (tic6x_unwind_regnames[i], stdout);
9687 if (mask > 1)
9688 fputs (", ", stdout);
9689 }
9690 }
9691}
0b6ae522
DJ
9692
9693#define ADVANCE \
9694 if (remaining == 0 && more_words) \
9695 { \
9696 data_offset += 4; \
dda8d76d 9697 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9698 data_offset, & word, & addr, NULL)) \
015dc7e1 9699 return false; \
0b6ae522
DJ
9700 remaining = 4; \
9701 more_words--; \
9702 } \
9703
9704#define GET_OP(OP) \
9705 ADVANCE; \
9706 if (remaining) \
9707 { \
9708 remaining--; \
9709 (OP) = word >> 24; \
9710 word <<= 8; \
9711 } \
9712 else \
9713 { \
2b692964 9714 printf (_("[Truncated opcode]\n")); \
015dc7e1 9715 return false; \
0b6ae522 9716 } \
cc5914eb 9717 printf ("0x%02x ", OP)
0b6ae522 9718
015dc7e1 9719static bool
dda8d76d
NC
9720decode_arm_unwind_bytecode (Filedata * filedata,
9721 struct arm_unw_aux_info * aux,
948f632f
DA
9722 unsigned int word,
9723 unsigned int remaining,
9724 unsigned int more_words,
9725 bfd_vma data_offset,
9726 Elf_Internal_Shdr * data_sec,
9727 struct arm_section * data_arm_sec)
fa197c1c
PB
9728{
9729 struct absaddr addr;
015dc7e1 9730 bool res = true;
0b6ae522
DJ
9731
9732 /* Decode the unwinding instructions. */
9733 while (1)
9734 {
9735 unsigned int op, op2;
9736
9737 ADVANCE;
9738 if (remaining == 0)
9739 break;
9740 remaining--;
9741 op = word >> 24;
9742 word <<= 8;
9743
cc5914eb 9744 printf (" 0x%02x ", op);
0b6ae522
DJ
9745
9746 if ((op & 0xc0) == 0x00)
9747 {
9748 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9749
cc5914eb 9750 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9751 }
9752 else if ((op & 0xc0) == 0x40)
9753 {
9754 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9755
cc5914eb 9756 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9757 }
9758 else if ((op & 0xf0) == 0x80)
9759 {
9760 GET_OP (op2);
9761 if (op == 0x80 && op2 == 0)
9762 printf (_("Refuse to unwind"));
9763 else
9764 {
9765 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9766 bool first = true;
0b6ae522 9767 int i;
2b692964 9768
0b6ae522
DJ
9769 printf ("pop {");
9770 for (i = 0; i < 12; i++)
9771 if (mask & (1 << i))
9772 {
9773 if (first)
015dc7e1 9774 first = false;
0b6ae522
DJ
9775 else
9776 printf (", ");
9777 printf ("r%d", 4 + i);
9778 }
9779 printf ("}");
9780 }
9781 }
9782 else if ((op & 0xf0) == 0x90)
9783 {
9784 if (op == 0x9d || op == 0x9f)
9785 printf (_(" [Reserved]"));
9786 else
cc5914eb 9787 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9788 }
9789 else if ((op & 0xf0) == 0xa0)
9790 {
9791 int end = 4 + (op & 0x07);
015dc7e1 9792 bool first = true;
0b6ae522 9793 int i;
61865e30 9794
0b6ae522
DJ
9795 printf (" pop {");
9796 for (i = 4; i <= end; i++)
9797 {
9798 if (first)
015dc7e1 9799 first = false;
0b6ae522
DJ
9800 else
9801 printf (", ");
9802 printf ("r%d", i);
9803 }
9804 if (op & 0x08)
9805 {
1b31d05e 9806 if (!first)
0b6ae522
DJ
9807 printf (", ");
9808 printf ("r14");
9809 }
9810 printf ("}");
9811 }
9812 else if (op == 0xb0)
9813 printf (_(" finish"));
9814 else if (op == 0xb1)
9815 {
9816 GET_OP (op2);
9817 if (op2 == 0 || (op2 & 0xf0) != 0)
9818 printf (_("[Spare]"));
9819 else
9820 {
9821 unsigned int mask = op2 & 0x0f;
015dc7e1 9822 bool first = true;
0b6ae522 9823 int i;
61865e30 9824
0b6ae522
DJ
9825 printf ("pop {");
9826 for (i = 0; i < 12; i++)
9827 if (mask & (1 << i))
9828 {
9829 if (first)
015dc7e1 9830 first = false;
0b6ae522
DJ
9831 else
9832 printf (", ");
9833 printf ("r%d", i);
9834 }
9835 printf ("}");
9836 }
9837 }
9838 else if (op == 0xb2)
9839 {
b115cf96 9840 unsigned char buf[9];
0b6ae522
DJ
9841 unsigned int i, len;
9842 unsigned long offset;
61865e30 9843
b115cf96 9844 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9845 {
9846 GET_OP (buf[i]);
9847 if ((buf[i] & 0x80) == 0)
9848 break;
9849 }
4082ef84 9850 if (i == sizeof (buf))
32ec8896 9851 {
27a45f42 9852 error (_("corrupt change to vsp\n"));
015dc7e1 9853 res = false;
32ec8896 9854 }
4082ef84
NC
9855 else
9856 {
015dc7e1 9857 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9858 assert (len == i + 1);
9859 offset = offset * 4 + 0x204;
9860 printf ("vsp = vsp + %ld", offset);
9861 }
0b6ae522 9862 }
61865e30 9863 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9864 {
61865e30
NC
9865 unsigned int first, last;
9866
9867 GET_OP (op2);
9868 first = op2 >> 4;
9869 last = op2 & 0x0f;
9870 if (op == 0xc8)
9871 first = first + 16;
9872 printf ("pop {D%d", first);
9873 if (last)
9874 printf ("-D%d", first + last);
9875 printf ("}");
9876 }
09854a88
TB
9877 else if (op == 0xb4)
9878 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9879 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9880 {
9881 unsigned int count = op & 0x07;
9882
9883 printf ("pop {D8");
9884 if (count)
9885 printf ("-D%d", 8 + count);
9886 printf ("}");
9887 }
9888 else if (op >= 0xc0 && op <= 0xc5)
9889 {
9890 unsigned int count = op & 0x07;
9891
9892 printf (" pop {wR10");
9893 if (count)
9894 printf ("-wR%d", 10 + count);
9895 printf ("}");
9896 }
9897 else if (op == 0xc6)
9898 {
9899 unsigned int first, last;
9900
9901 GET_OP (op2);
9902 first = op2 >> 4;
9903 last = op2 & 0x0f;
9904 printf ("pop {wR%d", first);
9905 if (last)
9906 printf ("-wR%d", first + last);
9907 printf ("}");
9908 }
9909 else if (op == 0xc7)
9910 {
9911 GET_OP (op2);
9912 if (op2 == 0 || (op2 & 0xf0) != 0)
9913 printf (_("[Spare]"));
0b6ae522
DJ
9914 else
9915 {
61865e30 9916 unsigned int mask = op2 & 0x0f;
015dc7e1 9917 bool first = true;
61865e30
NC
9918 int i;
9919
9920 printf ("pop {");
9921 for (i = 0; i < 4; i++)
9922 if (mask & (1 << i))
9923 {
9924 if (first)
015dc7e1 9925 first = false;
61865e30
NC
9926 else
9927 printf (", ");
9928 printf ("wCGR%d", i);
9929 }
9930 printf ("}");
0b6ae522
DJ
9931 }
9932 }
61865e30 9933 else
32ec8896
NC
9934 {
9935 printf (_(" [unsupported opcode]"));
015dc7e1 9936 res = false;
32ec8896
NC
9937 }
9938
0b6ae522
DJ
9939 printf ("\n");
9940 }
32ec8896
NC
9941
9942 return res;
fa197c1c
PB
9943}
9944
015dc7e1 9945static bool
dda8d76d
NC
9946decode_tic6x_unwind_bytecode (Filedata * filedata,
9947 struct arm_unw_aux_info * aux,
948f632f
DA
9948 unsigned int word,
9949 unsigned int remaining,
9950 unsigned int more_words,
9951 bfd_vma data_offset,
9952 Elf_Internal_Shdr * data_sec,
9953 struct arm_section * data_arm_sec)
fa197c1c
PB
9954{
9955 struct absaddr addr;
9956
9957 /* Decode the unwinding instructions. */
9958 while (1)
9959 {
9960 unsigned int op, op2;
9961
9962 ADVANCE;
9963 if (remaining == 0)
9964 break;
9965 remaining--;
9966 op = word >> 24;
9967 word <<= 8;
9968
9cf03b7e 9969 printf (" 0x%02x ", op);
fa197c1c
PB
9970
9971 if ((op & 0xc0) == 0x00)
9972 {
9973 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9974 printf (" sp = sp + %d", offset);
fa197c1c
PB
9975 }
9976 else if ((op & 0xc0) == 0x80)
9977 {
9978 GET_OP (op2);
9979 if (op == 0x80 && op2 == 0)
9980 printf (_("Refuse to unwind"));
9981 else
9982 {
9983 unsigned int mask = ((op & 0x1f) << 8) | op2;
9984 if (op & 0x20)
9985 printf ("pop compact {");
9986 else
9987 printf ("pop {");
9988
9989 decode_tic6x_unwind_regmask (mask);
9990 printf("}");
9991 }
9992 }
9993 else if ((op & 0xf0) == 0xc0)
9994 {
9995 unsigned int reg;
9996 unsigned int nregs;
9997 unsigned int i;
9998 const char *name;
a734115a
NC
9999 struct
10000 {
32ec8896
NC
10001 unsigned int offset;
10002 unsigned int reg;
fa197c1c
PB
10003 } regpos[16];
10004
10005 /* Scan entire instruction first so that GET_OP output is not
10006 interleaved with disassembly. */
10007 nregs = 0;
10008 for (i = 0; nregs < (op & 0xf); i++)
10009 {
10010 GET_OP (op2);
10011 reg = op2 >> 4;
10012 if (reg != 0xf)
10013 {
10014 regpos[nregs].offset = i * 2;
10015 regpos[nregs].reg = reg;
10016 nregs++;
10017 }
10018
10019 reg = op2 & 0xf;
10020 if (reg != 0xf)
10021 {
10022 regpos[nregs].offset = i * 2 + 1;
10023 regpos[nregs].reg = reg;
10024 nregs++;
10025 }
10026 }
10027
10028 printf (_("pop frame {"));
18344509 10029 if (nregs == 0)
fa197c1c 10030 {
18344509
NC
10031 printf (_("*corrupt* - no registers specified"));
10032 }
10033 else
10034 {
10035 reg = nregs - 1;
10036 for (i = i * 2; i > 0; i--)
fa197c1c 10037 {
18344509
NC
10038 if (regpos[reg].offset == i - 1)
10039 {
10040 name = tic6x_unwind_regnames[regpos[reg].reg];
10041 if (reg > 0)
10042 reg--;
10043 }
10044 else
10045 name = _("[pad]");
fa197c1c 10046
18344509
NC
10047 fputs (name, stdout);
10048 if (i > 1)
10049 printf (", ");
10050 }
fa197c1c
PB
10051 }
10052
10053 printf ("}");
10054 }
10055 else if (op == 0xd0)
10056 printf (" MOV FP, SP");
10057 else if (op == 0xd1)
10058 printf (" __c6xabi_pop_rts");
10059 else if (op == 0xd2)
10060 {
10061 unsigned char buf[9];
10062 unsigned int i, len;
10063 unsigned long offset;
a734115a 10064
fa197c1c
PB
10065 for (i = 0; i < sizeof (buf); i++)
10066 {
10067 GET_OP (buf[i]);
10068 if ((buf[i] & 0x80) == 0)
10069 break;
10070 }
0eff7165
NC
10071 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10072 if (i == sizeof (buf))
10073 {
0eff7165 10074 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10075 return false;
0eff7165 10076 }
948f632f 10077
015dc7e1 10078 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10079 assert (len == i + 1);
10080 offset = offset * 8 + 0x408;
10081 printf (_("sp = sp + %ld"), offset);
10082 }
10083 else if ((op & 0xf0) == 0xe0)
10084 {
10085 if ((op & 0x0f) == 7)
10086 printf (" RETURN");
10087 else
10088 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10089 }
10090 else
10091 {
10092 printf (_(" [unsupported opcode]"));
10093 }
10094 putchar ('\n');
10095 }
32ec8896 10096
015dc7e1 10097 return true;
fa197c1c
PB
10098}
10099
10100static bfd_vma
dda8d76d 10101arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
10102{
10103 bfd_vma offset;
10104
10105 offset = word & 0x7fffffff;
10106 if (offset & 0x40000000)
10107 offset |= ~ (bfd_vma) 0x7fffffff;
10108
dda8d76d 10109 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10110 offset <<= 1;
10111
10112 return offset + where;
10113}
10114
015dc7e1 10115static bool
dda8d76d
NC
10116decode_arm_unwind (Filedata * filedata,
10117 struct arm_unw_aux_info * aux,
1b31d05e
NC
10118 unsigned int word,
10119 unsigned int remaining,
10120 bfd_vma data_offset,
10121 Elf_Internal_Shdr * data_sec,
10122 struct arm_section * data_arm_sec)
fa197c1c
PB
10123{
10124 int per_index;
10125 unsigned int more_words = 0;
37e14bc3 10126 struct absaddr addr;
1b31d05e 10127 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 10128 bool res = true;
fa197c1c
PB
10129
10130 if (remaining == 0)
10131 {
1b31d05e
NC
10132 /* Fetch the first word.
10133 Note - when decoding an object file the address extracted
10134 here will always be 0. So we also pass in the sym_name
10135 parameter so that we can find the symbol associated with
10136 the personality routine. */
dda8d76d 10137 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10138 & word, & addr, & sym_name))
015dc7e1 10139 return false;
1b31d05e 10140
fa197c1c
PB
10141 remaining = 4;
10142 }
c93dbb25
CZ
10143 else
10144 {
10145 addr.section = SHN_UNDEF;
10146 addr.offset = 0;
10147 }
fa197c1c
PB
10148
10149 if ((word & 0x80000000) == 0)
10150 {
10151 /* Expand prel31 for personality routine. */
10152 bfd_vma fn;
10153 const char *procname;
10154
dda8d76d 10155 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10156 printf (_(" Personality routine: "));
1b31d05e
NC
10157 if (fn == 0
10158 && addr.section == SHN_UNDEF && addr.offset == 0
10159 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10160 {
10161 procname = aux->strtab + sym_name;
10162 print_vma (fn, PREFIX_HEX);
10163 if (procname)
10164 {
10165 fputs (" <", stdout);
10166 fputs (procname, stdout);
10167 fputc ('>', stdout);
10168 }
10169 }
10170 else
dda8d76d 10171 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10172 fputc ('\n', stdout);
10173
10174 /* The GCC personality routines use the standard compact
10175 encoding, starting with one byte giving the number of
10176 words. */
10177 if (procname != NULL
24d127aa
ML
10178 && (startswith (procname, "__gcc_personality_v0")
10179 || startswith (procname, "__gxx_personality_v0")
10180 || startswith (procname, "__gcj_personality_v0")
10181 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10182 {
10183 remaining = 0;
10184 more_words = 1;
10185 ADVANCE;
10186 if (!remaining)
10187 {
10188 printf (_(" [Truncated data]\n"));
015dc7e1 10189 return false;
fa197c1c
PB
10190 }
10191 more_words = word >> 24;
10192 word <<= 8;
10193 remaining--;
10194 per_index = -1;
10195 }
10196 else
015dc7e1 10197 return true;
fa197c1c
PB
10198 }
10199 else
10200 {
1b31d05e 10201 /* ARM EHABI Section 6.3:
0b4362b0 10202
1b31d05e 10203 An exception-handling table entry for the compact model looks like:
0b4362b0 10204
1b31d05e
NC
10205 31 30-28 27-24 23-0
10206 -- ----- ----- ----
10207 1 0 index Data for personalityRoutine[index] */
10208
dda8d76d 10209 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10210 && (word & 0x70000000))
32ec8896
NC
10211 {
10212 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10213 res = false;
32ec8896 10214 }
1b31d05e 10215
fa197c1c 10216 per_index = (word >> 24) & 0x7f;
1b31d05e 10217 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10218 if (per_index == 0)
10219 {
10220 more_words = 0;
10221 word <<= 8;
10222 remaining--;
10223 }
10224 else if (per_index < 3)
10225 {
10226 more_words = (word >> 16) & 0xff;
10227 word <<= 16;
10228 remaining -= 2;
10229 }
10230 }
10231
dda8d76d 10232 switch (filedata->file_header.e_machine)
fa197c1c
PB
10233 {
10234 case EM_ARM:
10235 if (per_index < 3)
10236 {
dda8d76d 10237 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10238 data_offset, data_sec, data_arm_sec))
015dc7e1 10239 res = false;
fa197c1c
PB
10240 }
10241 else
1b31d05e
NC
10242 {
10243 warn (_("Unknown ARM compact model index encountered\n"));
10244 printf (_(" [reserved]\n"));
015dc7e1 10245 res = false;
1b31d05e 10246 }
fa197c1c
PB
10247 break;
10248
10249 case EM_TI_C6000:
10250 if (per_index < 3)
10251 {
dda8d76d 10252 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10253 data_offset, data_sec, data_arm_sec))
015dc7e1 10254 res = false;
fa197c1c
PB
10255 }
10256 else if (per_index < 5)
10257 {
10258 if (((word >> 17) & 0x7f) == 0x7f)
10259 printf (_(" Restore stack from frame pointer\n"));
10260 else
10261 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10262 printf (_(" Registers restored: "));
10263 if (per_index == 4)
10264 printf (" (compact) ");
10265 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10266 putchar ('\n');
10267 printf (_(" Return register: %s\n"),
10268 tic6x_unwind_regnames[word & 0xf]);
10269 }
10270 else
1b31d05e 10271 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10272 break;
10273
10274 default:
74e1a04b 10275 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10276 filedata->file_header.e_machine);
015dc7e1 10277 res = false;
fa197c1c 10278 }
0b6ae522
DJ
10279
10280 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10281
10282 return res;
0b6ae522
DJ
10283}
10284
015dc7e1 10285static bool
dda8d76d
NC
10286dump_arm_unwind (Filedata * filedata,
10287 struct arm_unw_aux_info * aux,
10288 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10289{
10290 struct arm_section exidx_arm_sec, extab_arm_sec;
10291 unsigned int i, exidx_len;
948f632f 10292 unsigned long j, nfuns;
015dc7e1 10293 bool res = true;
0b6ae522
DJ
10294
10295 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10296 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10297 exidx_len = exidx_sec->sh_size / 8;
10298
948f632f
DA
10299 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10300 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10301 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10302 aux->funtab[nfuns++] = aux->symtab[j];
10303 aux->nfuns = nfuns;
10304 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10305
0b6ae522
DJ
10306 for (i = 0; i < exidx_len; i++)
10307 {
10308 unsigned int exidx_fn, exidx_entry;
10309 struct absaddr fn_addr, entry_addr;
10310 bfd_vma fn;
10311
10312 fputc ('\n', stdout);
10313
dda8d76d 10314 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10315 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10316 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10317 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10318 {
948f632f 10319 free (aux->funtab);
1b31d05e
NC
10320 arm_free_section (& exidx_arm_sec);
10321 arm_free_section (& extab_arm_sec);
015dc7e1 10322 return false;
0b6ae522
DJ
10323 }
10324
83c257ca
NC
10325 /* ARM EHABI, Section 5:
10326 An index table entry consists of 2 words.
10327 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10328 if (exidx_fn & 0x80000000)
32ec8896
NC
10329 {
10330 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10331 res = false;
32ec8896 10332 }
83c257ca 10333
dda8d76d 10334 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10335
dda8d76d 10336 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10337 fputs (": ", stdout);
10338
10339 if (exidx_entry == 1)
10340 {
10341 print_vma (exidx_entry, PREFIX_HEX);
10342 fputs (" [cantunwind]\n", stdout);
10343 }
10344 else if (exidx_entry & 0x80000000)
10345 {
10346 print_vma (exidx_entry, PREFIX_HEX);
10347 fputc ('\n', stdout);
dda8d76d 10348 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10349 }
10350 else
10351 {
8f73510c 10352 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10353 Elf_Internal_Shdr *table_sec;
10354
10355 fputs ("@", stdout);
dda8d76d 10356 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10357 print_vma (table, PREFIX_HEX);
10358 printf ("\n");
10359
10360 /* Locate the matching .ARM.extab. */
10361 if (entry_addr.section != SHN_UNDEF
dda8d76d 10362 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10363 {
dda8d76d 10364 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10365 table_offset = entry_addr.offset;
1a915552
NC
10366 /* PR 18879 */
10367 if (table_offset > table_sec->sh_size
10368 || ((bfd_signed_vma) table_offset) < 0)
10369 {
10370 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10371 (unsigned long) table_offset,
dda8d76d 10372 printable_section_name (filedata, table_sec));
015dc7e1 10373 res = false;
1a915552
NC
10374 continue;
10375 }
0b6ae522
DJ
10376 }
10377 else
10378 {
dda8d76d 10379 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10380 if (table_sec != NULL)
10381 table_offset = table - table_sec->sh_addr;
10382 }
32ec8896 10383
0b6ae522
DJ
10384 if (table_sec == NULL)
10385 {
10386 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10387 (unsigned long) table);
015dc7e1 10388 res = false;
0b6ae522
DJ
10389 continue;
10390 }
32ec8896 10391
dda8d76d 10392 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10393 &extab_arm_sec))
015dc7e1 10394 res = false;
0b6ae522
DJ
10395 }
10396 }
10397
10398 printf ("\n");
10399
948f632f 10400 free (aux->funtab);
0b6ae522
DJ
10401 arm_free_section (&exidx_arm_sec);
10402 arm_free_section (&extab_arm_sec);
32ec8896
NC
10403
10404 return res;
0b6ae522
DJ
10405}
10406
fa197c1c 10407/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10408
015dc7e1 10409static bool
dda8d76d 10410arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10411{
10412 struct arm_unw_aux_info aux;
10413 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10414 Elf_Internal_Shdr *sec;
10415 unsigned long i;
fa197c1c 10416 unsigned int sec_type;
015dc7e1 10417 bool res = true;
0b6ae522 10418
dda8d76d 10419 switch (filedata->file_header.e_machine)
fa197c1c
PB
10420 {
10421 case EM_ARM:
10422 sec_type = SHT_ARM_EXIDX;
10423 break;
10424
10425 case EM_TI_C6000:
10426 sec_type = SHT_C6000_UNWIND;
10427 break;
10428
0b4362b0 10429 default:
74e1a04b 10430 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10431 filedata->file_header.e_machine);
015dc7e1 10432 return false;
fa197c1c
PB
10433 }
10434
dda8d76d 10435 if (filedata->string_table == NULL)
015dc7e1 10436 return false;
1b31d05e
NC
10437
10438 memset (& aux, 0, sizeof (aux));
dda8d76d 10439 aux.filedata = filedata;
0b6ae522 10440
dda8d76d 10441 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10442 {
28d13567 10443 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10444 {
28d13567 10445 if (aux.symtab)
74e1a04b 10446 {
28d13567
AM
10447 error (_("Multiple symbol tables encountered\n"));
10448 free (aux.symtab);
10449 aux.symtab = NULL;
74e1a04b 10450 free (aux.strtab);
28d13567 10451 aux.strtab = NULL;
74e1a04b 10452 }
28d13567
AM
10453 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10454 &aux.strtab, &aux.strtab_size))
015dc7e1 10455 return false;
0b6ae522 10456 }
fa197c1c 10457 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10458 unwsec = sec;
10459 }
10460
1b31d05e 10461 if (unwsec == NULL)
0b6ae522 10462 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10463 else
dda8d76d 10464 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10465 {
10466 if (sec->sh_type == sec_type)
10467 {
d3a49aa8
AM
10468 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10469 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10470 "contains %lu entry:\n",
10471 "\nUnwind section '%s' at offset 0x%lx "
10472 "contains %lu entries:\n",
10473 num_unwind),
dda8d76d 10474 printable_section_name (filedata, sec),
1b31d05e 10475 (unsigned long) sec->sh_offset,
d3a49aa8 10476 num_unwind);
0b6ae522 10477
dda8d76d 10478 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10479 res = false;
1b31d05e
NC
10480 }
10481 }
0b6ae522 10482
9db70fc3
AM
10483 free (aux.symtab);
10484 free ((char *) aux.strtab);
32ec8896
NC
10485
10486 return res;
0b6ae522
DJ
10487}
10488
3ecc00ec
NC
10489static bool
10490no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10491{
10492 printf (_("No processor specific unwind information to decode\n"));
10493 return true;
10494}
10495
015dc7e1 10496static bool
dda8d76d 10497process_unwind (Filedata * filedata)
57346661 10498{
2cf0635d
NC
10499 struct unwind_handler
10500 {
32ec8896 10501 unsigned int machtype;
015dc7e1 10502 bool (* handler)(Filedata *);
2cf0635d
NC
10503 } handlers[] =
10504 {
0b6ae522 10505 { EM_ARM, arm_process_unwind },
57346661
AM
10506 { EM_IA_64, ia64_process_unwind },
10507 { EM_PARISC, hppa_process_unwind },
fa197c1c 10508 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10509 { EM_386, no_processor_specific_unwind },
10510 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10511 { 0, NULL }
57346661
AM
10512 };
10513 int i;
10514
10515 if (!do_unwind)
015dc7e1 10516 return true;
57346661
AM
10517
10518 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10519 if (filedata->file_header.e_machine == handlers[i].machtype)
10520 return handlers[i].handler (filedata);
57346661 10521
1b31d05e 10522 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10523 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10524 return true;
57346661
AM
10525}
10526
37c18eed
SD
10527static void
10528dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10529{
10530 switch (entry->d_tag)
10531 {
10532 case DT_AARCH64_BTI_PLT:
1dbade74 10533 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10534 break;
10535 default:
10536 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10537 break;
10538 }
10539 putchar ('\n');
10540}
10541
252b5132 10542static void
978c4450 10543dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10544{
10545 switch (entry->d_tag)
10546 {
10547 case DT_MIPS_FLAGS:
10548 if (entry->d_un.d_val == 0)
4b68bca3 10549 printf (_("NONE"));
252b5132
RH
10550 else
10551 {
10552 static const char * opts[] =
10553 {
10554 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10555 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10556 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10557 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10558 "RLD_ORDER_SAFE"
10559 };
10560 unsigned int cnt;
015dc7e1 10561 bool first = true;
2b692964 10562
60bca95a 10563 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10564 if (entry->d_un.d_val & (1 << cnt))
10565 {
10566 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10567 first = false;
252b5132 10568 }
252b5132
RH
10569 }
10570 break;
103f02d3 10571
252b5132 10572 case DT_MIPS_IVERSION:
84714f86 10573 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10574 printf (_("Interface Version: %s"),
84714f86 10575 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10576 else
f493c217
AM
10577 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
10578 (uint64_t) entry->d_un.d_ptr);
252b5132 10579 break;
103f02d3 10580
252b5132
RH
10581 case DT_MIPS_TIME_STAMP:
10582 {
d5b07ef4 10583 char timebuf[128];
2cf0635d 10584 struct tm * tmp;
91d6fa6a 10585 time_t atime = entry->d_un.d_val;
82b1b41b 10586
91d6fa6a 10587 tmp = gmtime (&atime);
82b1b41b
NC
10588 /* PR 17531: file: 6accc532. */
10589 if (tmp == NULL)
10590 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10591 else
10592 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10593 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10594 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10595 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10596 }
10597 break;
103f02d3 10598
252b5132
RH
10599 case DT_MIPS_RLD_VERSION:
10600 case DT_MIPS_LOCAL_GOTNO:
10601 case DT_MIPS_CONFLICTNO:
10602 case DT_MIPS_LIBLISTNO:
10603 case DT_MIPS_SYMTABNO:
10604 case DT_MIPS_UNREFEXTNO:
10605 case DT_MIPS_HIPAGENO:
10606 case DT_MIPS_DELTA_CLASS_NO:
10607 case DT_MIPS_DELTA_INSTANCE_NO:
10608 case DT_MIPS_DELTA_RELOC_NO:
10609 case DT_MIPS_DELTA_SYM_NO:
10610 case DT_MIPS_DELTA_CLASSSYM_NO:
10611 case DT_MIPS_COMPACT_SIZE:
c69075ac 10612 print_vma (entry->d_un.d_val, DEC);
252b5132 10613 break;
103f02d3 10614
f16a9783 10615 case DT_MIPS_XHASH:
978c4450
AM
10616 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10617 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10618 /* Falls through. */
10619
103f02d3 10620 default:
4b68bca3 10621 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10622 }
4b68bca3 10623 putchar ('\n');
103f02d3
UD
10624}
10625
103f02d3 10626static void
2cf0635d 10627dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10628{
10629 switch (entry->d_tag)
10630 {
10631 case DT_HP_DLD_FLAGS:
10632 {
10633 static struct
10634 {
10635 long int bit;
2cf0635d 10636 const char * str;
5e220199
NC
10637 }
10638 flags[] =
10639 {
10640 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10641 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10642 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10643 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10644 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10645 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10646 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10647 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10648 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10649 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10650 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10651 { DT_HP_GST, "HP_GST" },
10652 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10653 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10654 { DT_HP_NODELETE, "HP_NODELETE" },
10655 { DT_HP_GROUP, "HP_GROUP" },
10656 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10657 };
015dc7e1 10658 bool first = true;
5e220199 10659 size_t cnt;
f7a99963 10660 bfd_vma val = entry->d_un.d_val;
103f02d3 10661
60bca95a 10662 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10663 if (val & flags[cnt].bit)
30800947
NC
10664 {
10665 if (! first)
10666 putchar (' ');
10667 fputs (flags[cnt].str, stdout);
015dc7e1 10668 first = false;
30800947
NC
10669 val ^= flags[cnt].bit;
10670 }
76da6bbe 10671
103f02d3 10672 if (val != 0 || first)
f7a99963
NC
10673 {
10674 if (! first)
10675 putchar (' ');
10676 print_vma (val, HEX);
10677 }
103f02d3
UD
10678 }
10679 break;
76da6bbe 10680
252b5132 10681 default:
f7a99963
NC
10682 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10683 break;
252b5132 10684 }
35b1837e 10685 putchar ('\n');
252b5132
RH
10686}
10687
28f997cf
TG
10688#ifdef BFD64
10689
10690/* VMS vs Unix time offset and factor. */
10691
10692#define VMS_EPOCH_OFFSET 35067168000000000LL
10693#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10694#ifndef INT64_MIN
10695#define INT64_MIN (-9223372036854775807LL - 1)
10696#endif
28f997cf
TG
10697
10698/* Display a VMS time in a human readable format. */
10699
10700static void
0e3c1eeb 10701print_vms_time (int64_t vmstime)
28f997cf 10702{
dccc31de 10703 struct tm *tm = NULL;
28f997cf
TG
10704 time_t unxtime;
10705
dccc31de
AM
10706 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10707 {
10708 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10709 unxtime = vmstime;
10710 if (unxtime == vmstime)
10711 tm = gmtime (&unxtime);
10712 }
10713 if (tm != NULL)
10714 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10715 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10716 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10717}
10718#endif /* BFD64 */
10719
ecc51f48 10720static void
2cf0635d 10721dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10722{
10723 switch (entry->d_tag)
10724 {
0de14b54 10725 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10726 /* First 3 slots reserved. */
ecc51f48
NC
10727 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10728 printf (" -- ");
10729 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10730 break;
10731
28f997cf
TG
10732 case DT_IA_64_VMS_LINKTIME:
10733#ifdef BFD64
10734 print_vms_time (entry->d_un.d_val);
10735#endif
10736 break;
10737
10738 case DT_IA_64_VMS_LNKFLAGS:
10739 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10740 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10741 printf (" CALL_DEBUG");
10742 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10743 printf (" NOP0BUFS");
10744 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10745 printf (" P0IMAGE");
10746 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10747 printf (" MKTHREADS");
10748 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10749 printf (" UPCALLS");
10750 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10751 printf (" IMGSTA");
10752 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10753 printf (" INITIALIZE");
10754 if (entry->d_un.d_val & VMS_LF_MAIN)
10755 printf (" MAIN");
10756 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10757 printf (" EXE_INIT");
10758 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10759 printf (" TBK_IN_IMG");
10760 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10761 printf (" DBG_IN_IMG");
10762 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10763 printf (" TBK_IN_DSF");
10764 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10765 printf (" DBG_IN_DSF");
10766 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10767 printf (" SIGNATURES");
10768 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10769 printf (" REL_SEG_OFF");
10770 break;
10771
bdf4d63a
JJ
10772 default:
10773 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10774 break;
ecc51f48 10775 }
bdf4d63a 10776 putchar ('\n');
ecc51f48
NC
10777}
10778
015dc7e1 10779static bool
dda8d76d 10780get_32bit_dynamic_section (Filedata * filedata)
252b5132 10781{
2cf0635d
NC
10782 Elf32_External_Dyn * edyn;
10783 Elf32_External_Dyn * ext;
10784 Elf_Internal_Dyn * entry;
103f02d3 10785
978c4450
AM
10786 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10787 filedata->dynamic_addr, 1,
10788 filedata->dynamic_size,
10789 _("dynamic section"));
a6e9f9df 10790 if (!edyn)
015dc7e1 10791 return false;
103f02d3 10792
071436c6
NC
10793 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10794 might not have the luxury of section headers. Look for the DT_NULL
10795 terminator to determine the number of entries. */
978c4450
AM
10796 for (ext = edyn, filedata->dynamic_nent = 0;
10797 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10798 ext++)
10799 {
978c4450 10800 filedata->dynamic_nent++;
ba2685cc
AM
10801 if (BYTE_GET (ext->d_tag) == DT_NULL)
10802 break;
10803 }
252b5132 10804
978c4450
AM
10805 filedata->dynamic_section
10806 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10807 if (filedata->dynamic_section == NULL)
252b5132 10808 {
8b73c356 10809 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10810 (unsigned long) filedata->dynamic_nent);
9ea033b2 10811 free (edyn);
015dc7e1 10812 return false;
9ea033b2 10813 }
252b5132 10814
978c4450
AM
10815 for (ext = edyn, entry = filedata->dynamic_section;
10816 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10817 ext++, entry++)
9ea033b2 10818 {
fb514b26
AM
10819 entry->d_tag = BYTE_GET (ext->d_tag);
10820 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10821 }
10822
9ea033b2
NC
10823 free (edyn);
10824
015dc7e1 10825 return true;
9ea033b2
NC
10826}
10827
015dc7e1 10828static bool
dda8d76d 10829get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10830{
2cf0635d
NC
10831 Elf64_External_Dyn * edyn;
10832 Elf64_External_Dyn * ext;
10833 Elf_Internal_Dyn * entry;
103f02d3 10834
071436c6 10835 /* Read in the data. */
978c4450
AM
10836 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10837 filedata->dynamic_addr, 1,
10838 filedata->dynamic_size,
10839 _("dynamic section"));
a6e9f9df 10840 if (!edyn)
015dc7e1 10841 return false;
103f02d3 10842
071436c6
NC
10843 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10844 might not have the luxury of section headers. Look for the DT_NULL
10845 terminator to determine the number of entries. */
978c4450 10846 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10847 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10848 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10849 ext++)
10850 {
978c4450 10851 filedata->dynamic_nent++;
66543521 10852 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10853 break;
10854 }
252b5132 10855
978c4450
AM
10856 filedata->dynamic_section
10857 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10858 if (filedata->dynamic_section == NULL)
252b5132 10859 {
8b73c356 10860 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10861 (unsigned long) filedata->dynamic_nent);
252b5132 10862 free (edyn);
015dc7e1 10863 return false;
252b5132
RH
10864 }
10865
071436c6 10866 /* Convert from external to internal formats. */
978c4450
AM
10867 for (ext = edyn, entry = filedata->dynamic_section;
10868 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10869 ext++, entry++)
252b5132 10870 {
66543521
AM
10871 entry->d_tag = BYTE_GET (ext->d_tag);
10872 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10873 }
10874
10875 free (edyn);
10876
015dc7e1 10877 return true;
9ea033b2
NC
10878}
10879
4de91c10
AM
10880static bool
10881get_dynamic_section (Filedata *filedata)
10882{
10883 if (filedata->dynamic_section)
10884 return true;
10885
10886 if (is_32bit_elf)
10887 return get_32bit_dynamic_section (filedata);
10888 else
10889 return get_64bit_dynamic_section (filedata);
10890}
10891
e9e44622
JJ
10892static void
10893print_dynamic_flags (bfd_vma flags)
d1133906 10894{
015dc7e1 10895 bool first = true;
13ae64f3 10896
d1133906
NC
10897 while (flags)
10898 {
10899 bfd_vma flag;
10900
10901 flag = flags & - flags;
10902 flags &= ~ flag;
10903
e9e44622 10904 if (first)
015dc7e1 10905 first = false;
e9e44622
JJ
10906 else
10907 putc (' ', stdout);
13ae64f3 10908
d1133906
NC
10909 switch (flag)
10910 {
e9e44622
JJ
10911 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10912 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10913 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10914 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10915 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10916 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10917 }
10918 }
e9e44622 10919 puts ("");
d1133906
NC
10920}
10921
10ca4b04
L
10922static bfd_vma *
10923get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10924{
10925 unsigned char * e_data;
10926 bfd_vma * i_data;
10927
10928 /* If the size_t type is smaller than the bfd_size_type, eg because
10929 you are building a 32-bit tool on a 64-bit host, then make sure
10930 that when (number) is cast to (size_t) no information is lost. */
10931 if (sizeof (size_t) < sizeof (bfd_size_type)
10932 && (bfd_size_type) ((size_t) number) != number)
10933 {
b8281767
AM
10934 error (_("Size truncation prevents reading %" PRIu64
10935 " elements of size %u\n"),
10936 (uint64_t) number, ent_size);
10ca4b04
L
10937 return NULL;
10938 }
10939
10940 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10941 attempting to allocate memory when the read is bound to fail. */
10942 if (ent_size * number > filedata->file_size)
10943 {
b8281767
AM
10944 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
10945 (uint64_t) number);
10ca4b04
L
10946 return NULL;
10947 }
10948
10949 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10950 if (e_data == NULL)
10951 {
b8281767
AM
10952 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
10953 (uint64_t) number);
10ca4b04
L
10954 return NULL;
10955 }
10956
10957 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10958 {
b8281767
AM
10959 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
10960 (uint64_t) number * ent_size);
10ca4b04
L
10961 free (e_data);
10962 return NULL;
10963 }
10964
10965 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10966 if (i_data == NULL)
10967 {
b8281767
AM
10968 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
10969 (uint64_t) number);
10ca4b04
L
10970 free (e_data);
10971 return NULL;
10972 }
10973
10974 while (number--)
10975 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10976
10977 free (e_data);
10978
10979 return i_data;
10980}
10981
10982static unsigned long
10983get_num_dynamic_syms (Filedata * filedata)
10984{
10985 unsigned long num_of_syms = 0;
10986
10987 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10988 return num_of_syms;
10989
978c4450 10990 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10991 {
10992 unsigned char nb[8];
10993 unsigned char nc[8];
10994 unsigned int hash_ent_size = 4;
10995
10996 if ((filedata->file_header.e_machine == EM_ALPHA
10997 || filedata->file_header.e_machine == EM_S390
10998 || filedata->file_header.e_machine == EM_S390_OLD)
10999 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11000 hash_ent_size = 8;
11001
11002 if (fseek (filedata->handle,
978c4450
AM
11003 (filedata->archive_file_offset
11004 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11005 sizeof nb + sizeof nc)),
11006 SEEK_SET))
11007 {
11008 error (_("Unable to seek to start of dynamic information\n"));
11009 goto no_hash;
11010 }
11011
11012 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11013 {
11014 error (_("Failed to read in number of buckets\n"));
11015 goto no_hash;
11016 }
11017
11018 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11019 {
11020 error (_("Failed to read in number of chains\n"));
11021 goto no_hash;
11022 }
11023
978c4450
AM
11024 filedata->nbuckets = byte_get (nb, hash_ent_size);
11025 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11026
2482f306
AM
11027 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11028 {
11029 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11030 hash_ent_size);
11031 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11032 hash_ent_size);
001890e1 11033
2482f306
AM
11034 if (filedata->buckets != NULL && filedata->chains != NULL)
11035 num_of_syms = filedata->nchains;
11036 }
ceb9bf11 11037 no_hash:
10ca4b04
L
11038 if (num_of_syms == 0)
11039 {
9db70fc3
AM
11040 free (filedata->buckets);
11041 filedata->buckets = NULL;
11042 free (filedata->chains);
11043 filedata->chains = NULL;
978c4450 11044 filedata->nbuckets = 0;
10ca4b04
L
11045 }
11046 }
11047
978c4450 11048 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11049 {
11050 unsigned char nb[16];
11051 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11052 bfd_vma buckets_vma;
11053 unsigned long hn;
10ca4b04
L
11054
11055 if (fseek (filedata->handle,
978c4450
AM
11056 (filedata->archive_file_offset
11057 + offset_from_vma (filedata,
11058 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11059 sizeof nb)),
11060 SEEK_SET))
11061 {
11062 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11063 goto no_gnu_hash;
11064 }
11065
11066 if (fread (nb, 16, 1, filedata->handle) != 1)
11067 {
11068 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11069 goto no_gnu_hash;
11070 }
11071
978c4450
AM
11072 filedata->ngnubuckets = byte_get (nb, 4);
11073 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11074 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11075 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11076 if (is_32bit_elf)
11077 buckets_vma += bitmaskwords * 4;
11078 else
11079 buckets_vma += bitmaskwords * 8;
11080
11081 if (fseek (filedata->handle,
978c4450 11082 (filedata->archive_file_offset
10ca4b04
L
11083 + offset_from_vma (filedata, buckets_vma, 4)),
11084 SEEK_SET))
11085 {
11086 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11087 goto no_gnu_hash;
11088 }
11089
978c4450
AM
11090 filedata->gnubuckets
11091 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11092
978c4450 11093 if (filedata->gnubuckets == NULL)
90837ea7 11094 goto no_gnu_hash;
10ca4b04 11095
978c4450
AM
11096 for (i = 0; i < filedata->ngnubuckets; i++)
11097 if (filedata->gnubuckets[i] != 0)
10ca4b04 11098 {
978c4450 11099 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11100 goto no_gnu_hash;
10ca4b04 11101
978c4450
AM
11102 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11103 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11104 }
11105
11106 if (maxchain == 0xffffffff)
90837ea7 11107 goto no_gnu_hash;
10ca4b04 11108
978c4450 11109 maxchain -= filedata->gnusymidx;
10ca4b04
L
11110
11111 if (fseek (filedata->handle,
978c4450
AM
11112 (filedata->archive_file_offset
11113 + offset_from_vma (filedata,
11114 buckets_vma + 4 * (filedata->ngnubuckets
11115 + maxchain),
11116 4)),
10ca4b04
L
11117 SEEK_SET))
11118 {
11119 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11120 goto no_gnu_hash;
11121 }
11122
11123 do
11124 {
11125 if (fread (nb, 4, 1, filedata->handle) != 1)
11126 {
11127 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11128 goto no_gnu_hash;
11129 }
11130
11131 if (maxchain + 1 == 0)
90837ea7 11132 goto no_gnu_hash;
10ca4b04
L
11133
11134 ++maxchain;
11135 }
11136 while ((byte_get (nb, 4) & 1) == 0);
11137
11138 if (fseek (filedata->handle,
978c4450
AM
11139 (filedata->archive_file_offset
11140 + offset_from_vma (filedata, (buckets_vma
11141 + 4 * filedata->ngnubuckets),
11142 4)),
10ca4b04
L
11143 SEEK_SET))
11144 {
11145 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11146 goto no_gnu_hash;
11147 }
11148
978c4450
AM
11149 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11150 filedata->ngnuchains = maxchain;
10ca4b04 11151
978c4450 11152 if (filedata->gnuchains == NULL)
90837ea7 11153 goto no_gnu_hash;
10ca4b04 11154
978c4450 11155 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11156 {
11157 if (fseek (filedata->handle,
978c4450 11158 (filedata->archive_file_offset
10ca4b04 11159 + offset_from_vma (filedata, (buckets_vma
978c4450 11160 + 4 * (filedata->ngnubuckets
10ca4b04
L
11161 + maxchain)), 4)),
11162 SEEK_SET))
11163 {
11164 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11165 goto no_gnu_hash;
11166 }
11167
978c4450 11168 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11169 if (filedata->mipsxlat == NULL)
11170 goto no_gnu_hash;
10ca4b04
L
11171 }
11172
978c4450
AM
11173 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11174 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11175 {
978c4450
AM
11176 bfd_vma si = filedata->gnubuckets[hn];
11177 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11178
11179 do
11180 {
978c4450 11181 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11182 {
c31ab5a0
AM
11183 if (off < filedata->ngnuchains
11184 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11185 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11186 }
11187 else
11188 {
11189 if (si >= num_of_syms)
11190 num_of_syms = si + 1;
11191 }
11192 si++;
11193 }
978c4450
AM
11194 while (off < filedata->ngnuchains
11195 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11196 }
11197
90837ea7 11198 if (num_of_syms == 0)
10ca4b04 11199 {
90837ea7 11200 no_gnu_hash:
9db70fc3
AM
11201 free (filedata->mipsxlat);
11202 filedata->mipsxlat = NULL;
11203 free (filedata->gnuchains);
11204 filedata->gnuchains = NULL;
11205 free (filedata->gnubuckets);
11206 filedata->gnubuckets = NULL;
978c4450
AM
11207 filedata->ngnubuckets = 0;
11208 filedata->ngnuchains = 0;
10ca4b04
L
11209 }
11210 }
11211
11212 return num_of_syms;
11213}
11214
b2d38a17
NC
11215/* Parse and display the contents of the dynamic section. */
11216
015dc7e1 11217static bool
dda8d76d 11218process_dynamic_section (Filedata * filedata)
9ea033b2 11219{
2cf0635d 11220 Elf_Internal_Dyn * entry;
9ea033b2 11221
93df3340 11222 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11223 {
11224 if (do_dynamic)
ca0e11aa
NC
11225 {
11226 if (filedata->is_separate)
11227 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11228 filedata->file_name);
11229 else
11230 printf (_("\nThere is no dynamic section in this file.\n"));
11231 }
9ea033b2 11232
015dc7e1 11233 return true;
9ea033b2
NC
11234 }
11235
4de91c10
AM
11236 if (!get_dynamic_section (filedata))
11237 return false;
9ea033b2 11238
252b5132 11239 /* Find the appropriate symbol table. */
978c4450 11240 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11241 {
2482f306
AM
11242 unsigned long num_of_syms;
11243
978c4450
AM
11244 for (entry = filedata->dynamic_section;
11245 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11246 ++entry)
10ca4b04 11247 if (entry->d_tag == DT_SYMTAB)
978c4450 11248 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11249 else if (entry->d_tag == DT_SYMENT)
978c4450 11250 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11251 else if (entry->d_tag == DT_HASH)
978c4450 11252 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11253 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11254 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11255 else if ((filedata->file_header.e_machine == EM_MIPS
11256 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11257 && entry->d_tag == DT_MIPS_XHASH)
11258 {
978c4450
AM
11259 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11260 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11261 }
252b5132 11262
2482f306
AM
11263 num_of_syms = get_num_dynamic_syms (filedata);
11264
11265 if (num_of_syms != 0
11266 && filedata->dynamic_symbols == NULL
11267 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11268 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11269 {
11270 Elf_Internal_Phdr *seg;
2482f306 11271 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11272
2482f306
AM
11273 if (! get_program_headers (filedata))
11274 {
11275 error (_("Cannot interpret virtual addresses "
11276 "without program headers.\n"));
015dc7e1 11277 return false;
2482f306 11278 }
252b5132 11279
2482f306
AM
11280 for (seg = filedata->program_headers;
11281 seg < filedata->program_headers + filedata->file_header.e_phnum;
11282 ++seg)
11283 {
11284 if (seg->p_type != PT_LOAD)
11285 continue;
252b5132 11286
2482f306
AM
11287 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11288 {
11289 /* See PR 21379 for a reproducer. */
11290 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11291 return false;
2482f306 11292 }
252b5132 11293
2482f306
AM
11294 if (vma >= (seg->p_vaddr & -seg->p_align)
11295 && vma < seg->p_vaddr + seg->p_filesz)
11296 {
11297 /* Since we do not know how big the symbol table is,
11298 we default to reading in up to the end of PT_LOAD
11299 segment and processing that. This is overkill, I
11300 know, but it should work. */
11301 Elf_Internal_Shdr section;
11302 section.sh_offset = (vma - seg->p_vaddr
11303 + seg->p_offset);
11304 section.sh_size = (num_of_syms
11305 * filedata->dynamic_info[DT_SYMENT]);
11306 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11307
11308 if (do_checks
11309 && filedata->dynamic_symtab_section != NULL
11310 && ((filedata->dynamic_symtab_section->sh_offset
11311 != section.sh_offset)
11312 || (filedata->dynamic_symtab_section->sh_size
11313 != section.sh_size)
11314 || (filedata->dynamic_symtab_section->sh_entsize
11315 != section.sh_entsize)))
11316 warn (_("\
11317the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11318
2482f306
AM
11319 section.sh_name = filedata->string_table_length;
11320 filedata->dynamic_symbols
4de91c10 11321 = get_elf_symbols (filedata, &section,
2482f306
AM
11322 &filedata->num_dynamic_syms);
11323 if (filedata->dynamic_symbols == NULL
11324 || filedata->num_dynamic_syms != num_of_syms)
11325 {
11326 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11327 return false;
2482f306
AM
11328 }
11329 break;
11330 }
11331 }
11332 }
11333 }
252b5132
RH
11334
11335 /* Similarly find a string table. */
978c4450
AM
11336 if (filedata->dynamic_strings == NULL)
11337 for (entry = filedata->dynamic_section;
11338 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11339 ++entry)
11340 {
11341 if (entry->d_tag == DT_STRTAB)
978c4450 11342 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11343
10ca4b04 11344 if (entry->d_tag == DT_STRSZ)
978c4450 11345 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11346
978c4450
AM
11347 if (filedata->dynamic_info[DT_STRTAB]
11348 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11349 {
11350 unsigned long offset;
978c4450 11351 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11352
11353 offset = offset_from_vma (filedata,
978c4450 11354 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11355 str_tab_len);
8ac10c5b
L
11356 if (do_checks
11357 && filedata->dynamic_strtab_section
11358 && ((filedata->dynamic_strtab_section->sh_offset
11359 != (file_ptr) offset)
11360 || (filedata->dynamic_strtab_section->sh_size
11361 != str_tab_len)))
11362 warn (_("\
11363the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11364
978c4450
AM
11365 filedata->dynamic_strings
11366 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11367 _("dynamic string table"));
11368 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11369 {
11370 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11371 break;
11372 }
e3d39609 11373
978c4450 11374 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11375 break;
11376 }
11377 }
252b5132
RH
11378
11379 /* And find the syminfo section if available. */
978c4450 11380 if (filedata->dynamic_syminfo == NULL)
252b5132 11381 {
3e8bba36 11382 unsigned long syminsz = 0;
252b5132 11383
978c4450
AM
11384 for (entry = filedata->dynamic_section;
11385 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11386 ++entry)
252b5132
RH
11387 {
11388 if (entry->d_tag == DT_SYMINENT)
11389 {
11390 /* Note: these braces are necessary to avoid a syntax
11391 error from the SunOS4 C compiler. */
049b0c3a
NC
11392 /* PR binutils/17531: A corrupt file can trigger this test.
11393 So do not use an assert, instead generate an error message. */
11394 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11395 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11396 (int) entry->d_un.d_val);
252b5132
RH
11397 }
11398 else if (entry->d_tag == DT_SYMINSZ)
11399 syminsz = entry->d_un.d_val;
11400 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11401 filedata->dynamic_syminfo_offset
11402 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11403 }
11404
978c4450 11405 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11406 {
2cf0635d
NC
11407 Elf_External_Syminfo * extsyminfo;
11408 Elf_External_Syminfo * extsym;
11409 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11410
11411 /* There is a syminfo section. Read the data. */
3f5e193b 11412 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11413 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11414 1, syminsz, _("symbol information"));
a6e9f9df 11415 if (!extsyminfo)
015dc7e1 11416 return false;
252b5132 11417
978c4450 11418 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11419 {
11420 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11421 free (filedata->dynamic_syminfo);
e3d39609 11422 }
978c4450
AM
11423 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11424 if (filedata->dynamic_syminfo == NULL)
252b5132 11425 {
2482f306
AM
11426 error (_("Out of memory allocating %lu bytes "
11427 "for dynamic symbol info\n"),
8b73c356 11428 (unsigned long) syminsz);
015dc7e1 11429 return false;
252b5132
RH
11430 }
11431
2482f306
AM
11432 filedata->dynamic_syminfo_nent
11433 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11434 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11435 syminfo < (filedata->dynamic_syminfo
11436 + filedata->dynamic_syminfo_nent);
86dba8ee 11437 ++syminfo, ++extsym)
252b5132 11438 {
86dba8ee
AM
11439 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11440 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11441 }
11442
11443 free (extsyminfo);
11444 }
11445 }
11446
978c4450 11447 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11448 {
f253158f
NC
11449 if (filedata->is_separate)
11450 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11451 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11452 (unsigned long) filedata->dynamic_nent),
11453 filedata->file_name,
11454 filedata->dynamic_addr,
11455 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11456 else
11457 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11458 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11459 (unsigned long) filedata->dynamic_nent),
11460 filedata->dynamic_addr,
11461 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11462 }
252b5132
RH
11463 if (do_dynamic)
11464 printf (_(" Tag Type Name/Value\n"));
11465
978c4450
AM
11466 for (entry = filedata->dynamic_section;
11467 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11468 entry++)
252b5132
RH
11469 {
11470 if (do_dynamic)
f7a99963 11471 {
2cf0635d 11472 const char * dtype;
e699b9ff 11473
f7a99963
NC
11474 putchar (' ');
11475 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11476 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11477 printf (" (%s)%*s", dtype,
32ec8896 11478 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11479 }
252b5132
RH
11480
11481 switch (entry->d_tag)
11482 {
d1133906
NC
11483 case DT_FLAGS:
11484 if (do_dynamic)
e9e44622 11485 print_dynamic_flags (entry->d_un.d_val);
d1133906 11486 break;
76da6bbe 11487
252b5132
RH
11488 case DT_AUXILIARY:
11489 case DT_FILTER:
019148e4
L
11490 case DT_CONFIG:
11491 case DT_DEPAUDIT:
11492 case DT_AUDIT:
252b5132
RH
11493 if (do_dynamic)
11494 {
019148e4 11495 switch (entry->d_tag)
b34976b6 11496 {
019148e4
L
11497 case DT_AUXILIARY:
11498 printf (_("Auxiliary library"));
11499 break;
11500
11501 case DT_FILTER:
11502 printf (_("Filter library"));
11503 break;
11504
b34976b6 11505 case DT_CONFIG:
019148e4
L
11506 printf (_("Configuration file"));
11507 break;
11508
11509 case DT_DEPAUDIT:
11510 printf (_("Dependency audit library"));
11511 break;
11512
11513 case DT_AUDIT:
11514 printf (_("Audit library"));
11515 break;
11516 }
252b5132 11517
84714f86 11518 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11519 printf (": [%s]\n",
84714f86 11520 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11521 else
f7a99963
NC
11522 {
11523 printf (": ");
11524 print_vma (entry->d_un.d_val, PREFIX_HEX);
11525 putchar ('\n');
11526 }
252b5132
RH
11527 }
11528 break;
11529
dcefbbbd 11530 case DT_FEATURE:
252b5132
RH
11531 if (do_dynamic)
11532 {
11533 printf (_("Flags:"));
86f55779 11534
252b5132
RH
11535 if (entry->d_un.d_val == 0)
11536 printf (_(" None\n"));
11537 else
11538 {
11539 unsigned long int val = entry->d_un.d_val;
86f55779 11540
252b5132
RH
11541 if (val & DTF_1_PARINIT)
11542 {
11543 printf (" PARINIT");
11544 val ^= DTF_1_PARINIT;
11545 }
dcefbbbd
L
11546 if (val & DTF_1_CONFEXP)
11547 {
11548 printf (" CONFEXP");
11549 val ^= DTF_1_CONFEXP;
11550 }
252b5132
RH
11551 if (val != 0)
11552 printf (" %lx", val);
11553 puts ("");
11554 }
11555 }
11556 break;
11557
11558 case DT_POSFLAG_1:
11559 if (do_dynamic)
11560 {
11561 printf (_("Flags:"));
86f55779 11562
252b5132
RH
11563 if (entry->d_un.d_val == 0)
11564 printf (_(" None\n"));
11565 else
11566 {
11567 unsigned long int val = entry->d_un.d_val;
86f55779 11568
252b5132
RH
11569 if (val & DF_P1_LAZYLOAD)
11570 {
11571 printf (" LAZYLOAD");
11572 val ^= DF_P1_LAZYLOAD;
11573 }
11574 if (val & DF_P1_GROUPPERM)
11575 {
11576 printf (" GROUPPERM");
11577 val ^= DF_P1_GROUPPERM;
11578 }
11579 if (val != 0)
11580 printf (" %lx", val);
11581 puts ("");
11582 }
11583 }
11584 break;
11585
11586 case DT_FLAGS_1:
11587 if (do_dynamic)
11588 {
11589 printf (_("Flags:"));
11590 if (entry->d_un.d_val == 0)
11591 printf (_(" None\n"));
11592 else
11593 {
11594 unsigned long int val = entry->d_un.d_val;
86f55779 11595
252b5132
RH
11596 if (val & DF_1_NOW)
11597 {
11598 printf (" NOW");
11599 val ^= DF_1_NOW;
11600 }
11601 if (val & DF_1_GLOBAL)
11602 {
11603 printf (" GLOBAL");
11604 val ^= DF_1_GLOBAL;
11605 }
11606 if (val & DF_1_GROUP)
11607 {
11608 printf (" GROUP");
11609 val ^= DF_1_GROUP;
11610 }
11611 if (val & DF_1_NODELETE)
11612 {
11613 printf (" NODELETE");
11614 val ^= DF_1_NODELETE;
11615 }
11616 if (val & DF_1_LOADFLTR)
11617 {
11618 printf (" LOADFLTR");
11619 val ^= DF_1_LOADFLTR;
11620 }
11621 if (val & DF_1_INITFIRST)
11622 {
11623 printf (" INITFIRST");
11624 val ^= DF_1_INITFIRST;
11625 }
11626 if (val & DF_1_NOOPEN)
11627 {
11628 printf (" NOOPEN");
11629 val ^= DF_1_NOOPEN;
11630 }
11631 if (val & DF_1_ORIGIN)
11632 {
11633 printf (" ORIGIN");
11634 val ^= DF_1_ORIGIN;
11635 }
11636 if (val & DF_1_DIRECT)
11637 {
11638 printf (" DIRECT");
11639 val ^= DF_1_DIRECT;
11640 }
11641 if (val & DF_1_TRANS)
11642 {
11643 printf (" TRANS");
11644 val ^= DF_1_TRANS;
11645 }
11646 if (val & DF_1_INTERPOSE)
11647 {
11648 printf (" INTERPOSE");
11649 val ^= DF_1_INTERPOSE;
11650 }
f7db6139 11651 if (val & DF_1_NODEFLIB)
dcefbbbd 11652 {
f7db6139
L
11653 printf (" NODEFLIB");
11654 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11655 }
11656 if (val & DF_1_NODUMP)
11657 {
11658 printf (" NODUMP");
11659 val ^= DF_1_NODUMP;
11660 }
34b60028 11661 if (val & DF_1_CONFALT)
dcefbbbd 11662 {
34b60028
L
11663 printf (" CONFALT");
11664 val ^= DF_1_CONFALT;
11665 }
11666 if (val & DF_1_ENDFILTEE)
11667 {
11668 printf (" ENDFILTEE");
11669 val ^= DF_1_ENDFILTEE;
11670 }
11671 if (val & DF_1_DISPRELDNE)
11672 {
11673 printf (" DISPRELDNE");
11674 val ^= DF_1_DISPRELDNE;
11675 }
11676 if (val & DF_1_DISPRELPND)
11677 {
11678 printf (" DISPRELPND");
11679 val ^= DF_1_DISPRELPND;
11680 }
11681 if (val & DF_1_NODIRECT)
11682 {
11683 printf (" NODIRECT");
11684 val ^= DF_1_NODIRECT;
11685 }
11686 if (val & DF_1_IGNMULDEF)
11687 {
11688 printf (" IGNMULDEF");
11689 val ^= DF_1_IGNMULDEF;
11690 }
11691 if (val & DF_1_NOKSYMS)
11692 {
11693 printf (" NOKSYMS");
11694 val ^= DF_1_NOKSYMS;
11695 }
11696 if (val & DF_1_NOHDR)
11697 {
11698 printf (" NOHDR");
11699 val ^= DF_1_NOHDR;
11700 }
11701 if (val & DF_1_EDITED)
11702 {
11703 printf (" EDITED");
11704 val ^= DF_1_EDITED;
11705 }
11706 if (val & DF_1_NORELOC)
11707 {
11708 printf (" NORELOC");
11709 val ^= DF_1_NORELOC;
11710 }
11711 if (val & DF_1_SYMINTPOSE)
11712 {
11713 printf (" SYMINTPOSE");
11714 val ^= DF_1_SYMINTPOSE;
11715 }
11716 if (val & DF_1_GLOBAUDIT)
11717 {
11718 printf (" GLOBAUDIT");
11719 val ^= DF_1_GLOBAUDIT;
11720 }
11721 if (val & DF_1_SINGLETON)
11722 {
11723 printf (" SINGLETON");
11724 val ^= DF_1_SINGLETON;
dcefbbbd 11725 }
5c383f02
RO
11726 if (val & DF_1_STUB)
11727 {
11728 printf (" STUB");
11729 val ^= DF_1_STUB;
11730 }
11731 if (val & DF_1_PIE)
11732 {
11733 printf (" PIE");
11734 val ^= DF_1_PIE;
11735 }
b1202ffa
L
11736 if (val & DF_1_KMOD)
11737 {
11738 printf (" KMOD");
11739 val ^= DF_1_KMOD;
11740 }
11741 if (val & DF_1_WEAKFILTER)
11742 {
11743 printf (" WEAKFILTER");
11744 val ^= DF_1_WEAKFILTER;
11745 }
11746 if (val & DF_1_NOCOMMON)
11747 {
11748 printf (" NOCOMMON");
11749 val ^= DF_1_NOCOMMON;
11750 }
252b5132
RH
11751 if (val != 0)
11752 printf (" %lx", val);
11753 puts ("");
11754 }
11755 }
11756 break;
11757
11758 case DT_PLTREL:
978c4450 11759 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11760 if (do_dynamic)
dda8d76d 11761 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11762 break;
11763
11764 case DT_NULL :
11765 case DT_NEEDED :
11766 case DT_PLTGOT :
11767 case DT_HASH :
11768 case DT_STRTAB :
11769 case DT_SYMTAB :
11770 case DT_RELA :
11771 case DT_INIT :
11772 case DT_FINI :
11773 case DT_SONAME :
11774 case DT_RPATH :
11775 case DT_SYMBOLIC:
11776 case DT_REL :
a7fd1186 11777 case DT_RELR :
252b5132
RH
11778 case DT_DEBUG :
11779 case DT_TEXTREL :
11780 case DT_JMPREL :
019148e4 11781 case DT_RUNPATH :
978c4450 11782 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11783
11784 if (do_dynamic)
11785 {
84714f86 11786 const char *name;
252b5132 11787
84714f86
AM
11788 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11789 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11790 else
d79b3d50 11791 name = NULL;
252b5132
RH
11792
11793 if (name)
11794 {
11795 switch (entry->d_tag)
11796 {
11797 case DT_NEEDED:
11798 printf (_("Shared library: [%s]"), name);
11799
13acb58d
AM
11800 if (filedata->program_interpreter
11801 && streq (name, filedata->program_interpreter))
f7a99963 11802 printf (_(" program interpreter"));
252b5132
RH
11803 break;
11804
11805 case DT_SONAME:
f7a99963 11806 printf (_("Library soname: [%s]"), name);
252b5132
RH
11807 break;
11808
11809 case DT_RPATH:
f7a99963 11810 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11811 break;
11812
019148e4
L
11813 case DT_RUNPATH:
11814 printf (_("Library runpath: [%s]"), name);
11815 break;
11816
252b5132 11817 default:
f7a99963
NC
11818 print_vma (entry->d_un.d_val, PREFIX_HEX);
11819 break;
252b5132
RH
11820 }
11821 }
11822 else
f7a99963
NC
11823 print_vma (entry->d_un.d_val, PREFIX_HEX);
11824
11825 putchar ('\n');
252b5132
RH
11826 }
11827 break;
11828
11829 case DT_PLTRELSZ:
11830 case DT_RELASZ :
11831 case DT_STRSZ :
11832 case DT_RELSZ :
11833 case DT_RELAENT :
a7fd1186
FS
11834 case DT_RELRENT :
11835 case DT_RELRSZ :
252b5132
RH
11836 case DT_SYMENT :
11837 case DT_RELENT :
978c4450 11838 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11839 /* Fall through. */
252b5132
RH
11840 case DT_PLTPADSZ:
11841 case DT_MOVEENT :
11842 case DT_MOVESZ :
04d8355a 11843 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11844 case DT_INIT_ARRAYSZ:
11845 case DT_FINI_ARRAYSZ:
047b2264
JJ
11846 case DT_GNU_CONFLICTSZ:
11847 case DT_GNU_LIBLISTSZ:
252b5132 11848 if (do_dynamic)
f7a99963
NC
11849 {
11850 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11851 printf (_(" (bytes)\n"));
f7a99963 11852 }
252b5132
RH
11853 break;
11854
11855 case DT_VERDEFNUM:
11856 case DT_VERNEEDNUM:
11857 case DT_RELACOUNT:
11858 case DT_RELCOUNT:
11859 if (do_dynamic)
f7a99963
NC
11860 {
11861 print_vma (entry->d_un.d_val, UNSIGNED);
11862 putchar ('\n');
11863 }
252b5132
RH
11864 break;
11865
11866 case DT_SYMINSZ:
11867 case DT_SYMINENT:
11868 case DT_SYMINFO:
11869 case DT_USED:
11870 case DT_INIT_ARRAY:
11871 case DT_FINI_ARRAY:
11872 if (do_dynamic)
11873 {
d79b3d50 11874 if (entry->d_tag == DT_USED
84714f86 11875 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11876 {
84714f86
AM
11877 const char *name
11878 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11879
b34976b6 11880 if (*name)
252b5132
RH
11881 {
11882 printf (_("Not needed object: [%s]\n"), name);
11883 break;
11884 }
11885 }
103f02d3 11886
f7a99963
NC
11887 print_vma (entry->d_un.d_val, PREFIX_HEX);
11888 putchar ('\n');
252b5132
RH
11889 }
11890 break;
11891
11892 case DT_BIND_NOW:
11893 /* The value of this entry is ignored. */
35b1837e
AM
11894 if (do_dynamic)
11895 putchar ('\n');
252b5132 11896 break;
103f02d3 11897
047b2264
JJ
11898 case DT_GNU_PRELINKED:
11899 if (do_dynamic)
11900 {
2cf0635d 11901 struct tm * tmp;
91d6fa6a 11902 time_t atime = entry->d_un.d_val;
047b2264 11903
91d6fa6a 11904 tmp = gmtime (&atime);
071436c6
NC
11905 /* PR 17533 file: 041-1244816-0.004. */
11906 if (tmp == NULL)
5a2cbcf4
L
11907 printf (_("<corrupt time val: %lx"),
11908 (unsigned long) atime);
071436c6
NC
11909 else
11910 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11911 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11912 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11913
11914 }
11915 break;
11916
fdc90cb4 11917 case DT_GNU_HASH:
978c4450 11918 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11919 if (do_dynamic)
11920 {
11921 print_vma (entry->d_un.d_val, PREFIX_HEX);
11922 putchar ('\n');
11923 }
11924 break;
11925
a5da3dee
VDM
11926 case DT_GNU_FLAGS_1:
11927 if (do_dynamic)
11928 {
11929 printf (_("Flags:"));
11930 if (entry->d_un.d_val == 0)
11931 printf (_(" None\n"));
11932 else
11933 {
11934 unsigned long int val = entry->d_un.d_val;
11935
11936 if (val & DF_GNU_1_UNIQUE)
11937 {
11938 printf (" UNIQUE");
11939 val ^= DF_GNU_1_UNIQUE;
11940 }
11941 if (val != 0)
11942 printf (" %lx", val);
11943 puts ("");
11944 }
11945 }
11946 break;
11947
252b5132
RH
11948 default:
11949 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11950 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11951 = entry->d_un.d_val;
252b5132
RH
11952
11953 if (do_dynamic)
11954 {
dda8d76d 11955 switch (filedata->file_header.e_machine)
252b5132 11956 {
37c18eed
SD
11957 case EM_AARCH64:
11958 dynamic_section_aarch64_val (entry);
11959 break;
252b5132 11960 case EM_MIPS:
4fe85591 11961 case EM_MIPS_RS3_LE:
978c4450 11962 dynamic_section_mips_val (filedata, entry);
252b5132 11963 break;
103f02d3 11964 case EM_PARISC:
b2d38a17 11965 dynamic_section_parisc_val (entry);
103f02d3 11966 break;
ecc51f48 11967 case EM_IA_64:
b2d38a17 11968 dynamic_section_ia64_val (entry);
ecc51f48 11969 break;
252b5132 11970 default:
f7a99963
NC
11971 print_vma (entry->d_un.d_val, PREFIX_HEX);
11972 putchar ('\n');
252b5132
RH
11973 }
11974 }
11975 break;
11976 }
11977 }
11978
015dc7e1 11979 return true;
252b5132
RH
11980}
11981
11982static char *
d3ba0551 11983get_ver_flags (unsigned int flags)
252b5132 11984{
6d4f21f6 11985 static char buff[128];
252b5132
RH
11986
11987 buff[0] = 0;
11988
11989 if (flags == 0)
11990 return _("none");
11991
11992 if (flags & VER_FLG_BASE)
7bb1ad17 11993 strcat (buff, "BASE");
252b5132
RH
11994
11995 if (flags & VER_FLG_WEAK)
11996 {
11997 if (flags & VER_FLG_BASE)
7bb1ad17 11998 strcat (buff, " | ");
252b5132 11999
7bb1ad17 12000 strcat (buff, "WEAK");
252b5132
RH
12001 }
12002
44ec90b9
RO
12003 if (flags & VER_FLG_INFO)
12004 {
12005 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12006 strcat (buff, " | ");
44ec90b9 12007
7bb1ad17 12008 strcat (buff, "INFO");
44ec90b9
RO
12009 }
12010
12011 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12012 {
12013 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12014 strcat (buff, " | ");
12015
12016 strcat (buff, _("<unknown>"));
12017 }
252b5132
RH
12018
12019 return buff;
12020}
12021
12022/* Display the contents of the version sections. */
98fb390a 12023
015dc7e1 12024static bool
dda8d76d 12025process_version_sections (Filedata * filedata)
252b5132 12026{
2cf0635d 12027 Elf_Internal_Shdr * section;
b34976b6 12028 unsigned i;
015dc7e1 12029 bool found = false;
252b5132
RH
12030
12031 if (! do_version)
015dc7e1 12032 return true;
252b5132 12033
dda8d76d
NC
12034 for (i = 0, section = filedata->section_headers;
12035 i < filedata->file_header.e_shnum;
b34976b6 12036 i++, section++)
252b5132
RH
12037 {
12038 switch (section->sh_type)
12039 {
12040 case SHT_GNU_verdef:
12041 {
2cf0635d 12042 Elf_External_Verdef * edefs;
452bf675
AM
12043 unsigned long idx;
12044 unsigned long cnt;
2cf0635d 12045 char * endbuf;
252b5132 12046
015dc7e1 12047 found = true;
252b5132 12048
ca0e11aa
NC
12049 if (filedata->is_separate)
12050 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12051 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12052 section->sh_info),
12053 filedata->file_name,
12054 printable_section_name (filedata, section),
12055 section->sh_info);
12056 else
12057 printf (ngettext ("\nVersion definition section '%s' "
12058 "contains %u entry:\n",
12059 "\nVersion definition section '%s' "
12060 "contains %u entries:\n",
12061 section->sh_info),
12062 printable_section_name (filedata, section),
12063 section->sh_info);
047c3dbf 12064
f493c217 12065 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
233f82cf 12066 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12067 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12068 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12069
3f5e193b 12070 edefs = (Elf_External_Verdef *)
dda8d76d 12071 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12072 _("version definition section"));
a6e9f9df
AM
12073 if (!edefs)
12074 break;
59245841 12075 endbuf = (char *) edefs + section->sh_size;
252b5132 12076
1445030f 12077 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12078 {
2cf0635d
NC
12079 char * vstart;
12080 Elf_External_Verdef * edef;
b34976b6 12081 Elf_Internal_Verdef ent;
2cf0635d 12082 Elf_External_Verdaux * eaux;
b34976b6 12083 Elf_Internal_Verdaux aux;
452bf675 12084 unsigned long isum;
b34976b6 12085 int j;
103f02d3 12086
252b5132 12087 vstart = ((char *) edefs) + idx;
54806181
AM
12088 if (vstart + sizeof (*edef) > endbuf)
12089 break;
252b5132
RH
12090
12091 edef = (Elf_External_Verdef *) vstart;
12092
12093 ent.vd_version = BYTE_GET (edef->vd_version);
12094 ent.vd_flags = BYTE_GET (edef->vd_flags);
12095 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12096 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12097 ent.vd_hash = BYTE_GET (edef->vd_hash);
12098 ent.vd_aux = BYTE_GET (edef->vd_aux);
12099 ent.vd_next = BYTE_GET (edef->vd_next);
12100
452bf675 12101 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12102 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12103
12104 printf (_(" Index: %d Cnt: %d "),
12105 ent.vd_ndx, ent.vd_cnt);
12106
452bf675 12107 /* Check for overflow. */
1445030f 12108 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12109 break;
12110
252b5132
RH
12111 vstart += ent.vd_aux;
12112
1445030f
AM
12113 if (vstart + sizeof (*eaux) > endbuf)
12114 break;
252b5132
RH
12115 eaux = (Elf_External_Verdaux *) vstart;
12116
12117 aux.vda_name = BYTE_GET (eaux->vda_name);
12118 aux.vda_next = BYTE_GET (eaux->vda_next);
12119
84714f86 12120 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12121 printf (_("Name: %s\n"),
84714f86 12122 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12123 else
12124 printf (_("Name index: %ld\n"), aux.vda_name);
12125
12126 isum = idx + ent.vd_aux;
12127
b34976b6 12128 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12129 {
1445030f
AM
12130 if (aux.vda_next < sizeof (*eaux)
12131 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12132 {
12133 warn (_("Invalid vda_next field of %lx\n"),
12134 aux.vda_next);
12135 j = ent.vd_cnt;
12136 break;
12137 }
dd24e3da 12138 /* Check for overflow. */
7e26601c 12139 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12140 break;
12141
252b5132
RH
12142 isum += aux.vda_next;
12143 vstart += aux.vda_next;
12144
54806181
AM
12145 if (vstart + sizeof (*eaux) > endbuf)
12146 break;
1445030f 12147 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12148
12149 aux.vda_name = BYTE_GET (eaux->vda_name);
12150 aux.vda_next = BYTE_GET (eaux->vda_next);
12151
84714f86 12152 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12153 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12154 isum, j,
84714f86 12155 get_dynamic_name (filedata, aux.vda_name));
252b5132 12156 else
452bf675 12157 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12158 isum, j, aux.vda_name);
12159 }
dd24e3da 12160
54806181
AM
12161 if (j < ent.vd_cnt)
12162 printf (_(" Version def aux past end of section\n"));
252b5132 12163
c9f02c3e
MR
12164 /* PR 17531:
12165 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12166 if (ent.vd_next < sizeof (*edef)
12167 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12168 {
12169 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12170 cnt = section->sh_info;
12171 break;
12172 }
452bf675 12173 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12174 break;
12175
252b5132
RH
12176 idx += ent.vd_next;
12177 }
dd24e3da 12178
54806181
AM
12179 if (cnt < section->sh_info)
12180 printf (_(" Version definition past end of section\n"));
252b5132
RH
12181
12182 free (edefs);
12183 }
12184 break;
103f02d3 12185
252b5132
RH
12186 case SHT_GNU_verneed:
12187 {
2cf0635d 12188 Elf_External_Verneed * eneed;
452bf675
AM
12189 unsigned long idx;
12190 unsigned long cnt;
2cf0635d 12191 char * endbuf;
252b5132 12192
015dc7e1 12193 found = true;
252b5132 12194
ca0e11aa
NC
12195 if (filedata->is_separate)
12196 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12197 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12198 section->sh_info),
12199 filedata->file_name,
12200 printable_section_name (filedata, section),
12201 section->sh_info);
12202 else
12203 printf (ngettext ("\nVersion needs section '%s' "
12204 "contains %u entry:\n",
12205 "\nVersion needs section '%s' "
12206 "contains %u entries:\n",
12207 section->sh_info),
12208 printable_section_name (filedata, section),
12209 section->sh_info);
047c3dbf 12210
f493c217 12211 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
72de5009 12212 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12213 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12214 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12215
dda8d76d 12216 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12217 section->sh_offset, 1,
12218 section->sh_size,
9cf03b7e 12219 _("Version Needs section"));
a6e9f9df
AM
12220 if (!eneed)
12221 break;
59245841 12222 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12223
12224 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12225 {
2cf0635d 12226 Elf_External_Verneed * entry;
b34976b6 12227 Elf_Internal_Verneed ent;
452bf675 12228 unsigned long isum;
b34976b6 12229 int j;
2cf0635d 12230 char * vstart;
252b5132
RH
12231
12232 vstart = ((char *) eneed) + idx;
54806181
AM
12233 if (vstart + sizeof (*entry) > endbuf)
12234 break;
252b5132
RH
12235
12236 entry = (Elf_External_Verneed *) vstart;
12237
12238 ent.vn_version = BYTE_GET (entry->vn_version);
12239 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12240 ent.vn_file = BYTE_GET (entry->vn_file);
12241 ent.vn_aux = BYTE_GET (entry->vn_aux);
12242 ent.vn_next = BYTE_GET (entry->vn_next);
12243
452bf675 12244 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12245
84714f86 12246 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12247 printf (_(" File: %s"),
84714f86 12248 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12249 else
12250 printf (_(" File: %lx"), ent.vn_file);
12251
12252 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12253
dd24e3da 12254 /* Check for overflow. */
7e26601c 12255 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12256 break;
252b5132
RH
12257 vstart += ent.vn_aux;
12258
12259 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12260 {
2cf0635d 12261 Elf_External_Vernaux * eaux;
b34976b6 12262 Elf_Internal_Vernaux aux;
252b5132 12263
54806181
AM
12264 if (vstart + sizeof (*eaux) > endbuf)
12265 break;
252b5132
RH
12266 eaux = (Elf_External_Vernaux *) vstart;
12267
12268 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12269 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12270 aux.vna_other = BYTE_GET (eaux->vna_other);
12271 aux.vna_name = BYTE_GET (eaux->vna_name);
12272 aux.vna_next = BYTE_GET (eaux->vna_next);
12273
84714f86 12274 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12275 printf (_(" %#06lx: Name: %s"),
84714f86 12276 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12277 else
452bf675 12278 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12279 isum, aux.vna_name);
12280
12281 printf (_(" Flags: %s Version: %d\n"),
12282 get_ver_flags (aux.vna_flags), aux.vna_other);
12283
1445030f
AM
12284 if (aux.vna_next < sizeof (*eaux)
12285 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12286 {
12287 warn (_("Invalid vna_next field of %lx\n"),
12288 aux.vna_next);
12289 j = ent.vn_cnt;
12290 break;
12291 }
1445030f
AM
12292 /* Check for overflow. */
12293 if (aux.vna_next > (size_t) (endbuf - vstart))
12294 break;
252b5132
RH
12295 isum += aux.vna_next;
12296 vstart += aux.vna_next;
12297 }
9cf03b7e 12298
54806181 12299 if (j < ent.vn_cnt)
f9a6a8f0 12300 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12301
1445030f
AM
12302 if (ent.vn_next < sizeof (*entry)
12303 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12304 {
452bf675 12305 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12306 cnt = section->sh_info;
12307 break;
12308 }
1445030f
AM
12309 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12310 break;
252b5132
RH
12311 idx += ent.vn_next;
12312 }
9cf03b7e 12313
54806181 12314 if (cnt < section->sh_info)
9cf03b7e 12315 warn (_("Missing Version Needs information\n"));
103f02d3 12316
252b5132
RH
12317 free (eneed);
12318 }
12319 break;
12320
12321 case SHT_GNU_versym:
12322 {
2cf0635d 12323 Elf_Internal_Shdr * link_section;
8b73c356
NC
12324 size_t total;
12325 unsigned int cnt;
2cf0635d
NC
12326 unsigned char * edata;
12327 unsigned short * data;
12328 char * strtab;
12329 Elf_Internal_Sym * symbols;
12330 Elf_Internal_Shdr * string_sec;
ba5cdace 12331 unsigned long num_syms;
d3ba0551 12332 long off;
252b5132 12333
dda8d76d 12334 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12335 break;
12336
dda8d76d 12337 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12338 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12339
dda8d76d 12340 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12341 break;
12342
015dc7e1 12343 found = true;
252b5132 12344
4de91c10 12345 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12346 if (symbols == NULL)
12347 break;
252b5132 12348
dda8d76d 12349 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12350
dda8d76d 12351 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12352 string_sec->sh_size,
12353 _("version string table"));
a6e9f9df 12354 if (!strtab)
0429c154
MS
12355 {
12356 free (symbols);
12357 break;
12358 }
252b5132 12359
ca0e11aa
NC
12360 if (filedata->is_separate)
12361 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12362 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12363 total),
12364 filedata->file_name,
12365 printable_section_name (filedata, section),
12366 (unsigned long) total);
12367 else
12368 printf (ngettext ("\nVersion symbols section '%s' "
12369 "contains %lu entry:\n",
12370 "\nVersion symbols section '%s' "
12371 "contains %lu entries:\n",
12372 total),
12373 printable_section_name (filedata, section),
12374 (unsigned long) total);
252b5132 12375
f493c217 12376 printf (_(" Addr: 0x%016" PRIx64), (uint64_t) section->sh_addr);
72de5009 12377 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12378 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12379 printable_section_name (filedata, link_section));
252b5132 12380
dda8d76d 12381 off = offset_from_vma (filedata,
978c4450 12382 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12383 total * sizeof (short));
95099889
AM
12384 edata = (unsigned char *) get_data (NULL, filedata, off,
12385 sizeof (short), total,
12386 _("version symbol data"));
a6e9f9df
AM
12387 if (!edata)
12388 {
12389 free (strtab);
0429c154 12390 free (symbols);
a6e9f9df
AM
12391 break;
12392 }
252b5132 12393
3f5e193b 12394 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12395
12396 for (cnt = total; cnt --;)
b34976b6
AM
12397 data[cnt] = byte_get (edata + cnt * sizeof (short),
12398 sizeof (short));
252b5132
RH
12399
12400 free (edata);
12401
12402 for (cnt = 0; cnt < total; cnt += 4)
12403 {
12404 int j, nn;
ab273396
AM
12405 char *name;
12406 char *invalid = _("*invalid*");
252b5132
RH
12407
12408 printf (" %03x:", cnt);
12409
12410 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12411 switch (data[cnt + j])
252b5132
RH
12412 {
12413 case 0:
12414 fputs (_(" 0 (*local*) "), stdout);
12415 break;
12416
12417 case 1:
12418 fputs (_(" 1 (*global*) "), stdout);
12419 break;
12420
12421 default:
c244d050
NC
12422 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12423 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12424
dd24e3da 12425 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12426 array, break to avoid an out-of-bounds read. */
12427 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12428 {
12429 warn (_("invalid index into symbol array\n"));
12430 break;
12431 }
12432
ab273396 12433 name = NULL;
978c4450 12434 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12435 {
b34976b6
AM
12436 Elf_Internal_Verneed ivn;
12437 unsigned long offset;
252b5132 12438
d93f0186 12439 offset = offset_from_vma
978c4450
AM
12440 (filedata,
12441 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12442 sizeof (Elf_External_Verneed));
252b5132 12443
b34976b6 12444 do
252b5132 12445 {
b34976b6
AM
12446 Elf_Internal_Vernaux ivna;
12447 Elf_External_Verneed evn;
12448 Elf_External_Vernaux evna;
12449 unsigned long a_off;
252b5132 12450
dda8d76d 12451 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12452 _("version need")) == NULL)
12453 break;
0b4362b0 12454
252b5132
RH
12455 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12456 ivn.vn_next = BYTE_GET (evn.vn_next);
12457
12458 a_off = offset + ivn.vn_aux;
12459
12460 do
12461 {
dda8d76d 12462 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12463 1, _("version need aux (2)")) == NULL)
12464 {
12465 ivna.vna_next = 0;
12466 ivna.vna_other = 0;
12467 }
12468 else
12469 {
12470 ivna.vna_next = BYTE_GET (evna.vna_next);
12471 ivna.vna_other = BYTE_GET (evna.vna_other);
12472 }
252b5132
RH
12473
12474 a_off += ivna.vna_next;
12475 }
b34976b6 12476 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12477 && ivna.vna_next != 0);
12478
b34976b6 12479 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12480 {
12481 ivna.vna_name = BYTE_GET (evna.vna_name);
12482
54806181 12483 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12484 name = invalid;
54806181
AM
12485 else
12486 name = strtab + ivna.vna_name;
252b5132
RH
12487 break;
12488 }
12489
12490 offset += ivn.vn_next;
12491 }
12492 while (ivn.vn_next);
12493 }
00d93f34 12494
ab273396 12495 if (data[cnt + j] != 0x8001
978c4450 12496 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12497 {
b34976b6
AM
12498 Elf_Internal_Verdef ivd;
12499 Elf_External_Verdef evd;
12500 unsigned long offset;
252b5132 12501
d93f0186 12502 offset = offset_from_vma
978c4450
AM
12503 (filedata,
12504 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12505 sizeof evd);
252b5132
RH
12506
12507 do
12508 {
dda8d76d 12509 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12510 _("version def")) == NULL)
12511 {
12512 ivd.vd_next = 0;
948f632f 12513 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12514 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12515 break;
59245841
NC
12516 }
12517 else
12518 {
12519 ivd.vd_next = BYTE_GET (evd.vd_next);
12520 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12521 }
252b5132
RH
12522
12523 offset += ivd.vd_next;
12524 }
c244d050 12525 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12526 && ivd.vd_next != 0);
12527
c244d050 12528 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12529 {
b34976b6
AM
12530 Elf_External_Verdaux evda;
12531 Elf_Internal_Verdaux ivda;
252b5132
RH
12532
12533 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12534
dda8d76d 12535 if (get_data (&evda, filedata,
59245841
NC
12536 offset - ivd.vd_next + ivd.vd_aux,
12537 sizeof (evda), 1,
12538 _("version def aux")) == NULL)
12539 break;
252b5132
RH
12540
12541 ivda.vda_name = BYTE_GET (evda.vda_name);
12542
54806181 12543 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12544 name = invalid;
12545 else if (name != NULL && name != invalid)
12546 name = _("*both*");
54806181
AM
12547 else
12548 name = strtab + ivda.vda_name;
252b5132
RH
12549 }
12550 }
ab273396
AM
12551 if (name != NULL)
12552 nn += printf ("(%s%-*s",
12553 name,
12554 12 - (int) strlen (name),
12555 ")");
252b5132
RH
12556
12557 if (nn < 18)
12558 printf ("%*c", 18 - nn, ' ');
12559 }
12560
12561 putchar ('\n');
12562 }
12563
12564 free (data);
12565 free (strtab);
12566 free (symbols);
12567 }
12568 break;
103f02d3 12569
252b5132
RH
12570 default:
12571 break;
12572 }
12573 }
12574
12575 if (! found)
ca0e11aa
NC
12576 {
12577 if (filedata->is_separate)
12578 printf (_("\nNo version information found in linked file '%s'.\n"),
12579 filedata->file_name);
12580 else
12581 printf (_("\nNo version information found in this file.\n"));
12582 }
252b5132 12583
015dc7e1 12584 return true;
252b5132
RH
12585}
12586
d1133906 12587static const char *
dda8d76d 12588get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12589{
89246a0e 12590 static char buff[64];
252b5132
RH
12591
12592 switch (binding)
12593 {
b34976b6
AM
12594 case STB_LOCAL: return "LOCAL";
12595 case STB_GLOBAL: return "GLOBAL";
12596 case STB_WEAK: return "WEAK";
252b5132
RH
12597 default:
12598 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12599 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12600 binding);
252b5132 12601 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12602 {
12603 if (binding == STB_GNU_UNIQUE
df3a023b 12604 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12605 return "UNIQUE";
12606 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12607 }
252b5132 12608 else
e9e44622 12609 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12610 return buff;
12611 }
12612}
12613
d1133906 12614static const char *
dda8d76d 12615get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12616{
89246a0e 12617 static char buff[64];
252b5132
RH
12618
12619 switch (type)
12620 {
b34976b6
AM
12621 case STT_NOTYPE: return "NOTYPE";
12622 case STT_OBJECT: return "OBJECT";
12623 case STT_FUNC: return "FUNC";
12624 case STT_SECTION: return "SECTION";
12625 case STT_FILE: return "FILE";
12626 case STT_COMMON: return "COMMON";
12627 case STT_TLS: return "TLS";
15ab5209
DB
12628 case STT_RELC: return "RELC";
12629 case STT_SRELC: return "SRELC";
252b5132
RH
12630 default:
12631 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12632 {
dda8d76d 12633 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12634 return "THUMB_FUNC";
103f02d3 12635
dda8d76d 12636 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12637 return "REGISTER";
12638
dda8d76d 12639 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12640 return "PARISC_MILLI";
12641
e9e44622 12642 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12643 }
252b5132 12644 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12645 {
dda8d76d 12646 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12647 {
12648 if (type == STT_HP_OPAQUE)
12649 return "HP_OPAQUE";
12650 if (type == STT_HP_STUB)
12651 return "HP_STUB";
12652 }
12653
d8045f23 12654 if (type == STT_GNU_IFUNC
dda8d76d 12655 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12656 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12657 return "IFUNC";
12658
e9e44622 12659 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12660 }
252b5132 12661 else
e9e44622 12662 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12663 return buff;
12664 }
12665}
12666
d1133906 12667static const char *
d3ba0551 12668get_symbol_visibility (unsigned int visibility)
d1133906
NC
12669{
12670 switch (visibility)
12671 {
b34976b6
AM
12672 case STV_DEFAULT: return "DEFAULT";
12673 case STV_INTERNAL: return "INTERNAL";
12674 case STV_HIDDEN: return "HIDDEN";
d1133906 12675 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12676 default:
27a45f42 12677 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12678 return _("<unknown>");
d1133906
NC
12679 }
12680}
12681
2057d69d
CZ
12682static const char *
12683get_alpha_symbol_other (unsigned int other)
9abca702 12684{
2057d69d
CZ
12685 switch (other)
12686 {
12687 case STO_ALPHA_NOPV: return "NOPV";
12688 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12689 default:
27a45f42 12690 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12691 return _("<unknown>");
9abca702 12692 }
2057d69d
CZ
12693}
12694
fd85a6a1
NC
12695static const char *
12696get_solaris_symbol_visibility (unsigned int visibility)
12697{
12698 switch (visibility)
12699 {
12700 case 4: return "EXPORTED";
12701 case 5: return "SINGLETON";
12702 case 6: return "ELIMINATE";
12703 default: return get_symbol_visibility (visibility);
12704 }
12705}
12706
2301ed1c
SN
12707static const char *
12708get_aarch64_symbol_other (unsigned int other)
12709{
12710 static char buf[32];
12711
12712 if (other & STO_AARCH64_VARIANT_PCS)
12713 {
12714 other &= ~STO_AARCH64_VARIANT_PCS;
12715 if (other == 0)
12716 return "VARIANT_PCS";
12717 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12718 return buf;
12719 }
12720 return NULL;
12721}
12722
5e2b0d47
NC
12723static const char *
12724get_mips_symbol_other (unsigned int other)
12725{
12726 switch (other)
12727 {
32ec8896
NC
12728 case STO_OPTIONAL: return "OPTIONAL";
12729 case STO_MIPS_PLT: return "MIPS PLT";
12730 case STO_MIPS_PIC: return "MIPS PIC";
12731 case STO_MICROMIPS: return "MICROMIPS";
12732 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12733 case STO_MIPS16: return "MIPS16";
12734 default: return NULL;
5e2b0d47
NC
12735 }
12736}
12737
28f997cf 12738static const char *
dda8d76d 12739get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12740{
dda8d76d 12741 if (is_ia64_vms (filedata))
28f997cf
TG
12742 {
12743 static char res[32];
12744
12745 res[0] = 0;
12746
12747 /* Function types is for images and .STB files only. */
dda8d76d 12748 switch (filedata->file_header.e_type)
28f997cf
TG
12749 {
12750 case ET_DYN:
12751 case ET_EXEC:
12752 switch (VMS_ST_FUNC_TYPE (other))
12753 {
12754 case VMS_SFT_CODE_ADDR:
12755 strcat (res, " CA");
12756 break;
12757 case VMS_SFT_SYMV_IDX:
12758 strcat (res, " VEC");
12759 break;
12760 case VMS_SFT_FD:
12761 strcat (res, " FD");
12762 break;
12763 case VMS_SFT_RESERVE:
12764 strcat (res, " RSV");
12765 break;
12766 default:
bee0ee85
NC
12767 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12768 VMS_ST_FUNC_TYPE (other));
12769 strcat (res, " <unknown>");
12770 break;
28f997cf
TG
12771 }
12772 break;
12773 default:
12774 break;
12775 }
12776 switch (VMS_ST_LINKAGE (other))
12777 {
12778 case VMS_STL_IGNORE:
12779 strcat (res, " IGN");
12780 break;
12781 case VMS_STL_RESERVE:
12782 strcat (res, " RSV");
12783 break;
12784 case VMS_STL_STD:
12785 strcat (res, " STD");
12786 break;
12787 case VMS_STL_LNK:
12788 strcat (res, " LNK");
12789 break;
12790 default:
bee0ee85
NC
12791 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12792 VMS_ST_LINKAGE (other));
12793 strcat (res, " <unknown>");
12794 break;
28f997cf
TG
12795 }
12796
12797 if (res[0] != 0)
12798 return res + 1;
12799 else
12800 return res;
12801 }
12802 return NULL;
12803}
12804
6911b7dc
AM
12805static const char *
12806get_ppc64_symbol_other (unsigned int other)
12807{
14732552
AM
12808 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12809 return NULL;
12810
12811 other >>= STO_PPC64_LOCAL_BIT;
12812 if (other <= 6)
6911b7dc 12813 {
89246a0e 12814 static char buf[64];
14732552
AM
12815 if (other >= 2)
12816 other = ppc64_decode_local_entry (other);
12817 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12818 return buf;
12819 }
12820 return NULL;
12821}
12822
8155b853
NC
12823static const char *
12824get_riscv_symbol_other (unsigned int other)
12825{
12826 static char buf[32];
12827 buf[0] = 0;
12828
12829 if (other & STO_RISCV_VARIANT_CC)
12830 {
12831 strcat (buf, _(" VARIANT_CC"));
12832 other &= ~STO_RISCV_VARIANT_CC;
12833 }
12834
12835 if (other != 0)
12836 snprintf (buf, sizeof buf, " %x", other);
12837
12838
12839 if (buf[0] != 0)
12840 return buf + 1;
12841 else
12842 return buf;
12843}
12844
5e2b0d47 12845static const char *
dda8d76d 12846get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12847{
12848 const char * result = NULL;
89246a0e 12849 static char buff [64];
5e2b0d47
NC
12850
12851 if (other == 0)
12852 return "";
12853
dda8d76d 12854 switch (filedata->file_header.e_machine)
5e2b0d47 12855 {
2057d69d
CZ
12856 case EM_ALPHA:
12857 result = get_alpha_symbol_other (other);
12858 break;
2301ed1c
SN
12859 case EM_AARCH64:
12860 result = get_aarch64_symbol_other (other);
12861 break;
5e2b0d47
NC
12862 case EM_MIPS:
12863 result = get_mips_symbol_other (other);
28f997cf
TG
12864 break;
12865 case EM_IA_64:
dda8d76d 12866 result = get_ia64_symbol_other (filedata, other);
28f997cf 12867 break;
6911b7dc
AM
12868 case EM_PPC64:
12869 result = get_ppc64_symbol_other (other);
12870 break;
8155b853
NC
12871 case EM_RISCV:
12872 result = get_riscv_symbol_other (other);
12873 break;
5e2b0d47 12874 default:
fd85a6a1 12875 result = NULL;
5e2b0d47
NC
12876 break;
12877 }
12878
12879 if (result)
12880 return result;
12881
12882 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12883 return buff;
12884}
12885
d1133906 12886static const char *
dda8d76d 12887get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12888{
b34976b6 12889 static char buff[32];
5cf1065c 12890
252b5132
RH
12891 switch (type)
12892 {
b34976b6
AM
12893 case SHN_UNDEF: return "UND";
12894 case SHN_ABS: return "ABS";
12895 case SHN_COMMON: return "COM";
252b5132 12896 default:
9ce701e2 12897 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12898 && filedata->file_header.e_machine == EM_IA_64
12899 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12900 return "ANSI_COM";
12901 else if ((filedata->file_header.e_machine == EM_X86_64
12902 || filedata->file_header.e_machine == EM_L1OM
12903 || filedata->file_header.e_machine == EM_K1OM)
12904 && type == SHN_X86_64_LCOMMON)
12905 return "LARGE_COM";
12906 else if ((type == SHN_MIPS_SCOMMON
12907 && filedata->file_header.e_machine == EM_MIPS)
12908 || (type == SHN_TIC6X_SCOMMON
12909 && filedata->file_header.e_machine == EM_TI_C6000))
12910 return "SCOM";
12911 else if (type == SHN_MIPS_SUNDEFINED
12912 && filedata->file_header.e_machine == EM_MIPS)
12913 return "SUND";
12914 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12915 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12916 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12917 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12918 else if (type >= SHN_LORESERVE)
12919 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12920 else if (filedata->file_header.e_shnum != 0
12921 && type >= filedata->file_header.e_shnum)
12922 sprintf (buff, _("bad section index[%3d]"), type);
12923 else
12924 sprintf (buff, "%3d", type);
12925 break;
fd85a6a1
NC
12926 }
12927
10ca4b04 12928 return buff;
6bd1a22c
L
12929}
12930
bb4d2ac2 12931static const char *
dda8d76d 12932get_symbol_version_string (Filedata * filedata,
015dc7e1 12933 bool is_dynsym,
1449284b
NC
12934 const char * strtab,
12935 unsigned long int strtab_size,
12936 unsigned int si,
12937 Elf_Internal_Sym * psym,
12938 enum versioned_symbol_info * sym_info,
12939 unsigned short * vna_other)
bb4d2ac2 12940{
ab273396
AM
12941 unsigned char data[2];
12942 unsigned short vers_data;
12943 unsigned long offset;
7a815dd5 12944 unsigned short max_vd_ndx;
bb4d2ac2 12945
ab273396 12946 if (!is_dynsym
978c4450 12947 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12948 return NULL;
bb4d2ac2 12949
978c4450
AM
12950 offset = offset_from_vma (filedata,
12951 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12952 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12953
dda8d76d 12954 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12955 sizeof (data), 1, _("version data")) == NULL)
12956 return NULL;
12957
12958 vers_data = byte_get (data, 2);
bb4d2ac2 12959
1f6f5dba 12960 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12961 return NULL;
bb4d2ac2 12962
0b8b7609 12963 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12964 max_vd_ndx = 0;
12965
ab273396
AM
12966 /* Usually we'd only see verdef for defined symbols, and verneed for
12967 undefined symbols. However, symbols defined by the linker in
12968 .dynbss for variables copied from a shared library in order to
12969 avoid text relocations are defined yet have verneed. We could
12970 use a heuristic to detect the special case, for example, check
12971 for verneed first on symbols defined in SHT_NOBITS sections, but
12972 it is simpler and more reliable to just look for both verdef and
12973 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12974
ab273396
AM
12975 if (psym->st_shndx != SHN_UNDEF
12976 && vers_data != 0x8001
978c4450 12977 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12978 {
12979 Elf_Internal_Verdef ivd;
12980 Elf_Internal_Verdaux ivda;
12981 Elf_External_Verdaux evda;
12982 unsigned long off;
bb4d2ac2 12983
dda8d76d 12984 off = offset_from_vma (filedata,
978c4450 12985 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12986 sizeof (Elf_External_Verdef));
12987
12988 do
bb4d2ac2 12989 {
ab273396
AM
12990 Elf_External_Verdef evd;
12991
dda8d76d 12992 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12993 _("version def")) == NULL)
12994 {
12995 ivd.vd_ndx = 0;
12996 ivd.vd_aux = 0;
12997 ivd.vd_next = 0;
1f6f5dba 12998 ivd.vd_flags = 0;
ab273396
AM
12999 }
13000 else
bb4d2ac2 13001 {
ab273396
AM
13002 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13003 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13004 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13005 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13006 }
bb4d2ac2 13007
7a815dd5
L
13008 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13009 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13010
ab273396
AM
13011 off += ivd.vd_next;
13012 }
13013 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13014
ab273396
AM
13015 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13016 {
9abca702 13017 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13018 return NULL;
13019
ab273396
AM
13020 off -= ivd.vd_next;
13021 off += ivd.vd_aux;
bb4d2ac2 13022
dda8d76d 13023 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13024 _("version def aux")) != NULL)
13025 {
13026 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13027
ab273396 13028 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13029 return (ivda.vda_name < strtab_size
13030 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13031 }
13032 }
13033 }
bb4d2ac2 13034
978c4450 13035 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13036 {
13037 Elf_External_Verneed evn;
13038 Elf_Internal_Verneed ivn;
13039 Elf_Internal_Vernaux ivna;
bb4d2ac2 13040
dda8d76d 13041 offset = offset_from_vma (filedata,
978c4450 13042 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13043 sizeof evn);
13044 do
13045 {
13046 unsigned long vna_off;
bb4d2ac2 13047
dda8d76d 13048 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13049 _("version need")) == NULL)
13050 {
13051 ivna.vna_next = 0;
13052 ivna.vna_other = 0;
13053 ivna.vna_name = 0;
13054 break;
13055 }
bb4d2ac2 13056
ab273396
AM
13057 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13058 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13059
ab273396 13060 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13061
ab273396
AM
13062 do
13063 {
13064 Elf_External_Vernaux evna;
bb4d2ac2 13065
dda8d76d 13066 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13067 _("version need aux (3)")) == NULL)
bb4d2ac2 13068 {
ab273396
AM
13069 ivna.vna_next = 0;
13070 ivna.vna_other = 0;
13071 ivna.vna_name = 0;
bb4d2ac2 13072 }
bb4d2ac2 13073 else
bb4d2ac2 13074 {
ab273396
AM
13075 ivna.vna_other = BYTE_GET (evna.vna_other);
13076 ivna.vna_next = BYTE_GET (evna.vna_next);
13077 ivna.vna_name = BYTE_GET (evna.vna_name);
13078 }
bb4d2ac2 13079
ab273396
AM
13080 vna_off += ivna.vna_next;
13081 }
13082 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13083
ab273396
AM
13084 if (ivna.vna_other == vers_data)
13085 break;
bb4d2ac2 13086
ab273396
AM
13087 offset += ivn.vn_next;
13088 }
13089 while (ivn.vn_next != 0);
bb4d2ac2 13090
ab273396
AM
13091 if (ivna.vna_other == vers_data)
13092 {
13093 *sym_info = symbol_undefined;
13094 *vna_other = ivna.vna_other;
13095 return (ivna.vna_name < strtab_size
13096 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13097 }
7a815dd5
L
13098 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13099 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13100 return _("<corrupt>");
bb4d2ac2 13101 }
ab273396 13102 return NULL;
bb4d2ac2
L
13103}
13104
047c3dbf
NL
13105/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13106
13107static unsigned int
13108print_dynamic_symbol_size (bfd_vma vma, int base)
13109{
13110 switch (base)
13111 {
13112 case 8:
13113 return print_vma (vma, OCTAL_5);
13114
13115 case 10:
13116 return print_vma (vma, UNSIGNED_5);
13117
13118 case 16:
13119 return print_vma (vma, PREFIX_HEX_5);
13120
13121 case 0:
13122 default:
13123 return print_vma (vma, DEC_5);
13124 }
13125}
13126
10ca4b04
L
13127static void
13128print_dynamic_symbol (Filedata *filedata, unsigned long si,
13129 Elf_Internal_Sym *symtab,
13130 Elf_Internal_Shdr *section,
13131 char *strtab, size_t strtab_size)
252b5132 13132{
10ca4b04
L
13133 const char *version_string;
13134 enum versioned_symbol_info sym_info;
13135 unsigned short vna_other;
23356397
NC
13136 bool is_valid;
13137 const char * sstr;
10ca4b04 13138 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13139
10ca4b04
L
13140 printf ("%6ld: ", si);
13141 print_vma (psym->st_value, LONG_HEX);
13142 putchar (' ');
047c3dbf 13143 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13144 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13145 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13146 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13147 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13148 else
252b5132 13149 {
10ca4b04 13150 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13151
10ca4b04
L
13152 printf (" %-7s", get_symbol_visibility (vis));
13153 /* Check to see if any other bits in the st_other field are set.
13154 Note - displaying this information disrupts the layout of the
13155 table being generated, but for the moment this case is very rare. */
13156 if (psym->st_other ^ vis)
13157 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13158 }
10ca4b04 13159 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13160
23356397
NC
13161 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13162 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13163 && filedata->section_headers != NULL
23356397
NC
13164 && psym->st_name == 0)
13165 {
84714f86
AM
13166 is_valid
13167 = section_name_valid (filedata,
13168 filedata->section_headers + psym->st_shndx);
23356397 13169 sstr = is_valid ?
84714f86
AM
13170 section_name_print (filedata,
13171 filedata->section_headers + psym->st_shndx)
23356397
NC
13172 : _("<corrupt>");
13173 }
13174 else
13175 {
84714f86 13176 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13177 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13178 }
10ca4b04
L
13179
13180 version_string
13181 = get_symbol_version_string (filedata,
13182 (section == NULL
13183 || section->sh_type == SHT_DYNSYM),
13184 strtab, strtab_size, si,
13185 psym, &sym_info, &vna_other);
b9e920ec 13186
0942c7ab
NC
13187 int len_avail = 21;
13188 if (! do_wide && version_string != NULL)
13189 {
ddb43bab 13190 char buffer[16];
0942c7ab 13191
ddb43bab 13192 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13193
13194 if (sym_info == symbol_undefined)
13195 len_avail -= sprintf (buffer," (%d)", vna_other);
13196 else if (sym_info != symbol_hidden)
13197 len_avail -= 1;
13198 }
13199
13200 print_symbol (len_avail, sstr);
b9e920ec 13201
10ca4b04
L
13202 if (version_string)
13203 {
13204 if (sym_info == symbol_undefined)
13205 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13206 else
10ca4b04
L
13207 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13208 version_string);
13209 }
6bd1a22c 13210
10ca4b04 13211 putchar ('\n');
6bd1a22c 13212
10ca4b04
L
13213 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13214 && section != NULL
13215 && si >= section->sh_info
13216 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13217 && filedata->file_header.e_machine != EM_MIPS
13218 /* Solaris binaries have been found to violate this requirement as
13219 well. Not sure if this is a bug or an ABI requirement. */
13220 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13221 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13222 si, printable_section_name (filedata, section), section->sh_info);
13223}
f16a9783 13224
0f03783c
NC
13225static const char *
13226get_lto_kind (unsigned int kind)
13227{
13228 switch (kind)
13229 {
13230 case 0: return "DEF";
13231 case 1: return "WEAKDEF";
13232 case 2: return "UNDEF";
13233 case 3: return "WEAKUNDEF";
13234 case 4: return "COMMON";
13235 default:
13236 break;
13237 }
13238
13239 static char buffer[30];
13240 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13241 sprintf (buffer, "<unknown: %u>", kind);
13242 return buffer;
13243}
13244
13245static const char *
13246get_lto_visibility (unsigned int visibility)
13247{
13248 switch (visibility)
13249 {
13250 case 0: return "DEFAULT";
13251 case 1: return "PROTECTED";
13252 case 2: return "INTERNAL";
13253 case 3: return "HIDDEN";
13254 default:
13255 break;
13256 }
13257
13258 static char buffer[30];
13259 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13260 sprintf (buffer, "<unknown: %u>", visibility);
13261 return buffer;
13262}
13263
13264static const char *
13265get_lto_sym_type (unsigned int sym_type)
13266{
13267 switch (sym_type)
13268 {
13269 case 0: return "UNKNOWN";
13270 case 1: return "FUNCTION";
13271 case 2: return "VARIABLE";
13272 default:
13273 break;
13274 }
13275
13276 static char buffer[30];
13277 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13278 sprintf (buffer, "<unknown: %u>", sym_type);
13279 return buffer;
13280}
13281
13282/* Display an LTO format symbol table.
13283 FIXME: The format of LTO symbol tables is not formalized.
13284 So this code could need changing in the future. */
13285
015dc7e1 13286static bool
0f03783c
NC
13287display_lto_symtab (Filedata * filedata,
13288 Elf_Internal_Shdr * section)
13289{
13290 if (section->sh_size == 0)
13291 {
ca0e11aa
NC
13292 if (filedata->is_separate)
13293 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13294 printable_section_name (filedata, section),
13295 filedata->file_name);
13296 else
13297 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13298 printable_section_name (filedata, section));
047c3dbf 13299
015dc7e1 13300 return true;
0f03783c
NC
13301 }
13302
13303 if (section->sh_size > filedata->file_size)
13304 {
13305 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13306 printable_section_name (filedata, section),
13307 (unsigned long) section->sh_size);
015dc7e1 13308 return false;
0f03783c
NC
13309 }
13310
13311 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13312 section->sh_size, 1, _("LTO symbols"));
13313 if (alloced_data == NULL)
015dc7e1 13314 return false;
0f03783c
NC
13315
13316 /* Look for extended data for the symbol table. */
13317 Elf_Internal_Shdr * ext;
13318 void * ext_data_orig = NULL;
13319 char * ext_data = NULL;
13320 char * ext_data_end = NULL;
13321 char * ext_name = NULL;
13322
13323 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13324 (section_name (filedata, section)
13325 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13326 && ext_name != NULL /* Paranoia. */
13327 && (ext = find_section (filedata, ext_name)) != NULL)
13328 {
13329 if (ext->sh_size < 3)
13330 error (_("LTO Symbol extension table '%s' is empty!\n"),
13331 printable_section_name (filedata, ext));
13332 else
13333 {
13334 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13335 ext->sh_size, 1,
13336 _("LTO ext symbol data"));
13337 if (ext_data != NULL)
13338 {
13339 ext_data_end = ext_data + ext->sh_size;
13340 if (* ext_data++ != 1)
13341 error (_("Unexpected version number in symbol extension table\n"));
13342 }
13343 }
13344 }
b9e920ec 13345
0f03783c
NC
13346 const unsigned char * data = (const unsigned char *) alloced_data;
13347 const unsigned char * end = data + section->sh_size;
13348
ca0e11aa
NC
13349 if (filedata->is_separate)
13350 printf (_("\nIn linked file '%s': "), filedata->file_name);
13351 else
13352 printf ("\n");
13353
0f03783c
NC
13354 if (ext_data_orig != NULL)
13355 {
13356 if (do_wide)
ca0e11aa 13357 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13358 printable_section_name (filedata, section),
13359 printable_section_name (filedata, ext));
13360 else
13361 {
ca0e11aa 13362 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13363 printable_section_name (filedata, section));
13364 printf (_(" and extension table '%s' contain:\n"),
13365 printable_section_name (filedata, ext));
13366 }
13367 }
13368 else
ca0e11aa 13369 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13370 printable_section_name (filedata, section));
b9e920ec 13371
0f03783c 13372 /* FIXME: Add a wide version. */
b9e920ec 13373 if (ext_data_orig != NULL)
0f03783c
NC
13374 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13375 else
13376 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13377
13378 /* FIXME: We do not handle style prefixes. */
13379
13380 while (data < end)
13381 {
13382 const unsigned char * sym_name = data;
13383 data += strnlen ((const char *) sym_name, end - data) + 1;
13384 if (data >= end)
13385 goto fail;
13386
13387 const unsigned char * comdat_key = data;
13388 data += strnlen ((const char *) comdat_key, end - data) + 1;
13389 if (data >= end)
13390 goto fail;
13391
13392 if (data + 2 + 8 + 4 > end)
13393 goto fail;
13394
13395 unsigned int kind = *data++;
13396 unsigned int visibility = *data++;
13397
928c411d 13398 uint64_t size = byte_get (data, 8);
0f03783c
NC
13399 data += 8;
13400
928c411d 13401 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13402 data += 4;
13403
13404 if (ext_data != NULL)
13405 {
13406 if (ext_data < (ext_data_end - 1))
13407 {
13408 unsigned int sym_type = * ext_data ++;
13409 unsigned int sec_kind = * ext_data ++;
13410
13411 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13412 * comdat_key == 0 ? "-" : (char *) comdat_key,
13413 get_lto_kind (kind),
13414 get_lto_visibility (visibility),
13415 (long) size,
13416 (long) slot,
13417 get_lto_sym_type (sym_type),
13418 (long) sec_kind);
13419 print_symbol (6, (const char *) sym_name);
13420 }
13421 else
13422 {
13423 error (_("Ran out of LTO symbol extension data\n"));
13424 ext_data = NULL;
13425 /* FIXME: return FAIL result ? */
13426 }
13427 }
13428 else
13429 {
13430 printf (" %10s %10s %11s %08lx %08lx _",
13431 * comdat_key == 0 ? "-" : (char *) comdat_key,
13432 get_lto_kind (kind),
13433 get_lto_visibility (visibility),
13434 (long) size,
13435 (long) slot);
13436 print_symbol (21, (const char *) sym_name);
13437 }
13438 putchar ('\n');
13439 }
13440
13441 if (ext_data != NULL && ext_data < ext_data_end)
13442 {
13443 error (_("Data remains in the LTO symbol extension table\n"));
13444 goto fail;
13445 }
13446
13447 free (alloced_data);
13448 free (ext_data_orig);
13449 free (ext_name);
015dc7e1 13450 return true;
b9e920ec 13451
0f03783c
NC
13452 fail:
13453 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13454 free (alloced_data);
13455 free (ext_data_orig);
13456 free (ext_name);
015dc7e1 13457 return false;
0f03783c
NC
13458}
13459
13460/* Display LTO symbol tables. */
13461
015dc7e1 13462static bool
0f03783c
NC
13463process_lto_symbol_tables (Filedata * filedata)
13464{
13465 Elf_Internal_Shdr * section;
13466 unsigned int i;
015dc7e1 13467 bool res = true;
0f03783c
NC
13468
13469 if (!do_lto_syms)
015dc7e1 13470 return true;
0f03783c
NC
13471
13472 if (filedata->section_headers == NULL)
015dc7e1 13473 return true;
0f03783c
NC
13474
13475 for (i = 0, section = filedata->section_headers;
13476 i < filedata->file_header.e_shnum;
13477 i++, section++)
84714f86
AM
13478 if (section_name_valid (filedata, section)
13479 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13480 res &= display_lto_symtab (filedata, section);
13481
b9e920ec 13482 return res;
0f03783c
NC
13483}
13484
10ca4b04 13485/* Dump the symbol table. */
0f03783c 13486
015dc7e1 13487static bool
10ca4b04
L
13488process_symbol_table (Filedata * filedata)
13489{
13490 Elf_Internal_Shdr * section;
f16a9783 13491
10ca4b04 13492 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13493 return true;
6bd1a22c 13494
978c4450 13495 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13496 && do_syms
13497 && do_using_dynamic
978c4450
AM
13498 && filedata->dynamic_strings != NULL
13499 && filedata->dynamic_symbols != NULL)
6bd1a22c 13500 {
10ca4b04 13501 unsigned long si;
6bd1a22c 13502
ca0e11aa
NC
13503 if (filedata->is_separate)
13504 {
13505 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13506 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13507 filedata->num_dynamic_syms),
13508 filedata->file_name,
13509 filedata->num_dynamic_syms);
13510 }
13511 else
13512 {
13513 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13514 "\nSymbol table for image contains %lu entries:\n",
13515 filedata->num_dynamic_syms),
13516 filedata->num_dynamic_syms);
13517 }
10ca4b04
L
13518 if (is_32bit_elf)
13519 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13520 else
13521 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13522
978c4450
AM
13523 for (si = 0; si < filedata->num_dynamic_syms; si++)
13524 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13525 filedata->dynamic_strings,
13526 filedata->dynamic_strings_length);
252b5132 13527 }
8b73c356 13528 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13529 && filedata->section_headers != NULL)
252b5132 13530 {
b34976b6 13531 unsigned int i;
252b5132 13532
dda8d76d
NC
13533 for (i = 0, section = filedata->section_headers;
13534 i < filedata->file_header.e_shnum;
252b5132
RH
13535 i++, section++)
13536 {
2cf0635d 13537 char * strtab = NULL;
c256ffe7 13538 unsigned long int strtab_size = 0;
2cf0635d 13539 Elf_Internal_Sym * symtab;
ef3df110 13540 unsigned long si, num_syms;
252b5132 13541
2c610e4b
L
13542 if ((section->sh_type != SHT_SYMTAB
13543 && section->sh_type != SHT_DYNSYM)
13544 || (!do_syms
13545 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13546 continue;
13547
dd24e3da
NC
13548 if (section->sh_entsize == 0)
13549 {
13550 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13551 printable_section_name (filedata, section));
dd24e3da
NC
13552 continue;
13553 }
13554
d3a49aa8 13555 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13556
13557 if (filedata->is_separate)
13558 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13559 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13560 num_syms),
13561 filedata->file_name,
13562 printable_section_name (filedata, section),
13563 num_syms);
13564 else
13565 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13566 "\nSymbol table '%s' contains %lu entries:\n",
13567 num_syms),
13568 printable_section_name (filedata, section),
13569 num_syms);
dd24e3da 13570
f7a99963 13571 if (is_32bit_elf)
ca47b30c 13572 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13573 else
ca47b30c 13574 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13575
4de91c10 13576 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13577 if (symtab == NULL)
13578 continue;
13579
dda8d76d 13580 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13581 {
dda8d76d
NC
13582 strtab = filedata->string_table;
13583 strtab_size = filedata->string_table_length;
c256ffe7 13584 }
dda8d76d 13585 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13586 {
2cf0635d 13587 Elf_Internal_Shdr * string_sec;
252b5132 13588
dda8d76d 13589 string_sec = filedata->section_headers + section->sh_link;
252b5132 13590
dda8d76d 13591 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13592 1, string_sec->sh_size,
13593 _("string table"));
c256ffe7 13594 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13595 }
13596
10ca4b04
L
13597 for (si = 0; si < num_syms; si++)
13598 print_dynamic_symbol (filedata, si, symtab, section,
13599 strtab, strtab_size);
252b5132
RH
13600
13601 free (symtab);
dda8d76d 13602 if (strtab != filedata->string_table)
252b5132
RH
13603 free (strtab);
13604 }
13605 }
13606 else if (do_syms)
13607 printf
13608 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13609
978c4450 13610 if (do_histogram && filedata->buckets != NULL)
252b5132 13611 {
2cf0635d
NC
13612 unsigned long * lengths;
13613 unsigned long * counts;
66543521
AM
13614 unsigned long hn;
13615 bfd_vma si;
13616 unsigned long maxlength = 0;
13617 unsigned long nzero_counts = 0;
13618 unsigned long nsyms = 0;
6bd6a03d 13619 char *visited;
252b5132 13620
d3a49aa8
AM
13621 printf (ngettext ("\nHistogram for bucket list length "
13622 "(total of %lu bucket):\n",
13623 "\nHistogram for bucket list length "
13624 "(total of %lu buckets):\n",
978c4450
AM
13625 (unsigned long) filedata->nbuckets),
13626 (unsigned long) filedata->nbuckets);
252b5132 13627
978c4450
AM
13628 lengths = (unsigned long *) calloc (filedata->nbuckets,
13629 sizeof (*lengths));
252b5132
RH
13630 if (lengths == NULL)
13631 {
8b73c356 13632 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13633 goto err_out;
252b5132 13634 }
978c4450
AM
13635 visited = xcmalloc (filedata->nchains, 1);
13636 memset (visited, 0, filedata->nchains);
8b73c356
NC
13637
13638 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13639 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13640 {
978c4450 13641 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13642 {
b34976b6 13643 ++nsyms;
252b5132 13644 if (maxlength < ++lengths[hn])
b34976b6 13645 ++maxlength;
978c4450 13646 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13647 {
13648 error (_("histogram chain is corrupt\n"));
13649 break;
13650 }
13651 visited[si] = 1;
252b5132
RH
13652 }
13653 }
6bd6a03d 13654 free (visited);
252b5132 13655
3f5e193b 13656 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13657 if (counts == NULL)
13658 {
b2e951ec 13659 free (lengths);
8b73c356 13660 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13661 goto err_out;
252b5132
RH
13662 }
13663
978c4450 13664 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13665 ++counts[lengths[hn]];
252b5132 13666
978c4450 13667 if (filedata->nbuckets > 0)
252b5132 13668 {
66543521
AM
13669 unsigned long i;
13670 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13671 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13672 for (i = 1; i <= maxlength; ++i)
103f02d3 13673 {
66543521
AM
13674 nzero_counts += counts[i] * i;
13675 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13676 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13677 (nzero_counts * 100.0) / nsyms);
13678 }
252b5132
RH
13679 }
13680
13681 free (counts);
13682 free (lengths);
13683 }
13684
978c4450
AM
13685 free (filedata->buckets);
13686 filedata->buckets = NULL;
13687 filedata->nbuckets = 0;
13688 free (filedata->chains);
13689 filedata->chains = NULL;
252b5132 13690
978c4450 13691 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13692 {
2cf0635d
NC
13693 unsigned long * lengths;
13694 unsigned long * counts;
fdc90cb4
JJ
13695 unsigned long hn;
13696 unsigned long maxlength = 0;
13697 unsigned long nzero_counts = 0;
13698 unsigned long nsyms = 0;
fdc90cb4 13699
f16a9783 13700 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13701 "(total of %lu bucket):\n",
f16a9783 13702 "\nHistogram for `%s' bucket list length "
d3a49aa8 13703 "(total of %lu buckets):\n",
978c4450
AM
13704 (unsigned long) filedata->ngnubuckets),
13705 GNU_HASH_SECTION_NAME (filedata),
13706 (unsigned long) filedata->ngnubuckets);
8b73c356 13707
978c4450
AM
13708 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13709 sizeof (*lengths));
fdc90cb4
JJ
13710 if (lengths == NULL)
13711 {
8b73c356 13712 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13713 goto err_out;
fdc90cb4
JJ
13714 }
13715
fdc90cb4
JJ
13716 printf (_(" Length Number %% of total Coverage\n"));
13717
978c4450
AM
13718 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13719 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13720 {
13721 bfd_vma off, length = 1;
13722
978c4450 13723 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13724 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13725 off < filedata->ngnuchains
13726 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13727 ++off)
fdc90cb4
JJ
13728 ++length;
13729 lengths[hn] = length;
13730 if (length > maxlength)
13731 maxlength = length;
13732 nsyms += length;
13733 }
13734
3f5e193b 13735 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13736 if (counts == NULL)
13737 {
b2e951ec 13738 free (lengths);
8b73c356 13739 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13740 goto err_out;
fdc90cb4
JJ
13741 }
13742
978c4450 13743 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13744 ++counts[lengths[hn]];
13745
978c4450 13746 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13747 {
13748 unsigned long j;
13749 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13750 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13751 for (j = 1; j <= maxlength; ++j)
13752 {
13753 nzero_counts += counts[j] * j;
13754 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13755 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13756 (nzero_counts * 100.0) / nsyms);
13757 }
13758 }
13759
13760 free (counts);
13761 free (lengths);
fdc90cb4 13762 }
978c4450
AM
13763 free (filedata->gnubuckets);
13764 filedata->gnubuckets = NULL;
13765 filedata->ngnubuckets = 0;
13766 free (filedata->gnuchains);
13767 filedata->gnuchains = NULL;
13768 filedata->ngnuchains = 0;
13769 free (filedata->mipsxlat);
13770 filedata->mipsxlat = NULL;
015dc7e1 13771 return true;
fd486f32
AM
13772
13773 err_out:
978c4450
AM
13774 free (filedata->gnubuckets);
13775 filedata->gnubuckets = NULL;
13776 filedata->ngnubuckets = 0;
13777 free (filedata->gnuchains);
13778 filedata->gnuchains = NULL;
13779 filedata->ngnuchains = 0;
13780 free (filedata->mipsxlat);
13781 filedata->mipsxlat = NULL;
13782 free (filedata->buckets);
13783 filedata->buckets = NULL;
13784 filedata->nbuckets = 0;
13785 free (filedata->chains);
13786 filedata->chains = NULL;
015dc7e1 13787 return false;
252b5132
RH
13788}
13789
015dc7e1 13790static bool
ca0e11aa 13791process_syminfo (Filedata * filedata)
252b5132 13792{
b4c96d0d 13793 unsigned int i;
252b5132 13794
978c4450 13795 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13796 || !do_dynamic)
13797 /* No syminfo, this is ok. */
015dc7e1 13798 return true;
252b5132
RH
13799
13800 /* There better should be a dynamic symbol section. */
978c4450 13801 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13802 return false;
252b5132 13803
ca0e11aa
NC
13804 if (filedata->is_separate)
13805 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13806 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13807 filedata->dynamic_syminfo_nent),
13808 filedata->file_name,
13809 filedata->dynamic_syminfo_offset,
13810 filedata->dynamic_syminfo_nent);
13811 else
d3a49aa8
AM
13812 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13813 "contains %d entry:\n",
13814 "\nDynamic info segment at offset 0x%lx "
13815 "contains %d entries:\n",
978c4450 13816 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13817 filedata->dynamic_syminfo_offset,
13818 filedata->dynamic_syminfo_nent);
252b5132
RH
13819
13820 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13821 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13822 {
978c4450 13823 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13824
31104126 13825 printf ("%4d: ", i);
978c4450 13826 if (i >= filedata->num_dynamic_syms)
4082ef84 13827 printf (_("<corrupt index>"));
84714f86
AM
13828 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13829 print_symbol (30, get_dynamic_name (filedata,
978c4450 13830 filedata->dynamic_symbols[i].st_name));
d79b3d50 13831 else
978c4450 13832 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13833 putchar (' ');
252b5132 13834
978c4450 13835 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13836 {
13837 case SYMINFO_BT_SELF:
13838 fputs ("SELF ", stdout);
13839 break;
13840 case SYMINFO_BT_PARENT:
13841 fputs ("PARENT ", stdout);
13842 break;
13843 default:
978c4450
AM
13844 if (filedata->dynamic_syminfo[i].si_boundto > 0
13845 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13846 && valid_dynamic_name (filedata,
978c4450 13847 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13848 {
84714f86 13849 print_symbol (10, get_dynamic_name (filedata,
978c4450 13850 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13851 putchar (' ' );
13852 }
252b5132 13853 else
978c4450 13854 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13855 break;
13856 }
13857
13858 if (flags & SYMINFO_FLG_DIRECT)
13859 printf (" DIRECT");
13860 if (flags & SYMINFO_FLG_PASSTHRU)
13861 printf (" PASSTHRU");
13862 if (flags & SYMINFO_FLG_COPY)
13863 printf (" COPY");
13864 if (flags & SYMINFO_FLG_LAZYLOAD)
13865 printf (" LAZYLOAD");
13866
13867 puts ("");
13868 }
13869
015dc7e1 13870 return true;
252b5132
RH
13871}
13872
75802ccb
CE
13873/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13874 is contained by the region START .. END. The types of ADDR, START
13875 and END should all be the same. Note both ADDR + NELEM and END
13876 point to just beyond the end of the regions that are being tested. */
13877#define IN_RANGE(START,END,ADDR,NELEM) \
13878 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13879
cf13d699
NC
13880/* Check to see if the given reloc needs to be handled in a target specific
13881 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13882 FALSE.
13883
13884 If called with reloc == NULL, then this is a signal that reloc processing
13885 for the current section has finished, and any saved state should be
13886 discarded. */
09c11c86 13887
015dc7e1 13888static bool
dda8d76d
NC
13889target_specific_reloc_handling (Filedata * filedata,
13890 Elf_Internal_Rela * reloc,
13891 unsigned char * start,
13892 unsigned char * end,
13893 Elf_Internal_Sym * symtab,
13894 unsigned long num_syms)
252b5132 13895{
f84ce13b
NC
13896 unsigned int reloc_type = 0;
13897 unsigned long sym_index = 0;
13898
13899 if (reloc)
13900 {
dda8d76d 13901 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13902 sym_index = get_reloc_symindex (reloc->r_info);
13903 }
252b5132 13904
dda8d76d 13905 switch (filedata->file_header.e_machine)
252b5132 13906 {
13761a11
NC
13907 case EM_MSP430:
13908 case EM_MSP430_OLD:
13909 {
13910 static Elf_Internal_Sym * saved_sym = NULL;
13911
f84ce13b
NC
13912 if (reloc == NULL)
13913 {
13914 saved_sym = NULL;
015dc7e1 13915 return true;
f84ce13b
NC
13916 }
13917
13761a11
NC
13918 switch (reloc_type)
13919 {
13920 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13921 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13922 if (uses_msp430x_relocs (filedata))
13761a11 13923 break;
1a0670f3 13924 /* Fall through. */
13761a11 13925 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13926 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13927 /* PR 21139. */
13928 if (sym_index >= num_syms)
13929 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13930 sym_index);
13931 else
13932 saved_sym = symtab + sym_index;
015dc7e1 13933 return true;
13761a11
NC
13934
13935 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13936 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13937 goto handle_sym_diff;
0b4362b0 13938
13761a11
NC
13939 case 5: /* R_MSP430_16_BYTE */
13940 case 9: /* R_MSP430_8 */
7d81bc93 13941 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13942 if (uses_msp430x_relocs (filedata))
13761a11
NC
13943 break;
13944 goto handle_sym_diff;
13945
13946 case 2: /* R_MSP430_ABS16 */
13947 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13948 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13949 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13950 break;
13951 goto handle_sym_diff;
0b4362b0 13952
13761a11
NC
13953 handle_sym_diff:
13954 if (saved_sym != NULL)
13955 {
13956 bfd_vma value;
5a805384 13957 unsigned int reloc_size = 0;
7d81bc93
JL
13958 int leb_ret = 0;
13959 switch (reloc_type)
13960 {
13961 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13962 reloc_size = 4;
13963 break;
13964 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13965 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13966 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13967 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13968 &reloc_size, &leb_ret);
7d81bc93
JL
13969 break;
13970 default:
13971 reloc_size = 2;
13972 break;
13973 }
13761a11 13974
5a805384 13975 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13976 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13977 "ULEB128 value\n"),
13978 (long) reloc->r_offset);
13979 else if (sym_index >= num_syms)
f84ce13b
NC
13980 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13981 sym_index);
03f7786e 13982 else
f84ce13b
NC
13983 {
13984 value = reloc->r_addend + (symtab[sym_index].st_value
13985 - saved_sym->st_value);
13986
b32e566b 13987 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13988 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13989 else
13990 /* PR 21137 */
13991 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13992 (long) reloc->r_offset);
f84ce13b 13993 }
13761a11
NC
13994
13995 saved_sym = NULL;
015dc7e1 13996 return true;
13761a11
NC
13997 }
13998 break;
13999
14000 default:
14001 if (saved_sym != NULL)
071436c6 14002 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14003 break;
14004 }
14005 break;
14006 }
14007
cf13d699
NC
14008 case EM_MN10300:
14009 case EM_CYGNUS_MN10300:
14010 {
14011 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14012
f84ce13b
NC
14013 if (reloc == NULL)
14014 {
14015 saved_sym = NULL;
015dc7e1 14016 return true;
f84ce13b
NC
14017 }
14018
cf13d699
NC
14019 switch (reloc_type)
14020 {
14021 case 34: /* R_MN10300_ALIGN */
015dc7e1 14022 return true;
cf13d699 14023 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14024 if (sym_index >= num_syms)
14025 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14026 sym_index);
14027 else
14028 saved_sym = symtab + sym_index;
015dc7e1 14029 return true;
f84ce13b 14030
cf13d699
NC
14031 case 1: /* R_MN10300_32 */
14032 case 2: /* R_MN10300_16 */
14033 if (saved_sym != NULL)
14034 {
03f7786e 14035 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 14036 bfd_vma value;
252b5132 14037
f84ce13b
NC
14038 if (sym_index >= num_syms)
14039 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14040 sym_index);
03f7786e 14041 else
f84ce13b
NC
14042 {
14043 value = reloc->r_addend + (symtab[sym_index].st_value
14044 - saved_sym->st_value);
14045
b32e566b 14046 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14047 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14048 else
14049 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14050 (long) reloc->r_offset);
f84ce13b 14051 }
252b5132 14052
cf13d699 14053 saved_sym = NULL;
015dc7e1 14054 return true;
cf13d699
NC
14055 }
14056 break;
14057 default:
14058 if (saved_sym != NULL)
071436c6 14059 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14060 break;
14061 }
14062 break;
14063 }
6ff71e76
NC
14064
14065 case EM_RL78:
14066 {
14067 static bfd_vma saved_sym1 = 0;
14068 static bfd_vma saved_sym2 = 0;
14069 static bfd_vma value;
14070
f84ce13b
NC
14071 if (reloc == NULL)
14072 {
14073 saved_sym1 = saved_sym2 = 0;
015dc7e1 14074 return true;
f84ce13b
NC
14075 }
14076
6ff71e76
NC
14077 switch (reloc_type)
14078 {
14079 case 0x80: /* R_RL78_SYM. */
14080 saved_sym1 = saved_sym2;
f84ce13b
NC
14081 if (sym_index >= num_syms)
14082 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14083 sym_index);
14084 else
14085 {
14086 saved_sym2 = symtab[sym_index].st_value;
14087 saved_sym2 += reloc->r_addend;
14088 }
015dc7e1 14089 return true;
6ff71e76
NC
14090
14091 case 0x83: /* R_RL78_OPsub. */
14092 value = saved_sym1 - saved_sym2;
14093 saved_sym2 = saved_sym1 = 0;
015dc7e1 14094 return true;
6ff71e76
NC
14095 break;
14096
14097 case 0x41: /* R_RL78_ABS32. */
b32e566b 14098 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14099 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14100 else
14101 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14102 (long) reloc->r_offset);
6ff71e76 14103 value = 0;
015dc7e1 14104 return true;
6ff71e76
NC
14105
14106 case 0x43: /* R_RL78_ABS16. */
b32e566b 14107 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14108 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14109 else
14110 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14111 (long) reloc->r_offset);
6ff71e76 14112 value = 0;
015dc7e1 14113 return true;
6ff71e76
NC
14114
14115 default:
14116 break;
14117 }
14118 break;
14119 }
252b5132
RH
14120 }
14121
015dc7e1 14122 return false;
252b5132
RH
14123}
14124
aca88567
NC
14125/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14126 DWARF debug sections. This is a target specific test. Note - we do not
14127 go through the whole including-target-headers-multiple-times route, (as
14128 we have already done with <elf/h8.h>) because this would become very
14129 messy and even then this function would have to contain target specific
14130 information (the names of the relocs instead of their numeric values).
14131 FIXME: This is not the correct way to solve this problem. The proper way
14132 is to have target specific reloc sizing and typing functions created by
14133 the reloc-macros.h header, in the same way that it already creates the
14134 reloc naming functions. */
14135
015dc7e1 14136static bool
dda8d76d 14137is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14138{
d347c9df 14139 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14140 switch (filedata->file_header.e_machine)
aca88567 14141 {
41e92641 14142 case EM_386:
22abe556 14143 case EM_IAMCU:
41e92641 14144 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14145 case EM_68K:
14146 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14147 case EM_860:
14148 return reloc_type == 1; /* R_860_32. */
14149 case EM_960:
14150 return reloc_type == 2; /* R_960_32. */
a06ea964 14151 case EM_AARCH64:
9282b95a
JW
14152 return (reloc_type == 258
14153 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14154 case EM_BPF:
14155 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14156 case EM_ADAPTEVA_EPIPHANY:
14157 return reloc_type == 3;
aca88567 14158 case EM_ALPHA:
137b6b5f 14159 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14160 case EM_ARC:
14161 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14162 case EM_ARC_COMPACT:
14163 case EM_ARC_COMPACT2:
14164 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14165 case EM_ARM:
14166 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14167 case EM_AVR_OLD:
aca88567
NC
14168 case EM_AVR:
14169 return reloc_type == 1;
14170 case EM_BLACKFIN:
14171 return reloc_type == 0x12; /* R_byte4_data. */
14172 case EM_CRIS:
14173 return reloc_type == 3; /* R_CRIS_32. */
14174 case EM_CR16:
14175 return reloc_type == 3; /* R_CR16_NUM32. */
14176 case EM_CRX:
14177 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14178 case EM_CSKY:
14179 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14180 case EM_CYGNUS_FRV:
14181 return reloc_type == 1;
41e92641
NC
14182 case EM_CYGNUS_D10V:
14183 case EM_D10V:
14184 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14185 case EM_CYGNUS_D30V:
14186 case EM_D30V:
14187 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14188 case EM_DLX:
14189 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14190 case EM_CYGNUS_FR30:
14191 case EM_FR30:
14192 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14193 case EM_FT32:
14194 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14195 case EM_H8S:
14196 case EM_H8_300:
14197 case EM_H8_300H:
14198 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14199 case EM_IA_64:
262cdac7
AM
14200 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14201 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14202 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14203 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14204 case EM_IP2K_OLD:
14205 case EM_IP2K:
14206 return reloc_type == 2; /* R_IP2K_32. */
14207 case EM_IQ2000:
14208 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14209 case EM_LATTICEMICO32:
14210 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14211 case EM_LOONGARCH:
14212 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14213 case EM_M32C_OLD:
aca88567
NC
14214 case EM_M32C:
14215 return reloc_type == 3; /* R_M32C_32. */
14216 case EM_M32R:
14217 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14218 case EM_68HC11:
14219 case EM_68HC12:
14220 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14221 case EM_S12Z:
2849d19f
JD
14222 return reloc_type == 7 || /* R_S12Z_EXT32 */
14223 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14224 case EM_MCORE:
14225 return reloc_type == 1; /* R_MCORE_ADDR32. */
14226 case EM_CYGNUS_MEP:
14227 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14228 case EM_METAG:
14229 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14230 case EM_MICROBLAZE:
14231 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14232 case EM_MIPS:
14233 return reloc_type == 2; /* R_MIPS_32. */
14234 case EM_MMIX:
14235 return reloc_type == 4; /* R_MMIX_32. */
14236 case EM_CYGNUS_MN10200:
14237 case EM_MN10200:
14238 return reloc_type == 1; /* R_MN10200_32. */
14239 case EM_CYGNUS_MN10300:
14240 case EM_MN10300:
14241 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14242 case EM_MOXIE:
14243 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14244 case EM_MSP430_OLD:
14245 case EM_MSP430:
13761a11 14246 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14247 case EM_MT:
14248 return reloc_type == 2; /* R_MT_32. */
35c08157 14249 case EM_NDS32:
81c5e376 14250 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14251 case EM_ALTERA_NIOS2:
36591ba1 14252 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14253 case EM_NIOS32:
14254 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14255 case EM_OR1K:
14256 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14257 case EM_PARISC:
9abca702 14258 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14259 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14260 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14261 case EM_PJ:
14262 case EM_PJ_OLD:
14263 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14264 case EM_PPC64:
14265 return reloc_type == 1; /* R_PPC64_ADDR32. */
14266 case EM_PPC:
14267 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14268 case EM_TI_PRU:
14269 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14270 case EM_RISCV:
14271 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14272 case EM_RL78:
14273 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14274 case EM_RX:
14275 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14276 case EM_S370:
14277 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14278 case EM_S390_OLD:
14279 case EM_S390:
14280 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14281 case EM_SCORE:
14282 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14283 case EM_SH:
14284 return reloc_type == 1; /* R_SH_DIR32. */
14285 case EM_SPARC32PLUS:
14286 case EM_SPARCV9:
14287 case EM_SPARC:
14288 return reloc_type == 3 /* R_SPARC_32. */
14289 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14290 case EM_SPU:
14291 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14292 case EM_TI_C6000:
14293 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14294 case EM_TILEGX:
14295 return reloc_type == 2; /* R_TILEGX_32. */
14296 case EM_TILEPRO:
14297 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14298 case EM_CYGNUS_V850:
14299 case EM_V850:
14300 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14301 case EM_V800:
14302 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14303 case EM_VAX:
14304 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14305 case EM_VISIUM:
14306 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14307 case EM_WEBASSEMBLY:
14308 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14309 case EM_X86_64:
8a9036a4 14310 case EM_L1OM:
7a9068fe 14311 case EM_K1OM:
aca88567 14312 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14313 case EM_XGATE:
14314 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14315 case EM_XSTORMY16:
14316 return reloc_type == 1; /* R_XSTROMY16_32. */
14317 case EM_XTENSA_OLD:
14318 case EM_XTENSA:
14319 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14320 case EM_Z80:
14321 return reloc_type == 6; /* R_Z80_32. */
aca88567 14322 default:
bee0ee85
NC
14323 {
14324 static unsigned int prev_warn = 0;
14325
14326 /* Avoid repeating the same warning multiple times. */
dda8d76d 14327 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14328 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14329 filedata->file_header.e_machine);
14330 prev_warn = filedata->file_header.e_machine;
015dc7e1 14331 return false;
bee0ee85 14332 }
aca88567
NC
14333 }
14334}
14335
14336/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14337 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14338
015dc7e1 14339static bool
dda8d76d 14340is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14341{
dda8d76d 14342 switch (filedata->file_header.e_machine)
d347c9df 14343 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14344 {
41e92641 14345 case EM_386:
22abe556 14346 case EM_IAMCU:
3e0873ac 14347 return reloc_type == 2; /* R_386_PC32. */
aca88567 14348 case EM_68K:
3e0873ac 14349 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14350 case EM_AARCH64:
14351 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14352 case EM_ADAPTEVA_EPIPHANY:
14353 return reloc_type == 6;
aca88567
NC
14354 case EM_ALPHA:
14355 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14356 case EM_ARC_COMPACT:
14357 case EM_ARC_COMPACT2:
14358 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14359 case EM_ARM:
3e0873ac 14360 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14361 case EM_AVR_OLD:
14362 case EM_AVR:
14363 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14364 case EM_LOONGARCH:
14365 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14366 case EM_MICROBLAZE:
14367 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14368 case EM_OR1K:
14369 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14370 case EM_PARISC:
85acf597 14371 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14372 case EM_PPC:
14373 return reloc_type == 26; /* R_PPC_REL32. */
14374 case EM_PPC64:
3e0873ac 14375 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14376 case EM_RISCV:
14377 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14378 case EM_S390_OLD:
14379 case EM_S390:
3e0873ac 14380 return reloc_type == 5; /* R_390_PC32. */
aca88567 14381 case EM_SH:
3e0873ac 14382 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14383 case EM_SPARC32PLUS:
14384 case EM_SPARCV9:
14385 case EM_SPARC:
3e0873ac 14386 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14387 case EM_SPU:
14388 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14389 case EM_TILEGX:
14390 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14391 case EM_TILEPRO:
14392 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14393 case EM_VISIUM:
14394 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14395 case EM_X86_64:
8a9036a4 14396 case EM_L1OM:
7a9068fe 14397 case EM_K1OM:
3e0873ac 14398 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14399 case EM_VAX:
14400 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14401 case EM_XTENSA_OLD:
14402 case EM_XTENSA:
14403 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14404 default:
14405 /* Do not abort or issue an error message here. Not all targets use
14406 pc-relative 32-bit relocs in their DWARF debug information and we
14407 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14408 more helpful warning message will be generated by apply_relocations
14409 anyway, so just return. */
015dc7e1 14410 return false;
aca88567
NC
14411 }
14412}
14413
14414/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14415 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14416
015dc7e1 14417static bool
dda8d76d 14418is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14419{
dda8d76d 14420 switch (filedata->file_header.e_machine)
aca88567 14421 {
a06ea964
NC
14422 case EM_AARCH64:
14423 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14424 case EM_ALPHA:
14425 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14426 case EM_IA_64:
262cdac7
AM
14427 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14428 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14429 case EM_LOONGARCH:
14430 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14431 case EM_PARISC:
14432 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14433 case EM_PPC64:
14434 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14435 case EM_RISCV:
14436 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14437 case EM_SPARC32PLUS:
14438 case EM_SPARCV9:
14439 case EM_SPARC:
714da62f
NC
14440 return reloc_type == 32 /* R_SPARC_64. */
14441 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14442 case EM_X86_64:
8a9036a4 14443 case EM_L1OM:
7a9068fe 14444 case EM_K1OM:
aca88567 14445 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14446 case EM_S390_OLD:
14447 case EM_S390:
aa137e4d
NC
14448 return reloc_type == 22; /* R_S390_64. */
14449 case EM_TILEGX:
14450 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14451 case EM_MIPS:
aa137e4d 14452 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14453 default:
015dc7e1 14454 return false;
aca88567
NC
14455 }
14456}
14457
85acf597
RH
14458/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14459 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14460
015dc7e1 14461static bool
dda8d76d 14462is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14463{
dda8d76d 14464 switch (filedata->file_header.e_machine)
85acf597 14465 {
a06ea964
NC
14466 case EM_AARCH64:
14467 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14468 case EM_ALPHA:
aa137e4d 14469 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14470 case EM_IA_64:
262cdac7
AM
14471 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14472 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14473 case EM_PARISC:
aa137e4d 14474 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14475 case EM_PPC64:
aa137e4d 14476 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14477 case EM_SPARC32PLUS:
14478 case EM_SPARCV9:
14479 case EM_SPARC:
aa137e4d 14480 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14481 case EM_X86_64:
8a9036a4 14482 case EM_L1OM:
7a9068fe 14483 case EM_K1OM:
aa137e4d 14484 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14485 case EM_S390_OLD:
14486 case EM_S390:
aa137e4d
NC
14487 return reloc_type == 23; /* R_S390_PC64. */
14488 case EM_TILEGX:
14489 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14490 default:
015dc7e1 14491 return false;
85acf597
RH
14492 }
14493}
14494
4dc3c23d
AM
14495/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14496 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14497
015dc7e1 14498static bool
dda8d76d 14499is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14500{
dda8d76d 14501 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14502 {
14503 case EM_CYGNUS_MN10200:
14504 case EM_MN10200:
14505 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14506 case EM_FT32:
14507 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14508 case EM_Z80:
14509 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14510 default:
015dc7e1 14511 return false;
4dc3c23d
AM
14512 }
14513}
14514
aca88567
NC
14515/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14516 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14517
015dc7e1 14518static bool
dda8d76d 14519is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14520{
d347c9df 14521 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14522 switch (filedata->file_header.e_machine)
4b78141a 14523 {
886a2506
NC
14524 case EM_ARC:
14525 case EM_ARC_COMPACT:
14526 case EM_ARC_COMPACT2:
14527 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14528 case EM_ADAPTEVA_EPIPHANY:
14529 return reloc_type == 5;
aca88567
NC
14530 case EM_AVR_OLD:
14531 case EM_AVR:
14532 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14533 case EM_CYGNUS_D10V:
14534 case EM_D10V:
14535 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14536 case EM_FT32:
14537 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14538 case EM_H8S:
14539 case EM_H8_300:
14540 case EM_H8_300H:
aca88567
NC
14541 return reloc_type == R_H8_DIR16;
14542 case EM_IP2K_OLD:
14543 case EM_IP2K:
14544 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14545 case EM_M32C_OLD:
f4236fe4
DD
14546 case EM_M32C:
14547 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14548 case EM_CYGNUS_MN10200:
14549 case EM_MN10200:
14550 return reloc_type == 2; /* R_MN10200_16. */
14551 case EM_CYGNUS_MN10300:
14552 case EM_MN10300:
14553 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14554 case EM_MSP430:
dda8d76d 14555 if (uses_msp430x_relocs (filedata))
13761a11 14556 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14557 /* Fall through. */
78c8d46c 14558 case EM_MSP430_OLD:
aca88567 14559 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14560 case EM_NDS32:
81c5e376 14561 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14562 case EM_ALTERA_NIOS2:
36591ba1 14563 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14564 case EM_NIOS32:
14565 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14566 case EM_OR1K:
14567 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14568 case EM_RISCV:
14569 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14570 case EM_TI_PRU:
14571 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14572 case EM_TI_C6000:
14573 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14574 case EM_VISIUM:
14575 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14576 case EM_XGATE:
14577 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14578 case EM_Z80:
14579 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14580 default:
015dc7e1 14581 return false;
4b78141a
NC
14582 }
14583}
14584
39e07931
AS
14585/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14586 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14587
015dc7e1 14588static bool
39e07931
AS
14589is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14590{
14591 switch (filedata->file_header.e_machine)
14592 {
14593 case EM_RISCV:
14594 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14595 case EM_Z80:
14596 return reloc_type == 1; /* R_Z80_8. */
39e07931 14597 default:
015dc7e1 14598 return false;
39e07931
AS
14599 }
14600}
14601
14602/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14603 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14604
015dc7e1 14605static bool
39e07931
AS
14606is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14607{
14608 switch (filedata->file_header.e_machine)
14609 {
14610 case EM_RISCV:
14611 return reloc_type == 53; /* R_RISCV_SET6. */
14612 default:
015dc7e1 14613 return false;
39e07931
AS
14614 }
14615}
14616
03336641
JW
14617/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14618 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14619
015dc7e1 14620static bool
03336641
JW
14621is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14622{
14623 /* Please keep this table alpha-sorted for ease of visual lookup. */
14624 switch (filedata->file_header.e_machine)
14625 {
14626 case EM_RISCV:
14627 return reloc_type == 35; /* R_RISCV_ADD32. */
14628 default:
015dc7e1 14629 return false;
03336641
JW
14630 }
14631}
14632
14633/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14634 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14635
015dc7e1 14636static bool
03336641
JW
14637is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14638{
14639 /* Please keep this table alpha-sorted for ease of visual lookup. */
14640 switch (filedata->file_header.e_machine)
14641 {
14642 case EM_RISCV:
14643 return reloc_type == 39; /* R_RISCV_SUB32. */
14644 default:
015dc7e1 14645 return false;
03336641
JW
14646 }
14647}
14648
14649/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14650 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14651
015dc7e1 14652static bool
03336641
JW
14653is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14654{
14655 /* Please keep this table alpha-sorted for ease of visual lookup. */
14656 switch (filedata->file_header.e_machine)
14657 {
14658 case EM_RISCV:
14659 return reloc_type == 36; /* R_RISCV_ADD64. */
14660 default:
015dc7e1 14661 return false;
03336641
JW
14662 }
14663}
14664
14665/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14666 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14667
015dc7e1 14668static bool
03336641
JW
14669is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14670{
14671 /* Please keep this table alpha-sorted for ease of visual lookup. */
14672 switch (filedata->file_header.e_machine)
14673 {
14674 case EM_RISCV:
14675 return reloc_type == 40; /* R_RISCV_SUB64. */
14676 default:
015dc7e1 14677 return false;
03336641
JW
14678 }
14679}
14680
14681/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14682 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14683
015dc7e1 14684static bool
03336641
JW
14685is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14686{
14687 /* Please keep this table alpha-sorted for ease of visual lookup. */
14688 switch (filedata->file_header.e_machine)
14689 {
14690 case EM_RISCV:
14691 return reloc_type == 34; /* R_RISCV_ADD16. */
14692 default:
015dc7e1 14693 return false;
03336641
JW
14694 }
14695}
14696
14697/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14698 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14699
015dc7e1 14700static bool
03336641
JW
14701is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14702{
14703 /* Please keep this table alpha-sorted for ease of visual lookup. */
14704 switch (filedata->file_header.e_machine)
14705 {
14706 case EM_RISCV:
14707 return reloc_type == 38; /* R_RISCV_SUB16. */
14708 default:
015dc7e1 14709 return false;
03336641
JW
14710 }
14711}
14712
14713/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14714 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14715
015dc7e1 14716static bool
03336641
JW
14717is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14718{
14719 /* Please keep this table alpha-sorted for ease of visual lookup. */
14720 switch (filedata->file_header.e_machine)
14721 {
14722 case EM_RISCV:
14723 return reloc_type == 33; /* R_RISCV_ADD8. */
14724 default:
015dc7e1 14725 return false;
03336641
JW
14726 }
14727}
14728
14729/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14730 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14731
015dc7e1 14732static bool
03336641
JW
14733is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14734{
14735 /* Please keep this table alpha-sorted for ease of visual lookup. */
14736 switch (filedata->file_header.e_machine)
14737 {
14738 case EM_RISCV:
14739 return reloc_type == 37; /* R_RISCV_SUB8. */
14740 default:
015dc7e1 14741 return false;
03336641
JW
14742 }
14743}
14744
39e07931
AS
14745/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14746 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14747
015dc7e1 14748static bool
39e07931
AS
14749is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14750{
14751 switch (filedata->file_header.e_machine)
14752 {
14753 case EM_RISCV:
14754 return reloc_type == 52; /* R_RISCV_SUB6. */
14755 default:
015dc7e1 14756 return false;
39e07931
AS
14757 }
14758}
14759
2a7b2e88
JK
14760/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14761 relocation entries (possibly formerly used for SHT_GROUP sections). */
14762
015dc7e1 14763static bool
dda8d76d 14764is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14765{
dda8d76d 14766 switch (filedata->file_header.e_machine)
2a7b2e88 14767 {
cb8f3167 14768 case EM_386: /* R_386_NONE. */
d347c9df 14769 case EM_68K: /* R_68K_NONE. */
cfb8c092 14770 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14771 case EM_ALPHA: /* R_ALPHA_NONE. */
14772 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14773 case EM_ARC: /* R_ARC_NONE. */
886a2506 14774 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14775 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14776 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14777 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14778 case EM_FT32: /* R_FT32_NONE. */
14779 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14780 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14781 case EM_L1OM: /* R_X86_64_NONE. */
14782 case EM_M32R: /* R_M32R_NONE. */
14783 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14784 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14785 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14786 case EM_NIOS32: /* R_NIOS_NONE. */
14787 case EM_OR1K: /* R_OR1K_NONE. */
14788 case EM_PARISC: /* R_PARISC_NONE. */
14789 case EM_PPC64: /* R_PPC64_NONE. */
14790 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14791 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14792 case EM_S390: /* R_390_NONE. */
14793 case EM_S390_OLD:
14794 case EM_SH: /* R_SH_NONE. */
14795 case EM_SPARC32PLUS:
14796 case EM_SPARC: /* R_SPARC_NONE. */
14797 case EM_SPARCV9:
aa137e4d
NC
14798 case EM_TILEGX: /* R_TILEGX_NONE. */
14799 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14800 case EM_TI_C6000:/* R_C6000_NONE. */
14801 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14802 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14803 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14804 return reloc_type == 0;
d347c9df 14805
a06ea964
NC
14806 case EM_AARCH64:
14807 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14808 case EM_AVR_OLD:
14809 case EM_AVR:
14810 return (reloc_type == 0 /* R_AVR_NONE. */
14811 || reloc_type == 30 /* R_AVR_DIFF8. */
14812 || reloc_type == 31 /* R_AVR_DIFF16. */
14813 || reloc_type == 32 /* R_AVR_DIFF32. */);
14814 case EM_METAG:
14815 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14816 case EM_NDS32:
81c5e376
AM
14817 return (reloc_type == 0 /* R_NDS32_NONE. */
14818 || reloc_type == 205 /* R_NDS32_DIFF8. */
14819 || reloc_type == 206 /* R_NDS32_DIFF16. */
14820 || reloc_type == 207 /* R_NDS32_DIFF32. */
14821 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14822 case EM_TI_PRU:
14823 return (reloc_type == 0 /* R_PRU_NONE. */
14824 || reloc_type == 65 /* R_PRU_DIFF8. */
14825 || reloc_type == 66 /* R_PRU_DIFF16. */
14826 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14827 case EM_XTENSA_OLD:
14828 case EM_XTENSA:
4dc3c23d
AM
14829 return (reloc_type == 0 /* R_XTENSA_NONE. */
14830 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14831 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14832 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14833 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14834 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14835 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14836 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14837 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14838 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14839 }
015dc7e1 14840 return false;
2a7b2e88
JK
14841}
14842
d1c4b12b
NC
14843/* Returns TRUE if there is a relocation against
14844 section NAME at OFFSET bytes. */
14845
015dc7e1 14846bool
d1c4b12b
NC
14847reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14848{
14849 Elf_Internal_Rela * relocs;
14850 Elf_Internal_Rela * rp;
14851
14852 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14853 return false;
d1c4b12b
NC
14854
14855 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14856
14857 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14858 if (rp->r_offset == offset)
015dc7e1 14859 return true;
d1c4b12b 14860
015dc7e1 14861 return false;
d1c4b12b
NC
14862}
14863
cf13d699 14864/* Apply relocations to a section.
32ec8896
NC
14865 Returns TRUE upon success, FALSE otherwise.
14866 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14867 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14868 will be set to the number of relocs loaded.
14869
cf13d699 14870 Note: So far support has been added only for those relocations
32ec8896
NC
14871 which can be found in debug sections. FIXME: Add support for
14872 more relocations ? */
1b315056 14873
015dc7e1 14874static bool
dda8d76d 14875apply_relocations (Filedata * filedata,
d1c4b12b
NC
14876 const Elf_Internal_Shdr * section,
14877 unsigned char * start,
14878 bfd_size_type size,
1449284b 14879 void ** relocs_return,
d1c4b12b 14880 unsigned long * num_relocs_return)
1b315056 14881{
cf13d699 14882 Elf_Internal_Shdr * relsec;
0d2a7a93 14883 unsigned char * end = start + size;
cb8f3167 14884
d1c4b12b
NC
14885 if (relocs_return != NULL)
14886 {
14887 * (Elf_Internal_Rela **) relocs_return = NULL;
14888 * num_relocs_return = 0;
14889 }
14890
dda8d76d 14891 if (filedata->file_header.e_type != ET_REL)
32ec8896 14892 /* No relocs to apply. */
015dc7e1 14893 return true;
1b315056 14894
cf13d699 14895 /* Find the reloc section associated with the section. */
dda8d76d
NC
14896 for (relsec = filedata->section_headers;
14897 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14898 ++relsec)
252b5132 14899 {
015dc7e1 14900 bool is_rela;
41e92641 14901 unsigned long num_relocs;
2cf0635d
NC
14902 Elf_Internal_Rela * relocs;
14903 Elf_Internal_Rela * rp;
14904 Elf_Internal_Shdr * symsec;
14905 Elf_Internal_Sym * symtab;
ba5cdace 14906 unsigned long num_syms;
2cf0635d 14907 Elf_Internal_Sym * sym;
252b5132 14908
41e92641 14909 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14910 || relsec->sh_info >= filedata->file_header.e_shnum
14911 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14912 || relsec->sh_size == 0
dda8d76d 14913 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14914 continue;
428409d5 14915
a788aedd
AM
14916 symsec = filedata->section_headers + relsec->sh_link;
14917 if (symsec->sh_type != SHT_SYMTAB
14918 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14919 return false;
a788aedd 14920
41e92641
NC
14921 is_rela = relsec->sh_type == SHT_RELA;
14922
14923 if (is_rela)
14924 {
dda8d76d 14925 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14926 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14927 return false;
41e92641
NC
14928 }
14929 else
14930 {
dda8d76d 14931 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14932 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14933 return false;
41e92641
NC
14934 }
14935
14936 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14937 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14938 is_rela = false;
428409d5 14939
4de91c10 14940 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14941
41e92641 14942 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14943 {
015dc7e1
AM
14944 bfd_vma addend;
14945 unsigned int reloc_type;
14946 unsigned int reloc_size;
14947 bool reloc_inplace = false;
14948 bool reloc_subtract = false;
14949 unsigned char *rloc;
14950 unsigned long sym_index;
4b78141a 14951
dda8d76d 14952 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14953
dda8d76d 14954 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14955 continue;
dda8d76d 14956 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14957 continue;
dda8d76d
NC
14958 else if (is_32bit_abs_reloc (filedata, reloc_type)
14959 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14960 reloc_size = 4;
dda8d76d
NC
14961 else if (is_64bit_abs_reloc (filedata, reloc_type)
14962 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14963 reloc_size = 8;
dda8d76d 14964 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14965 reloc_size = 3;
dda8d76d 14966 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14967 reloc_size = 2;
39e07931
AS
14968 else if (is_8bit_abs_reloc (filedata, reloc_type)
14969 || is_6bit_abs_reloc (filedata, reloc_type))
14970 reloc_size = 1;
03336641
JW
14971 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14972 reloc_type))
14973 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14974 {
14975 reloc_size = 4;
015dc7e1 14976 reloc_inplace = true;
03336641
JW
14977 }
14978 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14979 reloc_type))
14980 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14981 {
14982 reloc_size = 8;
015dc7e1 14983 reloc_inplace = true;
03336641
JW
14984 }
14985 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14986 reloc_type))
14987 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14988 {
14989 reloc_size = 2;
015dc7e1 14990 reloc_inplace = true;
03336641
JW
14991 }
14992 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14993 reloc_type))
14994 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14995 {
14996 reloc_size = 1;
015dc7e1 14997 reloc_inplace = true;
03336641 14998 }
39e07931
AS
14999 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15000 reloc_type)))
15001 {
15002 reloc_size = 1;
015dc7e1 15003 reloc_inplace = true;
39e07931 15004 }
aca88567 15005 else
4b78141a 15006 {
bee0ee85 15007 static unsigned int prev_reloc = 0;
dda8d76d 15008
bee0ee85
NC
15009 if (reloc_type != prev_reloc)
15010 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15011 reloc_type, printable_section_name (filedata, section));
bee0ee85 15012 prev_reloc = reloc_type;
4b78141a
NC
15013 continue;
15014 }
103f02d3 15015
91d6fa6a 15016 rloc = start + rp->r_offset;
75802ccb 15017 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15018 {
15019 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15020 (unsigned long) rp->r_offset,
dda8d76d 15021 printable_section_name (filedata, section));
700dd8b7
L
15022 continue;
15023 }
103f02d3 15024
ba5cdace
NC
15025 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15026 if (sym_index >= num_syms)
15027 {
15028 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15029 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15030 continue;
15031 }
15032 sym = symtab + sym_index;
41e92641
NC
15033
15034 /* If the reloc has a symbol associated with it,
55f25fc3
L
15035 make sure that it is of an appropriate type.
15036
15037 Relocations against symbols without type can happen.
15038 Gcc -feliminate-dwarf2-dups may generate symbols
15039 without type for debug info.
15040
15041 Icc generates relocations against function symbols
15042 instead of local labels.
15043
15044 Relocations against object symbols can happen, eg when
15045 referencing a global array. For an example of this see
15046 the _clz.o binary in libgcc.a. */
aca88567 15047 if (sym != symtab
b8871f35 15048 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15049 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15050 {
d3a49aa8 15051 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15052 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15053 printable_section_name (filedata, relsec),
d3a49aa8 15054 (long int)(rp - relocs));
aca88567 15055 continue;
5b18a4bc 15056 }
252b5132 15057
4dc3c23d
AM
15058 addend = 0;
15059 if (is_rela)
15060 addend += rp->r_addend;
c47320c3
AM
15061 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15062 partial_inplace. */
4dc3c23d 15063 if (!is_rela
dda8d76d 15064 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15065 && reloc_type == 1)
dda8d76d
NC
15066 || ((filedata->file_header.e_machine == EM_PJ
15067 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15068 && reloc_type == 1)
dda8d76d
NC
15069 || ((filedata->file_header.e_machine == EM_D30V
15070 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15071 && reloc_type == 12)
15072 || reloc_inplace)
39e07931
AS
15073 {
15074 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15075 addend += byte_get (rloc, reloc_size) & 0x3f;
15076 else
15077 addend += byte_get (rloc, reloc_size);
15078 }
cb8f3167 15079
dda8d76d
NC
15080 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15081 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15082 {
15083 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15084 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15085 addend -= 8;
91d6fa6a 15086 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15087 reloc_size);
15088 }
39e07931
AS
15089 else if (is_6bit_abs_reloc (filedata, reloc_type)
15090 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15091 {
15092 if (reloc_subtract)
15093 addend -= sym->st_value;
15094 else
15095 addend += sym->st_value;
15096 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15097 byte_put (rloc, addend, reloc_size);
15098 }
03336641
JW
15099 else if (reloc_subtract)
15100 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15101 else
91d6fa6a 15102 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15103 }
252b5132 15104
5b18a4bc 15105 free (symtab);
f84ce13b
NC
15106 /* Let the target specific reloc processing code know that
15107 we have finished with these relocs. */
dda8d76d 15108 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15109
15110 if (relocs_return)
15111 {
15112 * (Elf_Internal_Rela **) relocs_return = relocs;
15113 * num_relocs_return = num_relocs;
15114 }
15115 else
15116 free (relocs);
15117
5b18a4bc
NC
15118 break;
15119 }
32ec8896 15120
015dc7e1 15121 return true;
5b18a4bc 15122}
103f02d3 15123
cf13d699 15124#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15125static bool
dda8d76d 15126disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15127{
dda8d76d 15128 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15129
74e1a04b 15130 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15131
015dc7e1 15132 return true;
cf13d699
NC
15133}
15134#endif
15135
15136/* Reads in the contents of SECTION from FILE, returning a pointer
15137 to a malloc'ed buffer or NULL if something went wrong. */
15138
15139static char *
dda8d76d 15140get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15141{
dda8d76d 15142 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15143
15144 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15145 {
c6b78c96 15146 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15147 printable_section_name (filedata, section));
cf13d699
NC
15148 return NULL;
15149 }
15150
dda8d76d 15151 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15152 _("section contents"));
cf13d699
NC
15153}
15154
0e602686
NC
15155/* Uncompresses a section that was compressed using zlib, in place. */
15156
015dc7e1 15157static bool
dda8d76d
NC
15158uncompress_section_contents (unsigned char ** buffer,
15159 dwarf_size_type uncompressed_size,
15160 dwarf_size_type * size)
0e602686
NC
15161{
15162 dwarf_size_type compressed_size = *size;
15163 unsigned char * compressed_buffer = *buffer;
15164 unsigned char * uncompressed_buffer;
15165 z_stream strm;
15166 int rc;
15167
15168 /* It is possible the section consists of several compressed
15169 buffers concatenated together, so we uncompress in a loop. */
15170 /* PR 18313: The state field in the z_stream structure is supposed
15171 to be invisible to the user (ie us), but some compilers will
15172 still complain about it being used without initialisation. So
15173 we first zero the entire z_stream structure and then set the fields
15174 that we need. */
15175 memset (& strm, 0, sizeof strm);
15176 strm.avail_in = compressed_size;
15177 strm.next_in = (Bytef *) compressed_buffer;
15178 strm.avail_out = uncompressed_size;
15179 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15180
15181 rc = inflateInit (& strm);
15182 while (strm.avail_in > 0)
15183 {
15184 if (rc != Z_OK)
3624a6c1 15185 break;
0e602686
NC
15186 strm.next_out = ((Bytef *) uncompressed_buffer
15187 + (uncompressed_size - strm.avail_out));
15188 rc = inflate (&strm, Z_FINISH);
15189 if (rc != Z_STREAM_END)
3624a6c1 15190 break;
0e602686
NC
15191 rc = inflateReset (& strm);
15192 }
ad92f33d
AM
15193 if (inflateEnd (& strm) != Z_OK
15194 || rc != Z_OK
0e602686
NC
15195 || strm.avail_out != 0)
15196 goto fail;
15197
15198 *buffer = uncompressed_buffer;
15199 *size = uncompressed_size;
015dc7e1 15200 return true;
0e602686
NC
15201
15202 fail:
15203 free (uncompressed_buffer);
15204 /* Indicate decompression failure. */
15205 *buffer = NULL;
015dc7e1 15206 return false;
0e602686 15207}
dd24e3da 15208
015dc7e1 15209static bool
dda8d76d 15210dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15211{
015dc7e1
AM
15212 Elf_Internal_Shdr *relsec;
15213 bfd_size_type num_bytes;
15214 unsigned char *data;
15215 unsigned char *end;
15216 unsigned char *real_start;
15217 unsigned char *start;
15218 bool some_strings_shown;
cf13d699 15219
dda8d76d 15220 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15221 if (start == NULL)
c6b78c96 15222 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15223 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15224
0e602686 15225 num_bytes = section->sh_size;
cf13d699 15226
835f2fae
NC
15227 if (filedata->is_separate)
15228 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15229 printable_section_name (filedata, section),
15230 filedata->file_name);
15231 else
15232 printf (_("\nString dump of section '%s':\n"),
15233 printable_section_name (filedata, section));
cf13d699 15234
0e602686
NC
15235 if (decompress_dumps)
15236 {
15237 dwarf_size_type new_size = num_bytes;
15238 dwarf_size_type uncompressed_size = 0;
15239
15240 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15241 {
15242 Elf_Internal_Chdr chdr;
15243 unsigned int compression_header_size
ebdf1ebf
NC
15244 = get_compression_header (& chdr, (unsigned char *) start,
15245 num_bytes);
5844b465
NC
15246 if (compression_header_size == 0)
15247 /* An error message will have already been generated
15248 by get_compression_header. */
15249 goto error_out;
0e602686 15250
813dabb9 15251 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15252 {
813dabb9 15253 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15254 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15255 goto error_out;
813dabb9 15256 }
813dabb9
L
15257 uncompressed_size = chdr.ch_size;
15258 start += compression_header_size;
15259 new_size -= compression_header_size;
0e602686
NC
15260 }
15261 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15262 {
15263 /* Read the zlib header. In this case, it should be "ZLIB"
15264 followed by the uncompressed section size, 8 bytes in
15265 big-endian order. */
15266 uncompressed_size = start[4]; uncompressed_size <<= 8;
15267 uncompressed_size += start[5]; uncompressed_size <<= 8;
15268 uncompressed_size += start[6]; uncompressed_size <<= 8;
15269 uncompressed_size += start[7]; uncompressed_size <<= 8;
15270 uncompressed_size += start[8]; uncompressed_size <<= 8;
15271 uncompressed_size += start[9]; uncompressed_size <<= 8;
15272 uncompressed_size += start[10]; uncompressed_size <<= 8;
15273 uncompressed_size += start[11];
15274 start += 12;
15275 new_size -= 12;
15276 }
15277
1835f746
NC
15278 if (uncompressed_size)
15279 {
15280 if (uncompress_section_contents (& start,
15281 uncompressed_size, & new_size))
15282 num_bytes = new_size;
15283 else
15284 {
15285 error (_("Unable to decompress section %s\n"),
dda8d76d 15286 printable_section_name (filedata, section));
f761cb13 15287 goto error_out;
1835f746
NC
15288 }
15289 }
bc303e5d
NC
15290 else
15291 start = real_start;
0e602686 15292 }
fd8008d8 15293
cf13d699
NC
15294 /* If the section being dumped has relocations against it the user might
15295 be expecting these relocations to have been applied. Check for this
15296 case and issue a warning message in order to avoid confusion.
15297 FIXME: Maybe we ought to have an option that dumps a section with
15298 relocs applied ? */
dda8d76d
NC
15299 for (relsec = filedata->section_headers;
15300 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15301 ++relsec)
15302 {
15303 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15304 || relsec->sh_info >= filedata->file_header.e_shnum
15305 || filedata->section_headers + relsec->sh_info != section
cf13d699 15306 || relsec->sh_size == 0
dda8d76d 15307 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15308 continue;
15309
15310 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15311 break;
15312 }
15313
cf13d699
NC
15314 data = start;
15315 end = start + num_bytes;
015dc7e1 15316 some_strings_shown = false;
cf13d699 15317
ba3265d0
NC
15318#ifdef HAVE_MBSTATE_T
15319 mbstate_t state;
15320 /* Initialise the multibyte conversion state. */
15321 memset (& state, 0, sizeof (state));
15322#endif
15323
015dc7e1 15324 bool continuing = false;
ba3265d0 15325
cf13d699
NC
15326 while (data < end)
15327 {
15328 while (!ISPRINT (* data))
15329 if (++ data >= end)
15330 break;
15331
15332 if (data < end)
15333 {
071436c6
NC
15334 size_t maxlen = end - data;
15335
ba3265d0
NC
15336 if (continuing)
15337 {
15338 printf (" ");
015dc7e1 15339 continuing = false;
ba3265d0
NC
15340 }
15341 else
15342 {
d1ce973e 15343 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15344 }
15345
4082ef84
NC
15346 if (maxlen > 0)
15347 {
f3da8a96 15348 char c = 0;
ba3265d0
NC
15349
15350 while (maxlen)
15351 {
15352 c = *data++;
15353
15354 if (c == 0)
15355 break;
15356
15357 /* PR 25543: Treat new-lines as string-ending characters. */
15358 if (c == '\n')
15359 {
15360 printf ("\\n\n");
15361 if (*data != 0)
015dc7e1 15362 continuing = true;
ba3265d0
NC
15363 break;
15364 }
15365
15366 /* Do not print control characters directly as they can affect terminal
15367 settings. Such characters usually appear in the names generated
15368 by the assembler for local labels. */
15369 if (ISCNTRL (c))
15370 {
15371 printf ("^%c", c + 0x40);
15372 }
15373 else if (ISPRINT (c))
15374 {
15375 putchar (c);
15376 }
15377 else
15378 {
15379 size_t n;
15380#ifdef HAVE_MBSTATE_T
15381 wchar_t w;
15382#endif
15383 /* Let printf do the hard work of displaying multibyte characters. */
15384 printf ("%.1s", data - 1);
15385#ifdef HAVE_MBSTATE_T
15386 /* Try to find out how many bytes made up the character that was
15387 just printed. Advance the symbol pointer past the bytes that
15388 were displayed. */
15389 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15390#else
15391 n = 1;
15392#endif
15393 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15394 data += (n - 1);
15395 }
15396 }
15397
15398 if (c != '\n')
15399 putchar ('\n');
4082ef84
NC
15400 }
15401 else
15402 {
15403 printf (_("<corrupt>\n"));
15404 data = end;
15405 }
015dc7e1 15406 some_strings_shown = true;
cf13d699
NC
15407 }
15408 }
15409
15410 if (! some_strings_shown)
15411 printf (_(" No strings found in this section."));
15412
0e602686 15413 free (real_start);
cf13d699
NC
15414
15415 putchar ('\n');
015dc7e1 15416 return true;
f761cb13
AM
15417
15418error_out:
15419 free (real_start);
015dc7e1 15420 return false;
cf13d699
NC
15421}
15422
015dc7e1
AM
15423static bool
15424dump_section_as_bytes (Elf_Internal_Shdr *section,
15425 Filedata *filedata,
15426 bool relocate)
cf13d699
NC
15427{
15428 Elf_Internal_Shdr * relsec;
0e602686
NC
15429 bfd_size_type bytes;
15430 bfd_size_type section_size;
15431 bfd_vma addr;
15432 unsigned char * data;
15433 unsigned char * real_start;
15434 unsigned char * start;
15435
dda8d76d 15436 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15437 if (start == NULL)
c6b78c96 15438 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15439 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15440
0e602686 15441 section_size = section->sh_size;
cf13d699 15442
835f2fae
NC
15443 if (filedata->is_separate)
15444 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15445 printable_section_name (filedata, section),
15446 filedata->file_name);
15447 else
15448 printf (_("\nHex dump of section '%s':\n"),
15449 printable_section_name (filedata, section));
cf13d699 15450
0e602686
NC
15451 if (decompress_dumps)
15452 {
15453 dwarf_size_type new_size = section_size;
15454 dwarf_size_type uncompressed_size = 0;
15455
15456 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15457 {
15458 Elf_Internal_Chdr chdr;
15459 unsigned int compression_header_size
ebdf1ebf 15460 = get_compression_header (& chdr, start, section_size);
0e602686 15461
5844b465
NC
15462 if (compression_header_size == 0)
15463 /* An error message will have already been generated
15464 by get_compression_header. */
15465 goto error_out;
15466
813dabb9 15467 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15468 {
813dabb9 15469 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15470 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15471 goto error_out;
0e602686 15472 }
813dabb9
L
15473 uncompressed_size = chdr.ch_size;
15474 start += compression_header_size;
15475 new_size -= compression_header_size;
0e602686
NC
15476 }
15477 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15478 {
15479 /* Read the zlib header. In this case, it should be "ZLIB"
15480 followed by the uncompressed section size, 8 bytes in
15481 big-endian order. */
15482 uncompressed_size = start[4]; uncompressed_size <<= 8;
15483 uncompressed_size += start[5]; uncompressed_size <<= 8;
15484 uncompressed_size += start[6]; uncompressed_size <<= 8;
15485 uncompressed_size += start[7]; uncompressed_size <<= 8;
15486 uncompressed_size += start[8]; uncompressed_size <<= 8;
15487 uncompressed_size += start[9]; uncompressed_size <<= 8;
15488 uncompressed_size += start[10]; uncompressed_size <<= 8;
15489 uncompressed_size += start[11];
15490 start += 12;
15491 new_size -= 12;
15492 }
15493
f055032e
NC
15494 if (uncompressed_size)
15495 {
15496 if (uncompress_section_contents (& start, uncompressed_size,
15497 & new_size))
bc303e5d
NC
15498 {
15499 section_size = new_size;
15500 }
f055032e
NC
15501 else
15502 {
15503 error (_("Unable to decompress section %s\n"),
dda8d76d 15504 printable_section_name (filedata, section));
bc303e5d 15505 /* FIXME: Print the section anyway ? */
f761cb13 15506 goto error_out;
f055032e
NC
15507 }
15508 }
bc303e5d
NC
15509 else
15510 start = real_start;
0e602686 15511 }
14ae95f2 15512
cf13d699
NC
15513 if (relocate)
15514 {
dda8d76d 15515 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15516 goto error_out;
cf13d699
NC
15517 }
15518 else
15519 {
15520 /* If the section being dumped has relocations against it the user might
15521 be expecting these relocations to have been applied. Check for this
15522 case and issue a warning message in order to avoid confusion.
15523 FIXME: Maybe we ought to have an option that dumps a section with
15524 relocs applied ? */
dda8d76d
NC
15525 for (relsec = filedata->section_headers;
15526 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15527 ++relsec)
15528 {
15529 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15530 || relsec->sh_info >= filedata->file_header.e_shnum
15531 || filedata->section_headers + relsec->sh_info != section
cf13d699 15532 || relsec->sh_size == 0
dda8d76d 15533 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15534 continue;
15535
15536 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15537 break;
15538 }
15539 }
15540
15541 addr = section->sh_addr;
0e602686 15542 bytes = section_size;
cf13d699
NC
15543 data = start;
15544
15545 while (bytes)
15546 {
15547 int j;
15548 int k;
15549 int lbytes;
15550
15551 lbytes = (bytes > 16 ? 16 : bytes);
15552
15553 printf (" 0x%8.8lx ", (unsigned long) addr);
15554
15555 for (j = 0; j < 16; j++)
15556 {
15557 if (j < lbytes)
15558 printf ("%2.2x", data[j]);
15559 else
15560 printf (" ");
15561
15562 if ((j & 3) == 3)
15563 printf (" ");
15564 }
15565
15566 for (j = 0; j < lbytes; j++)
15567 {
15568 k = data[j];
15569 if (k >= ' ' && k < 0x7f)
15570 printf ("%c", k);
15571 else
15572 printf (".");
15573 }
15574
15575 putchar ('\n');
15576
15577 data += lbytes;
15578 addr += lbytes;
15579 bytes -= lbytes;
15580 }
15581
0e602686 15582 free (real_start);
cf13d699
NC
15583
15584 putchar ('\n');
015dc7e1 15585 return true;
f761cb13
AM
15586
15587 error_out:
15588 free (real_start);
015dc7e1 15589 return false;
cf13d699
NC
15590}
15591
094e34f2 15592#ifdef ENABLE_LIBCTF
7d9813f1
NA
15593static ctf_sect_t *
15594shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15595{
84714f86 15596 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15597 buf->cts_size = shdr->sh_size;
15598 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15599
15600 return buf;
15601}
15602
15603/* Formatting callback function passed to ctf_dump. Returns either the pointer
15604 it is passed, or a pointer to newly-allocated storage, in which case
15605 dump_ctf() will free it when it no longer needs it. */
15606
2f6ecaed
NA
15607static char *
15608dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15609 char *s, void *arg)
7d9813f1 15610{
3e50a591 15611 const char *blanks = arg;
7d9813f1
NA
15612 char *new_s;
15613
3e50a591 15614 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15615 return s;
15616 return new_s;
15617}
15618
926c9e76
NA
15619/* Dump CTF errors/warnings. */
15620static void
139633c3 15621dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15622{
15623 ctf_next_t *it = NULL;
15624 char *errtext;
15625 int is_warning;
15626 int err;
15627
15628 /* Dump accumulated errors and warnings. */
15629 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15630 {
5e9b84f7 15631 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15632 errtext);
15633 free (errtext);
15634 }
15635 if (err != ECTF_NEXT_END)
15636 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15637}
15638
2f6ecaed
NA
15639/* Dump one CTF archive member. */
15640
80b56fad
NA
15641static void
15642dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15643 size_t member)
2f6ecaed 15644{
2f6ecaed
NA
15645 const char *things[] = {"Header", "Labels", "Data objects",
15646 "Function objects", "Variables", "Types", "Strings",
15647 ""};
15648 const char **thing;
15649 size_t i;
15650
80b56fad
NA
15651 /* Don't print out the name of the default-named archive member if it appears
15652 first in the list. The name .ctf appears everywhere, even for things that
15653 aren't really archives, so printing it out is liable to be confusing; also,
15654 the common case by far is for only one archive member to exist, and hiding
15655 it in that case seems worthwhile. */
2f6ecaed 15656
80b56fad
NA
15657 if (strcmp (name, ".ctf") != 0 || member != 0)
15658 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15659
80b56fad
NA
15660 if (ctf_parent_name (ctf) != NULL)
15661 ctf_import (ctf, parent);
2f6ecaed
NA
15662
15663 for (i = 0, thing = things; *thing[0]; thing++, i++)
15664 {
15665 ctf_dump_state_t *s = NULL;
15666 char *item;
15667
15668 printf ("\n %s:\n", *thing);
15669 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15670 (void *) " ")) != NULL)
15671 {
15672 printf ("%s\n", item);
15673 free (item);
15674 }
15675
15676 if (ctf_errno (ctf))
15677 {
15678 error (_("Iteration failed: %s, %s\n"), *thing,
15679 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15680 break;
2f6ecaed
NA
15681 }
15682 }
8b37e7b6 15683
926c9e76 15684 dump_ctf_errs (ctf);
2f6ecaed
NA
15685}
15686
015dc7e1 15687static bool
7d9813f1
NA
15688dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15689{
7d9813f1
NA
15690 Elf_Internal_Shdr * symtab_sec = NULL;
15691 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15692 void * data = NULL;
15693 void * symdata = NULL;
15694 void * strdata = NULL;
80b56fad 15695 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15696 ctf_sect_t * symsectp = NULL;
15697 ctf_sect_t * strsectp = NULL;
2f6ecaed 15698 ctf_archive_t * ctfa = NULL;
139633c3 15699 ctf_dict_t * parent = NULL;
80b56fad 15700 ctf_dict_t * fp;
7d9813f1 15701
80b56fad
NA
15702 ctf_next_t *i = NULL;
15703 const char *name;
15704 size_t member = 0;
7d9813f1 15705 int err;
015dc7e1 15706 bool ret = false;
7d9813f1
NA
15707
15708 shdr_to_ctf_sect (&ctfsect, section, filedata);
15709 data = get_section_contents (section, filedata);
15710 ctfsect.cts_data = data;
15711
616febde 15712 if (!dump_ctf_symtab_name)
3d16b64e 15713 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15714
15715 if (!dump_ctf_strtab_name)
3d16b64e 15716 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15717
15718 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15719 {
15720 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15721 {
15722 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15723 goto fail;
15724 }
15725 if ((symdata = (void *) get_data (NULL, filedata,
15726 symtab_sec->sh_offset, 1,
15727 symtab_sec->sh_size,
15728 _("symbols"))) == NULL)
15729 goto fail;
15730 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15731 symsect.cts_data = symdata;
15732 }
835f2fae 15733
df16e041 15734 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15735 {
15736 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15737 {
15738 error (_("No string table section named %s\n"),
15739 dump_ctf_strtab_name);
15740 goto fail;
15741 }
15742 if ((strdata = (void *) get_data (NULL, filedata,
15743 strtab_sec->sh_offset, 1,
15744 strtab_sec->sh_size,
15745 _("strings"))) == NULL)
15746 goto fail;
15747 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15748 strsect.cts_data = strdata;
15749 }
835f2fae 15750
2f6ecaed
NA
15751 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15752 libctf papers over the difference, so we can pretend it is always an
80b56fad 15753 archive. */
7d9813f1 15754
2f6ecaed 15755 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15756 {
926c9e76 15757 dump_ctf_errs (NULL);
7d9813f1
NA
15758 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15759 goto fail;
15760 }
15761
96c61be5
NA
15762 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15763 != ELFDATA2MSB);
15764
80b56fad
NA
15765 /* Preload the parent dict, since it will need to be imported into every
15766 child in turn. */
15767 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15768 {
926c9e76 15769 dump_ctf_errs (NULL);
2f6ecaed
NA
15770 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15771 goto fail;
7d9813f1
NA
15772 }
15773
015dc7e1 15774 ret = true;
7d9813f1 15775
835f2fae
NC
15776 if (filedata->is_separate)
15777 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15778 printable_section_name (filedata, section),
15779 filedata->file_name);
15780 else
15781 printf (_("\nDump of CTF section '%s':\n"),
15782 printable_section_name (filedata, section));
7d9813f1 15783
80b56fad
NA
15784 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15785 dump_ctf_archive_member (fp, name, parent, member++);
15786 if (err != ECTF_NEXT_END)
15787 {
15788 dump_ctf_errs (NULL);
15789 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15790 ret = false;
15791 }
7d9813f1
NA
15792
15793 fail:
139633c3 15794 ctf_dict_close (parent);
2f6ecaed 15795 ctf_close (ctfa);
7d9813f1
NA
15796 free (data);
15797 free (symdata);
15798 free (strdata);
15799 return ret;
15800}
094e34f2 15801#endif
7d9813f1 15802
015dc7e1 15803static bool
dda8d76d
NC
15804load_specific_debug_section (enum dwarf_section_display_enum debug,
15805 const Elf_Internal_Shdr * sec,
15806 void * data)
1007acb3 15807{
2cf0635d 15808 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15809 char buf [64];
dda8d76d 15810 Filedata * filedata = (Filedata *) data;
9abca702 15811
19e6b90e 15812 if (section->start != NULL)
dda8d76d
NC
15813 {
15814 /* If it is already loaded, do nothing. */
15815 if (streq (section->filename, filedata->file_name))
015dc7e1 15816 return true;
dda8d76d
NC
15817 free (section->start);
15818 }
1007acb3 15819
19e6b90e
L
15820 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15821 section->address = sec->sh_addr;
dda8d76d
NC
15822 section->filename = filedata->file_name;
15823 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15824 sec->sh_offset, 1,
15825 sec->sh_size, buf);
59245841
NC
15826 if (section->start == NULL)
15827 section->size = 0;
15828 else
15829 {
77115a4a
L
15830 unsigned char *start = section->start;
15831 dwarf_size_type size = sec->sh_size;
dab394de 15832 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15833
15834 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15835 {
15836 Elf_Internal_Chdr chdr;
d8024a91
NC
15837 unsigned int compression_header_size;
15838
f53be977
L
15839 if (size < (is_32bit_elf
15840 ? sizeof (Elf32_External_Chdr)
15841 : sizeof (Elf64_External_Chdr)))
d8024a91 15842 {
55be8fd0 15843 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15844 section->name);
015dc7e1 15845 return false;
d8024a91
NC
15846 }
15847
ebdf1ebf 15848 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15849 if (compression_header_size == 0)
15850 /* An error message will have already been generated
15851 by get_compression_header. */
015dc7e1 15852 return false;
d8024a91 15853
813dabb9
L
15854 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15855 {
15856 warn (_("section '%s' has unsupported compress type: %d\n"),
15857 section->name, chdr.ch_type);
015dc7e1 15858 return false;
813dabb9 15859 }
dab394de 15860 uncompressed_size = chdr.ch_size;
77115a4a
L
15861 start += compression_header_size;
15862 size -= compression_header_size;
15863 }
dab394de
L
15864 else if (size > 12 && streq ((char *) start, "ZLIB"))
15865 {
15866 /* Read the zlib header. In this case, it should be "ZLIB"
15867 followed by the uncompressed section size, 8 bytes in
15868 big-endian order. */
15869 uncompressed_size = start[4]; uncompressed_size <<= 8;
15870 uncompressed_size += start[5]; uncompressed_size <<= 8;
15871 uncompressed_size += start[6]; uncompressed_size <<= 8;
15872 uncompressed_size += start[7]; uncompressed_size <<= 8;
15873 uncompressed_size += start[8]; uncompressed_size <<= 8;
15874 uncompressed_size += start[9]; uncompressed_size <<= 8;
15875 uncompressed_size += start[10]; uncompressed_size <<= 8;
15876 uncompressed_size += start[11];
15877 start += 12;
15878 size -= 12;
15879 }
15880
1835f746 15881 if (uncompressed_size)
77115a4a 15882 {
1835f746
NC
15883 if (uncompress_section_contents (&start, uncompressed_size,
15884 &size))
15885 {
15886 /* Free the compressed buffer, update the section buffer
15887 and the section size if uncompress is successful. */
15888 free (section->start);
15889 section->start = start;
15890 }
15891 else
15892 {
15893 error (_("Unable to decompress section %s\n"),
dda8d76d 15894 printable_section_name (filedata, sec));
015dc7e1 15895 return false;
1835f746 15896 }
77115a4a 15897 }
bc303e5d 15898
77115a4a 15899 section->size = size;
59245841 15900 }
4a114e3e 15901
1b315056 15902 if (section->start == NULL)
015dc7e1 15903 return false;
1b315056 15904
19e6b90e 15905 if (debug_displays [debug].relocate)
32ec8896 15906 {
dda8d76d 15907 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15908 & section->reloc_info, & section->num_relocs))
015dc7e1 15909 return false;
32ec8896 15910 }
d1c4b12b
NC
15911 else
15912 {
15913 section->reloc_info = NULL;
15914 section->num_relocs = 0;
15915 }
1007acb3 15916
015dc7e1 15917 return true;
1007acb3
L
15918}
15919
301a9420
AM
15920#if HAVE_LIBDEBUGINFOD
15921/* Return a hex string representation of the build-id. */
15922unsigned char *
15923get_build_id (void * data)
15924{
ca0e11aa 15925 Filedata * filedata = (Filedata *) data;
301a9420
AM
15926 Elf_Internal_Shdr * shdr;
15927 unsigned long i;
15928
55be8fd0
NC
15929 /* Iterate through notes to find note.gnu.build-id.
15930 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15931 for (i = 0, shdr = filedata->section_headers;
15932 i < filedata->file_header.e_shnum && shdr != NULL;
15933 i++, shdr++)
15934 {
15935 if (shdr->sh_type != SHT_NOTE)
15936 continue;
15937
15938 char * next;
15939 char * end;
15940 size_t data_remaining;
15941 size_t min_notesz;
15942 Elf_External_Note * enote;
15943 Elf_Internal_Note inote;
15944
15945 bfd_vma offset = shdr->sh_offset;
15946 bfd_vma align = shdr->sh_addralign;
15947 bfd_vma length = shdr->sh_size;
15948
15949 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15950 if (enote == NULL)
15951 continue;
15952
15953 if (align < 4)
15954 align = 4;
15955 else if (align != 4 && align != 8)
f761cb13
AM
15956 {
15957 free (enote);
15958 continue;
15959 }
301a9420
AM
15960
15961 end = (char *) enote + length;
15962 data_remaining = end - (char *) enote;
15963
15964 if (!is_ia64_vms (filedata))
15965 {
15966 min_notesz = offsetof (Elf_External_Note, name);
15967 if (data_remaining < min_notesz)
15968 {
55be8fd0
NC
15969 warn (_("\
15970malformed note encountered in section %s whilst scanning for build-id note\n"),
15971 printable_section_name (filedata, shdr));
f761cb13 15972 free (enote);
55be8fd0 15973 continue;
301a9420
AM
15974 }
15975 data_remaining -= min_notesz;
15976
15977 inote.type = BYTE_GET (enote->type);
15978 inote.namesz = BYTE_GET (enote->namesz);
15979 inote.namedata = enote->name;
15980 inote.descsz = BYTE_GET (enote->descsz);
15981 inote.descdata = ((char *) enote
15982 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15983 inote.descpos = offset + (inote.descdata - (char *) enote);
15984 next = ((char *) enote
15985 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15986 }
15987 else
15988 {
15989 Elf64_External_VMS_Note *vms_enote;
15990
15991 /* PR binutils/15191
15992 Make sure that there is enough data to read. */
15993 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15994 if (data_remaining < min_notesz)
15995 {
55be8fd0
NC
15996 warn (_("\
15997malformed note encountered in section %s whilst scanning for build-id note\n"),
15998 printable_section_name (filedata, shdr));
f761cb13 15999 free (enote);
55be8fd0 16000 continue;
301a9420
AM
16001 }
16002 data_remaining -= min_notesz;
16003
16004 vms_enote = (Elf64_External_VMS_Note *) enote;
16005 inote.type = BYTE_GET (vms_enote->type);
16006 inote.namesz = BYTE_GET (vms_enote->namesz);
16007 inote.namedata = vms_enote->name;
16008 inote.descsz = BYTE_GET (vms_enote->descsz);
16009 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16010 inote.descpos = offset + (inote.descdata - (char *) enote);
16011 next = inote.descdata + align_power (inote.descsz, 3);
16012 }
16013
16014 /* Skip malformed notes. */
16015 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16016 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16017 || (size_t) (next - inote.descdata) < inote.descsz
16018 || ((size_t) (next - inote.descdata)
16019 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16020 {
55be8fd0
NC
16021 warn (_("\
16022malformed note encountered in section %s whilst scanning for build-id note\n"),
16023 printable_section_name (filedata, shdr));
f761cb13 16024 free (enote);
301a9420
AM
16025 continue;
16026 }
16027
16028 /* Check if this is the build-id note. If so then convert the build-id
16029 bytes to a hex string. */
16030 if (inote.namesz > 0
24d127aa 16031 && startswith (inote.namedata, "GNU")
301a9420
AM
16032 && inote.type == NT_GNU_BUILD_ID)
16033 {
16034 unsigned long j;
16035 char * build_id;
16036
16037 build_id = malloc (inote.descsz * 2 + 1);
16038 if (build_id == NULL)
f761cb13
AM
16039 {
16040 free (enote);
16041 return NULL;
16042 }
301a9420
AM
16043
16044 for (j = 0; j < inote.descsz; ++j)
16045 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16046 build_id[inote.descsz * 2] = '\0';
f761cb13 16047 free (enote);
301a9420 16048
55be8fd0 16049 return (unsigned char *) build_id;
301a9420 16050 }
f761cb13 16051 free (enote);
301a9420
AM
16052 }
16053
16054 return NULL;
16055}
16056#endif /* HAVE_LIBDEBUGINFOD */
16057
657d0d47
CC
16058/* If this is not NULL, load_debug_section will only look for sections
16059 within the list of sections given here. */
32ec8896 16060static unsigned int * section_subset = NULL;
657d0d47 16061
015dc7e1 16062bool
dda8d76d 16063load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16064{
2cf0635d
NC
16065 struct dwarf_section * section = &debug_displays [debug].section;
16066 Elf_Internal_Shdr * sec;
dda8d76d
NC
16067 Filedata * filedata = (Filedata *) data;
16068
e1dbfc17
L
16069 if (!dump_any_debugging)
16070 return false;
16071
f425ec66
NC
16072 /* Without section headers we cannot find any sections. */
16073 if (filedata->section_headers == NULL)
015dc7e1 16074 return false;
f425ec66 16075
9c1ce108
AM
16076 if (filedata->string_table == NULL
16077 && filedata->file_header.e_shstrndx != SHN_UNDEF
16078 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16079 {
16080 Elf_Internal_Shdr * strs;
16081
16082 /* Read in the string table, so that we have section names to scan. */
16083 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16084
4dff97b2 16085 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16086 {
9c1ce108
AM
16087 filedata->string_table
16088 = (char *) get_data (NULL, filedata, strs->sh_offset,
16089 1, strs->sh_size, _("string table"));
dda8d76d 16090
9c1ce108
AM
16091 filedata->string_table_length
16092 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16093 }
16094 }
d966045b
DJ
16095
16096 /* Locate the debug section. */
dda8d76d 16097 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16098 if (sec != NULL)
16099 section->name = section->uncompressed_name;
16100 else
16101 {
dda8d76d 16102 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16103 if (sec != NULL)
16104 section->name = section->compressed_name;
16105 }
16106 if (sec == NULL)
015dc7e1 16107 return false;
d966045b 16108
657d0d47
CC
16109 /* If we're loading from a subset of sections, and we've loaded
16110 a section matching this name before, it's likely that it's a
16111 different one. */
16112 if (section_subset != NULL)
16113 free_debug_section (debug);
16114
dda8d76d 16115 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16116}
16117
19e6b90e
L
16118void
16119free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16120{
2cf0635d 16121 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16122
19e6b90e
L
16123 if (section->start == NULL)
16124 return;
1007acb3 16125
19e6b90e
L
16126 free ((char *) section->start);
16127 section->start = NULL;
16128 section->address = 0;
16129 section->size = 0;
a788aedd 16130
9db70fc3
AM
16131 free (section->reloc_info);
16132 section->reloc_info = NULL;
16133 section->num_relocs = 0;
1007acb3
L
16134}
16135
015dc7e1 16136static bool
dda8d76d 16137display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16138{
84714f86
AM
16139 const char *name = (section_name_valid (filedata, section)
16140 ? section_name (filedata, section) : "");
16141 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16142 bfd_size_type length;
015dc7e1 16143 bool result = true;
3f5e193b 16144 int i;
1007acb3 16145
19e6b90e
L
16146 length = section->sh_size;
16147 if (length == 0)
1007acb3 16148 {
74e1a04b 16149 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16150 return true;
1007acb3 16151 }
5dff79d8
NC
16152 if (section->sh_type == SHT_NOBITS)
16153 {
16154 /* There is no point in dumping the contents of a debugging section
16155 which has the NOBITS type - the bits in the file will be random.
16156 This can happen when a file containing a .eh_frame section is
16157 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16158 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16159 print_name);
015dc7e1 16160 return false;
5dff79d8 16161 }
1007acb3 16162
24d127aa 16163 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16164 name = ".debug_info";
1007acb3 16165
19e6b90e
L
16166 /* See if we know how to display the contents of this section. */
16167 for (i = 0; i < max; i++)
d85bf2ba
NC
16168 {
16169 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16170 struct dwarf_section_display * display = debug_displays + i;
16171 struct dwarf_section * sec = & display->section;
d966045b 16172
d85bf2ba 16173 if (streq (sec->uncompressed_name, name)
24d127aa 16174 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16175 || streq (sec->compressed_name, name))
16176 {
015dc7e1 16177 bool secondary = (section != find_section (filedata, name));
1007acb3 16178
d85bf2ba
NC
16179 if (secondary)
16180 free_debug_section (id);
dda8d76d 16181
24d127aa 16182 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16183 sec->name = name;
16184 else if (streq (sec->uncompressed_name, name))
16185 sec->name = sec->uncompressed_name;
16186 else
16187 sec->name = sec->compressed_name;
657d0d47 16188
d85bf2ba
NC
16189 if (load_specific_debug_section (id, section, filedata))
16190 {
16191 /* If this debug section is part of a CU/TU set in a .dwp file,
16192 restrict load_debug_section to the sections in that set. */
16193 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16194
d85bf2ba 16195 result &= display->display (sec, filedata);
657d0d47 16196
d85bf2ba 16197 section_subset = NULL;
1007acb3 16198
44266f36 16199 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16200 free_debug_section (id);
16201 }
16202 break;
16203 }
16204 }
1007acb3 16205
19e6b90e 16206 if (i == max)
1007acb3 16207 {
74e1a04b 16208 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16209 result = false;
1007acb3
L
16210 }
16211
19e6b90e 16212 return result;
5b18a4bc 16213}
103f02d3 16214
aef1f6d0
DJ
16215/* Set DUMP_SECTS for all sections where dumps were requested
16216 based on section name. */
16217
16218static void
dda8d76d 16219initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16220{
2cf0635d 16221 struct dump_list_entry * cur;
aef1f6d0
DJ
16222
16223 for (cur = dump_sects_byname; cur; cur = cur->next)
16224 {
16225 unsigned int i;
015dc7e1 16226 bool any = false;
aef1f6d0 16227
dda8d76d 16228 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16229 if (section_name_valid (filedata, filedata->section_headers + i)
16230 && streq (section_name (filedata, filedata->section_headers + i),
16231 cur->name))
aef1f6d0 16232 {
6431e409 16233 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16234 any = true;
aef1f6d0
DJ
16235 }
16236
835f2fae
NC
16237 if (!any && !filedata->is_separate)
16238 warn (_("Section '%s' was not dumped because it does not exist\n"),
16239 cur->name);
aef1f6d0
DJ
16240 }
16241}
16242
015dc7e1 16243static bool
dda8d76d 16244process_section_contents (Filedata * filedata)
5b18a4bc 16245{
2cf0635d 16246 Elf_Internal_Shdr * section;
19e6b90e 16247 unsigned int i;
015dc7e1 16248 bool res = true;
103f02d3 16249
19e6b90e 16250 if (! do_dump)
015dc7e1 16251 return true;
103f02d3 16252
dda8d76d 16253 initialise_dumps_byname (filedata);
aef1f6d0 16254
dda8d76d 16255 for (i = 0, section = filedata->section_headers;
6431e409 16256 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16257 i++, section++)
16258 {
6431e409 16259 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16260
d6bfbc39
NC
16261 if (filedata->is_separate && ! process_links)
16262 dump &= DEBUG_DUMP;
047c3dbf 16263
19e6b90e 16264#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16265 if (dump & DISASS_DUMP)
16266 {
16267 if (! disassemble_section (section, filedata))
015dc7e1 16268 res = false;
dda8d76d 16269 }
19e6b90e 16270#endif
dda8d76d 16271 if (dump & HEX_DUMP)
32ec8896 16272 {
015dc7e1
AM
16273 if (! dump_section_as_bytes (section, filedata, false))
16274 res = false;
32ec8896 16275 }
103f02d3 16276
dda8d76d 16277 if (dump & RELOC_DUMP)
32ec8896 16278 {
015dc7e1
AM
16279 if (! dump_section_as_bytes (section, filedata, true))
16280 res = false;
32ec8896 16281 }
09c11c86 16282
dda8d76d 16283 if (dump & STRING_DUMP)
32ec8896 16284 {
dda8d76d 16285 if (! dump_section_as_strings (section, filedata))
015dc7e1 16286 res = false;
32ec8896 16287 }
cf13d699 16288
dda8d76d 16289 if (dump & DEBUG_DUMP)
32ec8896 16290 {
dda8d76d 16291 if (! display_debug_section (i, section, filedata))
015dc7e1 16292 res = false;
32ec8896 16293 }
7d9813f1 16294
094e34f2 16295#ifdef ENABLE_LIBCTF
7d9813f1
NA
16296 if (dump & CTF_DUMP)
16297 {
16298 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16299 res = false;
7d9813f1 16300 }
094e34f2 16301#endif
5b18a4bc 16302 }
103f02d3 16303
835f2fae 16304 if (! filedata->is_separate)
0ee3043f 16305 {
835f2fae
NC
16306 /* Check to see if the user requested a
16307 dump of a section that does not exist. */
16308 for (; i < filedata->dump.num_dump_sects; i++)
16309 if (filedata->dump.dump_sects[i])
16310 {
ca0e11aa 16311 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16312 res = false;
835f2fae 16313 }
0ee3043f 16314 }
32ec8896
NC
16315
16316 return res;
5b18a4bc 16317}
103f02d3 16318
5b18a4bc 16319static void
19e6b90e 16320process_mips_fpe_exception (int mask)
5b18a4bc 16321{
19e6b90e
L
16322 if (mask)
16323 {
015dc7e1 16324 bool first = true;
32ec8896 16325
19e6b90e 16326 if (mask & OEX_FPU_INEX)
015dc7e1 16327 fputs ("INEX", stdout), first = false;
19e6b90e 16328 if (mask & OEX_FPU_UFLO)
015dc7e1 16329 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16330 if (mask & OEX_FPU_OFLO)
015dc7e1 16331 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16332 if (mask & OEX_FPU_DIV0)
015dc7e1 16333 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16334 if (mask & OEX_FPU_INVAL)
16335 printf ("%sINVAL", first ? "" : "|");
16336 }
5b18a4bc 16337 else
19e6b90e 16338 fputs ("0", stdout);
5b18a4bc 16339}
103f02d3 16340
f6f0e17b
NC
16341/* Display's the value of TAG at location P. If TAG is
16342 greater than 0 it is assumed to be an unknown tag, and
16343 a message is printed to this effect. Otherwise it is
16344 assumed that a message has already been printed.
16345
16346 If the bottom bit of TAG is set it assumed to have a
16347 string value, otherwise it is assumed to have an integer
16348 value.
16349
16350 Returns an updated P pointing to the first unread byte
16351 beyond the end of TAG's value.
16352
16353 Reads at or beyond END will not be made. */
16354
16355static unsigned char *
60abdbed 16356display_tag_value (signed int tag,
f6f0e17b
NC
16357 unsigned char * p,
16358 const unsigned char * const end)
16359{
16360 unsigned long val;
16361
16362 if (tag > 0)
16363 printf (" Tag_unknown_%d: ", tag);
16364
16365 if (p >= end)
16366 {
4082ef84 16367 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16368 }
16369 else if (tag & 1)
16370 {
071436c6
NC
16371 /* PR 17531 file: 027-19978-0.004. */
16372 size_t maxlen = (end - p) - 1;
16373
16374 putchar ('"');
4082ef84
NC
16375 if (maxlen > 0)
16376 {
16377 print_symbol ((int) maxlen, (const char *) p);
16378 p += strnlen ((char *) p, maxlen) + 1;
16379 }
16380 else
16381 {
16382 printf (_("<corrupt string tag>"));
16383 p = (unsigned char *) end;
16384 }
071436c6 16385 printf ("\"\n");
f6f0e17b
NC
16386 }
16387 else
16388 {
cd30bcef 16389 READ_ULEB (val, p, end);
f6f0e17b
NC
16390 printf ("%ld (0x%lx)\n", val, val);
16391 }
16392
4082ef84 16393 assert (p <= end);
f6f0e17b
NC
16394 return p;
16395}
16396
53a346d8
CZ
16397/* ARC ABI attributes section. */
16398
16399static unsigned char *
16400display_arc_attribute (unsigned char * p,
16401 const unsigned char * const end)
16402{
16403 unsigned int tag;
53a346d8
CZ
16404 unsigned int val;
16405
cd30bcef 16406 READ_ULEB (tag, p, end);
53a346d8
CZ
16407
16408 switch (tag)
16409 {
16410 case Tag_ARC_PCS_config:
cd30bcef 16411 READ_ULEB (val, p, end);
53a346d8
CZ
16412 printf (" Tag_ARC_PCS_config: ");
16413 switch (val)
16414 {
16415 case 0:
16416 printf (_("Absent/Non standard\n"));
16417 break;
16418 case 1:
16419 printf (_("Bare metal/mwdt\n"));
16420 break;
16421 case 2:
16422 printf (_("Bare metal/newlib\n"));
16423 break;
16424 case 3:
16425 printf (_("Linux/uclibc\n"));
16426 break;
16427 case 4:
16428 printf (_("Linux/glibc\n"));
16429 break;
16430 default:
16431 printf (_("Unknown\n"));
16432 break;
16433 }
16434 break;
16435
16436 case Tag_ARC_CPU_base:
cd30bcef 16437 READ_ULEB (val, p, end);
53a346d8
CZ
16438 printf (" Tag_ARC_CPU_base: ");
16439 switch (val)
16440 {
16441 default:
16442 case TAG_CPU_NONE:
16443 printf (_("Absent\n"));
16444 break;
16445 case TAG_CPU_ARC6xx:
16446 printf ("ARC6xx\n");
16447 break;
16448 case TAG_CPU_ARC7xx:
16449 printf ("ARC7xx\n");
16450 break;
16451 case TAG_CPU_ARCEM:
16452 printf ("ARCEM\n");
16453 break;
16454 case TAG_CPU_ARCHS:
16455 printf ("ARCHS\n");
16456 break;
16457 }
16458 break;
16459
16460 case Tag_ARC_CPU_variation:
cd30bcef 16461 READ_ULEB (val, p, end);
53a346d8
CZ
16462 printf (" Tag_ARC_CPU_variation: ");
16463 switch (val)
16464 {
16465 default:
16466 if (val > 0 && val < 16)
53a346d8 16467 printf ("Core%d\n", val);
d8cbc93b
JL
16468 else
16469 printf ("Unknown\n");
16470 break;
16471
53a346d8
CZ
16472 case 0:
16473 printf (_("Absent\n"));
16474 break;
16475 }
16476 break;
16477
16478 case Tag_ARC_CPU_name:
16479 printf (" Tag_ARC_CPU_name: ");
16480 p = display_tag_value (-1, p, end);
16481 break;
16482
16483 case Tag_ARC_ABI_rf16:
cd30bcef 16484 READ_ULEB (val, p, end);
53a346d8
CZ
16485 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16486 break;
16487
16488 case Tag_ARC_ABI_osver:
cd30bcef 16489 READ_ULEB (val, p, end);
53a346d8
CZ
16490 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16491 break;
16492
16493 case Tag_ARC_ABI_pic:
16494 case Tag_ARC_ABI_sda:
cd30bcef 16495 READ_ULEB (val, p, end);
53a346d8
CZ
16496 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16497 : " Tag_ARC_ABI_pic: ");
16498 switch (val)
16499 {
16500 case 0:
16501 printf (_("Absent\n"));
16502 break;
16503 case 1:
16504 printf ("MWDT\n");
16505 break;
16506 case 2:
16507 printf ("GNU\n");
16508 break;
16509 default:
16510 printf (_("Unknown\n"));
16511 break;
16512 }
16513 break;
16514
16515 case Tag_ARC_ABI_tls:
cd30bcef 16516 READ_ULEB (val, p, end);
53a346d8
CZ
16517 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16518 break;
16519
16520 case Tag_ARC_ABI_enumsize:
cd30bcef 16521 READ_ULEB (val, p, end);
53a346d8
CZ
16522 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16523 _("smallest"));
16524 break;
16525
16526 case Tag_ARC_ABI_exceptions:
cd30bcef 16527 READ_ULEB (val, p, end);
53a346d8
CZ
16528 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16529 : _("default"));
16530 break;
16531
16532 case Tag_ARC_ABI_double_size:
cd30bcef 16533 READ_ULEB (val, p, end);
53a346d8
CZ
16534 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16535 break;
16536
16537 case Tag_ARC_ISA_config:
16538 printf (" Tag_ARC_ISA_config: ");
16539 p = display_tag_value (-1, p, end);
16540 break;
16541
16542 case Tag_ARC_ISA_apex:
16543 printf (" Tag_ARC_ISA_apex: ");
16544 p = display_tag_value (-1, p, end);
16545 break;
16546
16547 case Tag_ARC_ISA_mpy_option:
cd30bcef 16548 READ_ULEB (val, p, end);
53a346d8
CZ
16549 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16550 break;
16551
db1e1b45 16552 case Tag_ARC_ATR_version:
cd30bcef 16553 READ_ULEB (val, p, end);
db1e1b45 16554 printf (" Tag_ARC_ATR_version: %d\n", val);
16555 break;
16556
53a346d8
CZ
16557 default:
16558 return display_tag_value (tag & 1, p, end);
16559 }
16560
16561 return p;
16562}
16563
11c1ff18
PB
16564/* ARM EABI attributes section. */
16565typedef struct
16566{
70e99720 16567 unsigned int tag;
2cf0635d 16568 const char * name;
11c1ff18 16569 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16570 unsigned int type;
288f0ba2 16571 const char *const *table;
11c1ff18
PB
16572} arm_attr_public_tag;
16573
288f0ba2 16574static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16575 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16576 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16577 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16578 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16579static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16580static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16581 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16582static const char *const arm_attr_tag_FP_arch[] =
bca38921 16583 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16584 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16585static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16586static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16587 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16588 "NEON for ARMv8.1"};
288f0ba2 16589static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16590 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16591 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16592static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16593 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16594static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16595 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16596static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16597 {"Absolute", "PC-relative", "None"};
288f0ba2 16598static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16599 {"None", "direct", "GOT-indirect"};
288f0ba2 16600static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16601 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16602static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16603static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16604 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16605static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16606static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16607static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16608 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16609static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16610 {"Unused", "small", "int", "forced to int"};
288f0ba2 16611static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16612 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16613static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16614 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16615static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16616 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16617static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16618 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16619 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16620static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16621 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16622 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16623static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16624static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16625 {"Not Allowed", "Allowed"};
288f0ba2 16626static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16627 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16628static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16629 {"Follow architecture", "Allowed"};
288f0ba2 16630static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16631 {"Not Allowed", "Allowed"};
288f0ba2 16632static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16633 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16634 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16635static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16636static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16637 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16638 "TrustZone and Virtualization Extensions"};
288f0ba2 16639static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16640 {"Not Allowed", "Allowed"};
11c1ff18 16641
288f0ba2 16642static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16643 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16644
99db83d0
AC
16645static const char * arm_attr_tag_PAC_extension[] =
16646 {"No PAC/AUT instructions",
16647 "PAC/AUT instructions permitted in the NOP space",
16648 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16649
4b535030
AC
16650static const char * arm_attr_tag_BTI_extension[] =
16651 {"BTI instructions not permitted",
16652 "BTI instructions permitted in the NOP space",
16653 "BTI instructions permitted in the NOP and in the non-NOP space"};
16654
b81ee92f
AC
16655static const char * arm_attr_tag_BTI_use[] =
16656 {"Compiled without branch target enforcement",
16657 "Compiled with branch target enforcement"};
16658
c9fed665
AC
16659static const char * arm_attr_tag_PACRET_use[] =
16660 {"Compiled without return address signing and authentication",
16661 "Compiled with return address signing and authentication"};
16662
11c1ff18
PB
16663#define LOOKUP(id, name) \
16664 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16665static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16666{
16667 {4, "CPU_raw_name", 1, NULL},
16668 {5, "CPU_name", 1, NULL},
16669 LOOKUP(6, CPU_arch),
16670 {7, "CPU_arch_profile", 0, NULL},
16671 LOOKUP(8, ARM_ISA_use),
16672 LOOKUP(9, THUMB_ISA_use),
75375b3e 16673 LOOKUP(10, FP_arch),
11c1ff18 16674 LOOKUP(11, WMMX_arch),
f5f53991
AS
16675 LOOKUP(12, Advanced_SIMD_arch),
16676 LOOKUP(13, PCS_config),
11c1ff18
PB
16677 LOOKUP(14, ABI_PCS_R9_use),
16678 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16679 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16680 LOOKUP(17, ABI_PCS_GOT_use),
16681 LOOKUP(18, ABI_PCS_wchar_t),
16682 LOOKUP(19, ABI_FP_rounding),
16683 LOOKUP(20, ABI_FP_denormal),
16684 LOOKUP(21, ABI_FP_exceptions),
16685 LOOKUP(22, ABI_FP_user_exceptions),
16686 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16687 {24, "ABI_align_needed", 0, NULL},
16688 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16689 LOOKUP(26, ABI_enum_size),
16690 LOOKUP(27, ABI_HardFP_use),
16691 LOOKUP(28, ABI_VFP_args),
16692 LOOKUP(29, ABI_WMMX_args),
16693 LOOKUP(30, ABI_optimization_goals),
16694 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16695 {32, "compatibility", 0, NULL},
f5f53991 16696 LOOKUP(34, CPU_unaligned_access),
75375b3e 16697 LOOKUP(36, FP_HP_extension),
8e79c3df 16698 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16699 LOOKUP(42, MPextension_use),
16700 LOOKUP(44, DIV_use),
15afaa63 16701 LOOKUP(46, DSP_extension),
a7ad558c 16702 LOOKUP(48, MVE_arch),
99db83d0 16703 LOOKUP(50, PAC_extension),
4b535030 16704 LOOKUP(52, BTI_extension),
b81ee92f 16705 LOOKUP(74, BTI_use),
c9fed665 16706 LOOKUP(76, PACRET_use),
f5f53991
AS
16707 {64, "nodefaults", 0, NULL},
16708 {65, "also_compatible_with", 0, NULL},
16709 LOOKUP(66, T2EE_use),
16710 {67, "conformance", 1, NULL},
16711 LOOKUP(68, Virtualization_use),
cd21e546 16712 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16713};
16714#undef LOOKUP
16715
11c1ff18 16716static unsigned char *
f6f0e17b
NC
16717display_arm_attribute (unsigned char * p,
16718 const unsigned char * const end)
11c1ff18 16719{
70e99720 16720 unsigned int tag;
70e99720 16721 unsigned int val;
2cf0635d 16722 arm_attr_public_tag * attr;
11c1ff18 16723 unsigned i;
70e99720 16724 unsigned int type;
11c1ff18 16725
cd30bcef 16726 READ_ULEB (tag, p, end);
11c1ff18 16727 attr = NULL;
2cf0635d 16728 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16729 {
16730 if (arm_attr_public_tags[i].tag == tag)
16731 {
16732 attr = &arm_attr_public_tags[i];
16733 break;
16734 }
16735 }
16736
16737 if (attr)
16738 {
16739 printf (" Tag_%s: ", attr->name);
16740 switch (attr->type)
16741 {
16742 case 0:
16743 switch (tag)
16744 {
16745 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16746 READ_ULEB (val, p, end);
11c1ff18
PB
16747 switch (val)
16748 {
2b692964
NC
16749 case 0: printf (_("None\n")); break;
16750 case 'A': printf (_("Application\n")); break;
16751 case 'R': printf (_("Realtime\n")); break;
16752 case 'M': printf (_("Microcontroller\n")); break;
16753 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16754 default: printf ("??? (%d)\n", val); break;
16755 }
16756 break;
16757
75375b3e 16758 case 24: /* Tag_align_needed. */
cd30bcef 16759 READ_ULEB (val, p, end);
75375b3e
MGD
16760 switch (val)
16761 {
2b692964
NC
16762 case 0: printf (_("None\n")); break;
16763 case 1: printf (_("8-byte\n")); break;
16764 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16765 case 3: printf ("??? 3\n"); break;
16766 default:
16767 if (val <= 12)
dd24e3da 16768 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16769 1 << val);
16770 else
16771 printf ("??? (%d)\n", val);
16772 break;
16773 }
16774 break;
16775
16776 case 25: /* Tag_align_preserved. */
cd30bcef 16777 READ_ULEB (val, p, end);
75375b3e
MGD
16778 switch (val)
16779 {
2b692964
NC
16780 case 0: printf (_("None\n")); break;
16781 case 1: printf (_("8-byte, except leaf SP\n")); break;
16782 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16783 case 3: printf ("??? 3\n"); break;
16784 default:
16785 if (val <= 12)
dd24e3da 16786 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16787 1 << val);
16788 else
16789 printf ("??? (%d)\n", val);
16790 break;
16791 }
16792 break;
16793
11c1ff18 16794 case 32: /* Tag_compatibility. */
071436c6 16795 {
cd30bcef 16796 READ_ULEB (val, p, end);
071436c6 16797 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16798 if (p < end - 1)
16799 {
16800 size_t maxlen = (end - p) - 1;
16801
16802 print_symbol ((int) maxlen, (const char *) p);
16803 p += strnlen ((char *) p, maxlen) + 1;
16804 }
16805 else
16806 {
16807 printf (_("<corrupt>"));
16808 p = (unsigned char *) end;
16809 }
071436c6 16810 putchar ('\n');
071436c6 16811 }
11c1ff18
PB
16812 break;
16813
f5f53991 16814 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16815 /* PR 17531: file: 001-505008-0.01. */
16816 if (p < end)
16817 p++;
2b692964 16818 printf (_("True\n"));
f5f53991
AS
16819 break;
16820
16821 case 65: /* Tag_also_compatible_with. */
cd30bcef 16822 READ_ULEB (val, p, end);
f5f53991
AS
16823 if (val == 6 /* Tag_CPU_arch. */)
16824 {
cd30bcef 16825 READ_ULEB (val, p, end);
071436c6 16826 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16827 printf ("??? (%d)\n", val);
16828 else
16829 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16830 }
16831 else
16832 printf ("???\n");
071436c6
NC
16833 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16834 ;
f5f53991
AS
16835 break;
16836
11c1ff18 16837 default:
bee0ee85
NC
16838 printf (_("<unknown: %d>\n"), tag);
16839 break;
11c1ff18
PB
16840 }
16841 return p;
16842
16843 case 1:
f6f0e17b 16844 return display_tag_value (-1, p, end);
11c1ff18 16845 case 2:
f6f0e17b 16846 return display_tag_value (0, p, end);
11c1ff18
PB
16847
16848 default:
16849 assert (attr->type & 0x80);
cd30bcef 16850 READ_ULEB (val, p, end);
11c1ff18
PB
16851 type = attr->type & 0x7f;
16852 if (val >= type)
16853 printf ("??? (%d)\n", val);
16854 else
16855 printf ("%s\n", attr->table[val]);
16856 return p;
16857 }
16858 }
11c1ff18 16859
f6f0e17b 16860 return display_tag_value (tag, p, end);
11c1ff18
PB
16861}
16862
104d59d1 16863static unsigned char *
60bca95a 16864display_gnu_attribute (unsigned char * p,
60abdbed 16865 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16866 const unsigned char * const end)
104d59d1 16867{
cd30bcef 16868 unsigned int tag;
60abdbed 16869 unsigned int val;
104d59d1 16870
cd30bcef 16871 READ_ULEB (tag, p, end);
104d59d1
JM
16872
16873 /* Tag_compatibility is the only generic GNU attribute defined at
16874 present. */
16875 if (tag == 32)
16876 {
cd30bcef 16877 READ_ULEB (val, p, end);
071436c6
NC
16878
16879 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16880 if (p == end)
16881 {
071436c6 16882 printf (_("<corrupt>\n"));
f6f0e17b
NC
16883 warn (_("corrupt vendor attribute\n"));
16884 }
16885 else
16886 {
4082ef84
NC
16887 if (p < end - 1)
16888 {
16889 size_t maxlen = (end - p) - 1;
071436c6 16890
4082ef84
NC
16891 print_symbol ((int) maxlen, (const char *) p);
16892 p += strnlen ((char *) p, maxlen) + 1;
16893 }
16894 else
16895 {
16896 printf (_("<corrupt>"));
16897 p = (unsigned char *) end;
16898 }
071436c6 16899 putchar ('\n');
f6f0e17b 16900 }
104d59d1
JM
16901 return p;
16902 }
16903
16904 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16905 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16906
f6f0e17b 16907 return display_tag_value (tag, p, end);
104d59d1
JM
16908}
16909
85f7484a
PB
16910static unsigned char *
16911display_m68k_gnu_attribute (unsigned char * p,
16912 unsigned int tag,
16913 const unsigned char * const end)
16914{
16915 unsigned int val;
16916
16917 if (tag == Tag_GNU_M68K_ABI_FP)
16918 {
16919 printf (" Tag_GNU_M68K_ABI_FP: ");
16920 if (p == end)
16921 {
16922 printf (_("<corrupt>\n"));
16923 return p;
16924 }
16925 READ_ULEB (val, p, end);
16926
16927 if (val > 3)
16928 printf ("(%#x), ", val);
16929
16930 switch (val & 3)
16931 {
16932 case 0:
16933 printf (_("unspecified hard/soft float\n"));
16934 break;
16935 case 1:
16936 printf (_("hard float\n"));
16937 break;
16938 case 2:
16939 printf (_("soft float\n"));
16940 break;
16941 }
16942 return p;
16943 }
16944
16945 return display_tag_value (tag & 1, p, end);
16946}
16947
34c8bcba 16948static unsigned char *
f6f0e17b 16949display_power_gnu_attribute (unsigned char * p,
60abdbed 16950 unsigned int tag,
f6f0e17b 16951 const unsigned char * const end)
34c8bcba 16952{
005d79fd 16953 unsigned int val;
34c8bcba
JM
16954
16955 if (tag == Tag_GNU_Power_ABI_FP)
16956 {
34c8bcba 16957 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16958 if (p == end)
005d79fd
AM
16959 {
16960 printf (_("<corrupt>\n"));
16961 return p;
16962 }
cd30bcef 16963 READ_ULEB (val, p, end);
60bca95a 16964
005d79fd
AM
16965 if (val > 15)
16966 printf ("(%#x), ", val);
16967
16968 switch (val & 3)
34c8bcba
JM
16969 {
16970 case 0:
005d79fd 16971 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16972 break;
16973 case 1:
005d79fd 16974 printf (_("hard float, "));
34c8bcba
JM
16975 break;
16976 case 2:
005d79fd 16977 printf (_("soft float, "));
34c8bcba 16978 break;
3c7b9897 16979 case 3:
005d79fd 16980 printf (_("single-precision hard float, "));
3c7b9897 16981 break;
005d79fd
AM
16982 }
16983
16984 switch (val & 0xC)
16985 {
16986 case 0:
16987 printf (_("unspecified long double\n"));
16988 break;
16989 case 4:
16990 printf (_("128-bit IBM long double\n"));
16991 break;
16992 case 8:
16993 printf (_("64-bit long double\n"));
16994 break;
16995 case 12:
16996 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16997 break;
16998 }
16999 return p;
005d79fd 17000 }
34c8bcba 17001
c6e65352
DJ
17002 if (tag == Tag_GNU_Power_ABI_Vector)
17003 {
c6e65352 17004 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17005 if (p == end)
005d79fd
AM
17006 {
17007 printf (_("<corrupt>\n"));
17008 return p;
17009 }
cd30bcef 17010 READ_ULEB (val, p, end);
005d79fd
AM
17011
17012 if (val > 3)
17013 printf ("(%#x), ", val);
17014
17015 switch (val & 3)
c6e65352
DJ
17016 {
17017 case 0:
005d79fd 17018 printf (_("unspecified\n"));
c6e65352
DJ
17019 break;
17020 case 1:
005d79fd 17021 printf (_("generic\n"));
c6e65352
DJ
17022 break;
17023 case 2:
17024 printf ("AltiVec\n");
17025 break;
17026 case 3:
17027 printf ("SPE\n");
17028 break;
c6e65352
DJ
17029 }
17030 return p;
005d79fd 17031 }
c6e65352 17032
f82e0623
NF
17033 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17034 {
005d79fd 17035 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17036 if (p == end)
f6f0e17b 17037 {
005d79fd 17038 printf (_("<corrupt>\n"));
f6f0e17b
NC
17039 return p;
17040 }
cd30bcef 17041 READ_ULEB (val, p, end);
0b4362b0 17042
005d79fd
AM
17043 if (val > 2)
17044 printf ("(%#x), ", val);
17045
17046 switch (val & 3)
17047 {
17048 case 0:
17049 printf (_("unspecified\n"));
17050 break;
17051 case 1:
17052 printf ("r3/r4\n");
17053 break;
17054 case 2:
17055 printf (_("memory\n"));
17056 break;
17057 case 3:
17058 printf ("???\n");
17059 break;
17060 }
f82e0623
NF
17061 return p;
17062 }
17063
f6f0e17b 17064 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17065}
17066
643f7afb
AK
17067static unsigned char *
17068display_s390_gnu_attribute (unsigned char * p,
60abdbed 17069 unsigned int tag,
643f7afb
AK
17070 const unsigned char * const end)
17071{
cd30bcef 17072 unsigned int val;
643f7afb
AK
17073
17074 if (tag == Tag_GNU_S390_ABI_Vector)
17075 {
643f7afb 17076 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17077 READ_ULEB (val, p, end);
643f7afb
AK
17078
17079 switch (val)
17080 {
17081 case 0:
17082 printf (_("any\n"));
17083 break;
17084 case 1:
17085 printf (_("software\n"));
17086 break;
17087 case 2:
17088 printf (_("hardware\n"));
17089 break;
17090 default:
17091 printf ("??? (%d)\n", val);
17092 break;
17093 }
17094 return p;
17095 }
17096
17097 return display_tag_value (tag & 1, p, end);
17098}
17099
9e8c70f9 17100static void
60abdbed 17101display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17102{
17103 if (mask)
17104 {
015dc7e1 17105 bool first = true;
071436c6 17106
9e8c70f9 17107 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17108 fputs ("mul32", stdout), first = false;
9e8c70f9 17109 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17110 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17111 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17112 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17113 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17114 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17115 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17116 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17117 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17118 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17119 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17120 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17121 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17122 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17123 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17124 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17125 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17126 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17127 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17128 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17129 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17130 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17131 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17132 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17133 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17134 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17135 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17136 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17137 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17138 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17139 }
17140 else
071436c6
NC
17141 fputc ('0', stdout);
17142 fputc ('\n', stdout);
9e8c70f9
DM
17143}
17144
3d68f91c 17145static void
60abdbed 17146display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17147{
17148 if (mask)
17149 {
015dc7e1 17150 bool first = true;
071436c6 17151
3d68f91c 17152 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17153 fputs ("fjathplus", stdout), first = false;
3d68f91c 17154 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17155 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17156 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17157 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17158 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17159 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17160 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17161 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17162 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17163 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17164 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17165 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17166 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17167 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17168 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17169 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17170 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17171 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17172 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17173 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17174 }
17175 else
071436c6
NC
17176 fputc ('0', stdout);
17177 fputc ('\n', stdout);
3d68f91c
JM
17178}
17179
9e8c70f9 17180static unsigned char *
f6f0e17b 17181display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17182 unsigned int tag,
f6f0e17b 17183 const unsigned char * const end)
9e8c70f9 17184{
cd30bcef 17185 unsigned int val;
3d68f91c 17186
9e8c70f9
DM
17187 if (tag == Tag_GNU_Sparc_HWCAPS)
17188 {
cd30bcef 17189 READ_ULEB (val, p, end);
9e8c70f9 17190 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17191 display_sparc_hwcaps (val);
17192 return p;
3d68f91c
JM
17193 }
17194 if (tag == Tag_GNU_Sparc_HWCAPS2)
17195 {
cd30bcef 17196 READ_ULEB (val, p, end);
3d68f91c
JM
17197 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17198 display_sparc_hwcaps2 (val);
17199 return p;
17200 }
9e8c70f9 17201
f6f0e17b 17202 return display_tag_value (tag, p, end);
9e8c70f9
DM
17203}
17204
351cdf24 17205static void
32ec8896 17206print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17207{
17208 switch (val)
17209 {
17210 case Val_GNU_MIPS_ABI_FP_ANY:
17211 printf (_("Hard or soft float\n"));
17212 break;
17213 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17214 printf (_("Hard float (double precision)\n"));
17215 break;
17216 case Val_GNU_MIPS_ABI_FP_SINGLE:
17217 printf (_("Hard float (single precision)\n"));
17218 break;
17219 case Val_GNU_MIPS_ABI_FP_SOFT:
17220 printf (_("Soft float\n"));
17221 break;
17222 case Val_GNU_MIPS_ABI_FP_OLD_64:
17223 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17224 break;
17225 case Val_GNU_MIPS_ABI_FP_XX:
17226 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17227 break;
17228 case Val_GNU_MIPS_ABI_FP_64:
17229 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17230 break;
17231 case Val_GNU_MIPS_ABI_FP_64A:
17232 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17233 break;
3350cc01
CM
17234 case Val_GNU_MIPS_ABI_FP_NAN2008:
17235 printf (_("NaN 2008 compatibility\n"));
17236 break;
351cdf24
MF
17237 default:
17238 printf ("??? (%d)\n", val);
17239 break;
17240 }
17241}
17242
2cf19d5c 17243static unsigned char *
f6f0e17b 17244display_mips_gnu_attribute (unsigned char * p,
60abdbed 17245 unsigned int tag,
f6f0e17b 17246 const unsigned char * const end)
2cf19d5c 17247{
2cf19d5c
JM
17248 if (tag == Tag_GNU_MIPS_ABI_FP)
17249 {
32ec8896 17250 unsigned int val;
f6f0e17b 17251
2cf19d5c 17252 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17253 READ_ULEB (val, p, end);
351cdf24 17254 print_mips_fp_abi_value (val);
2cf19d5c
JM
17255 return p;
17256 }
17257
a9f58168
CF
17258 if (tag == Tag_GNU_MIPS_ABI_MSA)
17259 {
32ec8896 17260 unsigned int val;
a9f58168 17261
a9f58168 17262 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17263 READ_ULEB (val, p, end);
a9f58168
CF
17264
17265 switch (val)
17266 {
17267 case Val_GNU_MIPS_ABI_MSA_ANY:
17268 printf (_("Any MSA or not\n"));
17269 break;
17270 case Val_GNU_MIPS_ABI_MSA_128:
17271 printf (_("128-bit MSA\n"));
17272 break;
17273 default:
17274 printf ("??? (%d)\n", val);
17275 break;
17276 }
17277 return p;
17278 }
17279
f6f0e17b 17280 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17281}
17282
59e6276b 17283static unsigned char *
f6f0e17b
NC
17284display_tic6x_attribute (unsigned char * p,
17285 const unsigned char * const end)
59e6276b 17286{
60abdbed 17287 unsigned int tag;
cd30bcef 17288 unsigned int val;
59e6276b 17289
cd30bcef 17290 READ_ULEB (tag, p, end);
59e6276b
JM
17291
17292 switch (tag)
17293 {
75fa6dc1 17294 case Tag_ISA:
75fa6dc1 17295 printf (" Tag_ISA: ");
cd30bcef 17296 READ_ULEB (val, p, end);
59e6276b
JM
17297
17298 switch (val)
17299 {
75fa6dc1 17300 case C6XABI_Tag_ISA_none:
59e6276b
JM
17301 printf (_("None\n"));
17302 break;
75fa6dc1 17303 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17304 printf ("C62x\n");
17305 break;
75fa6dc1 17306 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17307 printf ("C67x\n");
17308 break;
75fa6dc1 17309 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17310 printf ("C67x+\n");
17311 break;
75fa6dc1 17312 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17313 printf ("C64x\n");
17314 break;
75fa6dc1 17315 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17316 printf ("C64x+\n");
17317 break;
75fa6dc1 17318 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17319 printf ("C674x\n");
17320 break;
17321 default:
17322 printf ("??? (%d)\n", val);
17323 break;
17324 }
17325 return p;
17326
87779176 17327 case Tag_ABI_wchar_t:
87779176 17328 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17329 READ_ULEB (val, p, end);
87779176
JM
17330 switch (val)
17331 {
17332 case 0:
17333 printf (_("Not used\n"));
17334 break;
17335 case 1:
17336 printf (_("2 bytes\n"));
17337 break;
17338 case 2:
17339 printf (_("4 bytes\n"));
17340 break;
17341 default:
17342 printf ("??? (%d)\n", val);
17343 break;
17344 }
17345 return p;
17346
17347 case Tag_ABI_stack_align_needed:
87779176 17348 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17349 READ_ULEB (val, p, end);
87779176
JM
17350 switch (val)
17351 {
17352 case 0:
17353 printf (_("8-byte\n"));
17354 break;
17355 case 1:
17356 printf (_("16-byte\n"));
17357 break;
17358 default:
17359 printf ("??? (%d)\n", val);
17360 break;
17361 }
17362 return p;
17363
17364 case Tag_ABI_stack_align_preserved:
cd30bcef 17365 READ_ULEB (val, p, end);
87779176
JM
17366 printf (" Tag_ABI_stack_align_preserved: ");
17367 switch (val)
17368 {
17369 case 0:
17370 printf (_("8-byte\n"));
17371 break;
17372 case 1:
17373 printf (_("16-byte\n"));
17374 break;
17375 default:
17376 printf ("??? (%d)\n", val);
17377 break;
17378 }
17379 return p;
17380
b5593623 17381 case Tag_ABI_DSBT:
cd30bcef 17382 READ_ULEB (val, p, end);
b5593623
JM
17383 printf (" Tag_ABI_DSBT: ");
17384 switch (val)
17385 {
17386 case 0:
17387 printf (_("DSBT addressing not used\n"));
17388 break;
17389 case 1:
17390 printf (_("DSBT addressing used\n"));
17391 break;
17392 default:
17393 printf ("??? (%d)\n", val);
17394 break;
17395 }
17396 return p;
17397
87779176 17398 case Tag_ABI_PID:
cd30bcef 17399 READ_ULEB (val, p, end);
87779176
JM
17400 printf (" Tag_ABI_PID: ");
17401 switch (val)
17402 {
17403 case 0:
17404 printf (_("Data addressing position-dependent\n"));
17405 break;
17406 case 1:
17407 printf (_("Data addressing position-independent, GOT near DP\n"));
17408 break;
17409 case 2:
17410 printf (_("Data addressing position-independent, GOT far from DP\n"));
17411 break;
17412 default:
17413 printf ("??? (%d)\n", val);
17414 break;
17415 }
17416 return p;
17417
17418 case Tag_ABI_PIC:
cd30bcef 17419 READ_ULEB (val, p, end);
87779176
JM
17420 printf (" Tag_ABI_PIC: ");
17421 switch (val)
17422 {
17423 case 0:
17424 printf (_("Code addressing position-dependent\n"));
17425 break;
17426 case 1:
17427 printf (_("Code addressing position-independent\n"));
17428 break;
17429 default:
17430 printf ("??? (%d)\n", val);
17431 break;
17432 }
17433 return p;
17434
17435 case Tag_ABI_array_object_alignment:
cd30bcef 17436 READ_ULEB (val, p, end);
87779176
JM
17437 printf (" Tag_ABI_array_object_alignment: ");
17438 switch (val)
17439 {
17440 case 0:
17441 printf (_("8-byte\n"));
17442 break;
17443 case 1:
17444 printf (_("4-byte\n"));
17445 break;
17446 case 2:
17447 printf (_("16-byte\n"));
17448 break;
17449 default:
17450 printf ("??? (%d)\n", val);
17451 break;
17452 }
17453 return p;
17454
17455 case Tag_ABI_array_object_align_expected:
cd30bcef 17456 READ_ULEB (val, p, end);
87779176
JM
17457 printf (" Tag_ABI_array_object_align_expected: ");
17458 switch (val)
17459 {
17460 case 0:
17461 printf (_("8-byte\n"));
17462 break;
17463 case 1:
17464 printf (_("4-byte\n"));
17465 break;
17466 case 2:
17467 printf (_("16-byte\n"));
17468 break;
17469 default:
17470 printf ("??? (%d)\n", val);
17471 break;
17472 }
17473 return p;
17474
3cbd1c06 17475 case Tag_ABI_compatibility:
071436c6 17476 {
cd30bcef 17477 READ_ULEB (val, p, end);
071436c6 17478 printf (" Tag_ABI_compatibility: ");
071436c6 17479 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17480 if (p < end - 1)
17481 {
17482 size_t maxlen = (end - p) - 1;
17483
17484 print_symbol ((int) maxlen, (const char *) p);
17485 p += strnlen ((char *) p, maxlen) + 1;
17486 }
17487 else
17488 {
17489 printf (_("<corrupt>"));
17490 p = (unsigned char *) end;
17491 }
071436c6 17492 putchar ('\n');
071436c6
NC
17493 return p;
17494 }
87779176
JM
17495
17496 case Tag_ABI_conformance:
071436c6 17497 {
4082ef84
NC
17498 printf (" Tag_ABI_conformance: \"");
17499 if (p < end - 1)
17500 {
17501 size_t maxlen = (end - p) - 1;
071436c6 17502
4082ef84
NC
17503 print_symbol ((int) maxlen, (const char *) p);
17504 p += strnlen ((char *) p, maxlen) + 1;
17505 }
17506 else
17507 {
17508 printf (_("<corrupt>"));
17509 p = (unsigned char *) end;
17510 }
071436c6 17511 printf ("\"\n");
071436c6
NC
17512 return p;
17513 }
59e6276b
JM
17514 }
17515
f6f0e17b
NC
17516 return display_tag_value (tag, p, end);
17517}
59e6276b 17518
f6f0e17b 17519static void
60abdbed 17520display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17521{
17522 unsigned long addr = 0;
17523 size_t bytes = end - p;
17524
feceaa59 17525 assert (end >= p);
f6f0e17b 17526 while (bytes)
87779176 17527 {
f6f0e17b
NC
17528 int j;
17529 int k;
17530 int lbytes = (bytes > 16 ? 16 : bytes);
17531
17532 printf (" 0x%8.8lx ", addr);
17533
17534 for (j = 0; j < 16; j++)
17535 {
17536 if (j < lbytes)
17537 printf ("%2.2x", p[j]);
17538 else
17539 printf (" ");
17540
17541 if ((j & 3) == 3)
17542 printf (" ");
17543 }
17544
17545 for (j = 0; j < lbytes; j++)
17546 {
17547 k = p[j];
17548 if (k >= ' ' && k < 0x7f)
17549 printf ("%c", k);
17550 else
17551 printf (".");
17552 }
17553
17554 putchar ('\n');
17555
17556 p += lbytes;
17557 bytes -= lbytes;
17558 addr += lbytes;
87779176 17559 }
59e6276b 17560
f6f0e17b 17561 putchar ('\n');
59e6276b
JM
17562}
17563
13761a11 17564static unsigned char *
b0191216 17565display_msp430_attribute (unsigned char * p,
13761a11
NC
17566 const unsigned char * const end)
17567{
60abdbed
NC
17568 unsigned int val;
17569 unsigned int tag;
13761a11 17570
cd30bcef 17571 READ_ULEB (tag, p, end);
0b4362b0 17572
13761a11
NC
17573 switch (tag)
17574 {
17575 case OFBA_MSPABI_Tag_ISA:
13761a11 17576 printf (" Tag_ISA: ");
cd30bcef 17577 READ_ULEB (val, p, end);
13761a11
NC
17578 switch (val)
17579 {
17580 case 0: printf (_("None\n")); break;
17581 case 1: printf (_("MSP430\n")); break;
17582 case 2: printf (_("MSP430X\n")); break;
17583 default: printf ("??? (%d)\n", val); break;
17584 }
17585 break;
17586
17587 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17588 printf (" Tag_Code_Model: ");
cd30bcef 17589 READ_ULEB (val, p, end);
13761a11
NC
17590 switch (val)
17591 {
17592 case 0: printf (_("None\n")); break;
17593 case 1: printf (_("Small\n")); break;
17594 case 2: printf (_("Large\n")); break;
17595 default: printf ("??? (%d)\n", val); break;
17596 }
17597 break;
17598
17599 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17600 printf (" Tag_Data_Model: ");
cd30bcef 17601 READ_ULEB (val, p, end);
13761a11
NC
17602 switch (val)
17603 {
17604 case 0: printf (_("None\n")); break;
17605 case 1: printf (_("Small\n")); break;
17606 case 2: printf (_("Large\n")); break;
17607 case 3: printf (_("Restricted Large\n")); break;
17608 default: printf ("??? (%d)\n", val); break;
17609 }
17610 break;
17611
17612 default:
17613 printf (_(" <unknown tag %d>: "), tag);
17614
17615 if (tag & 1)
17616 {
071436c6 17617 putchar ('"');
4082ef84
NC
17618 if (p < end - 1)
17619 {
17620 size_t maxlen = (end - p) - 1;
17621
17622 print_symbol ((int) maxlen, (const char *) p);
17623 p += strnlen ((char *) p, maxlen) + 1;
17624 }
17625 else
17626 {
17627 printf (_("<corrupt>"));
17628 p = (unsigned char *) end;
17629 }
071436c6 17630 printf ("\"\n");
13761a11
NC
17631 }
17632 else
17633 {
cd30bcef 17634 READ_ULEB (val, p, end);
13761a11
NC
17635 printf ("%d (0x%x)\n", val, val);
17636 }
17637 break;
17638 }
17639
4082ef84 17640 assert (p <= end);
13761a11
NC
17641 return p;
17642}
17643
c0ea7c52
JL
17644static unsigned char *
17645display_msp430_gnu_attribute (unsigned char * p,
17646 unsigned int tag,
17647 const unsigned char * const end)
17648{
17649 if (tag == Tag_GNU_MSP430_Data_Region)
17650 {
cd30bcef 17651 unsigned int val;
c0ea7c52 17652
c0ea7c52 17653 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17654 READ_ULEB (val, p, end);
c0ea7c52
JL
17655
17656 switch (val)
17657 {
17658 case Val_GNU_MSP430_Data_Region_Any:
17659 printf (_("Any Region\n"));
17660 break;
17661 case Val_GNU_MSP430_Data_Region_Lower:
17662 printf (_("Lower Region Only\n"));
17663 break;
17664 default:
cd30bcef 17665 printf ("??? (%u)\n", val);
c0ea7c52
JL
17666 }
17667 return p;
17668 }
17669 return display_tag_value (tag & 1, p, end);
17670}
17671
2dc8dd17
JW
17672struct riscv_attr_tag_t {
17673 const char *name;
cd30bcef 17674 unsigned int tag;
2dc8dd17
JW
17675};
17676
17677static struct riscv_attr_tag_t riscv_attr_tag[] =
17678{
17679#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17680 T(arch),
17681 T(priv_spec),
17682 T(priv_spec_minor),
17683 T(priv_spec_revision),
17684 T(unaligned_access),
17685 T(stack_align),
17686#undef T
17687};
17688
17689static unsigned char *
17690display_riscv_attribute (unsigned char *p,
17691 const unsigned char * const end)
17692{
cd30bcef
AM
17693 unsigned int val;
17694 unsigned int tag;
2dc8dd17
JW
17695 struct riscv_attr_tag_t *attr = NULL;
17696 unsigned i;
17697
cd30bcef 17698 READ_ULEB (tag, p, end);
2dc8dd17
JW
17699
17700 /* Find the name of attribute. */
17701 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17702 {
17703 if (riscv_attr_tag[i].tag == tag)
17704 {
17705 attr = &riscv_attr_tag[i];
17706 break;
17707 }
17708 }
17709
17710 if (attr)
17711 printf (" %s: ", attr->name);
17712 else
17713 return display_tag_value (tag, p, end);
17714
17715 switch (tag)
17716 {
17717 case Tag_RISCV_priv_spec:
17718 case Tag_RISCV_priv_spec_minor:
17719 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17720 READ_ULEB (val, p, end);
17721 printf (_("%u\n"), val);
2dc8dd17
JW
17722 break;
17723 case Tag_RISCV_unaligned_access:
cd30bcef 17724 READ_ULEB (val, p, end);
2dc8dd17
JW
17725 switch (val)
17726 {
17727 case 0:
17728 printf (_("No unaligned access\n"));
17729 break;
17730 case 1:
17731 printf (_("Unaligned access\n"));
17732 break;
17733 }
17734 break;
17735 case Tag_RISCV_stack_align:
cd30bcef
AM
17736 READ_ULEB (val, p, end);
17737 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17738 break;
17739 case Tag_RISCV_arch:
17740 p = display_tag_value (-1, p, end);
17741 break;
17742 default:
17743 return display_tag_value (tag, p, end);
17744 }
17745
17746 return p;
17747}
17748
0861f561
CQ
17749static unsigned char *
17750display_csky_attribute (unsigned char * p,
17751 const unsigned char * const end)
17752{
17753 unsigned int tag;
17754 unsigned int val;
17755 READ_ULEB (tag, p, end);
17756
17757 if (tag >= Tag_CSKY_MAX)
17758 {
17759 return display_tag_value (-1, p, end);
17760 }
17761
17762 switch (tag)
17763 {
17764 case Tag_CSKY_ARCH_NAME:
17765 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17766 return display_tag_value (-1, p, end);
17767 case Tag_CSKY_CPU_NAME:
17768 printf (" Tag_CSKY_CPU_NAME:\t\t");
17769 return display_tag_value (-1, p, end);
17770
17771 case Tag_CSKY_ISA_FLAGS:
17772 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17773 return display_tag_value (0, p, end);
17774 case Tag_CSKY_ISA_EXT_FLAGS:
17775 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17776 return display_tag_value (0, p, end);
17777
17778 case Tag_CSKY_DSP_VERSION:
17779 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17780 READ_ULEB (val, p, end);
17781 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17782 printf ("DSP Extension\n");
17783 else if (val == VAL_CSKY_DSP_VERSION_2)
17784 printf ("DSP 2.0\n");
17785 break;
17786
17787 case Tag_CSKY_VDSP_VERSION:
17788 printf (" Tag_CSKY_VDSP_VERSION:\t");
17789 READ_ULEB (val, p, end);
17790 printf ("VDSP Version %d\n", val);
17791 break;
17792
17793 case Tag_CSKY_FPU_VERSION:
17794 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17795 READ_ULEB (val, p, end);
17796 if (val == VAL_CSKY_FPU_VERSION_1)
17797 printf ("ABIV1 FPU Version 1\n");
17798 else if (val == VAL_CSKY_FPU_VERSION_2)
17799 printf ("FPU Version 2\n");
17800 break;
17801
17802 case Tag_CSKY_FPU_ABI:
17803 printf (" Tag_CSKY_FPU_ABI:\t\t");
17804 READ_ULEB (val, p, end);
17805 if (val == VAL_CSKY_FPU_ABI_HARD)
17806 printf ("Hard\n");
17807 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17808 printf ("SoftFP\n");
17809 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17810 printf ("Soft\n");
17811 break;
17812 case Tag_CSKY_FPU_ROUNDING:
17813 READ_ULEB (val, p, end);
f253158f
NC
17814 if (val == 1)
17815 {
17816 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17817 printf ("Needed\n");
17818 }
0861f561
CQ
17819 break;
17820 case Tag_CSKY_FPU_DENORMAL:
17821 READ_ULEB (val, p, end);
f253158f
NC
17822 if (val == 1)
17823 {
17824 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17825 printf ("Needed\n");
17826 }
0861f561
CQ
17827 break;
17828 case Tag_CSKY_FPU_Exception:
17829 READ_ULEB (val, p, end);
f253158f
NC
17830 if (val == 1)
17831 {
17832 printf (" Tag_CSKY_FPU_Exception:\t");
17833 printf ("Needed\n");
17834 }
0861f561
CQ
17835 break;
17836 case Tag_CSKY_FPU_NUMBER_MODULE:
17837 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17838 return display_tag_value (-1, p, end);
17839 case Tag_CSKY_FPU_HARDFP:
17840 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17841 READ_ULEB (val, p, end);
17842 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17843 printf (" Half");
17844 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17845 printf (" Single");
17846 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17847 printf (" Double");
17848 printf ("\n");
17849 break;
17850 default:
17851 return display_tag_value (tag, p, end);
17852 }
17853 return p;
17854}
17855
015dc7e1 17856static bool
dda8d76d 17857process_attributes (Filedata * filedata,
60bca95a 17858 const char * public_name,
104d59d1 17859 unsigned int proc_type,
f6f0e17b 17860 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17861 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17862{
2cf0635d 17863 Elf_Internal_Shdr * sect;
11c1ff18 17864 unsigned i;
015dc7e1 17865 bool res = true;
11c1ff18
PB
17866
17867 /* Find the section header so that we get the size. */
dda8d76d
NC
17868 for (i = 0, sect = filedata->section_headers;
17869 i < filedata->file_header.e_shnum;
11c1ff18
PB
17870 i++, sect++)
17871 {
071436c6
NC
17872 unsigned char * contents;
17873 unsigned char * p;
17874
104d59d1 17875 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17876 continue;
17877
dda8d76d 17878 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17879 sect->sh_size, _("attributes"));
60bca95a 17880 if (contents == NULL)
32ec8896 17881 {
015dc7e1 17882 res = false;
32ec8896
NC
17883 continue;
17884 }
60bca95a 17885
11c1ff18 17886 p = contents;
60abdbed
NC
17887 /* The first character is the version of the attributes.
17888 Currently only version 1, (aka 'A') is recognised here. */
17889 if (*p != 'A')
32ec8896
NC
17890 {
17891 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17892 res = false;
32ec8896 17893 }
60abdbed 17894 else
11c1ff18 17895 {
071436c6
NC
17896 bfd_vma section_len;
17897
17898 section_len = sect->sh_size - 1;
11c1ff18 17899 p++;
60bca95a 17900
071436c6 17901 while (section_len > 0)
11c1ff18 17902 {
071436c6 17903 bfd_vma attr_len;
e9847026 17904 unsigned int namelen;
015dc7e1
AM
17905 bool public_section;
17906 bool gnu_section;
11c1ff18 17907
071436c6 17908 if (section_len <= 4)
e0a31db1
NC
17909 {
17910 error (_("Tag section ends prematurely\n"));
015dc7e1 17911 res = false;
e0a31db1
NC
17912 break;
17913 }
071436c6 17914 attr_len = byte_get (p, 4);
11c1ff18 17915 p += 4;
60bca95a 17916
071436c6 17917 if (attr_len > section_len)
11c1ff18 17918 {
071436c6
NC
17919 error (_("Bad attribute length (%u > %u)\n"),
17920 (unsigned) attr_len, (unsigned) section_len);
17921 attr_len = section_len;
015dc7e1 17922 res = false;
11c1ff18 17923 }
74e1a04b 17924 /* PR 17531: file: 001-101425-0.004 */
071436c6 17925 else if (attr_len < 5)
74e1a04b 17926 {
071436c6 17927 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17928 res = false;
74e1a04b
NC
17929 break;
17930 }
e9847026 17931
071436c6
NC
17932 section_len -= attr_len;
17933 attr_len -= 4;
17934
17935 namelen = strnlen ((char *) p, attr_len) + 1;
17936 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17937 {
17938 error (_("Corrupt attribute section name\n"));
015dc7e1 17939 res = false;
e9847026
NC
17940 break;
17941 }
17942
071436c6
NC
17943 printf (_("Attribute Section: "));
17944 print_symbol (INT_MAX, (const char *) p);
17945 putchar ('\n');
60bca95a
NC
17946
17947 if (public_name && streq ((char *) p, public_name))
015dc7e1 17948 public_section = true;
11c1ff18 17949 else
015dc7e1 17950 public_section = false;
60bca95a
NC
17951
17952 if (streq ((char *) p, "gnu"))
015dc7e1 17953 gnu_section = true;
104d59d1 17954 else
015dc7e1 17955 gnu_section = false;
60bca95a 17956
11c1ff18 17957 p += namelen;
071436c6 17958 attr_len -= namelen;
e0a31db1 17959
071436c6 17960 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17961 {
e0a31db1 17962 int tag;
cd30bcef 17963 unsigned int val;
11c1ff18 17964 bfd_vma size;
071436c6 17965 unsigned char * end;
60bca95a 17966
e0a31db1 17967 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17968 if (attr_len < 6)
e0a31db1
NC
17969 {
17970 error (_("Unused bytes at end of section\n"));
015dc7e1 17971 res = false;
e0a31db1
NC
17972 section_len = 0;
17973 break;
17974 }
17975
17976 tag = *(p++);
11c1ff18 17977 size = byte_get (p, 4);
071436c6 17978 if (size > attr_len)
11c1ff18 17979 {
e9847026 17980 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17981 (unsigned) size, (unsigned) attr_len);
015dc7e1 17982 res = false;
071436c6 17983 size = attr_len;
11c1ff18 17984 }
e0a31db1
NC
17985 /* PR binutils/17531: Safe handling of corrupt files. */
17986 if (size < 6)
17987 {
17988 error (_("Bad subsection length (%u < 6)\n"),
17989 (unsigned) size);
015dc7e1 17990 res = false;
e0a31db1
NC
17991 section_len = 0;
17992 break;
17993 }
60bca95a 17994
071436c6 17995 attr_len -= size;
11c1ff18 17996 end = p + size - 1;
071436c6 17997 assert (end <= contents + sect->sh_size);
11c1ff18 17998 p += 4;
60bca95a 17999
11c1ff18
PB
18000 switch (tag)
18001 {
18002 case 1:
2b692964 18003 printf (_("File Attributes\n"));
11c1ff18
PB
18004 break;
18005 case 2:
2b692964 18006 printf (_("Section Attributes:"));
11c1ff18
PB
18007 goto do_numlist;
18008 case 3:
2b692964 18009 printf (_("Symbol Attributes:"));
1a0670f3 18010 /* Fall through. */
11c1ff18
PB
18011 do_numlist:
18012 for (;;)
18013 {
cd30bcef 18014 READ_ULEB (val, p, end);
11c1ff18
PB
18015 if (val == 0)
18016 break;
18017 printf (" %d", val);
18018 }
18019 printf ("\n");
18020 break;
18021 default:
2b692964 18022 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18023 public_section = false;
11c1ff18
PB
18024 break;
18025 }
60bca95a 18026
071436c6 18027 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18028 {
18029 while (p < end)
f6f0e17b 18030 p = display_pub_attribute (p, end);
60abdbed 18031 assert (p == end);
104d59d1 18032 }
071436c6 18033 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18034 {
18035 while (p < end)
18036 p = display_gnu_attribute (p,
f6f0e17b
NC
18037 display_proc_gnu_attribute,
18038 end);
60abdbed 18039 assert (p == end);
11c1ff18 18040 }
071436c6 18041 else if (p < end)
11c1ff18 18042 {
071436c6 18043 printf (_(" Unknown attribute:\n"));
f6f0e17b 18044 display_raw_attribute (p, end);
11c1ff18
PB
18045 p = end;
18046 }
071436c6
NC
18047 else
18048 attr_len = 0;
11c1ff18
PB
18049 }
18050 }
18051 }
d70c5fc7 18052
60bca95a 18053 free (contents);
11c1ff18 18054 }
32ec8896
NC
18055
18056 return res;
11c1ff18
PB
18057}
18058
ccb4c951
RS
18059/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18060 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18061 and return the VMA of the next entry, or -1 if there was a problem.
18062 Does not read from DATA_END or beyond. */
ccb4c951
RS
18063
18064static bfd_vma
82b1b41b
NC
18065print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
18066 unsigned char * data_end)
ccb4c951
RS
18067{
18068 printf (" ");
18069 print_vma (addr, LONG_HEX);
18070 printf (" ");
18071 if (addr < pltgot + 0xfff0)
18072 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18073 else
18074 printf ("%10s", "");
18075 printf (" ");
18076 if (data == NULL)
2b692964 18077 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18078 else
18079 {
18080 bfd_vma entry;
82b1b41b 18081 unsigned char * from = data + addr - pltgot;
ccb4c951 18082
82b1b41b
NC
18083 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18084 {
18085 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18086 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18087 return (bfd_vma) -1;
18088 }
18089 else
18090 {
18091 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18092 print_vma (entry, LONG_HEX);
18093 }
ccb4c951
RS
18094 }
18095 return addr + (is_32bit_elf ? 4 : 8);
18096}
18097
861fb55a
DJ
18098/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18099 PLTGOT. Print the Address and Initial fields of an entry at VMA
18100 ADDR and return the VMA of the next entry. */
18101
18102static bfd_vma
2cf0635d 18103print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
18104{
18105 printf (" ");
18106 print_vma (addr, LONG_HEX);
18107 printf (" ");
18108 if (data == NULL)
2b692964 18109 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18110 else
18111 {
18112 bfd_vma entry;
18113
18114 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18115 print_vma (entry, LONG_HEX);
18116 }
18117 return addr + (is_32bit_elf ? 4 : 8);
18118}
18119
351cdf24
MF
18120static void
18121print_mips_ases (unsigned int mask)
18122{
18123 if (mask & AFL_ASE_DSP)
18124 fputs ("\n\tDSP ASE", stdout);
18125 if (mask & AFL_ASE_DSPR2)
18126 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18127 if (mask & AFL_ASE_DSPR3)
18128 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18129 if (mask & AFL_ASE_EVA)
18130 fputs ("\n\tEnhanced VA Scheme", stdout);
18131 if (mask & AFL_ASE_MCU)
18132 fputs ("\n\tMCU (MicroController) ASE", stdout);
18133 if (mask & AFL_ASE_MDMX)
18134 fputs ("\n\tMDMX ASE", stdout);
18135 if (mask & AFL_ASE_MIPS3D)
18136 fputs ("\n\tMIPS-3D ASE", stdout);
18137 if (mask & AFL_ASE_MT)
18138 fputs ("\n\tMT ASE", stdout);
18139 if (mask & AFL_ASE_SMARTMIPS)
18140 fputs ("\n\tSmartMIPS ASE", stdout);
18141 if (mask & AFL_ASE_VIRT)
18142 fputs ("\n\tVZ ASE", stdout);
18143 if (mask & AFL_ASE_MSA)
18144 fputs ("\n\tMSA ASE", stdout);
18145 if (mask & AFL_ASE_MIPS16)
18146 fputs ("\n\tMIPS16 ASE", stdout);
18147 if (mask & AFL_ASE_MICROMIPS)
18148 fputs ("\n\tMICROMIPS ASE", stdout);
18149 if (mask & AFL_ASE_XPA)
18150 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18151 if (mask & AFL_ASE_MIPS16E2)
18152 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18153 if (mask & AFL_ASE_CRC)
18154 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18155 if (mask & AFL_ASE_GINV)
18156 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18157 if (mask & AFL_ASE_LOONGSON_MMI)
18158 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18159 if (mask & AFL_ASE_LOONGSON_CAM)
18160 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18161 if (mask & AFL_ASE_LOONGSON_EXT)
18162 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18163 if (mask & AFL_ASE_LOONGSON_EXT2)
18164 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18165 if (mask == 0)
18166 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18167 else if ((mask & ~AFL_ASE_MASK) != 0)
18168 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18169}
18170
18171static void
18172print_mips_isa_ext (unsigned int isa_ext)
18173{
18174 switch (isa_ext)
18175 {
18176 case 0:
18177 fputs (_("None"), stdout);
18178 break;
18179 case AFL_EXT_XLR:
18180 fputs ("RMI XLR", stdout);
18181 break;
2c629856
N
18182 case AFL_EXT_OCTEON3:
18183 fputs ("Cavium Networks Octeon3", stdout);
18184 break;
351cdf24
MF
18185 case AFL_EXT_OCTEON2:
18186 fputs ("Cavium Networks Octeon2", stdout);
18187 break;
18188 case AFL_EXT_OCTEONP:
18189 fputs ("Cavium Networks OcteonP", stdout);
18190 break;
351cdf24
MF
18191 case AFL_EXT_OCTEON:
18192 fputs ("Cavium Networks Octeon", stdout);
18193 break;
18194 case AFL_EXT_5900:
18195 fputs ("Toshiba R5900", stdout);
18196 break;
18197 case AFL_EXT_4650:
18198 fputs ("MIPS R4650", stdout);
18199 break;
18200 case AFL_EXT_4010:
18201 fputs ("LSI R4010", stdout);
18202 break;
18203 case AFL_EXT_4100:
18204 fputs ("NEC VR4100", stdout);
18205 break;
18206 case AFL_EXT_3900:
18207 fputs ("Toshiba R3900", stdout);
18208 break;
18209 case AFL_EXT_10000:
18210 fputs ("MIPS R10000", stdout);
18211 break;
18212 case AFL_EXT_SB1:
18213 fputs ("Broadcom SB-1", stdout);
18214 break;
18215 case AFL_EXT_4111:
18216 fputs ("NEC VR4111/VR4181", stdout);
18217 break;
18218 case AFL_EXT_4120:
18219 fputs ("NEC VR4120", stdout);
18220 break;
18221 case AFL_EXT_5400:
18222 fputs ("NEC VR5400", stdout);
18223 break;
18224 case AFL_EXT_5500:
18225 fputs ("NEC VR5500", stdout);
18226 break;
18227 case AFL_EXT_LOONGSON_2E:
18228 fputs ("ST Microelectronics Loongson 2E", stdout);
18229 break;
18230 case AFL_EXT_LOONGSON_2F:
18231 fputs ("ST Microelectronics Loongson 2F", stdout);
18232 break;
38bf472a
MR
18233 case AFL_EXT_INTERAPTIV_MR2:
18234 fputs ("Imagination interAptiv MR2", stdout);
18235 break;
351cdf24 18236 default:
00ac7aa0 18237 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18238 }
18239}
18240
32ec8896 18241static signed int
351cdf24
MF
18242get_mips_reg_size (int reg_size)
18243{
18244 return (reg_size == AFL_REG_NONE) ? 0
18245 : (reg_size == AFL_REG_32) ? 32
18246 : (reg_size == AFL_REG_64) ? 64
18247 : (reg_size == AFL_REG_128) ? 128
18248 : -1;
18249}
18250
015dc7e1 18251static bool
dda8d76d 18252process_mips_specific (Filedata * filedata)
5b18a4bc 18253{
2cf0635d 18254 Elf_Internal_Dyn * entry;
351cdf24 18255 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18256 size_t liblist_offset = 0;
18257 size_t liblistno = 0;
18258 size_t conflictsno = 0;
18259 size_t options_offset = 0;
18260 size_t conflicts_offset = 0;
861fb55a
DJ
18261 size_t pltrelsz = 0;
18262 size_t pltrel = 0;
ccb4c951 18263 bfd_vma pltgot = 0;
861fb55a
DJ
18264 bfd_vma mips_pltgot = 0;
18265 bfd_vma jmprel = 0;
ccb4c951
RS
18266 bfd_vma local_gotno = 0;
18267 bfd_vma gotsym = 0;
18268 bfd_vma symtabno = 0;
015dc7e1 18269 bool res = true;
103f02d3 18270
dda8d76d 18271 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18272 display_mips_gnu_attribute))
015dc7e1 18273 res = false;
2cf19d5c 18274
dda8d76d 18275 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18276
18277 if (sect != NULL)
18278 {
18279 Elf_External_ABIFlags_v0 *abiflags_ext;
18280 Elf_Internal_ABIFlags_v0 abiflags_in;
18281
18282 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18283 {
18284 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18285 res = false;
32ec8896 18286 }
351cdf24
MF
18287 else
18288 {
dda8d76d 18289 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18290 sect->sh_size, _("MIPS ABI Flags section"));
18291 if (abiflags_ext)
18292 {
18293 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18294 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18295 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18296 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18297 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18298 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18299 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18300 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18301 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18302 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18303 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18304
18305 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18306 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18307 if (abiflags_in.isa_rev > 1)
18308 printf ("r%d", abiflags_in.isa_rev);
18309 printf ("\nGPR size: %d",
18310 get_mips_reg_size (abiflags_in.gpr_size));
18311 printf ("\nCPR1 size: %d",
18312 get_mips_reg_size (abiflags_in.cpr1_size));
18313 printf ("\nCPR2 size: %d",
18314 get_mips_reg_size (abiflags_in.cpr2_size));
18315 fputs ("\nFP ABI: ", stdout);
18316 print_mips_fp_abi_value (abiflags_in.fp_abi);
18317 fputs ("ISA Extension: ", stdout);
18318 print_mips_isa_ext (abiflags_in.isa_ext);
18319 fputs ("\nASEs:", stdout);
18320 print_mips_ases (abiflags_in.ases);
18321 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18322 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18323 fputc ('\n', stdout);
18324 free (abiflags_ext);
18325 }
18326 }
18327 }
18328
19e6b90e 18329 /* We have a lot of special sections. Thanks SGI! */
978c4450 18330 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18331 {
18332 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18333 sect = find_section (filedata, ".got");
bbdd9a68
MR
18334 if (sect != NULL)
18335 {
18336 unsigned char *data_end;
18337 unsigned char *data;
18338 bfd_vma ent, end;
18339 int addr_size;
18340
18341 pltgot = sect->sh_addr;
18342
18343 ent = pltgot;
18344 addr_size = (is_32bit_elf ? 4 : 8);
18345 end = pltgot + sect->sh_size;
18346
dda8d76d 18347 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18348 end - pltgot, 1,
18349 _("Global Offset Table data"));
18350 /* PR 12855: Null data is handled gracefully throughout. */
18351 data_end = data + (end - pltgot);
18352
18353 printf (_("\nStatic GOT:\n"));
18354 printf (_(" Canonical gp value: "));
18355 print_vma (ent + 0x7ff0, LONG_HEX);
18356 printf ("\n\n");
18357
18358 /* In a dynamic binary GOT[0] is reserved for the dynamic
18359 loader to store the lazy resolver pointer, however in
18360 a static binary it may well have been omitted and GOT
18361 reduced to a table of addresses.
18362 PR 21344: Check for the entry being fully available
18363 before fetching it. */
18364 if (data
18365 && data + ent - pltgot + addr_size <= data_end
18366 && byte_get (data + ent - pltgot, addr_size) == 0)
18367 {
18368 printf (_(" Reserved entries:\n"));
18369 printf (_(" %*s %10s %*s\n"),
18370 addr_size * 2, _("Address"), _("Access"),
18371 addr_size * 2, _("Value"));
18372 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18373 printf ("\n");
18374 if (ent == (bfd_vma) -1)
18375 goto sgot_print_fail;
18376
18377 /* Check for the MSB of GOT[1] being set, identifying a
18378 GNU object. This entry will be used by some runtime
18379 loaders, to store the module pointer. Otherwise this
18380 is an ordinary local entry.
18381 PR 21344: Check for the entry being fully available
18382 before fetching it. */
18383 if (data
18384 && data + ent - pltgot + addr_size <= data_end
18385 && (byte_get (data + ent - pltgot, addr_size)
18386 >> (addr_size * 8 - 1)) != 0)
18387 {
18388 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18389 printf ("\n");
18390 if (ent == (bfd_vma) -1)
18391 goto sgot_print_fail;
18392 }
18393 printf ("\n");
18394 }
18395
f17e9d8a 18396 if (data != NULL && ent < end)
bbdd9a68
MR
18397 {
18398 printf (_(" Local entries:\n"));
18399 printf (" %*s %10s %*s\n",
18400 addr_size * 2, _("Address"), _("Access"),
18401 addr_size * 2, _("Value"));
18402 while (ent < end)
18403 {
18404 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18405 printf ("\n");
18406 if (ent == (bfd_vma) -1)
18407 goto sgot_print_fail;
18408 }
18409 printf ("\n");
18410 }
18411
18412 sgot_print_fail:
9db70fc3 18413 free (data);
bbdd9a68
MR
18414 }
18415 return res;
18416 }
252b5132 18417
978c4450 18418 for (entry = filedata->dynamic_section;
071436c6 18419 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18420 (entry < filedata->dynamic_section + filedata->dynamic_nent
18421 && entry->d_tag != DT_NULL);
071436c6 18422 ++entry)
252b5132
RH
18423 switch (entry->d_tag)
18424 {
18425 case DT_MIPS_LIBLIST:
d93f0186 18426 liblist_offset
dda8d76d 18427 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18428 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18429 break;
18430 case DT_MIPS_LIBLISTNO:
18431 liblistno = entry->d_un.d_val;
18432 break;
18433 case DT_MIPS_OPTIONS:
dda8d76d 18434 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18435 break;
18436 case DT_MIPS_CONFLICT:
d93f0186 18437 conflicts_offset
dda8d76d 18438 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18439 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18440 break;
18441 case DT_MIPS_CONFLICTNO:
18442 conflictsno = entry->d_un.d_val;
18443 break;
ccb4c951 18444 case DT_PLTGOT:
861fb55a
DJ
18445 pltgot = entry->d_un.d_ptr;
18446 break;
ccb4c951
RS
18447 case DT_MIPS_LOCAL_GOTNO:
18448 local_gotno = entry->d_un.d_val;
18449 break;
18450 case DT_MIPS_GOTSYM:
18451 gotsym = entry->d_un.d_val;
18452 break;
18453 case DT_MIPS_SYMTABNO:
18454 symtabno = entry->d_un.d_val;
18455 break;
861fb55a
DJ
18456 case DT_MIPS_PLTGOT:
18457 mips_pltgot = entry->d_un.d_ptr;
18458 break;
18459 case DT_PLTREL:
18460 pltrel = entry->d_un.d_val;
18461 break;
18462 case DT_PLTRELSZ:
18463 pltrelsz = entry->d_un.d_val;
18464 break;
18465 case DT_JMPREL:
18466 jmprel = entry->d_un.d_ptr;
18467 break;
252b5132
RH
18468 default:
18469 break;
18470 }
18471
18472 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18473 {
2cf0635d 18474 Elf32_External_Lib * elib;
252b5132
RH
18475 size_t cnt;
18476
dda8d76d 18477 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18478 sizeof (Elf32_External_Lib),
18479 liblistno,
18480 _("liblist section data"));
a6e9f9df 18481 if (elib)
252b5132 18482 {
d3a49aa8
AM
18483 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18484 "\nSection '.liblist' contains %lu entries:\n",
18485 (unsigned long) liblistno),
a6e9f9df 18486 (unsigned long) liblistno);
2b692964 18487 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18488 stdout);
18489
18490 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18491 {
a6e9f9df 18492 Elf32_Lib liblist;
91d6fa6a 18493 time_t atime;
d5b07ef4 18494 char timebuf[128];
2cf0635d 18495 struct tm * tmp;
a6e9f9df
AM
18496
18497 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18498 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18499 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18500 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18501 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18502
91d6fa6a 18503 tmp = gmtime (&atime);
e9e44622
JJ
18504 snprintf (timebuf, sizeof (timebuf),
18505 "%04u-%02u-%02uT%02u:%02u:%02u",
18506 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18507 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18508
31104126 18509 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18510 if (valid_dynamic_name (filedata, liblist.l_name))
18511 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18512 else
2b692964 18513 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18514 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18515 liblist.l_version);
a6e9f9df
AM
18516
18517 if (liblist.l_flags == 0)
2b692964 18518 puts (_(" NONE"));
a6e9f9df
AM
18519 else
18520 {
18521 static const struct
252b5132 18522 {
2cf0635d 18523 const char * name;
a6e9f9df 18524 int bit;
252b5132 18525 }
a6e9f9df
AM
18526 l_flags_vals[] =
18527 {
18528 { " EXACT_MATCH", LL_EXACT_MATCH },
18529 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18530 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18531 { " EXPORTS", LL_EXPORTS },
18532 { " DELAY_LOAD", LL_DELAY_LOAD },
18533 { " DELTA", LL_DELTA }
18534 };
18535 int flags = liblist.l_flags;
18536 size_t fcnt;
18537
60bca95a 18538 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18539 if ((flags & l_flags_vals[fcnt].bit) != 0)
18540 {
18541 fputs (l_flags_vals[fcnt].name, stdout);
18542 flags ^= l_flags_vals[fcnt].bit;
18543 }
18544 if (flags != 0)
18545 printf (" %#x", (unsigned int) flags);
252b5132 18546
a6e9f9df
AM
18547 puts ("");
18548 }
252b5132 18549 }
252b5132 18550
a6e9f9df
AM
18551 free (elib);
18552 }
32ec8896 18553 else
015dc7e1 18554 res = false;
252b5132
RH
18555 }
18556
18557 if (options_offset != 0)
18558 {
2cf0635d 18559 Elf_External_Options * eopt;
252b5132
RH
18560 size_t offset;
18561 int cnt;
18562
18563 /* Find the section header so that we get the size. */
dda8d76d 18564 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18565 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18566 if (sect == NULL)
18567 {
18568 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18569 return false;
071436c6 18570 }
7fc0c668
NC
18571 /* PR 24243 */
18572 if (sect->sh_size < sizeof (* eopt))
18573 {
18574 error (_("The MIPS options section is too small.\n"));
015dc7e1 18575 return false;
7fc0c668 18576 }
252b5132 18577
dda8d76d 18578 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18579 sect->sh_size, _("options"));
a6e9f9df 18580 if (eopt)
252b5132 18581 {
fd17d1e6 18582 Elf_Internal_Options option;
76da6bbe 18583
a6e9f9df 18584 offset = cnt = 0;
82b1b41b 18585 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18586 {
2cf0635d 18587 Elf_External_Options * eoption;
fd17d1e6 18588 unsigned int optsize;
252b5132 18589
a6e9f9df 18590 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18591
fd17d1e6 18592 optsize = BYTE_GET (eoption->size);
76da6bbe 18593
82b1b41b 18594 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18595 if (optsize < sizeof (* eopt)
18596 || optsize > sect->sh_size - offset)
82b1b41b 18597 {
645f43a8 18598 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18599 optsize);
645f43a8 18600 free (eopt);
015dc7e1 18601 return false;
82b1b41b 18602 }
fd17d1e6 18603 offset += optsize;
a6e9f9df
AM
18604 ++cnt;
18605 }
252b5132 18606
d3a49aa8
AM
18607 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18608 "\nSection '%s' contains %d entries:\n",
18609 cnt),
dda8d76d 18610 printable_section_name (filedata, sect), cnt);
76da6bbe 18611
82b1b41b 18612 offset = 0;
a6e9f9df 18613 while (cnt-- > 0)
252b5132 18614 {
a6e9f9df 18615 size_t len;
fd17d1e6
AM
18616 Elf_External_Options * eoption;
18617
18618 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18619
18620 option.kind = BYTE_GET (eoption->kind);
18621 option.size = BYTE_GET (eoption->size);
18622 option.section = BYTE_GET (eoption->section);
18623 option.info = BYTE_GET (eoption->info);
a6e9f9df 18624
fd17d1e6 18625 switch (option.kind)
252b5132 18626 {
a6e9f9df
AM
18627 case ODK_NULL:
18628 /* This shouldn't happen. */
d0c4e780 18629 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18630 option.section, option.info);
a6e9f9df 18631 break;
2e6be59c 18632
a6e9f9df
AM
18633 case ODK_REGINFO:
18634 printf (" REGINFO ");
dda8d76d 18635 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18636 {
2cf0635d 18637 Elf32_External_RegInfo * ereg;
b34976b6 18638 Elf32_RegInfo reginfo;
a6e9f9df 18639
2e6be59c 18640 /* 32bit form. */
fd17d1e6
AM
18641 if (option.size < (sizeof (Elf_External_Options)
18642 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18643 {
18644 printf (_("<corrupt>\n"));
18645 error (_("Truncated MIPS REGINFO option\n"));
18646 cnt = 0;
18647 break;
18648 }
18649
fd17d1e6 18650 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18651
a6e9f9df
AM
18652 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18653 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18654 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18655 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18656 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18657 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18658
d0c4e780
AM
18659 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18660 reginfo.ri_gprmask, reginfo.ri_gp_value);
18661 printf (" "
18662 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18663 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18664 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18665 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18666 }
18667 else
18668 {
18669 /* 64 bit form. */
2cf0635d 18670 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18671 Elf64_Internal_RegInfo reginfo;
18672
fd17d1e6
AM
18673 if (option.size < (sizeof (Elf_External_Options)
18674 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18675 {
18676 printf (_("<corrupt>\n"));
18677 error (_("Truncated MIPS REGINFO option\n"));
18678 cnt = 0;
18679 break;
18680 }
18681
fd17d1e6 18682 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18683 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18684 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18685 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18686 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18687 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18688 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18689
d0c4e780
AM
18690 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18691 reginfo.ri_gprmask, reginfo.ri_gp_value);
18692 printf (" "
18693 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18694 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18695 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18696 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18697 }
fd17d1e6 18698 offset += option.size;
a6e9f9df 18699 continue;
2e6be59c 18700
a6e9f9df
AM
18701 case ODK_EXCEPTIONS:
18702 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18703 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18704 fputs (") fpe_max(", stdout);
fd17d1e6 18705 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18706 fputs (")", stdout);
18707
fd17d1e6 18708 if (option.info & OEX_PAGE0)
a6e9f9df 18709 fputs (" PAGE0", stdout);
fd17d1e6 18710 if (option.info & OEX_SMM)
a6e9f9df 18711 fputs (" SMM", stdout);
fd17d1e6 18712 if (option.info & OEX_FPDBUG)
a6e9f9df 18713 fputs (" FPDBUG", stdout);
fd17d1e6 18714 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18715 fputs (" DISMISS", stdout);
18716 break;
2e6be59c 18717
a6e9f9df
AM
18718 case ODK_PAD:
18719 fputs (" PAD ", stdout);
fd17d1e6 18720 if (option.info & OPAD_PREFIX)
a6e9f9df 18721 fputs (" PREFIX", stdout);
fd17d1e6 18722 if (option.info & OPAD_POSTFIX)
a6e9f9df 18723 fputs (" POSTFIX", stdout);
fd17d1e6 18724 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18725 fputs (" SYMBOL", stdout);
18726 break;
2e6be59c 18727
a6e9f9df
AM
18728 case ODK_HWPATCH:
18729 fputs (" HWPATCH ", stdout);
fd17d1e6 18730 if (option.info & OHW_R4KEOP)
a6e9f9df 18731 fputs (" R4KEOP", stdout);
fd17d1e6 18732 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18733 fputs (" R8KPFETCH", stdout);
fd17d1e6 18734 if (option.info & OHW_R5KEOP)
a6e9f9df 18735 fputs (" R5KEOP", stdout);
fd17d1e6 18736 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18737 fputs (" R5KCVTL", stdout);
18738 break;
2e6be59c 18739
a6e9f9df
AM
18740 case ODK_FILL:
18741 fputs (" FILL ", stdout);
18742 /* XXX Print content of info word? */
18743 break;
2e6be59c 18744
a6e9f9df
AM
18745 case ODK_TAGS:
18746 fputs (" TAGS ", stdout);
18747 /* XXX Print content of info word? */
18748 break;
2e6be59c 18749
a6e9f9df
AM
18750 case ODK_HWAND:
18751 fputs (" HWAND ", stdout);
fd17d1e6 18752 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18753 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18754 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18755 fputs (" R4KEOP_CLEAN", stdout);
18756 break;
2e6be59c 18757
a6e9f9df
AM
18758 case ODK_HWOR:
18759 fputs (" HWOR ", stdout);
fd17d1e6 18760 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18761 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18762 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18763 fputs (" R4KEOP_CLEAN", stdout);
18764 break;
2e6be59c 18765
a6e9f9df 18766 case ODK_GP_GROUP:
d0c4e780 18767 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18768 option.info & OGP_GROUP,
18769 (option.info & OGP_SELF) >> 16);
a6e9f9df 18770 break;
2e6be59c 18771
a6e9f9df 18772 case ODK_IDENT:
d0c4e780 18773 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18774 option.info & OGP_GROUP,
18775 (option.info & OGP_SELF) >> 16);
a6e9f9df 18776 break;
2e6be59c 18777
a6e9f9df
AM
18778 default:
18779 /* This shouldn't happen. */
d0c4e780 18780 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18781 option.kind, option.section, option.info);
a6e9f9df 18782 break;
252b5132 18783 }
a6e9f9df 18784
2cf0635d 18785 len = sizeof (* eopt);
fd17d1e6 18786 while (len < option.size)
82b1b41b 18787 {
fd17d1e6 18788 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18789
82b1b41b
NC
18790 if (ISPRINT (datum))
18791 printf ("%c", datum);
18792 else
18793 printf ("\\%03o", datum);
18794 len ++;
18795 }
a6e9f9df 18796 fputs ("\n", stdout);
82b1b41b 18797
fd17d1e6 18798 offset += option.size;
252b5132 18799 }
a6e9f9df 18800 free (eopt);
252b5132 18801 }
32ec8896 18802 else
015dc7e1 18803 res = false;
252b5132
RH
18804 }
18805
18806 if (conflicts_offset != 0 && conflictsno != 0)
18807 {
2cf0635d 18808 Elf32_Conflict * iconf;
252b5132
RH
18809 size_t cnt;
18810
978c4450 18811 if (filedata->dynamic_symbols == NULL)
252b5132 18812 {
591a748a 18813 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18814 return false;
252b5132
RH
18815 }
18816
7296a62a
NC
18817 /* PR 21345 - print a slightly more helpful error message
18818 if we are sure that the cmalloc will fail. */
645f43a8 18819 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18820 {
18821 error (_("Overlarge number of conflicts detected: %lx\n"),
18822 (long) conflictsno);
015dc7e1 18823 return false;
7296a62a
NC
18824 }
18825
3f5e193b 18826 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18827 if (iconf == NULL)
18828 {
8b73c356 18829 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18830 return false;
252b5132
RH
18831 }
18832
9ea033b2 18833 if (is_32bit_elf)
252b5132 18834 {
2cf0635d 18835 Elf32_External_Conflict * econf32;
a6e9f9df 18836
3f5e193b 18837 econf32 = (Elf32_External_Conflict *)
95099889
AM
18838 get_data (NULL, filedata, conflicts_offset,
18839 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18840 if (!econf32)
5a814d6d
AM
18841 {
18842 free (iconf);
015dc7e1 18843 return false;
5a814d6d 18844 }
252b5132
RH
18845
18846 for (cnt = 0; cnt < conflictsno; ++cnt)
18847 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18848
18849 free (econf32);
252b5132
RH
18850 }
18851 else
18852 {
2cf0635d 18853 Elf64_External_Conflict * econf64;
a6e9f9df 18854
3f5e193b 18855 econf64 = (Elf64_External_Conflict *)
95099889
AM
18856 get_data (NULL, filedata, conflicts_offset,
18857 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18858 if (!econf64)
5a814d6d
AM
18859 {
18860 free (iconf);
015dc7e1 18861 return false;
5a814d6d 18862 }
252b5132
RH
18863
18864 for (cnt = 0; cnt < conflictsno; ++cnt)
18865 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18866
18867 free (econf64);
252b5132
RH
18868 }
18869
d3a49aa8
AM
18870 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18871 "\nSection '.conflict' contains %lu entries:\n",
18872 (unsigned long) conflictsno),
c7e7ca54 18873 (unsigned long) conflictsno);
252b5132
RH
18874 puts (_(" Num: Index Value Name"));
18875
18876 for (cnt = 0; cnt < conflictsno; ++cnt)
18877 {
b34976b6 18878 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18879
978c4450 18880 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18881 printf (_("<corrupt symbol index>"));
d79b3d50 18882 else
e0a31db1
NC
18883 {
18884 Elf_Internal_Sym * psym;
18885
978c4450 18886 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18887 print_vma (psym->st_value, FULL_HEX);
18888 putchar (' ');
84714f86
AM
18889 if (valid_dynamic_name (filedata, psym->st_name))
18890 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18891 else
18892 printf (_("<corrupt: %14ld>"), psym->st_name);
18893 }
31104126 18894 putchar ('\n');
252b5132
RH
18895 }
18896
252b5132
RH
18897 free (iconf);
18898 }
18899
ccb4c951
RS
18900 if (pltgot != 0 && local_gotno != 0)
18901 {
91d6fa6a 18902 bfd_vma ent, local_end, global_end;
bbeee7ea 18903 size_t i, offset;
2cf0635d 18904 unsigned char * data;
82b1b41b 18905 unsigned char * data_end;
bbeee7ea 18906 int addr_size;
ccb4c951 18907
91d6fa6a 18908 ent = pltgot;
ccb4c951
RS
18909 addr_size = (is_32bit_elf ? 4 : 8);
18910 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18911
74e1a04b
NC
18912 /* PR binutils/17533 file: 012-111227-0.004 */
18913 if (symtabno < gotsym)
18914 {
18915 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18916 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18917 return false;
74e1a04b 18918 }
82b1b41b 18919
74e1a04b 18920 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18921 /* PR 17531: file: 54c91a34. */
18922 if (global_end < local_end)
18923 {
18924 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18925 return false;
82b1b41b 18926 }
948f632f 18927
dda8d76d
NC
18928 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18929 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18930 global_end - pltgot, 1,
18931 _("Global Offset Table data"));
919383ac 18932 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18933 data_end = data + (global_end - pltgot);
59245841 18934
ccb4c951
RS
18935 printf (_("\nPrimary GOT:\n"));
18936 printf (_(" Canonical gp value: "));
18937 print_vma (pltgot + 0x7ff0, LONG_HEX);
18938 printf ("\n\n");
18939
18940 printf (_(" Reserved entries:\n"));
18941 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18942 addr_size * 2, _("Address"), _("Access"),
18943 addr_size * 2, _("Initial"));
82b1b41b 18944 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18945 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18946 if (ent == (bfd_vma) -1)
18947 goto got_print_fail;
75ec1fdb 18948
c4ab9505
MR
18949 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18950 This entry will be used by some runtime loaders, to store the
18951 module pointer. Otherwise this is an ordinary local entry.
18952 PR 21344: Check for the entry being fully available before
18953 fetching it. */
18954 if (data
18955 && data + ent - pltgot + addr_size <= data_end
18956 && (byte_get (data + ent - pltgot, addr_size)
18957 >> (addr_size * 8 - 1)) != 0)
18958 {
18959 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18960 printf (_(" Module pointer (GNU extension)\n"));
18961 if (ent == (bfd_vma) -1)
18962 goto got_print_fail;
ccb4c951
RS
18963 }
18964 printf ("\n");
18965
f17e9d8a 18966 if (data != NULL && ent < local_end)
ccb4c951
RS
18967 {
18968 printf (_(" Local entries:\n"));
cc5914eb 18969 printf (" %*s %10s %*s\n",
2b692964
NC
18970 addr_size * 2, _("Address"), _("Access"),
18971 addr_size * 2, _("Initial"));
91d6fa6a 18972 while (ent < local_end)
ccb4c951 18973 {
82b1b41b 18974 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18975 printf ("\n");
82b1b41b
NC
18976 if (ent == (bfd_vma) -1)
18977 goto got_print_fail;
ccb4c951
RS
18978 }
18979 printf ("\n");
18980 }
18981
f17e9d8a 18982 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18983 {
18984 int sym_width;
18985
18986 printf (_(" Global entries:\n"));
cc5914eb 18987 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18988 addr_size * 2, _("Address"),
18989 _("Access"),
2b692964 18990 addr_size * 2, _("Initial"),
9cf03b7e
NC
18991 addr_size * 2, _("Sym.Val."),
18992 _("Type"),
18993 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18994 _("Ndx"), _("Name"));
0b4362b0 18995
ccb4c951 18996 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18997
ccb4c951
RS
18998 for (i = gotsym; i < symtabno; i++)
18999 {
82b1b41b 19000 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19001 printf (" ");
e0a31db1 19002
978c4450 19003 if (filedata->dynamic_symbols == NULL)
e0a31db1 19004 printf (_("<no dynamic symbols>"));
978c4450 19005 else if (i < filedata->num_dynamic_syms)
e0a31db1 19006 {
978c4450 19007 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19008
19009 print_vma (psym->st_value, LONG_HEX);
19010 printf (" %-7s %3s ",
dda8d76d
NC
19011 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19012 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19013
84714f86 19014 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19015 print_symbol (sym_width,
84714f86 19016 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19017 else
19018 printf (_("<corrupt: %14ld>"), psym->st_name);
19019 }
ccb4c951 19020 else
7fc5ac57
JBG
19021 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19022 (unsigned long) i);
e0a31db1 19023
ccb4c951 19024 printf ("\n");
82b1b41b
NC
19025 if (ent == (bfd_vma) -1)
19026 break;
ccb4c951
RS
19027 }
19028 printf ("\n");
19029 }
19030
82b1b41b 19031 got_print_fail:
9db70fc3 19032 free (data);
ccb4c951
RS
19033 }
19034
861fb55a
DJ
19035 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19036 {
91d6fa6a 19037 bfd_vma ent, end;
861fb55a
DJ
19038 size_t offset, rel_offset;
19039 unsigned long count, i;
2cf0635d 19040 unsigned char * data;
861fb55a 19041 int addr_size, sym_width;
2cf0635d 19042 Elf_Internal_Rela * rels;
861fb55a 19043
dda8d76d 19044 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19045 if (pltrel == DT_RELA)
19046 {
dda8d76d 19047 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19048 return false;
861fb55a
DJ
19049 }
19050 else
19051 {
dda8d76d 19052 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19053 return false;
861fb55a
DJ
19054 }
19055
91d6fa6a 19056 ent = mips_pltgot;
861fb55a
DJ
19057 addr_size = (is_32bit_elf ? 4 : 8);
19058 end = mips_pltgot + (2 + count) * addr_size;
19059
dda8d76d
NC
19060 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19061 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19062 1, _("Procedure Linkage Table data"));
59245841 19063 if (data == NULL)
288f0ba2
AM
19064 {
19065 free (rels);
015dc7e1 19066 return false;
288f0ba2 19067 }
59245841 19068
9cf03b7e 19069 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19070 printf (_(" Reserved entries:\n"));
19071 printf (_(" %*s %*s Purpose\n"),
2b692964 19072 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19073 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19074 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19075 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19076 printf (_(" Module pointer\n"));
861fb55a
DJ
19077 printf ("\n");
19078
19079 printf (_(" Entries:\n"));
cc5914eb 19080 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19081 addr_size * 2, _("Address"),
19082 addr_size * 2, _("Initial"),
19083 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19084 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19085 for (i = 0; i < count; i++)
19086 {
df97ab2a 19087 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19088
91d6fa6a 19089 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19090 printf (" ");
e0a31db1 19091
978c4450 19092 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19093 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19094 else
e0a31db1 19095 {
978c4450 19096 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19097
19098 print_vma (psym->st_value, LONG_HEX);
19099 printf (" %-7s %3s ",
dda8d76d
NC
19100 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19101 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19102 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19103 print_symbol (sym_width,
84714f86 19104 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19105 else
19106 printf (_("<corrupt: %14ld>"), psym->st_name);
19107 }
861fb55a
DJ
19108 printf ("\n");
19109 }
19110 printf ("\n");
19111
9db70fc3 19112 free (data);
861fb55a
DJ
19113 free (rels);
19114 }
19115
32ec8896 19116 return res;
252b5132
RH
19117}
19118
015dc7e1 19119static bool
dda8d76d 19120process_nds32_specific (Filedata * filedata)
35c08157
KLC
19121{
19122 Elf_Internal_Shdr *sect = NULL;
19123
dda8d76d 19124 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19125 if (sect != NULL && sect->sh_size >= 4)
35c08157 19126 {
9c7b8e9b
AM
19127 unsigned char *buf;
19128 unsigned int flag;
35c08157
KLC
19129
19130 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19131 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19132 _("NDS32 elf flags section"));
35c08157 19133
9c7b8e9b 19134 if (buf == NULL)
015dc7e1 19135 return false;
32ec8896 19136
9c7b8e9b
AM
19137 flag = byte_get (buf, 4);
19138 free (buf);
19139 switch (flag & 0x3)
35c08157
KLC
19140 {
19141 case 0:
19142 printf ("(VEC_SIZE):\tNo entry.\n");
19143 break;
19144 case 1:
19145 printf ("(VEC_SIZE):\t4 bytes\n");
19146 break;
19147 case 2:
19148 printf ("(VEC_SIZE):\t16 bytes\n");
19149 break;
19150 case 3:
19151 printf ("(VEC_SIZE):\treserved\n");
19152 break;
19153 }
19154 }
19155
015dc7e1 19156 return true;
35c08157
KLC
19157}
19158
015dc7e1 19159static bool
dda8d76d 19160process_gnu_liblist (Filedata * filedata)
047b2264 19161{
2cf0635d
NC
19162 Elf_Internal_Shdr * section;
19163 Elf_Internal_Shdr * string_sec;
19164 Elf32_External_Lib * elib;
19165 char * strtab;
c256ffe7 19166 size_t strtab_size;
047b2264 19167 size_t cnt;
d3a49aa8 19168 unsigned long num_liblist;
047b2264 19169 unsigned i;
015dc7e1 19170 bool res = true;
047b2264
JJ
19171
19172 if (! do_arch)
015dc7e1 19173 return true;
047b2264 19174
dda8d76d
NC
19175 for (i = 0, section = filedata->section_headers;
19176 i < filedata->file_header.e_shnum;
b34976b6 19177 i++, section++)
047b2264
JJ
19178 {
19179 switch (section->sh_type)
19180 {
19181 case SHT_GNU_LIBLIST:
dda8d76d 19182 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19183 break;
19184
3f5e193b 19185 elib = (Elf32_External_Lib *)
dda8d76d 19186 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19187 _("liblist section data"));
047b2264
JJ
19188
19189 if (elib == NULL)
32ec8896 19190 {
015dc7e1 19191 res = false;
32ec8896
NC
19192 break;
19193 }
047b2264 19194
dda8d76d
NC
19195 string_sec = filedata->section_headers + section->sh_link;
19196 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19197 string_sec->sh_size,
19198 _("liblist string table"));
047b2264
JJ
19199 if (strtab == NULL
19200 || section->sh_entsize != sizeof (Elf32_External_Lib))
19201 {
19202 free (elib);
2842702f 19203 free (strtab);
015dc7e1 19204 res = false;
047b2264
JJ
19205 break;
19206 }
59245841 19207 strtab_size = string_sec->sh_size;
047b2264 19208
d3a49aa8
AM
19209 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19210 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19211 "\nLibrary list section '%s' contains %lu entries:\n",
19212 num_liblist),
dda8d76d 19213 printable_section_name (filedata, section),
d3a49aa8 19214 num_liblist);
047b2264 19215
2b692964 19216 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19217
19218 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19219 ++cnt)
19220 {
19221 Elf32_Lib liblist;
91d6fa6a 19222 time_t atime;
d5b07ef4 19223 char timebuf[128];
2cf0635d 19224 struct tm * tmp;
047b2264
JJ
19225
19226 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19227 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19228 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19229 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19230 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19231
91d6fa6a 19232 tmp = gmtime (&atime);
e9e44622
JJ
19233 snprintf (timebuf, sizeof (timebuf),
19234 "%04u-%02u-%02uT%02u:%02u:%02u",
19235 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19236 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19237
19238 printf ("%3lu: ", (unsigned long) cnt);
19239 if (do_wide)
c256ffe7 19240 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19241 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19242 else
c256ffe7 19243 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19244 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19245 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19246 liblist.l_version, liblist.l_flags);
19247 }
19248
19249 free (elib);
2842702f 19250 free (strtab);
047b2264
JJ
19251 }
19252 }
19253
32ec8896 19254 return res;
047b2264
JJ
19255}
19256
9437c45b 19257static const char *
dda8d76d 19258get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19259{
19260 static char buff[64];
103f02d3 19261
dda8d76d 19262 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19263 switch (e_type)
19264 {
57346661 19265 case NT_AUXV:
1ec5cd37 19266 return _("NT_AUXV (auxiliary vector)");
57346661 19267 case NT_PRSTATUS:
1ec5cd37 19268 return _("NT_PRSTATUS (prstatus structure)");
57346661 19269 case NT_FPREGSET:
1ec5cd37 19270 return _("NT_FPREGSET (floating point registers)");
57346661 19271 case NT_PRPSINFO:
1ec5cd37 19272 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19273 case NT_TASKSTRUCT:
1ec5cd37 19274 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19275 case NT_GDB_TDESC:
19276 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19277 case NT_PRXFPREG:
1ec5cd37 19278 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19279 case NT_PPC_VMX:
19280 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19281 case NT_PPC_VSX:
19282 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19283 case NT_PPC_TAR:
19284 return _("NT_PPC_TAR (ppc TAR register)");
19285 case NT_PPC_PPR:
19286 return _("NT_PPC_PPR (ppc PPR register)");
19287 case NT_PPC_DSCR:
19288 return _("NT_PPC_DSCR (ppc DSCR register)");
19289 case NT_PPC_EBB:
19290 return _("NT_PPC_EBB (ppc EBB registers)");
19291 case NT_PPC_PMU:
19292 return _("NT_PPC_PMU (ppc PMU registers)");
19293 case NT_PPC_TM_CGPR:
19294 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19295 case NT_PPC_TM_CFPR:
19296 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19297 case NT_PPC_TM_CVMX:
19298 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19299 case NT_PPC_TM_CVSX:
3fd21718 19300 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19301 case NT_PPC_TM_SPR:
19302 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19303 case NT_PPC_TM_CTAR:
19304 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19305 case NT_PPC_TM_CPPR:
19306 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19307 case NT_PPC_TM_CDSCR:
19308 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19309 case NT_386_TLS:
19310 return _("NT_386_TLS (x86 TLS information)");
19311 case NT_386_IOPERM:
19312 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19313 case NT_X86_XSTATE:
19314 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19315 case NT_X86_CET:
19316 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19317 case NT_S390_HIGH_GPRS:
19318 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19319 case NT_S390_TIMER:
19320 return _("NT_S390_TIMER (s390 timer register)");
19321 case NT_S390_TODCMP:
19322 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19323 case NT_S390_TODPREG:
19324 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19325 case NT_S390_CTRS:
19326 return _("NT_S390_CTRS (s390 control registers)");
19327 case NT_S390_PREFIX:
19328 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19329 case NT_S390_LAST_BREAK:
19330 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19331 case NT_S390_SYSTEM_CALL:
19332 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19333 case NT_S390_TDB:
19334 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19335 case NT_S390_VXRS_LOW:
19336 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19337 case NT_S390_VXRS_HIGH:
19338 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19339 case NT_S390_GS_CB:
19340 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19341 case NT_S390_GS_BC:
19342 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19343 case NT_ARM_VFP:
19344 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19345 case NT_ARM_TLS:
19346 return _("NT_ARM_TLS (AArch TLS registers)");
19347 case NT_ARM_HW_BREAK:
19348 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19349 case NT_ARM_HW_WATCH:
19350 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19351 case NT_ARM_SYSTEM_CALL:
19352 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19353 case NT_ARM_SVE:
19354 return _("NT_ARM_SVE (AArch SVE registers)");
19355 case NT_ARM_PAC_MASK:
19356 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19357 case NT_ARM_PACA_KEYS:
19358 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19359 case NT_ARM_PACG_KEYS:
19360 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19361 case NT_ARM_TAGGED_ADDR_CTRL:
19362 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19363 case NT_ARM_PAC_ENABLED_KEYS:
19364 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19365 case NT_ARC_V2:
19366 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19367 case NT_RISCV_CSR:
19368 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19369 case NT_PSTATUS:
1ec5cd37 19370 return _("NT_PSTATUS (pstatus structure)");
57346661 19371 case NT_FPREGS:
1ec5cd37 19372 return _("NT_FPREGS (floating point registers)");
57346661 19373 case NT_PSINFO:
1ec5cd37 19374 return _("NT_PSINFO (psinfo structure)");
57346661 19375 case NT_LWPSTATUS:
1ec5cd37 19376 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19377 case NT_LWPSINFO:
1ec5cd37 19378 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19379 case NT_WIN32PSTATUS:
1ec5cd37 19380 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19381 case NT_SIGINFO:
19382 return _("NT_SIGINFO (siginfo_t data)");
19383 case NT_FILE:
19384 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19385 default:
19386 break;
19387 }
19388 else
19389 switch (e_type)
19390 {
19391 case NT_VERSION:
19392 return _("NT_VERSION (version)");
19393 case NT_ARCH:
19394 return _("NT_ARCH (architecture)");
9ef920e9 19395 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19396 return _("OPEN");
9ef920e9 19397 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19398 return _("func");
c8795e1f
NC
19399 case NT_GO_BUILDID:
19400 return _("GO BUILDID");
3ac925fc
LB
19401 case FDO_PACKAGING_METADATA:
19402 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19403 default:
19404 break;
19405 }
19406
e9e44622 19407 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19408 return buff;
779fe533
NC
19409}
19410
015dc7e1 19411static bool
9ece1fa9
TT
19412print_core_note (Elf_Internal_Note *pnote)
19413{
19414 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19415 bfd_vma count, page_size;
19416 unsigned char *descdata, *filenames, *descend;
19417
19418 if (pnote->type != NT_FILE)
04ac15ab
AS
19419 {
19420 if (do_wide)
19421 printf ("\n");
015dc7e1 19422 return true;
04ac15ab 19423 }
9ece1fa9
TT
19424
19425#ifndef BFD64
19426 if (!is_32bit_elf)
19427 {
19428 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19429 /* Still "successful". */
015dc7e1 19430 return true;
9ece1fa9
TT
19431 }
19432#endif
19433
19434 if (pnote->descsz < 2 * addr_size)
19435 {
32ec8896 19436 error (_(" Malformed note - too short for header\n"));
015dc7e1 19437 return false;
9ece1fa9
TT
19438 }
19439
19440 descdata = (unsigned char *) pnote->descdata;
19441 descend = descdata + pnote->descsz;
19442
19443 if (descdata[pnote->descsz - 1] != '\0')
19444 {
32ec8896 19445 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19446 return false;
9ece1fa9
TT
19447 }
19448
19449 count = byte_get (descdata, addr_size);
19450 descdata += addr_size;
19451
19452 page_size = byte_get (descdata, addr_size);
19453 descdata += addr_size;
19454
5396a86e
AM
19455 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19456 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19457 {
32ec8896 19458 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19459 return false;
9ece1fa9
TT
19460 }
19461
19462 printf (_(" Page size: "));
19463 print_vma (page_size, DEC);
19464 printf ("\n");
19465
19466 printf (_(" %*s%*s%*s\n"),
19467 (int) (2 + 2 * addr_size), _("Start"),
19468 (int) (4 + 2 * addr_size), _("End"),
19469 (int) (4 + 2 * addr_size), _("Page Offset"));
19470 filenames = descdata + count * 3 * addr_size;
595712bb 19471 while (count-- > 0)
9ece1fa9
TT
19472 {
19473 bfd_vma start, end, file_ofs;
19474
19475 if (filenames == descend)
19476 {
32ec8896 19477 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19478 return false;
9ece1fa9
TT
19479 }
19480
19481 start = byte_get (descdata, addr_size);
19482 descdata += addr_size;
19483 end = byte_get (descdata, addr_size);
19484 descdata += addr_size;
19485 file_ofs = byte_get (descdata, addr_size);
19486 descdata += addr_size;
19487
19488 printf (" ");
19489 print_vma (start, FULL_HEX);
19490 printf (" ");
19491 print_vma (end, FULL_HEX);
19492 printf (" ");
19493 print_vma (file_ofs, FULL_HEX);
19494 printf ("\n %s\n", filenames);
19495
19496 filenames += 1 + strlen ((char *) filenames);
19497 }
19498
015dc7e1 19499 return true;
9ece1fa9
TT
19500}
19501
1118d252
RM
19502static const char *
19503get_gnu_elf_note_type (unsigned e_type)
19504{
1449284b 19505 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19506 switch (e_type)
19507 {
19508 case NT_GNU_ABI_TAG:
19509 return _("NT_GNU_ABI_TAG (ABI version tag)");
19510 case NT_GNU_HWCAP:
19511 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19512 case NT_GNU_BUILD_ID:
19513 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19514 case NT_GNU_GOLD_VERSION:
19515 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19516 case NT_GNU_PROPERTY_TYPE_0:
19517 return _("NT_GNU_PROPERTY_TYPE_0");
19518 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19519 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19520 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19521 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19522 default:
1449284b
NC
19523 {
19524 static char buff[64];
1118d252 19525
1449284b
NC
19526 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19527 return buff;
19528 }
19529 }
1118d252
RM
19530}
19531
a9eafb08
L
19532static void
19533decode_x86_compat_isa (unsigned int bitmask)
19534{
19535 while (bitmask)
19536 {
19537 unsigned int bit = bitmask & (- bitmask);
19538
19539 bitmask &= ~ bit;
19540 switch (bit)
19541 {
19542 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19543 printf ("i486");
19544 break;
19545 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19546 printf ("586");
19547 break;
19548 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19549 printf ("686");
19550 break;
19551 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19552 printf ("SSE");
19553 break;
19554 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19555 printf ("SSE2");
19556 break;
19557 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19558 printf ("SSE3");
19559 break;
19560 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19561 printf ("SSSE3");
19562 break;
19563 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19564 printf ("SSE4_1");
19565 break;
19566 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19567 printf ("SSE4_2");
19568 break;
19569 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19570 printf ("AVX");
19571 break;
19572 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19573 printf ("AVX2");
19574 break;
19575 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19576 printf ("AVX512F");
19577 break;
19578 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19579 printf ("AVX512CD");
19580 break;
19581 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19582 printf ("AVX512ER");
19583 break;
19584 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19585 printf ("AVX512PF");
19586 break;
19587 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19588 printf ("AVX512VL");
19589 break;
19590 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19591 printf ("AVX512DQ");
19592 break;
19593 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19594 printf ("AVX512BW");
19595 break;
65b3d26e
L
19596 default:
19597 printf (_("<unknown: %x>"), bit);
19598 break;
a9eafb08
L
19599 }
19600 if (bitmask)
19601 printf (", ");
19602 }
19603}
19604
9ef920e9 19605static void
32930e4e 19606decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19607{
0a59decb 19608 if (!bitmask)
90c745dc
L
19609 {
19610 printf (_("<None>"));
19611 return;
19612 }
90c745dc 19613
9ef920e9
NC
19614 while (bitmask)
19615 {
1fc87489 19616 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19617
19618 bitmask &= ~ bit;
19619 switch (bit)
19620 {
32930e4e 19621 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19622 printf ("CMOV");
19623 break;
32930e4e 19624 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19625 printf ("SSE");
19626 break;
32930e4e 19627 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19628 printf ("SSE2");
19629 break;
32930e4e 19630 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19631 printf ("SSE3");
19632 break;
32930e4e 19633 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19634 printf ("SSSE3");
19635 break;
32930e4e 19636 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19637 printf ("SSE4_1");
19638 break;
32930e4e 19639 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19640 printf ("SSE4_2");
19641 break;
32930e4e 19642 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19643 printf ("AVX");
19644 break;
32930e4e 19645 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19646 printf ("AVX2");
19647 break;
32930e4e 19648 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19649 printf ("FMA");
19650 break;
32930e4e 19651 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19652 printf ("AVX512F");
19653 break;
32930e4e 19654 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19655 printf ("AVX512CD");
19656 break;
32930e4e 19657 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19658 printf ("AVX512ER");
19659 break;
32930e4e 19660 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19661 printf ("AVX512PF");
19662 break;
32930e4e 19663 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19664 printf ("AVX512VL");
19665 break;
32930e4e 19666 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19667 printf ("AVX512DQ");
19668 break;
32930e4e 19669 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19670 printf ("AVX512BW");
19671 break;
32930e4e 19672 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19673 printf ("AVX512_4FMAPS");
19674 break;
32930e4e 19675 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19676 printf ("AVX512_4VNNIW");
19677 break;
32930e4e 19678 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19679 printf ("AVX512_BITALG");
19680 break;
32930e4e 19681 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19682 printf ("AVX512_IFMA");
19683 break;
32930e4e 19684 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19685 printf ("AVX512_VBMI");
19686 break;
32930e4e 19687 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19688 printf ("AVX512_VBMI2");
19689 break;
32930e4e 19690 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19691 printf ("AVX512_VNNI");
19692 break;
32930e4e 19693 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19694 printf ("AVX512_BF16");
19695 break;
65b3d26e
L
19696 default:
19697 printf (_("<unknown: %x>"), bit);
19698 break;
9ef920e9
NC
19699 }
19700 if (bitmask)
19701 printf (", ");
19702 }
19703}
19704
28cdbb18
SM
19705static const char *
19706get_amdgpu_elf_note_type (unsigned int e_type)
19707{
19708 switch (e_type)
19709 {
19710 case NT_AMDGPU_METADATA:
19711 return _("NT_AMDGPU_METADATA (code object metadata)");
19712 default:
19713 {
19714 static char buf[64];
19715 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19716 return buf;
19717 }
19718 }
19719}
19720
32930e4e
L
19721static void
19722decode_x86_isa (unsigned int bitmask)
19723{
32930e4e
L
19724 while (bitmask)
19725 {
19726 unsigned int bit = bitmask & (- bitmask);
19727
19728 bitmask &= ~ bit;
19729 switch (bit)
19730 {
b0ab0693
L
19731 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19732 printf ("x86-64-baseline");
19733 break;
32930e4e
L
19734 case GNU_PROPERTY_X86_ISA_1_V2:
19735 printf ("x86-64-v2");
19736 break;
19737 case GNU_PROPERTY_X86_ISA_1_V3:
19738 printf ("x86-64-v3");
19739 break;
19740 case GNU_PROPERTY_X86_ISA_1_V4:
19741 printf ("x86-64-v4");
19742 break;
19743 default:
19744 printf (_("<unknown: %x>"), bit);
19745 break;
19746 }
19747 if (bitmask)
19748 printf (", ");
19749 }
19750}
19751
ee2fdd6f 19752static void
a9eafb08 19753decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19754{
0a59decb 19755 if (!bitmask)
90c745dc
L
19756 {
19757 printf (_("<None>"));
19758 return;
19759 }
90c745dc 19760
ee2fdd6f
L
19761 while (bitmask)
19762 {
19763 unsigned int bit = bitmask & (- bitmask);
19764
19765 bitmask &= ~ bit;
19766 switch (bit)
19767 {
19768 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19769 printf ("IBT");
ee2fdd6f 19770 break;
48580982 19771 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19772 printf ("SHSTK");
48580982 19773 break;
279d901e
L
19774 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19775 printf ("LAM_U48");
19776 break;
19777 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19778 printf ("LAM_U57");
19779 break;
ee2fdd6f
L
19780 default:
19781 printf (_("<unknown: %x>"), bit);
19782 break;
19783 }
19784 if (bitmask)
19785 printf (", ");
19786 }
19787}
19788
a9eafb08
L
19789static void
19790decode_x86_feature_2 (unsigned int bitmask)
19791{
0a59decb 19792 if (!bitmask)
90c745dc
L
19793 {
19794 printf (_("<None>"));
19795 return;
19796 }
90c745dc 19797
a9eafb08
L
19798 while (bitmask)
19799 {
19800 unsigned int bit = bitmask & (- bitmask);
19801
19802 bitmask &= ~ bit;
19803 switch (bit)
19804 {
19805 case GNU_PROPERTY_X86_FEATURE_2_X86:
19806 printf ("x86");
19807 break;
19808 case GNU_PROPERTY_X86_FEATURE_2_X87:
19809 printf ("x87");
19810 break;
19811 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19812 printf ("MMX");
19813 break;
19814 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19815 printf ("XMM");
19816 break;
19817 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19818 printf ("YMM");
19819 break;
19820 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19821 printf ("ZMM");
19822 break;
a308b89d
L
19823 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19824 printf ("TMM");
19825 break;
32930e4e
L
19826 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19827 printf ("MASK");
19828 break;
a9eafb08
L
19829 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19830 printf ("FXSR");
19831 break;
19832 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19833 printf ("XSAVE");
19834 break;
19835 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19836 printf ("XSAVEOPT");
19837 break;
19838 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19839 printf ("XSAVEC");
19840 break;
65b3d26e
L
19841 default:
19842 printf (_("<unknown: %x>"), bit);
19843 break;
a9eafb08
L
19844 }
19845 if (bitmask)
19846 printf (", ");
19847 }
19848}
19849
cd702818
SD
19850static void
19851decode_aarch64_feature_1_and (unsigned int bitmask)
19852{
19853 while (bitmask)
19854 {
19855 unsigned int bit = bitmask & (- bitmask);
19856
19857 bitmask &= ~ bit;
19858 switch (bit)
19859 {
19860 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19861 printf ("BTI");
19862 break;
19863
19864 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19865 printf ("PAC");
19866 break;
19867
19868 default:
19869 printf (_("<unknown: %x>"), bit);
19870 break;
19871 }
19872 if (bitmask)
19873 printf (", ");
19874 }
19875}
19876
6320fd00
L
19877static void
19878decode_1_needed (unsigned int bitmask)
19879{
19880 while (bitmask)
19881 {
19882 unsigned int bit = bitmask & (- bitmask);
19883
19884 bitmask &= ~ bit;
19885 switch (bit)
19886 {
19887 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19888 printf ("indirect external access");
19889 break;
19890 default:
19891 printf (_("<unknown: %x>"), bit);
19892 break;
19893 }
19894 if (bitmask)
19895 printf (", ");
19896 }
19897}
19898
9ef920e9 19899static void
dda8d76d 19900print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19901{
19902 unsigned char * ptr = (unsigned char *) pnote->descdata;
19903 unsigned char * ptr_end = ptr + pnote->descsz;
19904 unsigned int size = is_32bit_elf ? 4 : 8;
19905
19906 printf (_(" Properties: "));
19907
1fc87489 19908 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19909 {
19910 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19911 return;
19912 }
19913
6ab2c4ed 19914 while (ptr < ptr_end)
9ef920e9 19915 {
1fc87489 19916 unsigned int j;
6ab2c4ed
MC
19917 unsigned int type;
19918 unsigned int datasz;
19919
19920 if ((size_t) (ptr_end - ptr) < 8)
19921 {
19922 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19923 break;
19924 }
19925
19926 type = byte_get (ptr, 4);
19927 datasz = byte_get (ptr + 4, 4);
9ef920e9 19928
1fc87489 19929 ptr += 8;
9ef920e9 19930
6ab2c4ed 19931 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19932 {
1fc87489
L
19933 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19934 type, datasz);
9ef920e9 19935 break;
1fc87489 19936 }
9ef920e9 19937
1fc87489
L
19938 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19939 {
dda8d76d
NC
19940 if (filedata->file_header.e_machine == EM_X86_64
19941 || filedata->file_header.e_machine == EM_IAMCU
19942 || filedata->file_header.e_machine == EM_386)
1fc87489 19943 {
aa7bca9b
L
19944 unsigned int bitmask;
19945
19946 if (datasz == 4)
0a59decb 19947 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19948 else
19949 bitmask = 0;
19950
1fc87489
L
19951 switch (type)
19952 {
19953 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19954 if (datasz != 4)
aa7bca9b
L
19955 printf (_("x86 ISA used: <corrupt length: %#x> "),
19956 datasz);
1fc87489 19957 else
aa7bca9b
L
19958 {
19959 printf ("x86 ISA used: ");
19960 decode_x86_isa (bitmask);
19961 }
1fc87489 19962 goto next;
9ef920e9 19963
1fc87489 19964 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19965 if (datasz != 4)
aa7bca9b
L
19966 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19967 datasz);
1fc87489 19968 else
aa7bca9b
L
19969 {
19970 printf ("x86 ISA needed: ");
19971 decode_x86_isa (bitmask);
19972 }
1fc87489 19973 goto next;
9ef920e9 19974
ee2fdd6f 19975 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19976 if (datasz != 4)
aa7bca9b
L
19977 printf (_("x86 feature: <corrupt length: %#x> "),
19978 datasz);
ee2fdd6f 19979 else
aa7bca9b
L
19980 {
19981 printf ("x86 feature: ");
a9eafb08
L
19982 decode_x86_feature_1 (bitmask);
19983 }
19984 goto next;
19985
19986 case GNU_PROPERTY_X86_FEATURE_2_USED:
19987 if (datasz != 4)
19988 printf (_("x86 feature used: <corrupt length: %#x> "),
19989 datasz);
19990 else
19991 {
19992 printf ("x86 feature used: ");
19993 decode_x86_feature_2 (bitmask);
19994 }
19995 goto next;
19996
19997 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19998 if (datasz != 4)
19999 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20000 else
20001 {
20002 printf ("x86 feature needed: ");
20003 decode_x86_feature_2 (bitmask);
20004 }
20005 goto next;
20006
20007 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20008 if (datasz != 4)
20009 printf (_("x86 ISA used: <corrupt length: %#x> "),
20010 datasz);
20011 else
20012 {
20013 printf ("x86 ISA used: ");
20014 decode_x86_compat_isa (bitmask);
20015 }
20016 goto next;
20017
20018 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20019 if (datasz != 4)
20020 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20021 datasz);
20022 else
20023 {
20024 printf ("x86 ISA needed: ");
20025 decode_x86_compat_isa (bitmask);
aa7bca9b 20026 }
ee2fdd6f
L
20027 goto next;
20028
32930e4e
L
20029 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20030 if (datasz != 4)
20031 printf (_("x86 ISA used: <corrupt length: %#x> "),
20032 datasz);
20033 else
20034 {
20035 printf ("x86 ISA used: ");
20036 decode_x86_compat_2_isa (bitmask);
20037 }
20038 goto next;
20039
20040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20041 if (datasz != 4)
20042 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20043 datasz);
20044 else
20045 {
20046 printf ("x86 ISA needed: ");
20047 decode_x86_compat_2_isa (bitmask);
20048 }
20049 goto next;
20050
1fc87489
L
20051 default:
20052 break;
20053 }
20054 }
cd702818
SD
20055 else if (filedata->file_header.e_machine == EM_AARCH64)
20056 {
20057 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20058 {
20059 printf ("AArch64 feature: ");
20060 if (datasz != 4)
20061 printf (_("<corrupt length: %#x> "), datasz);
20062 else
20063 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20064 goto next;
20065 }
20066 }
1fc87489
L
20067 }
20068 else
20069 {
20070 switch (type)
9ef920e9 20071 {
1fc87489
L
20072 case GNU_PROPERTY_STACK_SIZE:
20073 printf (_("stack size: "));
20074 if (datasz != size)
20075 printf (_("<corrupt length: %#x> "), datasz);
20076 else
20077 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20078 goto next;
20079
20080 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20081 printf ("no copy on protected ");
20082 if (datasz)
20083 printf (_("<corrupt length: %#x> "), datasz);
20084 goto next;
20085
20086 default:
5a767724
L
20087 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20088 && type <= GNU_PROPERTY_UINT32_AND_HI)
20089 || (type >= GNU_PROPERTY_UINT32_OR_LO
20090 && type <= GNU_PROPERTY_UINT32_OR_HI))
20091 {
6320fd00
L
20092 switch (type)
20093 {
20094 case GNU_PROPERTY_1_NEEDED:
20095 if (datasz != 4)
20096 printf (_("1_needed: <corrupt length: %#x> "),
20097 datasz);
20098 else
20099 {
20100 unsigned int bitmask = byte_get (ptr, 4);
20101 printf ("1_needed: ");
20102 decode_1_needed (bitmask);
20103 }
20104 goto next;
20105
20106 default:
20107 break;
20108 }
5a767724
L
20109 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20110 printf (_("UINT32_AND (%#x): "), type);
20111 else
20112 printf (_("UINT32_OR (%#x): "), type);
20113 if (datasz != 4)
20114 printf (_("<corrupt length: %#x> "), datasz);
20115 else
20116 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20117 goto next;
20118 }
9ef920e9
NC
20119 break;
20120 }
9ef920e9
NC
20121 }
20122
1fc87489
L
20123 if (type < GNU_PROPERTY_LOPROC)
20124 printf (_("<unknown type %#x data: "), type);
20125 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20126 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20127 else
20128 printf (_("<application-specific type %#x data: "), type);
20129 for (j = 0; j < datasz; ++j)
20130 printf ("%02x ", ptr[j] & 0xff);
20131 printf (">");
20132
dc1e8a47 20133 next:
9ef920e9 20134 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20135 if (ptr == ptr_end)
20136 break;
1fc87489 20137
6ab2c4ed
MC
20138 if (do_wide)
20139 printf (", ");
20140 else
20141 printf ("\n\t");
9ef920e9
NC
20142 }
20143
20144 printf ("\n");
20145}
20146
015dc7e1 20147static bool
dda8d76d 20148print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20149{
1449284b 20150 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20151 switch (pnote->type)
20152 {
20153 case NT_GNU_BUILD_ID:
20154 {
20155 unsigned long i;
20156
20157 printf (_(" Build ID: "));
20158 for (i = 0; i < pnote->descsz; ++i)
20159 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20160 printf ("\n");
664f90a3
TT
20161 }
20162 break;
20163
20164 case NT_GNU_ABI_TAG:
20165 {
20166 unsigned long os, major, minor, subminor;
20167 const char *osname;
20168
3102e897
NC
20169 /* PR 17531: file: 030-599401-0.004. */
20170 if (pnote->descsz < 16)
20171 {
20172 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20173 break;
20174 }
20175
664f90a3
TT
20176 os = byte_get ((unsigned char *) pnote->descdata, 4);
20177 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20178 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20179 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20180
20181 switch (os)
20182 {
20183 case GNU_ABI_TAG_LINUX:
20184 osname = "Linux";
20185 break;
20186 case GNU_ABI_TAG_HURD:
20187 osname = "Hurd";
20188 break;
20189 case GNU_ABI_TAG_SOLARIS:
20190 osname = "Solaris";
20191 break;
20192 case GNU_ABI_TAG_FREEBSD:
20193 osname = "FreeBSD";
20194 break;
20195 case GNU_ABI_TAG_NETBSD:
20196 osname = "NetBSD";
20197 break;
14ae95f2
RM
20198 case GNU_ABI_TAG_SYLLABLE:
20199 osname = "Syllable";
20200 break;
20201 case GNU_ABI_TAG_NACL:
20202 osname = "NaCl";
20203 break;
664f90a3
TT
20204 default:
20205 osname = "Unknown";
20206 break;
20207 }
20208
20209 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20210 major, minor, subminor);
20211 }
20212 break;
926c5385
CC
20213
20214 case NT_GNU_GOLD_VERSION:
20215 {
20216 unsigned long i;
20217
20218 printf (_(" Version: "));
20219 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20220 printf ("%c", pnote->descdata[i]);
20221 printf ("\n");
20222 }
20223 break;
1449284b
NC
20224
20225 case NT_GNU_HWCAP:
20226 {
20227 unsigned long num_entries, mask;
20228
20229 /* Hardware capabilities information. Word 0 is the number of entries.
20230 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20231 is a series of entries, where each entry is a single byte followed
20232 by a nul terminated string. The byte gives the bit number to test
20233 if enabled in the bitmask. */
20234 printf (_(" Hardware Capabilities: "));
20235 if (pnote->descsz < 8)
20236 {
32ec8896 20237 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20238 return false;
1449284b
NC
20239 }
20240 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20241 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20242 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20243 /* FIXME: Add code to display the entries... */
20244 }
20245 break;
20246
9ef920e9 20247 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20248 print_gnu_property_note (filedata, pnote);
9ef920e9 20249 break;
9abca702 20250
1449284b
NC
20251 default:
20252 /* Handle unrecognised types. An error message should have already been
20253 created by get_gnu_elf_note_type(), so all that we need to do is to
20254 display the data. */
20255 {
20256 unsigned long i;
20257
20258 printf (_(" Description data: "));
20259 for (i = 0; i < pnote->descsz; ++i)
20260 printf ("%02x ", pnote->descdata[i] & 0xff);
20261 printf ("\n");
20262 }
20263 break;
664f90a3
TT
20264 }
20265
015dc7e1 20266 return true;
664f90a3
TT
20267}
20268
685080f2
NC
20269static const char *
20270get_v850_elf_note_type (enum v850_notes n_type)
20271{
20272 static char buff[64];
20273
20274 switch (n_type)
20275 {
20276 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20277 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20278 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20279 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20280 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20281 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20282 default:
20283 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20284 return buff;
20285 }
20286}
20287
015dc7e1 20288static bool
685080f2
NC
20289print_v850_note (Elf_Internal_Note * pnote)
20290{
20291 unsigned int val;
20292
20293 if (pnote->descsz != 4)
015dc7e1 20294 return false;
32ec8896 20295
685080f2
NC
20296 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20297
20298 if (val == 0)
20299 {
20300 printf (_("not set\n"));
015dc7e1 20301 return true;
685080f2
NC
20302 }
20303
20304 switch (pnote->type)
20305 {
20306 case V850_NOTE_ALIGNMENT:
20307 switch (val)
20308 {
015dc7e1
AM
20309 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20310 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20311 }
20312 break;
14ae95f2 20313
685080f2
NC
20314 case V850_NOTE_DATA_SIZE:
20315 switch (val)
20316 {
015dc7e1
AM
20317 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20318 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20319 }
20320 break;
14ae95f2 20321
685080f2
NC
20322 case V850_NOTE_FPU_INFO:
20323 switch (val)
20324 {
015dc7e1
AM
20325 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20326 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20327 }
20328 break;
14ae95f2 20329
685080f2
NC
20330 case V850_NOTE_MMU_INFO:
20331 case V850_NOTE_CACHE_INFO:
20332 case V850_NOTE_SIMD_INFO:
20333 if (val == EF_RH850_SIMD)
20334 {
20335 printf (_("yes\n"));
015dc7e1 20336 return true;
685080f2
NC
20337 }
20338 break;
20339
20340 default:
20341 /* An 'unknown note type' message will already have been displayed. */
20342 break;
20343 }
20344
20345 printf (_("unknown value: %x\n"), val);
015dc7e1 20346 return false;
685080f2
NC
20347}
20348
015dc7e1 20349static bool
c6056a74
SF
20350process_netbsd_elf_note (Elf_Internal_Note * pnote)
20351{
20352 unsigned int version;
20353
20354 switch (pnote->type)
20355 {
20356 case NT_NETBSD_IDENT:
b966f55f
AM
20357 if (pnote->descsz < 1)
20358 break;
c6056a74
SF
20359 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20360 if ((version / 10000) % 100)
b966f55f 20361 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20362 version, version / 100000000, (version / 1000000) % 100,
20363 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20364 'A' + (version / 10000) % 26);
c6056a74
SF
20365 else
20366 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20367 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20368 (version / 100) % 100);
015dc7e1 20369 return true;
c6056a74
SF
20370
20371 case NT_NETBSD_MARCH:
9abca702 20372 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20373 pnote->descdata);
015dc7e1 20374 return true;
c6056a74 20375
9abca702 20376 case NT_NETBSD_PAX:
b966f55f
AM
20377 if (pnote->descsz < 1)
20378 break;
9abca702
CZ
20379 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20380 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20381 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20382 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20383 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20384 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20385 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20386 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20387 return true;
c6056a74 20388 }
b966f55f
AM
20389
20390 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20391 pnote->descsz, pnote->type);
015dc7e1 20392 return false;
c6056a74
SF
20393}
20394
f4ddf30f 20395static const char *
dda8d76d 20396get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20397{
f4ddf30f
JB
20398 switch (e_type)
20399 {
20400 case NT_FREEBSD_THRMISC:
20401 return _("NT_THRMISC (thrmisc structure)");
20402 case NT_FREEBSD_PROCSTAT_PROC:
20403 return _("NT_PROCSTAT_PROC (proc data)");
20404 case NT_FREEBSD_PROCSTAT_FILES:
20405 return _("NT_PROCSTAT_FILES (files data)");
20406 case NT_FREEBSD_PROCSTAT_VMMAP:
20407 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20408 case NT_FREEBSD_PROCSTAT_GROUPS:
20409 return _("NT_PROCSTAT_GROUPS (groups data)");
20410 case NT_FREEBSD_PROCSTAT_UMASK:
20411 return _("NT_PROCSTAT_UMASK (umask data)");
20412 case NT_FREEBSD_PROCSTAT_RLIMIT:
20413 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20414 case NT_FREEBSD_PROCSTAT_OSREL:
20415 return _("NT_PROCSTAT_OSREL (osreldate data)");
20416 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20417 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20418 case NT_FREEBSD_PROCSTAT_AUXV:
20419 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20420 case NT_FREEBSD_PTLWPINFO:
20421 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20422 case NT_FREEBSD_X86_SEGBASES:
20423 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20424 }
dda8d76d 20425 return get_note_type (filedata, e_type);
f4ddf30f
JB
20426}
20427
9437c45b 20428static const char *
dda8d76d 20429get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20430{
20431 static char buff[64];
20432
540e6170
CZ
20433 switch (e_type)
20434 {
20435 case NT_NETBSDCORE_PROCINFO:
20436 /* NetBSD core "procinfo" structure. */
20437 return _("NetBSD procinfo structure");
9437c45b 20438
540e6170
CZ
20439 case NT_NETBSDCORE_AUXV:
20440 return _("NetBSD ELF auxiliary vector data");
9437c45b 20441
06d949ec
KR
20442 case NT_NETBSDCORE_LWPSTATUS:
20443 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20444
540e6170 20445 default:
06d949ec 20446 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20447 defined for NetBSD core files. If the note type is less
20448 than the start of the machine-dependent note types, we don't
20449 understand it. */
20450
20451 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20452 {
20453 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20454 return buff;
20455 }
20456 break;
9437c45b
JT
20457 }
20458
dda8d76d 20459 switch (filedata->file_header.e_machine)
9437c45b
JT
20460 {
20461 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20462 and PT_GETFPREGS == mach+2. */
20463
20464 case EM_OLD_ALPHA:
20465 case EM_ALPHA:
20466 case EM_SPARC:
20467 case EM_SPARC32PLUS:
20468 case EM_SPARCV9:
20469 switch (e_type)
20470 {
2b692964 20471 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20472 return _("PT_GETREGS (reg structure)");
2b692964 20473 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20474 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20475 default:
20476 break;
20477 }
20478 break;
20479
c0d38b0e
CZ
20480 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20481 There's also old PT___GETREGS40 == mach + 1 for old reg
20482 structure which lacks GBR. */
20483 case EM_SH:
20484 switch (e_type)
20485 {
20486 case NT_NETBSDCORE_FIRSTMACH + 1:
20487 return _("PT___GETREGS40 (old reg structure)");
20488 case NT_NETBSDCORE_FIRSTMACH + 3:
20489 return _("PT_GETREGS (reg structure)");
20490 case NT_NETBSDCORE_FIRSTMACH + 5:
20491 return _("PT_GETFPREGS (fpreg structure)");
20492 default:
20493 break;
20494 }
20495 break;
20496
9437c45b
JT
20497 /* On all other arch's, PT_GETREGS == mach+1 and
20498 PT_GETFPREGS == mach+3. */
20499 default:
20500 switch (e_type)
20501 {
2b692964 20502 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20503 return _("PT_GETREGS (reg structure)");
2b692964 20504 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20505 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20506 default:
20507 break;
20508 }
20509 }
20510
9cf03b7e 20511 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20512 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20513 return buff;
20514}
20515
98ca73af
FC
20516static const char *
20517get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20518{
20519 switch (e_type)
20520 {
20521 case NT_OPENBSD_PROCINFO:
20522 return _("OpenBSD procinfo structure");
20523 case NT_OPENBSD_AUXV:
20524 return _("OpenBSD ELF auxiliary vector data");
20525 case NT_OPENBSD_REGS:
20526 return _("OpenBSD regular registers");
20527 case NT_OPENBSD_FPREGS:
20528 return _("OpenBSD floating point registers");
20529 case NT_OPENBSD_WCOOKIE:
20530 return _("OpenBSD window cookie");
20531 }
20532
20533 return get_note_type (filedata, e_type);
20534}
20535
70616151
TT
20536static const char *
20537get_stapsdt_note_type (unsigned e_type)
20538{
20539 static char buff[64];
20540
20541 switch (e_type)
20542 {
20543 case NT_STAPSDT:
20544 return _("NT_STAPSDT (SystemTap probe descriptors)");
20545
20546 default:
20547 break;
20548 }
20549
20550 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20551 return buff;
20552}
20553
015dc7e1 20554static bool
c6a9fc58
TT
20555print_stapsdt_note (Elf_Internal_Note *pnote)
20556{
3ca60c57
NC
20557 size_t len, maxlen;
20558 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20559 char *data = pnote->descdata;
20560 char *data_end = pnote->descdata + pnote->descsz;
20561 bfd_vma pc, base_addr, semaphore;
20562 char *provider, *probe, *arg_fmt;
20563
3ca60c57
NC
20564 if (pnote->descsz < (addr_size * 3))
20565 goto stapdt_note_too_small;
20566
c6a9fc58
TT
20567 pc = byte_get ((unsigned char *) data, addr_size);
20568 data += addr_size;
3ca60c57 20569
c6a9fc58
TT
20570 base_addr = byte_get ((unsigned char *) data, addr_size);
20571 data += addr_size;
3ca60c57 20572
c6a9fc58
TT
20573 semaphore = byte_get ((unsigned char *) data, addr_size);
20574 data += addr_size;
20575
3ca60c57
NC
20576 if (data >= data_end)
20577 goto stapdt_note_too_small;
20578 maxlen = data_end - data;
20579 len = strnlen (data, maxlen);
20580 if (len < maxlen)
20581 {
20582 provider = data;
20583 data += len + 1;
20584 }
20585 else
20586 goto stapdt_note_too_small;
20587
20588 if (data >= data_end)
20589 goto stapdt_note_too_small;
20590 maxlen = data_end - data;
20591 len = strnlen (data, maxlen);
20592 if (len < maxlen)
20593 {
20594 probe = data;
20595 data += len + 1;
20596 }
20597 else
20598 goto stapdt_note_too_small;
9abca702 20599
3ca60c57
NC
20600 if (data >= data_end)
20601 goto stapdt_note_too_small;
20602 maxlen = data_end - data;
20603 len = strnlen (data, maxlen);
20604 if (len < maxlen)
20605 {
20606 arg_fmt = data;
20607 data += len + 1;
20608 }
20609 else
20610 goto stapdt_note_too_small;
c6a9fc58
TT
20611
20612 printf (_(" Provider: %s\n"), provider);
20613 printf (_(" Name: %s\n"), probe);
20614 printf (_(" Location: "));
20615 print_vma (pc, FULL_HEX);
20616 printf (_(", Base: "));
20617 print_vma (base_addr, FULL_HEX);
20618 printf (_(", Semaphore: "));
20619 print_vma (semaphore, FULL_HEX);
9cf03b7e 20620 printf ("\n");
c6a9fc58
TT
20621 printf (_(" Arguments: %s\n"), arg_fmt);
20622
20623 return data == data_end;
3ca60c57
NC
20624
20625 stapdt_note_too_small:
20626 printf (_(" <corrupt - note is too small>\n"));
20627 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20628 return false;
c6a9fc58
TT
20629}
20630
e5382207
LB
20631static bool
20632print_fdo_note (Elf_Internal_Note * pnote)
20633{
20634 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20635 {
20636 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20637 return true;
20638 }
20639 return false;
20640}
20641
00e98fc7
TG
20642static const char *
20643get_ia64_vms_note_type (unsigned e_type)
20644{
20645 static char buff[64];
20646
20647 switch (e_type)
20648 {
20649 case NT_VMS_MHD:
20650 return _("NT_VMS_MHD (module header)");
20651 case NT_VMS_LNM:
20652 return _("NT_VMS_LNM (language name)");
20653 case NT_VMS_SRC:
20654 return _("NT_VMS_SRC (source files)");
20655 case NT_VMS_TITLE:
9cf03b7e 20656 return "NT_VMS_TITLE";
00e98fc7
TG
20657 case NT_VMS_EIDC:
20658 return _("NT_VMS_EIDC (consistency check)");
20659 case NT_VMS_FPMODE:
20660 return _("NT_VMS_FPMODE (FP mode)");
20661 case NT_VMS_LINKTIME:
9cf03b7e 20662 return "NT_VMS_LINKTIME";
00e98fc7
TG
20663 case NT_VMS_IMGNAM:
20664 return _("NT_VMS_IMGNAM (image name)");
20665 case NT_VMS_IMGID:
20666 return _("NT_VMS_IMGID (image id)");
20667 case NT_VMS_LINKID:
20668 return _("NT_VMS_LINKID (link id)");
20669 case NT_VMS_IMGBID:
20670 return _("NT_VMS_IMGBID (build id)");
20671 case NT_VMS_GSTNAM:
20672 return _("NT_VMS_GSTNAM (sym table name)");
20673 case NT_VMS_ORIG_DYN:
9cf03b7e 20674 return "NT_VMS_ORIG_DYN";
00e98fc7 20675 case NT_VMS_PATCHTIME:
9cf03b7e 20676 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20677 default:
20678 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20679 return buff;
20680 }
20681}
20682
015dc7e1 20683static bool
00e98fc7
TG
20684print_ia64_vms_note (Elf_Internal_Note * pnote)
20685{
8d18bf79
NC
20686 int maxlen = pnote->descsz;
20687
20688 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20689 goto desc_size_fail;
20690
00e98fc7
TG
20691 switch (pnote->type)
20692 {
20693 case NT_VMS_MHD:
8d18bf79
NC
20694 if (maxlen <= 36)
20695 goto desc_size_fail;
20696
20697 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20698
20699 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20700 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20701 if (l + 34 < maxlen)
20702 {
20703 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20704 if (l + 35 < maxlen)
20705 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20706 else
20707 printf (_(" Module version : <missing>\n"));
20708 }
00e98fc7 20709 else
8d18bf79
NC
20710 {
20711 printf (_(" Module name : <missing>\n"));
20712 printf (_(" Module version : <missing>\n"));
20713 }
00e98fc7 20714 break;
8d18bf79 20715
00e98fc7 20716 case NT_VMS_LNM:
8d18bf79 20717 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20718 break;
8d18bf79 20719
00e98fc7
TG
20720#ifdef BFD64
20721 case NT_VMS_FPMODE:
9cf03b7e 20722 printf (_(" Floating Point mode: "));
8d18bf79
NC
20723 if (maxlen < 8)
20724 goto desc_size_fail;
20725 /* FIXME: Generate an error if descsz > 8 ? */
20726
b8281767
AM
20727 printf ("0x%016" PRIx64 "\n",
20728 (uint64_t) byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20729 break;
8d18bf79 20730
00e98fc7
TG
20731 case NT_VMS_LINKTIME:
20732 printf (_(" Link time: "));
8d18bf79
NC
20733 if (maxlen < 8)
20734 goto desc_size_fail;
20735 /* FIXME: Generate an error if descsz > 8 ? */
20736
0e3c1eeb 20737 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20738 printf ("\n");
20739 break;
8d18bf79 20740
00e98fc7
TG
20741 case NT_VMS_PATCHTIME:
20742 printf (_(" Patch time: "));
8d18bf79
NC
20743 if (maxlen < 8)
20744 goto desc_size_fail;
20745 /* FIXME: Generate an error if descsz > 8 ? */
20746
0e3c1eeb 20747 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20748 printf ("\n");
20749 break;
8d18bf79 20750
00e98fc7 20751 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20752 if (maxlen < 34)
20753 goto desc_size_fail;
20754
00e98fc7 20755 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20756 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20757 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20758 printf (_(" Last modified : "));
0e3c1eeb 20759 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20760 printf (_("\n Link flags : "));
b8281767
AM
20761 printf ("0x%016" PRIx64 "\n",
20762 (uint64_t) byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20763 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20764 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20765 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20766 break;
20767#endif
8d18bf79 20768
00e98fc7 20769 case NT_VMS_IMGNAM:
8d18bf79 20770 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20771 break;
8d18bf79 20772
00e98fc7 20773 case NT_VMS_GSTNAM:
8d18bf79 20774 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20775 break;
8d18bf79 20776
00e98fc7 20777 case NT_VMS_IMGID:
8d18bf79 20778 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20779 break;
8d18bf79 20780
00e98fc7 20781 case NT_VMS_LINKID:
8d18bf79 20782 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20783 break;
8d18bf79 20784
00e98fc7 20785 default:
015dc7e1 20786 return false;
00e98fc7 20787 }
8d18bf79 20788
015dc7e1 20789 return true;
8d18bf79
NC
20790
20791 desc_size_fail:
20792 printf (_(" <corrupt - data size is too small>\n"));
20793 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20794 return false;
00e98fc7
TG
20795}
20796
fd486f32
AM
20797struct build_attr_cache {
20798 Filedata *filedata;
20799 char *strtab;
20800 unsigned long strtablen;
20801 Elf_Internal_Sym *symtab;
20802 unsigned long nsyms;
20803} ba_cache;
20804
6f156d7a
NC
20805/* Find the symbol associated with a build attribute that is attached
20806 to address OFFSET. If PNAME is non-NULL then store the name of
20807 the symbol (if found) in the provided pointer, Returns NULL if a
20808 symbol could not be found. */
c799a79d 20809
6f156d7a 20810static Elf_Internal_Sym *
015dc7e1
AM
20811get_symbol_for_build_attribute (Filedata *filedata,
20812 unsigned long offset,
20813 bool is_open_attr,
20814 const char **pname)
9ef920e9 20815{
fd486f32
AM
20816 Elf_Internal_Sym *saved_sym = NULL;
20817 Elf_Internal_Sym *sym;
9ef920e9 20818
dda8d76d 20819 if (filedata->section_headers != NULL
fd486f32 20820 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20821 {
c799a79d 20822 Elf_Internal_Shdr * symsec;
9ef920e9 20823
fd486f32
AM
20824 free (ba_cache.strtab);
20825 ba_cache.strtab = NULL;
20826 free (ba_cache.symtab);
20827 ba_cache.symtab = NULL;
20828
c799a79d 20829 /* Load the symbol and string sections. */
dda8d76d
NC
20830 for (symsec = filedata->section_headers;
20831 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20832 symsec ++)
9ef920e9 20833 {
28d13567
AM
20834 if (symsec->sh_type == SHT_SYMTAB
20835 && get_symtab (filedata, symsec,
20836 &ba_cache.symtab, &ba_cache.nsyms,
20837 &ba_cache.strtab, &ba_cache.strtablen))
20838 break;
9ef920e9 20839 }
fd486f32 20840 ba_cache.filedata = filedata;
9ef920e9
NC
20841 }
20842
fd486f32 20843 if (ba_cache.symtab == NULL)
6f156d7a 20844 return NULL;
9ef920e9 20845
c799a79d 20846 /* Find a symbol whose value matches offset. */
fd486f32 20847 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20848 if (sym->st_value == offset)
20849 {
fd486f32 20850 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20851 /* Huh ? This should not happen. */
20852 continue;
9ef920e9 20853
fd486f32 20854 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20855 continue;
9ef920e9 20856
9b9b1092 20857 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20858 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20859 if (ba_cache.strtab[sym->st_name] == '$'
20860 && ba_cache.strtab[sym->st_name + 1] != 0
20861 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20862 continue;
20863
c799a79d
NC
20864 if (is_open_attr)
20865 {
20866 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20867 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20868 FUNC symbols entirely. */
20869 switch (ELF_ST_TYPE (sym->st_info))
20870 {
c799a79d 20871 case STT_OBJECT:
6f156d7a 20872 case STT_FILE:
c799a79d 20873 saved_sym = sym;
6f156d7a
NC
20874 if (sym->st_size)
20875 {
20876 /* If the symbol has a size associated
20877 with it then we can stop searching. */
fd486f32 20878 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20879 }
c799a79d 20880 continue;
9ef920e9 20881
c799a79d
NC
20882 case STT_FUNC:
20883 /* Ignore function symbols. */
20884 continue;
20885
20886 default:
20887 break;
20888 }
20889
20890 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20891 {
c799a79d
NC
20892 case STB_GLOBAL:
20893 if (saved_sym == NULL
20894 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20895 saved_sym = sym;
20896 break;
c871dade 20897
c799a79d
NC
20898 case STB_LOCAL:
20899 if (saved_sym == NULL)
20900 saved_sym = sym;
20901 break;
20902
20903 default:
9ef920e9
NC
20904 break;
20905 }
20906 }
c799a79d
NC
20907 else
20908 {
20909 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20910 continue;
20911
20912 saved_sym = sym;
20913 break;
20914 }
20915 }
20916
6f156d7a 20917 if (saved_sym && pname)
fd486f32 20918 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20919
20920 return saved_sym;
c799a79d
NC
20921}
20922
d20e98ab
NC
20923/* Returns true iff addr1 and addr2 are in the same section. */
20924
015dc7e1 20925static bool
d20e98ab
NC
20926same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20927{
20928 Elf_Internal_Shdr * a1;
20929 Elf_Internal_Shdr * a2;
20930
20931 a1 = find_section_by_address (filedata, addr1);
20932 a2 = find_section_by_address (filedata, addr2);
9abca702 20933
d20e98ab
NC
20934 return a1 == a2 && a1 != NULL;
20935}
20936
015dc7e1 20937static bool
dda8d76d
NC
20938print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20939 Filedata * filedata)
c799a79d 20940{
015dc7e1
AM
20941 static unsigned long global_offset = 0;
20942 static unsigned long global_end = 0;
20943 static unsigned long func_offset = 0;
20944 static unsigned long func_end = 0;
c871dade 20945
015dc7e1
AM
20946 Elf_Internal_Sym *sym;
20947 const char *name;
20948 unsigned long start;
20949 unsigned long end;
20950 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20951
20952 switch (pnote->descsz)
c799a79d 20953 {
6f156d7a
NC
20954 case 0:
20955 /* A zero-length description means that the range of
20956 the previous note of the same type should be used. */
c799a79d 20957 if (is_open_attr)
c871dade 20958 {
6f156d7a
NC
20959 if (global_end > global_offset)
20960 printf (_(" Applies to region from %#lx to %#lx\n"),
20961 global_offset, global_end);
20962 else
20963 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20964 }
20965 else
20966 {
6f156d7a
NC
20967 if (func_end > func_offset)
20968 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20969 else
20970 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20971 }
015dc7e1 20972 return true;
9ef920e9 20973
6f156d7a
NC
20974 case 4:
20975 start = byte_get ((unsigned char *) pnote->descdata, 4);
20976 end = 0;
20977 break;
20978
20979 case 8:
c74147bb
NC
20980 start = byte_get ((unsigned char *) pnote->descdata, 4);
20981 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20982 break;
20983
20984 case 16:
20985 start = byte_get ((unsigned char *) pnote->descdata, 8);
20986 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20987 break;
9abca702 20988
6f156d7a 20989 default:
c799a79d
NC
20990 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20991 printf (_(" <invalid descsz>"));
015dc7e1 20992 return false;
c799a79d
NC
20993 }
20994
6f156d7a
NC
20995 name = NULL;
20996 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20997 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20998 in order to avoid them being confused with the start address of the
20999 first function in the file... */
21000 if (sym == NULL && is_open_attr)
21001 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21002 & name);
6f156d7a
NC
21003
21004 if (end == 0 && sym != NULL && sym->st_size > 0)
21005 end = start + sym->st_size;
c799a79d
NC
21006
21007 if (is_open_attr)
21008 {
d20e98ab
NC
21009 /* FIXME: Need to properly allow for section alignment.
21010 16 is just the alignment used on x86_64. */
21011 if (global_end > 0
21012 && start > BFD_ALIGN (global_end, 16)
21013 /* Build notes are not guaranteed to be organised in order of
21014 increasing address, but we should find the all of the notes
21015 for one section in the same place. */
21016 && same_section (filedata, start, global_end))
6f156d7a
NC
21017 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21018 global_end + 1, start - 1);
21019
21020 printf (_(" Applies to region from %#lx"), start);
21021 global_offset = start;
21022
21023 if (end)
21024 {
21025 printf (_(" to %#lx"), end);
21026 global_end = end;
21027 }
c799a79d
NC
21028 }
21029 else
21030 {
6f156d7a
NC
21031 printf (_(" Applies to region from %#lx"), start);
21032 func_offset = start;
21033
21034 if (end)
21035 {
21036 printf (_(" to %#lx"), end);
21037 func_end = end;
21038 }
c799a79d
NC
21039 }
21040
6f156d7a
NC
21041 if (sym && name)
21042 printf (_(" (%s)"), name);
21043
21044 printf ("\n");
015dc7e1 21045 return true;
9ef920e9
NC
21046}
21047
015dc7e1 21048static bool
9ef920e9
NC
21049print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21050{
1d15e434
NC
21051 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21052 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21053 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21054 char name_type;
21055 char name_attribute;
1d15e434 21056 const char * expected_types;
9ef920e9
NC
21057 const char * name = pnote->namedata;
21058 const char * text;
88305e1b 21059 signed int left;
9ef920e9
NC
21060
21061 if (name == NULL || pnote->namesz < 2)
21062 {
21063 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21064 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21065 return false;
9ef920e9
NC
21066 }
21067
6f156d7a
NC
21068 if (do_wide)
21069 left = 28;
21070 else
21071 left = 20;
88305e1b
NC
21072
21073 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21074 if (name[0] == 'G' && name[1] == 'A')
21075 {
6f156d7a
NC
21076 if (pnote->namesz < 4)
21077 {
21078 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21079 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21080 return false;
6f156d7a
NC
21081 }
21082
88305e1b
NC
21083 printf ("GA");
21084 name += 2;
21085 left -= 2;
21086 }
21087
9ef920e9
NC
21088 switch ((name_type = * name))
21089 {
21090 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21091 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21092 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21093 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21094 printf ("%c", * name);
88305e1b 21095 left --;
9ef920e9
NC
21096 break;
21097 default:
21098 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21099 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21100 return false;
9ef920e9
NC
21101 }
21102
9ef920e9
NC
21103 ++ name;
21104 text = NULL;
21105
21106 switch ((name_attribute = * name))
21107 {
21108 case GNU_BUILD_ATTRIBUTE_VERSION:
21109 text = _("<version>");
1d15e434 21110 expected_types = string_expected;
9ef920e9
NC
21111 ++ name;
21112 break;
21113 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21114 text = _("<stack prot>");
75d7d298 21115 expected_types = "!+*";
9ef920e9
NC
21116 ++ name;
21117 break;
21118 case GNU_BUILD_ATTRIBUTE_RELRO:
21119 text = _("<relro>");
1d15e434 21120 expected_types = bool_expected;
9ef920e9
NC
21121 ++ name;
21122 break;
21123 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21124 text = _("<stack size>");
1d15e434 21125 expected_types = number_expected;
9ef920e9
NC
21126 ++ name;
21127 break;
21128 case GNU_BUILD_ATTRIBUTE_TOOL:
21129 text = _("<tool>");
1d15e434 21130 expected_types = string_expected;
9ef920e9
NC
21131 ++ name;
21132 break;
21133 case GNU_BUILD_ATTRIBUTE_ABI:
21134 text = _("<ABI>");
21135 expected_types = "$*";
21136 ++ name;
21137 break;
21138 case GNU_BUILD_ATTRIBUTE_PIC:
21139 text = _("<PIC>");
1d15e434 21140 expected_types = number_expected;
9ef920e9
NC
21141 ++ name;
21142 break;
a8be5506
NC
21143 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21144 text = _("<short enum>");
1d15e434 21145 expected_types = bool_expected;
a8be5506
NC
21146 ++ name;
21147 break;
9ef920e9
NC
21148 default:
21149 if (ISPRINT (* name))
21150 {
21151 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21152
21153 if (len > left && ! do_wide)
21154 len = left;
75d7d298 21155 printf ("%.*s:", len, name);
9ef920e9 21156 left -= len;
0dd6ae21 21157 name += len;
9ef920e9
NC
21158 }
21159 else
21160 {
3e6b6445 21161 static char tmpbuf [128];
88305e1b 21162
3e6b6445
NC
21163 error (_("unrecognised byte in name field: %d\n"), * name);
21164 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21165 text = tmpbuf;
21166 name ++;
9ef920e9
NC
21167 }
21168 expected_types = "*$!+";
21169 break;
21170 }
21171
21172 if (text)
88305e1b 21173 left -= printf ("%s", text);
9ef920e9
NC
21174
21175 if (strchr (expected_types, name_type) == NULL)
75d7d298 21176 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21177
21178 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21179 {
21180 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21181 (unsigned long) pnote->namesz,
21182 (long) (name - pnote->namedata));
015dc7e1 21183 return false;
9ef920e9
NC
21184 }
21185
21186 if (left < 1 && ! do_wide)
015dc7e1 21187 return true;
9ef920e9
NC
21188
21189 switch (name_type)
21190 {
21191 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21192 {
b06b2c92 21193 unsigned int bytes;
ddef72cd
NC
21194 unsigned long long val = 0;
21195 unsigned int shift = 0;
21196 char * decoded = NULL;
21197
b06b2c92
NC
21198 bytes = pnote->namesz - (name - pnote->namedata);
21199 if (bytes > 0)
21200 /* The -1 is because the name field is always 0 terminated, and we
21201 want to be able to ensure that the shift in the while loop below
21202 will not overflow. */
21203 -- bytes;
21204
ddef72cd
NC
21205 if (bytes > sizeof (val))
21206 {
3e6b6445
NC
21207 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21208 bytes);
21209 bytes = sizeof (val);
ddef72cd 21210 }
3e6b6445
NC
21211 /* We do not bother to warn if bytes == 0 as this can
21212 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21213
21214 while (bytes --)
21215 {
54b8331d 21216 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21217
21218 val |= byte << shift;
9ef920e9
NC
21219 shift += 8;
21220 }
21221
75d7d298 21222 switch (name_attribute)
9ef920e9 21223 {
75d7d298 21224 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21225 switch (val)
21226 {
75d7d298
NC
21227 case 0: decoded = "static"; break;
21228 case 1: decoded = "pic"; break;
21229 case 2: decoded = "PIC"; break;
21230 case 3: decoded = "pie"; break;
21231 case 4: decoded = "PIE"; break;
21232 default: break;
9ef920e9 21233 }
75d7d298
NC
21234 break;
21235 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21236 switch (val)
9ef920e9 21237 {
75d7d298
NC
21238 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21239 case 0: decoded = "off"; break;
21240 case 1: decoded = "on"; break;
21241 case 2: decoded = "all"; break;
21242 case 3: decoded = "strong"; break;
21243 case 4: decoded = "explicit"; break;
21244 default: break;
9ef920e9 21245 }
75d7d298
NC
21246 break;
21247 default:
21248 break;
9ef920e9
NC
21249 }
21250
75d7d298 21251 if (decoded != NULL)
3e6b6445
NC
21252 {
21253 print_symbol (-left, decoded);
21254 left = 0;
21255 }
21256 else if (val == 0)
21257 {
21258 printf ("0x0");
21259 left -= 3;
21260 }
9ef920e9 21261 else
75d7d298
NC
21262 {
21263 if (do_wide)
ddef72cd 21264 left -= printf ("0x%llx", val);
75d7d298 21265 else
ddef72cd 21266 left -= printf ("0x%-.*llx", left, val);
75d7d298 21267 }
9ef920e9
NC
21268 }
21269 break;
21270 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21271 left -= print_symbol (- left, name);
21272 break;
21273 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21274 left -= print_symbol (- left, "true");
21275 break;
21276 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21277 left -= print_symbol (- left, "false");
21278 break;
21279 }
21280
21281 if (do_wide && left > 0)
21282 printf ("%-*s", left, " ");
9abca702 21283
015dc7e1 21284 return true;
9ef920e9
NC
21285}
21286
2952f10c
SM
21287/* Print the contents of PNOTE as hex. */
21288
21289static void
21290print_note_contents_hex (Elf_Internal_Note *pnote)
21291{
21292 if (pnote->descsz)
21293 {
21294 unsigned long i;
21295
21296 printf (_(" description data: "));
21297 for (i = 0; i < pnote->descsz; i++)
21298 printf ("%02x ", pnote->descdata[i] & 0xff);
21299 if (!do_wide)
21300 printf ("\n");
21301 }
21302
21303 if (do_wide)
21304 printf ("\n");
21305}
21306
21307#if defined HAVE_MSGPACK
21308
21309static void
21310print_indents (int n)
21311{
21312 printf (" ");
21313
21314 for (int i = 0; i < n; i++)
21315 printf (" ");
21316}
21317
21318/* Print OBJ in human-readable form. */
21319
21320static void
21321dump_msgpack_obj (const msgpack_object *obj, int indent)
21322{
21323 switch (obj->type)
21324 {
21325 case MSGPACK_OBJECT_NIL:
21326 printf ("(nil)");
21327 break;
21328
21329 case MSGPACK_OBJECT_BOOLEAN:
21330 printf ("%s", obj->via.boolean ? "true" : "false");
21331 break;
21332
21333 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21334 printf ("%" PRIu64, obj->via.u64);
21335 break;
21336
21337 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21338 printf ("%" PRIi64, obj->via.i64);
21339 break;
21340
21341 case MSGPACK_OBJECT_FLOAT32:
21342 case MSGPACK_OBJECT_FLOAT64:
21343 printf ("%f", obj->via.f64);
21344 break;
21345
21346 case MSGPACK_OBJECT_STR:
21347 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21348 break;
21349
21350 case MSGPACK_OBJECT_ARRAY:
21351 {
21352 const msgpack_object_array *array = &obj->via.array;
21353
21354 printf ("[\n");
21355 ++indent;
21356
21357 for (uint32_t i = 0; i < array->size; ++i)
21358 {
21359 const msgpack_object *item = &array->ptr[i];
21360
21361 print_indents (indent);
21362 dump_msgpack_obj (item, indent);
21363 printf (",\n");
21364 }
21365
21366 --indent;
21367 print_indents (indent);
21368 printf ("]");
21369 break;
21370 }
21371 break;
21372
21373 case MSGPACK_OBJECT_MAP:
21374 {
21375 const msgpack_object_map *map = &obj->via.map;
21376
21377 printf ("{\n");
21378 ++indent;
21379
21380 for (uint32_t i = 0; i < map->size; ++i)
21381 {
21382 const msgpack_object_kv *kv = &map->ptr[i];
21383 const msgpack_object *key = &kv->key;
21384 const msgpack_object *val = &kv->val;
21385
21386 print_indents (indent);
21387 dump_msgpack_obj (key, indent);
21388 printf (": ");
21389 dump_msgpack_obj (val, indent);
21390
21391 printf (",\n");
21392 }
21393
21394 --indent;
21395 print_indents (indent);
21396 printf ("}");
21397
21398 break;
21399 }
21400
21401 case MSGPACK_OBJECT_BIN:
21402 printf ("(bin)");
21403 break;
21404
21405 case MSGPACK_OBJECT_EXT:
21406 printf ("(ext)");
21407 break;
21408 }
21409}
21410
21411static void
21412dump_msgpack (const msgpack_unpacked *msg)
21413{
21414 print_indents (0);
21415 dump_msgpack_obj (&msg->data, 0);
21416 printf ("\n");
21417}
21418
21419#endif /* defined HAVE_MSGPACK */
21420
21421static bool
21422print_amdgpu_note (Elf_Internal_Note *pnote)
21423{
21424#if defined HAVE_MSGPACK
21425 /* If msgpack is available, decode and dump the note's content. */
21426 bool ret;
21427 msgpack_unpacked msg;
21428 msgpack_unpack_return msgpack_ret;
21429
21430 assert (pnote->type == NT_AMDGPU_METADATA);
21431
21432 msgpack_unpacked_init (&msg);
21433 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21434 NULL);
21435
21436 switch (msgpack_ret)
21437 {
21438 case MSGPACK_UNPACK_SUCCESS:
21439 dump_msgpack (&msg);
21440 ret = true;
21441 break;
21442
21443 default:
21444 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21445 ret = false;
21446 break;
21447 }
21448
21449 msgpack_unpacked_destroy (&msg);
21450 return ret;
21451#else
21452 /* msgpack is not available, dump contents as hex. */
21453 print_note_contents_hex (pnote);
21454 return true;
21455#endif
21456}
21457
6d118b09
NC
21458/* Note that by the ELF standard, the name field is already null byte
21459 terminated, and namesz includes the terminating null byte.
21460 I.E. the value of namesz for the name "FSF" is 4.
21461
e3c8793a 21462 If the value of namesz is zero, there is no name present. */
9ef920e9 21463
015dc7e1 21464static bool
9ef920e9 21465process_note (Elf_Internal_Note * pnote,
dda8d76d 21466 Filedata * filedata)
779fe533 21467{
2cf0635d
NC
21468 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21469 const char * nt;
9437c45b
JT
21470
21471 if (pnote->namesz == 0)
1ec5cd37
NC
21472 /* If there is no note name, then use the default set of
21473 note type strings. */
dda8d76d 21474 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21475
24d127aa 21476 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21477 /* GNU-specific object file notes. */
21478 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21479
28cdbb18
SM
21480 else if (startswith (pnote->namedata, "AMDGPU"))
21481 /* AMDGPU-specific object file notes. */
21482 nt = get_amdgpu_elf_note_type (pnote->type);
21483
24d127aa 21484 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21485 /* FreeBSD-specific core file notes. */
dda8d76d 21486 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21487
24d127aa 21488 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21489 /* NetBSD-specific core file notes. */
dda8d76d 21490 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21491
24d127aa 21492 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21493 /* NetBSD-specific core file notes. */
21494 return process_netbsd_elf_note (pnote);
21495
24d127aa 21496 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21497 /* NetBSD-specific core file notes. */
21498 return process_netbsd_elf_note (pnote);
21499
98ca73af
FC
21500 else if (startswith (pnote->namedata, "OpenBSD"))
21501 /* OpenBSD-specific core file notes. */
21502 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21503
e9b095a5 21504 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21505 {
21506 /* SPU-specific core file notes. */
21507 nt = pnote->namedata + 4;
21508 name = "SPU";
21509 }
21510
24d127aa 21511 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21512 /* VMS/ia64-specific file notes. */
21513 nt = get_ia64_vms_note_type (pnote->type);
21514
24d127aa 21515 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21516 nt = get_stapsdt_note_type (pnote->type);
21517
9437c45b 21518 else
1ec5cd37
NC
21519 /* Don't recognize this note name; just use the default set of
21520 note type strings. */
dda8d76d 21521 nt = get_note_type (filedata, pnote->type);
9437c45b 21522
1449284b 21523 printf (" ");
9ef920e9 21524
24d127aa 21525 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21526 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21527 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21528 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21529 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21530 print_gnu_build_attribute_name (pnote);
21531 else
21532 print_symbol (-20, name);
21533
21534 if (do_wide)
21535 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21536 else
21537 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21538
24d127aa 21539 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21540 return print_ia64_vms_note (pnote);
24d127aa 21541 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21542 return print_gnu_note (filedata, pnote);
24d127aa 21543 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21544 return print_stapsdt_note (pnote);
24d127aa 21545 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21546 return print_core_note (pnote);
e5382207
LB
21547 else if (startswith (pnote->namedata, "FDO"))
21548 return print_fdo_note (pnote);
24d127aa 21549 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21550 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21551 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21552 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21553 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21554 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21555 else if (startswith (pnote->namedata, "AMDGPU")
21556 && pnote->type == NT_AMDGPU_METADATA)
21557 return print_amdgpu_note (pnote);
779fe533 21558
2952f10c 21559 print_note_contents_hex (pnote);
015dc7e1 21560 return true;
1449284b 21561}
6d118b09 21562
015dc7e1 21563static bool
dda8d76d
NC
21564process_notes_at (Filedata * filedata,
21565 Elf_Internal_Shdr * section,
21566 bfd_vma offset,
82ed9683
L
21567 bfd_vma length,
21568 bfd_vma align)
779fe533 21569{
015dc7e1
AM
21570 Elf_External_Note *pnotes;
21571 Elf_External_Note *external;
21572 char *end;
21573 bool res = true;
103f02d3 21574
779fe533 21575 if (length <= 0)
015dc7e1 21576 return false;
103f02d3 21577
1449284b
NC
21578 if (section)
21579 {
dda8d76d 21580 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21581 if (pnotes)
32ec8896 21582 {
dda8d76d 21583 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21584 {
21585 free (pnotes);
015dc7e1 21586 return false;
f761cb13 21587 }
32ec8896 21588 }
1449284b
NC
21589 }
21590 else
82ed9683 21591 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21592 _("notes"));
4dff97b2 21593
dd24e3da 21594 if (pnotes == NULL)
015dc7e1 21595 return false;
779fe533 21596
103f02d3 21597 external = pnotes;
103f02d3 21598
ca0e11aa
NC
21599 if (filedata->is_separate)
21600 printf (_("In linked file '%s': "), filedata->file_name);
21601 else
21602 printf ("\n");
1449284b 21603 if (section)
ca0e11aa 21604 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21605 else
ca0e11aa 21606 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21607 (unsigned long) offset, (unsigned long) length);
21608
82ed9683
L
21609 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21610 specifies that notes should be aligned to 4 bytes in 32-bit
21611 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21612 we also support 4 byte alignment in 64-bit objects. If section
21613 alignment is less than 4, we treate alignment as 4 bytes. */
21614 if (align < 4)
21615 align = 4;
21616 else if (align != 4 && align != 8)
21617 {
21618 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21619 (long) align);
a788aedd 21620 free (pnotes);
015dc7e1 21621 return false;
82ed9683
L
21622 }
21623
dbe15e4e 21624 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21625
c8071705
NC
21626 end = (char *) pnotes + length;
21627 while ((char *) external < end)
779fe533 21628 {
b34976b6 21629 Elf_Internal_Note inote;
15b42fb0 21630 size_t min_notesz;
4dff97b2 21631 char * next;
2cf0635d 21632 char * temp = NULL;
c8071705 21633 size_t data_remaining = end - (char *) external;
6d118b09 21634
dda8d76d 21635 if (!is_ia64_vms (filedata))
15b42fb0 21636 {
9dd3a467
NC
21637 /* PR binutils/15191
21638 Make sure that there is enough data to read. */
15b42fb0
AM
21639 min_notesz = offsetof (Elf_External_Note, name);
21640 if (data_remaining < min_notesz)
9dd3a467 21641 {
d3a49aa8
AM
21642 warn (ngettext ("Corrupt note: only %ld byte remains, "
21643 "not enough for a full note\n",
21644 "Corrupt note: only %ld bytes remain, "
21645 "not enough for a full note\n",
21646 data_remaining),
21647 (long) data_remaining);
9dd3a467
NC
21648 break;
21649 }
5396a86e
AM
21650 data_remaining -= min_notesz;
21651
15b42fb0
AM
21652 inote.type = BYTE_GET (external->type);
21653 inote.namesz = BYTE_GET (external->namesz);
21654 inote.namedata = external->name;
21655 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21656 inote.descdata = ((char *) external
4dff97b2 21657 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21658 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21659 next = ((char *) external
4dff97b2 21660 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21661 }
00e98fc7 21662 else
15b42fb0
AM
21663 {
21664 Elf64_External_VMS_Note *vms_external;
00e98fc7 21665
9dd3a467
NC
21666 /* PR binutils/15191
21667 Make sure that there is enough data to read. */
15b42fb0
AM
21668 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21669 if (data_remaining < min_notesz)
9dd3a467 21670 {
d3a49aa8
AM
21671 warn (ngettext ("Corrupt note: only %ld byte remains, "
21672 "not enough for a full note\n",
21673 "Corrupt note: only %ld bytes remain, "
21674 "not enough for a full note\n",
21675 data_remaining),
21676 (long) data_remaining);
9dd3a467
NC
21677 break;
21678 }
5396a86e 21679 data_remaining -= min_notesz;
3e55a963 21680
15b42fb0
AM
21681 vms_external = (Elf64_External_VMS_Note *) external;
21682 inote.type = BYTE_GET (vms_external->type);
21683 inote.namesz = BYTE_GET (vms_external->namesz);
21684 inote.namedata = vms_external->name;
21685 inote.descsz = BYTE_GET (vms_external->descsz);
21686 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21687 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21688 next = inote.descdata + align_power (inote.descsz, 3);
21689 }
21690
5396a86e
AM
21691 /* PR 17531: file: 3443835e. */
21692 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21693 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21694 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21695 || (size_t) (next - inote.descdata) < inote.descsz
21696 || ((size_t) (next - inote.descdata)
21697 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21698 {
15b42fb0 21699 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21700 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21701 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21702 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21703 break;
21704 }
21705
15b42fb0 21706 external = (Elf_External_Note *) next;
dd24e3da 21707
6d118b09
NC
21708 /* Verify that name is null terminated. It appears that at least
21709 one version of Linux (RedHat 6.0) generates corefiles that don't
21710 comply with the ELF spec by failing to include the null byte in
21711 namesz. */
18344509 21712 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21713 {
5396a86e 21714 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21715 {
5396a86e
AM
21716 temp = (char *) malloc (inote.namesz + 1);
21717 if (temp == NULL)
21718 {
21719 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21720 res = false;
5396a86e
AM
21721 break;
21722 }
76da6bbe 21723
5396a86e
AM
21724 memcpy (temp, inote.namedata, inote.namesz);
21725 inote.namedata = temp;
21726 }
21727 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21728 }
21729
dda8d76d 21730 if (! process_note (& inote, filedata))
015dc7e1 21731 res = false;
103f02d3 21732
9db70fc3
AM
21733 free (temp);
21734 temp = NULL;
779fe533
NC
21735 }
21736
21737 free (pnotes);
103f02d3 21738
779fe533
NC
21739 return res;
21740}
21741
015dc7e1 21742static bool
dda8d76d 21743process_corefile_note_segments (Filedata * filedata)
779fe533 21744{
015dc7e1 21745 Elf_Internal_Phdr *segment;
b34976b6 21746 unsigned int i;
015dc7e1 21747 bool res = true;
103f02d3 21748
dda8d76d 21749 if (! get_program_headers (filedata))
015dc7e1 21750 return true;
103f02d3 21751
dda8d76d
NC
21752 for (i = 0, segment = filedata->program_headers;
21753 i < filedata->file_header.e_phnum;
b34976b6 21754 i++, segment++)
779fe533
NC
21755 {
21756 if (segment->p_type == PT_NOTE)
dda8d76d 21757 if (! process_notes_at (filedata, NULL,
32ec8896 21758 (bfd_vma) segment->p_offset,
82ed9683
L
21759 (bfd_vma) segment->p_filesz,
21760 (bfd_vma) segment->p_align))
015dc7e1 21761 res = false;
779fe533 21762 }
103f02d3 21763
779fe533
NC
21764 return res;
21765}
21766
015dc7e1 21767static bool
dda8d76d 21768process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21769{
21770 Elf_External_Note * pnotes;
21771 Elf_External_Note * external;
c8071705 21772 char * end;
015dc7e1 21773 bool res = true;
685080f2
NC
21774
21775 if (length <= 0)
015dc7e1 21776 return false;
685080f2 21777
dda8d76d 21778 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21779 _("v850 notes"));
21780 if (pnotes == NULL)
015dc7e1 21781 return false;
685080f2
NC
21782
21783 external = pnotes;
c8071705 21784 end = (char*) pnotes + length;
685080f2
NC
21785
21786 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21787 (unsigned long) offset, (unsigned long) length);
21788
c8071705 21789 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21790 {
21791 Elf_External_Note * next;
21792 Elf_Internal_Note inote;
21793
21794 inote.type = BYTE_GET (external->type);
21795 inote.namesz = BYTE_GET (external->namesz);
21796 inote.namedata = external->name;
21797 inote.descsz = BYTE_GET (external->descsz);
21798 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21799 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21800
c8071705
NC
21801 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21802 {
21803 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21804 inote.descdata = inote.namedata;
21805 inote.namesz = 0;
21806 }
21807
685080f2
NC
21808 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21809
c8071705 21810 if ( ((char *) next > end)
685080f2
NC
21811 || ((char *) next < (char *) pnotes))
21812 {
21813 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21814 (unsigned long) ((char *) external - (char *) pnotes));
21815 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21816 inote.type, inote.namesz, inote.descsz);
21817 break;
21818 }
21819
21820 external = next;
21821
21822 /* Prevent out-of-bounds indexing. */
c8071705 21823 if ( inote.namedata + inote.namesz > end
685080f2
NC
21824 || inote.namedata + inote.namesz < inote.namedata)
21825 {
21826 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21827 (unsigned long) ((char *) external - (char *) pnotes));
21828 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21829 inote.type, inote.namesz, inote.descsz);
21830 break;
21831 }
21832
21833 printf (" %s: ", get_v850_elf_note_type (inote.type));
21834
21835 if (! print_v850_note (& inote))
21836 {
015dc7e1 21837 res = false;
685080f2
NC
21838 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21839 inote.namesz, inote.descsz);
21840 }
21841 }
21842
21843 free (pnotes);
21844
21845 return res;
21846}
21847
015dc7e1 21848static bool
dda8d76d 21849process_note_sections (Filedata * filedata)
1ec5cd37 21850{
015dc7e1 21851 Elf_Internal_Shdr *section;
1ec5cd37 21852 unsigned long i;
32ec8896 21853 unsigned int n = 0;
015dc7e1 21854 bool res = true;
1ec5cd37 21855
dda8d76d
NC
21856 for (i = 0, section = filedata->section_headers;
21857 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21858 i++, section++)
685080f2
NC
21859 {
21860 if (section->sh_type == SHT_NOTE)
21861 {
dda8d76d 21862 if (! process_notes_at (filedata, section,
32ec8896 21863 (bfd_vma) section->sh_offset,
82ed9683
L
21864 (bfd_vma) section->sh_size,
21865 (bfd_vma) section->sh_addralign))
015dc7e1 21866 res = false;
685080f2
NC
21867 n++;
21868 }
21869
dda8d76d
NC
21870 if (( filedata->file_header.e_machine == EM_V800
21871 || filedata->file_header.e_machine == EM_V850
21872 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21873 && section->sh_type == SHT_RENESAS_INFO)
21874 {
dda8d76d 21875 if (! process_v850_notes (filedata,
32ec8896
NC
21876 (bfd_vma) section->sh_offset,
21877 (bfd_vma) section->sh_size))
015dc7e1 21878 res = false;
685080f2
NC
21879 n++;
21880 }
21881 }
df565f32
NC
21882
21883 if (n == 0)
21884 /* Try processing NOTE segments instead. */
dda8d76d 21885 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21886
21887 return res;
21888}
21889
015dc7e1 21890static bool
dda8d76d 21891process_notes (Filedata * filedata)
779fe533
NC
21892{
21893 /* If we have not been asked to display the notes then do nothing. */
21894 if (! do_notes)
015dc7e1 21895 return true;
103f02d3 21896
dda8d76d
NC
21897 if (filedata->file_header.e_type != ET_CORE)
21898 return process_note_sections (filedata);
103f02d3 21899
779fe533 21900 /* No program headers means no NOTE segment. */
dda8d76d
NC
21901 if (filedata->file_header.e_phnum > 0)
21902 return process_corefile_note_segments (filedata);
779fe533 21903
ca0e11aa
NC
21904 if (filedata->is_separate)
21905 printf (_("No notes found in linked file '%s'.\n"),
21906 filedata->file_name);
21907 else
21908 printf (_("No notes found file.\n"));
21909
015dc7e1 21910 return true;
779fe533
NC
21911}
21912
60abdbed
NC
21913static unsigned char *
21914display_public_gnu_attributes (unsigned char * start,
21915 const unsigned char * const end)
21916{
21917 printf (_(" Unknown GNU attribute: %s\n"), start);
21918
21919 start += strnlen ((char *) start, end - start);
21920 display_raw_attribute (start, end);
21921
21922 return (unsigned char *) end;
21923}
21924
21925static unsigned char *
21926display_generic_attribute (unsigned char * start,
21927 unsigned int tag,
21928 const unsigned char * const end)
21929{
21930 if (tag == 0)
21931 return (unsigned char *) end;
21932
21933 return display_tag_value (tag, start, end);
21934}
21935
015dc7e1 21936static bool
dda8d76d 21937process_arch_specific (Filedata * filedata)
252b5132 21938{
a952a375 21939 if (! do_arch)
015dc7e1 21940 return true;
a952a375 21941
dda8d76d 21942 switch (filedata->file_header.e_machine)
252b5132 21943 {
53a346d8
CZ
21944 case EM_ARC:
21945 case EM_ARC_COMPACT:
21946 case EM_ARC_COMPACT2:
dda8d76d 21947 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21948 display_arc_attribute,
21949 display_generic_attribute);
11c1ff18 21950 case EM_ARM:
dda8d76d 21951 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21952 display_arm_attribute,
21953 display_generic_attribute);
21954
252b5132 21955 case EM_MIPS:
4fe85591 21956 case EM_MIPS_RS3_LE:
dda8d76d 21957 return process_mips_specific (filedata);
60abdbed
NC
21958
21959 case EM_MSP430:
dda8d76d 21960 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21961 display_msp430_attribute,
c0ea7c52 21962 display_msp430_gnu_attribute);
60abdbed 21963
2dc8dd17
JW
21964 case EM_RISCV:
21965 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21966 display_riscv_attribute,
21967 display_generic_attribute);
21968
35c08157 21969 case EM_NDS32:
dda8d76d 21970 return process_nds32_specific (filedata);
60abdbed 21971
85f7484a
PB
21972 case EM_68K:
21973 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21974 display_m68k_gnu_attribute);
21975
34c8bcba 21976 case EM_PPC:
b82317dd 21977 case EM_PPC64:
dda8d76d 21978 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21979 display_power_gnu_attribute);
21980
643f7afb
AK
21981 case EM_S390:
21982 case EM_S390_OLD:
dda8d76d 21983 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21984 display_s390_gnu_attribute);
21985
9e8c70f9
DM
21986 case EM_SPARC:
21987 case EM_SPARC32PLUS:
21988 case EM_SPARCV9:
dda8d76d 21989 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21990 display_sparc_gnu_attribute);
21991
59e6276b 21992 case EM_TI_C6000:
dda8d76d 21993 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21994 display_tic6x_attribute,
21995 display_generic_attribute);
21996
0861f561
CQ
21997 case EM_CSKY:
21998 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21999 display_csky_attribute, NULL);
22000
252b5132 22001 default:
dda8d76d 22002 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22003 display_public_gnu_attributes,
22004 display_generic_attribute);
252b5132 22005 }
252b5132
RH
22006}
22007
015dc7e1 22008static bool
dda8d76d 22009get_file_header (Filedata * filedata)
252b5132 22010{
9ea033b2 22011 /* Read in the identity array. */
dda8d76d 22012 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22013 return false;
252b5132 22014
9ea033b2 22015 /* Determine how to read the rest of the header. */
dda8d76d 22016 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22017 {
1a0670f3
AM
22018 default:
22019 case ELFDATANONE:
adab8cdc
AO
22020 case ELFDATA2LSB:
22021 byte_get = byte_get_little_endian;
22022 byte_put = byte_put_little_endian;
22023 break;
22024 case ELFDATA2MSB:
22025 byte_get = byte_get_big_endian;
22026 byte_put = byte_put_big_endian;
22027 break;
9ea033b2
NC
22028 }
22029
22030 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22031 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22032
22033 /* Read in the rest of the header. */
22034 if (is_32bit_elf)
22035 {
22036 Elf32_External_Ehdr ehdr32;
252b5132 22037
dda8d76d 22038 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22039 return false;
103f02d3 22040
dda8d76d
NC
22041 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22042 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22043 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22044 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22045 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22046 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22047 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22048 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22049 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22050 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22051 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22052 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22053 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22054 }
252b5132 22055 else
9ea033b2
NC
22056 {
22057 Elf64_External_Ehdr ehdr64;
a952a375
NC
22058
22059 /* If we have been compiled with sizeof (bfd_vma) == 4, then
22060 we will not be able to cope with the 64bit data found in
22061 64 ELF files. Detect this now and abort before we start
50c2245b 22062 overwriting things. */
a952a375
NC
22063 if (sizeof (bfd_vma) < 8)
22064 {
e3c8793a
NC
22065 error (_("This instance of readelf has been built without support for a\n\
2206664 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 22067 return false;
a952a375 22068 }
103f02d3 22069
dda8d76d 22070 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22071 return false;
103f02d3 22072
dda8d76d
NC
22073 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22074 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22075 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22076 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22077 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22078 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22079 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22080 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22081 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22082 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22083 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22084 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22085 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22086 }
252b5132 22087
015dc7e1 22088 return true;
252b5132
RH
22089}
22090
13acb58d
AM
22091static void
22092free_filedata (Filedata *filedata)
22093{
22094 free (filedata->program_interpreter);
13acb58d 22095 free (filedata->program_headers);
13acb58d 22096 free (filedata->section_headers);
13acb58d 22097 free (filedata->string_table);
13acb58d 22098 free (filedata->dump.dump_sects);
13acb58d 22099 free (filedata->dynamic_strings);
13acb58d 22100 free (filedata->dynamic_symbols);
13acb58d 22101 free (filedata->dynamic_syminfo);
13acb58d 22102 free (filedata->dynamic_section);
13acb58d
AM
22103
22104 while (filedata->symtab_shndx_list != NULL)
22105 {
22106 elf_section_list *next = filedata->symtab_shndx_list->next;
22107 free (filedata->symtab_shndx_list);
22108 filedata->symtab_shndx_list = next;
22109 }
22110
22111 free (filedata->section_headers_groups);
13acb58d
AM
22112
22113 if (filedata->section_groups)
22114 {
22115 size_t i;
22116 struct group_list * g;
22117 struct group_list * next;
22118
22119 for (i = 0; i < filedata->group_count; i++)
22120 {
22121 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22122 {
22123 next = g->next;
22124 free (g);
22125 }
22126 }
22127
22128 free (filedata->section_groups);
13acb58d 22129 }
066f8fbe
AM
22130 memset (&filedata->section_headers, 0,
22131 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22132}
22133
dda8d76d
NC
22134static void
22135close_file (Filedata * filedata)
22136{
22137 if (filedata)
22138 {
22139 if (filedata->handle)
22140 fclose (filedata->handle);
22141 free (filedata);
22142 }
22143}
22144
22145void
22146close_debug_file (void * data)
22147{
13acb58d 22148 free_filedata ((Filedata *) data);
dda8d76d
NC
22149 close_file ((Filedata *) data);
22150}
22151
22152static Filedata *
015dc7e1 22153open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22154{
22155 struct stat statbuf;
22156 Filedata * filedata = NULL;
22157
22158 if (stat (pathname, & statbuf) < 0
22159 || ! S_ISREG (statbuf.st_mode))
22160 goto fail;
22161
22162 filedata = calloc (1, sizeof * filedata);
22163 if (filedata == NULL)
22164 goto fail;
22165
22166 filedata->handle = fopen (pathname, "rb");
22167 if (filedata->handle == NULL)
22168 goto fail;
22169
22170 filedata->file_size = (bfd_size_type) statbuf.st_size;
22171 filedata->file_name = pathname;
ca0e11aa 22172 filedata->is_separate = is_separate;
dda8d76d
NC
22173
22174 if (! get_file_header (filedata))
22175 goto fail;
22176
4de91c10
AM
22177 if (!get_section_headers (filedata, false))
22178 goto fail;
dda8d76d
NC
22179
22180 return filedata;
22181
22182 fail:
22183 if (filedata)
22184 {
22185 if (filedata->handle)
22186 fclose (filedata->handle);
22187 free (filedata);
22188 }
22189 return NULL;
22190}
22191
22192void *
22193open_debug_file (const char * pathname)
22194{
015dc7e1 22195 return open_file (pathname, true);
dda8d76d
NC
22196}
22197
835f2fae
NC
22198static void
22199initialise_dump_sects (Filedata * filedata)
22200{
22201 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22202 Note we do this even if cmdline_dump_sects is empty because we
22203 must make sure that the dump_sets array is zeroed out before each
22204 object file is processed. */
22205 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22206 memset (filedata->dump.dump_sects, 0,
22207 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22208
22209 if (cmdline.num_dump_sects > 0)
22210 {
22211 if (filedata->dump.num_dump_sects == 0)
22212 /* A sneaky way of allocating the dump_sects array. */
22213 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22214
22215 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22216 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22217 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22218 }
22219}
22220
94585d6d
NC
22221static bool
22222might_need_separate_debug_info (Filedata * filedata)
22223{
22224 /* Debuginfo files do not need further separate file loading. */
22225 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22226 return false;
22227
22228 /* Since do_follow_links might be enabled by default, only treat it as an
22229 indication that separate files should be loaded if setting it was a
22230 deliberate user action. */
22231 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22232 return true;
22233
22234 if (process_links || do_syms || do_unwind
22235 || dump_any_debugging || do_dump || do_debugging)
22236 return true;
22237
22238 return false;
22239}
22240
fb52b2f4
NC
22241/* Process one ELF object file according to the command line options.
22242 This file may actually be stored in an archive. The file is
32ec8896
NC
22243 positioned at the start of the ELF object. Returns TRUE if no
22244 problems were encountered, FALSE otherwise. */
fb52b2f4 22245
015dc7e1 22246static bool
dda8d76d 22247process_object (Filedata * filedata)
252b5132 22248{
015dc7e1 22249 bool have_separate_files;
252b5132 22250 unsigned int i;
015dc7e1 22251 bool res;
252b5132 22252
dda8d76d 22253 if (! get_file_header (filedata))
252b5132 22254 {
dda8d76d 22255 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22256 return false;
252b5132
RH
22257 }
22258
22259 /* Initialise per file variables. */
978c4450
AM
22260 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22261 filedata->version_info[i] = 0;
252b5132 22262
978c4450
AM
22263 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22264 filedata->dynamic_info[i] = 0;
22265 filedata->dynamic_info_DT_GNU_HASH = 0;
22266 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22267
22268 /* Process the file. */
22269 if (show_name)
dda8d76d 22270 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22271
835f2fae 22272 initialise_dump_sects (filedata);
d70c5fc7 22273
4de91c10
AM
22274 /* There may be some extensions in the first section header. Don't
22275 bomb if we can't read it. */
22276 get_section_headers (filedata, true);
22277
dda8d76d 22278 if (! process_file_header (filedata))
4de91c10
AM
22279 {
22280 res = false;
22281 goto out;
22282 }
252b5132 22283
e331b18d
AM
22284 /* Throw away the single section header read above, so that we
22285 re-read the entire set. */
22286 free (filedata->section_headers);
22287 filedata->section_headers = NULL;
22288
dda8d76d 22289 if (! process_section_headers (filedata))
2f62977e 22290 {
32ec8896 22291 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22292 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22293
2f62977e 22294 if (! do_using_dynamic)
015dc7e1 22295 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22296 }
252b5132 22297
dda8d76d 22298 if (! process_section_groups (filedata))
32ec8896 22299 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22300 do_unwind = false;
d1f5c6e3 22301
93df3340
AM
22302 process_program_headers (filedata);
22303
22304 res = process_dynamic_section (filedata);
252b5132 22305
dda8d76d 22306 if (! process_relocs (filedata))
015dc7e1 22307 res = false;
252b5132 22308
dda8d76d 22309 if (! process_unwind (filedata))
015dc7e1 22310 res = false;
4d6ed7c8 22311
dda8d76d 22312 if (! process_symbol_table (filedata))
015dc7e1 22313 res = false;
252b5132 22314
0f03783c 22315 if (! process_lto_symbol_tables (filedata))
015dc7e1 22316 res = false;
b9e920ec 22317
dda8d76d 22318 if (! process_syminfo (filedata))
015dc7e1 22319 res = false;
252b5132 22320
dda8d76d 22321 if (! process_version_sections (filedata))
015dc7e1 22322 res = false;
252b5132 22323
94585d6d 22324 if (might_need_separate_debug_info (filedata))
24841daa 22325 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22326 else
015dc7e1 22327 have_separate_files = false;
dda8d76d
NC
22328
22329 if (! process_section_contents (filedata))
015dc7e1 22330 res = false;
f5842774 22331
24841daa 22332 if (have_separate_files)
dda8d76d 22333 {
24841daa
NC
22334 separate_info * d;
22335
22336 for (d = first_separate_info; d != NULL; d = d->next)
22337 {
835f2fae
NC
22338 initialise_dump_sects (d->handle);
22339
ca0e11aa 22340 if (process_links && ! process_file_header (d->handle))
015dc7e1 22341 res = false;
ca0e11aa 22342 else if (! process_section_headers (d->handle))
015dc7e1 22343 res = false;
d6bfbc39 22344 else if (! process_section_contents (d->handle))
015dc7e1 22345 res = false;
ca0e11aa
NC
22346 else if (process_links)
22347 {
ca0e11aa 22348 if (! process_section_groups (d->handle))
015dc7e1 22349 res = false;
93df3340 22350 process_program_headers (d->handle);
ca0e11aa 22351 if (! process_dynamic_section (d->handle))
015dc7e1 22352 res = false;
ca0e11aa 22353 if (! process_relocs (d->handle))
015dc7e1 22354 res = false;
ca0e11aa 22355 if (! process_unwind (d->handle))
015dc7e1 22356 res = false;
ca0e11aa 22357 if (! process_symbol_table (d->handle))
015dc7e1 22358 res = false;
ca0e11aa 22359 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22360 res = false;
ca0e11aa 22361 if (! process_syminfo (d->handle))
015dc7e1 22362 res = false;
ca0e11aa 22363 if (! process_version_sections (d->handle))
015dc7e1 22364 res = false;
ca0e11aa 22365 if (! process_notes (d->handle))
015dc7e1 22366 res = false;
ca0e11aa 22367 }
24841daa
NC
22368 }
22369
22370 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22371 }
22372
22373 if (! process_notes (filedata))
015dc7e1 22374 res = false;
103f02d3 22375
dda8d76d 22376 if (! process_gnu_liblist (filedata))
015dc7e1 22377 res = false;
047b2264 22378
dda8d76d 22379 if (! process_arch_specific (filedata))
015dc7e1 22380 res = false;
252b5132 22381
4de91c10 22382 out:
13acb58d 22383 free_filedata (filedata);
e4b17d5c 22384
19e6b90e 22385 free_debug_memory ();
18bd398b 22386
32ec8896 22387 return res;
252b5132
RH
22388}
22389
2cf0635d 22390/* Process an ELF archive.
32ec8896
NC
22391 On entry the file is positioned just after the ARMAG string.
22392 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22393
015dc7e1
AM
22394static bool
22395process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22396{
22397 struct archive_info arch;
22398 struct archive_info nested_arch;
22399 size_t got;
015dc7e1 22400 bool ret = true;
2cf0635d 22401
015dc7e1 22402 show_name = true;
2cf0635d
NC
22403
22404 /* The ARCH structure is used to hold information about this archive. */
22405 arch.file_name = NULL;
22406 arch.file = NULL;
22407 arch.index_array = NULL;
22408 arch.sym_table = NULL;
22409 arch.longnames = NULL;
22410
22411 /* The NESTED_ARCH structure is used as a single-item cache of information
22412 about a nested archive (when members of a thin archive reside within
22413 another regular archive file). */
22414 nested_arch.file_name = NULL;
22415 nested_arch.file = NULL;
22416 nested_arch.index_array = NULL;
22417 nested_arch.sym_table = NULL;
22418 nested_arch.longnames = NULL;
22419
dda8d76d 22420 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22421 filedata->file_size, is_thin_archive,
22422 do_archive_index) != 0)
2cf0635d 22423 {
015dc7e1 22424 ret = false;
2cf0635d 22425 goto out;
4145f1d5 22426 }
fb52b2f4 22427
4145f1d5
NC
22428 if (do_archive_index)
22429 {
2cf0635d 22430 if (arch.sym_table == NULL)
1cb7d8b1
AM
22431 error (_("%s: unable to dump the index as none was found\n"),
22432 filedata->file_name);
4145f1d5
NC
22433 else
22434 {
591f7597 22435 unsigned long i, l;
4145f1d5
NC
22436 unsigned long current_pos;
22437
1cb7d8b1
AM
22438 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22439 "in the symbol table)\n"),
22440 filedata->file_name, (unsigned long) arch.index_num,
22441 arch.sym_size);
dda8d76d
NC
22442
22443 current_pos = ftell (filedata->handle);
4145f1d5 22444
2cf0635d 22445 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22446 {
1cb7d8b1
AM
22447 if (i == 0
22448 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22449 {
22450 char * member_name
22451 = get_archive_member_name_at (&arch, arch.index_array[i],
22452 &nested_arch);
2cf0635d 22453
1cb7d8b1
AM
22454 if (member_name != NULL)
22455 {
22456 char * qualified_name
22457 = make_qualified_name (&arch, &nested_arch,
22458 member_name);
2cf0635d 22459
1cb7d8b1
AM
22460 if (qualified_name != NULL)
22461 {
22462 printf (_("Contents of binary %s at offset "),
22463 qualified_name);
c2a7d3f5
NC
22464 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22465 putchar ('\n');
1cb7d8b1
AM
22466 free (qualified_name);
22467 }
fd486f32 22468 free (member_name);
4145f1d5
NC
22469 }
22470 }
2cf0635d
NC
22471
22472 if (l >= arch.sym_size)
4145f1d5 22473 {
1cb7d8b1
AM
22474 error (_("%s: end of the symbol table reached "
22475 "before the end of the index\n"),
dda8d76d 22476 filedata->file_name);
015dc7e1 22477 ret = false;
cb8f3167 22478 break;
4145f1d5 22479 }
591f7597 22480 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22481 printf ("\t%.*s\n",
22482 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22483 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22484 }
22485
67ce483b 22486 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22487 l = (l + 7) & ~ 7;
22488 else
22489 l += l & 1;
22490
2cf0635d 22491 if (l < arch.sym_size)
32ec8896 22492 {
d3a49aa8
AM
22493 error (ngettext ("%s: %ld byte remains in the symbol table, "
22494 "but without corresponding entries in "
22495 "the index table\n",
22496 "%s: %ld bytes remain in the symbol table, "
22497 "but without corresponding entries in "
22498 "the index table\n",
22499 arch.sym_size - l),
dda8d76d 22500 filedata->file_name, arch.sym_size - l);
015dc7e1 22501 ret = false;
32ec8896 22502 }
4145f1d5 22503
dda8d76d 22504 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22505 {
1cb7d8b1
AM
22506 error (_("%s: failed to seek back to start of object files "
22507 "in the archive\n"),
dda8d76d 22508 filedata->file_name);
015dc7e1 22509 ret = false;
2cf0635d 22510 goto out;
4145f1d5 22511 }
fb52b2f4 22512 }
4145f1d5
NC
22513
22514 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22515 && !do_segments && !do_header && !do_dump && !do_version
22516 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22517 && !do_section_groups && !do_dyn_syms)
2cf0635d 22518 {
015dc7e1 22519 ret = true; /* Archive index only. */
2cf0635d
NC
22520 goto out;
22521 }
fb52b2f4
NC
22522 }
22523
fb52b2f4
NC
22524 while (1)
22525 {
2cf0635d
NC
22526 char * name;
22527 size_t namelen;
22528 char * qualified_name;
22529
22530 /* Read the next archive header. */
dda8d76d 22531 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22532 {
22533 error (_("%s: failed to seek to next archive header\n"),
22534 arch.file_name);
015dc7e1 22535 ret = false;
1cb7d8b1
AM
22536 break;
22537 }
dda8d76d 22538 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22539 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22540 {
22541 if (got == 0)
2cf0635d 22542 break;
28e817cc
NC
22543 /* PR 24049 - we cannot use filedata->file_name as this will
22544 have already been freed. */
22545 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22546
015dc7e1 22547 ret = false;
1cb7d8b1
AM
22548 break;
22549 }
2cf0635d 22550 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22551 {
22552 error (_("%s: did not find a valid archive header\n"),
22553 arch.file_name);
015dc7e1 22554 ret = false;
1cb7d8b1
AM
22555 break;
22556 }
2cf0635d
NC
22557
22558 arch.next_arhdr_offset += sizeof arch.arhdr;
22559
978c4450 22560 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22561
22562 name = get_archive_member_name (&arch, &nested_arch);
22563 if (name == NULL)
fb52b2f4 22564 {
28e817cc 22565 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22566 ret = false;
d989285c 22567 break;
fb52b2f4 22568 }
2cf0635d 22569 namelen = strlen (name);
fb52b2f4 22570
2cf0635d
NC
22571 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22572 if (qualified_name == NULL)
fb52b2f4 22573 {
28e817cc 22574 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22575 free (name);
015dc7e1 22576 ret = false;
d989285c 22577 break;
fb52b2f4
NC
22578 }
22579
2cf0635d 22580 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22581 {
22582 /* This is a proxy for an external member of a thin archive. */
22583 Filedata * member_filedata;
22584 char * member_file_name = adjust_relative_path
dda8d76d 22585 (filedata->file_name, name, namelen);
32ec8896 22586
fd486f32 22587 free (name);
1cb7d8b1
AM
22588 if (member_file_name == NULL)
22589 {
fd486f32 22590 free (qualified_name);
015dc7e1 22591 ret = false;
1cb7d8b1
AM
22592 break;
22593 }
2cf0635d 22594
015dc7e1 22595 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22596 if (member_filedata == NULL)
22597 {
22598 error (_("Input file '%s' is not readable.\n"), member_file_name);
22599 free (member_file_name);
fd486f32 22600 free (qualified_name);
015dc7e1 22601 ret = false;
1cb7d8b1
AM
22602 break;
22603 }
2cf0635d 22604
978c4450 22605 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22606 member_filedata->file_name = qualified_name;
2cf0635d 22607
75a2da57
AH
22608 /* The call to process_object() expects the file to be at the beginning. */
22609 rewind (member_filedata->handle);
22610
1cb7d8b1 22611 if (! process_object (member_filedata))
015dc7e1 22612 ret = false;
2cf0635d 22613
1cb7d8b1
AM
22614 close_file (member_filedata);
22615 free (member_file_name);
1cb7d8b1 22616 }
2cf0635d 22617 else if (is_thin_archive)
1cb7d8b1
AM
22618 {
22619 Filedata thin_filedata;
eb02c04d 22620
1cb7d8b1 22621 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22622
a043396b
NC
22623 /* PR 15140: Allow for corrupt thin archives. */
22624 if (nested_arch.file == NULL)
22625 {
22626 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22627 qualified_name, name);
fd486f32
AM
22628 free (qualified_name);
22629 free (name);
015dc7e1 22630 ret = false;
a043396b
NC
22631 break;
22632 }
fd486f32 22633 free (name);
a043396b 22634
1cb7d8b1 22635 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22636 filedata->archive_file_offset
22637 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22638
1cb7d8b1
AM
22639 /* The nested archive file will have been opened and setup by
22640 get_archive_member_name. */
978c4450
AM
22641 if (fseek (nested_arch.file, filedata->archive_file_offset,
22642 SEEK_SET) != 0)
1cb7d8b1
AM
22643 {
22644 error (_("%s: failed to seek to archive member.\n"),
22645 nested_arch.file_name);
fd486f32 22646 free (qualified_name);
015dc7e1 22647 ret = false;
1cb7d8b1
AM
22648 break;
22649 }
2cf0635d 22650
dda8d76d
NC
22651 thin_filedata.handle = nested_arch.file;
22652 thin_filedata.file_name = qualified_name;
9abca702 22653
1cb7d8b1 22654 if (! process_object (& thin_filedata))
015dc7e1 22655 ret = false;
1cb7d8b1 22656 }
2cf0635d 22657 else
1cb7d8b1 22658 {
fd486f32 22659 free (name);
978c4450 22660 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22661 filedata->file_name = qualified_name;
1cb7d8b1 22662 if (! process_object (filedata))
015dc7e1 22663 ret = false;
237877b8 22664 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22665 /* Stop looping with "negative" archive_file_size. */
978c4450 22666 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22667 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22668 }
fb52b2f4 22669
2cf0635d 22670 free (qualified_name);
fb52b2f4
NC
22671 }
22672
4145f1d5 22673 out:
2cf0635d
NC
22674 if (nested_arch.file != NULL)
22675 fclose (nested_arch.file);
22676 release_archive (&nested_arch);
22677 release_archive (&arch);
fb52b2f4 22678
d989285c 22679 return ret;
fb52b2f4
NC
22680}
22681
015dc7e1 22682static bool
2cf0635d 22683process_file (char * file_name)
fb52b2f4 22684{
dda8d76d 22685 Filedata * filedata = NULL;
fb52b2f4
NC
22686 struct stat statbuf;
22687 char armag[SARMAG];
015dc7e1 22688 bool ret = true;
fb52b2f4
NC
22689
22690 if (stat (file_name, &statbuf) < 0)
22691 {
f24ddbdd
NC
22692 if (errno == ENOENT)
22693 error (_("'%s': No such file\n"), file_name);
22694 else
22695 error (_("Could not locate '%s'. System error message: %s\n"),
22696 file_name, strerror (errno));
015dc7e1 22697 return false;
f24ddbdd
NC
22698 }
22699
22700 if (! S_ISREG (statbuf.st_mode))
22701 {
22702 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22703 return false;
fb52b2f4
NC
22704 }
22705
dda8d76d
NC
22706 filedata = calloc (1, sizeof * filedata);
22707 if (filedata == NULL)
22708 {
22709 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22710 return false;
dda8d76d
NC
22711 }
22712
22713 filedata->file_name = file_name;
22714 filedata->handle = fopen (file_name, "rb");
22715 if (filedata->handle == NULL)
fb52b2f4 22716 {
f24ddbdd 22717 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22718 free (filedata);
015dc7e1 22719 return false;
fb52b2f4
NC
22720 }
22721
dda8d76d 22722 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22723 {
4145f1d5 22724 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22725 fclose (filedata->handle);
22726 free (filedata);
015dc7e1 22727 return false;
fb52b2f4
NC
22728 }
22729
dda8d76d 22730 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22731 filedata->is_separate = false;
f54498b4 22732
fb52b2f4 22733 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22734 {
015dc7e1
AM
22735 if (! process_archive (filedata, false))
22736 ret = false;
32ec8896 22737 }
2cf0635d 22738 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22739 {
015dc7e1
AM
22740 if ( ! process_archive (filedata, true))
22741 ret = false;
32ec8896 22742 }
fb52b2f4
NC
22743 else
22744 {
1b513401 22745 if (do_archive_index && !check_all)
4145f1d5
NC
22746 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22747 file_name);
22748
dda8d76d 22749 rewind (filedata->handle);
978c4450 22750 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22751
dda8d76d 22752 if (! process_object (filedata))
015dc7e1 22753 ret = false;
fb52b2f4
NC
22754 }
22755
dda8d76d 22756 fclose (filedata->handle);
8fb879cd
AM
22757 free (filedata->section_headers);
22758 free (filedata->program_headers);
22759 free (filedata->string_table);
6431e409 22760 free (filedata->dump.dump_sects);
dda8d76d 22761 free (filedata);
32ec8896 22762
fd486f32 22763 free (ba_cache.strtab);
1bd6175a 22764 ba_cache.strtab = NULL;
fd486f32 22765 free (ba_cache.symtab);
1bd6175a 22766 ba_cache.symtab = NULL;
fd486f32
AM
22767 ba_cache.filedata = NULL;
22768
fb52b2f4
NC
22769 return ret;
22770}
22771
252b5132
RH
22772#ifdef SUPPORT_DISASSEMBLY
22773/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22774 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22775 symbols. */
252b5132
RH
22776
22777void
2cf0635d 22778print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22779{
22780 fprintf (outfile,"0x%8.8x", addr);
22781}
22782
e3c8793a 22783/* Needed by the i386 disassembler. */
dda8d76d 22784
252b5132
RH
22785void
22786db_task_printsym (unsigned int addr)
22787{
22788 print_address (addr, stderr);
22789}
22790#endif
22791
22792int
2cf0635d 22793main (int argc, char ** argv)
252b5132 22794{
ff78d6d6
L
22795 int err;
22796
87b9f255 22797#ifdef HAVE_LC_MESSAGES
252b5132 22798 setlocale (LC_MESSAGES, "");
3882b010 22799#endif
3882b010 22800 setlocale (LC_CTYPE, "");
252b5132
RH
22801 bindtextdomain (PACKAGE, LOCALEDIR);
22802 textdomain (PACKAGE);
22803
869b9d07
MM
22804 expandargv (&argc, &argv);
22805
dda8d76d 22806 parse_args (& cmdline, argc, argv);
59f14fc0 22807
18bd398b 22808 if (optind < (argc - 1))
1b513401
NC
22809 /* When displaying information for more than one file,
22810 prefix the information with the file name. */
015dc7e1 22811 show_name = true;
5656ba2c
L
22812 else if (optind >= argc)
22813 {
1b513401 22814 /* Ensure that the warning is always displayed. */
015dc7e1 22815 do_checks = true;
1b513401 22816
5656ba2c
L
22817 warn (_("Nothing to do.\n"));
22818 usage (stderr);
22819 }
18bd398b 22820
015dc7e1 22821 err = false;
252b5132 22822 while (optind < argc)
32ec8896 22823 if (! process_file (argv[optind++]))
015dc7e1 22824 err = true;
252b5132 22825
9db70fc3 22826 free (cmdline.dump_sects);
252b5132 22827
7d9813f1
NA
22828 free (dump_ctf_symtab_name);
22829 free (dump_ctf_strtab_name);
22830 free (dump_ctf_parent_name);
22831
32ec8896 22832 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22833}