]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
LoongArch: Set defaults to exec stack 0.
[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
66cfc0fd
AM
433/* Print a BFD_VMA to an internal buffer, for use in error messages.
434 BFD_FMA_FMT can't be used in translated strings. */
435
436static const char *
437bfd_vmatoa (char *fmtch, bfd_vma value)
438{
439 /* bfd_vmatoa is used more then once in a printf call for output.
440 Cycle through an array of buffers. */
441 static int buf_pos = 0;
442 static struct bfd_vmatoa_buf
443 {
444 char place[64];
445 } buf[4];
446 char *ret;
447 char fmt[32];
448
449 ret = buf[buf_pos++].place;
450 buf_pos %= ARRAY_SIZE (buf);
451
452 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
453 snprintf (ret, sizeof (buf[0].place), fmt, value);
454 return ret;
455}
456
dda8d76d
NC
457/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
458 OFFSET + the offset of the current archive member, if we are examining an
459 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
460 allocate a buffer using malloc and fill that. In either case return the
461 pointer to the start of the retrieved data or NULL if something went wrong.
462 If something does go wrong and REASON is not NULL then emit an error
463 message using REASON as part of the context. */
59245841 464
c256ffe7 465static void *
dda8d76d
NC
466get_data (void * var,
467 Filedata * filedata,
468 unsigned long offset,
469 bfd_size_type size,
470 bfd_size_type nmemb,
471 const char * reason)
a6e9f9df 472{
2cf0635d 473 void * mvar;
57028622 474 bfd_size_type amt = size * nmemb;
a6e9f9df 475
c256ffe7 476 if (size == 0 || nmemb == 0)
a6e9f9df
AM
477 return NULL;
478
57028622
NC
479 /* If the size_t type is smaller than the bfd_size_type, eg because
480 you are building a 32-bit tool on a 64-bit host, then make sure
481 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
482 if ((size_t) size != size
483 || (size_t) nmemb != nmemb
484 || (size_t) amt != amt)
57028622
NC
485 {
486 if (reason)
66cfc0fd
AM
487 error (_("Size truncation prevents reading %s"
488 " elements of size %s for %s\n"),
489 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
490 return NULL;
491 }
492
493 /* Check for size overflow. */
7c1c1904 494 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
495 {
496 if (reason)
66cfc0fd
AM
497 error (_("Size overflow prevents reading %s"
498 " elements of size %s for %s\n"),
499 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
500 return NULL;
501 }
502
c22b42ce 503 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 504 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
505 if (filedata->archive_file_offset > filedata->file_size
506 || offset > filedata->file_size - filedata->archive_file_offset
507 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 508 {
049b0c3a 509 if (reason)
66cfc0fd
AM
510 error (_("Reading %s bytes extends past end of file for %s\n"),
511 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
512 return NULL;
513 }
514
978c4450
AM
515 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
516 SEEK_SET))
071436c6
NC
517 {
518 if (reason)
c9c1d674 519 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 520 filedata->archive_file_offset + offset, reason);
071436c6
NC
521 return NULL;
522 }
523
a6e9f9df
AM
524 mvar = var;
525 if (mvar == NULL)
526 {
7c1c1904
AM
527 /* + 1 so that we can '\0' terminate invalid string table sections. */
528 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
529
530 if (mvar == NULL)
531 {
049b0c3a 532 if (reason)
66cfc0fd
AM
533 error (_("Out of memory allocating %s bytes for %s\n"),
534 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
535 return NULL;
536 }
c256ffe7 537
c9c1d674 538 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
539 }
540
dda8d76d 541 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 542 {
049b0c3a 543 if (reason)
66cfc0fd
AM
544 error (_("Unable to read in %s bytes of %s\n"),
545 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
546 if (mvar != var)
547 free (mvar);
548 return NULL;
549 }
550
551 return mvar;
552}
553
32ec8896
NC
554/* Print a VMA value in the MODE specified.
555 Returns the number of characters displayed. */
cb8f3167 556
32ec8896 557static unsigned int
14a91970 558print_vma (bfd_vma vma, print_mode mode)
66543521 559{
32ec8896 560 unsigned int nc = 0;
66543521 561
14a91970 562 switch (mode)
66543521 563 {
14a91970
AM
564 case FULL_HEX:
565 nc = printf ("0x");
1a0670f3 566 /* Fall through. */
14a91970 567 case LONG_HEX:
f7a99963 568#ifdef BFD64
14a91970 569 if (is_32bit_elf)
437c2fb7 570 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 571#endif
14a91970
AM
572 printf_vma (vma);
573 return nc + 16;
b19aac67 574
14a91970
AM
575 case DEC_5:
576 if (vma <= 99999)
577 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 578 /* Fall through. */
14a91970
AM
579 case PREFIX_HEX:
580 nc = printf ("0x");
1a0670f3 581 /* Fall through. */
14a91970
AM
582 case HEX:
583 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 584
047c3dbf
NL
585 case PREFIX_HEX_5:
586 nc = printf ("0x");
587 /* Fall through. */
588 case HEX_5:
589 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
590
14a91970
AM
591 case DEC:
592 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 593
14a91970
AM
594 case UNSIGNED:
595 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 596
047c3dbf
NL
597 case UNSIGNED_5:
598 return printf ("%5" BFD_VMA_FMT "u", vma);
599
600 case OCTAL:
601 return printf ("%" BFD_VMA_FMT "o", vma);
602
603 case OCTAL_5:
604 return printf ("%5" BFD_VMA_FMT "o", vma);
605
32ec8896
NC
606 default:
607 /* FIXME: Report unrecognised mode ? */
608 return 0;
f7a99963 609 }
f7a99963
NC
610}
611
047c3dbf 612
7bfd842d 613/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 614 multibye characters (assuming the host environment supports them).
31104126 615
7bfd842d
NC
616 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
617
0942c7ab
NC
618 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
619 abs(WIDTH) - 5 characters followed by "[...]".
620
7bfd842d
NC
621 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
622 padding as necessary.
171191ba
NC
623
624 Returns the number of emitted characters. */
625
626static unsigned int
0942c7ab 627print_symbol (signed int width, const char * symbol)
31104126 628{
015dc7e1
AM
629 bool extra_padding = false;
630 bool do_dots = false;
32ec8896 631 signed int num_printed = 0;
3bfcb652 632#ifdef HAVE_MBSTATE_T
7bfd842d 633 mbstate_t state;
3bfcb652 634#endif
32ec8896 635 unsigned int width_remaining;
79bc120c 636 const void * alloced_symbol = NULL;
961c521f 637
7bfd842d 638 if (width < 0)
961c521f 639 {
88305e1b 640 /* Keep the width positive. This helps the code below. */
961c521f 641 width = - width;
015dc7e1 642 extra_padding = true;
0b4362b0 643 }
56d8f8a9
NC
644 else if (width == 0)
645 return 0;
961c521f 646
7bfd842d
NC
647 if (do_wide)
648 /* Set the remaining width to a very large value.
649 This simplifies the code below. */
650 width_remaining = INT_MAX;
651 else
0942c7ab
NC
652 {
653 width_remaining = width;
654 if (! do_not_show_symbol_truncation
655 && (int) strlen (symbol) > width)
656 {
657 width_remaining -= 5;
658 if ((int) width_remaining < 0)
659 width_remaining = 0;
015dc7e1 660 do_dots = true;
0942c7ab
NC
661 }
662 }
cb8f3167 663
3bfcb652 664#ifdef HAVE_MBSTATE_T
7bfd842d
NC
665 /* Initialise the multibyte conversion state. */
666 memset (& state, 0, sizeof (state));
3bfcb652 667#endif
961c521f 668
79bc120c
NC
669 if (do_demangle && *symbol)
670 {
671 const char * res = cplus_demangle (symbol, demangle_flags);
672
673 if (res != NULL)
674 alloced_symbol = symbol = res;
675 }
676
7bfd842d
NC
677 while (width_remaining)
678 {
679 size_t n;
7bfd842d 680 const char c = *symbol++;
961c521f 681
7bfd842d 682 if (c == 0)
961c521f
NC
683 break;
684
b3aa80b4
NC
685 if (ISPRINT (c))
686 {
687 putchar (c);
688 width_remaining --;
689 num_printed ++;
690 }
691 else if (ISCNTRL (c))
961c521f 692 {
b3aa80b4
NC
693 /* Do not print control characters directly as they can affect terminal
694 settings. Such characters usually appear in the names generated
695 by the assembler for local labels. */
696
7bfd842d 697 if (width_remaining < 2)
961c521f
NC
698 break;
699
7bfd842d
NC
700 printf ("^%c", c + 0x40);
701 width_remaining -= 2;
171191ba 702 num_printed += 2;
961c521f 703 }
b3aa80b4 704 else if (c == 0x7f)
7bfd842d 705 {
b3aa80b4
NC
706 if (width_remaining < 5)
707 break;
708 printf ("<DEL>");
709 width_remaining -= 5;
710 num_printed += 5;
711 }
712 else if (unicode_display != unicode_locale
713 && unicode_display != unicode_default)
714 {
715 /* Display unicode characters as something else. */
716 unsigned char bytes[4];
717 bool is_utf8;
795588ae 718 unsigned int nbytes;
b3aa80b4
NC
719
720 bytes[0] = c;
721
722 if (bytes[0] < 0xc0)
723 {
724 nbytes = 1;
725 is_utf8 = false;
726 }
727 else
728 {
729 bytes[1] = *symbol++;
730
731 if ((bytes[1] & 0xc0) != 0x80)
732 {
733 is_utf8 = false;
734 /* Do not consume this character. It may only
735 be the first byte in the sequence that was
736 corrupt. */
737 --symbol;
738 nbytes = 1;
739 }
740 else if ((bytes[0] & 0x20) == 0)
741 {
742 is_utf8 = true;
743 nbytes = 2;
744 }
745 else
746 {
747 bytes[2] = *symbol++;
748
749 if ((bytes[2] & 0xc0) != 0x80)
750 {
751 is_utf8 = false;
752 symbol -= 2;
753 nbytes = 1;
754 }
755 else if ((bytes[0] & 0x10) == 0)
756 {
757 is_utf8 = true;
758 nbytes = 3;
759 }
760 else
761 {
762 bytes[3] = *symbol++;
763
764 nbytes = 4;
765
766 if ((bytes[3] & 0xc0) != 0x80)
767 {
768 is_utf8 = false;
769 symbol -= 3;
770 nbytes = 1;
771 }
772 else
773 is_utf8 = true;
774 }
775 }
776 }
777
778 if (unicode_display == unicode_invalid)
779 is_utf8 = false;
780
781 if (unicode_display == unicode_hex || ! is_utf8)
782 {
795588ae 783 unsigned int i;
b3aa80b4
NC
784
785 if (width_remaining < (nbytes * 2) + 2)
786 break;
787
788 putchar (is_utf8 ? '<' : '{');
789 printf ("0x");
790 for (i = 0; i < nbytes; i++)
791 printf ("%02x", bytes[i]);
792 putchar (is_utf8 ? '>' : '}');
793 }
794 else
795 {
796 if (unicode_display == unicode_highlight && isatty (1))
797 printf ("\x1B[31;47m"); /* Red. */
798
799 switch (nbytes)
800 {
801 case 2:
802 if (width_remaining < 6)
803 break;
804 printf ("\\u%02x%02x",
805 (bytes[0] & 0x1c) >> 2,
806 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
807 break;
808 case 3:
809 if (width_remaining < 6)
810 break;
811 printf ("\\u%02x%02x",
812 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
813 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
814 break;
815 case 4:
816 if (width_remaining < 8)
817 break;
818 printf ("\\u%02x%02x%02x",
819 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
820 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
821 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
822
823 break;
824 default:
825 /* URG. */
826 break;
827 }
828
829 if (unicode_display == unicode_highlight && isatty (1))
830 printf ("\033[0m"); /* Default colour. */
831 }
832
833 if (bytes[nbytes - 1] == 0)
834 break;
7bfd842d 835 }
961c521f
NC
836 else
837 {
3bfcb652
NC
838#ifdef HAVE_MBSTATE_T
839 wchar_t w;
840#endif
7bfd842d
NC
841 /* Let printf do the hard work of displaying multibyte characters. */
842 printf ("%.1s", symbol - 1);
843 width_remaining --;
844 num_printed ++;
845
3bfcb652 846#ifdef HAVE_MBSTATE_T
7bfd842d
NC
847 /* Try to find out how many bytes made up the character that was
848 just printed. Advance the symbol pointer past the bytes that
849 were displayed. */
850 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
851#else
852 n = 1;
853#endif
7bfd842d
NC
854 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
855 symbol += (n - 1);
961c521f 856 }
961c521f 857 }
171191ba 858
0942c7ab
NC
859 if (do_dots)
860 num_printed += printf ("[...]");
861
7bfd842d 862 if (extra_padding && num_printed < width)
171191ba
NC
863 {
864 /* Fill in the remaining spaces. */
7bfd842d
NC
865 printf ("%-*s", width - num_printed, " ");
866 num_printed = width;
171191ba
NC
867 }
868
79bc120c 869 free ((void *) alloced_symbol);
171191ba 870 return num_printed;
31104126
NC
871}
872
1449284b 873/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
874 the given section's name. Like print_symbol, except that it does not try
875 to print multibyte characters, it just interprets them as hex values. */
876
877static const char *
dda8d76d 878printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 879{
ca0e11aa 880#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 881 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 882 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
883 char * buf = sec_name_buf;
884 char c;
885 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
886
887 while ((c = * name ++) != 0)
888 {
889 if (ISCNTRL (c))
890 {
891 if (remaining < 2)
892 break;
948f632f 893
74e1a04b
NC
894 * buf ++ = '^';
895 * buf ++ = c + 0x40;
896 remaining -= 2;
897 }
898 else if (ISPRINT (c))
899 {
900 * buf ++ = c;
901 remaining -= 1;
902 }
903 else
904 {
905 static char hex[17] = "0123456789ABCDEF";
906
907 if (remaining < 4)
908 break;
909 * buf ++ = '<';
910 * buf ++ = hex[(c & 0xf0) >> 4];
911 * buf ++ = hex[c & 0x0f];
912 * buf ++ = '>';
913 remaining -= 4;
914 }
915
916 if (remaining == 0)
917 break;
918 }
919
920 * buf = 0;
921 return sec_name_buf;
922}
923
924static const char *
dda8d76d 925printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 926{
dda8d76d 927 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
928 return _("<corrupt>");
929
dda8d76d 930 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
931}
932
89fac5e3
RS
933/* Return a pointer to section NAME, or NULL if no such section exists. */
934
935static Elf_Internal_Shdr *
dda8d76d 936find_section (Filedata * filedata, const char * name)
89fac5e3
RS
937{
938 unsigned int i;
939
68807c3c
NC
940 if (filedata->section_headers == NULL)
941 return NULL;
dda8d76d
NC
942
943 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
944 if (section_name_valid (filedata, filedata->section_headers + i)
945 && streq (section_name (filedata, filedata->section_headers + i),
946 name))
dda8d76d 947 return filedata->section_headers + i;
89fac5e3
RS
948
949 return NULL;
950}
951
0b6ae522
DJ
952/* Return a pointer to a section containing ADDR, or NULL if no such
953 section exists. */
954
955static Elf_Internal_Shdr *
dda8d76d 956find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
957{
958 unsigned int i;
959
68807c3c
NC
960 if (filedata->section_headers == NULL)
961 return NULL;
962
dda8d76d 963 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 964 {
dda8d76d
NC
965 Elf_Internal_Shdr *sec = filedata->section_headers + i;
966
0b6ae522
DJ
967 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
968 return sec;
969 }
970
971 return NULL;
972}
973
071436c6 974static Elf_Internal_Shdr *
dda8d76d 975find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
976{
977 unsigned int i;
978
68807c3c
NC
979 if (filedata->section_headers == NULL)
980 return NULL;
981
dda8d76d 982 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 983 {
dda8d76d
NC
984 Elf_Internal_Shdr *sec = filedata->section_headers + i;
985
071436c6
NC
986 if (sec->sh_type == type)
987 return sec;
988 }
989
990 return NULL;
991}
992
657d0d47
CC
993/* Return a pointer to section NAME, or NULL if no such section exists,
994 restricted to the list of sections given in SET. */
995
996static Elf_Internal_Shdr *
dda8d76d 997find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
998{
999 unsigned int i;
1000
68807c3c
NC
1001 if (filedata->section_headers == NULL)
1002 return NULL;
1003
657d0d47
CC
1004 if (set != NULL)
1005 {
1006 while ((i = *set++) > 0)
b814a36d
NC
1007 {
1008 /* See PR 21156 for a reproducer. */
dda8d76d 1009 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1010 continue; /* FIXME: Should we issue an error message ? */
1011
84714f86
AM
1012 if (section_name_valid (filedata, filedata->section_headers + i)
1013 && streq (section_name (filedata, filedata->section_headers + i),
1014 name))
dda8d76d 1015 return filedata->section_headers + i;
b814a36d 1016 }
657d0d47
CC
1017 }
1018
dda8d76d 1019 return find_section (filedata, name);
657d0d47
CC
1020}
1021
32ec8896 1022/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1023 This OS has so many departures from the ELF standard that we test it at
1024 many places. */
1025
015dc7e1 1026static inline bool
dda8d76d 1027is_ia64_vms (Filedata * filedata)
28f997cf 1028{
dda8d76d
NC
1029 return filedata->file_header.e_machine == EM_IA_64
1030 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1031}
1032
bcedfee6 1033/* Guess the relocation size commonly used by the specific machines. */
252b5132 1034
015dc7e1 1035static bool
2dc4cec1 1036guess_is_rela (unsigned int e_machine)
252b5132 1037{
9c19a809 1038 switch (e_machine)
252b5132
RH
1039 {
1040 /* Targets that use REL relocations. */
252b5132 1041 case EM_386:
22abe556 1042 case EM_IAMCU:
f954747f 1043 case EM_960:
e9f53129 1044 case EM_ARM:
2b0337b0 1045 case EM_D10V:
252b5132 1046 case EM_CYGNUS_D10V:
e9f53129 1047 case EM_DLX:
252b5132 1048 case EM_MIPS:
4fe85591 1049 case EM_MIPS_RS3_LE:
e9f53129 1050 case EM_CYGNUS_M32R:
1c0d3aa6 1051 case EM_SCORE:
f6c1a2d5 1052 case EM_XGATE:
fe944acf 1053 case EM_NFP:
aca4efc7 1054 case EM_BPF:
015dc7e1 1055 return false;
103f02d3 1056
252b5132
RH
1057 /* Targets that use RELA relocations. */
1058 case EM_68K:
f954747f 1059 case EM_860:
a06ea964 1060 case EM_AARCH64:
cfb8c092 1061 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1062 case EM_ALPHA:
1063 case EM_ALTERA_NIOS2:
886a2506
NC
1064 case EM_ARC:
1065 case EM_ARC_COMPACT:
1066 case EM_ARC_COMPACT2:
e9f53129
AM
1067 case EM_AVR:
1068 case EM_AVR_OLD:
1069 case EM_BLACKFIN:
60bca95a 1070 case EM_CR16:
e9f53129
AM
1071 case EM_CRIS:
1072 case EM_CRX:
b8891f8d 1073 case EM_CSKY:
2b0337b0 1074 case EM_D30V:
252b5132 1075 case EM_CYGNUS_D30V:
2b0337b0 1076 case EM_FR30:
3f8107ab 1077 case EM_FT32:
252b5132 1078 case EM_CYGNUS_FR30:
5c70f934 1079 case EM_CYGNUS_FRV:
e9f53129
AM
1080 case EM_H8S:
1081 case EM_H8_300:
1082 case EM_H8_300H:
800eeca4 1083 case EM_IA_64:
1e4cf259
NC
1084 case EM_IP2K:
1085 case EM_IP2K_OLD:
3b36097d 1086 case EM_IQ2000:
84e94c90 1087 case EM_LATTICEMICO32:
ff7eeb89 1088 case EM_M32C_OLD:
49f58d10 1089 case EM_M32C:
e9f53129
AM
1090 case EM_M32R:
1091 case EM_MCORE:
15ab5209 1092 case EM_CYGNUS_MEP:
a3c62988 1093 case EM_METAG:
e9f53129
AM
1094 case EM_MMIX:
1095 case EM_MN10200:
1096 case EM_CYGNUS_MN10200:
1097 case EM_MN10300:
1098 case EM_CYGNUS_MN10300:
5506d11a 1099 case EM_MOXIE:
e9f53129
AM
1100 case EM_MSP430:
1101 case EM_MSP430_OLD:
d031aafb 1102 case EM_MT:
35c08157 1103 case EM_NDS32:
64fd6348 1104 case EM_NIOS32:
73589c9d 1105 case EM_OR1K:
e9f53129
AM
1106 case EM_PPC64:
1107 case EM_PPC:
2b100bb5 1108 case EM_TI_PRU:
e23eba97 1109 case EM_RISCV:
99c513f6 1110 case EM_RL78:
c7927a3c 1111 case EM_RX:
e9f53129
AM
1112 case EM_S390:
1113 case EM_S390_OLD:
1114 case EM_SH:
1115 case EM_SPARC:
1116 case EM_SPARC32PLUS:
1117 case EM_SPARCV9:
1118 case EM_SPU:
40b36596 1119 case EM_TI_C6000:
aa137e4d
NC
1120 case EM_TILEGX:
1121 case EM_TILEPRO:
708e2187 1122 case EM_V800:
e9f53129
AM
1123 case EM_V850:
1124 case EM_CYGNUS_V850:
1125 case EM_VAX:
619ed720 1126 case EM_VISIUM:
e9f53129 1127 case EM_X86_64:
8a9036a4 1128 case EM_L1OM:
7a9068fe 1129 case EM_K1OM:
e9f53129
AM
1130 case EM_XSTORMY16:
1131 case EM_XTENSA:
1132 case EM_XTENSA_OLD:
7ba29e2a
NC
1133 case EM_MICROBLAZE:
1134 case EM_MICROBLAZE_OLD:
f96bd6c2 1135 case EM_WEBASSEMBLY:
015dc7e1 1136 return true;
103f02d3 1137
e9f53129
AM
1138 case EM_68HC05:
1139 case EM_68HC08:
1140 case EM_68HC11:
1141 case EM_68HC16:
1142 case EM_FX66:
1143 case EM_ME16:
d1133906 1144 case EM_MMA:
d1133906
NC
1145 case EM_NCPU:
1146 case EM_NDR1:
e9f53129 1147 case EM_PCP:
d1133906 1148 case EM_ST100:
e9f53129 1149 case EM_ST19:
d1133906 1150 case EM_ST7:
e9f53129
AM
1151 case EM_ST9PLUS:
1152 case EM_STARCORE:
d1133906 1153 case EM_SVX:
e9f53129 1154 case EM_TINYJ:
9c19a809
NC
1155 default:
1156 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1157 return false;
9c19a809
NC
1158 }
1159}
252b5132 1160
dda8d76d 1161/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1162 Returns TRUE upon success, FALSE otherwise. If successful then a
1163 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1164 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1165 responsibility to free the allocated buffer. */
1166
015dc7e1 1167static bool
dda8d76d
NC
1168slurp_rela_relocs (Filedata * filedata,
1169 unsigned long rel_offset,
1170 unsigned long rel_size,
1171 Elf_Internal_Rela ** relasp,
1172 unsigned long * nrelasp)
9c19a809 1173{
2cf0635d 1174 Elf_Internal_Rela * relas;
8b73c356 1175 size_t nrelas;
4d6ed7c8 1176 unsigned int i;
252b5132 1177
4d6ed7c8
NC
1178 if (is_32bit_elf)
1179 {
2cf0635d 1180 Elf32_External_Rela * erelas;
103f02d3 1181
dda8d76d 1182 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1183 rel_size, _("32-bit relocation data"));
a6e9f9df 1184 if (!erelas)
015dc7e1 1185 return false;
252b5132 1186
4d6ed7c8 1187 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1188
3f5e193b
NC
1189 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1190 sizeof (Elf_Internal_Rela));
103f02d3 1191
4d6ed7c8
NC
1192 if (relas == NULL)
1193 {
c256ffe7 1194 free (erelas);
591a748a 1195 error (_("out of memory parsing relocs\n"));
015dc7e1 1196 return false;
4d6ed7c8 1197 }
103f02d3 1198
4d6ed7c8
NC
1199 for (i = 0; i < nrelas; i++)
1200 {
1201 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1202 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1203 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1204 }
103f02d3 1205
4d6ed7c8
NC
1206 free (erelas);
1207 }
1208 else
1209 {
2cf0635d 1210 Elf64_External_Rela * erelas;
103f02d3 1211
dda8d76d 1212 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1213 rel_size, _("64-bit relocation data"));
a6e9f9df 1214 if (!erelas)
015dc7e1 1215 return false;
4d6ed7c8
NC
1216
1217 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1218
3f5e193b
NC
1219 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1220 sizeof (Elf_Internal_Rela));
103f02d3 1221
4d6ed7c8
NC
1222 if (relas == NULL)
1223 {
c256ffe7 1224 free (erelas);
591a748a 1225 error (_("out of memory parsing relocs\n"));
015dc7e1 1226 return false;
9c19a809 1227 }
4d6ed7c8
NC
1228
1229 for (i = 0; i < nrelas; i++)
9c19a809 1230 {
66543521
AM
1231 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1232 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1233 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1234
1235 /* The #ifdef BFD64 below is to prevent a compile time
1236 warning. We know that if we do not have a 64 bit data
1237 type that we will never execute this code anyway. */
1238#ifdef BFD64
dda8d76d
NC
1239 if (filedata->file_header.e_machine == EM_MIPS
1240 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1241 {
1242 /* In little-endian objects, r_info isn't really a
1243 64-bit little-endian value: it has a 32-bit
1244 little-endian symbol index followed by four
1245 individual byte fields. Reorder INFO
1246 accordingly. */
91d6fa6a
NC
1247 bfd_vma inf = relas[i].r_info;
1248 inf = (((inf & 0xffffffff) << 32)
1249 | ((inf >> 56) & 0xff)
1250 | ((inf >> 40) & 0xff00)
1251 | ((inf >> 24) & 0xff0000)
1252 | ((inf >> 8) & 0xff000000));
1253 relas[i].r_info = inf;
861fb55a
DJ
1254 }
1255#endif /* BFD64 */
4d6ed7c8 1256 }
103f02d3 1257
4d6ed7c8
NC
1258 free (erelas);
1259 }
32ec8896 1260
4d6ed7c8
NC
1261 *relasp = relas;
1262 *nrelasp = nrelas;
015dc7e1 1263 return true;
4d6ed7c8 1264}
103f02d3 1265
dda8d76d 1266/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1267 Returns TRUE upon success, FALSE otherwise. If successful then a
1268 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1269 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1270 responsibility to free the allocated buffer. */
1271
015dc7e1 1272static bool
dda8d76d
NC
1273slurp_rel_relocs (Filedata * filedata,
1274 unsigned long rel_offset,
1275 unsigned long rel_size,
1276 Elf_Internal_Rela ** relsp,
1277 unsigned long * nrelsp)
4d6ed7c8 1278{
2cf0635d 1279 Elf_Internal_Rela * rels;
8b73c356 1280 size_t nrels;
4d6ed7c8 1281 unsigned int i;
103f02d3 1282
4d6ed7c8
NC
1283 if (is_32bit_elf)
1284 {
2cf0635d 1285 Elf32_External_Rel * erels;
103f02d3 1286
dda8d76d 1287 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1288 rel_size, _("32-bit relocation data"));
a6e9f9df 1289 if (!erels)
015dc7e1 1290 return false;
103f02d3 1291
4d6ed7c8 1292 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1293
3f5e193b 1294 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1295
4d6ed7c8
NC
1296 if (rels == NULL)
1297 {
c256ffe7 1298 free (erels);
591a748a 1299 error (_("out of memory parsing relocs\n"));
015dc7e1 1300 return false;
4d6ed7c8
NC
1301 }
1302
1303 for (i = 0; i < nrels; i++)
1304 {
1305 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1306 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1307 rels[i].r_addend = 0;
9ea033b2 1308 }
4d6ed7c8
NC
1309
1310 free (erels);
9c19a809
NC
1311 }
1312 else
1313 {
2cf0635d 1314 Elf64_External_Rel * erels;
9ea033b2 1315
dda8d76d 1316 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1317 rel_size, _("64-bit relocation data"));
a6e9f9df 1318 if (!erels)
015dc7e1 1319 return false;
103f02d3 1320
4d6ed7c8 1321 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1322
3f5e193b 1323 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1324
4d6ed7c8 1325 if (rels == NULL)
9c19a809 1326 {
c256ffe7 1327 free (erels);
591a748a 1328 error (_("out of memory parsing relocs\n"));
015dc7e1 1329 return false;
4d6ed7c8 1330 }
103f02d3 1331
4d6ed7c8
NC
1332 for (i = 0; i < nrels; i++)
1333 {
66543521
AM
1334 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1335 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1336 rels[i].r_addend = 0;
861fb55a
DJ
1337
1338 /* The #ifdef BFD64 below is to prevent a compile time
1339 warning. We know that if we do not have a 64 bit data
1340 type that we will never execute this code anyway. */
1341#ifdef BFD64
dda8d76d
NC
1342 if (filedata->file_header.e_machine == EM_MIPS
1343 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1344 {
1345 /* In little-endian objects, r_info isn't really a
1346 64-bit little-endian value: it has a 32-bit
1347 little-endian symbol index followed by four
1348 individual byte fields. Reorder INFO
1349 accordingly. */
91d6fa6a
NC
1350 bfd_vma inf = rels[i].r_info;
1351 inf = (((inf & 0xffffffff) << 32)
1352 | ((inf >> 56) & 0xff)
1353 | ((inf >> 40) & 0xff00)
1354 | ((inf >> 24) & 0xff0000)
1355 | ((inf >> 8) & 0xff000000));
1356 rels[i].r_info = inf;
861fb55a
DJ
1357 }
1358#endif /* BFD64 */
4d6ed7c8 1359 }
103f02d3 1360
4d6ed7c8
NC
1361 free (erels);
1362 }
32ec8896 1363
4d6ed7c8
NC
1364 *relsp = rels;
1365 *nrelsp = nrels;
015dc7e1 1366 return true;
4d6ed7c8 1367}
103f02d3 1368
a7fd1186
FS
1369static bool
1370slurp_relr_relocs (Filedata * filedata,
1371 unsigned long relr_offset,
1372 unsigned long relr_size,
1373 bfd_vma ** relrsp,
1374 unsigned long * nrelrsp)
1375{
1376 void *relrs;
1377 size_t size = 0, nentries, i;
1378 bfd_vma base = 0, addr, entry;
1379
1380 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1381 _("RELR relocation data"));
1382 if (!relrs)
1383 return false;
1384
1385 if (is_32bit_elf)
1386 nentries = relr_size / sizeof (Elf32_External_Relr);
1387 else
1388 nentries = relr_size / sizeof (Elf64_External_Relr);
1389 for (i = 0; i < nentries; i++)
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 size++;
1397 else
1398 while ((entry >>= 1) != 0)
1399 if ((entry & 1) == 1)
1400 size++;
1401 }
1402
4491a7c1 1403 *relrsp = (bfd_vma *) malloc (size * sizeof (bfd_vma));
a7fd1186
FS
1404 if (*relrsp == NULL)
1405 {
1406 free (relrs);
1407 error (_("out of memory parsing relocs\n"));
1408 return false;
1409 }
1410
1411 size = 0;
1412 for (i = 0; i < nentries; i++)
1413 {
1414 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1415
1416 if (is_32bit_elf)
1417 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1418 else
1419 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1420 if ((entry & 1) == 0)
1421 {
1422 (*relrsp)[size++] = entry;
1423 base = entry + entry_bytes;
1424 }
1425 else
1426 {
1427 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1428 if ((entry & 1) != 0)
1429 (*relrsp)[size++] = addr;
1430 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1431 }
1432 }
1433
1434 *nrelrsp = size;
1435 free (relrs);
1436 return true;
1437}
1438
aca88567
NC
1439/* Returns the reloc type extracted from the reloc info field. */
1440
1441static unsigned int
dda8d76d 1442get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1443{
1444 if (is_32bit_elf)
1445 return ELF32_R_TYPE (reloc_info);
1446
dda8d76d 1447 switch (filedata->file_header.e_machine)
aca88567
NC
1448 {
1449 case EM_MIPS:
1450 /* Note: We assume that reloc_info has already been adjusted for us. */
1451 return ELF64_MIPS_R_TYPE (reloc_info);
1452
1453 case EM_SPARCV9:
1454 return ELF64_R_TYPE_ID (reloc_info);
1455
1456 default:
1457 return ELF64_R_TYPE (reloc_info);
1458 }
1459}
1460
1461/* Return the symbol index extracted from the reloc info field. */
1462
1463static bfd_vma
1464get_reloc_symindex (bfd_vma reloc_info)
1465{
1466 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1467}
1468
015dc7e1 1469static inline bool
dda8d76d 1470uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1471{
1472 return
dda8d76d 1473 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1474 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1475 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1476 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1477 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1478}
1479
d3ba0551
AM
1480/* Display the contents of the relocation data found at the specified
1481 offset. */
ee42cf8c 1482
015dc7e1 1483static bool
dda8d76d
NC
1484dump_relocations (Filedata * filedata,
1485 unsigned long rel_offset,
1486 unsigned long rel_size,
1487 Elf_Internal_Sym * symtab,
1488 unsigned long nsyms,
1489 char * strtab,
1490 unsigned long strtablen,
a7fd1186 1491 relocation_type rel_type,
015dc7e1 1492 bool is_dynsym)
4d6ed7c8 1493{
32ec8896 1494 unsigned long i;
2cf0635d 1495 Elf_Internal_Rela * rels;
015dc7e1 1496 bool res = true;
103f02d3 1497
a7fd1186
FS
1498 if (rel_type == reltype_unknown)
1499 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1500
a7fd1186 1501 if (rel_type == reltype_rela)
4d6ed7c8 1502 {
dda8d76d 1503 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1504 return false;
4d6ed7c8 1505 }
a7fd1186 1506 else if (rel_type == reltype_rel)
4d6ed7c8 1507 {
dda8d76d 1508 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1509 return false;
252b5132 1510 }
a7fd1186
FS
1511 else if (rel_type == reltype_relr)
1512 {
1513 bfd_vma * relrs;
1514 const char *format
1515 = is_32bit_elf ? "%08" BFD_VMA_FMT "x\n" : "%016" BFD_VMA_FMT "x\n";
1516
1517 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1518 &rel_size))
1519 return false;
1520
1521 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size), rel_size);
1522 for (i = 0; i < rel_size; i++)
1523 printf (format, relrs[i]);
1524 free (relrs);
1525 return true;
1526 }
252b5132 1527
410f7a12
L
1528 if (is_32bit_elf)
1529 {
a7fd1186 1530 if (rel_type == reltype_rela)
2c71103e
NC
1531 {
1532 if (do_wide)
1533 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1534 else
1535 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1536 }
410f7a12 1537 else
2c71103e
NC
1538 {
1539 if (do_wide)
1540 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1541 else
1542 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1543 }
410f7a12 1544 }
252b5132 1545 else
410f7a12 1546 {
a7fd1186 1547 if (rel_type == reltype_rela)
2c71103e
NC
1548 {
1549 if (do_wide)
8beeaeb7 1550 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1551 else
1552 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1553 }
410f7a12 1554 else
2c71103e
NC
1555 {
1556 if (do_wide)
8beeaeb7 1557 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1558 else
1559 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1560 }
410f7a12 1561 }
252b5132
RH
1562
1563 for (i = 0; i < rel_size; i++)
1564 {
2cf0635d 1565 const char * rtype;
b34976b6 1566 bfd_vma offset;
91d6fa6a 1567 bfd_vma inf;
b34976b6
AM
1568 bfd_vma symtab_index;
1569 bfd_vma type;
103f02d3 1570
b34976b6 1571 offset = rels[i].r_offset;
91d6fa6a 1572 inf = rels[i].r_info;
103f02d3 1573
dda8d76d 1574 type = get_reloc_type (filedata, inf);
91d6fa6a 1575 symtab_index = get_reloc_symindex (inf);
252b5132 1576
410f7a12
L
1577 if (is_32bit_elf)
1578 {
39dbeff8
AM
1579 printf ("%8.8lx %8.8lx ",
1580 (unsigned long) offset & 0xffffffff,
91d6fa6a 1581 (unsigned long) inf & 0xffffffff);
410f7a12
L
1582 }
1583 else
1584 {
39dbeff8 1585 printf (do_wide
d1ce973e
AM
1586 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1587 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1588 offset, inf);
410f7a12 1589 }
103f02d3 1590
dda8d76d 1591 switch (filedata->file_header.e_machine)
252b5132
RH
1592 {
1593 default:
1594 rtype = NULL;
1595 break;
1596
a06ea964
NC
1597 case EM_AARCH64:
1598 rtype = elf_aarch64_reloc_type (type);
1599 break;
1600
2b0337b0 1601 case EM_M32R:
252b5132 1602 case EM_CYGNUS_M32R:
9ea033b2 1603 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1604 break;
1605
1606 case EM_386:
22abe556 1607 case EM_IAMCU:
9ea033b2 1608 rtype = elf_i386_reloc_type (type);
252b5132
RH
1609 break;
1610
ba2685cc
AM
1611 case EM_68HC11:
1612 case EM_68HC12:
1613 rtype = elf_m68hc11_reloc_type (type);
1614 break;
75751cd9 1615
7b4ae824
JD
1616 case EM_S12Z:
1617 rtype = elf_s12z_reloc_type (type);
1618 break;
1619
252b5132 1620 case EM_68K:
9ea033b2 1621 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1622 break;
1623
f954747f
AM
1624 case EM_960:
1625 rtype = elf_i960_reloc_type (type);
1626 break;
1627
adde6300 1628 case EM_AVR:
2b0337b0 1629 case EM_AVR_OLD:
adde6300
AM
1630 rtype = elf_avr_reloc_type (type);
1631 break;
1632
9ea033b2
NC
1633 case EM_OLD_SPARCV9:
1634 case EM_SPARC32PLUS:
1635 case EM_SPARCV9:
252b5132 1636 case EM_SPARC:
9ea033b2 1637 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1638 break;
1639
e9f53129
AM
1640 case EM_SPU:
1641 rtype = elf_spu_reloc_type (type);
1642 break;
1643
708e2187
NC
1644 case EM_V800:
1645 rtype = v800_reloc_type (type);
1646 break;
2b0337b0 1647 case EM_V850:
252b5132 1648 case EM_CYGNUS_V850:
9ea033b2 1649 rtype = v850_reloc_type (type);
252b5132
RH
1650 break;
1651
2b0337b0 1652 case EM_D10V:
252b5132 1653 case EM_CYGNUS_D10V:
9ea033b2 1654 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1655 break;
1656
2b0337b0 1657 case EM_D30V:
252b5132 1658 case EM_CYGNUS_D30V:
9ea033b2 1659 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1660 break;
1661
d172d4ba
NC
1662 case EM_DLX:
1663 rtype = elf_dlx_reloc_type (type);
1664 break;
1665
252b5132 1666 case EM_SH:
9ea033b2 1667 rtype = elf_sh_reloc_type (type);
252b5132
RH
1668 break;
1669
2b0337b0 1670 case EM_MN10300:
252b5132 1671 case EM_CYGNUS_MN10300:
9ea033b2 1672 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1673 break;
1674
2b0337b0 1675 case EM_MN10200:
252b5132 1676 case EM_CYGNUS_MN10200:
9ea033b2 1677 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1678 break;
1679
2b0337b0 1680 case EM_FR30:
252b5132 1681 case EM_CYGNUS_FR30:
9ea033b2 1682 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1683 break;
1684
ba2685cc
AM
1685 case EM_CYGNUS_FRV:
1686 rtype = elf_frv_reloc_type (type);
1687 break;
5c70f934 1688
b8891f8d
AJ
1689 case EM_CSKY:
1690 rtype = elf_csky_reloc_type (type);
1691 break;
1692
3f8107ab
AM
1693 case EM_FT32:
1694 rtype = elf_ft32_reloc_type (type);
1695 break;
1696
252b5132 1697 case EM_MCORE:
9ea033b2 1698 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1699 break;
1700
3c3bdf30
NC
1701 case EM_MMIX:
1702 rtype = elf_mmix_reloc_type (type);
1703 break;
1704
5506d11a
AM
1705 case EM_MOXIE:
1706 rtype = elf_moxie_reloc_type (type);
1707 break;
1708
2469cfa2 1709 case EM_MSP430:
dda8d76d 1710 if (uses_msp430x_relocs (filedata))
13761a11
NC
1711 {
1712 rtype = elf_msp430x_reloc_type (type);
1713 break;
1714 }
1a0670f3 1715 /* Fall through. */
2469cfa2
NC
1716 case EM_MSP430_OLD:
1717 rtype = elf_msp430_reloc_type (type);
1718 break;
1719
35c08157
KLC
1720 case EM_NDS32:
1721 rtype = elf_nds32_reloc_type (type);
1722 break;
1723
252b5132 1724 case EM_PPC:
9ea033b2 1725 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1726 break;
1727
c833c019
AM
1728 case EM_PPC64:
1729 rtype = elf_ppc64_reloc_type (type);
1730 break;
1731
252b5132 1732 case EM_MIPS:
4fe85591 1733 case EM_MIPS_RS3_LE:
9ea033b2 1734 rtype = elf_mips_reloc_type (type);
252b5132
RH
1735 break;
1736
e23eba97
NC
1737 case EM_RISCV:
1738 rtype = elf_riscv_reloc_type (type);
1739 break;
1740
252b5132 1741 case EM_ALPHA:
9ea033b2 1742 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1743 break;
1744
1745 case EM_ARM:
9ea033b2 1746 rtype = elf_arm_reloc_type (type);
252b5132
RH
1747 break;
1748
584da044 1749 case EM_ARC:
886a2506
NC
1750 case EM_ARC_COMPACT:
1751 case EM_ARC_COMPACT2:
9ea033b2 1752 rtype = elf_arc_reloc_type (type);
252b5132
RH
1753 break;
1754
1755 case EM_PARISC:
69e617ca 1756 rtype = elf_hppa_reloc_type (type);
252b5132 1757 break;
7d466069 1758
b8720f9d
JL
1759 case EM_H8_300:
1760 case EM_H8_300H:
1761 case EM_H8S:
1762 rtype = elf_h8_reloc_type (type);
1763 break;
1764
73589c9d
CS
1765 case EM_OR1K:
1766 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1767 break;
1768
7d466069 1769 case EM_PJ:
2b0337b0 1770 case EM_PJ_OLD:
7d466069
ILT
1771 rtype = elf_pj_reloc_type (type);
1772 break;
800eeca4
JW
1773 case EM_IA_64:
1774 rtype = elf_ia64_reloc_type (type);
1775 break;
1b61cf92
HPN
1776
1777 case EM_CRIS:
1778 rtype = elf_cris_reloc_type (type);
1779 break;
535c37ff 1780
f954747f
AM
1781 case EM_860:
1782 rtype = elf_i860_reloc_type (type);
1783 break;
1784
bcedfee6 1785 case EM_X86_64:
8a9036a4 1786 case EM_L1OM:
7a9068fe 1787 case EM_K1OM:
bcedfee6
NC
1788 rtype = elf_x86_64_reloc_type (type);
1789 break;
a85d7ed0 1790
f954747f
AM
1791 case EM_S370:
1792 rtype = i370_reloc_type (type);
1793 break;
1794
53c7db4b
KH
1795 case EM_S390_OLD:
1796 case EM_S390:
1797 rtype = elf_s390_reloc_type (type);
1798 break;
93fbbb04 1799
1c0d3aa6
NC
1800 case EM_SCORE:
1801 rtype = elf_score_reloc_type (type);
1802 break;
1803
93fbbb04
GK
1804 case EM_XSTORMY16:
1805 rtype = elf_xstormy16_reloc_type (type);
1806 break;
179d3252 1807
1fe1f39c
NC
1808 case EM_CRX:
1809 rtype = elf_crx_reloc_type (type);
1810 break;
1811
179d3252
JT
1812 case EM_VAX:
1813 rtype = elf_vax_reloc_type (type);
1814 break;
1e4cf259 1815
619ed720
EB
1816 case EM_VISIUM:
1817 rtype = elf_visium_reloc_type (type);
1818 break;
1819
aca4efc7
JM
1820 case EM_BPF:
1821 rtype = elf_bpf_reloc_type (type);
1822 break;
1823
cfb8c092
NC
1824 case EM_ADAPTEVA_EPIPHANY:
1825 rtype = elf_epiphany_reloc_type (type);
1826 break;
1827
1e4cf259
NC
1828 case EM_IP2K:
1829 case EM_IP2K_OLD:
1830 rtype = elf_ip2k_reloc_type (type);
1831 break;
3b36097d
SC
1832
1833 case EM_IQ2000:
1834 rtype = elf_iq2000_reloc_type (type);
1835 break;
88da6820
NC
1836
1837 case EM_XTENSA_OLD:
1838 case EM_XTENSA:
1839 rtype = elf_xtensa_reloc_type (type);
1840 break;
a34e3ecb 1841
84e94c90
NC
1842 case EM_LATTICEMICO32:
1843 rtype = elf_lm32_reloc_type (type);
1844 break;
1845
ff7eeb89 1846 case EM_M32C_OLD:
49f58d10
JB
1847 case EM_M32C:
1848 rtype = elf_m32c_reloc_type (type);
1849 break;
1850
d031aafb
NS
1851 case EM_MT:
1852 rtype = elf_mt_reloc_type (type);
a34e3ecb 1853 break;
1d65ded4
CM
1854
1855 case EM_BLACKFIN:
1856 rtype = elf_bfin_reloc_type (type);
1857 break;
15ab5209
DB
1858
1859 case EM_CYGNUS_MEP:
1860 rtype = elf_mep_reloc_type (type);
1861 break;
60bca95a
NC
1862
1863 case EM_CR16:
1864 rtype = elf_cr16_reloc_type (type);
1865 break;
dd24e3da 1866
7ba29e2a
NC
1867 case EM_MICROBLAZE:
1868 case EM_MICROBLAZE_OLD:
1869 rtype = elf_microblaze_reloc_type (type);
1870 break;
c7927a3c 1871
99c513f6
DD
1872 case EM_RL78:
1873 rtype = elf_rl78_reloc_type (type);
1874 break;
1875
c7927a3c
NC
1876 case EM_RX:
1877 rtype = elf_rx_reloc_type (type);
1878 break;
c29aca4a 1879
a3c62988
NC
1880 case EM_METAG:
1881 rtype = elf_metag_reloc_type (type);
1882 break;
1883
40b36596
JM
1884 case EM_TI_C6000:
1885 rtype = elf_tic6x_reloc_type (type);
1886 break;
aa137e4d
NC
1887
1888 case EM_TILEGX:
1889 rtype = elf_tilegx_reloc_type (type);
1890 break;
1891
1892 case EM_TILEPRO:
1893 rtype = elf_tilepro_reloc_type (type);
1894 break;
f6c1a2d5 1895
f96bd6c2
PC
1896 case EM_WEBASSEMBLY:
1897 rtype = elf_wasm32_reloc_type (type);
1898 break;
1899
f6c1a2d5
NC
1900 case EM_XGATE:
1901 rtype = elf_xgate_reloc_type (type);
1902 break;
36591ba1
SL
1903
1904 case EM_ALTERA_NIOS2:
1905 rtype = elf_nios2_reloc_type (type);
1906 break;
2b100bb5
DD
1907
1908 case EM_TI_PRU:
1909 rtype = elf_pru_reloc_type (type);
1910 break;
fe944acf
FT
1911
1912 case EM_NFP:
1913 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1914 rtype = elf_nfp3200_reloc_type (type);
1915 else
1916 rtype = elf_nfp_reloc_type (type);
1917 break;
6655dba2
SB
1918
1919 case EM_Z80:
1920 rtype = elf_z80_reloc_type (type);
1921 break;
e9a0721f 1922
1923 case EM_LOONGARCH:
1924 rtype = elf_loongarch_reloc_type (type);
1925 break;
1926
0c857ef4
SM
1927 case EM_AMDGPU:
1928 rtype = elf_amdgpu_reloc_type (type);
1929 break;
252b5132
RH
1930 }
1931
1932 if (rtype == NULL)
39dbeff8 1933 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1934 else
5c144731 1935 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1936
dda8d76d 1937 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1938 && rtype != NULL
7ace3541 1939 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1940 && rel_type == reltype_rela)
7ace3541
RH
1941 {
1942 switch (rels[i].r_addend)
1943 {
1944 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1945 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1946 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1947 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1948 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1949 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1950 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1951 default: rtype = NULL;
1952 }
32ec8896 1953
7ace3541
RH
1954 if (rtype)
1955 printf (" (%s)", rtype);
1956 else
1957 {
1958 putchar (' ');
1959 printf (_("<unknown addend: %lx>"),
1960 (unsigned long) rels[i].r_addend);
015dc7e1 1961 res = false;
7ace3541
RH
1962 }
1963 }
1964 else if (symtab_index)
252b5132 1965 {
af3fc3bc 1966 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1967 {
27a45f42
AS
1968 error (_(" bad symbol index: %08lx in reloc\n"),
1969 (unsigned long) symtab_index);
015dc7e1 1970 res = false;
32ec8896 1971 }
af3fc3bc 1972 else
19936277 1973 {
2cf0635d 1974 Elf_Internal_Sym * psym;
bb4d2ac2
L
1975 const char * version_string;
1976 enum versioned_symbol_info sym_info;
1977 unsigned short vna_other;
19936277 1978
af3fc3bc 1979 psym = symtab + symtab_index;
103f02d3 1980
bb4d2ac2 1981 version_string
dda8d76d 1982 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1983 strtab, strtablen,
1984 symtab_index,
1985 psym,
1986 &sym_info,
1987 &vna_other);
1988
af3fc3bc 1989 printf (" ");
171191ba 1990
d8045f23
NC
1991 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1992 {
1993 const char * name;
1994 unsigned int len;
1995 unsigned int width = is_32bit_elf ? 8 : 14;
1996
1997 /* Relocations against GNU_IFUNC symbols do not use the value
1998 of the symbol as the address to relocate against. Instead
1999 they invoke the function named by the symbol and use its
2000 result as the address for relocation.
2001
2002 To indicate this to the user, do not display the value of
2003 the symbol in the "Symbols's Value" field. Instead show
2004 its name followed by () as a hint that the symbol is
2005 invoked. */
2006
2007 if (strtab == NULL
2008 || psym->st_name == 0
2009 || psym->st_name >= strtablen)
2010 name = "??";
2011 else
2012 name = strtab + psym->st_name;
2013
2014 len = print_symbol (width, name);
bb4d2ac2
L
2015 if (version_string)
2016 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2017 version_string);
d8045f23
NC
2018 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2019 }
2020 else
2021 {
2022 print_vma (psym->st_value, LONG_HEX);
171191ba 2023
d8045f23
NC
2024 printf (is_32bit_elf ? " " : " ");
2025 }
103f02d3 2026
af3fc3bc 2027 if (psym->st_name == 0)
f1ef08cb 2028 {
2cf0635d 2029 const char * sec_name = "<null>";
f1ef08cb
AM
2030 char name_buf[40];
2031
2032 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2033 {
b9af6379
AM
2034 if (psym->st_shndx < filedata->file_header.e_shnum
2035 && filedata->section_headers != NULL)
84714f86
AM
2036 sec_name = section_name_print (filedata,
2037 filedata->section_headers
b9e920ec 2038 + psym->st_shndx);
f1ef08cb
AM
2039 else if (psym->st_shndx == SHN_ABS)
2040 sec_name = "ABS";
2041 else if (psym->st_shndx == SHN_COMMON)
2042 sec_name = "COMMON";
dda8d76d 2043 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2044 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2045 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2046 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2047 sec_name = "SCOMMON";
dda8d76d 2048 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2049 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2050 sec_name = "SUNDEF";
dda8d76d
NC
2051 else if ((filedata->file_header.e_machine == EM_X86_64
2052 || filedata->file_header.e_machine == EM_L1OM
2053 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2054 && psym->st_shndx == SHN_X86_64_LCOMMON)
2055 sec_name = "LARGE_COMMON";
dda8d76d
NC
2056 else if (filedata->file_header.e_machine == EM_IA_64
2057 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2058 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2059 sec_name = "ANSI_COM";
dda8d76d 2060 else if (is_ia64_vms (filedata)
148b93f2
NC
2061 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2062 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2063 else
2064 {
2065 sprintf (name_buf, "<section 0x%x>",
2066 (unsigned int) psym->st_shndx);
2067 sec_name = name_buf;
2068 }
2069 }
2070 print_symbol (22, sec_name);
2071 }
af3fc3bc 2072 else if (strtab == NULL)
d79b3d50 2073 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2074 else if (psym->st_name >= strtablen)
32ec8896 2075 {
27a45f42
AS
2076 error (_("<corrupt string table index: %3ld>\n"),
2077 psym->st_name);
015dc7e1 2078 res = false;
32ec8896 2079 }
af3fc3bc 2080 else
bb4d2ac2
L
2081 {
2082 print_symbol (22, strtab + psym->st_name);
2083 if (version_string)
2084 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2085 version_string);
2086 }
103f02d3 2087
a7fd1186 2088 if (rel_type == reltype_rela)
171191ba 2089 {
7360e63f 2090 bfd_vma off = rels[i].r_addend;
171191ba 2091
7360e63f 2092 if ((bfd_signed_vma) off < 0)
598aaa76 2093 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 2094 else
598aaa76 2095 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 2096 }
19936277 2097 }
252b5132 2098 }
a7fd1186 2099 else if (rel_type == reltype_rela)
f7a99963 2100 {
7360e63f 2101 bfd_vma off = rels[i].r_addend;
e04d7088
L
2102
2103 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2104 if ((bfd_signed_vma) off < 0)
e04d7088
L
2105 printf ("-%" BFD_VMA_FMT "x", - off);
2106 else
2107 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 2108 }
252b5132 2109
dda8d76d 2110 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2111 && rtype != NULL
2112 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2113 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2114
252b5132 2115 putchar ('\n');
2c71103e 2116
aca88567 2117#ifdef BFD64
dda8d76d 2118 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2119 {
91d6fa6a
NC
2120 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2121 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2122 const char * rtype2 = elf_mips_reloc_type (type2);
2123 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2124
2c71103e
NC
2125 printf (" Type2: ");
2126
2127 if (rtype2 == NULL)
39dbeff8
AM
2128 printf (_("unrecognized: %-7lx"),
2129 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2130 else
2131 printf ("%-17.17s", rtype2);
2132
18bd398b 2133 printf ("\n Type3: ");
2c71103e
NC
2134
2135 if (rtype3 == NULL)
39dbeff8
AM
2136 printf (_("unrecognized: %-7lx"),
2137 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2138 else
2139 printf ("%-17.17s", rtype3);
2140
53c7db4b 2141 putchar ('\n');
2c71103e 2142 }
aca88567 2143#endif /* BFD64 */
252b5132
RH
2144 }
2145
c8286bd1 2146 free (rels);
32ec8896
NC
2147
2148 return res;
252b5132
RH
2149}
2150
37c18eed
SD
2151static const char *
2152get_aarch64_dynamic_type (unsigned long type)
2153{
2154 switch (type)
2155 {
2156 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2157 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2158 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2159 default:
2160 return NULL;
2161 }
2162}
2163
252b5132 2164static const char *
d3ba0551 2165get_mips_dynamic_type (unsigned long type)
252b5132
RH
2166{
2167 switch (type)
2168 {
2169 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2170 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2171 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2172 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2173 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2174 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2175 case DT_MIPS_MSYM: return "MIPS_MSYM";
2176 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2177 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2178 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2179 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2180 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2181 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2182 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2183 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2184 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2185 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2186 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2187 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2188 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2189 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2190 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2191 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2192 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2193 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2194 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2195 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2196 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2197 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2198 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2199 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2200 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2201 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2202 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2203 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2204 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2205 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2206 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2207 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2208 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2209 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2210 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2211 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2212 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2213 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2214 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2215 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2216 default:
2217 return NULL;
2218 }
2219}
2220
9a097730 2221static const char *
d3ba0551 2222get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2223{
2224 switch (type)
2225 {
2226 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2227 default:
2228 return NULL;
2229 }
103f02d3
UD
2230}
2231
7490d522
AM
2232static const char *
2233get_ppc_dynamic_type (unsigned long type)
2234{
2235 switch (type)
2236 {
a7f2871e 2237 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2238 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2239 default:
2240 return NULL;
2241 }
2242}
2243
f1cb7e17 2244static const char *
d3ba0551 2245get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2246{
2247 switch (type)
2248 {
a7f2871e
AM
2249 case DT_PPC64_GLINK: return "PPC64_GLINK";
2250 case DT_PPC64_OPD: return "PPC64_OPD";
2251 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2252 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2253 default:
2254 return NULL;
2255 }
2256}
2257
103f02d3 2258static const char *
d3ba0551 2259get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2260{
2261 switch (type)
2262 {
2263 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2264 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2265 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2266 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2267 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2268 case DT_HP_PREINIT: return "HP_PREINIT";
2269 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2270 case DT_HP_NEEDED: return "HP_NEEDED";
2271 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2272 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2273 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2274 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2275 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2276 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2277 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2278 case DT_HP_FILTERED: return "HP_FILTERED";
2279 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2280 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2281 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2282 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2283 case DT_PLT: return "PLT";
2284 case DT_PLT_SIZE: return "PLT_SIZE";
2285 case DT_DLT: return "DLT";
2286 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2287 default:
2288 return NULL;
2289 }
2290}
9a097730 2291
ecc51f48 2292static const char *
d3ba0551 2293get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2294{
2295 switch (type)
2296 {
148b93f2
NC
2297 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2298 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2299 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2300 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2301 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2302 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2303 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2304 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2305 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2306 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2307 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2308 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2309 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2310 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2311 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2312 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2313 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2314 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2315 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2316 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2317 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2318 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2319 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2320 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2321 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2322 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2323 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2324 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2325 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2326 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2327 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2328 default:
2329 return NULL;
2330 }
2331}
2332
fd85a6a1
NC
2333static const char *
2334get_solaris_section_type (unsigned long type)
2335{
2336 switch (type)
2337 {
2338 case 0x6fffffee: return "SUNW_ancillary";
2339 case 0x6fffffef: return "SUNW_capchain";
2340 case 0x6ffffff0: return "SUNW_capinfo";
2341 case 0x6ffffff1: return "SUNW_symsort";
2342 case 0x6ffffff2: return "SUNW_tlssort";
2343 case 0x6ffffff3: return "SUNW_LDYNSYM";
2344 case 0x6ffffff4: return "SUNW_dof";
2345 case 0x6ffffff5: return "SUNW_cap";
2346 case 0x6ffffff6: return "SUNW_SIGNATURE";
2347 case 0x6ffffff7: return "SUNW_ANNOTATE";
2348 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2349 case 0x6ffffff9: return "SUNW_DEBUG";
2350 case 0x6ffffffa: return "SUNW_move";
2351 case 0x6ffffffb: return "SUNW_COMDAT";
2352 case 0x6ffffffc: return "SUNW_syminfo";
2353 case 0x6ffffffd: return "SUNW_verdef";
2354 case 0x6ffffffe: return "SUNW_verneed";
2355 case 0x6fffffff: return "SUNW_versym";
2356 case 0x70000000: return "SPARC_GOTDATA";
2357 default: return NULL;
2358 }
2359}
2360
fabcb361
RH
2361static const char *
2362get_alpha_dynamic_type (unsigned long type)
2363{
2364 switch (type)
2365 {
2366 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2367 default: return NULL;
fabcb361
RH
2368 }
2369}
2370
1c0d3aa6
NC
2371static const char *
2372get_score_dynamic_type (unsigned long type)
2373{
2374 switch (type)
2375 {
2376 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2377 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2378 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2379 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2380 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2381 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2382 default: return NULL;
1c0d3aa6
NC
2383 }
2384}
2385
40b36596
JM
2386static const char *
2387get_tic6x_dynamic_type (unsigned long type)
2388{
2389 switch (type)
2390 {
2391 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2392 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2393 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2394 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2395 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2396 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2397 default: return NULL;
40b36596
JM
2398 }
2399}
1c0d3aa6 2400
36591ba1
SL
2401static const char *
2402get_nios2_dynamic_type (unsigned long type)
2403{
2404 switch (type)
2405 {
2406 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2407 default: return NULL;
36591ba1
SL
2408 }
2409}
2410
fd85a6a1
NC
2411static const char *
2412get_solaris_dynamic_type (unsigned long type)
2413{
2414 switch (type)
2415 {
2416 case 0x6000000d: return "SUNW_AUXILIARY";
2417 case 0x6000000e: return "SUNW_RTLDINF";
2418 case 0x6000000f: return "SUNW_FILTER";
2419 case 0x60000010: return "SUNW_CAP";
2420 case 0x60000011: return "SUNW_SYMTAB";
2421 case 0x60000012: return "SUNW_SYMSZ";
2422 case 0x60000013: return "SUNW_SORTENT";
2423 case 0x60000014: return "SUNW_SYMSORT";
2424 case 0x60000015: return "SUNW_SYMSORTSZ";
2425 case 0x60000016: return "SUNW_TLSSORT";
2426 case 0x60000017: return "SUNW_TLSSORTSZ";
2427 case 0x60000018: return "SUNW_CAPINFO";
2428 case 0x60000019: return "SUNW_STRPAD";
2429 case 0x6000001a: return "SUNW_CAPCHAIN";
2430 case 0x6000001b: return "SUNW_LDMACH";
2431 case 0x6000001d: return "SUNW_CAPCHAINENT";
2432 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2433 case 0x60000021: return "SUNW_PARENT";
2434 case 0x60000023: return "SUNW_ASLR";
2435 case 0x60000025: return "SUNW_RELAX";
2436 case 0x60000029: return "SUNW_NXHEAP";
2437 case 0x6000002b: return "SUNW_NXSTACK";
2438
2439 case 0x70000001: return "SPARC_REGISTER";
2440 case 0x7ffffffd: return "AUXILIARY";
2441 case 0x7ffffffe: return "USED";
2442 case 0x7fffffff: return "FILTER";
2443
15f205b1 2444 default: return NULL;
fd85a6a1
NC
2445 }
2446}
2447
8155b853
NC
2448static const char *
2449get_riscv_dynamic_type (unsigned long type)
2450{
2451 switch (type)
2452 {
2453 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2454 default:
2455 return NULL;
2456 }
2457}
2458
252b5132 2459static const char *
dda8d76d 2460get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2461{
e9e44622 2462 static char buff[64];
252b5132
RH
2463
2464 switch (type)
2465 {
2466 case DT_NULL: return "NULL";
2467 case DT_NEEDED: return "NEEDED";
2468 case DT_PLTRELSZ: return "PLTRELSZ";
2469 case DT_PLTGOT: return "PLTGOT";
2470 case DT_HASH: return "HASH";
2471 case DT_STRTAB: return "STRTAB";
2472 case DT_SYMTAB: return "SYMTAB";
2473 case DT_RELA: return "RELA";
2474 case DT_RELASZ: return "RELASZ";
2475 case DT_RELAENT: return "RELAENT";
2476 case DT_STRSZ: return "STRSZ";
2477 case DT_SYMENT: return "SYMENT";
2478 case DT_INIT: return "INIT";
2479 case DT_FINI: return "FINI";
2480 case DT_SONAME: return "SONAME";
2481 case DT_RPATH: return "RPATH";
2482 case DT_SYMBOLIC: return "SYMBOLIC";
2483 case DT_REL: return "REL";
2484 case DT_RELSZ: return "RELSZ";
2485 case DT_RELENT: return "RELENT";
dd207c13
FS
2486 case DT_RELR: return "RELR";
2487 case DT_RELRSZ: return "RELRSZ";
2488 case DT_RELRENT: return "RELRENT";
252b5132
RH
2489 case DT_PLTREL: return "PLTREL";
2490 case DT_DEBUG: return "DEBUG";
2491 case DT_TEXTREL: return "TEXTREL";
2492 case DT_JMPREL: return "JMPREL";
2493 case DT_BIND_NOW: return "BIND_NOW";
2494 case DT_INIT_ARRAY: return "INIT_ARRAY";
2495 case DT_FINI_ARRAY: return "FINI_ARRAY";
2496 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2497 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2498 case DT_RUNPATH: return "RUNPATH";
2499 case DT_FLAGS: return "FLAGS";
2d0e6f43 2500
d1133906
NC
2501 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2502 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2503 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2504
05107a46 2505 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2506 case DT_PLTPADSZ: return "PLTPADSZ";
2507 case DT_MOVEENT: return "MOVEENT";
2508 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2509 case DT_FEATURE: return "FEATURE";
252b5132
RH
2510 case DT_POSFLAG_1: return "POSFLAG_1";
2511 case DT_SYMINSZ: return "SYMINSZ";
2512 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2513
252b5132 2514 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2515 case DT_CONFIG: return "CONFIG";
2516 case DT_DEPAUDIT: return "DEPAUDIT";
2517 case DT_AUDIT: return "AUDIT";
2518 case DT_PLTPAD: return "PLTPAD";
2519 case DT_MOVETAB: return "MOVETAB";
252b5132 2520 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2521
252b5132 2522 case DT_VERSYM: return "VERSYM";
103f02d3 2523
67a4f2b7
AO
2524 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2525 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2526 case DT_RELACOUNT: return "RELACOUNT";
2527 case DT_RELCOUNT: return "RELCOUNT";
2528 case DT_FLAGS_1: return "FLAGS_1";
2529 case DT_VERDEF: return "VERDEF";
2530 case DT_VERDEFNUM: return "VERDEFNUM";
2531 case DT_VERNEED: return "VERNEED";
2532 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2533
019148e4 2534 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2535 case DT_USED: return "USED";
2536 case DT_FILTER: return "FILTER";
103f02d3 2537
047b2264
JJ
2538 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2539 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2540 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2541 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2542 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2543 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2544 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2545
252b5132
RH
2546 default:
2547 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2548 {
2cf0635d 2549 const char * result;
103f02d3 2550
dda8d76d 2551 switch (filedata->file_header.e_machine)
252b5132 2552 {
37c18eed
SD
2553 case EM_AARCH64:
2554 result = get_aarch64_dynamic_type (type);
2555 break;
252b5132 2556 case EM_MIPS:
4fe85591 2557 case EM_MIPS_RS3_LE:
252b5132
RH
2558 result = get_mips_dynamic_type (type);
2559 break;
9a097730
RH
2560 case EM_SPARCV9:
2561 result = get_sparc64_dynamic_type (type);
2562 break;
7490d522
AM
2563 case EM_PPC:
2564 result = get_ppc_dynamic_type (type);
2565 break;
f1cb7e17
AM
2566 case EM_PPC64:
2567 result = get_ppc64_dynamic_type (type);
2568 break;
ecc51f48
NC
2569 case EM_IA_64:
2570 result = get_ia64_dynamic_type (type);
2571 break;
fabcb361
RH
2572 case EM_ALPHA:
2573 result = get_alpha_dynamic_type (type);
2574 break;
1c0d3aa6
NC
2575 case EM_SCORE:
2576 result = get_score_dynamic_type (type);
2577 break;
40b36596
JM
2578 case EM_TI_C6000:
2579 result = get_tic6x_dynamic_type (type);
2580 break;
36591ba1
SL
2581 case EM_ALTERA_NIOS2:
2582 result = get_nios2_dynamic_type (type);
2583 break;
8155b853
NC
2584 case EM_RISCV:
2585 result = get_riscv_dynamic_type (type);
2586 break;
252b5132 2587 default:
dda8d76d 2588 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2589 result = get_solaris_dynamic_type (type);
2590 else
2591 result = NULL;
252b5132
RH
2592 break;
2593 }
2594
2595 if (result != NULL)
2596 return result;
2597
e9e44622 2598 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2599 }
eec8f817 2600 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2601 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2602 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2603 {
2cf0635d 2604 const char * result;
103f02d3 2605
dda8d76d 2606 switch (filedata->file_header.e_machine)
103f02d3
UD
2607 {
2608 case EM_PARISC:
2609 result = get_parisc_dynamic_type (type);
2610 break;
148b93f2
NC
2611 case EM_IA_64:
2612 result = get_ia64_dynamic_type (type);
2613 break;
103f02d3 2614 default:
dda8d76d 2615 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2616 result = get_solaris_dynamic_type (type);
2617 else
2618 result = NULL;
103f02d3
UD
2619 break;
2620 }
2621
2622 if (result != NULL)
2623 return result;
2624
e9e44622
JJ
2625 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2626 type);
103f02d3 2627 }
252b5132 2628 else
e9e44622 2629 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2630
252b5132
RH
2631 return buff;
2632 }
2633}
2634
93df3340
AM
2635static bool get_program_headers (Filedata *);
2636static bool get_dynamic_section (Filedata *);
2637
2638static void
2639locate_dynamic_section (Filedata *filedata)
2640{
2641 unsigned long dynamic_addr = 0;
2642 bfd_size_type dynamic_size = 0;
2643
2644 if (filedata->file_header.e_phnum != 0
2645 && get_program_headers (filedata))
2646 {
2647 Elf_Internal_Phdr *segment;
2648 unsigned int i;
2649
2650 for (i = 0, segment = filedata->program_headers;
2651 i < filedata->file_header.e_phnum;
2652 i++, segment++)
2653 {
2654 if (segment->p_type == PT_DYNAMIC)
2655 {
2656 dynamic_addr = segment->p_offset;
2657 dynamic_size = segment->p_filesz;
2658
2659 if (filedata->section_headers != NULL)
2660 {
2661 Elf_Internal_Shdr *sec;
2662
2663 sec = find_section (filedata, ".dynamic");
2664 if (sec != NULL)
2665 {
2666 if (sec->sh_size == 0
2667 || sec->sh_type == SHT_NOBITS)
2668 {
2669 dynamic_addr = 0;
2670 dynamic_size = 0;
2671 }
2672 else
2673 {
2674 dynamic_addr = sec->sh_offset;
2675 dynamic_size = sec->sh_size;
2676 }
2677 }
2678 }
2679
2680 if (dynamic_addr > filedata->file_size
2681 || (dynamic_size > filedata->file_size - dynamic_addr))
2682 {
2683 dynamic_addr = 0;
2684 dynamic_size = 0;
2685 }
2686 break;
2687 }
2688 }
2689 }
2690 filedata->dynamic_addr = dynamic_addr;
2691 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2692}
2693
2694static bool
2695is_pie (Filedata *filedata)
2696{
2697 Elf_Internal_Dyn *entry;
2698
2699 if (filedata->dynamic_size == 0)
2700 locate_dynamic_section (filedata);
2701 if (filedata->dynamic_size <= 1)
2702 return false;
2703
2704 if (!get_dynamic_section (filedata))
2705 return false;
2706
2707 for (entry = filedata->dynamic_section;
2708 entry < filedata->dynamic_section + filedata->dynamic_nent;
2709 entry++)
2710 {
2711 if (entry->d_tag == DT_FLAGS_1)
2712 {
2713 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2714 return true;
2715 break;
2716 }
2717 }
2718 return false;
2719}
2720
252b5132 2721static char *
93df3340 2722get_file_type (Filedata *filedata)
252b5132 2723{
93df3340 2724 unsigned e_type = filedata->file_header.e_type;
89246a0e 2725 static char buff[64];
252b5132
RH
2726
2727 switch (e_type)
2728 {
32ec8896
NC
2729 case ET_NONE: return _("NONE (None)");
2730 case ET_REL: return _("REL (Relocatable file)");
2731 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2732 case ET_DYN:
2733 if (is_pie (filedata))
2734 return _("DYN (Position-Independent Executable file)");
2735 else
2736 return _("DYN (Shared object file)");
32ec8896 2737 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2738
2739 default:
2740 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2741 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2742 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2743 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2744 else
e9e44622 2745 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2746 return buff;
2747 }
2748}
2749
2750static char *
d3ba0551 2751get_machine_name (unsigned e_machine)
252b5132 2752{
b34976b6 2753 static char buff[64]; /* XXX */
252b5132
RH
2754
2755 switch (e_machine)
2756 {
55e22ca8
NC
2757 /* Please keep this switch table sorted by increasing EM_ value. */
2758 /* 0 */
c45021f2
NC
2759 case EM_NONE: return _("None");
2760 case EM_M32: return "WE32100";
2761 case EM_SPARC: return "Sparc";
2762 case EM_386: return "Intel 80386";
2763 case EM_68K: return "MC68000";
2764 case EM_88K: return "MC88000";
22abe556 2765 case EM_IAMCU: return "Intel MCU";
fb70ec17 2766 case EM_860: return "Intel 80860";
c45021f2
NC
2767 case EM_MIPS: return "MIPS R3000";
2768 case EM_S370: return "IBM System/370";
55e22ca8 2769 /* 10 */
7036c0e1 2770 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2771 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2772 case EM_PARISC: return "HPPA";
55e22ca8 2773 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2774 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2775 case EM_960: return "Intel 80960";
c45021f2 2776 case EM_PPC: return "PowerPC";
55e22ca8 2777 /* 20 */
285d1771 2778 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2779 case EM_S390_OLD:
2780 case EM_S390: return "IBM S/390";
2781 case EM_SPU: return "SPU";
2782 /* 30 */
2783 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2784 case EM_FR20: return "Fujitsu FR20";
2785 case EM_RH32: return "TRW RH32";
b34976b6 2786 case EM_MCORE: return "MCORE";
55e22ca8 2787 /* 40 */
7036c0e1
AJ
2788 case EM_ARM: return "ARM";
2789 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2790 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2791 case EM_SPARCV9: return "Sparc v9";
2792 case EM_TRICORE: return "Siemens Tricore";
584da044 2793 case EM_ARC: return "ARC";
c2dcd04e
NC
2794 case EM_H8_300: return "Renesas H8/300";
2795 case EM_H8_300H: return "Renesas H8/300H";
2796 case EM_H8S: return "Renesas H8S";
2797 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2798 /* 50 */
30800947 2799 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2800 case EM_MIPS_X: return "Stanford MIPS-X";
2801 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2802 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2803 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2804 case EM_PCP: return "Siemens PCP";
2805 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2806 case EM_NDR1: return "Denso NDR1 microprocesspr";
2807 case EM_STARCORE: return "Motorola Star*Core processor";
2808 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2809 /* 60 */
7036c0e1
AJ
2810 case EM_ST100: return "STMicroelectronics ST100 processor";
2811 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2812 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2813 case EM_PDSP: return "Sony DSP processor";
2814 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2815 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2816 case EM_FX66: return "Siemens FX66 microcontroller";
2817 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2818 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2819 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2820 /* 70 */
7036c0e1
AJ
2821 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2822 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2823 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2824 case EM_SVX: return "Silicon Graphics SVx";
2825 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2826 case EM_VAX: return "Digital VAX";
1b61cf92 2827 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2828 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2829 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2830 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2831 /* 80 */
b34976b6 2832 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2833 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2834 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2835 case EM_AVR_OLD:
2836 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2837 case EM_CYGNUS_FR30:
2838 case EM_FR30: return "Fujitsu FR30";
2839 case EM_CYGNUS_D10V:
2840 case EM_D10V: return "d10v";
2841 case EM_CYGNUS_D30V:
2842 case EM_D30V: return "d30v";
2843 case EM_CYGNUS_V850:
2844 case EM_V850: return "Renesas V850";
2845 case EM_CYGNUS_M32R:
2846 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2847 case EM_CYGNUS_MN10300:
2848 case EM_MN10300: return "mn10300";
2849 /* 90 */
2850 case EM_CYGNUS_MN10200:
2851 case EM_MN10200: return "mn10200";
2852 case EM_PJ: return "picoJava";
73589c9d 2853 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2854 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2855 case EM_XTENSA_OLD:
2856 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2857 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2858 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2859 case EM_NS32K: return "National Semiconductor 32000 series";
2860 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2861 case EM_SNP1K: return "Trebia SNP 1000 processor";
2862 /* 100 */
9abca702 2863 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2864 case EM_IP2K_OLD:
2865 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2866 case EM_MAX: return "MAX Processor";
2867 case EM_CR: return "National Semiconductor CompactRISC";
2868 case EM_F2MC16: return "Fujitsu F2MC16";
2869 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2870 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2871 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2872 case EM_SEP: return "Sharp embedded microprocessor";
2873 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2874 /* 110 */
11636f9e
JM
2875 case EM_UNICORE: return "Unicore";
2876 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2877 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2878 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2879 case EM_CRX: return "National Semiconductor CRX microprocessor";
2880 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2881 case EM_C166:
d70c5fc7 2882 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2883 case EM_M16C: return "Renesas M16C series microprocessors";
2884 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2885 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2886 /* 120 */
2887 case EM_M32C: return "Renesas M32c";
2888 /* 130 */
11636f9e
JM
2889 case EM_TSK3000: return "Altium TSK3000 core";
2890 case EM_RS08: return "Freescale RS08 embedded processor";
2891 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2892 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2893 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2894 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2895 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2896 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2897 /* 140 */
11636f9e
JM
2898 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2899 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2900 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2901 case EM_TI_PRU: return "TI PRU I/O processor";
2902 /* 160 */
11636f9e
JM
2903 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2904 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2905 case EM_R32C: return "Renesas R32C series microprocessors";
2906 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2907 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2908 case EM_8051: return "Intel 8051 and variants";
2909 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2910 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2911 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2912 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2913 /* 170 */
11636f9e
JM
2914 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2915 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2916 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2917 case EM_RX: return "Renesas RX";
a3c62988 2918 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2919 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2920 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2921 case EM_CR16:
2922 case EM_MICROBLAZE:
2923 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2924 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2925 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2926 /* 180 */
2927 case EM_L1OM: return "Intel L1OM";
2928 case EM_K1OM: return "Intel K1OM";
2929 case EM_INTEL182: return "Intel (reserved)";
2930 case EM_AARCH64: return "AArch64";
2931 case EM_ARM184: return "ARM (reserved)";
2932 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2933 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2934 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2935 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2936 /* 190 */
11636f9e 2937 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2938 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2939 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2940 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2941 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2942 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2943 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2944 case EM_RL78: return "Renesas RL78";
6d913794 2945 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2946 case EM_78K0R: return "Renesas 78K0R";
2947 /* 200 */
6d913794 2948 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2949 case EM_BA1: return "Beyond BA1 CPU architecture";
2950 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2951 case EM_XCORE: return "XMOS xCORE processor family";
2952 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2953 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2954 /* 210 */
6d913794
NC
2955 case EM_KM32: return "KM211 KM32 32-bit processor";
2956 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2957 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2958 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2959 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2960 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2961 case EM_COGE: return "Cognitive Smart Memory Processor";
2962 case EM_COOL: return "Bluechip Systems CoolEngine";
2963 case EM_NORC: return "Nanoradio Optimized RISC";
2964 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2965 /* 220 */
15f205b1 2966 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2967 case EM_VISIUM: return "CDS VISIUMcore processor";
2968 case EM_FT32: return "FTDI Chip FT32";
2969 case EM_MOXIE: return "Moxie";
2970 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2971 /* 230 (all reserved) */
2972 /* 240 */
55e22ca8
NC
2973 case EM_RISCV: return "RISC-V";
2974 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2975 case EM_CEVA: return "CEVA Processor Architecture Family";
2976 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2977 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2978 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2979 case EM_IMG1: return "Imagination Technologies";
2980 /* 250 */
fe944acf 2981 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2982 case EM_VE: return "NEC Vector Engine";
2983 case EM_CSKY: return "C-SKY";
2984 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2985 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2986 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2987 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2988 case EM_65816: return "WDC 65816/65C816";
01a8c731 2989 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2990 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2991
2992 /* Large numbers... */
2993 case EM_MT: return "Morpho Techologies MT processor";
2994 case EM_ALPHA: return "Alpha";
2995 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2996 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2997 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2998 case EM_IQ2000: return "Vitesse IQ2000";
2999 case EM_M32C_OLD:
3000 case EM_NIOS32: return "Altera Nios";
3001 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3002 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3003 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3004 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3005
252b5132 3006 default:
35d9dd2f 3007 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3008 return buff;
3009 }
3010}
3011
a9522a21
AB
3012static void
3013decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3014{
3015 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3016 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3017 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3018 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3019 architectures.
3020
3021 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3022 but also sets a specific architecture type in the e_flags field.
3023
3024 However, when decoding the flags we don't worry if we see an
3025 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3026 ARCEM architecture type. */
3027
3028 switch (e_flags & EF_ARC_MACH_MSK)
3029 {
3030 /* We only expect these to occur for EM_ARC_COMPACT2. */
3031 case EF_ARC_CPU_ARCV2EM:
3032 strcat (buf, ", ARC EM");
3033 break;
3034 case EF_ARC_CPU_ARCV2HS:
3035 strcat (buf, ", ARC HS");
3036 break;
3037
3038 /* We only expect these to occur for EM_ARC_COMPACT. */
3039 case E_ARC_MACH_ARC600:
3040 strcat (buf, ", ARC600");
3041 break;
3042 case E_ARC_MACH_ARC601:
3043 strcat (buf, ", ARC601");
3044 break;
3045 case E_ARC_MACH_ARC700:
3046 strcat (buf, ", ARC700");
3047 break;
3048
3049 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3050 new ELF with new architecture being read by an old version of
3051 readelf, or (c) An ELF built with non-GNU compiler that does not
3052 set the architecture in the e_flags. */
3053 default:
3054 if (e_machine == EM_ARC_COMPACT)
3055 strcat (buf, ", Unknown ARCompact");
3056 else
3057 strcat (buf, ", Unknown ARC");
3058 break;
3059 }
3060
3061 switch (e_flags & EF_ARC_OSABI_MSK)
3062 {
3063 case E_ARC_OSABI_ORIG:
3064 strcat (buf, ", (ABI:legacy)");
3065 break;
3066 case E_ARC_OSABI_V2:
3067 strcat (buf, ", (ABI:v2)");
3068 break;
3069 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3070 case E_ARC_OSABI_V3:
3071 strcat (buf, ", v3 no-legacy-syscalls ABI");
3072 break;
53a346d8
CZ
3073 case E_ARC_OSABI_V4:
3074 strcat (buf, ", v4 ABI");
3075 break;
a9522a21
AB
3076 default:
3077 strcat (buf, ", unrecognised ARC OSABI flag");
3078 break;
3079 }
3080}
3081
f3485b74 3082static void
d3ba0551 3083decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3084{
3085 unsigned eabi;
015dc7e1 3086 bool unknown = false;
f3485b74
NC
3087
3088 eabi = EF_ARM_EABI_VERSION (e_flags);
3089 e_flags &= ~ EF_ARM_EABIMASK;
3090
3091 /* Handle "generic" ARM flags. */
3092 if (e_flags & EF_ARM_RELEXEC)
3093 {
3094 strcat (buf, ", relocatable executable");
3095 e_flags &= ~ EF_ARM_RELEXEC;
3096 }
76da6bbe 3097
18a20338
CL
3098 if (e_flags & EF_ARM_PIC)
3099 {
3100 strcat (buf, ", position independent");
3101 e_flags &= ~ EF_ARM_PIC;
3102 }
3103
f3485b74
NC
3104 /* Now handle EABI specific flags. */
3105 switch (eabi)
3106 {
3107 default:
2c71103e 3108 strcat (buf, ", <unrecognized EABI>");
f3485b74 3109 if (e_flags)
015dc7e1 3110 unknown = true;
f3485b74
NC
3111 break;
3112
3113 case EF_ARM_EABI_VER1:
a5bcd848 3114 strcat (buf, ", Version1 EABI");
f3485b74
NC
3115 while (e_flags)
3116 {
3117 unsigned flag;
76da6bbe 3118
f3485b74
NC
3119 /* Process flags one bit at a time. */
3120 flag = e_flags & - e_flags;
3121 e_flags &= ~ flag;
76da6bbe 3122
f3485b74
NC
3123 switch (flag)
3124 {
a5bcd848 3125 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3126 strcat (buf, ", sorted symbol tables");
3127 break;
76da6bbe 3128
f3485b74 3129 default:
015dc7e1 3130 unknown = true;
f3485b74
NC
3131 break;
3132 }
3133 }
3134 break;
76da6bbe 3135
a5bcd848
PB
3136 case EF_ARM_EABI_VER2:
3137 strcat (buf, ", Version2 EABI");
3138 while (e_flags)
3139 {
3140 unsigned flag;
3141
3142 /* Process flags one bit at a time. */
3143 flag = e_flags & - e_flags;
3144 e_flags &= ~ flag;
3145
3146 switch (flag)
3147 {
3148 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3149 strcat (buf, ", sorted symbol tables");
3150 break;
3151
3152 case EF_ARM_DYNSYMSUSESEGIDX:
3153 strcat (buf, ", dynamic symbols use segment index");
3154 break;
3155
3156 case EF_ARM_MAPSYMSFIRST:
3157 strcat (buf, ", mapping symbols precede others");
3158 break;
3159
3160 default:
015dc7e1 3161 unknown = true;
a5bcd848
PB
3162 break;
3163 }
3164 }
3165 break;
3166
d507cf36
PB
3167 case EF_ARM_EABI_VER3:
3168 strcat (buf, ", Version3 EABI");
8cb51566
PB
3169 break;
3170
3171 case EF_ARM_EABI_VER4:
3172 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3173 while (e_flags)
3174 {
3175 unsigned flag;
3176
3177 /* Process flags one bit at a time. */
3178 flag = e_flags & - e_flags;
3179 e_flags &= ~ flag;
3180
3181 switch (flag)
3182 {
3183 case EF_ARM_BE8:
3184 strcat (buf, ", BE8");
3185 break;
3186
3187 case EF_ARM_LE8:
3188 strcat (buf, ", LE8");
3189 break;
3190
3191 default:
015dc7e1 3192 unknown = true;
3bfcb652
NC
3193 break;
3194 }
3bfcb652
NC
3195 }
3196 break;
3a4a14e9
PB
3197
3198 case EF_ARM_EABI_VER5:
3199 strcat (buf, ", Version5 EABI");
d507cf36
PB
3200 while (e_flags)
3201 {
3202 unsigned flag;
3203
3204 /* Process flags one bit at a time. */
3205 flag = e_flags & - e_flags;
3206 e_flags &= ~ flag;
3207
3208 switch (flag)
3209 {
3210 case EF_ARM_BE8:
3211 strcat (buf, ", BE8");
3212 break;
3213
3214 case EF_ARM_LE8:
3215 strcat (buf, ", LE8");
3216 break;
3217
3bfcb652
NC
3218 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3219 strcat (buf, ", soft-float ABI");
3220 break;
3221
3222 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3223 strcat (buf, ", hard-float ABI");
3224 break;
3225
d507cf36 3226 default:
015dc7e1 3227 unknown = true;
d507cf36
PB
3228 break;
3229 }
3230 }
3231 break;
3232
f3485b74 3233 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3234 strcat (buf, ", GNU EABI");
f3485b74
NC
3235 while (e_flags)
3236 {
3237 unsigned flag;
76da6bbe 3238
f3485b74
NC
3239 /* Process flags one bit at a time. */
3240 flag = e_flags & - e_flags;
3241 e_flags &= ~ flag;
76da6bbe 3242
f3485b74
NC
3243 switch (flag)
3244 {
a5bcd848 3245 case EF_ARM_INTERWORK:
f3485b74
NC
3246 strcat (buf, ", interworking enabled");
3247 break;
76da6bbe 3248
a5bcd848 3249 case EF_ARM_APCS_26:
f3485b74
NC
3250 strcat (buf, ", uses APCS/26");
3251 break;
76da6bbe 3252
a5bcd848 3253 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3254 strcat (buf, ", uses APCS/float");
3255 break;
76da6bbe 3256
a5bcd848 3257 case EF_ARM_PIC:
f3485b74
NC
3258 strcat (buf, ", position independent");
3259 break;
76da6bbe 3260
a5bcd848 3261 case EF_ARM_ALIGN8:
f3485b74
NC
3262 strcat (buf, ", 8 bit structure alignment");
3263 break;
76da6bbe 3264
a5bcd848 3265 case EF_ARM_NEW_ABI:
f3485b74
NC
3266 strcat (buf, ", uses new ABI");
3267 break;
76da6bbe 3268
a5bcd848 3269 case EF_ARM_OLD_ABI:
f3485b74
NC
3270 strcat (buf, ", uses old ABI");
3271 break;
76da6bbe 3272
a5bcd848 3273 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3274 strcat (buf, ", software FP");
3275 break;
76da6bbe 3276
90e01f86
ILT
3277 case EF_ARM_VFP_FLOAT:
3278 strcat (buf, ", VFP");
3279 break;
3280
fde78edd
NC
3281 case EF_ARM_MAVERICK_FLOAT:
3282 strcat (buf, ", Maverick FP");
3283 break;
3284
f3485b74 3285 default:
015dc7e1 3286 unknown = true;
f3485b74
NC
3287 break;
3288 }
3289 }
3290 }
f3485b74
NC
3291
3292 if (unknown)
2b692964 3293 strcat (buf,_(", <unknown>"));
f3485b74
NC
3294}
3295
343433df
AB
3296static void
3297decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3298{
3299 --size; /* Leave space for null terminator. */
3300
3301 switch (e_flags & EF_AVR_MACH)
3302 {
3303 case E_AVR_MACH_AVR1:
3304 strncat (buf, ", avr:1", size);
3305 break;
3306 case E_AVR_MACH_AVR2:
3307 strncat (buf, ", avr:2", size);
3308 break;
3309 case E_AVR_MACH_AVR25:
3310 strncat (buf, ", avr:25", size);
3311 break;
3312 case E_AVR_MACH_AVR3:
3313 strncat (buf, ", avr:3", size);
3314 break;
3315 case E_AVR_MACH_AVR31:
3316 strncat (buf, ", avr:31", size);
3317 break;
3318 case E_AVR_MACH_AVR35:
3319 strncat (buf, ", avr:35", size);
3320 break;
3321 case E_AVR_MACH_AVR4:
3322 strncat (buf, ", avr:4", size);
3323 break;
3324 case E_AVR_MACH_AVR5:
3325 strncat (buf, ", avr:5", size);
3326 break;
3327 case E_AVR_MACH_AVR51:
3328 strncat (buf, ", avr:51", size);
3329 break;
3330 case E_AVR_MACH_AVR6:
3331 strncat (buf, ", avr:6", size);
3332 break;
3333 case E_AVR_MACH_AVRTINY:
3334 strncat (buf, ", avr:100", size);
3335 break;
3336 case E_AVR_MACH_XMEGA1:
3337 strncat (buf, ", avr:101", size);
3338 break;
3339 case E_AVR_MACH_XMEGA2:
3340 strncat (buf, ", avr:102", size);
3341 break;
3342 case E_AVR_MACH_XMEGA3:
3343 strncat (buf, ", avr:103", size);
3344 break;
3345 case E_AVR_MACH_XMEGA4:
3346 strncat (buf, ", avr:104", size);
3347 break;
3348 case E_AVR_MACH_XMEGA5:
3349 strncat (buf, ", avr:105", size);
3350 break;
3351 case E_AVR_MACH_XMEGA6:
3352 strncat (buf, ", avr:106", size);
3353 break;
3354 case E_AVR_MACH_XMEGA7:
3355 strncat (buf, ", avr:107", size);
3356 break;
3357 default:
3358 strncat (buf, ", avr:<unknown>", size);
3359 break;
3360 }
3361
3362 size -= strlen (buf);
3363 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3364 strncat (buf, ", link-relax", size);
3365}
3366
35c08157
KLC
3367static void
3368decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3369{
3370 unsigned abi;
3371 unsigned arch;
3372 unsigned config;
3373 unsigned version;
015dc7e1 3374 bool has_fpu = false;
32ec8896 3375 unsigned int r = 0;
35c08157
KLC
3376
3377 static const char *ABI_STRINGS[] =
3378 {
3379 "ABI v0", /* use r5 as return register; only used in N1213HC */
3380 "ABI v1", /* use r0 as return register */
3381 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3382 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3383 "AABI",
3384 "ABI2 FP+"
35c08157
KLC
3385 };
3386 static const char *VER_STRINGS[] =
3387 {
3388 "Andes ELF V1.3 or older",
3389 "Andes ELF V1.3.1",
3390 "Andes ELF V1.4"
3391 };
3392 static const char *ARCH_STRINGS[] =
3393 {
3394 "",
3395 "Andes Star v1.0",
3396 "Andes Star v2.0",
3397 "Andes Star v3.0",
3398 "Andes Star v3.0m"
3399 };
3400
3401 abi = EF_NDS_ABI & e_flags;
3402 arch = EF_NDS_ARCH & e_flags;
3403 config = EF_NDS_INST & e_flags;
3404 version = EF_NDS32_ELF_VERSION & e_flags;
3405
3406 memset (buf, 0, size);
3407
3408 switch (abi)
3409 {
3410 case E_NDS_ABI_V0:
3411 case E_NDS_ABI_V1:
3412 case E_NDS_ABI_V2:
3413 case E_NDS_ABI_V2FP:
3414 case E_NDS_ABI_AABI:
40c7a7cb 3415 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3416 /* In case there are holes in the array. */
3417 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3418 break;
3419
3420 default:
3421 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3422 break;
3423 }
3424
3425 switch (version)
3426 {
3427 case E_NDS32_ELF_VER_1_2:
3428 case E_NDS32_ELF_VER_1_3:
3429 case E_NDS32_ELF_VER_1_4:
3430 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3431 break;
3432
3433 default:
3434 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3435 break;
3436 }
3437
3438 if (E_NDS_ABI_V0 == abi)
3439 {
3440 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3441 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3442 if (arch == E_NDS_ARCH_STAR_V1_0)
3443 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3444 return;
3445 }
3446
3447 switch (arch)
3448 {
3449 case E_NDS_ARCH_STAR_V1_0:
3450 case E_NDS_ARCH_STAR_V2_0:
3451 case E_NDS_ARCH_STAR_V3_0:
3452 case E_NDS_ARCH_STAR_V3_M:
3453 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3454 break;
3455
3456 default:
3457 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3458 /* ARCH version determines how the e_flags are interpreted.
3459 If it is unknown, we cannot proceed. */
3460 return;
3461 }
3462
3463 /* Newer ABI; Now handle architecture specific flags. */
3464 if (arch == E_NDS_ARCH_STAR_V1_0)
3465 {
3466 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3467 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3468
3469 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3470 r += snprintf (buf + r, size -r, ", MAC");
3471
3472 if (config & E_NDS32_HAS_DIV_INST)
3473 r += snprintf (buf + r, size -r, ", DIV");
3474
3475 if (config & E_NDS32_HAS_16BIT_INST)
3476 r += snprintf (buf + r, size -r, ", 16b");
3477 }
3478 else
3479 {
3480 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3481 {
3482 if (version <= E_NDS32_ELF_VER_1_3)
3483 r += snprintf (buf + r, size -r, ", [B8]");
3484 else
3485 r += snprintf (buf + r, size -r, ", EX9");
3486 }
3487
3488 if (config & E_NDS32_HAS_MAC_DX_INST)
3489 r += snprintf (buf + r, size -r, ", MAC_DX");
3490
3491 if (config & E_NDS32_HAS_DIV_DX_INST)
3492 r += snprintf (buf + r, size -r, ", DIV_DX");
3493
3494 if (config & E_NDS32_HAS_16BIT_INST)
3495 {
3496 if (version <= E_NDS32_ELF_VER_1_3)
3497 r += snprintf (buf + r, size -r, ", 16b");
3498 else
3499 r += snprintf (buf + r, size -r, ", IFC");
3500 }
3501 }
3502
3503 if (config & E_NDS32_HAS_EXT_INST)
3504 r += snprintf (buf + r, size -r, ", PERF1");
3505
3506 if (config & E_NDS32_HAS_EXT2_INST)
3507 r += snprintf (buf + r, size -r, ", PERF2");
3508
3509 if (config & E_NDS32_HAS_FPU_INST)
3510 {
015dc7e1 3511 has_fpu = true;
35c08157
KLC
3512 r += snprintf (buf + r, size -r, ", FPU_SP");
3513 }
3514
3515 if (config & E_NDS32_HAS_FPU_DP_INST)
3516 {
015dc7e1 3517 has_fpu = true;
35c08157
KLC
3518 r += snprintf (buf + r, size -r, ", FPU_DP");
3519 }
3520
3521 if (config & E_NDS32_HAS_FPU_MAC_INST)
3522 {
015dc7e1 3523 has_fpu = true;
35c08157
KLC
3524 r += snprintf (buf + r, size -r, ", FPU_MAC");
3525 }
3526
3527 if (has_fpu)
3528 {
3529 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3530 {
3531 case E_NDS32_FPU_REG_8SP_4DP:
3532 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3533 break;
3534 case E_NDS32_FPU_REG_16SP_8DP:
3535 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3536 break;
3537 case E_NDS32_FPU_REG_32SP_16DP:
3538 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3539 break;
3540 case E_NDS32_FPU_REG_32SP_32DP:
3541 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3542 break;
3543 }
3544 }
3545
3546 if (config & E_NDS32_HAS_AUDIO_INST)
3547 r += snprintf (buf + r, size -r, ", AUDIO");
3548
3549 if (config & E_NDS32_HAS_STRING_INST)
3550 r += snprintf (buf + r, size -r, ", STR");
3551
3552 if (config & E_NDS32_HAS_REDUCED_REGS)
3553 r += snprintf (buf + r, size -r, ", 16REG");
3554
3555 if (config & E_NDS32_HAS_VIDEO_INST)
3556 {
3557 if (version <= E_NDS32_ELF_VER_1_3)
3558 r += snprintf (buf + r, size -r, ", VIDEO");
3559 else
3560 r += snprintf (buf + r, size -r, ", SATURATION");
3561 }
3562
3563 if (config & E_NDS32_HAS_ENCRIPT_INST)
3564 r += snprintf (buf + r, size -r, ", ENCRP");
3565
3566 if (config & E_NDS32_HAS_L2C_INST)
3567 r += snprintf (buf + r, size -r, ", L2C");
3568}
3569
c077c580
SM
3570static void
3571decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3572 char *buf)
3573{
3574 unsigned char *e_ident = filedata->file_header.e_ident;
3575 unsigned char osabi = e_ident[EI_OSABI];
3576 unsigned char abiversion = e_ident[EI_ABIVERSION];
3577 unsigned int mach;
3578
3579 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3580 it has been deprecated for a while.
3581
3582 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3583 of writing, they use the same flags as HSA v3, so the code below uses that
3584 assumption. */
3585 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3586 return;
3587
3588 mach = e_flags & EF_AMDGPU_MACH;
3589 switch (mach)
3590 {
3591#define AMDGPU_CASE(code, string) \
3592 case code: strcat (buf, ", " string); break;
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3614 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3615 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3616 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3617 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3618 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3619 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3620 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3621 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3622 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3623 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3624 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3625 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3626 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3627 default:
3628 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3629 break;
3630#undef AMDGPU_CASE
3631 }
3632
3633 buf += strlen (buf);
3634 e_flags &= ~EF_AMDGPU_MACH;
3635
3636 if ((osabi == ELFOSABI_AMDGPU_HSA
3637 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3638 || osabi != ELFOSABI_AMDGPU_HSA)
3639 {
3640 /* For HSA v3 and other OS ABIs. */
3641 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3642 {
3643 strcat (buf, ", xnack on");
3644 buf += strlen (buf);
3645 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3646 }
3647
3648 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3649 {
3650 strcat (buf, ", sramecc on");
3651 buf += strlen (buf);
3652 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3653 }
3654 }
3655 else
3656 {
3657 /* For HSA v4+. */
3658 int xnack, sramecc;
3659
3660 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3661 switch (xnack)
3662 {
3663 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3664 break;
3665
3666 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3667 strcat (buf, ", xnack any");
3668 break;
3669
3670 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3671 strcat (buf, ", xnack off");
3672 break;
3673
3674 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3675 strcat (buf, ", xnack on");
3676 break;
3677
3678 default:
3679 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3680 break;
3681 }
3682
3683 buf += strlen (buf);
3684 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3685
3686 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3687 switch (sramecc)
3688 {
3689 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3690 break;
3691
3692 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3693 strcat (buf, ", sramecc any");
3694 break;
3695
3696 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3697 strcat (buf, ", sramecc off");
3698 break;
3699
3700 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3701 strcat (buf, ", sramecc on");
3702 break;
3703
3704 default:
3705 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3706 break;
3707 }
3708
3709 buf += strlen (buf);
3710 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3711 }
3712
3713 if (e_flags != 0)
3714 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3715}
3716
252b5132 3717static char *
dda8d76d 3718get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3719{
b34976b6 3720 static char buf[1024];
252b5132
RH
3721
3722 buf[0] = '\0';
76da6bbe 3723
252b5132
RH
3724 if (e_flags)
3725 {
3726 switch (e_machine)
3727 {
3728 default:
3729 break;
3730
886a2506 3731 case EM_ARC_COMPACT2:
886a2506 3732 case EM_ARC_COMPACT:
a9522a21
AB
3733 decode_ARC_machine_flags (e_flags, e_machine, buf);
3734 break;
886a2506 3735
f3485b74
NC
3736 case EM_ARM:
3737 decode_ARM_machine_flags (e_flags, buf);
3738 break;
76da6bbe 3739
343433df
AB
3740 case EM_AVR:
3741 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3742 break;
3743
781303ce
MF
3744 case EM_BLACKFIN:
3745 if (e_flags & EF_BFIN_PIC)
3746 strcat (buf, ", PIC");
3747
3748 if (e_flags & EF_BFIN_FDPIC)
3749 strcat (buf, ", FDPIC");
3750
3751 if (e_flags & EF_BFIN_CODE_IN_L1)
3752 strcat (buf, ", code in L1");
3753
3754 if (e_flags & EF_BFIN_DATA_IN_L1)
3755 strcat (buf, ", data in L1");
3756
3757 break;
3758
ec2dfb42
AO
3759 case EM_CYGNUS_FRV:
3760 switch (e_flags & EF_FRV_CPU_MASK)
3761 {
3762 case EF_FRV_CPU_GENERIC:
3763 break;
3764
3765 default:
3766 strcat (buf, ", fr???");
3767 break;
57346661 3768
ec2dfb42
AO
3769 case EF_FRV_CPU_FR300:
3770 strcat (buf, ", fr300");
3771 break;
3772
3773 case EF_FRV_CPU_FR400:
3774 strcat (buf, ", fr400");
3775 break;
3776 case EF_FRV_CPU_FR405:
3777 strcat (buf, ", fr405");
3778 break;
3779
3780 case EF_FRV_CPU_FR450:
3781 strcat (buf, ", fr450");
3782 break;
3783
3784 case EF_FRV_CPU_FR500:
3785 strcat (buf, ", fr500");
3786 break;
3787 case EF_FRV_CPU_FR550:
3788 strcat (buf, ", fr550");
3789 break;
3790
3791 case EF_FRV_CPU_SIMPLE:
3792 strcat (buf, ", simple");
3793 break;
3794 case EF_FRV_CPU_TOMCAT:
3795 strcat (buf, ", tomcat");
3796 break;
3797 }
1c877e87 3798 break;
ec2dfb42 3799
53c7db4b 3800 case EM_68K:
425c6cb0 3801 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3802 strcat (buf, ", m68000");
425c6cb0 3803 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3804 strcat (buf, ", cpu32");
3805 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3806 strcat (buf, ", fido_a");
425c6cb0 3807 else
266abb8f 3808 {
2cf0635d
NC
3809 char const * isa = _("unknown");
3810 char const * mac = _("unknown mac");
3811 char const * additional = NULL;
0112cd26 3812
c694fd50 3813 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3814 {
c694fd50 3815 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3816 isa = "A";
3817 additional = ", nodiv";
3818 break;
c694fd50 3819 case EF_M68K_CF_ISA_A:
266abb8f
NS
3820 isa = "A";
3821 break;
c694fd50 3822 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3823 isa = "A+";
3824 break;
c694fd50 3825 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3826 isa = "B";
3827 additional = ", nousp";
3828 break;
c694fd50 3829 case EF_M68K_CF_ISA_B:
266abb8f
NS
3830 isa = "B";
3831 break;
f608cd77
NS
3832 case EF_M68K_CF_ISA_C:
3833 isa = "C";
3834 break;
3835 case EF_M68K_CF_ISA_C_NODIV:
3836 isa = "C";
3837 additional = ", nodiv";
3838 break;
266abb8f
NS
3839 }
3840 strcat (buf, ", cf, isa ");
3841 strcat (buf, isa);
0b2e31dc
NS
3842 if (additional)
3843 strcat (buf, additional);
c694fd50 3844 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3845 strcat (buf, ", float");
c694fd50 3846 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3847 {
3848 case 0:
3849 mac = NULL;
3850 break;
c694fd50 3851 case EF_M68K_CF_MAC:
266abb8f
NS
3852 mac = "mac";
3853 break;
c694fd50 3854 case EF_M68K_CF_EMAC:
266abb8f
NS
3855 mac = "emac";
3856 break;
f608cd77
NS
3857 case EF_M68K_CF_EMAC_B:
3858 mac = "emac_b";
3859 break;
266abb8f
NS
3860 }
3861 if (mac)
3862 {
3863 strcat (buf, ", ");
3864 strcat (buf, mac);
3865 }
266abb8f 3866 }
53c7db4b 3867 break;
33c63f9d 3868
c077c580
SM
3869 case EM_AMDGPU:
3870 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3871 break;
3872
153a2776
NC
3873 case EM_CYGNUS_MEP:
3874 switch (e_flags & EF_MEP_CPU_MASK)
3875 {
3876 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3877 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3878 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3879 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3880 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3881 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3882 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3883 }
3884
3885 switch (e_flags & EF_MEP_COP_MASK)
3886 {
3887 case EF_MEP_COP_NONE: break;
3888 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3889 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3890 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3891 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3892 default: strcat (buf, _("<unknown MeP copro type>")); break;
3893 }
3894
3895 if (e_flags & EF_MEP_LIBRARY)
3896 strcat (buf, ", Built for Library");
3897
3898 if (e_flags & EF_MEP_INDEX_MASK)
3899 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3900 e_flags & EF_MEP_INDEX_MASK);
3901
3902 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3903 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3904 e_flags & ~ EF_MEP_ALL_FLAGS);
3905 break;
3906
252b5132
RH
3907 case EM_PPC:
3908 if (e_flags & EF_PPC_EMB)
3909 strcat (buf, ", emb");
3910
3911 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3912 strcat (buf, _(", relocatable"));
252b5132
RH
3913
3914 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3915 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3916 break;
3917
ee67d69a
AM
3918 case EM_PPC64:
3919 if (e_flags & EF_PPC64_ABI)
3920 {
3921 char abi[] = ", abiv0";
3922
3923 abi[6] += e_flags & EF_PPC64_ABI;
3924 strcat (buf, abi);
3925 }
3926 break;
3927
708e2187
NC
3928 case EM_V800:
3929 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3930 strcat (buf, ", RH850 ABI");
0b4362b0 3931
708e2187
NC
3932 if (e_flags & EF_V800_850E3)
3933 strcat (buf, ", V3 architecture");
3934
3935 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3936 strcat (buf, ", FPU not used");
3937
3938 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3939 strcat (buf, ", regmode: COMMON");
3940
3941 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3942 strcat (buf, ", r4 not used");
3943
3944 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3945 strcat (buf, ", r30 not used");
3946
3947 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3948 strcat (buf, ", r5 not used");
3949
3950 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3951 strcat (buf, ", r2 not used");
3952
3953 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3954 {
3955 switch (e_flags & - e_flags)
3956 {
3957 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3958 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3959 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3960 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3961 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3962 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3963 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3964 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3965 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3966 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3967 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3968 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3969 default: break;
3970 }
3971 }
3972 break;
3973
2b0337b0 3974 case EM_V850:
252b5132
RH
3975 case EM_CYGNUS_V850:
3976 switch (e_flags & EF_V850_ARCH)
3977 {
78c8d46c
NC
3978 case E_V850E3V5_ARCH:
3979 strcat (buf, ", v850e3v5");
3980 break;
1cd986c5
NC
3981 case E_V850E2V3_ARCH:
3982 strcat (buf, ", v850e2v3");
3983 break;
3984 case E_V850E2_ARCH:
3985 strcat (buf, ", v850e2");
3986 break;
3987 case E_V850E1_ARCH:
3988 strcat (buf, ", v850e1");
8ad30312 3989 break;
252b5132
RH
3990 case E_V850E_ARCH:
3991 strcat (buf, ", v850e");
3992 break;
252b5132
RH
3993 case E_V850_ARCH:
3994 strcat (buf, ", v850");
3995 break;
3996 default:
2b692964 3997 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3998 break;
3999 }
4000 break;
4001
2b0337b0 4002 case EM_M32R:
252b5132
RH
4003 case EM_CYGNUS_M32R:
4004 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4005 strcat (buf, ", m32r");
252b5132
RH
4006 break;
4007
4008 case EM_MIPS:
4fe85591 4009 case EM_MIPS_RS3_LE:
252b5132
RH
4010 if (e_flags & EF_MIPS_NOREORDER)
4011 strcat (buf, ", noreorder");
4012
4013 if (e_flags & EF_MIPS_PIC)
4014 strcat (buf, ", pic");
4015
4016 if (e_flags & EF_MIPS_CPIC)
4017 strcat (buf, ", cpic");
4018
d1bdd336
TS
4019 if (e_flags & EF_MIPS_UCODE)
4020 strcat (buf, ", ugen_reserved");
4021
252b5132
RH
4022 if (e_flags & EF_MIPS_ABI2)
4023 strcat (buf, ", abi2");
4024
43521d43
TS
4025 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4026 strcat (buf, ", odk first");
4027
a5d22d2a
TS
4028 if (e_flags & EF_MIPS_32BITMODE)
4029 strcat (buf, ", 32bitmode");
4030
ba92f887
MR
4031 if (e_flags & EF_MIPS_NAN2008)
4032 strcat (buf, ", nan2008");
4033
fef1b0b3
SE
4034 if (e_flags & EF_MIPS_FP64)
4035 strcat (buf, ", fp64");
4036
156c2f8b
NC
4037 switch ((e_flags & EF_MIPS_MACH))
4038 {
4039 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4040 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4041 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4042 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4043 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4044 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4045 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4046 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4047 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4048 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4049 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4050 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4051 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4052 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4053 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4054 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4055 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4056 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4057 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4058 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4059 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4060 case 0:
4061 /* We simply ignore the field in this case to avoid confusion:
4062 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4063 extension. */
4064 break;
2b692964 4065 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4066 }
43521d43
TS
4067
4068 switch ((e_flags & EF_MIPS_ABI))
4069 {
4070 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4071 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4072 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4073 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4074 case 0:
4075 /* We simply ignore the field in this case to avoid confusion:
4076 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4077 This means it is likely to be an o32 file, but not for
4078 sure. */
4079 break;
2b692964 4080 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4081 }
4082
4083 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4084 strcat (buf, ", mdmx");
4085
4086 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4087 strcat (buf, ", mips16");
4088
df58fc94
RS
4089 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4090 strcat (buf, ", micromips");
4091
43521d43
TS
4092 switch ((e_flags & EF_MIPS_ARCH))
4093 {
4094 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4095 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4096 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4097 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4098 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4099 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4100 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4101 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4102 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4103 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4104 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4105 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4106 }
252b5132 4107 break;
351b4b40 4108
35c08157
KLC
4109 case EM_NDS32:
4110 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4111 break;
4112
fe944acf
FT
4113 case EM_NFP:
4114 switch (EF_NFP_MACH (e_flags))
4115 {
4116 case E_NFP_MACH_3200:
4117 strcat (buf, ", NFP-32xx");
4118 break;
4119 case E_NFP_MACH_6000:
4120 strcat (buf, ", NFP-6xxx");
4121 break;
4122 }
4123 break;
4124
e23eba97
NC
4125 case EM_RISCV:
4126 if (e_flags & EF_RISCV_RVC)
4127 strcat (buf, ", RVC");
2922d21d 4128
7f999549
JW
4129 if (e_flags & EF_RISCV_RVE)
4130 strcat (buf, ", RVE");
4131
2922d21d
AW
4132 switch (e_flags & EF_RISCV_FLOAT_ABI)
4133 {
4134 case EF_RISCV_FLOAT_ABI_SOFT:
4135 strcat (buf, ", soft-float ABI");
4136 break;
4137
4138 case EF_RISCV_FLOAT_ABI_SINGLE:
4139 strcat (buf, ", single-float ABI");
4140 break;
4141
4142 case EF_RISCV_FLOAT_ABI_DOUBLE:
4143 strcat (buf, ", double-float ABI");
4144 break;
4145
4146 case EF_RISCV_FLOAT_ABI_QUAD:
4147 strcat (buf, ", quad-float ABI");
4148 break;
4149 }
e23eba97
NC
4150 break;
4151
ccde1100
AO
4152 case EM_SH:
4153 switch ((e_flags & EF_SH_MACH_MASK))
4154 {
4155 case EF_SH1: strcat (buf, ", sh1"); break;
4156 case EF_SH2: strcat (buf, ", sh2"); break;
4157 case EF_SH3: strcat (buf, ", sh3"); break;
4158 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4159 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4160 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4161 case EF_SH3E: strcat (buf, ", sh3e"); break;
4162 case EF_SH4: strcat (buf, ", sh4"); break;
4163 case EF_SH5: strcat (buf, ", sh5"); break;
4164 case EF_SH2E: strcat (buf, ", sh2e"); break;
4165 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4166 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4167 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4168 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4169 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4170 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4171 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4172 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4173 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4174 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4175 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4176 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4177 }
4178
cec6a5b8
MR
4179 if (e_flags & EF_SH_PIC)
4180 strcat (buf, ", pic");
4181
4182 if (e_flags & EF_SH_FDPIC)
4183 strcat (buf, ", fdpic");
ccde1100 4184 break;
948f632f 4185
73589c9d
CS
4186 case EM_OR1K:
4187 if (e_flags & EF_OR1K_NODELAY)
4188 strcat (buf, ", no delay");
4189 break;
57346661 4190
351b4b40
RH
4191 case EM_SPARCV9:
4192 if (e_flags & EF_SPARC_32PLUS)
4193 strcat (buf, ", v8+");
4194
4195 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4196 strcat (buf, ", ultrasparcI");
4197
4198 if (e_flags & EF_SPARC_SUN_US3)
4199 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4200
4201 if (e_flags & EF_SPARC_HAL_R1)
4202 strcat (buf, ", halr1");
4203
4204 if (e_flags & EF_SPARC_LEDATA)
4205 strcat (buf, ", ledata");
4206
4207 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4208 strcat (buf, ", tso");
4209
4210 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4211 strcat (buf, ", pso");
4212
4213 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4214 strcat (buf, ", rmo");
4215 break;
7d466069 4216
103f02d3
UD
4217 case EM_PARISC:
4218 switch (e_flags & EF_PARISC_ARCH)
4219 {
4220 case EFA_PARISC_1_0:
4221 strcpy (buf, ", PA-RISC 1.0");
4222 break;
4223 case EFA_PARISC_1_1:
4224 strcpy (buf, ", PA-RISC 1.1");
4225 break;
4226 case EFA_PARISC_2_0:
4227 strcpy (buf, ", PA-RISC 2.0");
4228 break;
4229 default:
4230 break;
4231 }
4232 if (e_flags & EF_PARISC_TRAPNIL)
4233 strcat (buf, ", trapnil");
4234 if (e_flags & EF_PARISC_EXT)
4235 strcat (buf, ", ext");
4236 if (e_flags & EF_PARISC_LSB)
4237 strcat (buf, ", lsb");
4238 if (e_flags & EF_PARISC_WIDE)
4239 strcat (buf, ", wide");
4240 if (e_flags & EF_PARISC_NO_KABP)
4241 strcat (buf, ", no kabp");
4242 if (e_flags & EF_PARISC_LAZYSWAP)
4243 strcat (buf, ", lazyswap");
30800947 4244 break;
76da6bbe 4245
7d466069 4246 case EM_PJ:
2b0337b0 4247 case EM_PJ_OLD:
7d466069
ILT
4248 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4249 strcat (buf, ", new calling convention");
4250
4251 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4252 strcat (buf, ", gnu calling convention");
4253 break;
4d6ed7c8
NC
4254
4255 case EM_IA_64:
4256 if ((e_flags & EF_IA_64_ABI64))
4257 strcat (buf, ", 64-bit");
4258 else
4259 strcat (buf, ", 32-bit");
4260 if ((e_flags & EF_IA_64_REDUCEDFP))
4261 strcat (buf, ", reduced fp model");
4262 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4263 strcat (buf, ", no function descriptors, constant gp");
4264 else if ((e_flags & EF_IA_64_CONS_GP))
4265 strcat (buf, ", constant gp");
4266 if ((e_flags & EF_IA_64_ABSOLUTE))
4267 strcat (buf, ", absolute");
dda8d76d 4268 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4269 {
4270 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4271 strcat (buf, ", vms_linkages");
4272 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4273 {
4274 case EF_IA_64_VMS_COMCOD_SUCCESS:
4275 break;
4276 case EF_IA_64_VMS_COMCOD_WARNING:
4277 strcat (buf, ", warning");
4278 break;
4279 case EF_IA_64_VMS_COMCOD_ERROR:
4280 strcat (buf, ", error");
4281 break;
4282 case EF_IA_64_VMS_COMCOD_ABORT:
4283 strcat (buf, ", abort");
4284 break;
4285 default:
bee0ee85
NC
4286 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4287 e_flags & EF_IA_64_VMS_COMCOD);
4288 strcat (buf, ", <unknown>");
28f997cf
TG
4289 }
4290 }
4d6ed7c8 4291 break;
179d3252
JT
4292
4293 case EM_VAX:
4294 if ((e_flags & EF_VAX_NONPIC))
4295 strcat (buf, ", non-PIC");
4296 if ((e_flags & EF_VAX_DFLOAT))
4297 strcat (buf, ", D-Float");
4298 if ((e_flags & EF_VAX_GFLOAT))
4299 strcat (buf, ", G-Float");
4300 break;
c7927a3c 4301
619ed720
EB
4302 case EM_VISIUM:
4303 if (e_flags & EF_VISIUM_ARCH_MCM)
4304 strcat (buf, ", mcm");
4305 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4306 strcat (buf, ", mcm24");
4307 if (e_flags & EF_VISIUM_ARCH_GR6)
4308 strcat (buf, ", gr6");
4309 break;
4310
4046d87a 4311 case EM_RL78:
1740ba0c
NC
4312 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4313 {
4314 case E_FLAG_RL78_ANY_CPU: break;
4315 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4316 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4317 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4318 }
856ea05c
KP
4319 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4320 strcat (buf, ", 64-bit doubles");
4046d87a 4321 break;
0b4362b0 4322
c7927a3c
NC
4323 case EM_RX:
4324 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4325 strcat (buf, ", 64-bit doubles");
4326 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4327 strcat (buf, ", dsp");
d4cb0ea0 4328 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4329 strcat (buf, ", pid");
708e2187
NC
4330 if (e_flags & E_FLAG_RX_ABI)
4331 strcat (buf, ", RX ABI");
3525236c
NC
4332 if (e_flags & E_FLAG_RX_SINSNS_SET)
4333 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4334 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4335 if (e_flags & E_FLAG_RX_V2)
4336 strcat (buf, ", V2");
f87673e0
YS
4337 if (e_flags & E_FLAG_RX_V3)
4338 strcat (buf, ", V3");
d4cb0ea0 4339 break;
55786da2
AK
4340
4341 case EM_S390:
4342 if (e_flags & EF_S390_HIGH_GPRS)
4343 strcat (buf, ", highgprs");
d4cb0ea0 4344 break;
40b36596
JM
4345
4346 case EM_TI_C6000:
4347 if ((e_flags & EF_C6000_REL))
4348 strcat (buf, ", relocatable module");
d4cb0ea0 4349 break;
13761a11
NC
4350
4351 case EM_MSP430:
4352 strcat (buf, _(": architecture variant: "));
4353 switch (e_flags & EF_MSP430_MACH)
4354 {
4355 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4356 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4357 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4358 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4359 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4360 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4361 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4362 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4363 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4364 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4365 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4366 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4367 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4368 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4369 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4370 default:
4371 strcat (buf, _(": unknown")); break;
4372 }
4373
4374 if (e_flags & ~ EF_MSP430_MACH)
4375 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4376 break;
4377
4378 case EM_Z80:
4379 switch (e_flags & EF_Z80_MACH_MSK)
4380 {
4381 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4382 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4383 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4384 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4385 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4386 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4387 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4388 default:
4389 strcat (buf, _(", unknown")); break;
4390 }
4391 break;
e9a0721f 4392 case EM_LOONGARCH:
4393 if (EF_LOONGARCH_IS_LP64 (e_flags))
4394 strcat (buf, ", LP64");
4395 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4396 strcat (buf, ", ILP32");
4397
4398 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4399 strcat (buf, ", SOFT-FLOAT");
4400 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4401 strcat (buf, ", SINGLE-FLOAT");
4402 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4403 strcat (buf, ", DOUBLE-FLOAT");
4404
4405 break;
252b5132
RH
4406 }
4407 }
4408
4409 return buf;
4410}
4411
252b5132 4412static const char *
dda8d76d 4413get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4414{
4415 static char buff[32];
4416
4417 switch (osabi)
4418 {
4419 case ELFOSABI_NONE: return "UNIX - System V";
4420 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4421 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4422 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4423 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4424 case ELFOSABI_AIX: return "UNIX - AIX";
4425 case ELFOSABI_IRIX: return "UNIX - IRIX";
4426 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4427 case ELFOSABI_TRU64: return "UNIX - TRU64";
4428 case ELFOSABI_MODESTO: return "Novell - Modesto";
4429 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4430 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4431 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4432 case ELFOSABI_AROS: return "AROS";
11636f9e 4433 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4434 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4435 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4436 default:
40b36596 4437 if (osabi >= 64)
dda8d76d 4438 switch (filedata->file_header.e_machine)
40b36596 4439 {
37870be8
SM
4440 case EM_AMDGPU:
4441 switch (osabi)
4442 {
4443 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4444 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4445 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4446 default:
4447 break;
4448 }
4449 break;
4450
40b36596
JM
4451 case EM_ARM:
4452 switch (osabi)
4453 {
4454 case ELFOSABI_ARM: return "ARM";
18a20338 4455 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4456 default:
4457 break;
4458 }
4459 break;
4460
4461 case EM_MSP430:
4462 case EM_MSP430_OLD:
619ed720 4463 case EM_VISIUM:
40b36596
JM
4464 switch (osabi)
4465 {
4466 case ELFOSABI_STANDALONE: return _("Standalone App");
4467 default:
4468 break;
4469 }
4470 break;
4471
4472 case EM_TI_C6000:
4473 switch (osabi)
4474 {
4475 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4476 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4477 default:
4478 break;
4479 }
4480 break;
4481
4482 default:
4483 break;
4484 }
e9e44622 4485 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4486 return buff;
4487 }
4488}
4489
a06ea964
NC
4490static const char *
4491get_aarch64_segment_type (unsigned long type)
4492{
4493 switch (type)
4494 {
32ec8896 4495 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4496 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4497 default: return NULL;
a06ea964 4498 }
a06ea964
NC
4499}
4500
b294bdf8
MM
4501static const char *
4502get_arm_segment_type (unsigned long type)
4503{
4504 switch (type)
4505 {
32ec8896
NC
4506 case PT_ARM_EXIDX: return "EXIDX";
4507 default: return NULL;
b294bdf8 4508 }
b294bdf8
MM
4509}
4510
b4cbbe8f
AK
4511static const char *
4512get_s390_segment_type (unsigned long type)
4513{
4514 switch (type)
4515 {
4516 case PT_S390_PGSTE: return "S390_PGSTE";
4517 default: return NULL;
4518 }
4519}
4520
d3ba0551
AM
4521static const char *
4522get_mips_segment_type (unsigned long type)
252b5132
RH
4523{
4524 switch (type)
4525 {
32ec8896
NC
4526 case PT_MIPS_REGINFO: return "REGINFO";
4527 case PT_MIPS_RTPROC: return "RTPROC";
4528 case PT_MIPS_OPTIONS: return "OPTIONS";
4529 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4530 default: return NULL;
252b5132 4531 }
252b5132
RH
4532}
4533
103f02d3 4534static const char *
d3ba0551 4535get_parisc_segment_type (unsigned long type)
103f02d3
UD
4536{
4537 switch (type)
4538 {
103f02d3
UD
4539 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4540 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4541 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4542 default: return NULL;
103f02d3 4543 }
103f02d3
UD
4544}
4545
4d6ed7c8 4546static const char *
d3ba0551 4547get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4548{
4549 switch (type)
4550 {
4551 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4552 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4553 default: return NULL;
4d6ed7c8 4554 }
4d6ed7c8
NC
4555}
4556
40b36596
JM
4557static const char *
4558get_tic6x_segment_type (unsigned long type)
4559{
4560 switch (type)
4561 {
32ec8896
NC
4562 case PT_C6000_PHATTR: return "C6000_PHATTR";
4563 default: return NULL;
40b36596 4564 }
40b36596
JM
4565}
4566
fbc95f1e
KC
4567static const char *
4568get_riscv_segment_type (unsigned long type)
4569{
4570 switch (type)
4571 {
4572 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4573 default: return NULL;
4574 }
4575}
4576
df3a023b
AM
4577static const char *
4578get_hpux_segment_type (unsigned long type, unsigned e_machine)
4579{
4580 if (e_machine == EM_PARISC)
4581 switch (type)
4582 {
4583 case PT_HP_TLS: return "HP_TLS";
4584 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4585 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4586 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4587 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4588 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4589 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4590 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4591 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4592 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4593 case PT_HP_PARALLEL: return "HP_PARALLEL";
4594 case PT_HP_FASTBIND: return "HP_FASTBIND";
4595 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4596 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4597 case PT_HP_STACK: return "HP_STACK";
4598 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4599 default: return NULL;
4600 }
4601
4602 if (e_machine == EM_IA_64)
4603 switch (type)
4604 {
4605 case PT_HP_TLS: return "HP_TLS";
4606 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4607 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4608 case PT_IA_64_HP_STACK: return "HP_STACK";
4609 default: return NULL;
4610 }
4611
4612 return NULL;
4613}
4614
5522f910
NC
4615static const char *
4616get_solaris_segment_type (unsigned long type)
4617{
4618 switch (type)
4619 {
4620 case 0x6464e550: return "PT_SUNW_UNWIND";
4621 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4622 case 0x6ffffff7: return "PT_LOSUNW";
4623 case 0x6ffffffa: return "PT_SUNWBSS";
4624 case 0x6ffffffb: return "PT_SUNWSTACK";
4625 case 0x6ffffffc: return "PT_SUNWDTRACE";
4626 case 0x6ffffffd: return "PT_SUNWCAP";
4627 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4628 default: return NULL;
5522f910
NC
4629 }
4630}
4631
252b5132 4632static const char *
dda8d76d 4633get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4634{
b34976b6 4635 static char buff[32];
252b5132
RH
4636
4637 switch (p_type)
4638 {
b34976b6
AM
4639 case PT_NULL: return "NULL";
4640 case PT_LOAD: return "LOAD";
252b5132 4641 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4642 case PT_INTERP: return "INTERP";
4643 case PT_NOTE: return "NOTE";
4644 case PT_SHLIB: return "SHLIB";
4645 case PT_PHDR: return "PHDR";
13ae64f3 4646 case PT_TLS: return "TLS";
32ec8896 4647 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4648 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4649 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4650 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4651
3eba3ef3
NC
4652 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4653 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4654 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4655
252b5132 4656 default:
df3a023b 4657 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4658 {
2cf0635d 4659 const char * result;
103f02d3 4660
dda8d76d 4661 switch (filedata->file_header.e_machine)
252b5132 4662 {
a06ea964
NC
4663 case EM_AARCH64:
4664 result = get_aarch64_segment_type (p_type);
4665 break;
b294bdf8
MM
4666 case EM_ARM:
4667 result = get_arm_segment_type (p_type);
4668 break;
252b5132 4669 case EM_MIPS:
4fe85591 4670 case EM_MIPS_RS3_LE:
252b5132
RH
4671 result = get_mips_segment_type (p_type);
4672 break;
103f02d3
UD
4673 case EM_PARISC:
4674 result = get_parisc_segment_type (p_type);
4675 break;
4d6ed7c8
NC
4676 case EM_IA_64:
4677 result = get_ia64_segment_type (p_type);
4678 break;
40b36596
JM
4679 case EM_TI_C6000:
4680 result = get_tic6x_segment_type (p_type);
4681 break;
b4cbbe8f
AK
4682 case EM_S390:
4683 case EM_S390_OLD:
4684 result = get_s390_segment_type (p_type);
4685 break;
fbc95f1e
KC
4686 case EM_RISCV:
4687 result = get_riscv_segment_type (p_type);
4688 break;
252b5132
RH
4689 default:
4690 result = NULL;
4691 break;
4692 }
103f02d3 4693
252b5132
RH
4694 if (result != NULL)
4695 return result;
103f02d3 4696
1a9ccd70 4697 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4698 }
4699 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4700 {
df3a023b 4701 const char * result = NULL;
103f02d3 4702
df3a023b 4703 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4704 {
df3a023b
AM
4705 case ELFOSABI_GNU:
4706 case ELFOSABI_FREEBSD:
4707 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4708 {
4709 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4710 result = buff;
4711 }
103f02d3 4712 break;
df3a023b
AM
4713 case ELFOSABI_HPUX:
4714 result = get_hpux_segment_type (p_type,
4715 filedata->file_header.e_machine);
4716 break;
4717 case ELFOSABI_SOLARIS:
4718 result = get_solaris_segment_type (p_type);
00428cca 4719 break;
103f02d3 4720 default:
103f02d3
UD
4721 break;
4722 }
103f02d3
UD
4723 if (result != NULL)
4724 return result;
4725
1a9ccd70 4726 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4727 }
252b5132 4728 else
e9e44622 4729 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4730
4731 return buff;
4732 }
4733}
4734
53a346d8
CZ
4735static const char *
4736get_arc_section_type_name (unsigned int sh_type)
4737{
4738 switch (sh_type)
4739 {
4740 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4741 default:
4742 break;
4743 }
4744 return NULL;
4745}
4746
252b5132 4747static const char *
d3ba0551 4748get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4749{
4750 switch (sh_type)
4751 {
b34976b6
AM
4752 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4753 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4754 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4755 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4756 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4757 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4758 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4759 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4760 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4761 case SHT_MIPS_RELD: return "MIPS_RELD";
4762 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4763 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4764 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4765 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4766 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4767 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4768 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4769 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4770 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4771 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4772 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4773 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4774 case SHT_MIPS_LINE: return "MIPS_LINE";
4775 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4776 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4777 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4778 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4779 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4780 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4781 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4782 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4783 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4784 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4785 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4786 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4787 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4788 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4789 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4790 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4791 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4792 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4793 default:
4794 break;
4795 }
4796 return NULL;
4797}
4798
103f02d3 4799static const char *
d3ba0551 4800get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4801{
4802 switch (sh_type)
4803 {
4804 case SHT_PARISC_EXT: return "PARISC_EXT";
4805 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4806 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4807 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4808 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4809 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4810 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4811 default: return NULL;
103f02d3 4812 }
103f02d3
UD
4813}
4814
4d6ed7c8 4815static const char *
dda8d76d 4816get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4817{
18bd398b 4818 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4819 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4820 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4821
4d6ed7c8
NC
4822 switch (sh_type)
4823 {
148b93f2
NC
4824 case SHT_IA_64_EXT: return "IA_64_EXT";
4825 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4826 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4827 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4828 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4829 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4830 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4831 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4832 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4833 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4834 default:
4835 break;
4836 }
4837 return NULL;
4838}
4839
d2b2c203
DJ
4840static const char *
4841get_x86_64_section_type_name (unsigned int sh_type)
4842{
4843 switch (sh_type)
4844 {
4845 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4846 default: return NULL;
d2b2c203 4847 }
d2b2c203
DJ
4848}
4849
a06ea964
NC
4850static const char *
4851get_aarch64_section_type_name (unsigned int sh_type)
4852{
4853 switch (sh_type)
4854 {
32ec8896
NC
4855 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4856 default: return NULL;
a06ea964 4857 }
a06ea964
NC
4858}
4859
40a18ebd
NC
4860static const char *
4861get_arm_section_type_name (unsigned int sh_type)
4862{
4863 switch (sh_type)
4864 {
7f6fed87
NC
4865 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4866 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4867 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4868 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4869 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4870 default: return NULL;
40a18ebd 4871 }
40a18ebd
NC
4872}
4873
40b36596
JM
4874static const char *
4875get_tic6x_section_type_name (unsigned int sh_type)
4876{
4877 switch (sh_type)
4878 {
32ec8896
NC
4879 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4880 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4881 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4882 case SHT_TI_ICODE: return "TI_ICODE";
4883 case SHT_TI_XREF: return "TI_XREF";
4884 case SHT_TI_HANDLER: return "TI_HANDLER";
4885 case SHT_TI_INITINFO: return "TI_INITINFO";
4886 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4887 default: return NULL;
40b36596 4888 }
40b36596
JM
4889}
4890
13761a11 4891static const char *
b0191216 4892get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4893{
4894 switch (sh_type)
4895 {
32ec8896
NC
4896 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4897 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4898 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4899 default: return NULL;
13761a11
NC
4900 }
4901}
4902
fe944acf
FT
4903static const char *
4904get_nfp_section_type_name (unsigned int sh_type)
4905{
4906 switch (sh_type)
4907 {
4908 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4909 case SHT_NFP_INITREG: return "NFP_INITREG";
4910 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4911 default: return NULL;
4912 }
4913}
4914
685080f2
NC
4915static const char *
4916get_v850_section_type_name (unsigned int sh_type)
4917{
4918 switch (sh_type)
4919 {
32ec8896
NC
4920 case SHT_V850_SCOMMON: return "V850 Small Common";
4921 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4922 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4923 case SHT_RENESAS_IOP: return "RENESAS IOP";
4924 case SHT_RENESAS_INFO: return "RENESAS INFO";
4925 default: return NULL;
685080f2
NC
4926 }
4927}
4928
2dc8dd17
JW
4929static const char *
4930get_riscv_section_type_name (unsigned int sh_type)
4931{
4932 switch (sh_type)
4933 {
4934 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4935 default: return NULL;
4936 }
4937}
4938
0861f561
CQ
4939static const char *
4940get_csky_section_type_name (unsigned int sh_type)
4941{
4942 switch (sh_type)
4943 {
4944 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4945 default: return NULL;
4946 }
4947}
4948
252b5132 4949static const char *
dda8d76d 4950get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4951{
b34976b6 4952 static char buff[32];
9fb71ee4 4953 const char * result;
252b5132
RH
4954
4955 switch (sh_type)
4956 {
4957 case SHT_NULL: return "NULL";
4958 case SHT_PROGBITS: return "PROGBITS";
4959 case SHT_SYMTAB: return "SYMTAB";
4960 case SHT_STRTAB: return "STRTAB";
4961 case SHT_RELA: return "RELA";
dd207c13 4962 case SHT_RELR: return "RELR";
252b5132
RH
4963 case SHT_HASH: return "HASH";
4964 case SHT_DYNAMIC: return "DYNAMIC";
4965 case SHT_NOTE: return "NOTE";
4966 case SHT_NOBITS: return "NOBITS";
4967 case SHT_REL: return "REL";
4968 case SHT_SHLIB: return "SHLIB";
4969 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4970 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4971 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4972 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4973 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4974 case SHT_GROUP: return "GROUP";
67ce483b 4975 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4976 case SHT_GNU_verdef: return "VERDEF";
4977 case SHT_GNU_verneed: return "VERNEED";
4978 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4979 case 0x6ffffff0: return "VERSYM";
4980 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4981 case 0x7ffffffd: return "AUXILIARY";
4982 case 0x7fffffff: return "FILTER";
047b2264 4983 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4984
4985 default:
4986 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4987 {
dda8d76d 4988 switch (filedata->file_header.e_machine)
252b5132 4989 {
53a346d8
CZ
4990 case EM_ARC:
4991 case EM_ARC_COMPACT:
4992 case EM_ARC_COMPACT2:
4993 result = get_arc_section_type_name (sh_type);
4994 break;
252b5132 4995 case EM_MIPS:
4fe85591 4996 case EM_MIPS_RS3_LE:
252b5132
RH
4997 result = get_mips_section_type_name (sh_type);
4998 break;
103f02d3
UD
4999 case EM_PARISC:
5000 result = get_parisc_section_type_name (sh_type);
5001 break;
4d6ed7c8 5002 case EM_IA_64:
dda8d76d 5003 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5004 break;
d2b2c203 5005 case EM_X86_64:
8a9036a4 5006 case EM_L1OM:
7a9068fe 5007 case EM_K1OM:
d2b2c203
DJ
5008 result = get_x86_64_section_type_name (sh_type);
5009 break;
a06ea964
NC
5010 case EM_AARCH64:
5011 result = get_aarch64_section_type_name (sh_type);
5012 break;
40a18ebd
NC
5013 case EM_ARM:
5014 result = get_arm_section_type_name (sh_type);
5015 break;
40b36596
JM
5016 case EM_TI_C6000:
5017 result = get_tic6x_section_type_name (sh_type);
5018 break;
13761a11 5019 case EM_MSP430:
b0191216 5020 result = get_msp430_section_type_name (sh_type);
13761a11 5021 break;
fe944acf
FT
5022 case EM_NFP:
5023 result = get_nfp_section_type_name (sh_type);
5024 break;
685080f2
NC
5025 case EM_V800:
5026 case EM_V850:
5027 case EM_CYGNUS_V850:
5028 result = get_v850_section_type_name (sh_type);
5029 break;
2dc8dd17
JW
5030 case EM_RISCV:
5031 result = get_riscv_section_type_name (sh_type);
5032 break;
0861f561
CQ
5033 case EM_CSKY:
5034 result = get_csky_section_type_name (sh_type);
5035 break;
252b5132
RH
5036 default:
5037 result = NULL;
5038 break;
5039 }
5040
5041 if (result != NULL)
5042 return result;
5043
9fb71ee4 5044 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5045 }
5046 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5047 {
dda8d76d 5048 switch (filedata->file_header.e_machine)
148b93f2
NC
5049 {
5050 case EM_IA_64:
dda8d76d 5051 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5052 break;
5053 default:
dda8d76d 5054 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5055 result = get_solaris_section_type (sh_type);
5056 else
1b4b80bf
NC
5057 {
5058 switch (sh_type)
5059 {
5060 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5061 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5062 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5063 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5064 default:
5065 result = NULL;
5066 break;
5067 }
5068 }
148b93f2
NC
5069 break;
5070 }
5071
5072 if (result != NULL)
5073 return result;
5074
9fb71ee4 5075 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5076 }
252b5132 5077 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5078 {
dda8d76d 5079 switch (filedata->file_header.e_machine)
685080f2
NC
5080 {
5081 case EM_V800:
5082 case EM_V850:
5083 case EM_CYGNUS_V850:
9fb71ee4 5084 result = get_v850_section_type_name (sh_type);
a9fb83be 5085 break;
685080f2 5086 default:
9fb71ee4 5087 result = NULL;
685080f2
NC
5088 break;
5089 }
5090
9fb71ee4
NC
5091 if (result != NULL)
5092 return result;
5093
5094 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5095 }
252b5132 5096 else
a7dbfd1c
NC
5097 /* This message is probably going to be displayed in a 15
5098 character wide field, so put the hex value first. */
5099 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5100
252b5132
RH
5101 return buff;
5102 }
5103}
5104
79bc120c
NC
5105enum long_option_values
5106{
5107 OPTION_DEBUG_DUMP = 512,
5108 OPTION_DYN_SYMS,
0f03783c 5109 OPTION_LTO_SYMS,
79bc120c
NC
5110 OPTION_DWARF_DEPTH,
5111 OPTION_DWARF_START,
5112 OPTION_DWARF_CHECK,
5113 OPTION_CTF_DUMP,
5114 OPTION_CTF_PARENT,
5115 OPTION_CTF_SYMBOLS,
5116 OPTION_CTF_STRINGS,
5117 OPTION_WITH_SYMBOL_VERSIONS,
5118 OPTION_RECURSE_LIMIT,
5119 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5120 OPTION_NO_DEMANGLING,
5121 OPTION_SYM_BASE
79bc120c 5122};
2979dc34 5123
85b1c36d 5124static struct option options[] =
252b5132 5125{
79bc120c
NC
5126 /* Note - This table is alpha-sorted on the 'val'
5127 field in order to make adding new options easier. */
5128 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5129 {"all", no_argument, 0, 'a'},
79bc120c
NC
5130 {"demangle", optional_argument, 0, 'C'},
5131 {"archive-index", no_argument, 0, 'c'},
5132 {"use-dynamic", no_argument, 0, 'D'},
5133 {"dynamic", no_argument, 0, 'd'},
b34976b6 5134 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5135 {"section-groups", no_argument, 0, 'g'},
5136 {"help", no_argument, 0, 'H'},
5137 {"file-header", no_argument, 0, 'h'},
b34976b6 5138 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5139 {"lint", no_argument, 0, 'L'},
5140 {"enable-checks", no_argument, 0, 'L'},
5141 {"program-headers", no_argument, 0, 'l'},
b34976b6 5142 {"segments", no_argument, 0, 'l'},
595cf52e 5143 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5144 {"notes", no_argument, 0, 'n'},
ca0e11aa 5145 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5146 {"string-dump", required_argument, 0, 'p'},
5147 {"relocated-dump", required_argument, 0, 'R'},
5148 {"relocs", no_argument, 0, 'r'},
5149 {"section-headers", no_argument, 0, 'S'},
5150 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5151 {"symbols", no_argument, 0, 's'},
5152 {"syms", no_argument, 0, 's'},
79bc120c
NC
5153 {"silent-truncation",no_argument, 0, 'T'},
5154 {"section-details", no_argument, 0, 't'},
b3aa80b4 5155 {"unicode", required_argument, NULL, 'U'},
09c11c86 5156 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5157 {"version-info", no_argument, 0, 'V'},
5158 {"version", no_argument, 0, 'v'},
5159 {"wide", no_argument, 0, 'W'},
b34976b6 5160 {"hex-dump", required_argument, 0, 'x'},
0e602686 5161 {"decompress", no_argument, 0, 'z'},
252b5132 5162
79bc120c
NC
5163 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5164 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5165 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5166 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5167 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5168 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5169 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5170 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5171 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5172 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5173#ifdef ENABLE_LIBCTF
d344b407 5174 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5175 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5176 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5177 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5178#endif
047c3dbf 5179 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5180
b34976b6 5181 {0, no_argument, 0, 0}
252b5132
RH
5182};
5183
5184static void
2cf0635d 5185usage (FILE * stream)
252b5132 5186{
92f01d61
JM
5187 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5188 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5189 fprintf (stream, _(" Options are:\n"));
5190 fprintf (stream, _("\
5191 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5192 fprintf (stream, _("\
5193 -h --file-header Display the ELF file header\n"));
5194 fprintf (stream, _("\
5195 -l --program-headers Display the program headers\n"));
5196 fprintf (stream, _("\
5197 --segments An alias for --program-headers\n"));
5198 fprintf (stream, _("\
5199 -S --section-headers Display the sections' header\n"));
5200 fprintf (stream, _("\
5201 --sections An alias for --section-headers\n"));
5202 fprintf (stream, _("\
5203 -g --section-groups Display the section groups\n"));
5204 fprintf (stream, _("\
5205 -t --section-details Display the section details\n"));
5206 fprintf (stream, _("\
5207 -e --headers Equivalent to: -h -l -S\n"));
5208 fprintf (stream, _("\
5209 -s --syms Display the symbol table\n"));
5210 fprintf (stream, _("\
5211 --symbols An alias for --syms\n"));
5212 fprintf (stream, _("\
5213 --dyn-syms Display the dynamic symbol table\n"));
5214 fprintf (stream, _("\
5215 --lto-syms Display LTO symbol tables\n"));
5216 fprintf (stream, _("\
047c3dbf
NL
5217 --sym-base=[0|8|10|16] \n\
5218 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5219 mixed (the default), octal, decimal, hexadecimal.\n"));
5220 fprintf (stream, _("\
0d646226
AM
5221 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5222 display_demangler_styles (stream, _("\
5223 STYLE can be "));
d6249f5f
AM
5224 fprintf (stream, _("\
5225 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5226 fprintf (stream, _("\
5227 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5228 fprintf (stream, _("\
5229 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5230 fprintf (stream, _("\
5231 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5232 Display unicode characters as determined by the current locale\n\
5233 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5234 escape sequences, or treat them as invalid and display as\n\
5235 \"{hex sequences}\"\n"));
d6249f5f
AM
5236 fprintf (stream, _("\
5237 -n --notes Display the core notes (if present)\n"));
5238 fprintf (stream, _("\
5239 -r --relocs Display the relocations (if present)\n"));
5240 fprintf (stream, _("\
5241 -u --unwind Display the unwind info (if present)\n"));
5242 fprintf (stream, _("\
5243 -d --dynamic Display the dynamic section (if present)\n"));
5244 fprintf (stream, _("\
5245 -V --version-info Display the version sections (if present)\n"));
5246 fprintf (stream, _("\
5247 -A --arch-specific Display architecture specific information (if any)\n"));
5248 fprintf (stream, _("\
5249 -c --archive-index Display the symbol/file index in an archive\n"));
5250 fprintf (stream, _("\
5251 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5252 fprintf (stream, _("\
5253 -L --lint|--enable-checks\n\
5254 Display warning messages for possible problems\n"));
5255 fprintf (stream, _("\
09c11c86 5256 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5257 Dump the contents of section <number|name> as bytes\n"));
5258 fprintf (stream, _("\
09c11c86 5259 -p --string-dump=<number|name>\n\
d6249f5f
AM
5260 Dump the contents of section <number|name> as strings\n"));
5261 fprintf (stream, _("\
cf13d699 5262 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5263 Dump the relocated contents of section <number|name>\n"));
5264 fprintf (stream, _("\
5265 -z --decompress Decompress section before dumping it\n"));
5266 fprintf (stream, _("\
5267 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5268 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5269 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5270 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5271 U/=trace_info]\n\
5272 Display the contents of DWARF debug sections\n"));
5273 fprintf (stream, _("\
5274 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5275 debuginfo files\n"));
5276 fprintf (stream, _("\
5277 -P --process-links Display the contents of non-debug sections in separate\n\
5278 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5279#if DEFAULT_FOR_FOLLOW_LINKS
5280 fprintf (stream, _("\
d6249f5f
AM
5281 -wK --debug-dump=follow-links\n\
5282 Follow links to separate debug info files (default)\n"));
5283 fprintf (stream, _("\
5284 -wN --debug-dump=no-follow-links\n\
5285 Do not follow links to separate debug info files\n"));
c46b7066
NC
5286#else
5287 fprintf (stream, _("\
d6249f5f
AM
5288 -wK --debug-dump=follow-links\n\
5289 Follow links to separate debug info files\n"));
5290 fprintf (stream, _("\
5291 -wN --debug-dump=no-follow-links\n\
5292 Do not follow links to separate debug info files\n\
5293 (default)\n"));
bed566bb
NC
5294#endif
5295#if HAVE_LIBDEBUGINFOD
5296 fprintf (stream, _("\
5297 -wD --debug-dump=use-debuginfod\n\
5298 When following links, also query debuginfod servers (default)\n"));
5299 fprintf (stream, _("\
5300 -wE --debug-dump=do-not-use-debuginfod\n\
5301 When following links, do not query debuginfod servers\n"));
c46b7066 5302#endif
fd2f0033 5303 fprintf (stream, _("\
d6249f5f
AM
5304 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5305 fprintf (stream, _("\
5306 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5307#ifdef ENABLE_LIBCTF
7d9813f1 5308 fprintf (stream, _("\
d6249f5f
AM
5309 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5310 fprintf (stream, _("\
80b56fad 5311 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5312 fprintf (stream, _("\
7d9813f1 5313 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5314 Use section <number|name> as the CTF external symtab\n"));
5315 fprintf (stream, _("\
7d9813f1 5316 --ctf-strings=<number|name>\n\
d6249f5f 5317 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5318#endif
7d9813f1 5319
252b5132 5320#ifdef SUPPORT_DISASSEMBLY
92f01d61 5321 fprintf (stream, _("\
09c11c86
NC
5322 -i --instruction-dump=<number|name>\n\
5323 Disassemble the contents of section <number|name>\n"));
252b5132 5324#endif
92f01d61 5325 fprintf (stream, _("\
d6249f5f
AM
5326 -I --histogram Display histogram of bucket list lengths\n"));
5327 fprintf (stream, _("\
5328 -W --wide Allow output width to exceed 80 characters\n"));
5329 fprintf (stream, _("\
5330 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5331 fprintf (stream, _("\
5332 @<file> Read options from <file>\n"));
5333 fprintf (stream, _("\
5334 -H --help Display this information\n"));
5335 fprintf (stream, _("\
8b53311e 5336 -v --version Display the version number of readelf\n"));
1118d252 5337
92f01d61
JM
5338 if (REPORT_BUGS_TO[0] && stream == stdout)
5339 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5340
92f01d61 5341 exit (stream == stdout ? 0 : 1);
252b5132
RH
5342}
5343
18bd398b
NC
5344/* Record the fact that the user wants the contents of section number
5345 SECTION to be displayed using the method(s) encoded as flags bits
5346 in TYPE. Note, TYPE can be zero if we are creating the array for
5347 the first time. */
5348
252b5132 5349static void
6431e409
AM
5350request_dump_bynumber (struct dump_data *dumpdata,
5351 unsigned int section, dump_type type)
252b5132 5352{
6431e409 5353 if (section >= dumpdata->num_dump_sects)
252b5132 5354 {
2cf0635d 5355 dump_type * new_dump_sects;
252b5132 5356
3f5e193b 5357 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5358 sizeof (* new_dump_sects));
252b5132
RH
5359
5360 if (new_dump_sects == NULL)
591a748a 5361 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5362 else
5363 {
6431e409 5364 if (dumpdata->dump_sects)
21b65bac
NC
5365 {
5366 /* Copy current flag settings. */
6431e409
AM
5367 memcpy (new_dump_sects, dumpdata->dump_sects,
5368 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5369
6431e409 5370 free (dumpdata->dump_sects);
21b65bac 5371 }
252b5132 5372
6431e409
AM
5373 dumpdata->dump_sects = new_dump_sects;
5374 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5375 }
5376 }
5377
6431e409
AM
5378 if (dumpdata->dump_sects)
5379 dumpdata->dump_sects[section] |= type;
252b5132
RH
5380}
5381
aef1f6d0
DJ
5382/* Request a dump by section name. */
5383
5384static void
2cf0635d 5385request_dump_byname (const char * section, dump_type type)
aef1f6d0 5386{
2cf0635d 5387 struct dump_list_entry * new_request;
aef1f6d0 5388
3f5e193b
NC
5389 new_request = (struct dump_list_entry *)
5390 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5391 if (!new_request)
591a748a 5392 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5393
5394 new_request->name = strdup (section);
5395 if (!new_request->name)
591a748a 5396 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5397
5398 new_request->type = type;
5399
5400 new_request->next = dump_sects_byname;
5401 dump_sects_byname = new_request;
5402}
5403
cf13d699 5404static inline void
6431e409 5405request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5406{
5407 int section;
5408 char * cp;
5409
015dc7e1 5410 do_dump = true;
cf13d699
NC
5411 section = strtoul (optarg, & cp, 0);
5412
5413 if (! *cp && section >= 0)
6431e409 5414 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5415 else
5416 request_dump_byname (optarg, type);
5417}
5418
252b5132 5419static void
6431e409 5420parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5421{
5422 int c;
5423
5424 if (argc < 2)
92f01d61 5425 usage (stderr);
252b5132
RH
5426
5427 while ((c = getopt_long
b3aa80b4 5428 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5429 {
252b5132
RH
5430 switch (c)
5431 {
5432 case 0:
5433 /* Long options. */
5434 break;
5435 case 'H':
92f01d61 5436 usage (stdout);
252b5132
RH
5437 break;
5438
5439 case 'a':
015dc7e1
AM
5440 do_syms = true;
5441 do_reloc = true;
5442 do_unwind = true;
5443 do_dynamic = true;
5444 do_header = true;
5445 do_sections = true;
5446 do_section_groups = true;
5447 do_segments = true;
5448 do_version = true;
5449 do_histogram = true;
5450 do_arch = true;
5451 do_notes = true;
252b5132 5452 break;
79bc120c 5453
f5842774 5454 case 'g':
015dc7e1 5455 do_section_groups = true;
f5842774 5456 break;
5477e8a0 5457 case 't':
595cf52e 5458 case 'N':
015dc7e1
AM
5459 do_sections = true;
5460 do_section_details = true;
595cf52e 5461 break;
252b5132 5462 case 'e':
015dc7e1
AM
5463 do_header = true;
5464 do_sections = true;
5465 do_segments = true;
252b5132 5466 break;
a952a375 5467 case 'A':
015dc7e1 5468 do_arch = true;
a952a375 5469 break;
252b5132 5470 case 'D':
015dc7e1 5471 do_using_dynamic = true;
252b5132
RH
5472 break;
5473 case 'r':
015dc7e1 5474 do_reloc = true;
252b5132 5475 break;
4d6ed7c8 5476 case 'u':
015dc7e1 5477 do_unwind = true;
4d6ed7c8 5478 break;
252b5132 5479 case 'h':
015dc7e1 5480 do_header = true;
252b5132
RH
5481 break;
5482 case 'l':
015dc7e1 5483 do_segments = true;
252b5132
RH
5484 break;
5485 case 's':
015dc7e1 5486 do_syms = true;
252b5132
RH
5487 break;
5488 case 'S':
015dc7e1 5489 do_sections = true;
252b5132
RH
5490 break;
5491 case 'd':
015dc7e1 5492 do_dynamic = true;
252b5132 5493 break;
a952a375 5494 case 'I':
015dc7e1 5495 do_histogram = true;
a952a375 5496 break;
779fe533 5497 case 'n':
015dc7e1 5498 do_notes = true;
779fe533 5499 break;
4145f1d5 5500 case 'c':
015dc7e1 5501 do_archive_index = true;
4145f1d5 5502 break;
1b513401 5503 case 'L':
015dc7e1 5504 do_checks = true;
1b513401 5505 break;
ca0e11aa 5506 case 'P':
015dc7e1
AM
5507 process_links = true;
5508 do_follow_links = true;
e1dbfc17 5509 dump_any_debugging = true;
ca0e11aa 5510 break;
252b5132 5511 case 'x':
6431e409 5512 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5513 break;
09c11c86 5514 case 'p':
6431e409 5515 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5516 break;
5517 case 'R':
6431e409 5518 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5519 break;
0e602686 5520 case 'z':
015dc7e1 5521 decompress_dumps = true;
0e602686 5522 break;
252b5132 5523 case 'w':
0f03783c 5524 if (optarg == NULL)
613ff48b 5525 {
015dc7e1 5526 do_debugging = true;
94585d6d
NC
5527 do_dump = true;
5528 dump_any_debugging = true;
613ff48b
CC
5529 dwarf_select_sections_all ();
5530 }
252b5132
RH
5531 else
5532 {
015dc7e1 5533 do_debugging = false;
94585d6d
NC
5534 if (dwarf_select_sections_by_letters (optarg))
5535 {
5536 do_dump = true;
5537 dump_any_debugging = true;
5538 }
252b5132
RH
5539 }
5540 break;
2979dc34 5541 case OPTION_DEBUG_DUMP:
0f03783c 5542 if (optarg == NULL)
d6249f5f 5543 {
94585d6d 5544 do_dump = true;
d6249f5f 5545 do_debugging = true;
94585d6d 5546 dump_any_debugging = true;
d6249f5f
AM
5547 dwarf_select_sections_all ();
5548 }
2979dc34
JJ
5549 else
5550 {
015dc7e1 5551 do_debugging = false;
94585d6d
NC
5552 if (dwarf_select_sections_by_names (optarg))
5553 {
5554 do_dump = true;
5555 dump_any_debugging = true;
5556 }
2979dc34
JJ
5557 }
5558 break;
fd2f0033
TT
5559 case OPTION_DWARF_DEPTH:
5560 {
5561 char *cp;
5562
5563 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5564 }
5565 break;
5566 case OPTION_DWARF_START:
5567 {
5568 char *cp;
5569
5570 dwarf_start_die = strtoul (optarg, & cp, 0);
5571 }
5572 break;
4723351a 5573 case OPTION_DWARF_CHECK:
015dc7e1 5574 dwarf_check = true;
4723351a 5575 break;
7d9813f1 5576 case OPTION_CTF_DUMP:
015dc7e1 5577 do_ctf = true;
6431e409 5578 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5579 break;
5580 case OPTION_CTF_SYMBOLS:
df16e041 5581 free (dump_ctf_symtab_name);
7d9813f1
NA
5582 dump_ctf_symtab_name = strdup (optarg);
5583 break;
5584 case OPTION_CTF_STRINGS:
df16e041 5585 free (dump_ctf_strtab_name);
7d9813f1
NA
5586 dump_ctf_strtab_name = strdup (optarg);
5587 break;
5588 case OPTION_CTF_PARENT:
df16e041 5589 free (dump_ctf_parent_name);
7d9813f1
NA
5590 dump_ctf_parent_name = strdup (optarg);
5591 break;
2c610e4b 5592 case OPTION_DYN_SYMS:
015dc7e1 5593 do_dyn_syms = true;
2c610e4b 5594 break;
0f03783c 5595 case OPTION_LTO_SYMS:
015dc7e1 5596 do_lto_syms = true;
0f03783c 5597 break;
252b5132
RH
5598#ifdef SUPPORT_DISASSEMBLY
5599 case 'i':
6431e409 5600 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5601 break;
252b5132
RH
5602#endif
5603 case 'v':
5604 print_version (program_name);
5605 break;
5606 case 'V':
015dc7e1 5607 do_version = true;
252b5132 5608 break;
d974e256 5609 case 'W':
015dc7e1 5610 do_wide = true;
d974e256 5611 break;
0942c7ab 5612 case 'T':
015dc7e1 5613 do_not_show_symbol_truncation = true;
0942c7ab 5614 break;
79bc120c 5615 case 'C':
015dc7e1 5616 do_demangle = true;
79bc120c
NC
5617 if (optarg != NULL)
5618 {
5619 enum demangling_styles style;
5620
5621 style = cplus_demangle_name_to_style (optarg);
5622 if (style == unknown_demangling)
5623 error (_("unknown demangling style `%s'"), optarg);
5624
5625 cplus_demangle_set_style (style);
5626 }
5627 break;
5628 case OPTION_NO_DEMANGLING:
015dc7e1 5629 do_demangle = false;
79bc120c
NC
5630 break;
5631 case OPTION_RECURSE_LIMIT:
5632 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5633 break;
5634 case OPTION_NO_RECURSE_LIMIT:
5635 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5636 break;
5637 case OPTION_WITH_SYMBOL_VERSIONS:
5638 /* Ignored for backward compatibility. */
5639 break;
b9e920ec 5640
b3aa80b4
NC
5641 case 'U':
5642 if (optarg == NULL)
5643 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5644 else if (streq (optarg, "default") || streq (optarg, "d"))
5645 unicode_display = unicode_default;
5646 else if (streq (optarg, "locale") || streq (optarg, "l"))
5647 unicode_display = unicode_locale;
5648 else if (streq (optarg, "escape") || streq (optarg, "e"))
5649 unicode_display = unicode_escape;
5650 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5651 unicode_display = unicode_invalid;
5652 else if (streq (optarg, "hex") || streq (optarg, "x"))
5653 unicode_display = unicode_hex;
5654 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5655 unicode_display = unicode_highlight;
5656 else
5657 error (_("invalid argument to -U/--unicode: %s"), optarg);
5658 break;
5659
047c3dbf
NL
5660 case OPTION_SYM_BASE:
5661 sym_base = 0;
5662 if (optarg != NULL)
5663 {
5664 sym_base = strtoul (optarg, NULL, 0);
5665 switch (sym_base)
5666 {
5667 case 0:
5668 case 8:
5669 case 10:
5670 case 16:
5671 break;
5672
5673 default:
5674 sym_base = 0;
5675 break;
5676 }
5677 }
5678 break;
5679
252b5132 5680 default:
252b5132
RH
5681 /* xgettext:c-format */
5682 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5683 /* Fall through. */
252b5132 5684 case '?':
92f01d61 5685 usage (stderr);
252b5132
RH
5686 }
5687 }
5688
4d6ed7c8 5689 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5690 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5691 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5692 && !do_section_groups && !do_archive_index
0f03783c 5693 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5694 {
5695 if (do_checks)
5696 {
015dc7e1
AM
5697 check_all = true;
5698 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5699 do_segments = do_header = do_dump = do_version = true;
5700 do_histogram = do_debugging = do_arch = do_notes = true;
5701 do_section_groups = do_archive_index = do_dyn_syms = true;
5702 do_lto_syms = true;
1b513401
NC
5703 }
5704 else
5705 usage (stderr);
5706 }
252b5132
RH
5707}
5708
5709static const char *
d3ba0551 5710get_elf_class (unsigned int elf_class)
252b5132 5711{
b34976b6 5712 static char buff[32];
103f02d3 5713
252b5132
RH
5714 switch (elf_class)
5715 {
5716 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5717 case ELFCLASS32: return "ELF32";
5718 case ELFCLASS64: return "ELF64";
ab5e7794 5719 default:
e9e44622 5720 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5721 return buff;
252b5132
RH
5722 }
5723}
5724
5725static const char *
d3ba0551 5726get_data_encoding (unsigned int encoding)
252b5132 5727{
b34976b6 5728 static char buff[32];
103f02d3 5729
252b5132
RH
5730 switch (encoding)
5731 {
5732 case ELFDATANONE: return _("none");
33c63f9d
CM
5733 case ELFDATA2LSB: return _("2's complement, little endian");
5734 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5735 default:
e9e44622 5736 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5737 return buff;
252b5132
RH
5738 }
5739}
5740
dda8d76d 5741/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5742
015dc7e1 5743static bool
dda8d76d 5744process_file_header (Filedata * filedata)
252b5132 5745{
dda8d76d
NC
5746 Elf_Internal_Ehdr * header = & filedata->file_header;
5747
5748 if ( header->e_ident[EI_MAG0] != ELFMAG0
5749 || header->e_ident[EI_MAG1] != ELFMAG1
5750 || header->e_ident[EI_MAG2] != ELFMAG2
5751 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5752 {
5753 error
5754 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5755 return false;
252b5132
RH
5756 }
5757
ca0e11aa
NC
5758 if (! filedata->is_separate)
5759 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5760
252b5132
RH
5761 if (do_header)
5762 {
32ec8896 5763 unsigned i;
252b5132 5764
ca0e11aa
NC
5765 if (filedata->is_separate)
5766 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5767 else
5768 printf (_("ELF Header:\n"));
252b5132 5769 printf (_(" Magic: "));
b34976b6 5770 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5771 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5772 printf ("\n");
5773 printf (_(" Class: %s\n"),
dda8d76d 5774 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5775 printf (_(" Data: %s\n"),
dda8d76d 5776 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5777 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5778 header->e_ident[EI_VERSION],
5779 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5780 ? _(" (current)")
dda8d76d 5781 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5782 ? _(" <unknown>")
789be9f7 5783 : "")));
252b5132 5784 printf (_(" OS/ABI: %s\n"),
dda8d76d 5785 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5786 printf (_(" ABI Version: %d\n"),
dda8d76d 5787 header->e_ident[EI_ABIVERSION]);
252b5132 5788 printf (_(" Type: %s\n"),
93df3340 5789 get_file_type (filedata));
252b5132 5790 printf (_(" Machine: %s\n"),
dda8d76d 5791 get_machine_name (header->e_machine));
252b5132 5792 printf (_(" Version: 0x%lx\n"),
e8a64888 5793 header->e_version);
76da6bbe 5794
f7a99963 5795 printf (_(" Entry point address: "));
e8a64888 5796 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5797 printf (_("\n Start of program headers: "));
e8a64888 5798 print_vma (header->e_phoff, DEC);
f7a99963 5799 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5800 print_vma (header->e_shoff, DEC);
f7a99963 5801 printf (_(" (bytes into file)\n"));
76da6bbe 5802
252b5132 5803 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5804 header->e_flags,
dda8d76d 5805 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5806 printf (_(" Size of this header: %u (bytes)\n"),
5807 header->e_ehsize);
5808 printf (_(" Size of program headers: %u (bytes)\n"),
5809 header->e_phentsize);
5810 printf (_(" Number of program headers: %u"),
5811 header->e_phnum);
dda8d76d
NC
5812 if (filedata->section_headers != NULL
5813 && header->e_phnum == PN_XNUM
5814 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5815 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5816 putc ('\n', stdout);
e8a64888
AM
5817 printf (_(" Size of section headers: %u (bytes)\n"),
5818 header->e_shentsize);
5819 printf (_(" Number of section headers: %u"),
5820 header->e_shnum);
dda8d76d 5821 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5822 {
5823 header->e_shnum = filedata->section_headers[0].sh_size;
5824 printf (" (%u)", header->e_shnum);
5825 }
560f3c1c 5826 putc ('\n', stdout);
e8a64888
AM
5827 printf (_(" Section header string table index: %u"),
5828 header->e_shstrndx);
dda8d76d
NC
5829 if (filedata->section_headers != NULL
5830 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5831 {
5832 header->e_shstrndx = filedata->section_headers[0].sh_link;
5833 printf (" (%u)", header->e_shstrndx);
5834 }
5835 if (header->e_shstrndx != SHN_UNDEF
5836 && header->e_shstrndx >= header->e_shnum)
5837 {
5838 header->e_shstrndx = SHN_UNDEF;
5839 printf (_(" <corrupt: out of range>"));
5840 }
560f3c1c
AM
5841 putc ('\n', stdout);
5842 }
5843
dda8d76d 5844 if (filedata->section_headers != NULL)
560f3c1c 5845 {
dda8d76d
NC
5846 if (header->e_phnum == PN_XNUM
5847 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5848 {
5849 /* Throw away any cached read of PN_XNUM headers. */
5850 free (filedata->program_headers);
5851 filedata->program_headers = NULL;
5852 header->e_phnum = filedata->section_headers[0].sh_info;
5853 }
dda8d76d
NC
5854 if (header->e_shnum == SHN_UNDEF)
5855 header->e_shnum = filedata->section_headers[0].sh_size;
5856 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5857 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5858 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5859 header->e_shstrndx = SHN_UNDEF;
252b5132 5860 }
103f02d3 5861
015dc7e1 5862 return true;
9ea033b2
NC
5863}
5864
dda8d76d
NC
5865/* Read in the program headers from FILEDATA and store them in PHEADERS.
5866 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5867
015dc7e1 5868static bool
dda8d76d 5869get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5870{
2cf0635d
NC
5871 Elf32_External_Phdr * phdrs;
5872 Elf32_External_Phdr * external;
5873 Elf_Internal_Phdr * internal;
b34976b6 5874 unsigned int i;
dda8d76d
NC
5875 unsigned int size = filedata->file_header.e_phentsize;
5876 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5877
5878 /* PR binutils/17531: Cope with unexpected section header sizes. */
5879 if (size == 0 || num == 0)
015dc7e1 5880 return false;
e0a31db1
NC
5881 if (size < sizeof * phdrs)
5882 {
5883 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5884 return false;
e0a31db1
NC
5885 }
5886 if (size > sizeof * phdrs)
5887 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5888
dda8d76d 5889 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5890 size, num, _("program headers"));
5891 if (phdrs == NULL)
015dc7e1 5892 return false;
9ea033b2 5893
91d6fa6a 5894 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5895 i < filedata->file_header.e_phnum;
b34976b6 5896 i++, internal++, external++)
252b5132 5897 {
9ea033b2
NC
5898 internal->p_type = BYTE_GET (external->p_type);
5899 internal->p_offset = BYTE_GET (external->p_offset);
5900 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5901 internal->p_paddr = BYTE_GET (external->p_paddr);
5902 internal->p_filesz = BYTE_GET (external->p_filesz);
5903 internal->p_memsz = BYTE_GET (external->p_memsz);
5904 internal->p_flags = BYTE_GET (external->p_flags);
5905 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5906 }
5907
9ea033b2 5908 free (phdrs);
015dc7e1 5909 return true;
252b5132
RH
5910}
5911
dda8d76d
NC
5912/* Read in the program headers from FILEDATA and store them in PHEADERS.
5913 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5914
015dc7e1 5915static bool
dda8d76d 5916get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5917{
2cf0635d
NC
5918 Elf64_External_Phdr * phdrs;
5919 Elf64_External_Phdr * external;
5920 Elf_Internal_Phdr * internal;
b34976b6 5921 unsigned int i;
dda8d76d
NC
5922 unsigned int size = filedata->file_header.e_phentsize;
5923 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5924
5925 /* PR binutils/17531: Cope with unexpected section header sizes. */
5926 if (size == 0 || num == 0)
015dc7e1 5927 return false;
e0a31db1
NC
5928 if (size < sizeof * phdrs)
5929 {
5930 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5931 return false;
e0a31db1
NC
5932 }
5933 if (size > sizeof * phdrs)
5934 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5935
dda8d76d 5936 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5937 size, num, _("program headers"));
a6e9f9df 5938 if (!phdrs)
015dc7e1 5939 return false;
9ea033b2 5940
91d6fa6a 5941 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5942 i < filedata->file_header.e_phnum;
b34976b6 5943 i++, internal++, external++)
9ea033b2
NC
5944 {
5945 internal->p_type = BYTE_GET (external->p_type);
5946 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5947 internal->p_offset = BYTE_GET (external->p_offset);
5948 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5949 internal->p_paddr = BYTE_GET (external->p_paddr);
5950 internal->p_filesz = BYTE_GET (external->p_filesz);
5951 internal->p_memsz = BYTE_GET (external->p_memsz);
5952 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5953 }
5954
5955 free (phdrs);
015dc7e1 5956 return true;
9ea033b2 5957}
252b5132 5958
32ec8896 5959/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5960
015dc7e1 5961static bool
dda8d76d 5962get_program_headers (Filedata * filedata)
d93f0186 5963{
2cf0635d 5964 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5965
5966 /* Check cache of prior read. */
dda8d76d 5967 if (filedata->program_headers != NULL)
015dc7e1 5968 return true;
d93f0186 5969
82156ab7
NC
5970 /* Be kind to memory checkers by looking for
5971 e_phnum values which we know must be invalid. */
dda8d76d 5972 if (filedata->file_header.e_phnum
82156ab7 5973 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5974 >= filedata->file_size)
82156ab7
NC
5975 {
5976 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5977 filedata->file_header.e_phnum);
015dc7e1 5978 return false;
82156ab7 5979 }
d93f0186 5980
dda8d76d 5981 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5982 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5983 if (phdrs == NULL)
5984 {
8b73c356 5985 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5986 filedata->file_header.e_phnum);
015dc7e1 5987 return false;
d93f0186
NC
5988 }
5989
5990 if (is_32bit_elf
dda8d76d
NC
5991 ? get_32bit_program_headers (filedata, phdrs)
5992 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5993 {
dda8d76d 5994 filedata->program_headers = phdrs;
015dc7e1 5995 return true;
d93f0186
NC
5996 }
5997
5998 free (phdrs);
015dc7e1 5999 return false;
d93f0186
NC
6000}
6001
93df3340 6002/* Print program header info and locate dynamic section. */
2f62977e 6003
93df3340 6004static void
dda8d76d 6005process_program_headers (Filedata * filedata)
252b5132 6006{
2cf0635d 6007 Elf_Internal_Phdr * segment;
b34976b6 6008 unsigned int i;
1a9ccd70 6009 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6010
dda8d76d 6011 if (filedata->file_header.e_phnum == 0)
252b5132 6012 {
82f2dbf7 6013 /* PR binutils/12467. */
dda8d76d 6014 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6015 warn (_("possibly corrupt ELF header - it has a non-zero program"
6016 " header offset, but no program headers\n"));
82f2dbf7 6017 else if (do_segments)
ca0e11aa
NC
6018 {
6019 if (filedata->is_separate)
6020 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6021 filedata->file_name);
6022 else
6023 printf (_("\nThere are no program headers in this file.\n"));
6024 }
93df3340 6025 goto no_headers;
252b5132
RH
6026 }
6027
6028 if (do_segments && !do_header)
6029 {
ca0e11aa
NC
6030 if (filedata->is_separate)
6031 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6032 filedata->file_name, get_file_type (filedata));
ca0e11aa 6033 else
93df3340 6034 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 6035 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
6036 printf (ngettext ("There is %d program header, starting at offset %s\n",
6037 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
6038 filedata->file_header.e_phnum),
6039 filedata->file_header.e_phnum,
6040 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
6041 }
6042
dda8d76d 6043 if (! get_program_headers (filedata))
93df3340 6044 goto no_headers;
103f02d3 6045
252b5132
RH
6046 if (do_segments)
6047 {
dda8d76d 6048 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6049 printf (_("\nProgram Headers:\n"));
6050 else
6051 printf (_("\nProgram Headers:\n"));
76da6bbe 6052
f7a99963
NC
6053 if (is_32bit_elf)
6054 printf
6055 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6056 else if (do_wide)
6057 printf
6058 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6059 else
6060 {
6061 printf
6062 (_(" Type Offset VirtAddr PhysAddr\n"));
6063 printf
6064 (_(" FileSiz MemSiz Flags Align\n"));
6065 }
252b5132
RH
6066 }
6067
93df3340
AM
6068 unsigned long dynamic_addr = 0;
6069 bfd_size_type dynamic_size = 0;
dda8d76d
NC
6070 for (i = 0, segment = filedata->program_headers;
6071 i < filedata->file_header.e_phnum;
b34976b6 6072 i++, segment++)
252b5132
RH
6073 {
6074 if (do_segments)
6075 {
dda8d76d 6076 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6077
6078 if (is_32bit_elf)
6079 {
6080 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6081 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6082 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6083 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6084 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6085 printf ("%c%c%c ",
6086 (segment->p_flags & PF_R ? 'R' : ' '),
6087 (segment->p_flags & PF_W ? 'W' : ' '),
6088 (segment->p_flags & PF_X ? 'E' : ' '));
6089 printf ("%#lx", (unsigned long) segment->p_align);
6090 }
d974e256
JJ
6091 else if (do_wide)
6092 {
6093 if ((unsigned long) segment->p_offset == segment->p_offset)
6094 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6095 else
6096 {
6097 print_vma (segment->p_offset, FULL_HEX);
6098 putchar (' ');
6099 }
6100
6101 print_vma (segment->p_vaddr, FULL_HEX);
6102 putchar (' ');
6103 print_vma (segment->p_paddr, FULL_HEX);
6104 putchar (' ');
6105
6106 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6107 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6108 else
6109 {
6110 print_vma (segment->p_filesz, FULL_HEX);
6111 putchar (' ');
6112 }
6113
6114 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6115 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6116 else
6117 {
f48e6c45 6118 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6119 }
6120
6121 printf (" %c%c%c ",
6122 (segment->p_flags & PF_R ? 'R' : ' '),
6123 (segment->p_flags & PF_W ? 'W' : ' '),
6124 (segment->p_flags & PF_X ? 'E' : ' '));
6125
6126 if ((unsigned long) segment->p_align == segment->p_align)
6127 printf ("%#lx", (unsigned long) segment->p_align);
6128 else
6129 {
6130 print_vma (segment->p_align, PREFIX_HEX);
6131 }
6132 }
f7a99963
NC
6133 else
6134 {
6135 print_vma (segment->p_offset, FULL_HEX);
6136 putchar (' ');
6137 print_vma (segment->p_vaddr, FULL_HEX);
6138 putchar (' ');
6139 print_vma (segment->p_paddr, FULL_HEX);
6140 printf ("\n ");
6141 print_vma (segment->p_filesz, FULL_HEX);
6142 putchar (' ');
6143 print_vma (segment->p_memsz, FULL_HEX);
6144 printf (" %c%c%c ",
6145 (segment->p_flags & PF_R ? 'R' : ' '),
6146 (segment->p_flags & PF_W ? 'W' : ' '),
6147 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6148 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6149 }
252b5132 6150
1a9ccd70
NC
6151 putc ('\n', stdout);
6152 }
f54498b4 6153
252b5132
RH
6154 switch (segment->p_type)
6155 {
1a9ccd70 6156 case PT_LOAD:
502d895c
NC
6157#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6158 required by the ELF standard, several programs, including the Linux
6159 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6160 if (previous_load
6161 && previous_load->p_vaddr > segment->p_vaddr)
6162 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6163#endif
1a9ccd70
NC
6164 if (segment->p_memsz < segment->p_filesz)
6165 error (_("the segment's file size is larger than its memory size\n"));
6166 previous_load = segment;
6167 break;
6168
6169 case PT_PHDR:
6170 /* PR 20815 - Verify that the program header is loaded into memory. */
6171 if (i > 0 && previous_load != NULL)
6172 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6173 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6174 {
6175 unsigned int j;
6176
dda8d76d 6177 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6178 {
6179 Elf_Internal_Phdr *load = filedata->program_headers + j;
6180 if (load->p_type == PT_LOAD
6181 && load->p_offset <= segment->p_offset
6182 && (load->p_offset + load->p_filesz
6183 >= segment->p_offset + segment->p_filesz)
6184 && load->p_vaddr <= segment->p_vaddr
6185 && (load->p_vaddr + load->p_filesz
6186 >= segment->p_vaddr + segment->p_filesz))
6187 break;
6188 }
dda8d76d 6189 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6190 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6191 }
6192 break;
6193
252b5132 6194 case PT_DYNAMIC:
93df3340 6195 if (dynamic_addr)
252b5132
RH
6196 error (_("more than one dynamic segment\n"));
6197
20737c13
AM
6198 /* By default, assume that the .dynamic section is the first
6199 section in the DYNAMIC segment. */
93df3340
AM
6200 dynamic_addr = segment->p_offset;
6201 dynamic_size = segment->p_filesz;
20737c13 6202
b2d38a17
NC
6203 /* Try to locate the .dynamic section. If there is
6204 a section header table, we can easily locate it. */
dda8d76d 6205 if (filedata->section_headers != NULL)
b2d38a17 6206 {
2cf0635d 6207 Elf_Internal_Shdr * sec;
b2d38a17 6208
dda8d76d 6209 sec = find_section (filedata, ".dynamic");
89fac5e3 6210 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6211 {
93df3340
AM
6212 /* A corresponding .dynamic section is expected, but on
6213 IA-64/OpenVMS it is OK for it to be missing. */
6214 if (!is_ia64_vms (filedata))
6215 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6216 break;
6217 }
6218
42bb2e33 6219 if (sec->sh_type == SHT_NOBITS)
20737c13 6220 {
93df3340
AM
6221 dynamic_addr = 0;
6222 dynamic_size = 0;
20737c13
AM
6223 break;
6224 }
42bb2e33 6225
93df3340
AM
6226 dynamic_addr = sec->sh_offset;
6227 dynamic_size = sec->sh_size;
b2d38a17 6228
8ac10c5b
L
6229 /* The PT_DYNAMIC segment, which is used by the run-time
6230 loader, should exactly match the .dynamic section. */
6231 if (do_checks
93df3340
AM
6232 && (dynamic_addr != segment->p_offset
6233 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6234 warn (_("\
6235the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6236 }
39e224f6
MW
6237
6238 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6239 segment. Check this after matching against the section headers
6240 so we don't warn on debuginfo file (which have NOBITS .dynamic
6241 sections). */
93df3340
AM
6242 if (dynamic_addr > filedata->file_size
6243 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6244 {
6245 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6246 dynamic_addr = 0;
6247 dynamic_size = 0;
39e224f6 6248 }
252b5132
RH
6249 break;
6250
6251 case PT_INTERP:
13acb58d
AM
6252 if (segment->p_offset >= filedata->file_size
6253 || segment->p_filesz > filedata->file_size - segment->p_offset
6254 || segment->p_filesz - 1 >= (size_t) -2
6255 || fseek (filedata->handle,
6256 filedata->archive_file_offset + (long) segment->p_offset,
6257 SEEK_SET))
252b5132
RH
6258 error (_("Unable to find program interpreter name\n"));
6259 else
6260 {
13acb58d
AM
6261 size_t len = segment->p_filesz;
6262 free (filedata->program_interpreter);
6263 filedata->program_interpreter = xmalloc (len + 1);
6264 len = fread (filedata->program_interpreter, 1, len,
6265 filedata->handle);
6266 filedata->program_interpreter[len] = 0;
252b5132
RH
6267
6268 if (do_segments)
f54498b4 6269 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6270 filedata->program_interpreter);
252b5132
RH
6271 }
6272 break;
6273 }
252b5132
RH
6274 }
6275
dda8d76d
NC
6276 if (do_segments
6277 && filedata->section_headers != NULL
6278 && filedata->string_table != NULL)
252b5132
RH
6279 {
6280 printf (_("\n Section to Segment mapping:\n"));
6281 printf (_(" Segment Sections...\n"));
6282
dda8d76d 6283 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6284 {
9ad5cbcf 6285 unsigned int j;
2cf0635d 6286 Elf_Internal_Shdr * section;
252b5132 6287
dda8d76d
NC
6288 segment = filedata->program_headers + i;
6289 section = filedata->section_headers + 1;
252b5132
RH
6290
6291 printf (" %2.2d ", i);
6292
dda8d76d 6293 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6294 {
f4638467
AM
6295 if (!ELF_TBSS_SPECIAL (section, segment)
6296 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6297 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6298 }
6299
6300 putc ('\n',stdout);
6301 }
6302 }
6303
93df3340
AM
6304 filedata->dynamic_addr = dynamic_addr;
6305 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6306 return;
6307
6308 no_headers:
6309 filedata->dynamic_addr = 0;
6310 filedata->dynamic_size = 1;
252b5132
RH
6311}
6312
6313
d93f0186
NC
6314/* Find the file offset corresponding to VMA by using the program headers. */
6315
6316static long
dda8d76d 6317offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6318{
2cf0635d 6319 Elf_Internal_Phdr * seg;
d93f0186 6320
dda8d76d 6321 if (! get_program_headers (filedata))
d93f0186
NC
6322 {
6323 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6324 return (long) vma;
6325 }
6326
dda8d76d
NC
6327 for (seg = filedata->program_headers;
6328 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6329 ++seg)
6330 {
6331 if (seg->p_type != PT_LOAD)
6332 continue;
6333
6334 if (vma >= (seg->p_vaddr & -seg->p_align)
6335 && vma + size <= seg->p_vaddr + seg->p_filesz)
6336 return vma - seg->p_vaddr + seg->p_offset;
6337 }
6338
6339 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6340 (unsigned long) vma);
d93f0186
NC
6341 return (long) vma;
6342}
6343
6344
dda8d76d
NC
6345/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6346 If PROBE is true, this is just a probe and we do not generate any error
6347 messages if the load fails. */
049b0c3a 6348
015dc7e1
AM
6349static bool
6350get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6351{
2cf0635d
NC
6352 Elf32_External_Shdr * shdrs;
6353 Elf_Internal_Shdr * internal;
dda8d76d
NC
6354 unsigned int i;
6355 unsigned int size = filedata->file_header.e_shentsize;
6356 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6357
6358 /* PR binutils/17531: Cope with unexpected section header sizes. */
6359 if (size == 0 || num == 0)
015dc7e1 6360 return false;
049b0c3a
NC
6361 if (size < sizeof * shdrs)
6362 {
6363 if (! probe)
6364 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6365 return false;
049b0c3a
NC
6366 }
6367 if (!probe && size > sizeof * shdrs)
6368 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6369
dda8d76d 6370 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6371 size, num,
6372 probe ? NULL : _("section headers"));
6373 if (shdrs == NULL)
015dc7e1 6374 return false;
252b5132 6375
dda8d76d
NC
6376 filedata->section_headers = (Elf_Internal_Shdr *)
6377 cmalloc (num, sizeof (Elf_Internal_Shdr));
6378 if (filedata->section_headers == NULL)
252b5132 6379 {
049b0c3a 6380 if (!probe)
8b73c356 6381 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6382 free (shdrs);
015dc7e1 6383 return false;
252b5132
RH
6384 }
6385
dda8d76d 6386 for (i = 0, internal = filedata->section_headers;
560f3c1c 6387 i < num;
b34976b6 6388 i++, internal++)
252b5132
RH
6389 {
6390 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6391 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6392 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6393 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6394 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6395 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6396 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6397 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6398 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6399 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6400 if (!probe && internal->sh_link > num)
6401 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6402 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6403 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6404 }
6405
6406 free (shdrs);
015dc7e1 6407 return true;
252b5132
RH
6408}
6409
dda8d76d
NC
6410/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6411
015dc7e1
AM
6412static bool
6413get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6414{
dda8d76d
NC
6415 Elf64_External_Shdr * shdrs;
6416 Elf_Internal_Shdr * internal;
6417 unsigned int i;
6418 unsigned int size = filedata->file_header.e_shentsize;
6419 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6420
6421 /* PR binutils/17531: Cope with unexpected section header sizes. */
6422 if (size == 0 || num == 0)
015dc7e1 6423 return false;
dda8d76d 6424
049b0c3a
NC
6425 if (size < sizeof * shdrs)
6426 {
6427 if (! probe)
6428 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6429 return false;
049b0c3a 6430 }
dda8d76d 6431
049b0c3a
NC
6432 if (! probe && size > sizeof * shdrs)
6433 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6434
dda8d76d
NC
6435 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6436 filedata->file_header.e_shoff,
049b0c3a
NC
6437 size, num,
6438 probe ? NULL : _("section headers"));
6439 if (shdrs == NULL)
015dc7e1 6440 return false;
9ea033b2 6441
dda8d76d
NC
6442 filedata->section_headers = (Elf_Internal_Shdr *)
6443 cmalloc (num, sizeof (Elf_Internal_Shdr));
6444 if (filedata->section_headers == NULL)
9ea033b2 6445 {
049b0c3a 6446 if (! probe)
8b73c356 6447 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6448 free (shdrs);
015dc7e1 6449 return false;
9ea033b2
NC
6450 }
6451
dda8d76d 6452 for (i = 0, internal = filedata->section_headers;
560f3c1c 6453 i < num;
b34976b6 6454 i++, internal++)
9ea033b2
NC
6455 {
6456 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6457 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6458 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6459 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6460 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6461 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6462 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6463 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6464 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6465 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6466 if (!probe && internal->sh_link > num)
6467 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6468 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6469 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6470 }
6471
6472 free (shdrs);
015dc7e1 6473 return true;
9ea033b2
NC
6474}
6475
4de91c10
AM
6476static bool
6477get_section_headers (Filedata *filedata, bool probe)
6478{
6479 if (filedata->section_headers != NULL)
6480 return true;
6481
4de91c10
AM
6482 if (is_32bit_elf)
6483 return get_32bit_section_headers (filedata, probe);
6484 else
6485 return get_64bit_section_headers (filedata, probe);
6486}
6487
252b5132 6488static Elf_Internal_Sym *
dda8d76d
NC
6489get_32bit_elf_symbols (Filedata * filedata,
6490 Elf_Internal_Shdr * section,
6491 unsigned long * num_syms_return)
252b5132 6492{
ba5cdace 6493 unsigned long number = 0;
dd24e3da 6494 Elf32_External_Sym * esyms = NULL;
ba5cdace 6495 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6496 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6497 Elf_Internal_Sym * psym;
b34976b6 6498 unsigned int j;
e3d39609 6499 elf_section_list * entry;
252b5132 6500
c9c1d674
EG
6501 if (section->sh_size == 0)
6502 {
6503 if (num_syms_return != NULL)
6504 * num_syms_return = 0;
6505 return NULL;
6506 }
6507
dd24e3da 6508 /* Run some sanity checks first. */
c9c1d674 6509 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6510 {
c9c1d674 6511 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6512 printable_section_name (filedata, section),
6513 (unsigned long) section->sh_entsize);
ba5cdace 6514 goto exit_point;
dd24e3da
NC
6515 }
6516
dda8d76d 6517 if (section->sh_size > filedata->file_size)
f54498b4
NC
6518 {
6519 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6520 printable_section_name (filedata, section),
6521 (unsigned long) section->sh_size);
f54498b4
NC
6522 goto exit_point;
6523 }
6524
dd24e3da
NC
6525 number = section->sh_size / section->sh_entsize;
6526
6527 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6528 {
c9c1d674 6529 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6530 (unsigned long) section->sh_size,
dda8d76d 6531 printable_section_name (filedata, section),
8066deb1 6532 (unsigned long) section->sh_entsize);
ba5cdace 6533 goto exit_point;
dd24e3da
NC
6534 }
6535
dda8d76d 6536 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6537 section->sh_size, _("symbols"));
dd24e3da 6538 if (esyms == NULL)
ba5cdace 6539 goto exit_point;
252b5132 6540
e3d39609 6541 shndx = NULL;
978c4450 6542 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6543 {
6544 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6545 continue;
6546
6547 if (shndx != NULL)
6548 {
6549 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6550 free (shndx);
6551 }
6552
6553 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6554 entry->hdr->sh_offset,
6555 1, entry->hdr->sh_size,
6556 _("symbol table section indices"));
6557 if (shndx == NULL)
6558 goto exit_point;
6559
6560 /* PR17531: file: heap-buffer-overflow */
6561 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6562 {
6563 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6564 printable_section_name (filedata, entry->hdr),
6565 (unsigned long) entry->hdr->sh_size,
6566 (unsigned long) section->sh_size);
6567 goto exit_point;
c9c1d674 6568 }
e3d39609 6569 }
9ad5cbcf 6570
3f5e193b 6571 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6572
6573 if (isyms == NULL)
6574 {
8b73c356
NC
6575 error (_("Out of memory reading %lu symbols\n"),
6576 (unsigned long) number);
dd24e3da 6577 goto exit_point;
252b5132
RH
6578 }
6579
dd24e3da 6580 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6581 {
6582 psym->st_name = BYTE_GET (esyms[j].st_name);
6583 psym->st_value = BYTE_GET (esyms[j].st_value);
6584 psym->st_size = BYTE_GET (esyms[j].st_size);
6585 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6586 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6587 psym->st_shndx
6588 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6589 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6590 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6591 psym->st_info = BYTE_GET (esyms[j].st_info);
6592 psym->st_other = BYTE_GET (esyms[j].st_other);
6593 }
6594
dd24e3da 6595 exit_point:
e3d39609
NC
6596 free (shndx);
6597 free (esyms);
252b5132 6598
ba5cdace
NC
6599 if (num_syms_return != NULL)
6600 * num_syms_return = isyms == NULL ? 0 : number;
6601
252b5132
RH
6602 return isyms;
6603}
6604
9ea033b2 6605static Elf_Internal_Sym *
dda8d76d
NC
6606get_64bit_elf_symbols (Filedata * filedata,
6607 Elf_Internal_Shdr * section,
6608 unsigned long * num_syms_return)
9ea033b2 6609{
ba5cdace
NC
6610 unsigned long number = 0;
6611 Elf64_External_Sym * esyms = NULL;
6612 Elf_External_Sym_Shndx * shndx = NULL;
6613 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6614 Elf_Internal_Sym * psym;
b34976b6 6615 unsigned int j;
e3d39609 6616 elf_section_list * entry;
9ea033b2 6617
c9c1d674
EG
6618 if (section->sh_size == 0)
6619 {
6620 if (num_syms_return != NULL)
6621 * num_syms_return = 0;
6622 return NULL;
6623 }
6624
dd24e3da 6625 /* Run some sanity checks first. */
c9c1d674 6626 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6627 {
c9c1d674 6628 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6629 printable_section_name (filedata, section),
8066deb1 6630 (unsigned long) section->sh_entsize);
ba5cdace 6631 goto exit_point;
dd24e3da
NC
6632 }
6633
dda8d76d 6634 if (section->sh_size > filedata->file_size)
f54498b4
NC
6635 {
6636 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6637 printable_section_name (filedata, section),
8066deb1 6638 (unsigned long) section->sh_size);
f54498b4
NC
6639 goto exit_point;
6640 }
6641
dd24e3da
NC
6642 number = section->sh_size / section->sh_entsize;
6643
6644 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6645 {
c9c1d674 6646 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6647 (unsigned long) section->sh_size,
dda8d76d 6648 printable_section_name (filedata, section),
8066deb1 6649 (unsigned long) section->sh_entsize);
ba5cdace 6650 goto exit_point;
dd24e3da
NC
6651 }
6652
dda8d76d 6653 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6654 section->sh_size, _("symbols"));
a6e9f9df 6655 if (!esyms)
ba5cdace 6656 goto exit_point;
9ea033b2 6657
e3d39609 6658 shndx = NULL;
978c4450 6659 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6660 {
6661 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6662 continue;
6663
6664 if (shndx != NULL)
6665 {
6666 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6667 free (shndx);
c9c1d674 6668 }
e3d39609
NC
6669
6670 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6671 entry->hdr->sh_offset,
6672 1, entry->hdr->sh_size,
6673 _("symbol table section indices"));
6674 if (shndx == NULL)
6675 goto exit_point;
6676
6677 /* PR17531: file: heap-buffer-overflow */
6678 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6679 {
6680 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6681 printable_section_name (filedata, entry->hdr),
6682 (unsigned long) entry->hdr->sh_size,
6683 (unsigned long) section->sh_size);
6684 goto exit_point;
6685 }
6686 }
9ad5cbcf 6687
3f5e193b 6688 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6689
6690 if (isyms == NULL)
6691 {
8b73c356
NC
6692 error (_("Out of memory reading %lu symbols\n"),
6693 (unsigned long) number);
ba5cdace 6694 goto exit_point;
9ea033b2
NC
6695 }
6696
ba5cdace 6697 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6698 {
6699 psym->st_name = BYTE_GET (esyms[j].st_name);
6700 psym->st_info = BYTE_GET (esyms[j].st_info);
6701 psym->st_other = BYTE_GET (esyms[j].st_other);
6702 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6703
4fbb74a6 6704 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6705 psym->st_shndx
6706 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6707 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6708 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6709
66543521
AM
6710 psym->st_value = BYTE_GET (esyms[j].st_value);
6711 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6712 }
6713
ba5cdace 6714 exit_point:
e3d39609
NC
6715 free (shndx);
6716 free (esyms);
ba5cdace
NC
6717
6718 if (num_syms_return != NULL)
6719 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6720
6721 return isyms;
6722}
6723
4de91c10
AM
6724static Elf_Internal_Sym *
6725get_elf_symbols (Filedata *filedata,
6726 Elf_Internal_Shdr *section,
6727 unsigned long *num_syms_return)
6728{
6729 if (is_32bit_elf)
6730 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6731 else
6732 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6733}
6734
d1133906 6735static const char *
dda8d76d 6736get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6737{
5477e8a0 6738 static char buff[1024];
2cf0635d 6739 char * p = buff;
32ec8896
NC
6740 unsigned int field_size = is_32bit_elf ? 8 : 16;
6741 signed int sindex;
6742 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6743 bfd_vma os_flags = 0;
6744 bfd_vma proc_flags = 0;
6745 bfd_vma unknown_flags = 0;
148b93f2 6746 static const struct
5477e8a0 6747 {
2cf0635d 6748 const char * str;
32ec8896 6749 unsigned int len;
5477e8a0
L
6750 }
6751 flags [] =
6752 {
cfcac11d
NC
6753 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6754 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6755 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6756 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6757 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6758 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6759 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6760 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6761 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6762 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6763 /* IA-64 specific. */
6764 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6765 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6766 /* IA-64 OpenVMS specific. */
6767 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6768 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6769 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6770 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6771 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6772 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6773 /* Generic. */
cfcac11d 6774 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6775 /* SPARC specific. */
77115a4a 6776 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6777 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6778 /* ARM specific. */
6779 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6780 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6781 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6782 /* GNU specific. */
6783 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6784 /* VLE specific. */
6785 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6786 /* GNU specific. */
6787 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6788 };
6789
6790 if (do_section_details)
6791 {
8d5ff12c
L
6792 sprintf (buff, "[%*.*lx]: ",
6793 field_size, field_size, (unsigned long) sh_flags);
6794 p += field_size + 4;
5477e8a0 6795 }
76da6bbe 6796
d1133906
NC
6797 while (sh_flags)
6798 {
6799 bfd_vma flag;
6800
6801 flag = sh_flags & - sh_flags;
6802 sh_flags &= ~ flag;
76da6bbe 6803
5477e8a0 6804 if (do_section_details)
d1133906 6805 {
5477e8a0
L
6806 switch (flag)
6807 {
91d6fa6a
NC
6808 case SHF_WRITE: sindex = 0; break;
6809 case SHF_ALLOC: sindex = 1; break;
6810 case SHF_EXECINSTR: sindex = 2; break;
6811 case SHF_MERGE: sindex = 3; break;
6812 case SHF_STRINGS: sindex = 4; break;
6813 case SHF_INFO_LINK: sindex = 5; break;
6814 case SHF_LINK_ORDER: sindex = 6; break;
6815 case SHF_OS_NONCONFORMING: sindex = 7; break;
6816 case SHF_GROUP: sindex = 8; break;
6817 case SHF_TLS: sindex = 9; break;
18ae9cc1 6818 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6819 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6820
5477e8a0 6821 default:
91d6fa6a 6822 sindex = -1;
dda8d76d 6823 switch (filedata->file_header.e_machine)
148b93f2 6824 {
cfcac11d 6825 case EM_IA_64:
148b93f2 6826 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6827 sindex = 10;
148b93f2 6828 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6829 sindex = 11;
148b93f2 6830#ifdef BFD64
dda8d76d 6831 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6832 switch (flag)
6833 {
91d6fa6a
NC
6834 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6835 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6836 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6837 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6838 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6839 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6840 default: break;
6841 }
6842#endif
cfcac11d
NC
6843 break;
6844
caa83f8b 6845 case EM_386:
22abe556 6846 case EM_IAMCU:
caa83f8b 6847 case EM_X86_64:
7f502d6c 6848 case EM_L1OM:
7a9068fe 6849 case EM_K1OM:
cfcac11d
NC
6850 case EM_OLD_SPARCV9:
6851 case EM_SPARC32PLUS:
6852 case EM_SPARCV9:
6853 case EM_SPARC:
18ae9cc1 6854 if (flag == SHF_ORDERED)
91d6fa6a 6855 sindex = 19;
cfcac11d 6856 break;
ac4c9b04
MG
6857
6858 case EM_ARM:
6859 switch (flag)
6860 {
6861 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6862 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6863 case SHF_COMDEF: sindex = 23; break;
6864 default: break;
6865 }
6866 break;
83eef883
AFB
6867 case EM_PPC:
6868 if (flag == SHF_PPC_VLE)
6869 sindex = 25;
6870 break;
99fabbc9
JL
6871 default:
6872 break;
6873 }
ac4c9b04 6874
99fabbc9
JL
6875 switch (filedata->file_header.e_ident[EI_OSABI])
6876 {
6877 case ELFOSABI_GNU:
6878 case ELFOSABI_FREEBSD:
6879 if (flag == SHF_GNU_RETAIN)
6880 sindex = 26;
6881 /* Fall through */
6882 case ELFOSABI_NONE:
6883 if (flag == SHF_GNU_MBIND)
6884 /* We should not recognize SHF_GNU_MBIND for
6885 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6886 not set the EI_OSABI header byte. */
6887 sindex = 24;
6888 break;
cfcac11d
NC
6889 default:
6890 break;
148b93f2 6891 }
99fabbc9 6892 break;
5477e8a0
L
6893 }
6894
91d6fa6a 6895 if (sindex != -1)
5477e8a0 6896 {
8d5ff12c
L
6897 if (p != buff + field_size + 4)
6898 {
6899 if (size < (10 + 2))
bee0ee85
NC
6900 {
6901 warn (_("Internal error: not enough buffer room for section flag info"));
6902 return _("<unknown>");
6903 }
8d5ff12c
L
6904 size -= 2;
6905 *p++ = ',';
6906 *p++ = ' ';
6907 }
6908
91d6fa6a
NC
6909 size -= flags [sindex].len;
6910 p = stpcpy (p, flags [sindex].str);
5477e8a0 6911 }
3b22753a 6912 else if (flag & SHF_MASKOS)
8d5ff12c 6913 os_flags |= flag;
d1133906 6914 else if (flag & SHF_MASKPROC)
8d5ff12c 6915 proc_flags |= flag;
d1133906 6916 else
8d5ff12c 6917 unknown_flags |= flag;
5477e8a0
L
6918 }
6919 else
6920 {
6921 switch (flag)
6922 {
6923 case SHF_WRITE: *p = 'W'; break;
6924 case SHF_ALLOC: *p = 'A'; break;
6925 case SHF_EXECINSTR: *p = 'X'; break;
6926 case SHF_MERGE: *p = 'M'; break;
6927 case SHF_STRINGS: *p = 'S'; break;
6928 case SHF_INFO_LINK: *p = 'I'; break;
6929 case SHF_LINK_ORDER: *p = 'L'; break;
6930 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6931 case SHF_GROUP: *p = 'G'; break;
6932 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6933 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6934 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6935
6936 default:
dda8d76d
NC
6937 if ((filedata->file_header.e_machine == EM_X86_64
6938 || filedata->file_header.e_machine == EM_L1OM
6939 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6940 && flag == SHF_X86_64_LARGE)
6941 *p = 'l';
dda8d76d 6942 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6943 && flag == SHF_ARM_PURECODE)
99fabbc9 6944 *p = 'y';
dda8d76d 6945 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6946 && flag == SHF_PPC_VLE)
99fabbc9 6947 *p = 'v';
5477e8a0
L
6948 else if (flag & SHF_MASKOS)
6949 {
99fabbc9
JL
6950 switch (filedata->file_header.e_ident[EI_OSABI])
6951 {
6952 case ELFOSABI_GNU:
6953 case ELFOSABI_FREEBSD:
6954 if (flag == SHF_GNU_RETAIN)
6955 {
6956 *p = 'R';
6957 break;
6958 }
6959 /* Fall through */
6960 case ELFOSABI_NONE:
6961 if (flag == SHF_GNU_MBIND)
6962 {
6963 /* We should not recognize SHF_GNU_MBIND for
6964 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6965 not set the EI_OSABI header byte. */
6966 *p = 'D';
6967 break;
6968 }
6969 /* Fall through */
6970 default:
6971 *p = 'o';
6972 sh_flags &= ~SHF_MASKOS;
6973 break;
6974 }
5477e8a0
L
6975 }
6976 else if (flag & SHF_MASKPROC)
6977 {
6978 *p = 'p';
6979 sh_flags &= ~ SHF_MASKPROC;
6980 }
6981 else
6982 *p = 'x';
6983 break;
6984 }
6985 p++;
d1133906
NC
6986 }
6987 }
76da6bbe 6988
8d5ff12c
L
6989 if (do_section_details)
6990 {
6991 if (os_flags)
6992 {
6993 size -= 5 + field_size;
6994 if (p != buff + field_size + 4)
6995 {
6996 if (size < (2 + 1))
bee0ee85
NC
6997 {
6998 warn (_("Internal error: not enough buffer room for section flag info"));
6999 return _("<unknown>");
7000 }
8d5ff12c
L
7001 size -= 2;
7002 *p++ = ',';
7003 *p++ = ' ';
7004 }
7005 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7006 (unsigned long) os_flags);
7007 p += 5 + field_size;
7008 }
7009 if (proc_flags)
7010 {
7011 size -= 7 + field_size;
7012 if (p != buff + field_size + 4)
7013 {
7014 if (size < (2 + 1))
bee0ee85
NC
7015 {
7016 warn (_("Internal error: not enough buffer room for section flag info"));
7017 return _("<unknown>");
7018 }
8d5ff12c
L
7019 size -= 2;
7020 *p++ = ',';
7021 *p++ = ' ';
7022 }
7023 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7024 (unsigned long) proc_flags);
7025 p += 7 + field_size;
7026 }
7027 if (unknown_flags)
7028 {
7029 size -= 10 + field_size;
7030 if (p != buff + field_size + 4)
7031 {
7032 if (size < (2 + 1))
bee0ee85
NC
7033 {
7034 warn (_("Internal error: not enough buffer room for section flag info"));
7035 return _("<unknown>");
7036 }
8d5ff12c
L
7037 size -= 2;
7038 *p++ = ',';
7039 *p++ = ' ';
7040 }
2b692964 7041 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7042 (unsigned long) unknown_flags);
7043 p += 10 + field_size;
7044 }
7045 }
7046
e9e44622 7047 *p = '\0';
d1133906
NC
7048 return buff;
7049}
7050
5844b465 7051static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 7052get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
7053{
7054 if (is_32bit_elf)
7055 {
7056 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7057
ebdf1ebf
NC
7058 if (size < sizeof (* echdr))
7059 {
7060 error (_("Compressed section is too small even for a compression header\n"));
7061 return 0;
7062 }
7063
77115a4a
L
7064 chdr->ch_type = BYTE_GET (echdr->ch_type);
7065 chdr->ch_size = BYTE_GET (echdr->ch_size);
7066 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7067 return sizeof (*echdr);
7068 }
7069 else
7070 {
7071 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7072
ebdf1ebf
NC
7073 if (size < sizeof (* echdr))
7074 {
7075 error (_("Compressed section is too small even for a compression header\n"));
7076 return 0;
7077 }
7078
77115a4a
L
7079 chdr->ch_type = BYTE_GET (echdr->ch_type);
7080 chdr->ch_size = BYTE_GET (echdr->ch_size);
7081 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7082 return sizeof (*echdr);
7083 }
7084}
7085
015dc7e1 7086static bool
dda8d76d 7087process_section_headers (Filedata * filedata)
252b5132 7088{
2cf0635d 7089 Elf_Internal_Shdr * section;
b34976b6 7090 unsigned int i;
252b5132 7091
dda8d76d 7092 if (filedata->file_header.e_shnum == 0)
252b5132 7093 {
82f2dbf7 7094 /* PR binutils/12467. */
dda8d76d 7095 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7096 {
7097 warn (_("possibly corrupt ELF file header - it has a non-zero"
7098 " section header offset, but no section headers\n"));
015dc7e1 7099 return false;
32ec8896 7100 }
82f2dbf7 7101 else if (do_sections)
252b5132
RH
7102 printf (_("\nThere are no sections in this file.\n"));
7103
015dc7e1 7104 return true;
252b5132
RH
7105 }
7106
7107 if (do_sections && !do_header)
ca0e11aa
NC
7108 {
7109 if (filedata->is_separate && process_links)
7110 printf (_("In linked file '%s': "), filedata->file_name);
7111 if (! filedata->is_separate || process_links)
7112 printf (ngettext ("There is %d section header, "
7113 "starting at offset 0x%lx:\n",
7114 "There are %d section headers, "
7115 "starting at offset 0x%lx:\n",
7116 filedata->file_header.e_shnum),
7117 filedata->file_header.e_shnum,
7118 (unsigned long) filedata->file_header.e_shoff);
7119 }
252b5132 7120
4de91c10
AM
7121 if (!get_section_headers (filedata, false))
7122 return false;
252b5132
RH
7123
7124 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7125 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7126 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7127 {
dda8d76d 7128 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7129
c256ffe7
JJ
7130 if (section->sh_size != 0)
7131 {
dda8d76d
NC
7132 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7133 1, section->sh_size,
7134 _("string table"));
0de14b54 7135
dda8d76d 7136 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7137 }
252b5132
RH
7138 }
7139
7140 /* Scan the sections for the dynamic symbol table
e3c8793a 7141 and dynamic string table and debug sections. */
89fac5e3 7142 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7143 switch (filedata->file_header.e_machine)
89fac5e3
RS
7144 {
7145 case EM_MIPS:
7146 case EM_MIPS_RS3_LE:
7147 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7148 FDE addresses. However, the ABI also has a semi-official ILP32
7149 variant for which the normal FDE address size rules apply.
7150
7151 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7152 section, where XX is the size of longs in bits. Unfortunately,
7153 earlier compilers provided no way of distinguishing ILP32 objects
7154 from LP64 objects, so if there's any doubt, we should assume that
7155 the official LP64 form is being used. */
dda8d76d
NC
7156 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7157 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7158 eh_addr_size = 8;
7159 break;
0f56a26a
DD
7160
7161 case EM_H8_300:
7162 case EM_H8_300H:
dda8d76d 7163 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7164 {
7165 case E_H8_MACH_H8300:
7166 case E_H8_MACH_H8300HN:
7167 case E_H8_MACH_H8300SN:
7168 case E_H8_MACH_H8300SXN:
7169 eh_addr_size = 2;
7170 break;
7171 case E_H8_MACH_H8300H:
7172 case E_H8_MACH_H8300S:
7173 case E_H8_MACH_H8300SX:
7174 eh_addr_size = 4;
7175 break;
7176 }
f4236fe4
DD
7177 break;
7178
ff7eeb89 7179 case EM_M32C_OLD:
f4236fe4 7180 case EM_M32C:
dda8d76d 7181 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7182 {
7183 case EF_M32C_CPU_M16C:
7184 eh_addr_size = 2;
7185 break;
7186 }
7187 break;
89fac5e3
RS
7188 }
7189
76ca31c0
NC
7190#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7191 do \
7192 { \
7193 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7194 if (section->sh_entsize != expected_entsize) \
9dd3a467 7195 { \
76ca31c0
NC
7196 char buf[40]; \
7197 sprintf_vma (buf, section->sh_entsize); \
7198 /* Note: coded this way so that there is a single string for \
7199 translation. */ \
7200 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7201 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7202 (unsigned) expected_entsize); \
9dd3a467 7203 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7204 } \
7205 } \
08d8fa11 7206 while (0)
9dd3a467
NC
7207
7208#define CHECK_ENTSIZE(section, i, type) \
1b513401 7209 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7210 sizeof (Elf64_External_##type))
7211
dda8d76d
NC
7212 for (i = 0, section = filedata->section_headers;
7213 i < filedata->file_header.e_shnum;
b34976b6 7214 i++, section++)
252b5132 7215 {
84714f86 7216 const char *name = section_name_print (filedata, section);
252b5132 7217
1b513401
NC
7218 /* Run some sanity checks on the headers and
7219 possibly fill in some file data as well. */
7220 switch (section->sh_type)
252b5132 7221 {
1b513401 7222 case SHT_DYNSYM:
978c4450 7223 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7224 {
7225 error (_("File contains multiple dynamic symbol tables\n"));
7226 continue;
7227 }
7228
08d8fa11 7229 CHECK_ENTSIZE (section, i, Sym);
978c4450 7230 filedata->dynamic_symbols
4de91c10 7231 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7232 filedata->dynamic_symtab_section = section;
1b513401
NC
7233 break;
7234
7235 case SHT_STRTAB:
7236 if (streq (name, ".dynstr"))
252b5132 7237 {
1b513401
NC
7238 if (filedata->dynamic_strings != NULL)
7239 {
7240 error (_("File contains multiple dynamic string tables\n"));
7241 continue;
7242 }
7243
7244 filedata->dynamic_strings
7245 = (char *) get_data (NULL, filedata, section->sh_offset,
7246 1, section->sh_size, _("dynamic strings"));
7247 filedata->dynamic_strings_length
7248 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7249 filedata->dynamic_strtab_section = section;
252b5132 7250 }
1b513401
NC
7251 break;
7252
7253 case SHT_SYMTAB_SHNDX:
7254 {
7255 elf_section_list * entry = xmalloc (sizeof * entry);
7256
7257 entry->hdr = section;
7258 entry->next = filedata->symtab_shndx_list;
7259 filedata->symtab_shndx_list = entry;
7260 }
7261 break;
7262
7263 case SHT_SYMTAB:
7264 CHECK_ENTSIZE (section, i, Sym);
7265 break;
7266
7267 case SHT_GROUP:
7268 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7269 break;
252b5132 7270
1b513401
NC
7271 case SHT_REL:
7272 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7273 if (do_checks && section->sh_size == 0)
1b513401
NC
7274 warn (_("Section '%s': zero-sized relocation section\n"), name);
7275 break;
7276
7277 case SHT_RELA:
7278 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7279 if (do_checks && section->sh_size == 0)
1b513401
NC
7280 warn (_("Section '%s': zero-sized relocation section\n"), name);
7281 break;
7282
682351b9
AM
7283 case SHT_RELR:
7284 CHECK_ENTSIZE (section, i, Relr);
7285 break;
7286
1b513401
NC
7287 case SHT_NOTE:
7288 case SHT_PROGBITS:
546cb2d8
NC
7289 /* Having a zero sized section is not illegal according to the
7290 ELF standard, but it might be an indication that something
7291 is wrong. So issue a warning if we are running in lint mode. */
7292 if (do_checks && section->sh_size == 0)
1b513401
NC
7293 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7294 break;
7295
7296 default:
7297 break;
7298 }
7299
7300 if ((do_debugging || do_debug_info || do_debug_abbrevs
7301 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7302 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7303 || do_debug_str || do_debug_str_offsets || do_debug_loc
7304 || do_debug_ranges
1b513401 7305 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7306 && (startswith (name, ".debug_")
7307 || startswith (name, ".zdebug_")))
252b5132 7308 {
1b315056
CS
7309 if (name[1] == 'z')
7310 name += sizeof (".zdebug_") - 1;
7311 else
7312 name += sizeof (".debug_") - 1;
252b5132
RH
7313
7314 if (do_debugging
24d127aa
ML
7315 || (do_debug_info && startswith (name, "info"))
7316 || (do_debug_info && startswith (name, "types"))
7317 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7318 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7319 || (do_debug_lines && startswith (name, "line."))
7320 || (do_debug_pubnames && startswith (name, "pubnames"))
7321 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7322 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7323 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7324 || (do_debug_aranges && startswith (name, "aranges"))
7325 || (do_debug_ranges && startswith (name, "ranges"))
7326 || (do_debug_ranges && startswith (name, "rnglists"))
7327 || (do_debug_frames && startswith (name, "frame"))
7328 || (do_debug_macinfo && startswith (name, "macinfo"))
7329 || (do_debug_macinfo && startswith (name, "macro"))
7330 || (do_debug_str && startswith (name, "str"))
7331 || (do_debug_links && startswith (name, "sup"))
7332 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7333 || (do_debug_loc && startswith (name, "loc"))
7334 || (do_debug_loc && startswith (name, "loclists"))
7335 || (do_debug_addr && startswith (name, "addr"))
7336 || (do_debug_cu_index && startswith (name, "cu_index"))
7337 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7338 )
6431e409 7339 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7340 }
a262ae96 7341 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7342 else if ((do_debugging || do_debug_info)
24d127aa 7343 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7344 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7345 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7346 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7347 else if (do_gdb_index && (streq (name, ".gdb_index")
7348 || streq (name, ".debug_names")))
6431e409 7349 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7350 /* Trace sections for Itanium VMS. */
7351 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7352 || do_trace_aranges)
24d127aa 7353 && startswith (name, ".trace_"))
6f875884
TG
7354 {
7355 name += sizeof (".trace_") - 1;
7356
7357 if (do_debugging
7358 || (do_trace_info && streq (name, "info"))
7359 || (do_trace_abbrevs && streq (name, "abbrev"))
7360 || (do_trace_aranges && streq (name, "aranges"))
7361 )
6431e409 7362 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7363 }
dda8d76d 7364 else if ((do_debugging || do_debug_links)
24d127aa
ML
7365 && (startswith (name, ".gnu_debuglink")
7366 || startswith (name, ".gnu_debugaltlink")))
6431e409 7367 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7368 }
7369
7370 if (! do_sections)
015dc7e1 7371 return true;
252b5132 7372
ca0e11aa 7373 if (filedata->is_separate && ! process_links)
015dc7e1 7374 return true;
ca0e11aa
NC
7375
7376 if (filedata->is_separate)
7377 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7378 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7379 printf (_("\nSection Headers:\n"));
7380 else
7381 printf (_("\nSection Header:\n"));
76da6bbe 7382
f7a99963 7383 if (is_32bit_elf)
595cf52e 7384 {
5477e8a0 7385 if (do_section_details)
595cf52e
L
7386 {
7387 printf (_(" [Nr] Name\n"));
5477e8a0 7388 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7389 }
7390 else
7391 printf
7392 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7393 }
d974e256 7394 else if (do_wide)
595cf52e 7395 {
5477e8a0 7396 if (do_section_details)
595cf52e
L
7397 {
7398 printf (_(" [Nr] Name\n"));
5477e8a0 7399 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7400 }
7401 else
7402 printf
7403 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7404 }
f7a99963
NC
7405 else
7406 {
5477e8a0 7407 if (do_section_details)
595cf52e
L
7408 {
7409 printf (_(" [Nr] Name\n"));
5477e8a0
L
7410 printf (_(" Type Address Offset Link\n"));
7411 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7412 }
7413 else
7414 {
7415 printf (_(" [Nr] Name Type Address Offset\n"));
7416 printf (_(" Size EntSize Flags Link Info Align\n"));
7417 }
f7a99963 7418 }
252b5132 7419
5477e8a0
L
7420 if (do_section_details)
7421 printf (_(" Flags\n"));
7422
dda8d76d
NC
7423 for (i = 0, section = filedata->section_headers;
7424 i < filedata->file_header.e_shnum;
b34976b6 7425 i++, section++)
252b5132 7426 {
dd905818
NC
7427 /* Run some sanity checks on the section header. */
7428
7429 /* Check the sh_link field. */
7430 switch (section->sh_type)
7431 {
285e3f99
AM
7432 case SHT_REL:
7433 case SHT_RELA:
7434 if (section->sh_link == 0
7435 && (filedata->file_header.e_type == ET_EXEC
7436 || filedata->file_header.e_type == ET_DYN))
7437 /* A dynamic relocation section where all entries use a
7438 zero symbol index need not specify a symtab section. */
7439 break;
7440 /* Fall through. */
dd905818
NC
7441 case SHT_SYMTAB_SHNDX:
7442 case SHT_GROUP:
7443 case SHT_HASH:
7444 case SHT_GNU_HASH:
7445 case SHT_GNU_versym:
285e3f99 7446 if (section->sh_link == 0
dda8d76d
NC
7447 || section->sh_link >= filedata->file_header.e_shnum
7448 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7449 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7450 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7451 i, section->sh_link);
7452 break;
7453
7454 case SHT_DYNAMIC:
7455 case SHT_SYMTAB:
7456 case SHT_DYNSYM:
7457 case SHT_GNU_verneed:
7458 case SHT_GNU_verdef:
7459 case SHT_GNU_LIBLIST:
285e3f99 7460 if (section->sh_link == 0
dda8d76d
NC
7461 || section->sh_link >= filedata->file_header.e_shnum
7462 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7463 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7464 i, section->sh_link);
7465 break;
7466
7467 case SHT_INIT_ARRAY:
7468 case SHT_FINI_ARRAY:
7469 case SHT_PREINIT_ARRAY:
7470 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7471 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7472 i, section->sh_link);
7473 break;
7474
7475 default:
7476 /* FIXME: Add support for target specific section types. */
7477#if 0 /* Currently we do not check other section types as there are too
7478 many special cases. Stab sections for example have a type
7479 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7480 section. */
7481 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7482 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7483 i, section->sh_link);
7484#endif
7485 break;
7486 }
7487
7488 /* Check the sh_info field. */
7489 switch (section->sh_type)
7490 {
7491 case SHT_REL:
7492 case SHT_RELA:
285e3f99
AM
7493 if (section->sh_info == 0
7494 && (filedata->file_header.e_type == ET_EXEC
7495 || filedata->file_header.e_type == ET_DYN))
7496 /* Dynamic relocations apply to segments, so they do not
7497 need to specify the section they relocate. */
7498 break;
7499 if (section->sh_info == 0
dda8d76d
NC
7500 || section->sh_info >= filedata->file_header.e_shnum
7501 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7502 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7503 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7504 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7505 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7506 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7507 /* FIXME: Are other section types valid ? */
dda8d76d 7508 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7509 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7510 i, section->sh_info);
dd905818
NC
7511 break;
7512
7513 case SHT_DYNAMIC:
7514 case SHT_HASH:
7515 case SHT_SYMTAB_SHNDX:
7516 case SHT_INIT_ARRAY:
7517 case SHT_FINI_ARRAY:
7518 case SHT_PREINIT_ARRAY:
7519 if (section->sh_info != 0)
7520 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7521 i, section->sh_info);
7522 break;
7523
7524 case SHT_GROUP:
7525 case SHT_SYMTAB:
7526 case SHT_DYNSYM:
7527 /* A symbol index - we assume that it is valid. */
7528 break;
7529
7530 default:
7531 /* FIXME: Add support for target specific section types. */
7532 if (section->sh_type == SHT_NOBITS)
7533 /* NOBITS section headers with non-zero sh_info fields can be
7534 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7535 information. The stripped sections have their headers
7536 preserved but their types set to SHT_NOBITS. So do not check
7537 this type of section. */
dd905818
NC
7538 ;
7539 else if (section->sh_flags & SHF_INFO_LINK)
7540 {
dda8d76d 7541 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7542 warn (_("[%2u]: Expected link to another section in info field"), i);
7543 }
a91e1603
L
7544 else if (section->sh_type < SHT_LOOS
7545 && (section->sh_flags & SHF_GNU_MBIND) == 0
7546 && section->sh_info != 0)
dd905818
NC
7547 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7548 i, section->sh_info);
7549 break;
7550 }
7551
3e6b6445 7552 /* Check the sh_size field. */
dda8d76d 7553 if (section->sh_size > filedata->file_size
3e6b6445
NC
7554 && section->sh_type != SHT_NOBITS
7555 && section->sh_type != SHT_NULL
7556 && section->sh_type < SHT_LOOS)
7557 warn (_("Size of section %u is larger than the entire file!\n"), i);
7558
7bfd842d 7559 printf (" [%2u] ", i);
5477e8a0 7560 if (do_section_details)
dda8d76d 7561 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7562 else
84714f86 7563 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7564
ea52a088 7565 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7566 get_section_type_name (filedata, section->sh_type));
0b4362b0 7567
f7a99963
NC
7568 if (is_32bit_elf)
7569 {
cfcac11d
NC
7570 const char * link_too_big = NULL;
7571
f7a99963 7572 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7573
f7a99963
NC
7574 printf ( " %6.6lx %6.6lx %2.2lx",
7575 (unsigned long) section->sh_offset,
7576 (unsigned long) section->sh_size,
7577 (unsigned long) section->sh_entsize);
d1133906 7578
5477e8a0
L
7579 if (do_section_details)
7580 fputs (" ", stdout);
7581 else
dda8d76d 7582 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7583
dda8d76d 7584 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7585 {
7586 link_too_big = "";
7587 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7588 an error but it can have special values in Solaris binaries. */
dda8d76d 7589 switch (filedata->file_header.e_machine)
cfcac11d 7590 {
caa83f8b 7591 case EM_386:
22abe556 7592 case EM_IAMCU:
caa83f8b 7593 case EM_X86_64:
7f502d6c 7594 case EM_L1OM:
7a9068fe 7595 case EM_K1OM:
cfcac11d
NC
7596 case EM_OLD_SPARCV9:
7597 case EM_SPARC32PLUS:
7598 case EM_SPARCV9:
7599 case EM_SPARC:
7600 if (section->sh_link == (SHN_BEFORE & 0xffff))
7601 link_too_big = "BEFORE";
7602 else if (section->sh_link == (SHN_AFTER & 0xffff))
7603 link_too_big = "AFTER";
7604 break;
7605 default:
7606 break;
7607 }
7608 }
7609
7610 if (do_section_details)
7611 {
7612 if (link_too_big != NULL && * link_too_big)
7613 printf ("<%s> ", link_too_big);
7614 else
7615 printf ("%2u ", section->sh_link);
7616 printf ("%3u %2lu\n", section->sh_info,
7617 (unsigned long) section->sh_addralign);
7618 }
7619 else
7620 printf ("%2u %3u %2lu\n",
7621 section->sh_link,
7622 section->sh_info,
7623 (unsigned long) section->sh_addralign);
7624
7625 if (link_too_big && ! * link_too_big)
7626 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7627 i, section->sh_link);
f7a99963 7628 }
d974e256
JJ
7629 else if (do_wide)
7630 {
7631 print_vma (section->sh_addr, LONG_HEX);
7632
7633 if ((long) section->sh_offset == section->sh_offset)
7634 printf (" %6.6lx", (unsigned long) section->sh_offset);
7635 else
7636 {
7637 putchar (' ');
7638 print_vma (section->sh_offset, LONG_HEX);
7639 }
7640
7641 if ((unsigned long) section->sh_size == section->sh_size)
7642 printf (" %6.6lx", (unsigned long) section->sh_size);
7643 else
7644 {
7645 putchar (' ');
7646 print_vma (section->sh_size, LONG_HEX);
7647 }
7648
7649 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7650 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7651 else
7652 {
7653 putchar (' ');
7654 print_vma (section->sh_entsize, LONG_HEX);
7655 }
7656
5477e8a0
L
7657 if (do_section_details)
7658 fputs (" ", stdout);
7659 else
dda8d76d 7660 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7661
72de5009 7662 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7663
7664 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7665 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7666 else
7667 {
7668 print_vma (section->sh_addralign, DEC);
7669 putchar ('\n');
7670 }
7671 }
5477e8a0 7672 else if (do_section_details)
595cf52e 7673 {
55cc53e9 7674 putchar (' ');
595cf52e
L
7675 print_vma (section->sh_addr, LONG_HEX);
7676 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7677 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7678 else
7679 {
7680 printf (" ");
7681 print_vma (section->sh_offset, LONG_HEX);
7682 }
72de5009 7683 printf (" %u\n ", section->sh_link);
595cf52e 7684 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7685 putchar (' ');
595cf52e
L
7686 print_vma (section->sh_entsize, LONG_HEX);
7687
72de5009
AM
7688 printf (" %-16u %lu\n",
7689 section->sh_info,
595cf52e
L
7690 (unsigned long) section->sh_addralign);
7691 }
f7a99963
NC
7692 else
7693 {
7694 putchar (' ');
7695 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7696 if ((long) section->sh_offset == section->sh_offset)
7697 printf (" %8.8lx", (unsigned long) section->sh_offset);
7698 else
7699 {
7700 printf (" ");
7701 print_vma (section->sh_offset, LONG_HEX);
7702 }
f7a99963
NC
7703 printf ("\n ");
7704 print_vma (section->sh_size, LONG_HEX);
7705 printf (" ");
7706 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7707
dda8d76d 7708 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7709
72de5009
AM
7710 printf (" %2u %3u %lu\n",
7711 section->sh_link,
7712 section->sh_info,
f7a99963
NC
7713 (unsigned long) section->sh_addralign);
7714 }
5477e8a0
L
7715
7716 if (do_section_details)
77115a4a 7717 {
dda8d76d 7718 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7719 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7720 {
7721 /* Minimum section size is 12 bytes for 32-bit compression
7722 header + 12 bytes for compressed data header. */
7723 unsigned char buf[24];
d8024a91 7724
77115a4a 7725 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7726 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7727 sizeof (buf), _("compression header")))
7728 {
7729 Elf_Internal_Chdr chdr;
d8024a91 7730
5844b465
NC
7731 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7732 printf (_(" [<corrupt>]\n"));
77115a4a 7733 else
5844b465
NC
7734 {
7735 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7736 printf (" ZLIB, ");
7737 else
7738 printf (_(" [<unknown>: 0x%x], "),
7739 chdr.ch_type);
7740 print_vma (chdr.ch_size, LONG_HEX);
7741 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7742 }
77115a4a
L
7743 }
7744 }
7745 }
252b5132
RH
7746 }
7747
5477e8a0 7748 if (!do_section_details)
3dbcc61d 7749 {
9fb71ee4
NC
7750 /* The ordering of the letters shown here matches the ordering of the
7751 corresponding SHF_xxx values, and hence the order in which these
7752 letters will be displayed to the user. */
7753 printf (_("Key to Flags:\n\
7754 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7755 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7756 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7757 switch (filedata->file_header.e_ident[EI_OSABI])
7758 {
7759 case ELFOSABI_GNU:
7760 case ELFOSABI_FREEBSD:
7761 printf (_("R (retain), "));
7762 /* Fall through */
7763 case ELFOSABI_NONE:
7764 printf (_("D (mbind), "));
7765 break;
7766 default:
7767 break;
7768 }
dda8d76d
NC
7769 if (filedata->file_header.e_machine == EM_X86_64
7770 || filedata->file_header.e_machine == EM_L1OM
7771 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7772 printf (_("l (large), "));
dda8d76d 7773 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7774 printf (_("y (purecode), "));
dda8d76d 7775 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7776 printf (_("v (VLE), "));
9fb71ee4 7777 printf ("p (processor specific)\n");
0b4362b0 7778 }
d1133906 7779
015dc7e1 7780 return true;
252b5132
RH
7781}
7782
015dc7e1 7783static bool
28d13567
AM
7784get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7785 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7786 char **strtab, unsigned long *strtablen)
7787{
7788 *strtab = NULL;
7789 *strtablen = 0;
4de91c10 7790 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7791
7792 if (*symtab == NULL)
015dc7e1 7793 return false;
28d13567
AM
7794
7795 if (symsec->sh_link != 0)
7796 {
7797 Elf_Internal_Shdr *strsec;
7798
7799 if (symsec->sh_link >= filedata->file_header.e_shnum)
7800 {
7801 error (_("Bad sh_link in symbol table section\n"));
7802 free (*symtab);
7803 *symtab = NULL;
7804 *nsyms = 0;
015dc7e1 7805 return false;
28d13567
AM
7806 }
7807
7808 strsec = filedata->section_headers + symsec->sh_link;
7809
7810 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7811 1, strsec->sh_size, _("string table"));
7812 if (*strtab == NULL)
7813 {
7814 free (*symtab);
7815 *symtab = NULL;
7816 *nsyms = 0;
015dc7e1 7817 return false;
28d13567
AM
7818 }
7819 *strtablen = strsec->sh_size;
7820 }
015dc7e1 7821 return true;
28d13567
AM
7822}
7823
f5842774
L
7824static const char *
7825get_group_flags (unsigned int flags)
7826{
1449284b 7827 static char buff[128];
220453ec 7828
6d913794
NC
7829 if (flags == 0)
7830 return "";
7831 else if (flags == GRP_COMDAT)
7832 return "COMDAT ";
f5842774 7833
89246a0e
AM
7834 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7835 flags,
7836 flags & GRP_MASKOS ? _("<OS specific>") : "",
7837 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7838 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7839 ? _("<unknown>") : ""));
6d913794 7840
f5842774
L
7841 return buff;
7842}
7843
015dc7e1 7844static bool
dda8d76d 7845process_section_groups (Filedata * filedata)
f5842774 7846{
2cf0635d 7847 Elf_Internal_Shdr * section;
f5842774 7848 unsigned int i;
2cf0635d
NC
7849 struct group * group;
7850 Elf_Internal_Shdr * symtab_sec;
7851 Elf_Internal_Shdr * strtab_sec;
7852 Elf_Internal_Sym * symtab;
ba5cdace 7853 unsigned long num_syms;
2cf0635d 7854 char * strtab;
c256ffe7 7855 size_t strtab_size;
d1f5c6e3
L
7856
7857 /* Don't process section groups unless needed. */
7858 if (!do_unwind && !do_section_groups)
015dc7e1 7859 return true;
f5842774 7860
dda8d76d 7861 if (filedata->file_header.e_shnum == 0)
f5842774
L
7862 {
7863 if (do_section_groups)
ca0e11aa
NC
7864 {
7865 if (filedata->is_separate)
7866 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7867 filedata->file_name);
7868 else
7869 printf (_("\nThere are no section groups in this file.\n"));
7870 }
015dc7e1 7871 return true;
f5842774
L
7872 }
7873
dda8d76d 7874 if (filedata->section_headers == NULL)
f5842774
L
7875 {
7876 error (_("Section headers are not available!\n"));
fa1908fd 7877 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7878 return false;
f5842774
L
7879 }
7880
978c4450
AM
7881 filedata->section_headers_groups
7882 = (struct group **) calloc (filedata->file_header.e_shnum,
7883 sizeof (struct group *));
e4b17d5c 7884
978c4450 7885 if (filedata->section_headers_groups == NULL)
e4b17d5c 7886 {
8b73c356 7887 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7888 filedata->file_header.e_shnum);
015dc7e1 7889 return false;
e4b17d5c
L
7890 }
7891
f5842774 7892 /* Scan the sections for the group section. */
978c4450 7893 filedata->group_count = 0;
dda8d76d
NC
7894 for (i = 0, section = filedata->section_headers;
7895 i < filedata->file_header.e_shnum;
f5842774 7896 i++, section++)
e4b17d5c 7897 if (section->sh_type == SHT_GROUP)
978c4450 7898 filedata->group_count++;
e4b17d5c 7899
978c4450 7900 if (filedata->group_count == 0)
d1f5c6e3
L
7901 {
7902 if (do_section_groups)
ca0e11aa
NC
7903 {
7904 if (filedata->is_separate)
7905 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7906 filedata->file_name);
7907 else
7908 printf (_("\nThere are no section groups in this file.\n"));
7909 }
d1f5c6e3 7910
015dc7e1 7911 return true;
d1f5c6e3
L
7912 }
7913
978c4450
AM
7914 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7915 sizeof (struct group));
e4b17d5c 7916
978c4450 7917 if (filedata->section_groups == NULL)
e4b17d5c 7918 {
8b73c356 7919 error (_("Out of memory reading %lu groups\n"),
978c4450 7920 (unsigned long) filedata->group_count);
015dc7e1 7921 return false;
e4b17d5c
L
7922 }
7923
d1f5c6e3
L
7924 symtab_sec = NULL;
7925 strtab_sec = NULL;
7926 symtab = NULL;
ba5cdace 7927 num_syms = 0;
d1f5c6e3 7928 strtab = NULL;
c256ffe7 7929 strtab_size = 0;
ca0e11aa
NC
7930
7931 if (filedata->is_separate)
7932 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7933
978c4450 7934 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7935 i < filedata->file_header.e_shnum;
e4b17d5c 7936 i++, section++)
f5842774
L
7937 {
7938 if (section->sh_type == SHT_GROUP)
7939 {
dda8d76d 7940 const char * name = printable_section_name (filedata, section);
74e1a04b 7941 const char * group_name;
2cf0635d
NC
7942 unsigned char * start;
7943 unsigned char * indices;
f5842774 7944 unsigned int entry, j, size;
2cf0635d
NC
7945 Elf_Internal_Shdr * sec;
7946 Elf_Internal_Sym * sym;
f5842774
L
7947
7948 /* Get the symbol table. */
dda8d76d
NC
7949 if (section->sh_link >= filedata->file_header.e_shnum
7950 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7951 != SHT_SYMTAB))
f5842774
L
7952 {
7953 error (_("Bad sh_link in group section `%s'\n"), name);
7954 continue;
7955 }
d1f5c6e3
L
7956
7957 if (symtab_sec != sec)
7958 {
7959 symtab_sec = sec;
9db70fc3 7960 free (symtab);
4de91c10 7961 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7962 }
f5842774 7963
dd24e3da
NC
7964 if (symtab == NULL)
7965 {
7966 error (_("Corrupt header in group section `%s'\n"), name);
7967 continue;
7968 }
7969
ba5cdace
NC
7970 if (section->sh_info >= num_syms)
7971 {
7972 error (_("Bad sh_info in group section `%s'\n"), name);
7973 continue;
7974 }
7975
f5842774
L
7976 sym = symtab + section->sh_info;
7977
7978 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7979 {
4fbb74a6 7980 if (sym->st_shndx == 0
dda8d76d 7981 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7982 {
7983 error (_("Bad sh_info in group section `%s'\n"), name);
7984 continue;
7985 }
ba2685cc 7986
84714f86
AM
7987 group_name = section_name_print (filedata,
7988 filedata->section_headers
b9e920ec 7989 + sym->st_shndx);
c256ffe7 7990 strtab_sec = NULL;
9db70fc3 7991 free (strtab);
f5842774 7992 strtab = NULL;
c256ffe7 7993 strtab_size = 0;
f5842774
L
7994 }
7995 else
7996 {
7997 /* Get the string table. */
dda8d76d 7998 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7999 {
8000 strtab_sec = NULL;
9db70fc3 8001 free (strtab);
c256ffe7
JJ
8002 strtab = NULL;
8003 strtab_size = 0;
8004 }
8005 else if (strtab_sec
dda8d76d 8006 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8007 {
8008 strtab_sec = sec;
9db70fc3 8009 free (strtab);
071436c6 8010
dda8d76d 8011 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8012 1, strtab_sec->sh_size,
8013 _("string table"));
c256ffe7 8014 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8015 }
c256ffe7 8016 group_name = sym->st_name < strtab_size
2b692964 8017 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8018 }
8019
c9c1d674
EG
8020 /* PR 17531: file: loop. */
8021 if (section->sh_entsize > section->sh_size)
8022 {
8023 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8024 printable_section_name (filedata, section),
8066deb1
AM
8025 (unsigned long) section->sh_entsize,
8026 (unsigned long) section->sh_size);
61dd8e19 8027 continue;
c9c1d674
EG
8028 }
8029
dda8d76d 8030 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8031 1, section->sh_size,
8032 _("section data"));
59245841
NC
8033 if (start == NULL)
8034 continue;
f5842774
L
8035
8036 indices = start;
8037 size = (section->sh_size / section->sh_entsize) - 1;
8038 entry = byte_get (indices, 4);
8039 indices += 4;
e4b17d5c
L
8040
8041 if (do_section_groups)
8042 {
2b692964 8043 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8044 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8045
e4b17d5c
L
8046 printf (_(" [Index] Name\n"));
8047 }
8048
8049 group->group_index = i;
8050
f5842774
L
8051 for (j = 0; j < size; j++)
8052 {
2cf0635d 8053 struct group_list * g;
e4b17d5c 8054
f5842774
L
8055 entry = byte_get (indices, 4);
8056 indices += 4;
8057
dda8d76d 8058 if (entry >= filedata->file_header.e_shnum)
391cb864 8059 {
57028622
NC
8060 static unsigned num_group_errors = 0;
8061
8062 if (num_group_errors ++ < 10)
8063 {
8064 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8065 entry, i, filedata->file_header.e_shnum - 1);
57028622 8066 if (num_group_errors == 10)
67ce483b 8067 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8068 }
391cb864
L
8069 continue;
8070 }
391cb864 8071
978c4450 8072 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8073 {
d1f5c6e3
L
8074 if (entry)
8075 {
57028622
NC
8076 static unsigned num_errs = 0;
8077
8078 if (num_errs ++ < 10)
8079 {
8080 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8081 entry, i,
978c4450 8082 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8083 if (num_errs == 10)
8084 warn (_("Further error messages about already contained group sections suppressed\n"));
8085 }
d1f5c6e3
L
8086 continue;
8087 }
8088 else
8089 {
8090 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8091 section group. We just warn it the first time
d1f5c6e3 8092 and ignore it afterwards. */
015dc7e1 8093 static bool warned = false;
d1f5c6e3
L
8094 if (!warned)
8095 {
8096 error (_("section 0 in group section [%5u]\n"),
978c4450 8097 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8098 warned = true;
d1f5c6e3
L
8099 }
8100 }
e4b17d5c
L
8101 }
8102
978c4450 8103 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8104
8105 if (do_section_groups)
8106 {
dda8d76d
NC
8107 sec = filedata->section_headers + entry;
8108 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8109 }
8110
3f5e193b 8111 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8112 g->section_index = entry;
8113 g->next = group->root;
8114 group->root = g;
f5842774
L
8115 }
8116
9db70fc3 8117 free (start);
e4b17d5c
L
8118
8119 group++;
f5842774
L
8120 }
8121 }
8122
9db70fc3
AM
8123 free (symtab);
8124 free (strtab);
015dc7e1 8125 return true;
f5842774
L
8126}
8127
28f997cf
TG
8128/* Data used to display dynamic fixups. */
8129
8130struct ia64_vms_dynfixup
8131{
8132 bfd_vma needed_ident; /* Library ident number. */
8133 bfd_vma needed; /* Index in the dstrtab of the library name. */
8134 bfd_vma fixup_needed; /* Index of the library. */
8135 bfd_vma fixup_rela_cnt; /* Number of fixups. */
8136 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
8137};
8138
8139/* Data used to display dynamic relocations. */
8140
8141struct ia64_vms_dynimgrela
8142{
8143 bfd_vma img_rela_cnt; /* Number of relocations. */
8144 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
8145};
8146
8147/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8148 library). */
8149
015dc7e1 8150static bool
dda8d76d
NC
8151dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8152 struct ia64_vms_dynfixup * fixup,
8153 const char * strtab,
8154 unsigned int strtab_sz)
28f997cf 8155{
32ec8896 8156 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8157 long i;
32ec8896 8158 const char * lib_name;
28f997cf 8159
978c4450
AM
8160 imfs = get_data (NULL, filedata,
8161 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8162 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8163 _("dynamic section image fixups"));
8164 if (!imfs)
015dc7e1 8165 return false;
28f997cf
TG
8166
8167 if (fixup->needed < strtab_sz)
8168 lib_name = strtab + fixup->needed;
8169 else
8170 {
32ec8896 8171 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8172 (unsigned long) fixup->needed);
28f997cf
TG
8173 lib_name = "???";
8174 }
736990c4 8175
28f997cf
TG
8176 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8177 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8178 printf
8179 (_("Seg Offset Type SymVec DataType\n"));
8180
8181 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8182 {
8183 unsigned int type;
8184 const char *rtype;
8185
8186 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8187 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8188 type = BYTE_GET (imfs [i].type);
8189 rtype = elf_ia64_reloc_type (type);
8190 if (rtype == NULL)
8191 printf (" 0x%08x ", type);
8192 else
8193 printf (" %-32s ", rtype);
8194 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8195 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8196 }
8197
8198 free (imfs);
015dc7e1 8199 return true;
28f997cf
TG
8200}
8201
8202/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8203
015dc7e1 8204static bool
dda8d76d 8205dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8206{
8207 Elf64_External_VMS_IMAGE_RELA *imrs;
8208 long i;
8209
978c4450
AM
8210 imrs = get_data (NULL, filedata,
8211 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8212 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8213 _("dynamic section image relocations"));
28f997cf 8214 if (!imrs)
015dc7e1 8215 return false;
28f997cf
TG
8216
8217 printf (_("\nImage relocs\n"));
8218 printf
8219 (_("Seg Offset Type Addend Seg Sym Off\n"));
8220
8221 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8222 {
8223 unsigned int type;
8224 const char *rtype;
8225
8226 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8227 printf ("%08" BFD_VMA_FMT "x ",
8228 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8229 type = BYTE_GET (imrs [i].type);
8230 rtype = elf_ia64_reloc_type (type);
8231 if (rtype == NULL)
8232 printf ("0x%08x ", type);
8233 else
8234 printf ("%-31s ", rtype);
8235 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8236 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8237 printf ("%08" BFD_VMA_FMT "x\n",
8238 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8239 }
8240
8241 free (imrs);
015dc7e1 8242 return true;
28f997cf
TG
8243}
8244
8245/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8246
015dc7e1 8247static bool
dda8d76d 8248process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8249{
8250 struct ia64_vms_dynfixup fixup;
8251 struct ia64_vms_dynimgrela imgrela;
8252 Elf_Internal_Dyn *entry;
28f997cf
TG
8253 bfd_vma strtab_off = 0;
8254 bfd_vma strtab_sz = 0;
8255 char *strtab = NULL;
015dc7e1 8256 bool res = true;
28f997cf
TG
8257
8258 memset (&fixup, 0, sizeof (fixup));
8259 memset (&imgrela, 0, sizeof (imgrela));
8260
8261 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8262 for (entry = filedata->dynamic_section;
8263 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8264 entry++)
8265 {
8266 switch (entry->d_tag)
8267 {
8268 case DT_IA_64_VMS_STRTAB_OFFSET:
8269 strtab_off = entry->d_un.d_val;
8270 break;
8271 case DT_STRSZ:
8272 strtab_sz = entry->d_un.d_val;
8273 if (strtab == NULL)
978c4450
AM
8274 strtab = get_data (NULL, filedata,
8275 filedata->dynamic_addr + strtab_off,
28f997cf 8276 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8277 if (strtab == NULL)
8278 strtab_sz = 0;
28f997cf
TG
8279 break;
8280
8281 case DT_IA_64_VMS_NEEDED_IDENT:
8282 fixup.needed_ident = entry->d_un.d_val;
8283 break;
8284 case DT_NEEDED:
8285 fixup.needed = entry->d_un.d_val;
8286 break;
8287 case DT_IA_64_VMS_FIXUP_NEEDED:
8288 fixup.fixup_needed = entry->d_un.d_val;
8289 break;
8290 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8291 fixup.fixup_rela_cnt = entry->d_un.d_val;
8292 break;
8293 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8294 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8295 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8296 res = false;
28f997cf 8297 break;
28f997cf
TG
8298 case DT_IA_64_VMS_IMG_RELA_CNT:
8299 imgrela.img_rela_cnt = entry->d_un.d_val;
8300 break;
8301 case DT_IA_64_VMS_IMG_RELA_OFF:
8302 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8303 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8304 res = false;
28f997cf
TG
8305 break;
8306
8307 default:
8308 break;
8309 }
8310 }
8311
9db70fc3 8312 free (strtab);
28f997cf
TG
8313
8314 return res;
8315}
8316
85b1c36d 8317static struct
566b0d53 8318{
2cf0635d 8319 const char * name;
566b0d53
L
8320 int reloc;
8321 int size;
a7fd1186 8322 relocation_type rel_type;
32ec8896
NC
8323}
8324 dynamic_relocations [] =
566b0d53 8325{
a7fd1186
FS
8326 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8327 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8328 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8329 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8330};
8331
252b5132 8332/* Process the reloc section. */
18bd398b 8333
015dc7e1 8334static bool
dda8d76d 8335process_relocs (Filedata * filedata)
252b5132 8336{
b34976b6
AM
8337 unsigned long rel_size;
8338 unsigned long rel_offset;
252b5132 8339
252b5132 8340 if (!do_reloc)
015dc7e1 8341 return true;
252b5132
RH
8342
8343 if (do_using_dynamic)
8344 {
a7fd1186 8345 relocation_type rel_type;
2cf0635d 8346 const char * name;
015dc7e1 8347 bool has_dynamic_reloc;
566b0d53 8348 unsigned int i;
0de14b54 8349
015dc7e1 8350 has_dynamic_reloc = false;
252b5132 8351
566b0d53 8352 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8353 {
a7fd1186 8354 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8355 name = dynamic_relocations [i].name;
978c4450
AM
8356 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8357 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8358
32ec8896 8359 if (rel_size)
015dc7e1 8360 has_dynamic_reloc = true;
566b0d53 8361
a7fd1186 8362 if (rel_type == reltype_unknown)
aa903cfb 8363 {
566b0d53 8364 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8365 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8366 {
8367 case DT_REL:
a7fd1186 8368 rel_type = reltype_rel;
566b0d53
L
8369 break;
8370 case DT_RELA:
a7fd1186 8371 rel_type = reltype_rela;
566b0d53
L
8372 break;
8373 }
aa903cfb 8374 }
252b5132 8375
566b0d53
L
8376 if (rel_size)
8377 {
ca0e11aa
NC
8378 if (filedata->is_separate)
8379 printf
8380 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8381 filedata->file_name, name, rel_offset, rel_size);
8382 else
8383 printf
8384 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8385 name, rel_offset, rel_size);
252b5132 8386
dda8d76d
NC
8387 dump_relocations (filedata,
8388 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8389 rel_size,
978c4450
AM
8390 filedata->dynamic_symbols,
8391 filedata->num_dynamic_syms,
8392 filedata->dynamic_strings,
8393 filedata->dynamic_strings_length,
a7fd1186 8394 rel_type, true /* is_dynamic */);
566b0d53 8395 }
252b5132 8396 }
566b0d53 8397
dda8d76d
NC
8398 if (is_ia64_vms (filedata))
8399 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8400 has_dynamic_reloc = true;
28f997cf 8401
566b0d53 8402 if (! has_dynamic_reloc)
ca0e11aa
NC
8403 {
8404 if (filedata->is_separate)
8405 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8406 filedata->file_name);
8407 else
8408 printf (_("\nThere are no dynamic relocations in this file.\n"));
8409 }
252b5132
RH
8410 }
8411 else
8412 {
2cf0635d 8413 Elf_Internal_Shdr * section;
b34976b6 8414 unsigned long i;
015dc7e1 8415 bool found = false;
252b5132 8416
dda8d76d
NC
8417 for (i = 0, section = filedata->section_headers;
8418 i < filedata->file_header.e_shnum;
b34976b6 8419 i++, section++)
252b5132
RH
8420 {
8421 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8422 && section->sh_type != SHT_REL
8423 && section->sh_type != SHT_RELR)
252b5132
RH
8424 continue;
8425
8426 rel_offset = section->sh_offset;
8427 rel_size = section->sh_size;
8428
8429 if (rel_size)
8430 {
a7fd1186 8431 relocation_type rel_type;
d3a49aa8 8432 unsigned long num_rela;
103f02d3 8433
ca0e11aa
NC
8434 if (filedata->is_separate)
8435 printf (_("\nIn linked file '%s' relocation section "),
8436 filedata->file_name);
8437 else
8438 printf (_("\nRelocation section "));
252b5132 8439
dda8d76d 8440 if (filedata->string_table == NULL)
19936277 8441 printf ("%d", section->sh_name);
252b5132 8442 else
dda8d76d 8443 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8444
d3a49aa8
AM
8445 num_rela = rel_size / section->sh_entsize;
8446 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8447 " at offset 0x%lx contains %lu entries:\n",
8448 num_rela),
8449 rel_offset, num_rela);
252b5132 8450
a7fd1186
FS
8451 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8452 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8453
4fbb74a6 8454 if (section->sh_link != 0
dda8d76d 8455 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8456 {
2cf0635d
NC
8457 Elf_Internal_Shdr * symsec;
8458 Elf_Internal_Sym * symtab;
d79b3d50 8459 unsigned long nsyms;
c256ffe7 8460 unsigned long strtablen = 0;
2cf0635d 8461 char * strtab = NULL;
57346661 8462
dda8d76d 8463 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8464 if (symsec->sh_type != SHT_SYMTAB
8465 && symsec->sh_type != SHT_DYNSYM)
8466 continue;
8467
28d13567
AM
8468 if (!get_symtab (filedata, symsec,
8469 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8470 continue;
252b5132 8471
dda8d76d 8472 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8473 symtab, nsyms, strtab, strtablen,
a7fd1186 8474 rel_type,
bb4d2ac2 8475 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8476 free (strtab);
d79b3d50
NC
8477 free (symtab);
8478 }
8479 else
dda8d76d 8480 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8481 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8482
015dc7e1 8483 found = true;
252b5132
RH
8484 }
8485 }
8486
8487 if (! found)
45ac8f4f
NC
8488 {
8489 /* Users sometimes forget the -D option, so try to be helpful. */
8490 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8491 {
978c4450 8492 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8493 {
ca0e11aa
NC
8494 if (filedata->is_separate)
8495 printf (_("\nThere are no static relocations in linked file '%s'."),
8496 filedata->file_name);
8497 else
8498 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8499 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8500
8501 break;
8502 }
8503 }
8504 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8505 {
8506 if (filedata->is_separate)
8507 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8508 filedata->file_name);
8509 else
8510 printf (_("\nThere are no relocations in this file.\n"));
8511 }
45ac8f4f 8512 }
252b5132
RH
8513 }
8514
015dc7e1 8515 return true;
252b5132
RH
8516}
8517
4d6ed7c8
NC
8518/* An absolute address consists of a section and an offset. If the
8519 section is NULL, the offset itself is the address, otherwise, the
8520 address equals to LOAD_ADDRESS(section) + offset. */
8521
8522struct absaddr
948f632f
DA
8523{
8524 unsigned short section;
8525 bfd_vma offset;
8526};
4d6ed7c8 8527
948f632f
DA
8528/* Find the nearest symbol at or below ADDR. Returns the symbol
8529 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8530
4d6ed7c8 8531static void
dda8d76d
NC
8532find_symbol_for_address (Filedata * filedata,
8533 Elf_Internal_Sym * symtab,
8534 unsigned long nsyms,
8535 const char * strtab,
8536 unsigned long strtab_size,
8537 struct absaddr addr,
8538 const char ** symname,
8539 bfd_vma * offset)
4d6ed7c8 8540{
d3ba0551 8541 bfd_vma dist = 0x100000;
2cf0635d 8542 Elf_Internal_Sym * sym;
948f632f
DA
8543 Elf_Internal_Sym * beg;
8544 Elf_Internal_Sym * end;
2cf0635d 8545 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8546
0b6ae522 8547 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8548 beg = symtab;
8549 end = symtab + nsyms;
0b6ae522 8550
948f632f 8551 while (beg < end)
4d6ed7c8 8552 {
948f632f
DA
8553 bfd_vma value;
8554
8555 sym = beg + (end - beg) / 2;
0b6ae522 8556
948f632f 8557 value = sym->st_value;
0b6ae522
DJ
8558 REMOVE_ARCH_BITS (value);
8559
948f632f 8560 if (sym->st_name != 0
4d6ed7c8 8561 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8562 && addr.offset >= value
8563 && addr.offset - value < dist)
4d6ed7c8
NC
8564 {
8565 best = sym;
0b6ae522 8566 dist = addr.offset - value;
4d6ed7c8
NC
8567 if (!dist)
8568 break;
8569 }
948f632f
DA
8570
8571 if (addr.offset < value)
8572 end = sym;
8573 else
8574 beg = sym + 1;
4d6ed7c8 8575 }
1b31d05e 8576
4d6ed7c8
NC
8577 if (best)
8578 {
57346661 8579 *symname = (best->st_name >= strtab_size
2b692964 8580 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8581 *offset = dist;
8582 return;
8583 }
1b31d05e 8584
4d6ed7c8
NC
8585 *symname = NULL;
8586 *offset = addr.offset;
8587}
8588
32ec8896 8589static /* signed */ int
948f632f
DA
8590symcmp (const void *p, const void *q)
8591{
8592 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8593 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8594
8595 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8596}
8597
8598/* Process the unwind section. */
8599
8600#include "unwind-ia64.h"
8601
8602struct ia64_unw_table_entry
8603{
8604 struct absaddr start;
8605 struct absaddr end;
8606 struct absaddr info;
8607};
8608
8609struct ia64_unw_aux_info
8610{
32ec8896
NC
8611 struct ia64_unw_table_entry * table; /* Unwind table. */
8612 unsigned long table_len; /* Length of unwind table. */
8613 unsigned char * info; /* Unwind info. */
8614 unsigned long info_size; /* Size of unwind info. */
8615 bfd_vma info_addr; /* Starting address of unwind info. */
8616 bfd_vma seg_base; /* Starting address of segment. */
8617 Elf_Internal_Sym * symtab; /* The symbol table. */
8618 unsigned long nsyms; /* Number of symbols. */
8619 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8620 unsigned long nfuns; /* Number of entries in funtab. */
8621 char * strtab; /* The string table. */
8622 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8623};
8624
015dc7e1 8625static bool
dda8d76d 8626dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8627{
2cf0635d 8628 struct ia64_unw_table_entry * tp;
948f632f 8629 unsigned long j, nfuns;
4d6ed7c8 8630 int in_body;
015dc7e1 8631 bool res = true;
7036c0e1 8632
948f632f
DA
8633 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8634 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8635 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8636 aux->funtab[nfuns++] = aux->symtab[j];
8637 aux->nfuns = nfuns;
8638 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8639
4d6ed7c8
NC
8640 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8641 {
8642 bfd_vma stamp;
8643 bfd_vma offset;
2cf0635d
NC
8644 const unsigned char * dp;
8645 const unsigned char * head;
53774b7e 8646 const unsigned char * end;
2cf0635d 8647 const char * procname;
4d6ed7c8 8648
dda8d76d 8649 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8650 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8651
8652 fputs ("\n<", stdout);
8653
8654 if (procname)
8655 {
8656 fputs (procname, stdout);
8657
8658 if (offset)
8659 printf ("+%lx", (unsigned long) offset);
8660 }
8661
8662 fputs (">: [", stdout);
8663 print_vma (tp->start.offset, PREFIX_HEX);
8664 fputc ('-', stdout);
8665 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8666 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8667 (unsigned long) (tp->info.offset - aux->seg_base));
8668
53774b7e
NC
8669 /* PR 17531: file: 86232b32. */
8670 if (aux->info == NULL)
8671 continue;
8672
97c0a079
AM
8673 offset = tp->info.offset;
8674 if (tp->info.section)
8675 {
8676 if (tp->info.section >= filedata->file_header.e_shnum)
8677 {
8678 warn (_("Invalid section %u in table entry %ld\n"),
8679 tp->info.section, (long) (tp - aux->table));
015dc7e1 8680 res = false;
97c0a079
AM
8681 continue;
8682 }
8683 offset += filedata->section_headers[tp->info.section].sh_addr;
8684 }
8685 offset -= aux->info_addr;
53774b7e 8686 /* PR 17531: file: 0997b4d1. */
90679903
AM
8687 if (offset >= aux->info_size
8688 || aux->info_size - offset < 8)
53774b7e
NC
8689 {
8690 warn (_("Invalid offset %lx in table entry %ld\n"),
8691 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8692 res = false;
53774b7e
NC
8693 continue;
8694 }
8695
97c0a079 8696 head = aux->info + offset;
a4a00738 8697 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8698
86f55779 8699 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8700 (unsigned) UNW_VER (stamp),
8701 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8702 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8703 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8704 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8705
8706 if (UNW_VER (stamp) != 1)
8707 {
2b692964 8708 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8709 continue;
8710 }
8711
8712 in_body = 0;
53774b7e
NC
8713 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8714 /* PR 17531: file: 16ceda89. */
8715 if (end > aux->info + aux->info_size)
8716 end = aux->info + aux->info_size;
8717 for (dp = head + 8; dp < end;)
b4477bc8 8718 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8719 }
948f632f
DA
8720
8721 free (aux->funtab);
32ec8896
NC
8722
8723 return res;
4d6ed7c8
NC
8724}
8725
015dc7e1 8726static bool
dda8d76d
NC
8727slurp_ia64_unwind_table (Filedata * filedata,
8728 struct ia64_unw_aux_info * aux,
8729 Elf_Internal_Shdr * sec)
4d6ed7c8 8730{
89fac5e3 8731 unsigned long size, nrelas, i;
2cf0635d
NC
8732 Elf_Internal_Phdr * seg;
8733 struct ia64_unw_table_entry * tep;
8734 Elf_Internal_Shdr * relsec;
8735 Elf_Internal_Rela * rela;
8736 Elf_Internal_Rela * rp;
8737 unsigned char * table;
8738 unsigned char * tp;
8739 Elf_Internal_Sym * sym;
8740 const char * relname;
4d6ed7c8 8741
53774b7e
NC
8742 aux->table_len = 0;
8743
4d6ed7c8
NC
8744 /* First, find the starting address of the segment that includes
8745 this section: */
8746
dda8d76d 8747 if (filedata->file_header.e_phnum)
4d6ed7c8 8748 {
dda8d76d 8749 if (! get_program_headers (filedata))
015dc7e1 8750 return false;
4d6ed7c8 8751
dda8d76d
NC
8752 for (seg = filedata->program_headers;
8753 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8754 ++seg)
4d6ed7c8
NC
8755 {
8756 if (seg->p_type != PT_LOAD)
8757 continue;
8758
8759 if (sec->sh_addr >= seg->p_vaddr
8760 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8761 {
8762 aux->seg_base = seg->p_vaddr;
8763 break;
8764 }
8765 }
4d6ed7c8
NC
8766 }
8767
8768 /* Second, build the unwind table from the contents of the unwind section: */
8769 size = sec->sh_size;
dda8d76d 8770 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8771 _("unwind table"));
a6e9f9df 8772 if (!table)
015dc7e1 8773 return false;
4d6ed7c8 8774
53774b7e 8775 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8776 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8777 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8778 tep = aux->table;
53774b7e
NC
8779
8780 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8781 {
8782 tep->start.section = SHN_UNDEF;
8783 tep->end.section = SHN_UNDEF;
8784 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8785 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8786 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8787 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8788 tep->start.offset += aux->seg_base;
8789 tep->end.offset += aux->seg_base;
8790 tep->info.offset += aux->seg_base;
8791 }
8792 free (table);
8793
41e92641 8794 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8795 for (relsec = filedata->section_headers;
8796 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8797 ++relsec)
8798 {
8799 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8800 || relsec->sh_info >= filedata->file_header.e_shnum
8801 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8802 continue;
8803
dda8d76d 8804 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8805 & rela, & nrelas))
53774b7e
NC
8806 {
8807 free (aux->table);
8808 aux->table = NULL;
8809 aux->table_len = 0;
015dc7e1 8810 return false;
53774b7e 8811 }
4d6ed7c8
NC
8812
8813 for (rp = rela; rp < rela + nrelas; ++rp)
8814 {
4770fb94 8815 unsigned int sym_ndx;
726bd37d
AM
8816 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8817 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8818
82b1b41b
NC
8819 /* PR 17531: file: 9fa67536. */
8820 if (relname == NULL)
8821 {
726bd37d 8822 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8823 continue;
8824 }
948f632f 8825
24d127aa 8826 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8827 {
82b1b41b 8828 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8829 continue;
8830 }
8831
89fac5e3 8832 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8833
53774b7e
NC
8834 /* PR 17531: file: 5bc8d9bf. */
8835 if (i >= aux->table_len)
8836 {
8837 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8838 continue;
8839 }
8840
4770fb94
AM
8841 sym_ndx = get_reloc_symindex (rp->r_info);
8842 if (sym_ndx >= aux->nsyms)
8843 {
8844 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8845 sym_ndx);
8846 continue;
8847 }
8848 sym = aux->symtab + sym_ndx;
8849
53774b7e 8850 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8851 {
8852 case 0:
8853 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8854 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8855 break;
8856 case 1:
8857 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8858 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8859 break;
8860 case 2:
8861 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8862 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8863 break;
8864 default:
8865 break;
8866 }
8867 }
8868
8869 free (rela);
8870 }
8871
015dc7e1 8872 return true;
4d6ed7c8
NC
8873}
8874
015dc7e1 8875static bool
dda8d76d 8876ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8877{
2cf0635d
NC
8878 Elf_Internal_Shdr * sec;
8879 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8880 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8881 struct ia64_unw_aux_info aux;
015dc7e1 8882 bool res = true;
f1467e33 8883
4d6ed7c8
NC
8884 memset (& aux, 0, sizeof (aux));
8885
dda8d76d 8886 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8887 {
28d13567 8888 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8889 {
28d13567 8890 if (aux.symtab)
4082ef84 8891 {
28d13567
AM
8892 error (_("Multiple symbol tables encountered\n"));
8893 free (aux.symtab);
8894 aux.symtab = NULL;
4082ef84 8895 free (aux.strtab);
28d13567 8896 aux.strtab = NULL;
4082ef84 8897 }
28d13567
AM
8898 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8899 &aux.strtab, &aux.strtab_size))
015dc7e1 8900 return false;
4d6ed7c8
NC
8901 }
8902 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8903 unwcount++;
8904 }
8905
8906 if (!unwcount)
8907 printf (_("\nThere are no unwind sections in this file.\n"));
8908
8909 while (unwcount-- > 0)
8910 {
84714f86 8911 const char *suffix;
579f31ac
JJ
8912 size_t len, len2;
8913
dda8d76d
NC
8914 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8915 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8916 if (sec->sh_type == SHT_IA_64_UNWIND)
8917 {
8918 unwsec = sec;
8919 break;
8920 }
4082ef84
NC
8921 /* We have already counted the number of SHT_IA64_UNWIND
8922 sections so the loop above should never fail. */
8923 assert (unwsec != NULL);
579f31ac
JJ
8924
8925 unwstart = i + 1;
8926 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8927
e4b17d5c
L
8928 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8929 {
8930 /* We need to find which section group it is in. */
4082ef84 8931 struct group_list * g;
e4b17d5c 8932
978c4450
AM
8933 if (filedata->section_headers_groups == NULL
8934 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8935 i = filedata->file_header.e_shnum;
4082ef84 8936 else
e4b17d5c 8937 {
978c4450 8938 g = filedata->section_headers_groups[i]->root;
18bd398b 8939
4082ef84
NC
8940 for (; g != NULL; g = g->next)
8941 {
dda8d76d 8942 sec = filedata->section_headers + g->section_index;
e4b17d5c 8943
84714f86
AM
8944 if (section_name_valid (filedata, sec)
8945 && streq (section_name (filedata, sec),
8946 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8947 break;
8948 }
8949
8950 if (g == NULL)
dda8d76d 8951 i = filedata->file_header.e_shnum;
4082ef84 8952 }
e4b17d5c 8953 }
84714f86
AM
8954 else if (section_name_valid (filedata, unwsec)
8955 && startswith (section_name (filedata, unwsec),
e9b095a5 8956 ELF_STRING_ia64_unwind_once))
579f31ac 8957 {
18bd398b 8958 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8959 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8960 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8961 for (i = 0, sec = filedata->section_headers;
8962 i < filedata->file_header.e_shnum;
579f31ac 8963 ++i, ++sec)
84714f86
AM
8964 if (section_name_valid (filedata, sec)
8965 && startswith (section_name (filedata, sec),
e9b095a5 8966 ELF_STRING_ia64_unwind_info_once)
84714f86 8967 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8968 break;
8969 }
8970 else
8971 {
8972 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8973 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8974 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8975 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8976 suffix = "";
84714f86
AM
8977 if (section_name_valid (filedata, unwsec)
8978 && startswith (section_name (filedata, unwsec),
8979 ELF_STRING_ia64_unwind))
8980 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8981 for (i = 0, sec = filedata->section_headers;
8982 i < filedata->file_header.e_shnum;
579f31ac 8983 ++i, ++sec)
84714f86
AM
8984 if (section_name_valid (filedata, sec)
8985 && startswith (section_name (filedata, sec),
8986 ELF_STRING_ia64_unwind_info)
8987 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8988 break;
8989 }
8990
dda8d76d 8991 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8992 {
8993 printf (_("\nCould not find unwind info section for "));
8994
dda8d76d 8995 if (filedata->string_table == NULL)
579f31ac
JJ
8996 printf ("%d", unwsec->sh_name);
8997 else
dda8d76d 8998 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8999 }
9000 else
4d6ed7c8 9001 {
4d6ed7c8 9002 aux.info_addr = sec->sh_addr;
dda8d76d 9003 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9004 sec->sh_size,
9005 _("unwind info"));
59245841 9006 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9007
579f31ac 9008 printf (_("\nUnwind section "));
4d6ed7c8 9009
dda8d76d 9010 if (filedata->string_table == NULL)
579f31ac
JJ
9011 printf ("%d", unwsec->sh_name);
9012 else
dda8d76d 9013 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9014
579f31ac 9015 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9016 (unsigned long) unwsec->sh_offset,
89fac5e3 9017 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9018
dda8d76d 9019 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9020 && aux.table_len > 0)
dda8d76d 9021 dump_ia64_unwind (filedata, & aux);
579f31ac 9022
9db70fc3
AM
9023 free ((char *) aux.table);
9024 free ((char *) aux.info);
579f31ac
JJ
9025 aux.table = NULL;
9026 aux.info = NULL;
9027 }
4d6ed7c8 9028 }
4d6ed7c8 9029
9db70fc3
AM
9030 free (aux.symtab);
9031 free ((char *) aux.strtab);
32ec8896
NC
9032
9033 return res;
4d6ed7c8
NC
9034}
9035
3f5e193b 9036struct hppa_unw_table_entry
32ec8896
NC
9037{
9038 struct absaddr start;
9039 struct absaddr end;
9040 unsigned int Cannot_unwind:1; /* 0 */
9041 unsigned int Millicode:1; /* 1 */
9042 unsigned int Millicode_save_sr0:1; /* 2 */
9043 unsigned int Region_description:2; /* 3..4 */
9044 unsigned int reserved1:1; /* 5 */
9045 unsigned int Entry_SR:1; /* 6 */
9046 unsigned int Entry_FR:4; /* Number saved 7..10 */
9047 unsigned int Entry_GR:5; /* Number saved 11..15 */
9048 unsigned int Args_stored:1; /* 16 */
9049 unsigned int Variable_Frame:1; /* 17 */
9050 unsigned int Separate_Package_Body:1; /* 18 */
9051 unsigned int Frame_Extension_Millicode:1; /* 19 */
9052 unsigned int Stack_Overflow_Check:1; /* 20 */
9053 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9054 unsigned int Ada_Region:1; /* 22 */
9055 unsigned int cxx_info:1; /* 23 */
9056 unsigned int cxx_try_catch:1; /* 24 */
9057 unsigned int sched_entry_seq:1; /* 25 */
9058 unsigned int reserved2:1; /* 26 */
9059 unsigned int Save_SP:1; /* 27 */
9060 unsigned int Save_RP:1; /* 28 */
9061 unsigned int Save_MRP_in_frame:1; /* 29 */
9062 unsigned int extn_ptr_defined:1; /* 30 */
9063 unsigned int Cleanup_defined:1; /* 31 */
9064
9065 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9066 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9067 unsigned int Large_frame:1; /* 2 */
9068 unsigned int Pseudo_SP_Set:1; /* 3 */
9069 unsigned int reserved4:1; /* 4 */
9070 unsigned int Total_frame_size:27; /* 5..31 */
9071};
3f5e193b 9072
57346661 9073struct hppa_unw_aux_info
948f632f 9074{
32ec8896
NC
9075 struct hppa_unw_table_entry * table; /* Unwind table. */
9076 unsigned long table_len; /* Length of unwind table. */
9077 bfd_vma seg_base; /* Starting address of segment. */
9078 Elf_Internal_Sym * symtab; /* The symbol table. */
9079 unsigned long nsyms; /* Number of symbols. */
9080 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9081 unsigned long nfuns; /* Number of entries in funtab. */
9082 char * strtab; /* The string table. */
9083 unsigned long strtab_size; /* Size of string table. */
948f632f 9084};
57346661 9085
015dc7e1 9086static bool
dda8d76d 9087dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9088{
2cf0635d 9089 struct hppa_unw_table_entry * tp;
948f632f 9090 unsigned long j, nfuns;
015dc7e1 9091 bool res = true;
948f632f
DA
9092
9093 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9094 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9095 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9096 aux->funtab[nfuns++] = aux->symtab[j];
9097 aux->nfuns = nfuns;
9098 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9099
57346661
AM
9100 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9101 {
9102 bfd_vma offset;
2cf0635d 9103 const char * procname;
57346661 9104
dda8d76d 9105 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9106 aux->strtab_size, tp->start, &procname,
9107 &offset);
9108
9109 fputs ("\n<", stdout);
9110
9111 if (procname)
9112 {
9113 fputs (procname, stdout);
9114
9115 if (offset)
9116 printf ("+%lx", (unsigned long) offset);
9117 }
9118
9119 fputs (">: [", stdout);
9120 print_vma (tp->start.offset, PREFIX_HEX);
9121 fputc ('-', stdout);
9122 print_vma (tp->end.offset, PREFIX_HEX);
9123 printf ("]\n\t");
9124
18bd398b
NC
9125#define PF(_m) if (tp->_m) printf (#_m " ");
9126#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9127 PF(Cannot_unwind);
9128 PF(Millicode);
9129 PF(Millicode_save_sr0);
18bd398b 9130 /* PV(Region_description); */
57346661
AM
9131 PF(Entry_SR);
9132 PV(Entry_FR);
9133 PV(Entry_GR);
9134 PF(Args_stored);
9135 PF(Variable_Frame);
9136 PF(Separate_Package_Body);
9137 PF(Frame_Extension_Millicode);
9138 PF(Stack_Overflow_Check);
9139 PF(Two_Instruction_SP_Increment);
9140 PF(Ada_Region);
9141 PF(cxx_info);
9142 PF(cxx_try_catch);
9143 PF(sched_entry_seq);
9144 PF(Save_SP);
9145 PF(Save_RP);
9146 PF(Save_MRP_in_frame);
9147 PF(extn_ptr_defined);
9148 PF(Cleanup_defined);
9149 PF(MPE_XL_interrupt_marker);
9150 PF(HP_UX_interrupt_marker);
9151 PF(Large_frame);
9152 PF(Pseudo_SP_Set);
9153 PV(Total_frame_size);
9154#undef PF
9155#undef PV
9156 }
9157
18bd398b 9158 printf ("\n");
948f632f
DA
9159
9160 free (aux->funtab);
32ec8896
NC
9161
9162 return res;
57346661
AM
9163}
9164
015dc7e1 9165static bool
dda8d76d
NC
9166slurp_hppa_unwind_table (Filedata * filedata,
9167 struct hppa_unw_aux_info * aux,
9168 Elf_Internal_Shdr * sec)
57346661 9169{
1c0751b2 9170 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9171 Elf_Internal_Phdr * seg;
9172 struct hppa_unw_table_entry * tep;
9173 Elf_Internal_Shdr * relsec;
9174 Elf_Internal_Rela * rela;
9175 Elf_Internal_Rela * rp;
9176 unsigned char * table;
9177 unsigned char * tp;
9178 Elf_Internal_Sym * sym;
9179 const char * relname;
57346661 9180
57346661
AM
9181 /* First, find the starting address of the segment that includes
9182 this section. */
dda8d76d 9183 if (filedata->file_header.e_phnum)
57346661 9184 {
dda8d76d 9185 if (! get_program_headers (filedata))
015dc7e1 9186 return false;
57346661 9187
dda8d76d
NC
9188 for (seg = filedata->program_headers;
9189 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9190 ++seg)
9191 {
9192 if (seg->p_type != PT_LOAD)
9193 continue;
9194
9195 if (sec->sh_addr >= seg->p_vaddr
9196 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9197 {
9198 aux->seg_base = seg->p_vaddr;
9199 break;
9200 }
9201 }
9202 }
9203
9204 /* Second, build the unwind table from the contents of the unwind
9205 section. */
9206 size = sec->sh_size;
dda8d76d 9207 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9208 _("unwind table"));
57346661 9209 if (!table)
015dc7e1 9210 return false;
57346661 9211
1c0751b2
DA
9212 unw_ent_size = 16;
9213 nentries = size / unw_ent_size;
9214 size = unw_ent_size * nentries;
57346661 9215
e3fdc001 9216 aux->table_len = nentries;
3f5e193b
NC
9217 tep = aux->table = (struct hppa_unw_table_entry *)
9218 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9219
1c0751b2 9220 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9221 {
9222 unsigned int tmp1, tmp2;
9223
9224 tep->start.section = SHN_UNDEF;
9225 tep->end.section = SHN_UNDEF;
9226
1c0751b2
DA
9227 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9228 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9229 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9230 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9231
9232 tep->start.offset += aux->seg_base;
9233 tep->end.offset += aux->seg_base;
57346661
AM
9234
9235 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9236 tep->Millicode = (tmp1 >> 30) & 0x1;
9237 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9238 tep->Region_description = (tmp1 >> 27) & 0x3;
9239 tep->reserved1 = (tmp1 >> 26) & 0x1;
9240 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9241 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9242 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9243 tep->Args_stored = (tmp1 >> 15) & 0x1;
9244 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9245 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9246 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9247 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9248 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9249 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9250 tep->cxx_info = (tmp1 >> 8) & 0x1;
9251 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9252 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9253 tep->reserved2 = (tmp1 >> 5) & 0x1;
9254 tep->Save_SP = (tmp1 >> 4) & 0x1;
9255 tep->Save_RP = (tmp1 >> 3) & 0x1;
9256 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9257 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9258 tep->Cleanup_defined = tmp1 & 0x1;
9259
9260 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9261 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9262 tep->Large_frame = (tmp2 >> 29) & 0x1;
9263 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9264 tep->reserved4 = (tmp2 >> 27) & 0x1;
9265 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9266 }
9267 free (table);
9268
9269 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9270 for (relsec = filedata->section_headers;
9271 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9272 ++relsec)
9273 {
9274 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9275 || relsec->sh_info >= filedata->file_header.e_shnum
9276 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9277 continue;
9278
dda8d76d 9279 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9280 & rela, & nrelas))
015dc7e1 9281 return false;
57346661
AM
9282
9283 for (rp = rela; rp < rela + nrelas; ++rp)
9284 {
4770fb94 9285 unsigned int sym_ndx;
726bd37d
AM
9286 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9287 relname = elf_hppa_reloc_type (r_type);
57346661 9288
726bd37d
AM
9289 if (relname == NULL)
9290 {
9291 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9292 continue;
9293 }
9294
57346661 9295 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9296 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9297 {
726bd37d 9298 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9299 continue;
9300 }
9301
9302 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9303 if (i >= aux->table_len)
9304 {
9305 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9306 continue;
9307 }
57346661 9308
4770fb94
AM
9309 sym_ndx = get_reloc_symindex (rp->r_info);
9310 if (sym_ndx >= aux->nsyms)
9311 {
9312 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9313 sym_ndx);
9314 continue;
9315 }
9316 sym = aux->symtab + sym_ndx;
9317
43f6cd05 9318 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9319 {
9320 case 0:
9321 aux->table[i].start.section = sym->st_shndx;
1e456d54 9322 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9323 break;
9324 case 1:
9325 aux->table[i].end.section = sym->st_shndx;
1e456d54 9326 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9327 break;
9328 default:
9329 break;
9330 }
9331 }
9332
9333 free (rela);
9334 }
9335
015dc7e1 9336 return true;
57346661
AM
9337}
9338
015dc7e1 9339static bool
dda8d76d 9340hppa_process_unwind (Filedata * filedata)
57346661 9341{
57346661 9342 struct hppa_unw_aux_info aux;
2cf0635d 9343 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9344 Elf_Internal_Shdr * sec;
18bd398b 9345 unsigned long i;
015dc7e1 9346 bool res = true;
57346661 9347
dda8d76d 9348 if (filedata->string_table == NULL)
015dc7e1 9349 return false;
1b31d05e
NC
9350
9351 memset (& aux, 0, sizeof (aux));
57346661 9352
dda8d76d 9353 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9354 {
28d13567 9355 if (sec->sh_type == SHT_SYMTAB)
57346661 9356 {
28d13567 9357 if (aux.symtab)
4082ef84 9358 {
28d13567
AM
9359 error (_("Multiple symbol tables encountered\n"));
9360 free (aux.symtab);
9361 aux.symtab = NULL;
4082ef84 9362 free (aux.strtab);
28d13567 9363 aux.strtab = NULL;
4082ef84 9364 }
28d13567
AM
9365 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9366 &aux.strtab, &aux.strtab_size))
015dc7e1 9367 return false;
57346661 9368 }
84714f86
AM
9369 else if (section_name_valid (filedata, sec)
9370 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9371 unwsec = sec;
9372 }
9373
9374 if (!unwsec)
9375 printf (_("\nThere are no unwind sections in this file.\n"));
9376
dda8d76d 9377 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9378 {
84714f86
AM
9379 if (section_name_valid (filedata, sec)
9380 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9381 {
43f6cd05 9382 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9383
d3a49aa8
AM
9384 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9385 "contains %lu entry:\n",
9386 "\nUnwind section '%s' at offset 0x%lx "
9387 "contains %lu entries:\n",
9388 num_unwind),
dda8d76d 9389 printable_section_name (filedata, sec),
57346661 9390 (unsigned long) sec->sh_offset,
d3a49aa8 9391 num_unwind);
57346661 9392
dda8d76d 9393 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9394 res = false;
66b09c7e
S
9395
9396 if (res && aux.table_len > 0)
32ec8896 9397 {
dda8d76d 9398 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9399 res = false;
32ec8896 9400 }
57346661 9401
9db70fc3 9402 free ((char *) aux.table);
57346661
AM
9403 aux.table = NULL;
9404 }
9405 }
9406
9db70fc3
AM
9407 free (aux.symtab);
9408 free ((char *) aux.strtab);
32ec8896
NC
9409
9410 return res;
57346661
AM
9411}
9412
0b6ae522
DJ
9413struct arm_section
9414{
a734115a
NC
9415 unsigned char * data; /* The unwind data. */
9416 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9417 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9418 unsigned long nrelas; /* The number of relocations. */
9419 unsigned int rel_type; /* REL or RELA ? */
9420 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9421};
9422
9423struct arm_unw_aux_info
9424{
dda8d76d 9425 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9426 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9427 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9428 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9429 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9430 char * strtab; /* The file's string table. */
9431 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9432};
9433
9434static const char *
dda8d76d
NC
9435arm_print_vma_and_name (Filedata * filedata,
9436 struct arm_unw_aux_info * aux,
9437 bfd_vma fn,
9438 struct absaddr addr)
0b6ae522
DJ
9439{
9440 const char *procname;
9441 bfd_vma sym_offset;
9442
9443 if (addr.section == SHN_UNDEF)
9444 addr.offset = fn;
9445
dda8d76d 9446 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9447 aux->strtab_size, addr, &procname,
9448 &sym_offset);
9449
9450 print_vma (fn, PREFIX_HEX);
9451
9452 if (procname)
9453 {
9454 fputs (" <", stdout);
9455 fputs (procname, stdout);
9456
9457 if (sym_offset)
9458 printf ("+0x%lx", (unsigned long) sym_offset);
9459 fputc ('>', stdout);
9460 }
9461
9462 return procname;
9463}
9464
9465static void
9466arm_free_section (struct arm_section *arm_sec)
9467{
9db70fc3
AM
9468 free (arm_sec->data);
9469 free (arm_sec->rela);
0b6ae522
DJ
9470}
9471
a734115a
NC
9472/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9473 cached section and install SEC instead.
9474 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9475 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9476 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9477 relocation's offset in ADDR.
1b31d05e
NC
9478 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9479 into the string table of the symbol associated with the reloc. If no
9480 reloc was applied store -1 there.
9481 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9482
015dc7e1 9483static bool
dda8d76d
NC
9484get_unwind_section_word (Filedata * filedata,
9485 struct arm_unw_aux_info * aux,
1b31d05e
NC
9486 struct arm_section * arm_sec,
9487 Elf_Internal_Shdr * sec,
9488 bfd_vma word_offset,
9489 unsigned int * wordp,
9490 struct absaddr * addr,
9491 bfd_vma * sym_name)
0b6ae522
DJ
9492{
9493 Elf_Internal_Rela *rp;
9494 Elf_Internal_Sym *sym;
9495 const char * relname;
9496 unsigned int word;
015dc7e1 9497 bool wrapped;
0b6ae522 9498
e0a31db1 9499 if (sec == NULL || arm_sec == NULL)
015dc7e1 9500 return false;
e0a31db1 9501
0b6ae522
DJ
9502 addr->section = SHN_UNDEF;
9503 addr->offset = 0;
9504
1b31d05e
NC
9505 if (sym_name != NULL)
9506 *sym_name = (bfd_vma) -1;
9507
a734115a 9508 /* If necessary, update the section cache. */
0b6ae522
DJ
9509 if (sec != arm_sec->sec)
9510 {
9511 Elf_Internal_Shdr *relsec;
9512
9513 arm_free_section (arm_sec);
9514
9515 arm_sec->sec = sec;
dda8d76d 9516 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9517 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9518 arm_sec->rela = NULL;
9519 arm_sec->nrelas = 0;
9520
dda8d76d
NC
9521 for (relsec = filedata->section_headers;
9522 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9523 ++relsec)
9524 {
dda8d76d
NC
9525 if (relsec->sh_info >= filedata->file_header.e_shnum
9526 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9527 /* PR 15745: Check the section type as well. */
9528 || (relsec->sh_type != SHT_REL
9529 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9530 continue;
9531
a734115a 9532 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9533 if (relsec->sh_type == SHT_REL)
9534 {
dda8d76d 9535 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9536 relsec->sh_size,
9537 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9538 return false;
0b6ae522 9539 }
1ae40aa4 9540 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9541 {
dda8d76d 9542 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9543 relsec->sh_size,
9544 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9545 return false;
0b6ae522 9546 }
1ae40aa4 9547 break;
0b6ae522
DJ
9548 }
9549
9550 arm_sec->next_rela = arm_sec->rela;
9551 }
9552
a734115a 9553 /* If there is no unwind data we can do nothing. */
0b6ae522 9554 if (arm_sec->data == NULL)
015dc7e1 9555 return false;
0b6ae522 9556
e0a31db1 9557 /* If the offset is invalid then fail. */
f32ba729
NC
9558 if (/* PR 21343 *//* PR 18879 */
9559 sec->sh_size < 4
9560 || word_offset > (sec->sh_size - 4)
1a915552 9561 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9562 return false;
e0a31db1 9563
a734115a 9564 /* Get the word at the required offset. */
0b6ae522
DJ
9565 word = byte_get (arm_sec->data + word_offset, 4);
9566
0eff7165
NC
9567 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9568 if (arm_sec->rela == NULL)
9569 {
9570 * wordp = word;
015dc7e1 9571 return true;
0eff7165
NC
9572 }
9573
a734115a 9574 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9575 wrapped = false;
0b6ae522
DJ
9576 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9577 {
9578 bfd_vma prelval, offset;
9579
9580 if (rp->r_offset > word_offset && !wrapped)
9581 {
9582 rp = arm_sec->rela;
015dc7e1 9583 wrapped = true;
0b6ae522
DJ
9584 }
9585 if (rp->r_offset > word_offset)
9586 break;
9587
9588 if (rp->r_offset & 3)
9589 {
9590 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9591 (unsigned long) rp->r_offset);
9592 continue;
9593 }
9594
9595 if (rp->r_offset < word_offset)
9596 continue;
9597
74e1a04b
NC
9598 /* PR 17531: file: 027-161405-0.004 */
9599 if (aux->symtab == NULL)
9600 continue;
9601
0b6ae522
DJ
9602 if (arm_sec->rel_type == SHT_REL)
9603 {
9604 offset = word & 0x7fffffff;
9605 if (offset & 0x40000000)
9606 offset |= ~ (bfd_vma) 0x7fffffff;
9607 }
a734115a 9608 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9609 offset = rp->r_addend;
a734115a 9610 else
74e1a04b
NC
9611 {
9612 error (_("Unknown section relocation type %d encountered\n"),
9613 arm_sec->rel_type);
9614 break;
9615 }
0b6ae522 9616
071436c6
NC
9617 /* PR 17531 file: 027-1241568-0.004. */
9618 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9619 {
9620 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9621 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9622 break;
9623 }
9624
9625 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9626 offset += sym->st_value;
9627 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9628
a734115a 9629 /* Check that we are processing the expected reloc type. */
dda8d76d 9630 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9631 {
9632 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9633 if (relname == NULL)
9634 {
9635 warn (_("Skipping unknown ARM relocation type: %d\n"),
9636 (int) ELF32_R_TYPE (rp->r_info));
9637 continue;
9638 }
a734115a
NC
9639
9640 if (streq (relname, "R_ARM_NONE"))
9641 continue;
0b4362b0 9642
a734115a
NC
9643 if (! streq (relname, "R_ARM_PREL31"))
9644 {
071436c6 9645 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9646 continue;
9647 }
9648 }
dda8d76d 9649 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9650 {
9651 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9652 if (relname == NULL)
9653 {
9654 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9655 (int) ELF32_R_TYPE (rp->r_info));
9656 continue;
9657 }
0b4362b0 9658
a734115a
NC
9659 if (streq (relname, "R_C6000_NONE"))
9660 continue;
9661
9662 if (! streq (relname, "R_C6000_PREL31"))
9663 {
071436c6 9664 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9665 continue;
9666 }
9667
9668 prelval >>= 1;
9669 }
9670 else
74e1a04b
NC
9671 {
9672 /* This function currently only supports ARM and TI unwinders. */
9673 warn (_("Only TI and ARM unwinders are currently supported\n"));
9674 break;
9675 }
fa197c1c 9676
0b6ae522
DJ
9677 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9678 addr->section = sym->st_shndx;
9679 addr->offset = offset;
74e1a04b 9680
1b31d05e
NC
9681 if (sym_name)
9682 * sym_name = sym->st_name;
0b6ae522
DJ
9683 break;
9684 }
9685
9686 *wordp = word;
9687 arm_sec->next_rela = rp;
9688
015dc7e1 9689 return true;
0b6ae522
DJ
9690}
9691
a734115a
NC
9692static const char *tic6x_unwind_regnames[16] =
9693{
0b4362b0
RM
9694 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9695 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9696 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9697};
fa197c1c 9698
0b6ae522 9699static void
fa197c1c 9700decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9701{
fa197c1c
PB
9702 int i;
9703
9704 for (i = 12; mask; mask >>= 1, i--)
9705 {
9706 if (mask & 1)
9707 {
9708 fputs (tic6x_unwind_regnames[i], stdout);
9709 if (mask > 1)
9710 fputs (", ", stdout);
9711 }
9712 }
9713}
0b6ae522
DJ
9714
9715#define ADVANCE \
9716 if (remaining == 0 && more_words) \
9717 { \
9718 data_offset += 4; \
dda8d76d 9719 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9720 data_offset, & word, & addr, NULL)) \
015dc7e1 9721 return false; \
0b6ae522
DJ
9722 remaining = 4; \
9723 more_words--; \
9724 } \
9725
9726#define GET_OP(OP) \
9727 ADVANCE; \
9728 if (remaining) \
9729 { \
9730 remaining--; \
9731 (OP) = word >> 24; \
9732 word <<= 8; \
9733 } \
9734 else \
9735 { \
2b692964 9736 printf (_("[Truncated opcode]\n")); \
015dc7e1 9737 return false; \
0b6ae522 9738 } \
cc5914eb 9739 printf ("0x%02x ", OP)
0b6ae522 9740
015dc7e1 9741static bool
dda8d76d
NC
9742decode_arm_unwind_bytecode (Filedata * filedata,
9743 struct arm_unw_aux_info * aux,
948f632f
DA
9744 unsigned int word,
9745 unsigned int remaining,
9746 unsigned int more_words,
9747 bfd_vma data_offset,
9748 Elf_Internal_Shdr * data_sec,
9749 struct arm_section * data_arm_sec)
fa197c1c
PB
9750{
9751 struct absaddr addr;
015dc7e1 9752 bool res = true;
0b6ae522
DJ
9753
9754 /* Decode the unwinding instructions. */
9755 while (1)
9756 {
9757 unsigned int op, op2;
9758
9759 ADVANCE;
9760 if (remaining == 0)
9761 break;
9762 remaining--;
9763 op = word >> 24;
9764 word <<= 8;
9765
cc5914eb 9766 printf (" 0x%02x ", op);
0b6ae522
DJ
9767
9768 if ((op & 0xc0) == 0x00)
9769 {
9770 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9771
cc5914eb 9772 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9773 }
9774 else if ((op & 0xc0) == 0x40)
9775 {
9776 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9777
cc5914eb 9778 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9779 }
9780 else if ((op & 0xf0) == 0x80)
9781 {
9782 GET_OP (op2);
9783 if (op == 0x80 && op2 == 0)
9784 printf (_("Refuse to unwind"));
9785 else
9786 {
9787 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9788 bool first = true;
0b6ae522 9789 int i;
2b692964 9790
0b6ae522
DJ
9791 printf ("pop {");
9792 for (i = 0; i < 12; i++)
9793 if (mask & (1 << i))
9794 {
9795 if (first)
015dc7e1 9796 first = false;
0b6ae522
DJ
9797 else
9798 printf (", ");
9799 printf ("r%d", 4 + i);
9800 }
9801 printf ("}");
9802 }
9803 }
9804 else if ((op & 0xf0) == 0x90)
9805 {
9806 if (op == 0x9d || op == 0x9f)
9807 printf (_(" [Reserved]"));
9808 else
cc5914eb 9809 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9810 }
9811 else if ((op & 0xf0) == 0xa0)
9812 {
9813 int end = 4 + (op & 0x07);
015dc7e1 9814 bool first = true;
0b6ae522 9815 int i;
61865e30 9816
0b6ae522
DJ
9817 printf (" pop {");
9818 for (i = 4; i <= end; i++)
9819 {
9820 if (first)
015dc7e1 9821 first = false;
0b6ae522
DJ
9822 else
9823 printf (", ");
9824 printf ("r%d", i);
9825 }
9826 if (op & 0x08)
9827 {
1b31d05e 9828 if (!first)
0b6ae522
DJ
9829 printf (", ");
9830 printf ("r14");
9831 }
9832 printf ("}");
9833 }
9834 else if (op == 0xb0)
9835 printf (_(" finish"));
9836 else if (op == 0xb1)
9837 {
9838 GET_OP (op2);
9839 if (op2 == 0 || (op2 & 0xf0) != 0)
9840 printf (_("[Spare]"));
9841 else
9842 {
9843 unsigned int mask = op2 & 0x0f;
015dc7e1 9844 bool first = true;
0b6ae522 9845 int i;
61865e30 9846
0b6ae522
DJ
9847 printf ("pop {");
9848 for (i = 0; i < 12; i++)
9849 if (mask & (1 << i))
9850 {
9851 if (first)
015dc7e1 9852 first = false;
0b6ae522
DJ
9853 else
9854 printf (", ");
9855 printf ("r%d", i);
9856 }
9857 printf ("}");
9858 }
9859 }
9860 else if (op == 0xb2)
9861 {
b115cf96 9862 unsigned char buf[9];
0b6ae522
DJ
9863 unsigned int i, len;
9864 unsigned long offset;
61865e30 9865
b115cf96 9866 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9867 {
9868 GET_OP (buf[i]);
9869 if ((buf[i] & 0x80) == 0)
9870 break;
9871 }
4082ef84 9872 if (i == sizeof (buf))
32ec8896 9873 {
27a45f42 9874 error (_("corrupt change to vsp\n"));
015dc7e1 9875 res = false;
32ec8896 9876 }
4082ef84
NC
9877 else
9878 {
015dc7e1 9879 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9880 assert (len == i + 1);
9881 offset = offset * 4 + 0x204;
9882 printf ("vsp = vsp + %ld", offset);
9883 }
0b6ae522 9884 }
61865e30 9885 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9886 {
61865e30
NC
9887 unsigned int first, last;
9888
9889 GET_OP (op2);
9890 first = op2 >> 4;
9891 last = op2 & 0x0f;
9892 if (op == 0xc8)
9893 first = first + 16;
9894 printf ("pop {D%d", first);
9895 if (last)
9896 printf ("-D%d", first + last);
9897 printf ("}");
9898 }
09854a88
TB
9899 else if (op == 0xb4)
9900 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9901 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9902 {
9903 unsigned int count = op & 0x07;
9904
9905 printf ("pop {D8");
9906 if (count)
9907 printf ("-D%d", 8 + count);
9908 printf ("}");
9909 }
9910 else if (op >= 0xc0 && op <= 0xc5)
9911 {
9912 unsigned int count = op & 0x07;
9913
9914 printf (" pop {wR10");
9915 if (count)
9916 printf ("-wR%d", 10 + count);
9917 printf ("}");
9918 }
9919 else if (op == 0xc6)
9920 {
9921 unsigned int first, last;
9922
9923 GET_OP (op2);
9924 first = op2 >> 4;
9925 last = op2 & 0x0f;
9926 printf ("pop {wR%d", first);
9927 if (last)
9928 printf ("-wR%d", first + last);
9929 printf ("}");
9930 }
9931 else if (op == 0xc7)
9932 {
9933 GET_OP (op2);
9934 if (op2 == 0 || (op2 & 0xf0) != 0)
9935 printf (_("[Spare]"));
0b6ae522
DJ
9936 else
9937 {
61865e30 9938 unsigned int mask = op2 & 0x0f;
015dc7e1 9939 bool first = true;
61865e30
NC
9940 int i;
9941
9942 printf ("pop {");
9943 for (i = 0; i < 4; i++)
9944 if (mask & (1 << i))
9945 {
9946 if (first)
015dc7e1 9947 first = false;
61865e30
NC
9948 else
9949 printf (", ");
9950 printf ("wCGR%d", i);
9951 }
9952 printf ("}");
0b6ae522
DJ
9953 }
9954 }
61865e30 9955 else
32ec8896
NC
9956 {
9957 printf (_(" [unsupported opcode]"));
015dc7e1 9958 res = false;
32ec8896
NC
9959 }
9960
0b6ae522
DJ
9961 printf ("\n");
9962 }
32ec8896
NC
9963
9964 return res;
fa197c1c
PB
9965}
9966
015dc7e1 9967static bool
dda8d76d
NC
9968decode_tic6x_unwind_bytecode (Filedata * filedata,
9969 struct arm_unw_aux_info * aux,
948f632f
DA
9970 unsigned int word,
9971 unsigned int remaining,
9972 unsigned int more_words,
9973 bfd_vma data_offset,
9974 Elf_Internal_Shdr * data_sec,
9975 struct arm_section * data_arm_sec)
fa197c1c
PB
9976{
9977 struct absaddr addr;
9978
9979 /* Decode the unwinding instructions. */
9980 while (1)
9981 {
9982 unsigned int op, op2;
9983
9984 ADVANCE;
9985 if (remaining == 0)
9986 break;
9987 remaining--;
9988 op = word >> 24;
9989 word <<= 8;
9990
9cf03b7e 9991 printf (" 0x%02x ", op);
fa197c1c
PB
9992
9993 if ((op & 0xc0) == 0x00)
9994 {
9995 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9996 printf (" sp = sp + %d", offset);
fa197c1c
PB
9997 }
9998 else if ((op & 0xc0) == 0x80)
9999 {
10000 GET_OP (op2);
10001 if (op == 0x80 && op2 == 0)
10002 printf (_("Refuse to unwind"));
10003 else
10004 {
10005 unsigned int mask = ((op & 0x1f) << 8) | op2;
10006 if (op & 0x20)
10007 printf ("pop compact {");
10008 else
10009 printf ("pop {");
10010
10011 decode_tic6x_unwind_regmask (mask);
10012 printf("}");
10013 }
10014 }
10015 else if ((op & 0xf0) == 0xc0)
10016 {
10017 unsigned int reg;
10018 unsigned int nregs;
10019 unsigned int i;
10020 const char *name;
a734115a
NC
10021 struct
10022 {
32ec8896
NC
10023 unsigned int offset;
10024 unsigned int reg;
fa197c1c
PB
10025 } regpos[16];
10026
10027 /* Scan entire instruction first so that GET_OP output is not
10028 interleaved with disassembly. */
10029 nregs = 0;
10030 for (i = 0; nregs < (op & 0xf); i++)
10031 {
10032 GET_OP (op2);
10033 reg = op2 >> 4;
10034 if (reg != 0xf)
10035 {
10036 regpos[nregs].offset = i * 2;
10037 regpos[nregs].reg = reg;
10038 nregs++;
10039 }
10040
10041 reg = op2 & 0xf;
10042 if (reg != 0xf)
10043 {
10044 regpos[nregs].offset = i * 2 + 1;
10045 regpos[nregs].reg = reg;
10046 nregs++;
10047 }
10048 }
10049
10050 printf (_("pop frame {"));
18344509 10051 if (nregs == 0)
fa197c1c 10052 {
18344509
NC
10053 printf (_("*corrupt* - no registers specified"));
10054 }
10055 else
10056 {
10057 reg = nregs - 1;
10058 for (i = i * 2; i > 0; i--)
fa197c1c 10059 {
18344509
NC
10060 if (regpos[reg].offset == i - 1)
10061 {
10062 name = tic6x_unwind_regnames[regpos[reg].reg];
10063 if (reg > 0)
10064 reg--;
10065 }
10066 else
10067 name = _("[pad]");
fa197c1c 10068
18344509
NC
10069 fputs (name, stdout);
10070 if (i > 1)
10071 printf (", ");
10072 }
fa197c1c
PB
10073 }
10074
10075 printf ("}");
10076 }
10077 else if (op == 0xd0)
10078 printf (" MOV FP, SP");
10079 else if (op == 0xd1)
10080 printf (" __c6xabi_pop_rts");
10081 else if (op == 0xd2)
10082 {
10083 unsigned char buf[9];
10084 unsigned int i, len;
10085 unsigned long offset;
a734115a 10086
fa197c1c
PB
10087 for (i = 0; i < sizeof (buf); i++)
10088 {
10089 GET_OP (buf[i]);
10090 if ((buf[i] & 0x80) == 0)
10091 break;
10092 }
0eff7165
NC
10093 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10094 if (i == sizeof (buf))
10095 {
0eff7165 10096 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10097 return false;
0eff7165 10098 }
948f632f 10099
015dc7e1 10100 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10101 assert (len == i + 1);
10102 offset = offset * 8 + 0x408;
10103 printf (_("sp = sp + %ld"), offset);
10104 }
10105 else if ((op & 0xf0) == 0xe0)
10106 {
10107 if ((op & 0x0f) == 7)
10108 printf (" RETURN");
10109 else
10110 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10111 }
10112 else
10113 {
10114 printf (_(" [unsupported opcode]"));
10115 }
10116 putchar ('\n');
10117 }
32ec8896 10118
015dc7e1 10119 return true;
fa197c1c
PB
10120}
10121
10122static bfd_vma
dda8d76d 10123arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
10124{
10125 bfd_vma offset;
10126
10127 offset = word & 0x7fffffff;
10128 if (offset & 0x40000000)
10129 offset |= ~ (bfd_vma) 0x7fffffff;
10130
dda8d76d 10131 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10132 offset <<= 1;
10133
10134 return offset + where;
10135}
10136
015dc7e1 10137static bool
dda8d76d
NC
10138decode_arm_unwind (Filedata * filedata,
10139 struct arm_unw_aux_info * aux,
1b31d05e
NC
10140 unsigned int word,
10141 unsigned int remaining,
10142 bfd_vma data_offset,
10143 Elf_Internal_Shdr * data_sec,
10144 struct arm_section * data_arm_sec)
fa197c1c
PB
10145{
10146 int per_index;
10147 unsigned int more_words = 0;
37e14bc3 10148 struct absaddr addr;
1b31d05e 10149 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 10150 bool res = true;
fa197c1c
PB
10151
10152 if (remaining == 0)
10153 {
1b31d05e
NC
10154 /* Fetch the first word.
10155 Note - when decoding an object file the address extracted
10156 here will always be 0. So we also pass in the sym_name
10157 parameter so that we can find the symbol associated with
10158 the personality routine. */
dda8d76d 10159 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10160 & word, & addr, & sym_name))
015dc7e1 10161 return false;
1b31d05e 10162
fa197c1c
PB
10163 remaining = 4;
10164 }
c93dbb25
CZ
10165 else
10166 {
10167 addr.section = SHN_UNDEF;
10168 addr.offset = 0;
10169 }
fa197c1c
PB
10170
10171 if ((word & 0x80000000) == 0)
10172 {
10173 /* Expand prel31 for personality routine. */
10174 bfd_vma fn;
10175 const char *procname;
10176
dda8d76d 10177 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10178 printf (_(" Personality routine: "));
1b31d05e
NC
10179 if (fn == 0
10180 && addr.section == SHN_UNDEF && addr.offset == 0
10181 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10182 {
10183 procname = aux->strtab + sym_name;
10184 print_vma (fn, PREFIX_HEX);
10185 if (procname)
10186 {
10187 fputs (" <", stdout);
10188 fputs (procname, stdout);
10189 fputc ('>', stdout);
10190 }
10191 }
10192 else
dda8d76d 10193 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10194 fputc ('\n', stdout);
10195
10196 /* The GCC personality routines use the standard compact
10197 encoding, starting with one byte giving the number of
10198 words. */
10199 if (procname != NULL
24d127aa
ML
10200 && (startswith (procname, "__gcc_personality_v0")
10201 || startswith (procname, "__gxx_personality_v0")
10202 || startswith (procname, "__gcj_personality_v0")
10203 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10204 {
10205 remaining = 0;
10206 more_words = 1;
10207 ADVANCE;
10208 if (!remaining)
10209 {
10210 printf (_(" [Truncated data]\n"));
015dc7e1 10211 return false;
fa197c1c
PB
10212 }
10213 more_words = word >> 24;
10214 word <<= 8;
10215 remaining--;
10216 per_index = -1;
10217 }
10218 else
015dc7e1 10219 return true;
fa197c1c
PB
10220 }
10221 else
10222 {
1b31d05e 10223 /* ARM EHABI Section 6.3:
0b4362b0 10224
1b31d05e 10225 An exception-handling table entry for the compact model looks like:
0b4362b0 10226
1b31d05e
NC
10227 31 30-28 27-24 23-0
10228 -- ----- ----- ----
10229 1 0 index Data for personalityRoutine[index] */
10230
dda8d76d 10231 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10232 && (word & 0x70000000))
32ec8896
NC
10233 {
10234 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10235 res = false;
32ec8896 10236 }
1b31d05e 10237
fa197c1c 10238 per_index = (word >> 24) & 0x7f;
1b31d05e 10239 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10240 if (per_index == 0)
10241 {
10242 more_words = 0;
10243 word <<= 8;
10244 remaining--;
10245 }
10246 else if (per_index < 3)
10247 {
10248 more_words = (word >> 16) & 0xff;
10249 word <<= 16;
10250 remaining -= 2;
10251 }
10252 }
10253
dda8d76d 10254 switch (filedata->file_header.e_machine)
fa197c1c
PB
10255 {
10256 case EM_ARM:
10257 if (per_index < 3)
10258 {
dda8d76d 10259 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10260 data_offset, data_sec, data_arm_sec))
015dc7e1 10261 res = false;
fa197c1c
PB
10262 }
10263 else
1b31d05e
NC
10264 {
10265 warn (_("Unknown ARM compact model index encountered\n"));
10266 printf (_(" [reserved]\n"));
015dc7e1 10267 res = false;
1b31d05e 10268 }
fa197c1c
PB
10269 break;
10270
10271 case EM_TI_C6000:
10272 if (per_index < 3)
10273 {
dda8d76d 10274 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10275 data_offset, data_sec, data_arm_sec))
015dc7e1 10276 res = false;
fa197c1c
PB
10277 }
10278 else if (per_index < 5)
10279 {
10280 if (((word >> 17) & 0x7f) == 0x7f)
10281 printf (_(" Restore stack from frame pointer\n"));
10282 else
10283 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10284 printf (_(" Registers restored: "));
10285 if (per_index == 4)
10286 printf (" (compact) ");
10287 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10288 putchar ('\n');
10289 printf (_(" Return register: %s\n"),
10290 tic6x_unwind_regnames[word & 0xf]);
10291 }
10292 else
1b31d05e 10293 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10294 break;
10295
10296 default:
74e1a04b 10297 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10298 filedata->file_header.e_machine);
015dc7e1 10299 res = false;
fa197c1c 10300 }
0b6ae522
DJ
10301
10302 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10303
10304 return res;
0b6ae522
DJ
10305}
10306
015dc7e1 10307static bool
dda8d76d
NC
10308dump_arm_unwind (Filedata * filedata,
10309 struct arm_unw_aux_info * aux,
10310 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10311{
10312 struct arm_section exidx_arm_sec, extab_arm_sec;
10313 unsigned int i, exidx_len;
948f632f 10314 unsigned long j, nfuns;
015dc7e1 10315 bool res = true;
0b6ae522
DJ
10316
10317 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10318 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10319 exidx_len = exidx_sec->sh_size / 8;
10320
948f632f
DA
10321 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10322 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10323 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10324 aux->funtab[nfuns++] = aux->symtab[j];
10325 aux->nfuns = nfuns;
10326 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10327
0b6ae522
DJ
10328 for (i = 0; i < exidx_len; i++)
10329 {
10330 unsigned int exidx_fn, exidx_entry;
10331 struct absaddr fn_addr, entry_addr;
10332 bfd_vma fn;
10333
10334 fputc ('\n', stdout);
10335
dda8d76d 10336 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10337 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10338 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10339 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10340 {
948f632f 10341 free (aux->funtab);
1b31d05e
NC
10342 arm_free_section (& exidx_arm_sec);
10343 arm_free_section (& extab_arm_sec);
015dc7e1 10344 return false;
0b6ae522
DJ
10345 }
10346
83c257ca
NC
10347 /* ARM EHABI, Section 5:
10348 An index table entry consists of 2 words.
10349 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10350 if (exidx_fn & 0x80000000)
32ec8896
NC
10351 {
10352 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10353 res = false;
32ec8896 10354 }
83c257ca 10355
dda8d76d 10356 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10357
dda8d76d 10358 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10359 fputs (": ", stdout);
10360
10361 if (exidx_entry == 1)
10362 {
10363 print_vma (exidx_entry, PREFIX_HEX);
10364 fputs (" [cantunwind]\n", stdout);
10365 }
10366 else if (exidx_entry & 0x80000000)
10367 {
10368 print_vma (exidx_entry, PREFIX_HEX);
10369 fputc ('\n', stdout);
dda8d76d 10370 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10371 }
10372 else
10373 {
8f73510c 10374 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10375 Elf_Internal_Shdr *table_sec;
10376
10377 fputs ("@", stdout);
dda8d76d 10378 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10379 print_vma (table, PREFIX_HEX);
10380 printf ("\n");
10381
10382 /* Locate the matching .ARM.extab. */
10383 if (entry_addr.section != SHN_UNDEF
dda8d76d 10384 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10385 {
dda8d76d 10386 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10387 table_offset = entry_addr.offset;
1a915552
NC
10388 /* PR 18879 */
10389 if (table_offset > table_sec->sh_size
10390 || ((bfd_signed_vma) table_offset) < 0)
10391 {
10392 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10393 (unsigned long) table_offset,
dda8d76d 10394 printable_section_name (filedata, table_sec));
015dc7e1 10395 res = false;
1a915552
NC
10396 continue;
10397 }
0b6ae522
DJ
10398 }
10399 else
10400 {
dda8d76d 10401 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10402 if (table_sec != NULL)
10403 table_offset = table - table_sec->sh_addr;
10404 }
32ec8896 10405
0b6ae522
DJ
10406 if (table_sec == NULL)
10407 {
10408 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10409 (unsigned long) table);
015dc7e1 10410 res = false;
0b6ae522
DJ
10411 continue;
10412 }
32ec8896 10413
dda8d76d 10414 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10415 &extab_arm_sec))
015dc7e1 10416 res = false;
0b6ae522
DJ
10417 }
10418 }
10419
10420 printf ("\n");
10421
948f632f 10422 free (aux->funtab);
0b6ae522
DJ
10423 arm_free_section (&exidx_arm_sec);
10424 arm_free_section (&extab_arm_sec);
32ec8896
NC
10425
10426 return res;
0b6ae522
DJ
10427}
10428
fa197c1c 10429/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10430
015dc7e1 10431static bool
dda8d76d 10432arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10433{
10434 struct arm_unw_aux_info aux;
10435 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10436 Elf_Internal_Shdr *sec;
10437 unsigned long i;
fa197c1c 10438 unsigned int sec_type;
015dc7e1 10439 bool res = true;
0b6ae522 10440
dda8d76d 10441 switch (filedata->file_header.e_machine)
fa197c1c
PB
10442 {
10443 case EM_ARM:
10444 sec_type = SHT_ARM_EXIDX;
10445 break;
10446
10447 case EM_TI_C6000:
10448 sec_type = SHT_C6000_UNWIND;
10449 break;
10450
0b4362b0 10451 default:
74e1a04b 10452 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10453 filedata->file_header.e_machine);
015dc7e1 10454 return false;
fa197c1c
PB
10455 }
10456
dda8d76d 10457 if (filedata->string_table == NULL)
015dc7e1 10458 return false;
1b31d05e
NC
10459
10460 memset (& aux, 0, sizeof (aux));
dda8d76d 10461 aux.filedata = filedata;
0b6ae522 10462
dda8d76d 10463 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10464 {
28d13567 10465 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10466 {
28d13567 10467 if (aux.symtab)
74e1a04b 10468 {
28d13567
AM
10469 error (_("Multiple symbol tables encountered\n"));
10470 free (aux.symtab);
10471 aux.symtab = NULL;
74e1a04b 10472 free (aux.strtab);
28d13567 10473 aux.strtab = NULL;
74e1a04b 10474 }
28d13567
AM
10475 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10476 &aux.strtab, &aux.strtab_size))
015dc7e1 10477 return false;
0b6ae522 10478 }
fa197c1c 10479 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10480 unwsec = sec;
10481 }
10482
1b31d05e 10483 if (unwsec == NULL)
0b6ae522 10484 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10485 else
dda8d76d 10486 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10487 {
10488 if (sec->sh_type == sec_type)
10489 {
d3a49aa8
AM
10490 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10491 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10492 "contains %lu entry:\n",
10493 "\nUnwind section '%s' at offset 0x%lx "
10494 "contains %lu entries:\n",
10495 num_unwind),
dda8d76d 10496 printable_section_name (filedata, sec),
1b31d05e 10497 (unsigned long) sec->sh_offset,
d3a49aa8 10498 num_unwind);
0b6ae522 10499
dda8d76d 10500 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10501 res = false;
1b31d05e
NC
10502 }
10503 }
0b6ae522 10504
9db70fc3
AM
10505 free (aux.symtab);
10506 free ((char *) aux.strtab);
32ec8896
NC
10507
10508 return res;
0b6ae522
DJ
10509}
10510
3ecc00ec
NC
10511static bool
10512no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10513{
10514 printf (_("No processor specific unwind information to decode\n"));
10515 return true;
10516}
10517
015dc7e1 10518static bool
dda8d76d 10519process_unwind (Filedata * filedata)
57346661 10520{
2cf0635d
NC
10521 struct unwind_handler
10522 {
32ec8896 10523 unsigned int machtype;
015dc7e1 10524 bool (* handler)(Filedata *);
2cf0635d
NC
10525 } handlers[] =
10526 {
0b6ae522 10527 { EM_ARM, arm_process_unwind },
57346661
AM
10528 { EM_IA_64, ia64_process_unwind },
10529 { EM_PARISC, hppa_process_unwind },
fa197c1c 10530 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10531 { EM_386, no_processor_specific_unwind },
10532 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10533 { 0, NULL }
57346661
AM
10534 };
10535 int i;
10536
10537 if (!do_unwind)
015dc7e1 10538 return true;
57346661
AM
10539
10540 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10541 if (filedata->file_header.e_machine == handlers[i].machtype)
10542 return handlers[i].handler (filedata);
57346661 10543
1b31d05e 10544 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10545 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10546 return true;
57346661
AM
10547}
10548
37c18eed
SD
10549static void
10550dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10551{
10552 switch (entry->d_tag)
10553 {
10554 case DT_AARCH64_BTI_PLT:
1dbade74 10555 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10556 break;
10557 default:
10558 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10559 break;
10560 }
10561 putchar ('\n');
10562}
10563
252b5132 10564static void
978c4450 10565dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10566{
10567 switch (entry->d_tag)
10568 {
10569 case DT_MIPS_FLAGS:
10570 if (entry->d_un.d_val == 0)
4b68bca3 10571 printf (_("NONE"));
252b5132
RH
10572 else
10573 {
10574 static const char * opts[] =
10575 {
10576 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10577 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10578 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10579 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10580 "RLD_ORDER_SAFE"
10581 };
10582 unsigned int cnt;
015dc7e1 10583 bool first = true;
2b692964 10584
60bca95a 10585 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10586 if (entry->d_un.d_val & (1 << cnt))
10587 {
10588 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10589 first = false;
252b5132 10590 }
252b5132
RH
10591 }
10592 break;
103f02d3 10593
252b5132 10594 case DT_MIPS_IVERSION:
84714f86 10595 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10596 printf (_("Interface Version: %s"),
84714f86 10597 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10598 else
76ca31c0
NC
10599 {
10600 char buf[40];
10601 sprintf_vma (buf, entry->d_un.d_ptr);
10602 /* Note: coded this way so that there is a single string for translation. */
10603 printf (_("<corrupt: %s>"), buf);
10604 }
252b5132 10605 break;
103f02d3 10606
252b5132
RH
10607 case DT_MIPS_TIME_STAMP:
10608 {
d5b07ef4 10609 char timebuf[128];
2cf0635d 10610 struct tm * tmp;
91d6fa6a 10611 time_t atime = entry->d_un.d_val;
82b1b41b 10612
91d6fa6a 10613 tmp = gmtime (&atime);
82b1b41b
NC
10614 /* PR 17531: file: 6accc532. */
10615 if (tmp == NULL)
10616 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10617 else
10618 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10619 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10620 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10621 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10622 }
10623 break;
103f02d3 10624
252b5132
RH
10625 case DT_MIPS_RLD_VERSION:
10626 case DT_MIPS_LOCAL_GOTNO:
10627 case DT_MIPS_CONFLICTNO:
10628 case DT_MIPS_LIBLISTNO:
10629 case DT_MIPS_SYMTABNO:
10630 case DT_MIPS_UNREFEXTNO:
10631 case DT_MIPS_HIPAGENO:
10632 case DT_MIPS_DELTA_CLASS_NO:
10633 case DT_MIPS_DELTA_INSTANCE_NO:
10634 case DT_MIPS_DELTA_RELOC_NO:
10635 case DT_MIPS_DELTA_SYM_NO:
10636 case DT_MIPS_DELTA_CLASSSYM_NO:
10637 case DT_MIPS_COMPACT_SIZE:
c69075ac 10638 print_vma (entry->d_un.d_val, DEC);
252b5132 10639 break;
103f02d3 10640
f16a9783 10641 case DT_MIPS_XHASH:
978c4450
AM
10642 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10643 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10644 /* Falls through. */
10645
103f02d3 10646 default:
4b68bca3 10647 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10648 }
4b68bca3 10649 putchar ('\n');
103f02d3
UD
10650}
10651
103f02d3 10652static void
2cf0635d 10653dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10654{
10655 switch (entry->d_tag)
10656 {
10657 case DT_HP_DLD_FLAGS:
10658 {
10659 static struct
10660 {
10661 long int bit;
2cf0635d 10662 const char * str;
5e220199
NC
10663 }
10664 flags[] =
10665 {
10666 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10667 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10668 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10669 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10670 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10671 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10672 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10673 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10674 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10675 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10676 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10677 { DT_HP_GST, "HP_GST" },
10678 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10679 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10680 { DT_HP_NODELETE, "HP_NODELETE" },
10681 { DT_HP_GROUP, "HP_GROUP" },
10682 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10683 };
015dc7e1 10684 bool first = true;
5e220199 10685 size_t cnt;
f7a99963 10686 bfd_vma val = entry->d_un.d_val;
103f02d3 10687
60bca95a 10688 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10689 if (val & flags[cnt].bit)
30800947
NC
10690 {
10691 if (! first)
10692 putchar (' ');
10693 fputs (flags[cnt].str, stdout);
015dc7e1 10694 first = false;
30800947
NC
10695 val ^= flags[cnt].bit;
10696 }
76da6bbe 10697
103f02d3 10698 if (val != 0 || first)
f7a99963
NC
10699 {
10700 if (! first)
10701 putchar (' ');
10702 print_vma (val, HEX);
10703 }
103f02d3
UD
10704 }
10705 break;
76da6bbe 10706
252b5132 10707 default:
f7a99963
NC
10708 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10709 break;
252b5132 10710 }
35b1837e 10711 putchar ('\n');
252b5132
RH
10712}
10713
28f997cf
TG
10714#ifdef BFD64
10715
10716/* VMS vs Unix time offset and factor. */
10717
10718#define VMS_EPOCH_OFFSET 35067168000000000LL
10719#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10720#ifndef INT64_MIN
10721#define INT64_MIN (-9223372036854775807LL - 1)
10722#endif
28f997cf
TG
10723
10724/* Display a VMS time in a human readable format. */
10725
10726static void
0e3c1eeb 10727print_vms_time (int64_t vmstime)
28f997cf 10728{
dccc31de 10729 struct tm *tm = NULL;
28f997cf
TG
10730 time_t unxtime;
10731
dccc31de
AM
10732 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10733 {
10734 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10735 unxtime = vmstime;
10736 if (unxtime == vmstime)
10737 tm = gmtime (&unxtime);
10738 }
10739 if (tm != NULL)
10740 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10741 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10742 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10743}
10744#endif /* BFD64 */
10745
ecc51f48 10746static void
2cf0635d 10747dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10748{
10749 switch (entry->d_tag)
10750 {
0de14b54 10751 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10752 /* First 3 slots reserved. */
ecc51f48
NC
10753 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10754 printf (" -- ");
10755 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10756 break;
10757
28f997cf
TG
10758 case DT_IA_64_VMS_LINKTIME:
10759#ifdef BFD64
10760 print_vms_time (entry->d_un.d_val);
10761#endif
10762 break;
10763
10764 case DT_IA_64_VMS_LNKFLAGS:
10765 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10766 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10767 printf (" CALL_DEBUG");
10768 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10769 printf (" NOP0BUFS");
10770 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10771 printf (" P0IMAGE");
10772 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10773 printf (" MKTHREADS");
10774 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10775 printf (" UPCALLS");
10776 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10777 printf (" IMGSTA");
10778 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10779 printf (" INITIALIZE");
10780 if (entry->d_un.d_val & VMS_LF_MAIN)
10781 printf (" MAIN");
10782 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10783 printf (" EXE_INIT");
10784 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10785 printf (" TBK_IN_IMG");
10786 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10787 printf (" DBG_IN_IMG");
10788 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10789 printf (" TBK_IN_DSF");
10790 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10791 printf (" DBG_IN_DSF");
10792 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10793 printf (" SIGNATURES");
10794 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10795 printf (" REL_SEG_OFF");
10796 break;
10797
bdf4d63a
JJ
10798 default:
10799 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10800 break;
ecc51f48 10801 }
bdf4d63a 10802 putchar ('\n');
ecc51f48
NC
10803}
10804
015dc7e1 10805static bool
dda8d76d 10806get_32bit_dynamic_section (Filedata * filedata)
252b5132 10807{
2cf0635d
NC
10808 Elf32_External_Dyn * edyn;
10809 Elf32_External_Dyn * ext;
10810 Elf_Internal_Dyn * entry;
103f02d3 10811
978c4450
AM
10812 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10813 filedata->dynamic_addr, 1,
10814 filedata->dynamic_size,
10815 _("dynamic section"));
a6e9f9df 10816 if (!edyn)
015dc7e1 10817 return false;
103f02d3 10818
071436c6
NC
10819 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10820 might not have the luxury of section headers. Look for the DT_NULL
10821 terminator to determine the number of entries. */
978c4450
AM
10822 for (ext = edyn, filedata->dynamic_nent = 0;
10823 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10824 ext++)
10825 {
978c4450 10826 filedata->dynamic_nent++;
ba2685cc
AM
10827 if (BYTE_GET (ext->d_tag) == DT_NULL)
10828 break;
10829 }
252b5132 10830
978c4450
AM
10831 filedata->dynamic_section
10832 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10833 if (filedata->dynamic_section == NULL)
252b5132 10834 {
8b73c356 10835 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10836 (unsigned long) filedata->dynamic_nent);
9ea033b2 10837 free (edyn);
015dc7e1 10838 return false;
9ea033b2 10839 }
252b5132 10840
978c4450
AM
10841 for (ext = edyn, entry = filedata->dynamic_section;
10842 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10843 ext++, entry++)
9ea033b2 10844 {
fb514b26
AM
10845 entry->d_tag = BYTE_GET (ext->d_tag);
10846 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10847 }
10848
9ea033b2
NC
10849 free (edyn);
10850
015dc7e1 10851 return true;
9ea033b2
NC
10852}
10853
015dc7e1 10854static bool
dda8d76d 10855get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10856{
2cf0635d
NC
10857 Elf64_External_Dyn * edyn;
10858 Elf64_External_Dyn * ext;
10859 Elf_Internal_Dyn * entry;
103f02d3 10860
071436c6 10861 /* Read in the data. */
978c4450
AM
10862 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10863 filedata->dynamic_addr, 1,
10864 filedata->dynamic_size,
10865 _("dynamic section"));
a6e9f9df 10866 if (!edyn)
015dc7e1 10867 return false;
103f02d3 10868
071436c6
NC
10869 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10870 might not have the luxury of section headers. Look for the DT_NULL
10871 terminator to determine the number of entries. */
978c4450 10872 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10873 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10874 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10875 ext++)
10876 {
978c4450 10877 filedata->dynamic_nent++;
66543521 10878 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10879 break;
10880 }
252b5132 10881
978c4450
AM
10882 filedata->dynamic_section
10883 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10884 if (filedata->dynamic_section == NULL)
252b5132 10885 {
8b73c356 10886 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10887 (unsigned long) filedata->dynamic_nent);
252b5132 10888 free (edyn);
015dc7e1 10889 return false;
252b5132
RH
10890 }
10891
071436c6 10892 /* Convert from external to internal formats. */
978c4450
AM
10893 for (ext = edyn, entry = filedata->dynamic_section;
10894 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10895 ext++, entry++)
252b5132 10896 {
66543521
AM
10897 entry->d_tag = BYTE_GET (ext->d_tag);
10898 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10899 }
10900
10901 free (edyn);
10902
015dc7e1 10903 return true;
9ea033b2
NC
10904}
10905
4de91c10
AM
10906static bool
10907get_dynamic_section (Filedata *filedata)
10908{
10909 if (filedata->dynamic_section)
10910 return true;
10911
10912 if (is_32bit_elf)
10913 return get_32bit_dynamic_section (filedata);
10914 else
10915 return get_64bit_dynamic_section (filedata);
10916}
10917
e9e44622
JJ
10918static void
10919print_dynamic_flags (bfd_vma flags)
d1133906 10920{
015dc7e1 10921 bool first = true;
13ae64f3 10922
d1133906
NC
10923 while (flags)
10924 {
10925 bfd_vma flag;
10926
10927 flag = flags & - flags;
10928 flags &= ~ flag;
10929
e9e44622 10930 if (first)
015dc7e1 10931 first = false;
e9e44622
JJ
10932 else
10933 putc (' ', stdout);
13ae64f3 10934
d1133906
NC
10935 switch (flag)
10936 {
e9e44622
JJ
10937 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10938 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10939 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10940 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10941 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10942 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10943 }
10944 }
e9e44622 10945 puts ("");
d1133906
NC
10946}
10947
10ca4b04
L
10948static bfd_vma *
10949get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10950{
10951 unsigned char * e_data;
10952 bfd_vma * i_data;
10953
10954 /* If the size_t type is smaller than the bfd_size_type, eg because
10955 you are building a 32-bit tool on a 64-bit host, then make sure
10956 that when (number) is cast to (size_t) no information is lost. */
10957 if (sizeof (size_t) < sizeof (bfd_size_type)
10958 && (bfd_size_type) ((size_t) number) != number)
10959 {
10960 error (_("Size truncation prevents reading %s elements of size %u\n"),
10961 bfd_vmatoa ("u", number), ent_size);
10962 return NULL;
10963 }
10964
10965 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10966 attempting to allocate memory when the read is bound to fail. */
10967 if (ent_size * number > filedata->file_size)
10968 {
10969 error (_("Invalid number of dynamic entries: %s\n"),
10970 bfd_vmatoa ("u", number));
10971 return NULL;
10972 }
10973
10974 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10975 if (e_data == NULL)
10976 {
10977 error (_("Out of memory reading %s dynamic entries\n"),
10978 bfd_vmatoa ("u", number));
10979 return NULL;
10980 }
10981
10982 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10983 {
10984 error (_("Unable to read in %s bytes of dynamic data\n"),
10985 bfd_vmatoa ("u", number * ent_size));
10986 free (e_data);
10987 return NULL;
10988 }
10989
10990 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10991 if (i_data == NULL)
10992 {
10993 error (_("Out of memory allocating space for %s dynamic entries\n"),
10994 bfd_vmatoa ("u", number));
10995 free (e_data);
10996 return NULL;
10997 }
10998
10999 while (number--)
11000 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11001
11002 free (e_data);
11003
11004 return i_data;
11005}
11006
11007static unsigned long
11008get_num_dynamic_syms (Filedata * filedata)
11009{
11010 unsigned long num_of_syms = 0;
11011
11012 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11013 return num_of_syms;
11014
978c4450 11015 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11016 {
11017 unsigned char nb[8];
11018 unsigned char nc[8];
11019 unsigned int hash_ent_size = 4;
11020
11021 if ((filedata->file_header.e_machine == EM_ALPHA
11022 || filedata->file_header.e_machine == EM_S390
11023 || filedata->file_header.e_machine == EM_S390_OLD)
11024 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11025 hash_ent_size = 8;
11026
11027 if (fseek (filedata->handle,
978c4450
AM
11028 (filedata->archive_file_offset
11029 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11030 sizeof nb + sizeof nc)),
11031 SEEK_SET))
11032 {
11033 error (_("Unable to seek to start of dynamic information\n"));
11034 goto no_hash;
11035 }
11036
11037 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11038 {
11039 error (_("Failed to read in number of buckets\n"));
11040 goto no_hash;
11041 }
11042
11043 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11044 {
11045 error (_("Failed to read in number of chains\n"));
11046 goto no_hash;
11047 }
11048
978c4450
AM
11049 filedata->nbuckets = byte_get (nb, hash_ent_size);
11050 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11051
2482f306
AM
11052 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11053 {
11054 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11055 hash_ent_size);
11056 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11057 hash_ent_size);
001890e1 11058
2482f306
AM
11059 if (filedata->buckets != NULL && filedata->chains != NULL)
11060 num_of_syms = filedata->nchains;
11061 }
ceb9bf11 11062 no_hash:
10ca4b04
L
11063 if (num_of_syms == 0)
11064 {
9db70fc3
AM
11065 free (filedata->buckets);
11066 filedata->buckets = NULL;
11067 free (filedata->chains);
11068 filedata->chains = NULL;
978c4450 11069 filedata->nbuckets = 0;
10ca4b04
L
11070 }
11071 }
11072
978c4450 11073 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11074 {
11075 unsigned char nb[16];
11076 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11077 bfd_vma buckets_vma;
11078 unsigned long hn;
10ca4b04
L
11079
11080 if (fseek (filedata->handle,
978c4450
AM
11081 (filedata->archive_file_offset
11082 + offset_from_vma (filedata,
11083 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11084 sizeof nb)),
11085 SEEK_SET))
11086 {
11087 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11088 goto no_gnu_hash;
11089 }
11090
11091 if (fread (nb, 16, 1, filedata->handle) != 1)
11092 {
11093 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11094 goto no_gnu_hash;
11095 }
11096
978c4450
AM
11097 filedata->ngnubuckets = byte_get (nb, 4);
11098 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11099 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11100 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11101 if (is_32bit_elf)
11102 buckets_vma += bitmaskwords * 4;
11103 else
11104 buckets_vma += bitmaskwords * 8;
11105
11106 if (fseek (filedata->handle,
978c4450 11107 (filedata->archive_file_offset
10ca4b04
L
11108 + offset_from_vma (filedata, buckets_vma, 4)),
11109 SEEK_SET))
11110 {
11111 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11112 goto no_gnu_hash;
11113 }
11114
978c4450
AM
11115 filedata->gnubuckets
11116 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11117
978c4450 11118 if (filedata->gnubuckets == NULL)
90837ea7 11119 goto no_gnu_hash;
10ca4b04 11120
978c4450
AM
11121 for (i = 0; i < filedata->ngnubuckets; i++)
11122 if (filedata->gnubuckets[i] != 0)
10ca4b04 11123 {
978c4450 11124 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11125 goto no_gnu_hash;
10ca4b04 11126
978c4450
AM
11127 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11128 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11129 }
11130
11131 if (maxchain == 0xffffffff)
90837ea7 11132 goto no_gnu_hash;
10ca4b04 11133
978c4450 11134 maxchain -= filedata->gnusymidx;
10ca4b04
L
11135
11136 if (fseek (filedata->handle,
978c4450
AM
11137 (filedata->archive_file_offset
11138 + offset_from_vma (filedata,
11139 buckets_vma + 4 * (filedata->ngnubuckets
11140 + maxchain),
11141 4)),
10ca4b04
L
11142 SEEK_SET))
11143 {
11144 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11145 goto no_gnu_hash;
11146 }
11147
11148 do
11149 {
11150 if (fread (nb, 4, 1, filedata->handle) != 1)
11151 {
11152 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11153 goto no_gnu_hash;
11154 }
11155
11156 if (maxchain + 1 == 0)
90837ea7 11157 goto no_gnu_hash;
10ca4b04
L
11158
11159 ++maxchain;
11160 }
11161 while ((byte_get (nb, 4) & 1) == 0);
11162
11163 if (fseek (filedata->handle,
978c4450
AM
11164 (filedata->archive_file_offset
11165 + offset_from_vma (filedata, (buckets_vma
11166 + 4 * filedata->ngnubuckets),
11167 4)),
10ca4b04
L
11168 SEEK_SET))
11169 {
11170 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11171 goto no_gnu_hash;
11172 }
11173
978c4450
AM
11174 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11175 filedata->ngnuchains = maxchain;
10ca4b04 11176
978c4450 11177 if (filedata->gnuchains == NULL)
90837ea7 11178 goto no_gnu_hash;
10ca4b04 11179
978c4450 11180 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11181 {
11182 if (fseek (filedata->handle,
978c4450 11183 (filedata->archive_file_offset
10ca4b04 11184 + offset_from_vma (filedata, (buckets_vma
978c4450 11185 + 4 * (filedata->ngnubuckets
10ca4b04
L
11186 + maxchain)), 4)),
11187 SEEK_SET))
11188 {
11189 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11190 goto no_gnu_hash;
11191 }
11192
978c4450 11193 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11194 if (filedata->mipsxlat == NULL)
11195 goto no_gnu_hash;
10ca4b04
L
11196 }
11197
978c4450
AM
11198 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11199 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11200 {
978c4450
AM
11201 bfd_vma si = filedata->gnubuckets[hn];
11202 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11203
11204 do
11205 {
978c4450 11206 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11207 {
c31ab5a0
AM
11208 if (off < filedata->ngnuchains
11209 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11210 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11211 }
11212 else
11213 {
11214 if (si >= num_of_syms)
11215 num_of_syms = si + 1;
11216 }
11217 si++;
11218 }
978c4450
AM
11219 while (off < filedata->ngnuchains
11220 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11221 }
11222
90837ea7 11223 if (num_of_syms == 0)
10ca4b04 11224 {
90837ea7 11225 no_gnu_hash:
9db70fc3
AM
11226 free (filedata->mipsxlat);
11227 filedata->mipsxlat = NULL;
11228 free (filedata->gnuchains);
11229 filedata->gnuchains = NULL;
11230 free (filedata->gnubuckets);
11231 filedata->gnubuckets = NULL;
978c4450
AM
11232 filedata->ngnubuckets = 0;
11233 filedata->ngnuchains = 0;
10ca4b04
L
11234 }
11235 }
11236
11237 return num_of_syms;
11238}
11239
b2d38a17
NC
11240/* Parse and display the contents of the dynamic section. */
11241
015dc7e1 11242static bool
dda8d76d 11243process_dynamic_section (Filedata * filedata)
9ea033b2 11244{
2cf0635d 11245 Elf_Internal_Dyn * entry;
9ea033b2 11246
93df3340 11247 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11248 {
11249 if (do_dynamic)
ca0e11aa
NC
11250 {
11251 if (filedata->is_separate)
11252 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11253 filedata->file_name);
11254 else
11255 printf (_("\nThere is no dynamic section in this file.\n"));
11256 }
9ea033b2 11257
015dc7e1 11258 return true;
9ea033b2
NC
11259 }
11260
4de91c10
AM
11261 if (!get_dynamic_section (filedata))
11262 return false;
9ea033b2 11263
252b5132 11264 /* Find the appropriate symbol table. */
978c4450 11265 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11266 {
2482f306
AM
11267 unsigned long num_of_syms;
11268
978c4450
AM
11269 for (entry = filedata->dynamic_section;
11270 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11271 ++entry)
10ca4b04 11272 if (entry->d_tag == DT_SYMTAB)
978c4450 11273 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11274 else if (entry->d_tag == DT_SYMENT)
978c4450 11275 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11276 else if (entry->d_tag == DT_HASH)
978c4450 11277 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11278 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11279 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11280 else if ((filedata->file_header.e_machine == EM_MIPS
11281 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11282 && entry->d_tag == DT_MIPS_XHASH)
11283 {
978c4450
AM
11284 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11285 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11286 }
252b5132 11287
2482f306
AM
11288 num_of_syms = get_num_dynamic_syms (filedata);
11289
11290 if (num_of_syms != 0
11291 && filedata->dynamic_symbols == NULL
11292 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11293 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11294 {
11295 Elf_Internal_Phdr *seg;
2482f306 11296 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11297
2482f306
AM
11298 if (! get_program_headers (filedata))
11299 {
11300 error (_("Cannot interpret virtual addresses "
11301 "without program headers.\n"));
015dc7e1 11302 return false;
2482f306 11303 }
252b5132 11304
2482f306
AM
11305 for (seg = filedata->program_headers;
11306 seg < filedata->program_headers + filedata->file_header.e_phnum;
11307 ++seg)
11308 {
11309 if (seg->p_type != PT_LOAD)
11310 continue;
252b5132 11311
2482f306
AM
11312 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11313 {
11314 /* See PR 21379 for a reproducer. */
11315 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11316 return false;
2482f306 11317 }
252b5132 11318
2482f306
AM
11319 if (vma >= (seg->p_vaddr & -seg->p_align)
11320 && vma < seg->p_vaddr + seg->p_filesz)
11321 {
11322 /* Since we do not know how big the symbol table is,
11323 we default to reading in up to the end of PT_LOAD
11324 segment and processing that. This is overkill, I
11325 know, but it should work. */
11326 Elf_Internal_Shdr section;
11327 section.sh_offset = (vma - seg->p_vaddr
11328 + seg->p_offset);
11329 section.sh_size = (num_of_syms
11330 * filedata->dynamic_info[DT_SYMENT]);
11331 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11332
11333 if (do_checks
11334 && filedata->dynamic_symtab_section != NULL
11335 && ((filedata->dynamic_symtab_section->sh_offset
11336 != section.sh_offset)
11337 || (filedata->dynamic_symtab_section->sh_size
11338 != section.sh_size)
11339 || (filedata->dynamic_symtab_section->sh_entsize
11340 != section.sh_entsize)))
11341 warn (_("\
11342the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11343
2482f306
AM
11344 section.sh_name = filedata->string_table_length;
11345 filedata->dynamic_symbols
4de91c10 11346 = get_elf_symbols (filedata, &section,
2482f306
AM
11347 &filedata->num_dynamic_syms);
11348 if (filedata->dynamic_symbols == NULL
11349 || filedata->num_dynamic_syms != num_of_syms)
11350 {
11351 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11352 return false;
2482f306
AM
11353 }
11354 break;
11355 }
11356 }
11357 }
11358 }
252b5132
RH
11359
11360 /* Similarly find a string table. */
978c4450
AM
11361 if (filedata->dynamic_strings == NULL)
11362 for (entry = filedata->dynamic_section;
11363 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11364 ++entry)
11365 {
11366 if (entry->d_tag == DT_STRTAB)
978c4450 11367 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11368
10ca4b04 11369 if (entry->d_tag == DT_STRSZ)
978c4450 11370 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11371
978c4450
AM
11372 if (filedata->dynamic_info[DT_STRTAB]
11373 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11374 {
11375 unsigned long offset;
978c4450 11376 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11377
11378 offset = offset_from_vma (filedata,
978c4450 11379 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11380 str_tab_len);
8ac10c5b
L
11381 if (do_checks
11382 && filedata->dynamic_strtab_section
11383 && ((filedata->dynamic_strtab_section->sh_offset
11384 != (file_ptr) offset)
11385 || (filedata->dynamic_strtab_section->sh_size
11386 != str_tab_len)))
11387 warn (_("\
11388the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11389
978c4450
AM
11390 filedata->dynamic_strings
11391 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11392 _("dynamic string table"));
11393 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11394 {
11395 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11396 break;
11397 }
e3d39609 11398
978c4450 11399 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11400 break;
11401 }
11402 }
252b5132
RH
11403
11404 /* And find the syminfo section if available. */
978c4450 11405 if (filedata->dynamic_syminfo == NULL)
252b5132 11406 {
3e8bba36 11407 unsigned long syminsz = 0;
252b5132 11408
978c4450
AM
11409 for (entry = filedata->dynamic_section;
11410 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11411 ++entry)
252b5132
RH
11412 {
11413 if (entry->d_tag == DT_SYMINENT)
11414 {
11415 /* Note: these braces are necessary to avoid a syntax
11416 error from the SunOS4 C compiler. */
049b0c3a
NC
11417 /* PR binutils/17531: A corrupt file can trigger this test.
11418 So do not use an assert, instead generate an error message. */
11419 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11420 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11421 (int) entry->d_un.d_val);
252b5132
RH
11422 }
11423 else if (entry->d_tag == DT_SYMINSZ)
11424 syminsz = entry->d_un.d_val;
11425 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11426 filedata->dynamic_syminfo_offset
11427 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11428 }
11429
978c4450 11430 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11431 {
2cf0635d
NC
11432 Elf_External_Syminfo * extsyminfo;
11433 Elf_External_Syminfo * extsym;
11434 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11435
11436 /* There is a syminfo section. Read the data. */
3f5e193b 11437 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11438 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11439 1, syminsz, _("symbol information"));
a6e9f9df 11440 if (!extsyminfo)
015dc7e1 11441 return false;
252b5132 11442
978c4450 11443 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11444 {
11445 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11446 free (filedata->dynamic_syminfo);
e3d39609 11447 }
978c4450
AM
11448 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11449 if (filedata->dynamic_syminfo == NULL)
252b5132 11450 {
2482f306
AM
11451 error (_("Out of memory allocating %lu bytes "
11452 "for dynamic symbol info\n"),
8b73c356 11453 (unsigned long) syminsz);
015dc7e1 11454 return false;
252b5132
RH
11455 }
11456
2482f306
AM
11457 filedata->dynamic_syminfo_nent
11458 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11459 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11460 syminfo < (filedata->dynamic_syminfo
11461 + filedata->dynamic_syminfo_nent);
86dba8ee 11462 ++syminfo, ++extsym)
252b5132 11463 {
86dba8ee
AM
11464 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11465 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11466 }
11467
11468 free (extsyminfo);
11469 }
11470 }
11471
978c4450 11472 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11473 {
f253158f
NC
11474 if (filedata->is_separate)
11475 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11476 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11477 (unsigned long) filedata->dynamic_nent),
11478 filedata->file_name,
11479 filedata->dynamic_addr,
11480 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11481 else
11482 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11483 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11484 (unsigned long) filedata->dynamic_nent),
11485 filedata->dynamic_addr,
11486 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11487 }
252b5132
RH
11488 if (do_dynamic)
11489 printf (_(" Tag Type Name/Value\n"));
11490
978c4450
AM
11491 for (entry = filedata->dynamic_section;
11492 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11493 entry++)
252b5132
RH
11494 {
11495 if (do_dynamic)
f7a99963 11496 {
2cf0635d 11497 const char * dtype;
e699b9ff 11498
f7a99963
NC
11499 putchar (' ');
11500 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11501 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11502 printf (" (%s)%*s", dtype,
32ec8896 11503 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11504 }
252b5132
RH
11505
11506 switch (entry->d_tag)
11507 {
d1133906
NC
11508 case DT_FLAGS:
11509 if (do_dynamic)
e9e44622 11510 print_dynamic_flags (entry->d_un.d_val);
d1133906 11511 break;
76da6bbe 11512
252b5132
RH
11513 case DT_AUXILIARY:
11514 case DT_FILTER:
019148e4
L
11515 case DT_CONFIG:
11516 case DT_DEPAUDIT:
11517 case DT_AUDIT:
252b5132
RH
11518 if (do_dynamic)
11519 {
019148e4 11520 switch (entry->d_tag)
b34976b6 11521 {
019148e4
L
11522 case DT_AUXILIARY:
11523 printf (_("Auxiliary library"));
11524 break;
11525
11526 case DT_FILTER:
11527 printf (_("Filter library"));
11528 break;
11529
b34976b6 11530 case DT_CONFIG:
019148e4
L
11531 printf (_("Configuration file"));
11532 break;
11533
11534 case DT_DEPAUDIT:
11535 printf (_("Dependency audit library"));
11536 break;
11537
11538 case DT_AUDIT:
11539 printf (_("Audit library"));
11540 break;
11541 }
252b5132 11542
84714f86 11543 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11544 printf (": [%s]\n",
84714f86 11545 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11546 else
f7a99963
NC
11547 {
11548 printf (": ");
11549 print_vma (entry->d_un.d_val, PREFIX_HEX);
11550 putchar ('\n');
11551 }
252b5132
RH
11552 }
11553 break;
11554
dcefbbbd 11555 case DT_FEATURE:
252b5132
RH
11556 if (do_dynamic)
11557 {
11558 printf (_("Flags:"));
86f55779 11559
252b5132
RH
11560 if (entry->d_un.d_val == 0)
11561 printf (_(" None\n"));
11562 else
11563 {
11564 unsigned long int val = entry->d_un.d_val;
86f55779 11565
252b5132
RH
11566 if (val & DTF_1_PARINIT)
11567 {
11568 printf (" PARINIT");
11569 val ^= DTF_1_PARINIT;
11570 }
dcefbbbd
L
11571 if (val & DTF_1_CONFEXP)
11572 {
11573 printf (" CONFEXP");
11574 val ^= DTF_1_CONFEXP;
11575 }
252b5132
RH
11576 if (val != 0)
11577 printf (" %lx", val);
11578 puts ("");
11579 }
11580 }
11581 break;
11582
11583 case DT_POSFLAG_1:
11584 if (do_dynamic)
11585 {
11586 printf (_("Flags:"));
86f55779 11587
252b5132
RH
11588 if (entry->d_un.d_val == 0)
11589 printf (_(" None\n"));
11590 else
11591 {
11592 unsigned long int val = entry->d_un.d_val;
86f55779 11593
252b5132
RH
11594 if (val & DF_P1_LAZYLOAD)
11595 {
11596 printf (" LAZYLOAD");
11597 val ^= DF_P1_LAZYLOAD;
11598 }
11599 if (val & DF_P1_GROUPPERM)
11600 {
11601 printf (" GROUPPERM");
11602 val ^= DF_P1_GROUPPERM;
11603 }
11604 if (val != 0)
11605 printf (" %lx", val);
11606 puts ("");
11607 }
11608 }
11609 break;
11610
11611 case DT_FLAGS_1:
11612 if (do_dynamic)
11613 {
11614 printf (_("Flags:"));
11615 if (entry->d_un.d_val == 0)
11616 printf (_(" None\n"));
11617 else
11618 {
11619 unsigned long int val = entry->d_un.d_val;
86f55779 11620
252b5132
RH
11621 if (val & DF_1_NOW)
11622 {
11623 printf (" NOW");
11624 val ^= DF_1_NOW;
11625 }
11626 if (val & DF_1_GLOBAL)
11627 {
11628 printf (" GLOBAL");
11629 val ^= DF_1_GLOBAL;
11630 }
11631 if (val & DF_1_GROUP)
11632 {
11633 printf (" GROUP");
11634 val ^= DF_1_GROUP;
11635 }
11636 if (val & DF_1_NODELETE)
11637 {
11638 printf (" NODELETE");
11639 val ^= DF_1_NODELETE;
11640 }
11641 if (val & DF_1_LOADFLTR)
11642 {
11643 printf (" LOADFLTR");
11644 val ^= DF_1_LOADFLTR;
11645 }
11646 if (val & DF_1_INITFIRST)
11647 {
11648 printf (" INITFIRST");
11649 val ^= DF_1_INITFIRST;
11650 }
11651 if (val & DF_1_NOOPEN)
11652 {
11653 printf (" NOOPEN");
11654 val ^= DF_1_NOOPEN;
11655 }
11656 if (val & DF_1_ORIGIN)
11657 {
11658 printf (" ORIGIN");
11659 val ^= DF_1_ORIGIN;
11660 }
11661 if (val & DF_1_DIRECT)
11662 {
11663 printf (" DIRECT");
11664 val ^= DF_1_DIRECT;
11665 }
11666 if (val & DF_1_TRANS)
11667 {
11668 printf (" TRANS");
11669 val ^= DF_1_TRANS;
11670 }
11671 if (val & DF_1_INTERPOSE)
11672 {
11673 printf (" INTERPOSE");
11674 val ^= DF_1_INTERPOSE;
11675 }
f7db6139 11676 if (val & DF_1_NODEFLIB)
dcefbbbd 11677 {
f7db6139
L
11678 printf (" NODEFLIB");
11679 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11680 }
11681 if (val & DF_1_NODUMP)
11682 {
11683 printf (" NODUMP");
11684 val ^= DF_1_NODUMP;
11685 }
34b60028 11686 if (val & DF_1_CONFALT)
dcefbbbd 11687 {
34b60028
L
11688 printf (" CONFALT");
11689 val ^= DF_1_CONFALT;
11690 }
11691 if (val & DF_1_ENDFILTEE)
11692 {
11693 printf (" ENDFILTEE");
11694 val ^= DF_1_ENDFILTEE;
11695 }
11696 if (val & DF_1_DISPRELDNE)
11697 {
11698 printf (" DISPRELDNE");
11699 val ^= DF_1_DISPRELDNE;
11700 }
11701 if (val & DF_1_DISPRELPND)
11702 {
11703 printf (" DISPRELPND");
11704 val ^= DF_1_DISPRELPND;
11705 }
11706 if (val & DF_1_NODIRECT)
11707 {
11708 printf (" NODIRECT");
11709 val ^= DF_1_NODIRECT;
11710 }
11711 if (val & DF_1_IGNMULDEF)
11712 {
11713 printf (" IGNMULDEF");
11714 val ^= DF_1_IGNMULDEF;
11715 }
11716 if (val & DF_1_NOKSYMS)
11717 {
11718 printf (" NOKSYMS");
11719 val ^= DF_1_NOKSYMS;
11720 }
11721 if (val & DF_1_NOHDR)
11722 {
11723 printf (" NOHDR");
11724 val ^= DF_1_NOHDR;
11725 }
11726 if (val & DF_1_EDITED)
11727 {
11728 printf (" EDITED");
11729 val ^= DF_1_EDITED;
11730 }
11731 if (val & DF_1_NORELOC)
11732 {
11733 printf (" NORELOC");
11734 val ^= DF_1_NORELOC;
11735 }
11736 if (val & DF_1_SYMINTPOSE)
11737 {
11738 printf (" SYMINTPOSE");
11739 val ^= DF_1_SYMINTPOSE;
11740 }
11741 if (val & DF_1_GLOBAUDIT)
11742 {
11743 printf (" GLOBAUDIT");
11744 val ^= DF_1_GLOBAUDIT;
11745 }
11746 if (val & DF_1_SINGLETON)
11747 {
11748 printf (" SINGLETON");
11749 val ^= DF_1_SINGLETON;
dcefbbbd 11750 }
5c383f02
RO
11751 if (val & DF_1_STUB)
11752 {
11753 printf (" STUB");
11754 val ^= DF_1_STUB;
11755 }
11756 if (val & DF_1_PIE)
11757 {
11758 printf (" PIE");
11759 val ^= DF_1_PIE;
11760 }
b1202ffa
L
11761 if (val & DF_1_KMOD)
11762 {
11763 printf (" KMOD");
11764 val ^= DF_1_KMOD;
11765 }
11766 if (val & DF_1_WEAKFILTER)
11767 {
11768 printf (" WEAKFILTER");
11769 val ^= DF_1_WEAKFILTER;
11770 }
11771 if (val & DF_1_NOCOMMON)
11772 {
11773 printf (" NOCOMMON");
11774 val ^= DF_1_NOCOMMON;
11775 }
252b5132
RH
11776 if (val != 0)
11777 printf (" %lx", val);
11778 puts ("");
11779 }
11780 }
11781 break;
11782
11783 case DT_PLTREL:
978c4450 11784 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11785 if (do_dynamic)
dda8d76d 11786 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11787 break;
11788
11789 case DT_NULL :
11790 case DT_NEEDED :
11791 case DT_PLTGOT :
11792 case DT_HASH :
11793 case DT_STRTAB :
11794 case DT_SYMTAB :
11795 case DT_RELA :
11796 case DT_INIT :
11797 case DT_FINI :
11798 case DT_SONAME :
11799 case DT_RPATH :
11800 case DT_SYMBOLIC:
11801 case DT_REL :
a7fd1186 11802 case DT_RELR :
252b5132
RH
11803 case DT_DEBUG :
11804 case DT_TEXTREL :
11805 case DT_JMPREL :
019148e4 11806 case DT_RUNPATH :
978c4450 11807 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11808
11809 if (do_dynamic)
11810 {
84714f86 11811 const char *name;
252b5132 11812
84714f86
AM
11813 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11814 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11815 else
d79b3d50 11816 name = NULL;
252b5132
RH
11817
11818 if (name)
11819 {
11820 switch (entry->d_tag)
11821 {
11822 case DT_NEEDED:
11823 printf (_("Shared library: [%s]"), name);
11824
13acb58d
AM
11825 if (filedata->program_interpreter
11826 && streq (name, filedata->program_interpreter))
f7a99963 11827 printf (_(" program interpreter"));
252b5132
RH
11828 break;
11829
11830 case DT_SONAME:
f7a99963 11831 printf (_("Library soname: [%s]"), name);
252b5132
RH
11832 break;
11833
11834 case DT_RPATH:
f7a99963 11835 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11836 break;
11837
019148e4
L
11838 case DT_RUNPATH:
11839 printf (_("Library runpath: [%s]"), name);
11840 break;
11841
252b5132 11842 default:
f7a99963
NC
11843 print_vma (entry->d_un.d_val, PREFIX_HEX);
11844 break;
252b5132
RH
11845 }
11846 }
11847 else
f7a99963
NC
11848 print_vma (entry->d_un.d_val, PREFIX_HEX);
11849
11850 putchar ('\n');
252b5132
RH
11851 }
11852 break;
11853
11854 case DT_PLTRELSZ:
11855 case DT_RELASZ :
11856 case DT_STRSZ :
11857 case DT_RELSZ :
11858 case DT_RELAENT :
a7fd1186
FS
11859 case DT_RELRENT :
11860 case DT_RELRSZ :
252b5132
RH
11861 case DT_SYMENT :
11862 case DT_RELENT :
978c4450 11863 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11864 /* Fall through. */
252b5132
RH
11865 case DT_PLTPADSZ:
11866 case DT_MOVEENT :
11867 case DT_MOVESZ :
04d8355a 11868 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11869 case DT_INIT_ARRAYSZ:
11870 case DT_FINI_ARRAYSZ:
047b2264
JJ
11871 case DT_GNU_CONFLICTSZ:
11872 case DT_GNU_LIBLISTSZ:
252b5132 11873 if (do_dynamic)
f7a99963
NC
11874 {
11875 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11876 printf (_(" (bytes)\n"));
f7a99963 11877 }
252b5132
RH
11878 break;
11879
11880 case DT_VERDEFNUM:
11881 case DT_VERNEEDNUM:
11882 case DT_RELACOUNT:
11883 case DT_RELCOUNT:
11884 if (do_dynamic)
f7a99963
NC
11885 {
11886 print_vma (entry->d_un.d_val, UNSIGNED);
11887 putchar ('\n');
11888 }
252b5132
RH
11889 break;
11890
11891 case DT_SYMINSZ:
11892 case DT_SYMINENT:
11893 case DT_SYMINFO:
11894 case DT_USED:
11895 case DT_INIT_ARRAY:
11896 case DT_FINI_ARRAY:
11897 if (do_dynamic)
11898 {
d79b3d50 11899 if (entry->d_tag == DT_USED
84714f86 11900 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11901 {
84714f86
AM
11902 const char *name
11903 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11904
b34976b6 11905 if (*name)
252b5132
RH
11906 {
11907 printf (_("Not needed object: [%s]\n"), name);
11908 break;
11909 }
11910 }
103f02d3 11911
f7a99963
NC
11912 print_vma (entry->d_un.d_val, PREFIX_HEX);
11913 putchar ('\n');
252b5132
RH
11914 }
11915 break;
11916
11917 case DT_BIND_NOW:
11918 /* The value of this entry is ignored. */
35b1837e
AM
11919 if (do_dynamic)
11920 putchar ('\n');
252b5132 11921 break;
103f02d3 11922
047b2264
JJ
11923 case DT_GNU_PRELINKED:
11924 if (do_dynamic)
11925 {
2cf0635d 11926 struct tm * tmp;
91d6fa6a 11927 time_t atime = entry->d_un.d_val;
047b2264 11928
91d6fa6a 11929 tmp = gmtime (&atime);
071436c6
NC
11930 /* PR 17533 file: 041-1244816-0.004. */
11931 if (tmp == NULL)
5a2cbcf4
L
11932 printf (_("<corrupt time val: %lx"),
11933 (unsigned long) atime);
071436c6
NC
11934 else
11935 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11936 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11937 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11938
11939 }
11940 break;
11941
fdc90cb4 11942 case DT_GNU_HASH:
978c4450 11943 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11944 if (do_dynamic)
11945 {
11946 print_vma (entry->d_un.d_val, PREFIX_HEX);
11947 putchar ('\n');
11948 }
11949 break;
11950
a5da3dee
VDM
11951 case DT_GNU_FLAGS_1:
11952 if (do_dynamic)
11953 {
11954 printf (_("Flags:"));
11955 if (entry->d_un.d_val == 0)
11956 printf (_(" None\n"));
11957 else
11958 {
11959 unsigned long int val = entry->d_un.d_val;
11960
11961 if (val & DF_GNU_1_UNIQUE)
11962 {
11963 printf (" UNIQUE");
11964 val ^= DF_GNU_1_UNIQUE;
11965 }
11966 if (val != 0)
11967 printf (" %lx", val);
11968 puts ("");
11969 }
11970 }
11971 break;
11972
252b5132
RH
11973 default:
11974 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11975 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11976 = entry->d_un.d_val;
252b5132
RH
11977
11978 if (do_dynamic)
11979 {
dda8d76d 11980 switch (filedata->file_header.e_machine)
252b5132 11981 {
37c18eed
SD
11982 case EM_AARCH64:
11983 dynamic_section_aarch64_val (entry);
11984 break;
252b5132 11985 case EM_MIPS:
4fe85591 11986 case EM_MIPS_RS3_LE:
978c4450 11987 dynamic_section_mips_val (filedata, entry);
252b5132 11988 break;
103f02d3 11989 case EM_PARISC:
b2d38a17 11990 dynamic_section_parisc_val (entry);
103f02d3 11991 break;
ecc51f48 11992 case EM_IA_64:
b2d38a17 11993 dynamic_section_ia64_val (entry);
ecc51f48 11994 break;
252b5132 11995 default:
f7a99963
NC
11996 print_vma (entry->d_un.d_val, PREFIX_HEX);
11997 putchar ('\n');
252b5132
RH
11998 }
11999 }
12000 break;
12001 }
12002 }
12003
015dc7e1 12004 return true;
252b5132
RH
12005}
12006
12007static char *
d3ba0551 12008get_ver_flags (unsigned int flags)
252b5132 12009{
6d4f21f6 12010 static char buff[128];
252b5132
RH
12011
12012 buff[0] = 0;
12013
12014 if (flags == 0)
12015 return _("none");
12016
12017 if (flags & VER_FLG_BASE)
7bb1ad17 12018 strcat (buff, "BASE");
252b5132
RH
12019
12020 if (flags & VER_FLG_WEAK)
12021 {
12022 if (flags & VER_FLG_BASE)
7bb1ad17 12023 strcat (buff, " | ");
252b5132 12024
7bb1ad17 12025 strcat (buff, "WEAK");
252b5132
RH
12026 }
12027
44ec90b9
RO
12028 if (flags & VER_FLG_INFO)
12029 {
12030 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12031 strcat (buff, " | ");
44ec90b9 12032
7bb1ad17 12033 strcat (buff, "INFO");
44ec90b9
RO
12034 }
12035
12036 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12037 {
12038 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12039 strcat (buff, " | ");
12040
12041 strcat (buff, _("<unknown>"));
12042 }
252b5132
RH
12043
12044 return buff;
12045}
12046
12047/* Display the contents of the version sections. */
98fb390a 12048
015dc7e1 12049static bool
dda8d76d 12050process_version_sections (Filedata * filedata)
252b5132 12051{
2cf0635d 12052 Elf_Internal_Shdr * section;
b34976b6 12053 unsigned i;
015dc7e1 12054 bool found = false;
252b5132
RH
12055
12056 if (! do_version)
015dc7e1 12057 return true;
252b5132 12058
dda8d76d
NC
12059 for (i = 0, section = filedata->section_headers;
12060 i < filedata->file_header.e_shnum;
b34976b6 12061 i++, section++)
252b5132
RH
12062 {
12063 switch (section->sh_type)
12064 {
12065 case SHT_GNU_verdef:
12066 {
2cf0635d 12067 Elf_External_Verdef * edefs;
452bf675
AM
12068 unsigned long idx;
12069 unsigned long cnt;
2cf0635d 12070 char * endbuf;
252b5132 12071
015dc7e1 12072 found = true;
252b5132 12073
ca0e11aa
NC
12074 if (filedata->is_separate)
12075 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12076 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12077 section->sh_info),
12078 filedata->file_name,
12079 printable_section_name (filedata, section),
12080 section->sh_info);
12081 else
12082 printf (ngettext ("\nVersion definition section '%s' "
12083 "contains %u entry:\n",
12084 "\nVersion definition section '%s' "
12085 "contains %u entries:\n",
12086 section->sh_info),
12087 printable_section_name (filedata, section),
12088 section->sh_info);
047c3dbf 12089
ae9ac79e 12090 printf (_(" Addr: 0x"));
252b5132 12091 printf_vma (section->sh_addr);
233f82cf 12092 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12093 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12094 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12095
3f5e193b 12096 edefs = (Elf_External_Verdef *)
dda8d76d 12097 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12098 _("version definition section"));
a6e9f9df
AM
12099 if (!edefs)
12100 break;
59245841 12101 endbuf = (char *) edefs + section->sh_size;
252b5132 12102
1445030f 12103 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12104 {
2cf0635d
NC
12105 char * vstart;
12106 Elf_External_Verdef * edef;
b34976b6 12107 Elf_Internal_Verdef ent;
2cf0635d 12108 Elf_External_Verdaux * eaux;
b34976b6 12109 Elf_Internal_Verdaux aux;
452bf675 12110 unsigned long isum;
b34976b6 12111 int j;
103f02d3 12112
252b5132 12113 vstart = ((char *) edefs) + idx;
54806181
AM
12114 if (vstart + sizeof (*edef) > endbuf)
12115 break;
252b5132
RH
12116
12117 edef = (Elf_External_Verdef *) vstart;
12118
12119 ent.vd_version = BYTE_GET (edef->vd_version);
12120 ent.vd_flags = BYTE_GET (edef->vd_flags);
12121 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12122 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12123 ent.vd_hash = BYTE_GET (edef->vd_hash);
12124 ent.vd_aux = BYTE_GET (edef->vd_aux);
12125 ent.vd_next = BYTE_GET (edef->vd_next);
12126
452bf675 12127 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12128 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12129
12130 printf (_(" Index: %d Cnt: %d "),
12131 ent.vd_ndx, ent.vd_cnt);
12132
452bf675 12133 /* Check for overflow. */
1445030f 12134 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12135 break;
12136
252b5132
RH
12137 vstart += ent.vd_aux;
12138
1445030f
AM
12139 if (vstart + sizeof (*eaux) > endbuf)
12140 break;
252b5132
RH
12141 eaux = (Elf_External_Verdaux *) vstart;
12142
12143 aux.vda_name = BYTE_GET (eaux->vda_name);
12144 aux.vda_next = BYTE_GET (eaux->vda_next);
12145
84714f86 12146 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12147 printf (_("Name: %s\n"),
84714f86 12148 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12149 else
12150 printf (_("Name index: %ld\n"), aux.vda_name);
12151
12152 isum = idx + ent.vd_aux;
12153
b34976b6 12154 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12155 {
1445030f
AM
12156 if (aux.vda_next < sizeof (*eaux)
12157 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12158 {
12159 warn (_("Invalid vda_next field of %lx\n"),
12160 aux.vda_next);
12161 j = ent.vd_cnt;
12162 break;
12163 }
dd24e3da 12164 /* Check for overflow. */
7e26601c 12165 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12166 break;
12167
252b5132
RH
12168 isum += aux.vda_next;
12169 vstart += aux.vda_next;
12170
54806181
AM
12171 if (vstart + sizeof (*eaux) > endbuf)
12172 break;
1445030f 12173 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12174
12175 aux.vda_name = BYTE_GET (eaux->vda_name);
12176 aux.vda_next = BYTE_GET (eaux->vda_next);
12177
84714f86 12178 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12179 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12180 isum, j,
84714f86 12181 get_dynamic_name (filedata, aux.vda_name));
252b5132 12182 else
452bf675 12183 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12184 isum, j, aux.vda_name);
12185 }
dd24e3da 12186
54806181
AM
12187 if (j < ent.vd_cnt)
12188 printf (_(" Version def aux past end of section\n"));
252b5132 12189
c9f02c3e
MR
12190 /* PR 17531:
12191 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12192 if (ent.vd_next < sizeof (*edef)
12193 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12194 {
12195 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12196 cnt = section->sh_info;
12197 break;
12198 }
452bf675 12199 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12200 break;
12201
252b5132
RH
12202 idx += ent.vd_next;
12203 }
dd24e3da 12204
54806181
AM
12205 if (cnt < section->sh_info)
12206 printf (_(" Version definition past end of section\n"));
252b5132
RH
12207
12208 free (edefs);
12209 }
12210 break;
103f02d3 12211
252b5132
RH
12212 case SHT_GNU_verneed:
12213 {
2cf0635d 12214 Elf_External_Verneed * eneed;
452bf675
AM
12215 unsigned long idx;
12216 unsigned long cnt;
2cf0635d 12217 char * endbuf;
252b5132 12218
015dc7e1 12219 found = true;
252b5132 12220
ca0e11aa
NC
12221 if (filedata->is_separate)
12222 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12223 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12224 section->sh_info),
12225 filedata->file_name,
12226 printable_section_name (filedata, section),
12227 section->sh_info);
12228 else
12229 printf (ngettext ("\nVersion needs section '%s' "
12230 "contains %u entry:\n",
12231 "\nVersion needs section '%s' "
12232 "contains %u entries:\n",
12233 section->sh_info),
12234 printable_section_name (filedata, section),
12235 section->sh_info);
047c3dbf 12236
252b5132
RH
12237 printf (_(" Addr: 0x"));
12238 printf_vma (section->sh_addr);
72de5009 12239 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12240 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12241 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12242
dda8d76d 12243 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12244 section->sh_offset, 1,
12245 section->sh_size,
9cf03b7e 12246 _("Version Needs section"));
a6e9f9df
AM
12247 if (!eneed)
12248 break;
59245841 12249 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12250
12251 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12252 {
2cf0635d 12253 Elf_External_Verneed * entry;
b34976b6 12254 Elf_Internal_Verneed ent;
452bf675 12255 unsigned long isum;
b34976b6 12256 int j;
2cf0635d 12257 char * vstart;
252b5132
RH
12258
12259 vstart = ((char *) eneed) + idx;
54806181
AM
12260 if (vstart + sizeof (*entry) > endbuf)
12261 break;
252b5132
RH
12262
12263 entry = (Elf_External_Verneed *) vstart;
12264
12265 ent.vn_version = BYTE_GET (entry->vn_version);
12266 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12267 ent.vn_file = BYTE_GET (entry->vn_file);
12268 ent.vn_aux = BYTE_GET (entry->vn_aux);
12269 ent.vn_next = BYTE_GET (entry->vn_next);
12270
452bf675 12271 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12272
84714f86 12273 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12274 printf (_(" File: %s"),
84714f86 12275 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12276 else
12277 printf (_(" File: %lx"), ent.vn_file);
12278
12279 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12280
dd24e3da 12281 /* Check for overflow. */
7e26601c 12282 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12283 break;
252b5132
RH
12284 vstart += ent.vn_aux;
12285
12286 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12287 {
2cf0635d 12288 Elf_External_Vernaux * eaux;
b34976b6 12289 Elf_Internal_Vernaux aux;
252b5132 12290
54806181
AM
12291 if (vstart + sizeof (*eaux) > endbuf)
12292 break;
252b5132
RH
12293 eaux = (Elf_External_Vernaux *) vstart;
12294
12295 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12296 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12297 aux.vna_other = BYTE_GET (eaux->vna_other);
12298 aux.vna_name = BYTE_GET (eaux->vna_name);
12299 aux.vna_next = BYTE_GET (eaux->vna_next);
12300
84714f86 12301 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12302 printf (_(" %#06lx: Name: %s"),
84714f86 12303 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12304 else
452bf675 12305 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12306 isum, aux.vna_name);
12307
12308 printf (_(" Flags: %s Version: %d\n"),
12309 get_ver_flags (aux.vna_flags), aux.vna_other);
12310
1445030f
AM
12311 if (aux.vna_next < sizeof (*eaux)
12312 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12313 {
12314 warn (_("Invalid vna_next field of %lx\n"),
12315 aux.vna_next);
12316 j = ent.vn_cnt;
12317 break;
12318 }
1445030f
AM
12319 /* Check for overflow. */
12320 if (aux.vna_next > (size_t) (endbuf - vstart))
12321 break;
252b5132
RH
12322 isum += aux.vna_next;
12323 vstart += aux.vna_next;
12324 }
9cf03b7e 12325
54806181 12326 if (j < ent.vn_cnt)
f9a6a8f0 12327 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12328
1445030f
AM
12329 if (ent.vn_next < sizeof (*entry)
12330 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12331 {
452bf675 12332 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12333 cnt = section->sh_info;
12334 break;
12335 }
1445030f
AM
12336 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12337 break;
252b5132
RH
12338 idx += ent.vn_next;
12339 }
9cf03b7e 12340
54806181 12341 if (cnt < section->sh_info)
9cf03b7e 12342 warn (_("Missing Version Needs information\n"));
103f02d3 12343
252b5132
RH
12344 free (eneed);
12345 }
12346 break;
12347
12348 case SHT_GNU_versym:
12349 {
2cf0635d 12350 Elf_Internal_Shdr * link_section;
8b73c356
NC
12351 size_t total;
12352 unsigned int cnt;
2cf0635d
NC
12353 unsigned char * edata;
12354 unsigned short * data;
12355 char * strtab;
12356 Elf_Internal_Sym * symbols;
12357 Elf_Internal_Shdr * string_sec;
ba5cdace 12358 unsigned long num_syms;
d3ba0551 12359 long off;
252b5132 12360
dda8d76d 12361 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12362 break;
12363
dda8d76d 12364 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12365 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12366
dda8d76d 12367 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12368 break;
12369
015dc7e1 12370 found = true;
252b5132 12371
4de91c10 12372 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12373 if (symbols == NULL)
12374 break;
252b5132 12375
dda8d76d 12376 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12377
dda8d76d 12378 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12379 string_sec->sh_size,
12380 _("version string table"));
a6e9f9df 12381 if (!strtab)
0429c154
MS
12382 {
12383 free (symbols);
12384 break;
12385 }
252b5132 12386
ca0e11aa
NC
12387 if (filedata->is_separate)
12388 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12389 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12390 total),
12391 filedata->file_name,
12392 printable_section_name (filedata, section),
12393 (unsigned long) total);
12394 else
12395 printf (ngettext ("\nVersion symbols section '%s' "
12396 "contains %lu entry:\n",
12397 "\nVersion symbols section '%s' "
12398 "contains %lu entries:\n",
12399 total),
12400 printable_section_name (filedata, section),
12401 (unsigned long) total);
252b5132 12402
ae9ac79e 12403 printf (_(" Addr: 0x"));
252b5132 12404 printf_vma (section->sh_addr);
72de5009 12405 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12406 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12407 printable_section_name (filedata, link_section));
252b5132 12408
dda8d76d 12409 off = offset_from_vma (filedata,
978c4450 12410 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12411 total * sizeof (short));
95099889
AM
12412 edata = (unsigned char *) get_data (NULL, filedata, off,
12413 sizeof (short), total,
12414 _("version symbol data"));
a6e9f9df
AM
12415 if (!edata)
12416 {
12417 free (strtab);
0429c154 12418 free (symbols);
a6e9f9df
AM
12419 break;
12420 }
252b5132 12421
3f5e193b 12422 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12423
12424 for (cnt = total; cnt --;)
b34976b6
AM
12425 data[cnt] = byte_get (edata + cnt * sizeof (short),
12426 sizeof (short));
252b5132
RH
12427
12428 free (edata);
12429
12430 for (cnt = 0; cnt < total; cnt += 4)
12431 {
12432 int j, nn;
ab273396
AM
12433 char *name;
12434 char *invalid = _("*invalid*");
252b5132
RH
12435
12436 printf (" %03x:", cnt);
12437
12438 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12439 switch (data[cnt + j])
252b5132
RH
12440 {
12441 case 0:
12442 fputs (_(" 0 (*local*) "), stdout);
12443 break;
12444
12445 case 1:
12446 fputs (_(" 1 (*global*) "), stdout);
12447 break;
12448
12449 default:
c244d050
NC
12450 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12451 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12452
dd24e3da 12453 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12454 array, break to avoid an out-of-bounds read. */
12455 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12456 {
12457 warn (_("invalid index into symbol array\n"));
12458 break;
12459 }
12460
ab273396 12461 name = NULL;
978c4450 12462 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12463 {
b34976b6
AM
12464 Elf_Internal_Verneed ivn;
12465 unsigned long offset;
252b5132 12466
d93f0186 12467 offset = offset_from_vma
978c4450
AM
12468 (filedata,
12469 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12470 sizeof (Elf_External_Verneed));
252b5132 12471
b34976b6 12472 do
252b5132 12473 {
b34976b6
AM
12474 Elf_Internal_Vernaux ivna;
12475 Elf_External_Verneed evn;
12476 Elf_External_Vernaux evna;
12477 unsigned long a_off;
252b5132 12478
dda8d76d 12479 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12480 _("version need")) == NULL)
12481 break;
0b4362b0 12482
252b5132
RH
12483 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12484 ivn.vn_next = BYTE_GET (evn.vn_next);
12485
12486 a_off = offset + ivn.vn_aux;
12487
12488 do
12489 {
dda8d76d 12490 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12491 1, _("version need aux (2)")) == NULL)
12492 {
12493 ivna.vna_next = 0;
12494 ivna.vna_other = 0;
12495 }
12496 else
12497 {
12498 ivna.vna_next = BYTE_GET (evna.vna_next);
12499 ivna.vna_other = BYTE_GET (evna.vna_other);
12500 }
252b5132
RH
12501
12502 a_off += ivna.vna_next;
12503 }
b34976b6 12504 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12505 && ivna.vna_next != 0);
12506
b34976b6 12507 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12508 {
12509 ivna.vna_name = BYTE_GET (evna.vna_name);
12510
54806181 12511 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12512 name = invalid;
54806181
AM
12513 else
12514 name = strtab + ivna.vna_name;
252b5132
RH
12515 break;
12516 }
12517
12518 offset += ivn.vn_next;
12519 }
12520 while (ivn.vn_next);
12521 }
00d93f34 12522
ab273396 12523 if (data[cnt + j] != 0x8001
978c4450 12524 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12525 {
b34976b6
AM
12526 Elf_Internal_Verdef ivd;
12527 Elf_External_Verdef evd;
12528 unsigned long offset;
252b5132 12529
d93f0186 12530 offset = offset_from_vma
978c4450
AM
12531 (filedata,
12532 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12533 sizeof evd);
252b5132
RH
12534
12535 do
12536 {
dda8d76d 12537 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12538 _("version def")) == NULL)
12539 {
12540 ivd.vd_next = 0;
948f632f 12541 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12542 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12543 break;
59245841
NC
12544 }
12545 else
12546 {
12547 ivd.vd_next = BYTE_GET (evd.vd_next);
12548 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12549 }
252b5132
RH
12550
12551 offset += ivd.vd_next;
12552 }
c244d050 12553 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12554 && ivd.vd_next != 0);
12555
c244d050 12556 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12557 {
b34976b6
AM
12558 Elf_External_Verdaux evda;
12559 Elf_Internal_Verdaux ivda;
252b5132
RH
12560
12561 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12562
dda8d76d 12563 if (get_data (&evda, filedata,
59245841
NC
12564 offset - ivd.vd_next + ivd.vd_aux,
12565 sizeof (evda), 1,
12566 _("version def aux")) == NULL)
12567 break;
252b5132
RH
12568
12569 ivda.vda_name = BYTE_GET (evda.vda_name);
12570
54806181 12571 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12572 name = invalid;
12573 else if (name != NULL && name != invalid)
12574 name = _("*both*");
54806181
AM
12575 else
12576 name = strtab + ivda.vda_name;
252b5132
RH
12577 }
12578 }
ab273396
AM
12579 if (name != NULL)
12580 nn += printf ("(%s%-*s",
12581 name,
12582 12 - (int) strlen (name),
12583 ")");
252b5132
RH
12584
12585 if (nn < 18)
12586 printf ("%*c", 18 - nn, ' ');
12587 }
12588
12589 putchar ('\n');
12590 }
12591
12592 free (data);
12593 free (strtab);
12594 free (symbols);
12595 }
12596 break;
103f02d3 12597
252b5132
RH
12598 default:
12599 break;
12600 }
12601 }
12602
12603 if (! found)
ca0e11aa
NC
12604 {
12605 if (filedata->is_separate)
12606 printf (_("\nNo version information found in linked file '%s'.\n"),
12607 filedata->file_name);
12608 else
12609 printf (_("\nNo version information found in this file.\n"));
12610 }
252b5132 12611
015dc7e1 12612 return true;
252b5132
RH
12613}
12614
d1133906 12615static const char *
dda8d76d 12616get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12617{
89246a0e 12618 static char buff[64];
252b5132
RH
12619
12620 switch (binding)
12621 {
b34976b6
AM
12622 case STB_LOCAL: return "LOCAL";
12623 case STB_GLOBAL: return "GLOBAL";
12624 case STB_WEAK: return "WEAK";
252b5132
RH
12625 default:
12626 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12627 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12628 binding);
252b5132 12629 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12630 {
12631 if (binding == STB_GNU_UNIQUE
df3a023b 12632 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12633 return "UNIQUE";
12634 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12635 }
252b5132 12636 else
e9e44622 12637 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12638 return buff;
12639 }
12640}
12641
d1133906 12642static const char *
dda8d76d 12643get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12644{
89246a0e 12645 static char buff[64];
252b5132
RH
12646
12647 switch (type)
12648 {
b34976b6
AM
12649 case STT_NOTYPE: return "NOTYPE";
12650 case STT_OBJECT: return "OBJECT";
12651 case STT_FUNC: return "FUNC";
12652 case STT_SECTION: return "SECTION";
12653 case STT_FILE: return "FILE";
12654 case STT_COMMON: return "COMMON";
12655 case STT_TLS: return "TLS";
15ab5209
DB
12656 case STT_RELC: return "RELC";
12657 case STT_SRELC: return "SRELC";
252b5132
RH
12658 default:
12659 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12660 {
dda8d76d 12661 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12662 return "THUMB_FUNC";
103f02d3 12663
dda8d76d 12664 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12665 return "REGISTER";
12666
dda8d76d 12667 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12668 return "PARISC_MILLI";
12669
e9e44622 12670 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12671 }
252b5132 12672 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12673 {
dda8d76d 12674 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12675 {
12676 if (type == STT_HP_OPAQUE)
12677 return "HP_OPAQUE";
12678 if (type == STT_HP_STUB)
12679 return "HP_STUB";
12680 }
12681
d8045f23 12682 if (type == STT_GNU_IFUNC
dda8d76d 12683 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12684 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12685 return "IFUNC";
12686
e9e44622 12687 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12688 }
252b5132 12689 else
e9e44622 12690 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12691 return buff;
12692 }
12693}
12694
d1133906 12695static const char *
d3ba0551 12696get_symbol_visibility (unsigned int visibility)
d1133906
NC
12697{
12698 switch (visibility)
12699 {
b34976b6
AM
12700 case STV_DEFAULT: return "DEFAULT";
12701 case STV_INTERNAL: return "INTERNAL";
12702 case STV_HIDDEN: return "HIDDEN";
d1133906 12703 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12704 default:
27a45f42 12705 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12706 return _("<unknown>");
d1133906
NC
12707 }
12708}
12709
2057d69d
CZ
12710static const char *
12711get_alpha_symbol_other (unsigned int other)
9abca702 12712{
2057d69d
CZ
12713 switch (other)
12714 {
12715 case STO_ALPHA_NOPV: return "NOPV";
12716 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12717 default:
27a45f42 12718 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12719 return _("<unknown>");
9abca702 12720 }
2057d69d
CZ
12721}
12722
fd85a6a1
NC
12723static const char *
12724get_solaris_symbol_visibility (unsigned int visibility)
12725{
12726 switch (visibility)
12727 {
12728 case 4: return "EXPORTED";
12729 case 5: return "SINGLETON";
12730 case 6: return "ELIMINATE";
12731 default: return get_symbol_visibility (visibility);
12732 }
12733}
12734
2301ed1c
SN
12735static const char *
12736get_aarch64_symbol_other (unsigned int other)
12737{
12738 static char buf[32];
12739
12740 if (other & STO_AARCH64_VARIANT_PCS)
12741 {
12742 other &= ~STO_AARCH64_VARIANT_PCS;
12743 if (other == 0)
12744 return "VARIANT_PCS";
12745 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12746 return buf;
12747 }
12748 return NULL;
12749}
12750
5e2b0d47
NC
12751static const char *
12752get_mips_symbol_other (unsigned int other)
12753{
12754 switch (other)
12755 {
32ec8896
NC
12756 case STO_OPTIONAL: return "OPTIONAL";
12757 case STO_MIPS_PLT: return "MIPS PLT";
12758 case STO_MIPS_PIC: return "MIPS PIC";
12759 case STO_MICROMIPS: return "MICROMIPS";
12760 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12761 case STO_MIPS16: return "MIPS16";
12762 default: return NULL;
5e2b0d47
NC
12763 }
12764}
12765
28f997cf 12766static const char *
dda8d76d 12767get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12768{
dda8d76d 12769 if (is_ia64_vms (filedata))
28f997cf
TG
12770 {
12771 static char res[32];
12772
12773 res[0] = 0;
12774
12775 /* Function types is for images and .STB files only. */
dda8d76d 12776 switch (filedata->file_header.e_type)
28f997cf
TG
12777 {
12778 case ET_DYN:
12779 case ET_EXEC:
12780 switch (VMS_ST_FUNC_TYPE (other))
12781 {
12782 case VMS_SFT_CODE_ADDR:
12783 strcat (res, " CA");
12784 break;
12785 case VMS_SFT_SYMV_IDX:
12786 strcat (res, " VEC");
12787 break;
12788 case VMS_SFT_FD:
12789 strcat (res, " FD");
12790 break;
12791 case VMS_SFT_RESERVE:
12792 strcat (res, " RSV");
12793 break;
12794 default:
bee0ee85
NC
12795 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12796 VMS_ST_FUNC_TYPE (other));
12797 strcat (res, " <unknown>");
12798 break;
28f997cf
TG
12799 }
12800 break;
12801 default:
12802 break;
12803 }
12804 switch (VMS_ST_LINKAGE (other))
12805 {
12806 case VMS_STL_IGNORE:
12807 strcat (res, " IGN");
12808 break;
12809 case VMS_STL_RESERVE:
12810 strcat (res, " RSV");
12811 break;
12812 case VMS_STL_STD:
12813 strcat (res, " STD");
12814 break;
12815 case VMS_STL_LNK:
12816 strcat (res, " LNK");
12817 break;
12818 default:
bee0ee85
NC
12819 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12820 VMS_ST_LINKAGE (other));
12821 strcat (res, " <unknown>");
12822 break;
28f997cf
TG
12823 }
12824
12825 if (res[0] != 0)
12826 return res + 1;
12827 else
12828 return res;
12829 }
12830 return NULL;
12831}
12832
6911b7dc
AM
12833static const char *
12834get_ppc64_symbol_other (unsigned int other)
12835{
14732552
AM
12836 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12837 return NULL;
12838
12839 other >>= STO_PPC64_LOCAL_BIT;
12840 if (other <= 6)
6911b7dc 12841 {
89246a0e 12842 static char buf[64];
14732552
AM
12843 if (other >= 2)
12844 other = ppc64_decode_local_entry (other);
12845 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12846 return buf;
12847 }
12848 return NULL;
12849}
12850
8155b853
NC
12851static const char *
12852get_riscv_symbol_other (unsigned int other)
12853{
12854 static char buf[32];
12855 buf[0] = 0;
12856
12857 if (other & STO_RISCV_VARIANT_CC)
12858 {
12859 strcat (buf, _(" VARIANT_CC"));
12860 other &= ~STO_RISCV_VARIANT_CC;
12861 }
12862
12863 if (other != 0)
12864 snprintf (buf, sizeof buf, " %x", other);
12865
12866
12867 if (buf[0] != 0)
12868 return buf + 1;
12869 else
12870 return buf;
12871}
12872
5e2b0d47 12873static const char *
dda8d76d 12874get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12875{
12876 const char * result = NULL;
89246a0e 12877 static char buff [64];
5e2b0d47
NC
12878
12879 if (other == 0)
12880 return "";
12881
dda8d76d 12882 switch (filedata->file_header.e_machine)
5e2b0d47 12883 {
2057d69d
CZ
12884 case EM_ALPHA:
12885 result = get_alpha_symbol_other (other);
12886 break;
2301ed1c
SN
12887 case EM_AARCH64:
12888 result = get_aarch64_symbol_other (other);
12889 break;
5e2b0d47
NC
12890 case EM_MIPS:
12891 result = get_mips_symbol_other (other);
28f997cf
TG
12892 break;
12893 case EM_IA_64:
dda8d76d 12894 result = get_ia64_symbol_other (filedata, other);
28f997cf 12895 break;
6911b7dc
AM
12896 case EM_PPC64:
12897 result = get_ppc64_symbol_other (other);
12898 break;
8155b853
NC
12899 case EM_RISCV:
12900 result = get_riscv_symbol_other (other);
12901 break;
5e2b0d47 12902 default:
fd85a6a1 12903 result = NULL;
5e2b0d47
NC
12904 break;
12905 }
12906
12907 if (result)
12908 return result;
12909
12910 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12911 return buff;
12912}
12913
d1133906 12914static const char *
dda8d76d 12915get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12916{
b34976b6 12917 static char buff[32];
5cf1065c 12918
252b5132
RH
12919 switch (type)
12920 {
b34976b6
AM
12921 case SHN_UNDEF: return "UND";
12922 case SHN_ABS: return "ABS";
12923 case SHN_COMMON: return "COM";
252b5132 12924 default:
9ce701e2 12925 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12926 && filedata->file_header.e_machine == EM_IA_64
12927 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12928 return "ANSI_COM";
12929 else if ((filedata->file_header.e_machine == EM_X86_64
12930 || filedata->file_header.e_machine == EM_L1OM
12931 || filedata->file_header.e_machine == EM_K1OM)
12932 && type == SHN_X86_64_LCOMMON)
12933 return "LARGE_COM";
12934 else if ((type == SHN_MIPS_SCOMMON
12935 && filedata->file_header.e_machine == EM_MIPS)
12936 || (type == SHN_TIC6X_SCOMMON
12937 && filedata->file_header.e_machine == EM_TI_C6000))
12938 return "SCOM";
12939 else if (type == SHN_MIPS_SUNDEFINED
12940 && filedata->file_header.e_machine == EM_MIPS)
12941 return "SUND";
12942 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12943 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12944 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12945 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12946 else if (type >= SHN_LORESERVE)
12947 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12948 else if (filedata->file_header.e_shnum != 0
12949 && type >= filedata->file_header.e_shnum)
12950 sprintf (buff, _("bad section index[%3d]"), type);
12951 else
12952 sprintf (buff, "%3d", type);
12953 break;
fd85a6a1
NC
12954 }
12955
10ca4b04 12956 return buff;
6bd1a22c
L
12957}
12958
bb4d2ac2 12959static const char *
dda8d76d 12960get_symbol_version_string (Filedata * filedata,
015dc7e1 12961 bool is_dynsym,
1449284b
NC
12962 const char * strtab,
12963 unsigned long int strtab_size,
12964 unsigned int si,
12965 Elf_Internal_Sym * psym,
12966 enum versioned_symbol_info * sym_info,
12967 unsigned short * vna_other)
bb4d2ac2 12968{
ab273396
AM
12969 unsigned char data[2];
12970 unsigned short vers_data;
12971 unsigned long offset;
7a815dd5 12972 unsigned short max_vd_ndx;
bb4d2ac2 12973
ab273396 12974 if (!is_dynsym
978c4450 12975 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12976 return NULL;
bb4d2ac2 12977
978c4450
AM
12978 offset = offset_from_vma (filedata,
12979 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12980 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12981
dda8d76d 12982 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12983 sizeof (data), 1, _("version data")) == NULL)
12984 return NULL;
12985
12986 vers_data = byte_get (data, 2);
bb4d2ac2 12987
1f6f5dba 12988 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12989 return NULL;
bb4d2ac2 12990
0b8b7609 12991 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12992 max_vd_ndx = 0;
12993
ab273396
AM
12994 /* Usually we'd only see verdef for defined symbols, and verneed for
12995 undefined symbols. However, symbols defined by the linker in
12996 .dynbss for variables copied from a shared library in order to
12997 avoid text relocations are defined yet have verneed. We could
12998 use a heuristic to detect the special case, for example, check
12999 for verneed first on symbols defined in SHT_NOBITS sections, but
13000 it is simpler and more reliable to just look for both verdef and
13001 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13002
ab273396
AM
13003 if (psym->st_shndx != SHN_UNDEF
13004 && vers_data != 0x8001
978c4450 13005 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13006 {
13007 Elf_Internal_Verdef ivd;
13008 Elf_Internal_Verdaux ivda;
13009 Elf_External_Verdaux evda;
13010 unsigned long off;
bb4d2ac2 13011
dda8d76d 13012 off = offset_from_vma (filedata,
978c4450 13013 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13014 sizeof (Elf_External_Verdef));
13015
13016 do
bb4d2ac2 13017 {
ab273396
AM
13018 Elf_External_Verdef evd;
13019
dda8d76d 13020 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13021 _("version def")) == NULL)
13022 {
13023 ivd.vd_ndx = 0;
13024 ivd.vd_aux = 0;
13025 ivd.vd_next = 0;
1f6f5dba 13026 ivd.vd_flags = 0;
ab273396
AM
13027 }
13028 else
bb4d2ac2 13029 {
ab273396
AM
13030 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13031 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13032 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13033 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13034 }
bb4d2ac2 13035
7a815dd5
L
13036 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13037 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13038
ab273396
AM
13039 off += ivd.vd_next;
13040 }
13041 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13042
ab273396
AM
13043 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13044 {
9abca702 13045 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13046 return NULL;
13047
ab273396
AM
13048 off -= ivd.vd_next;
13049 off += ivd.vd_aux;
bb4d2ac2 13050
dda8d76d 13051 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13052 _("version def aux")) != NULL)
13053 {
13054 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13055
ab273396 13056 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13057 return (ivda.vda_name < strtab_size
13058 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13059 }
13060 }
13061 }
bb4d2ac2 13062
978c4450 13063 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13064 {
13065 Elf_External_Verneed evn;
13066 Elf_Internal_Verneed ivn;
13067 Elf_Internal_Vernaux ivna;
bb4d2ac2 13068
dda8d76d 13069 offset = offset_from_vma (filedata,
978c4450 13070 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13071 sizeof evn);
13072 do
13073 {
13074 unsigned long vna_off;
bb4d2ac2 13075
dda8d76d 13076 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13077 _("version need")) == NULL)
13078 {
13079 ivna.vna_next = 0;
13080 ivna.vna_other = 0;
13081 ivna.vna_name = 0;
13082 break;
13083 }
bb4d2ac2 13084
ab273396
AM
13085 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13086 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13087
ab273396 13088 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13089
ab273396
AM
13090 do
13091 {
13092 Elf_External_Vernaux evna;
bb4d2ac2 13093
dda8d76d 13094 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13095 _("version need aux (3)")) == NULL)
bb4d2ac2 13096 {
ab273396
AM
13097 ivna.vna_next = 0;
13098 ivna.vna_other = 0;
13099 ivna.vna_name = 0;
bb4d2ac2 13100 }
bb4d2ac2 13101 else
bb4d2ac2 13102 {
ab273396
AM
13103 ivna.vna_other = BYTE_GET (evna.vna_other);
13104 ivna.vna_next = BYTE_GET (evna.vna_next);
13105 ivna.vna_name = BYTE_GET (evna.vna_name);
13106 }
bb4d2ac2 13107
ab273396
AM
13108 vna_off += ivna.vna_next;
13109 }
13110 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13111
ab273396
AM
13112 if (ivna.vna_other == vers_data)
13113 break;
bb4d2ac2 13114
ab273396
AM
13115 offset += ivn.vn_next;
13116 }
13117 while (ivn.vn_next != 0);
bb4d2ac2 13118
ab273396
AM
13119 if (ivna.vna_other == vers_data)
13120 {
13121 *sym_info = symbol_undefined;
13122 *vna_other = ivna.vna_other;
13123 return (ivna.vna_name < strtab_size
13124 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13125 }
7a815dd5
L
13126 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13127 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13128 return _("<corrupt>");
bb4d2ac2 13129 }
ab273396 13130 return NULL;
bb4d2ac2
L
13131}
13132
047c3dbf
NL
13133/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13134
13135static unsigned int
13136print_dynamic_symbol_size (bfd_vma vma, int base)
13137{
13138 switch (base)
13139 {
13140 case 8:
13141 return print_vma (vma, OCTAL_5);
13142
13143 case 10:
13144 return print_vma (vma, UNSIGNED_5);
13145
13146 case 16:
13147 return print_vma (vma, PREFIX_HEX_5);
13148
13149 case 0:
13150 default:
13151 return print_vma (vma, DEC_5);
13152 }
13153}
13154
10ca4b04
L
13155static void
13156print_dynamic_symbol (Filedata *filedata, unsigned long si,
13157 Elf_Internal_Sym *symtab,
13158 Elf_Internal_Shdr *section,
13159 char *strtab, size_t strtab_size)
252b5132 13160{
10ca4b04
L
13161 const char *version_string;
13162 enum versioned_symbol_info sym_info;
13163 unsigned short vna_other;
23356397
NC
13164 bool is_valid;
13165 const char * sstr;
10ca4b04 13166 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13167
10ca4b04
L
13168 printf ("%6ld: ", si);
13169 print_vma (psym->st_value, LONG_HEX);
13170 putchar (' ');
047c3dbf 13171 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13172 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13173 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13174 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13175 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13176 else
252b5132 13177 {
10ca4b04 13178 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13179
10ca4b04
L
13180 printf (" %-7s", get_symbol_visibility (vis));
13181 /* Check to see if any other bits in the st_other field are set.
13182 Note - displaying this information disrupts the layout of the
13183 table being generated, but for the moment this case is very rare. */
13184 if (psym->st_other ^ vis)
13185 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13186 }
10ca4b04 13187 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13188
23356397
NC
13189 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13190 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13191 && filedata->section_headers != NULL
23356397
NC
13192 && psym->st_name == 0)
13193 {
84714f86
AM
13194 is_valid
13195 = section_name_valid (filedata,
13196 filedata->section_headers + psym->st_shndx);
23356397 13197 sstr = is_valid ?
84714f86
AM
13198 section_name_print (filedata,
13199 filedata->section_headers + psym->st_shndx)
23356397
NC
13200 : _("<corrupt>");
13201 }
13202 else
13203 {
84714f86 13204 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13205 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13206 }
10ca4b04
L
13207
13208 version_string
13209 = get_symbol_version_string (filedata,
13210 (section == NULL
13211 || section->sh_type == SHT_DYNSYM),
13212 strtab, strtab_size, si,
13213 psym, &sym_info, &vna_other);
b9e920ec 13214
0942c7ab
NC
13215 int len_avail = 21;
13216 if (! do_wide && version_string != NULL)
13217 {
ddb43bab 13218 char buffer[16];
0942c7ab 13219
ddb43bab 13220 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13221
13222 if (sym_info == symbol_undefined)
13223 len_avail -= sprintf (buffer," (%d)", vna_other);
13224 else if (sym_info != symbol_hidden)
13225 len_avail -= 1;
13226 }
13227
13228 print_symbol (len_avail, sstr);
b9e920ec 13229
10ca4b04
L
13230 if (version_string)
13231 {
13232 if (sym_info == symbol_undefined)
13233 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13234 else
10ca4b04
L
13235 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13236 version_string);
13237 }
6bd1a22c 13238
10ca4b04 13239 putchar ('\n');
6bd1a22c 13240
10ca4b04
L
13241 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13242 && section != NULL
13243 && si >= section->sh_info
13244 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13245 && filedata->file_header.e_machine != EM_MIPS
13246 /* Solaris binaries have been found to violate this requirement as
13247 well. Not sure if this is a bug or an ABI requirement. */
13248 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13249 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13250 si, printable_section_name (filedata, section), section->sh_info);
13251}
f16a9783 13252
0f03783c
NC
13253static const char *
13254get_lto_kind (unsigned int kind)
13255{
13256 switch (kind)
13257 {
13258 case 0: return "DEF";
13259 case 1: return "WEAKDEF";
13260 case 2: return "UNDEF";
13261 case 3: return "WEAKUNDEF";
13262 case 4: return "COMMON";
13263 default:
13264 break;
13265 }
13266
13267 static char buffer[30];
13268 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13269 sprintf (buffer, "<unknown: %u>", kind);
13270 return buffer;
13271}
13272
13273static const char *
13274get_lto_visibility (unsigned int visibility)
13275{
13276 switch (visibility)
13277 {
13278 case 0: return "DEFAULT";
13279 case 1: return "PROTECTED";
13280 case 2: return "INTERNAL";
13281 case 3: return "HIDDEN";
13282 default:
13283 break;
13284 }
13285
13286 static char buffer[30];
13287 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13288 sprintf (buffer, "<unknown: %u>", visibility);
13289 return buffer;
13290}
13291
13292static const char *
13293get_lto_sym_type (unsigned int sym_type)
13294{
13295 switch (sym_type)
13296 {
13297 case 0: return "UNKNOWN";
13298 case 1: return "FUNCTION";
13299 case 2: return "VARIABLE";
13300 default:
13301 break;
13302 }
13303
13304 static char buffer[30];
13305 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13306 sprintf (buffer, "<unknown: %u>", sym_type);
13307 return buffer;
13308}
13309
13310/* Display an LTO format symbol table.
13311 FIXME: The format of LTO symbol tables is not formalized.
13312 So this code could need changing in the future. */
13313
015dc7e1 13314static bool
0f03783c
NC
13315display_lto_symtab (Filedata * filedata,
13316 Elf_Internal_Shdr * section)
13317{
13318 if (section->sh_size == 0)
13319 {
ca0e11aa
NC
13320 if (filedata->is_separate)
13321 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13322 printable_section_name (filedata, section),
13323 filedata->file_name);
13324 else
13325 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13326 printable_section_name (filedata, section));
047c3dbf 13327
015dc7e1 13328 return true;
0f03783c
NC
13329 }
13330
13331 if (section->sh_size > filedata->file_size)
13332 {
13333 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13334 printable_section_name (filedata, section),
13335 (unsigned long) section->sh_size);
015dc7e1 13336 return false;
0f03783c
NC
13337 }
13338
13339 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13340 section->sh_size, 1, _("LTO symbols"));
13341 if (alloced_data == NULL)
015dc7e1 13342 return false;
0f03783c
NC
13343
13344 /* Look for extended data for the symbol table. */
13345 Elf_Internal_Shdr * ext;
13346 void * ext_data_orig = NULL;
13347 char * ext_data = NULL;
13348 char * ext_data_end = NULL;
13349 char * ext_name = NULL;
13350
13351 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13352 (section_name (filedata, section)
13353 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13354 && ext_name != NULL /* Paranoia. */
13355 && (ext = find_section (filedata, ext_name)) != NULL)
13356 {
13357 if (ext->sh_size < 3)
13358 error (_("LTO Symbol extension table '%s' is empty!\n"),
13359 printable_section_name (filedata, ext));
13360 else
13361 {
13362 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13363 ext->sh_size, 1,
13364 _("LTO ext symbol data"));
13365 if (ext_data != NULL)
13366 {
13367 ext_data_end = ext_data + ext->sh_size;
13368 if (* ext_data++ != 1)
13369 error (_("Unexpected version number in symbol extension table\n"));
13370 }
13371 }
13372 }
b9e920ec 13373
0f03783c
NC
13374 const unsigned char * data = (const unsigned char *) alloced_data;
13375 const unsigned char * end = data + section->sh_size;
13376
ca0e11aa
NC
13377 if (filedata->is_separate)
13378 printf (_("\nIn linked file '%s': "), filedata->file_name);
13379 else
13380 printf ("\n");
13381
0f03783c
NC
13382 if (ext_data_orig != NULL)
13383 {
13384 if (do_wide)
ca0e11aa 13385 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13386 printable_section_name (filedata, section),
13387 printable_section_name (filedata, ext));
13388 else
13389 {
ca0e11aa 13390 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13391 printable_section_name (filedata, section));
13392 printf (_(" and extension table '%s' contain:\n"),
13393 printable_section_name (filedata, ext));
13394 }
13395 }
13396 else
ca0e11aa 13397 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13398 printable_section_name (filedata, section));
b9e920ec 13399
0f03783c 13400 /* FIXME: Add a wide version. */
b9e920ec 13401 if (ext_data_orig != NULL)
0f03783c
NC
13402 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13403 else
13404 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13405
13406 /* FIXME: We do not handle style prefixes. */
13407
13408 while (data < end)
13409 {
13410 const unsigned char * sym_name = data;
13411 data += strnlen ((const char *) sym_name, end - data) + 1;
13412 if (data >= end)
13413 goto fail;
13414
13415 const unsigned char * comdat_key = data;
13416 data += strnlen ((const char *) comdat_key, end - data) + 1;
13417 if (data >= end)
13418 goto fail;
13419
13420 if (data + 2 + 8 + 4 > end)
13421 goto fail;
13422
13423 unsigned int kind = *data++;
13424 unsigned int visibility = *data++;
13425
13426 elf_vma size = byte_get (data, 8);
13427 data += 8;
13428
13429 elf_vma slot = byte_get (data, 4);
13430 data += 4;
13431
13432 if (ext_data != NULL)
13433 {
13434 if (ext_data < (ext_data_end - 1))
13435 {
13436 unsigned int sym_type = * ext_data ++;
13437 unsigned int sec_kind = * ext_data ++;
13438
13439 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13440 * comdat_key == 0 ? "-" : (char *) comdat_key,
13441 get_lto_kind (kind),
13442 get_lto_visibility (visibility),
13443 (long) size,
13444 (long) slot,
13445 get_lto_sym_type (sym_type),
13446 (long) sec_kind);
13447 print_symbol (6, (const char *) sym_name);
13448 }
13449 else
13450 {
13451 error (_("Ran out of LTO symbol extension data\n"));
13452 ext_data = NULL;
13453 /* FIXME: return FAIL result ? */
13454 }
13455 }
13456 else
13457 {
13458 printf (" %10s %10s %11s %08lx %08lx _",
13459 * comdat_key == 0 ? "-" : (char *) comdat_key,
13460 get_lto_kind (kind),
13461 get_lto_visibility (visibility),
13462 (long) size,
13463 (long) slot);
13464 print_symbol (21, (const char *) sym_name);
13465 }
13466 putchar ('\n');
13467 }
13468
13469 if (ext_data != NULL && ext_data < ext_data_end)
13470 {
13471 error (_("Data remains in the LTO symbol extension table\n"));
13472 goto fail;
13473 }
13474
13475 free (alloced_data);
13476 free (ext_data_orig);
13477 free (ext_name);
015dc7e1 13478 return true;
b9e920ec 13479
0f03783c
NC
13480 fail:
13481 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13482 free (alloced_data);
13483 free (ext_data_orig);
13484 free (ext_name);
015dc7e1 13485 return false;
0f03783c
NC
13486}
13487
13488/* Display LTO symbol tables. */
13489
015dc7e1 13490static bool
0f03783c
NC
13491process_lto_symbol_tables (Filedata * filedata)
13492{
13493 Elf_Internal_Shdr * section;
13494 unsigned int i;
015dc7e1 13495 bool res = true;
0f03783c
NC
13496
13497 if (!do_lto_syms)
015dc7e1 13498 return true;
0f03783c
NC
13499
13500 if (filedata->section_headers == NULL)
015dc7e1 13501 return true;
0f03783c
NC
13502
13503 for (i = 0, section = filedata->section_headers;
13504 i < filedata->file_header.e_shnum;
13505 i++, section++)
84714f86
AM
13506 if (section_name_valid (filedata, section)
13507 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13508 res &= display_lto_symtab (filedata, section);
13509
b9e920ec 13510 return res;
0f03783c
NC
13511}
13512
10ca4b04 13513/* Dump the symbol table. */
0f03783c 13514
015dc7e1 13515static bool
10ca4b04
L
13516process_symbol_table (Filedata * filedata)
13517{
13518 Elf_Internal_Shdr * section;
f16a9783 13519
10ca4b04 13520 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13521 return true;
6bd1a22c 13522
978c4450 13523 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13524 && do_syms
13525 && do_using_dynamic
978c4450
AM
13526 && filedata->dynamic_strings != NULL
13527 && filedata->dynamic_symbols != NULL)
6bd1a22c 13528 {
10ca4b04 13529 unsigned long si;
6bd1a22c 13530
ca0e11aa
NC
13531 if (filedata->is_separate)
13532 {
13533 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13534 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13535 filedata->num_dynamic_syms),
13536 filedata->file_name,
13537 filedata->num_dynamic_syms);
13538 }
13539 else
13540 {
13541 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13542 "\nSymbol table for image contains %lu entries:\n",
13543 filedata->num_dynamic_syms),
13544 filedata->num_dynamic_syms);
13545 }
10ca4b04
L
13546 if (is_32bit_elf)
13547 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13548 else
13549 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13550
978c4450
AM
13551 for (si = 0; si < filedata->num_dynamic_syms; si++)
13552 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13553 filedata->dynamic_strings,
13554 filedata->dynamic_strings_length);
252b5132 13555 }
8b73c356 13556 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13557 && filedata->section_headers != NULL)
252b5132 13558 {
b34976b6 13559 unsigned int i;
252b5132 13560
dda8d76d
NC
13561 for (i = 0, section = filedata->section_headers;
13562 i < filedata->file_header.e_shnum;
252b5132
RH
13563 i++, section++)
13564 {
2cf0635d 13565 char * strtab = NULL;
c256ffe7 13566 unsigned long int strtab_size = 0;
2cf0635d 13567 Elf_Internal_Sym * symtab;
ef3df110 13568 unsigned long si, num_syms;
252b5132 13569
2c610e4b
L
13570 if ((section->sh_type != SHT_SYMTAB
13571 && section->sh_type != SHT_DYNSYM)
13572 || (!do_syms
13573 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13574 continue;
13575
dd24e3da
NC
13576 if (section->sh_entsize == 0)
13577 {
13578 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13579 printable_section_name (filedata, section));
dd24e3da
NC
13580 continue;
13581 }
13582
d3a49aa8 13583 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13584
13585 if (filedata->is_separate)
13586 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13587 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13588 num_syms),
13589 filedata->file_name,
13590 printable_section_name (filedata, section),
13591 num_syms);
13592 else
13593 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13594 "\nSymbol table '%s' contains %lu entries:\n",
13595 num_syms),
13596 printable_section_name (filedata, section),
13597 num_syms);
dd24e3da 13598
f7a99963 13599 if (is_32bit_elf)
ca47b30c 13600 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13601 else
ca47b30c 13602 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13603
4de91c10 13604 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13605 if (symtab == NULL)
13606 continue;
13607
dda8d76d 13608 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13609 {
dda8d76d
NC
13610 strtab = filedata->string_table;
13611 strtab_size = filedata->string_table_length;
c256ffe7 13612 }
dda8d76d 13613 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13614 {
2cf0635d 13615 Elf_Internal_Shdr * string_sec;
252b5132 13616
dda8d76d 13617 string_sec = filedata->section_headers + section->sh_link;
252b5132 13618
dda8d76d 13619 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13620 1, string_sec->sh_size,
13621 _("string table"));
c256ffe7 13622 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13623 }
13624
10ca4b04
L
13625 for (si = 0; si < num_syms; si++)
13626 print_dynamic_symbol (filedata, si, symtab, section,
13627 strtab, strtab_size);
252b5132
RH
13628
13629 free (symtab);
dda8d76d 13630 if (strtab != filedata->string_table)
252b5132
RH
13631 free (strtab);
13632 }
13633 }
13634 else if (do_syms)
13635 printf
13636 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13637
978c4450 13638 if (do_histogram && filedata->buckets != NULL)
252b5132 13639 {
2cf0635d
NC
13640 unsigned long * lengths;
13641 unsigned long * counts;
66543521
AM
13642 unsigned long hn;
13643 bfd_vma si;
13644 unsigned long maxlength = 0;
13645 unsigned long nzero_counts = 0;
13646 unsigned long nsyms = 0;
6bd6a03d 13647 char *visited;
252b5132 13648
d3a49aa8
AM
13649 printf (ngettext ("\nHistogram for bucket list length "
13650 "(total of %lu bucket):\n",
13651 "\nHistogram for bucket list length "
13652 "(total of %lu buckets):\n",
978c4450
AM
13653 (unsigned long) filedata->nbuckets),
13654 (unsigned long) filedata->nbuckets);
252b5132 13655
978c4450
AM
13656 lengths = (unsigned long *) calloc (filedata->nbuckets,
13657 sizeof (*lengths));
252b5132
RH
13658 if (lengths == NULL)
13659 {
8b73c356 13660 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13661 goto err_out;
252b5132 13662 }
978c4450
AM
13663 visited = xcmalloc (filedata->nchains, 1);
13664 memset (visited, 0, filedata->nchains);
8b73c356
NC
13665
13666 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13667 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13668 {
978c4450 13669 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13670 {
b34976b6 13671 ++nsyms;
252b5132 13672 if (maxlength < ++lengths[hn])
b34976b6 13673 ++maxlength;
978c4450 13674 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13675 {
13676 error (_("histogram chain is corrupt\n"));
13677 break;
13678 }
13679 visited[si] = 1;
252b5132
RH
13680 }
13681 }
6bd6a03d 13682 free (visited);
252b5132 13683
3f5e193b 13684 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13685 if (counts == NULL)
13686 {
b2e951ec 13687 free (lengths);
8b73c356 13688 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13689 goto err_out;
252b5132
RH
13690 }
13691
978c4450 13692 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13693 ++counts[lengths[hn]];
252b5132 13694
978c4450 13695 if (filedata->nbuckets > 0)
252b5132 13696 {
66543521
AM
13697 unsigned long i;
13698 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13699 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13700 for (i = 1; i <= maxlength; ++i)
103f02d3 13701 {
66543521
AM
13702 nzero_counts += counts[i] * i;
13703 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13704 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13705 (nzero_counts * 100.0) / nsyms);
13706 }
252b5132
RH
13707 }
13708
13709 free (counts);
13710 free (lengths);
13711 }
13712
978c4450
AM
13713 free (filedata->buckets);
13714 filedata->buckets = NULL;
13715 filedata->nbuckets = 0;
13716 free (filedata->chains);
13717 filedata->chains = NULL;
252b5132 13718
978c4450 13719 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13720 {
2cf0635d
NC
13721 unsigned long * lengths;
13722 unsigned long * counts;
fdc90cb4
JJ
13723 unsigned long hn;
13724 unsigned long maxlength = 0;
13725 unsigned long nzero_counts = 0;
13726 unsigned long nsyms = 0;
fdc90cb4 13727
f16a9783 13728 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13729 "(total of %lu bucket):\n",
f16a9783 13730 "\nHistogram for `%s' bucket list length "
d3a49aa8 13731 "(total of %lu buckets):\n",
978c4450
AM
13732 (unsigned long) filedata->ngnubuckets),
13733 GNU_HASH_SECTION_NAME (filedata),
13734 (unsigned long) filedata->ngnubuckets);
8b73c356 13735
978c4450
AM
13736 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13737 sizeof (*lengths));
fdc90cb4
JJ
13738 if (lengths == NULL)
13739 {
8b73c356 13740 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13741 goto err_out;
fdc90cb4
JJ
13742 }
13743
fdc90cb4
JJ
13744 printf (_(" Length Number %% of total Coverage\n"));
13745
978c4450
AM
13746 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13747 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13748 {
13749 bfd_vma off, length = 1;
13750
978c4450 13751 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13752 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13753 off < filedata->ngnuchains
13754 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13755 ++off)
fdc90cb4
JJ
13756 ++length;
13757 lengths[hn] = length;
13758 if (length > maxlength)
13759 maxlength = length;
13760 nsyms += length;
13761 }
13762
3f5e193b 13763 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13764 if (counts == NULL)
13765 {
b2e951ec 13766 free (lengths);
8b73c356 13767 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13768 goto err_out;
fdc90cb4
JJ
13769 }
13770
978c4450 13771 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13772 ++counts[lengths[hn]];
13773
978c4450 13774 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13775 {
13776 unsigned long j;
13777 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13778 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13779 for (j = 1; j <= maxlength; ++j)
13780 {
13781 nzero_counts += counts[j] * j;
13782 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13783 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13784 (nzero_counts * 100.0) / nsyms);
13785 }
13786 }
13787
13788 free (counts);
13789 free (lengths);
fdc90cb4 13790 }
978c4450
AM
13791 free (filedata->gnubuckets);
13792 filedata->gnubuckets = NULL;
13793 filedata->ngnubuckets = 0;
13794 free (filedata->gnuchains);
13795 filedata->gnuchains = NULL;
13796 filedata->ngnuchains = 0;
13797 free (filedata->mipsxlat);
13798 filedata->mipsxlat = NULL;
015dc7e1 13799 return true;
fd486f32
AM
13800
13801 err_out:
978c4450
AM
13802 free (filedata->gnubuckets);
13803 filedata->gnubuckets = NULL;
13804 filedata->ngnubuckets = 0;
13805 free (filedata->gnuchains);
13806 filedata->gnuchains = NULL;
13807 filedata->ngnuchains = 0;
13808 free (filedata->mipsxlat);
13809 filedata->mipsxlat = NULL;
13810 free (filedata->buckets);
13811 filedata->buckets = NULL;
13812 filedata->nbuckets = 0;
13813 free (filedata->chains);
13814 filedata->chains = NULL;
015dc7e1 13815 return false;
252b5132
RH
13816}
13817
015dc7e1 13818static bool
ca0e11aa 13819process_syminfo (Filedata * filedata)
252b5132 13820{
b4c96d0d 13821 unsigned int i;
252b5132 13822
978c4450 13823 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13824 || !do_dynamic)
13825 /* No syminfo, this is ok. */
015dc7e1 13826 return true;
252b5132
RH
13827
13828 /* There better should be a dynamic symbol section. */
978c4450 13829 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13830 return false;
252b5132 13831
ca0e11aa
NC
13832 if (filedata->is_separate)
13833 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13834 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13835 filedata->dynamic_syminfo_nent),
13836 filedata->file_name,
13837 filedata->dynamic_syminfo_offset,
13838 filedata->dynamic_syminfo_nent);
13839 else
d3a49aa8
AM
13840 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13841 "contains %d entry:\n",
13842 "\nDynamic info segment at offset 0x%lx "
13843 "contains %d entries:\n",
978c4450 13844 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13845 filedata->dynamic_syminfo_offset,
13846 filedata->dynamic_syminfo_nent);
252b5132
RH
13847
13848 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13849 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13850 {
978c4450 13851 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13852
31104126 13853 printf ("%4d: ", i);
978c4450 13854 if (i >= filedata->num_dynamic_syms)
4082ef84 13855 printf (_("<corrupt index>"));
84714f86
AM
13856 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13857 print_symbol (30, get_dynamic_name (filedata,
978c4450 13858 filedata->dynamic_symbols[i].st_name));
d79b3d50 13859 else
978c4450 13860 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13861 putchar (' ');
252b5132 13862
978c4450 13863 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13864 {
13865 case SYMINFO_BT_SELF:
13866 fputs ("SELF ", stdout);
13867 break;
13868 case SYMINFO_BT_PARENT:
13869 fputs ("PARENT ", stdout);
13870 break;
13871 default:
978c4450
AM
13872 if (filedata->dynamic_syminfo[i].si_boundto > 0
13873 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13874 && valid_dynamic_name (filedata,
978c4450 13875 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13876 {
84714f86 13877 print_symbol (10, get_dynamic_name (filedata,
978c4450 13878 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13879 putchar (' ' );
13880 }
252b5132 13881 else
978c4450 13882 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13883 break;
13884 }
13885
13886 if (flags & SYMINFO_FLG_DIRECT)
13887 printf (" DIRECT");
13888 if (flags & SYMINFO_FLG_PASSTHRU)
13889 printf (" PASSTHRU");
13890 if (flags & SYMINFO_FLG_COPY)
13891 printf (" COPY");
13892 if (flags & SYMINFO_FLG_LAZYLOAD)
13893 printf (" LAZYLOAD");
13894
13895 puts ("");
13896 }
13897
015dc7e1 13898 return true;
252b5132
RH
13899}
13900
75802ccb
CE
13901/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13902 is contained by the region START .. END. The types of ADDR, START
13903 and END should all be the same. Note both ADDR + NELEM and END
13904 point to just beyond the end of the regions that are being tested. */
13905#define IN_RANGE(START,END,ADDR,NELEM) \
13906 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13907
cf13d699
NC
13908/* Check to see if the given reloc needs to be handled in a target specific
13909 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13910 FALSE.
13911
13912 If called with reloc == NULL, then this is a signal that reloc processing
13913 for the current section has finished, and any saved state should be
13914 discarded. */
09c11c86 13915
015dc7e1 13916static bool
dda8d76d
NC
13917target_specific_reloc_handling (Filedata * filedata,
13918 Elf_Internal_Rela * reloc,
13919 unsigned char * start,
13920 unsigned char * end,
13921 Elf_Internal_Sym * symtab,
13922 unsigned long num_syms)
252b5132 13923{
f84ce13b
NC
13924 unsigned int reloc_type = 0;
13925 unsigned long sym_index = 0;
13926
13927 if (reloc)
13928 {
dda8d76d 13929 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13930 sym_index = get_reloc_symindex (reloc->r_info);
13931 }
252b5132 13932
dda8d76d 13933 switch (filedata->file_header.e_machine)
252b5132 13934 {
13761a11
NC
13935 case EM_MSP430:
13936 case EM_MSP430_OLD:
13937 {
13938 static Elf_Internal_Sym * saved_sym = NULL;
13939
f84ce13b
NC
13940 if (reloc == NULL)
13941 {
13942 saved_sym = NULL;
015dc7e1 13943 return true;
f84ce13b
NC
13944 }
13945
13761a11
NC
13946 switch (reloc_type)
13947 {
13948 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13949 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13950 if (uses_msp430x_relocs (filedata))
13761a11 13951 break;
1a0670f3 13952 /* Fall through. */
13761a11 13953 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13954 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13955 /* PR 21139. */
13956 if (sym_index >= num_syms)
13957 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13958 sym_index);
13959 else
13960 saved_sym = symtab + sym_index;
015dc7e1 13961 return true;
13761a11
NC
13962
13963 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13964 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13965 goto handle_sym_diff;
0b4362b0 13966
13761a11
NC
13967 case 5: /* R_MSP430_16_BYTE */
13968 case 9: /* R_MSP430_8 */
7d81bc93 13969 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13970 if (uses_msp430x_relocs (filedata))
13761a11
NC
13971 break;
13972 goto handle_sym_diff;
13973
13974 case 2: /* R_MSP430_ABS16 */
13975 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13976 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13977 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13978 break;
13979 goto handle_sym_diff;
0b4362b0 13980
13761a11
NC
13981 handle_sym_diff:
13982 if (saved_sym != NULL)
13983 {
13984 bfd_vma value;
5a805384 13985 unsigned int reloc_size = 0;
7d81bc93
JL
13986 int leb_ret = 0;
13987 switch (reloc_type)
13988 {
13989 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13990 reloc_size = 4;
13991 break;
13992 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13993 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13994 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13995 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13996 &reloc_size, &leb_ret);
7d81bc93
JL
13997 break;
13998 default:
13999 reloc_size = 2;
14000 break;
14001 }
13761a11 14002
5a805384 14003 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
14004 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
14005 "ULEB128 value\n"),
14006 (long) reloc->r_offset);
14007 else if (sym_index >= num_syms)
f84ce13b
NC
14008 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
14009 sym_index);
03f7786e 14010 else
f84ce13b
NC
14011 {
14012 value = reloc->r_addend + (symtab[sym_index].st_value
14013 - saved_sym->st_value);
14014
b32e566b 14015 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14016 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14017 else
14018 /* PR 21137 */
14019 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14020 (long) reloc->r_offset);
f84ce13b 14021 }
13761a11
NC
14022
14023 saved_sym = NULL;
015dc7e1 14024 return true;
13761a11
NC
14025 }
14026 break;
14027
14028 default:
14029 if (saved_sym != NULL)
071436c6 14030 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14031 break;
14032 }
14033 break;
14034 }
14035
cf13d699
NC
14036 case EM_MN10300:
14037 case EM_CYGNUS_MN10300:
14038 {
14039 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14040
f84ce13b
NC
14041 if (reloc == NULL)
14042 {
14043 saved_sym = NULL;
015dc7e1 14044 return true;
f84ce13b
NC
14045 }
14046
cf13d699
NC
14047 switch (reloc_type)
14048 {
14049 case 34: /* R_MN10300_ALIGN */
015dc7e1 14050 return true;
cf13d699 14051 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14052 if (sym_index >= num_syms)
14053 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14054 sym_index);
14055 else
14056 saved_sym = symtab + sym_index;
015dc7e1 14057 return true;
f84ce13b 14058
cf13d699
NC
14059 case 1: /* R_MN10300_32 */
14060 case 2: /* R_MN10300_16 */
14061 if (saved_sym != NULL)
14062 {
03f7786e 14063 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 14064 bfd_vma value;
252b5132 14065
f84ce13b
NC
14066 if (sym_index >= num_syms)
14067 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14068 sym_index);
03f7786e 14069 else
f84ce13b
NC
14070 {
14071 value = reloc->r_addend + (symtab[sym_index].st_value
14072 - saved_sym->st_value);
14073
b32e566b 14074 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14075 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14076 else
14077 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14078 (long) reloc->r_offset);
f84ce13b 14079 }
252b5132 14080
cf13d699 14081 saved_sym = NULL;
015dc7e1 14082 return true;
cf13d699
NC
14083 }
14084 break;
14085 default:
14086 if (saved_sym != NULL)
071436c6 14087 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14088 break;
14089 }
14090 break;
14091 }
6ff71e76
NC
14092
14093 case EM_RL78:
14094 {
14095 static bfd_vma saved_sym1 = 0;
14096 static bfd_vma saved_sym2 = 0;
14097 static bfd_vma value;
14098
f84ce13b
NC
14099 if (reloc == NULL)
14100 {
14101 saved_sym1 = saved_sym2 = 0;
015dc7e1 14102 return true;
f84ce13b
NC
14103 }
14104
6ff71e76
NC
14105 switch (reloc_type)
14106 {
14107 case 0x80: /* R_RL78_SYM. */
14108 saved_sym1 = saved_sym2;
f84ce13b
NC
14109 if (sym_index >= num_syms)
14110 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14111 sym_index);
14112 else
14113 {
14114 saved_sym2 = symtab[sym_index].st_value;
14115 saved_sym2 += reloc->r_addend;
14116 }
015dc7e1 14117 return true;
6ff71e76
NC
14118
14119 case 0x83: /* R_RL78_OPsub. */
14120 value = saved_sym1 - saved_sym2;
14121 saved_sym2 = saved_sym1 = 0;
015dc7e1 14122 return true;
6ff71e76
NC
14123 break;
14124
14125 case 0x41: /* R_RL78_ABS32. */
b32e566b 14126 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14127 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14128 else
14129 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14130 (long) reloc->r_offset);
6ff71e76 14131 value = 0;
015dc7e1 14132 return true;
6ff71e76
NC
14133
14134 case 0x43: /* R_RL78_ABS16. */
b32e566b 14135 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14136 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14137 else
14138 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14139 (long) reloc->r_offset);
6ff71e76 14140 value = 0;
015dc7e1 14141 return true;
6ff71e76
NC
14142
14143 default:
14144 break;
14145 }
14146 break;
14147 }
252b5132
RH
14148 }
14149
015dc7e1 14150 return false;
252b5132
RH
14151}
14152
aca88567
NC
14153/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14154 DWARF debug sections. This is a target specific test. Note - we do not
14155 go through the whole including-target-headers-multiple-times route, (as
14156 we have already done with <elf/h8.h>) because this would become very
14157 messy and even then this function would have to contain target specific
14158 information (the names of the relocs instead of their numeric values).
14159 FIXME: This is not the correct way to solve this problem. The proper way
14160 is to have target specific reloc sizing and typing functions created by
14161 the reloc-macros.h header, in the same way that it already creates the
14162 reloc naming functions. */
14163
015dc7e1 14164static bool
dda8d76d 14165is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14166{
d347c9df 14167 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14168 switch (filedata->file_header.e_machine)
aca88567 14169 {
41e92641 14170 case EM_386:
22abe556 14171 case EM_IAMCU:
41e92641 14172 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14173 case EM_68K:
14174 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14175 case EM_860:
14176 return reloc_type == 1; /* R_860_32. */
14177 case EM_960:
14178 return reloc_type == 2; /* R_960_32. */
a06ea964 14179 case EM_AARCH64:
9282b95a
JW
14180 return (reloc_type == 258
14181 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14182 case EM_BPF:
14183 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14184 case EM_ADAPTEVA_EPIPHANY:
14185 return reloc_type == 3;
aca88567 14186 case EM_ALPHA:
137b6b5f 14187 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14188 case EM_ARC:
14189 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14190 case EM_ARC_COMPACT:
14191 case EM_ARC_COMPACT2:
14192 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14193 case EM_ARM:
14194 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14195 case EM_AVR_OLD:
aca88567
NC
14196 case EM_AVR:
14197 return reloc_type == 1;
14198 case EM_BLACKFIN:
14199 return reloc_type == 0x12; /* R_byte4_data. */
14200 case EM_CRIS:
14201 return reloc_type == 3; /* R_CRIS_32. */
14202 case EM_CR16:
14203 return reloc_type == 3; /* R_CR16_NUM32. */
14204 case EM_CRX:
14205 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14206 case EM_CSKY:
14207 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14208 case EM_CYGNUS_FRV:
14209 return reloc_type == 1;
41e92641
NC
14210 case EM_CYGNUS_D10V:
14211 case EM_D10V:
14212 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14213 case EM_CYGNUS_D30V:
14214 case EM_D30V:
14215 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14216 case EM_DLX:
14217 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14218 case EM_CYGNUS_FR30:
14219 case EM_FR30:
14220 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14221 case EM_FT32:
14222 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14223 case EM_H8S:
14224 case EM_H8_300:
14225 case EM_H8_300H:
14226 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14227 case EM_IA_64:
262cdac7
AM
14228 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14229 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14230 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14231 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14232 case EM_IP2K_OLD:
14233 case EM_IP2K:
14234 return reloc_type == 2; /* R_IP2K_32. */
14235 case EM_IQ2000:
14236 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14237 case EM_LATTICEMICO32:
14238 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14239 case EM_LOONGARCH:
14240 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14241 case EM_M32C_OLD:
aca88567
NC
14242 case EM_M32C:
14243 return reloc_type == 3; /* R_M32C_32. */
14244 case EM_M32R:
14245 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14246 case EM_68HC11:
14247 case EM_68HC12:
14248 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14249 case EM_S12Z:
2849d19f
JD
14250 return reloc_type == 7 || /* R_S12Z_EXT32 */
14251 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14252 case EM_MCORE:
14253 return reloc_type == 1; /* R_MCORE_ADDR32. */
14254 case EM_CYGNUS_MEP:
14255 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14256 case EM_METAG:
14257 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14258 case EM_MICROBLAZE:
14259 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14260 case EM_MIPS:
14261 return reloc_type == 2; /* R_MIPS_32. */
14262 case EM_MMIX:
14263 return reloc_type == 4; /* R_MMIX_32. */
14264 case EM_CYGNUS_MN10200:
14265 case EM_MN10200:
14266 return reloc_type == 1; /* R_MN10200_32. */
14267 case EM_CYGNUS_MN10300:
14268 case EM_MN10300:
14269 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14270 case EM_MOXIE:
14271 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14272 case EM_MSP430_OLD:
14273 case EM_MSP430:
13761a11 14274 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14275 case EM_MT:
14276 return reloc_type == 2; /* R_MT_32. */
35c08157 14277 case EM_NDS32:
81c5e376 14278 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14279 case EM_ALTERA_NIOS2:
36591ba1 14280 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14281 case EM_NIOS32:
14282 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14283 case EM_OR1K:
14284 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14285 case EM_PARISC:
9abca702 14286 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14287 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14288 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14289 case EM_PJ:
14290 case EM_PJ_OLD:
14291 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14292 case EM_PPC64:
14293 return reloc_type == 1; /* R_PPC64_ADDR32. */
14294 case EM_PPC:
14295 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14296 case EM_TI_PRU:
14297 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14298 case EM_RISCV:
14299 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14300 case EM_RL78:
14301 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14302 case EM_RX:
14303 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14304 case EM_S370:
14305 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14306 case EM_S390_OLD:
14307 case EM_S390:
14308 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14309 case EM_SCORE:
14310 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14311 case EM_SH:
14312 return reloc_type == 1; /* R_SH_DIR32. */
14313 case EM_SPARC32PLUS:
14314 case EM_SPARCV9:
14315 case EM_SPARC:
14316 return reloc_type == 3 /* R_SPARC_32. */
14317 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14318 case EM_SPU:
14319 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14320 case EM_TI_C6000:
14321 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14322 case EM_TILEGX:
14323 return reloc_type == 2; /* R_TILEGX_32. */
14324 case EM_TILEPRO:
14325 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14326 case EM_CYGNUS_V850:
14327 case EM_V850:
14328 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14329 case EM_V800:
14330 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14331 case EM_VAX:
14332 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14333 case EM_VISIUM:
14334 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14335 case EM_WEBASSEMBLY:
14336 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14337 case EM_X86_64:
8a9036a4 14338 case EM_L1OM:
7a9068fe 14339 case EM_K1OM:
aca88567 14340 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14341 case EM_XGATE:
14342 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14343 case EM_XSTORMY16:
14344 return reloc_type == 1; /* R_XSTROMY16_32. */
14345 case EM_XTENSA_OLD:
14346 case EM_XTENSA:
14347 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14348 case EM_Z80:
14349 return reloc_type == 6; /* R_Z80_32. */
aca88567 14350 default:
bee0ee85
NC
14351 {
14352 static unsigned int prev_warn = 0;
14353
14354 /* Avoid repeating the same warning multiple times. */
dda8d76d 14355 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14356 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14357 filedata->file_header.e_machine);
14358 prev_warn = filedata->file_header.e_machine;
015dc7e1 14359 return false;
bee0ee85 14360 }
aca88567
NC
14361 }
14362}
14363
14364/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14365 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14366
015dc7e1 14367static bool
dda8d76d 14368is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14369{
dda8d76d 14370 switch (filedata->file_header.e_machine)
d347c9df 14371 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14372 {
41e92641 14373 case EM_386:
22abe556 14374 case EM_IAMCU:
3e0873ac 14375 return reloc_type == 2; /* R_386_PC32. */
aca88567 14376 case EM_68K:
3e0873ac 14377 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14378 case EM_AARCH64:
14379 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14380 case EM_ADAPTEVA_EPIPHANY:
14381 return reloc_type == 6;
aca88567
NC
14382 case EM_ALPHA:
14383 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14384 case EM_ARC_COMPACT:
14385 case EM_ARC_COMPACT2:
14386 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14387 case EM_ARM:
3e0873ac 14388 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14389 case EM_AVR_OLD:
14390 case EM_AVR:
14391 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14392 case EM_LOONGARCH:
14393 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14394 case EM_MICROBLAZE:
14395 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14396 case EM_OR1K:
14397 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14398 case EM_PARISC:
85acf597 14399 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14400 case EM_PPC:
14401 return reloc_type == 26; /* R_PPC_REL32. */
14402 case EM_PPC64:
3e0873ac 14403 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14404 case EM_RISCV:
14405 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14406 case EM_S390_OLD:
14407 case EM_S390:
3e0873ac 14408 return reloc_type == 5; /* R_390_PC32. */
aca88567 14409 case EM_SH:
3e0873ac 14410 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14411 case EM_SPARC32PLUS:
14412 case EM_SPARCV9:
14413 case EM_SPARC:
3e0873ac 14414 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14415 case EM_SPU:
14416 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14417 case EM_TILEGX:
14418 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14419 case EM_TILEPRO:
14420 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14421 case EM_VISIUM:
14422 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14423 case EM_X86_64:
8a9036a4 14424 case EM_L1OM:
7a9068fe 14425 case EM_K1OM:
3e0873ac 14426 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14427 case EM_VAX:
14428 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14429 case EM_XTENSA_OLD:
14430 case EM_XTENSA:
14431 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14432 default:
14433 /* Do not abort or issue an error message here. Not all targets use
14434 pc-relative 32-bit relocs in their DWARF debug information and we
14435 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14436 more helpful warning message will be generated by apply_relocations
14437 anyway, so just return. */
015dc7e1 14438 return false;
aca88567
NC
14439 }
14440}
14441
14442/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14443 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14444
015dc7e1 14445static bool
dda8d76d 14446is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14447{
dda8d76d 14448 switch (filedata->file_header.e_machine)
aca88567 14449 {
a06ea964
NC
14450 case EM_AARCH64:
14451 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14452 case EM_ALPHA:
14453 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14454 case EM_IA_64:
262cdac7
AM
14455 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14456 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14457 case EM_LOONGARCH:
14458 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14459 case EM_PARISC:
14460 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14461 case EM_PPC64:
14462 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14463 case EM_RISCV:
14464 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14465 case EM_SPARC32PLUS:
14466 case EM_SPARCV9:
14467 case EM_SPARC:
714da62f
NC
14468 return reloc_type == 32 /* R_SPARC_64. */
14469 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14470 case EM_X86_64:
8a9036a4 14471 case EM_L1OM:
7a9068fe 14472 case EM_K1OM:
aca88567 14473 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14474 case EM_S390_OLD:
14475 case EM_S390:
aa137e4d
NC
14476 return reloc_type == 22; /* R_S390_64. */
14477 case EM_TILEGX:
14478 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14479 case EM_MIPS:
aa137e4d 14480 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14481 default:
015dc7e1 14482 return false;
aca88567
NC
14483 }
14484}
14485
85acf597
RH
14486/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14487 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14488
015dc7e1 14489static bool
dda8d76d 14490is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14491{
dda8d76d 14492 switch (filedata->file_header.e_machine)
85acf597 14493 {
a06ea964
NC
14494 case EM_AARCH64:
14495 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14496 case EM_ALPHA:
aa137e4d 14497 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14498 case EM_IA_64:
262cdac7
AM
14499 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14500 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14501 case EM_PARISC:
aa137e4d 14502 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14503 case EM_PPC64:
aa137e4d 14504 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14505 case EM_SPARC32PLUS:
14506 case EM_SPARCV9:
14507 case EM_SPARC:
aa137e4d 14508 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14509 case EM_X86_64:
8a9036a4 14510 case EM_L1OM:
7a9068fe 14511 case EM_K1OM:
aa137e4d 14512 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14513 case EM_S390_OLD:
14514 case EM_S390:
aa137e4d
NC
14515 return reloc_type == 23; /* R_S390_PC64. */
14516 case EM_TILEGX:
14517 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14518 default:
015dc7e1 14519 return false;
85acf597
RH
14520 }
14521}
14522
4dc3c23d
AM
14523/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14524 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14525
015dc7e1 14526static bool
dda8d76d 14527is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14528{
dda8d76d 14529 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14530 {
14531 case EM_CYGNUS_MN10200:
14532 case EM_MN10200:
14533 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14534 case EM_FT32:
14535 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14536 case EM_Z80:
14537 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14538 default:
015dc7e1 14539 return false;
4dc3c23d
AM
14540 }
14541}
14542
aca88567
NC
14543/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14544 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14545
015dc7e1 14546static bool
dda8d76d 14547is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14548{
d347c9df 14549 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14550 switch (filedata->file_header.e_machine)
4b78141a 14551 {
886a2506
NC
14552 case EM_ARC:
14553 case EM_ARC_COMPACT:
14554 case EM_ARC_COMPACT2:
14555 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14556 case EM_ADAPTEVA_EPIPHANY:
14557 return reloc_type == 5;
aca88567
NC
14558 case EM_AVR_OLD:
14559 case EM_AVR:
14560 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14561 case EM_CYGNUS_D10V:
14562 case EM_D10V:
14563 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14564 case EM_FT32:
14565 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14566 case EM_H8S:
14567 case EM_H8_300:
14568 case EM_H8_300H:
aca88567
NC
14569 return reloc_type == R_H8_DIR16;
14570 case EM_IP2K_OLD:
14571 case EM_IP2K:
14572 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14573 case EM_M32C_OLD:
f4236fe4
DD
14574 case EM_M32C:
14575 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14576 case EM_CYGNUS_MN10200:
14577 case EM_MN10200:
14578 return reloc_type == 2; /* R_MN10200_16. */
14579 case EM_CYGNUS_MN10300:
14580 case EM_MN10300:
14581 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14582 case EM_MSP430:
dda8d76d 14583 if (uses_msp430x_relocs (filedata))
13761a11 14584 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14585 /* Fall through. */
78c8d46c 14586 case EM_MSP430_OLD:
aca88567 14587 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14588 case EM_NDS32:
81c5e376 14589 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14590 case EM_ALTERA_NIOS2:
36591ba1 14591 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14592 case EM_NIOS32:
14593 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14594 case EM_OR1K:
14595 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14596 case EM_RISCV:
14597 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14598 case EM_TI_PRU:
14599 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14600 case EM_TI_C6000:
14601 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14602 case EM_VISIUM:
14603 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14604 case EM_XGATE:
14605 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14606 case EM_Z80:
14607 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14608 default:
015dc7e1 14609 return false;
4b78141a
NC
14610 }
14611}
14612
39e07931
AS
14613/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14614 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14615
015dc7e1 14616static bool
39e07931
AS
14617is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14618{
14619 switch (filedata->file_header.e_machine)
14620 {
14621 case EM_RISCV:
14622 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14623 case EM_Z80:
14624 return reloc_type == 1; /* R_Z80_8. */
39e07931 14625 default:
015dc7e1 14626 return false;
39e07931
AS
14627 }
14628}
14629
14630/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14631 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14632
015dc7e1 14633static bool
39e07931
AS
14634is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14635{
14636 switch (filedata->file_header.e_machine)
14637 {
14638 case EM_RISCV:
14639 return reloc_type == 53; /* R_RISCV_SET6. */
14640 default:
015dc7e1 14641 return false;
39e07931
AS
14642 }
14643}
14644
03336641
JW
14645/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14646 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14647
015dc7e1 14648static bool
03336641
JW
14649is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14650{
14651 /* Please keep this table alpha-sorted for ease of visual lookup. */
14652 switch (filedata->file_header.e_machine)
14653 {
14654 case EM_RISCV:
14655 return reloc_type == 35; /* R_RISCV_ADD32. */
14656 default:
015dc7e1 14657 return false;
03336641
JW
14658 }
14659}
14660
14661/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14662 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14663
015dc7e1 14664static bool
03336641
JW
14665is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14666{
14667 /* Please keep this table alpha-sorted for ease of visual lookup. */
14668 switch (filedata->file_header.e_machine)
14669 {
14670 case EM_RISCV:
14671 return reloc_type == 39; /* R_RISCV_SUB32. */
14672 default:
015dc7e1 14673 return false;
03336641
JW
14674 }
14675}
14676
14677/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14678 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14679
015dc7e1 14680static bool
03336641
JW
14681is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14682{
14683 /* Please keep this table alpha-sorted for ease of visual lookup. */
14684 switch (filedata->file_header.e_machine)
14685 {
14686 case EM_RISCV:
14687 return reloc_type == 36; /* R_RISCV_ADD64. */
14688 default:
015dc7e1 14689 return false;
03336641
JW
14690 }
14691}
14692
14693/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14694 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14695
015dc7e1 14696static bool
03336641
JW
14697is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14698{
14699 /* Please keep this table alpha-sorted for ease of visual lookup. */
14700 switch (filedata->file_header.e_machine)
14701 {
14702 case EM_RISCV:
14703 return reloc_type == 40; /* R_RISCV_SUB64. */
14704 default:
015dc7e1 14705 return false;
03336641
JW
14706 }
14707}
14708
14709/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14710 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14711
015dc7e1 14712static bool
03336641
JW
14713is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14714{
14715 /* Please keep this table alpha-sorted for ease of visual lookup. */
14716 switch (filedata->file_header.e_machine)
14717 {
14718 case EM_RISCV:
14719 return reloc_type == 34; /* R_RISCV_ADD16. */
14720 default:
015dc7e1 14721 return false;
03336641
JW
14722 }
14723}
14724
14725/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14726 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14727
015dc7e1 14728static bool
03336641
JW
14729is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14730{
14731 /* Please keep this table alpha-sorted for ease of visual lookup. */
14732 switch (filedata->file_header.e_machine)
14733 {
14734 case EM_RISCV:
14735 return reloc_type == 38; /* R_RISCV_SUB16. */
14736 default:
015dc7e1 14737 return false;
03336641
JW
14738 }
14739}
14740
14741/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14742 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14743
015dc7e1 14744static bool
03336641
JW
14745is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14746{
14747 /* Please keep this table alpha-sorted for ease of visual lookup. */
14748 switch (filedata->file_header.e_machine)
14749 {
14750 case EM_RISCV:
14751 return reloc_type == 33; /* R_RISCV_ADD8. */
14752 default:
015dc7e1 14753 return false;
03336641
JW
14754 }
14755}
14756
14757/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14758 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14759
015dc7e1 14760static bool
03336641
JW
14761is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14762{
14763 /* Please keep this table alpha-sorted for ease of visual lookup. */
14764 switch (filedata->file_header.e_machine)
14765 {
14766 case EM_RISCV:
14767 return reloc_type == 37; /* R_RISCV_SUB8. */
14768 default:
015dc7e1 14769 return false;
03336641
JW
14770 }
14771}
14772
39e07931
AS
14773/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14774 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14775
015dc7e1 14776static bool
39e07931
AS
14777is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14778{
14779 switch (filedata->file_header.e_machine)
14780 {
14781 case EM_RISCV:
14782 return reloc_type == 52; /* R_RISCV_SUB6. */
14783 default:
015dc7e1 14784 return false;
39e07931
AS
14785 }
14786}
14787
2a7b2e88
JK
14788/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14789 relocation entries (possibly formerly used for SHT_GROUP sections). */
14790
015dc7e1 14791static bool
dda8d76d 14792is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14793{
dda8d76d 14794 switch (filedata->file_header.e_machine)
2a7b2e88 14795 {
cb8f3167 14796 case EM_386: /* R_386_NONE. */
d347c9df 14797 case EM_68K: /* R_68K_NONE. */
cfb8c092 14798 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14799 case EM_ALPHA: /* R_ALPHA_NONE. */
14800 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14801 case EM_ARC: /* R_ARC_NONE. */
886a2506 14802 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14803 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14804 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14805 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14806 case EM_FT32: /* R_FT32_NONE. */
14807 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14808 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14809 case EM_L1OM: /* R_X86_64_NONE. */
14810 case EM_M32R: /* R_M32R_NONE. */
14811 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14812 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14813 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14814 case EM_NIOS32: /* R_NIOS_NONE. */
14815 case EM_OR1K: /* R_OR1K_NONE. */
14816 case EM_PARISC: /* R_PARISC_NONE. */
14817 case EM_PPC64: /* R_PPC64_NONE. */
14818 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14819 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14820 case EM_S390: /* R_390_NONE. */
14821 case EM_S390_OLD:
14822 case EM_SH: /* R_SH_NONE. */
14823 case EM_SPARC32PLUS:
14824 case EM_SPARC: /* R_SPARC_NONE. */
14825 case EM_SPARCV9:
aa137e4d
NC
14826 case EM_TILEGX: /* R_TILEGX_NONE. */
14827 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14828 case EM_TI_C6000:/* R_C6000_NONE. */
14829 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14830 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14831 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14832 return reloc_type == 0;
d347c9df 14833
a06ea964
NC
14834 case EM_AARCH64:
14835 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14836 case EM_AVR_OLD:
14837 case EM_AVR:
14838 return (reloc_type == 0 /* R_AVR_NONE. */
14839 || reloc_type == 30 /* R_AVR_DIFF8. */
14840 || reloc_type == 31 /* R_AVR_DIFF16. */
14841 || reloc_type == 32 /* R_AVR_DIFF32. */);
14842 case EM_METAG:
14843 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14844 case EM_NDS32:
81c5e376
AM
14845 return (reloc_type == 0 /* R_NDS32_NONE. */
14846 || reloc_type == 205 /* R_NDS32_DIFF8. */
14847 || reloc_type == 206 /* R_NDS32_DIFF16. */
14848 || reloc_type == 207 /* R_NDS32_DIFF32. */
14849 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14850 case EM_TI_PRU:
14851 return (reloc_type == 0 /* R_PRU_NONE. */
14852 || reloc_type == 65 /* R_PRU_DIFF8. */
14853 || reloc_type == 66 /* R_PRU_DIFF16. */
14854 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14855 case EM_XTENSA_OLD:
14856 case EM_XTENSA:
4dc3c23d
AM
14857 return (reloc_type == 0 /* R_XTENSA_NONE. */
14858 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14859 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14860 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14861 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14862 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14863 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14864 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14865 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14866 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14867 }
015dc7e1 14868 return false;
2a7b2e88
JK
14869}
14870
d1c4b12b
NC
14871/* Returns TRUE if there is a relocation against
14872 section NAME at OFFSET bytes. */
14873
015dc7e1 14874bool
d1c4b12b
NC
14875reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14876{
14877 Elf_Internal_Rela * relocs;
14878 Elf_Internal_Rela * rp;
14879
14880 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14881 return false;
d1c4b12b
NC
14882
14883 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14884
14885 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14886 if (rp->r_offset == offset)
015dc7e1 14887 return true;
d1c4b12b 14888
015dc7e1 14889 return false;
d1c4b12b
NC
14890}
14891
cf13d699 14892/* Apply relocations to a section.
32ec8896
NC
14893 Returns TRUE upon success, FALSE otherwise.
14894 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14895 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14896 will be set to the number of relocs loaded.
14897
cf13d699 14898 Note: So far support has been added only for those relocations
32ec8896
NC
14899 which can be found in debug sections. FIXME: Add support for
14900 more relocations ? */
1b315056 14901
015dc7e1 14902static bool
dda8d76d 14903apply_relocations (Filedata * filedata,
d1c4b12b
NC
14904 const Elf_Internal_Shdr * section,
14905 unsigned char * start,
14906 bfd_size_type size,
1449284b 14907 void ** relocs_return,
d1c4b12b 14908 unsigned long * num_relocs_return)
1b315056 14909{
cf13d699 14910 Elf_Internal_Shdr * relsec;
0d2a7a93 14911 unsigned char * end = start + size;
cb8f3167 14912
d1c4b12b
NC
14913 if (relocs_return != NULL)
14914 {
14915 * (Elf_Internal_Rela **) relocs_return = NULL;
14916 * num_relocs_return = 0;
14917 }
14918
dda8d76d 14919 if (filedata->file_header.e_type != ET_REL)
32ec8896 14920 /* No relocs to apply. */
015dc7e1 14921 return true;
1b315056 14922
cf13d699 14923 /* Find the reloc section associated with the section. */
dda8d76d
NC
14924 for (relsec = filedata->section_headers;
14925 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14926 ++relsec)
252b5132 14927 {
015dc7e1 14928 bool is_rela;
41e92641 14929 unsigned long num_relocs;
2cf0635d
NC
14930 Elf_Internal_Rela * relocs;
14931 Elf_Internal_Rela * rp;
14932 Elf_Internal_Shdr * symsec;
14933 Elf_Internal_Sym * symtab;
ba5cdace 14934 unsigned long num_syms;
2cf0635d 14935 Elf_Internal_Sym * sym;
252b5132 14936
41e92641 14937 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14938 || relsec->sh_info >= filedata->file_header.e_shnum
14939 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14940 || relsec->sh_size == 0
dda8d76d 14941 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14942 continue;
428409d5 14943
a788aedd
AM
14944 symsec = filedata->section_headers + relsec->sh_link;
14945 if (symsec->sh_type != SHT_SYMTAB
14946 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14947 return false;
a788aedd 14948
41e92641
NC
14949 is_rela = relsec->sh_type == SHT_RELA;
14950
14951 if (is_rela)
14952 {
dda8d76d 14953 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14954 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14955 return false;
41e92641
NC
14956 }
14957 else
14958 {
dda8d76d 14959 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14960 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14961 return false;
41e92641
NC
14962 }
14963
14964 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14965 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14966 is_rela = false;
428409d5 14967
4de91c10 14968 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14969
41e92641 14970 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14971 {
015dc7e1
AM
14972 bfd_vma addend;
14973 unsigned int reloc_type;
14974 unsigned int reloc_size;
14975 bool reloc_inplace = false;
14976 bool reloc_subtract = false;
14977 unsigned char *rloc;
14978 unsigned long sym_index;
4b78141a 14979
dda8d76d 14980 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14981
dda8d76d 14982 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14983 continue;
dda8d76d 14984 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14985 continue;
dda8d76d
NC
14986 else if (is_32bit_abs_reloc (filedata, reloc_type)
14987 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14988 reloc_size = 4;
dda8d76d
NC
14989 else if (is_64bit_abs_reloc (filedata, reloc_type)
14990 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14991 reloc_size = 8;
dda8d76d 14992 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14993 reloc_size = 3;
dda8d76d 14994 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14995 reloc_size = 2;
39e07931
AS
14996 else if (is_8bit_abs_reloc (filedata, reloc_type)
14997 || is_6bit_abs_reloc (filedata, reloc_type))
14998 reloc_size = 1;
03336641
JW
14999 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15000 reloc_type))
15001 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15002 {
15003 reloc_size = 4;
015dc7e1 15004 reloc_inplace = true;
03336641
JW
15005 }
15006 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15007 reloc_type))
15008 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15009 {
15010 reloc_size = 8;
015dc7e1 15011 reloc_inplace = true;
03336641
JW
15012 }
15013 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15014 reloc_type))
15015 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15016 {
15017 reloc_size = 2;
015dc7e1 15018 reloc_inplace = true;
03336641
JW
15019 }
15020 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15021 reloc_type))
15022 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15023 {
15024 reloc_size = 1;
015dc7e1 15025 reloc_inplace = true;
03336641 15026 }
39e07931
AS
15027 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15028 reloc_type)))
15029 {
15030 reloc_size = 1;
015dc7e1 15031 reloc_inplace = true;
39e07931 15032 }
aca88567 15033 else
4b78141a 15034 {
bee0ee85 15035 static unsigned int prev_reloc = 0;
dda8d76d 15036
bee0ee85
NC
15037 if (reloc_type != prev_reloc)
15038 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15039 reloc_type, printable_section_name (filedata, section));
bee0ee85 15040 prev_reloc = reloc_type;
4b78141a
NC
15041 continue;
15042 }
103f02d3 15043
91d6fa6a 15044 rloc = start + rp->r_offset;
75802ccb 15045 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15046 {
15047 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15048 (unsigned long) rp->r_offset,
dda8d76d 15049 printable_section_name (filedata, section));
700dd8b7
L
15050 continue;
15051 }
103f02d3 15052
ba5cdace
NC
15053 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15054 if (sym_index >= num_syms)
15055 {
15056 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15057 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15058 continue;
15059 }
15060 sym = symtab + sym_index;
41e92641
NC
15061
15062 /* If the reloc has a symbol associated with it,
55f25fc3
L
15063 make sure that it is of an appropriate type.
15064
15065 Relocations against symbols without type can happen.
15066 Gcc -feliminate-dwarf2-dups may generate symbols
15067 without type for debug info.
15068
15069 Icc generates relocations against function symbols
15070 instead of local labels.
15071
15072 Relocations against object symbols can happen, eg when
15073 referencing a global array. For an example of this see
15074 the _clz.o binary in libgcc.a. */
aca88567 15075 if (sym != symtab
b8871f35 15076 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15077 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15078 {
d3a49aa8 15079 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15080 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15081 printable_section_name (filedata, relsec),
d3a49aa8 15082 (long int)(rp - relocs));
aca88567 15083 continue;
5b18a4bc 15084 }
252b5132 15085
4dc3c23d
AM
15086 addend = 0;
15087 if (is_rela)
15088 addend += rp->r_addend;
c47320c3
AM
15089 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15090 partial_inplace. */
4dc3c23d 15091 if (!is_rela
dda8d76d 15092 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15093 && reloc_type == 1)
dda8d76d
NC
15094 || ((filedata->file_header.e_machine == EM_PJ
15095 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15096 && reloc_type == 1)
dda8d76d
NC
15097 || ((filedata->file_header.e_machine == EM_D30V
15098 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15099 && reloc_type == 12)
15100 || reloc_inplace)
39e07931
AS
15101 {
15102 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15103 addend += byte_get (rloc, reloc_size) & 0x3f;
15104 else
15105 addend += byte_get (rloc, reloc_size);
15106 }
cb8f3167 15107
dda8d76d
NC
15108 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15109 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15110 {
15111 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15112 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15113 addend -= 8;
91d6fa6a 15114 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15115 reloc_size);
15116 }
39e07931
AS
15117 else if (is_6bit_abs_reloc (filedata, reloc_type)
15118 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15119 {
15120 if (reloc_subtract)
15121 addend -= sym->st_value;
15122 else
15123 addend += sym->st_value;
15124 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15125 byte_put (rloc, addend, reloc_size);
15126 }
03336641
JW
15127 else if (reloc_subtract)
15128 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15129 else
91d6fa6a 15130 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15131 }
252b5132 15132
5b18a4bc 15133 free (symtab);
f84ce13b
NC
15134 /* Let the target specific reloc processing code know that
15135 we have finished with these relocs. */
dda8d76d 15136 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15137
15138 if (relocs_return)
15139 {
15140 * (Elf_Internal_Rela **) relocs_return = relocs;
15141 * num_relocs_return = num_relocs;
15142 }
15143 else
15144 free (relocs);
15145
5b18a4bc
NC
15146 break;
15147 }
32ec8896 15148
015dc7e1 15149 return true;
5b18a4bc 15150}
103f02d3 15151
cf13d699 15152#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15153static bool
dda8d76d 15154disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15155{
dda8d76d 15156 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15157
74e1a04b 15158 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15159
015dc7e1 15160 return true;
cf13d699
NC
15161}
15162#endif
15163
15164/* Reads in the contents of SECTION from FILE, returning a pointer
15165 to a malloc'ed buffer or NULL if something went wrong. */
15166
15167static char *
dda8d76d 15168get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15169{
dda8d76d 15170 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15171
15172 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15173 {
c6b78c96 15174 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15175 printable_section_name (filedata, section));
cf13d699
NC
15176 return NULL;
15177 }
15178
dda8d76d 15179 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15180 _("section contents"));
cf13d699
NC
15181}
15182
0e602686
NC
15183/* Uncompresses a section that was compressed using zlib, in place. */
15184
015dc7e1 15185static bool
dda8d76d
NC
15186uncompress_section_contents (unsigned char ** buffer,
15187 dwarf_size_type uncompressed_size,
15188 dwarf_size_type * size)
0e602686
NC
15189{
15190 dwarf_size_type compressed_size = *size;
15191 unsigned char * compressed_buffer = *buffer;
15192 unsigned char * uncompressed_buffer;
15193 z_stream strm;
15194 int rc;
15195
15196 /* It is possible the section consists of several compressed
15197 buffers concatenated together, so we uncompress in a loop. */
15198 /* PR 18313: The state field in the z_stream structure is supposed
15199 to be invisible to the user (ie us), but some compilers will
15200 still complain about it being used without initialisation. So
15201 we first zero the entire z_stream structure and then set the fields
15202 that we need. */
15203 memset (& strm, 0, sizeof strm);
15204 strm.avail_in = compressed_size;
15205 strm.next_in = (Bytef *) compressed_buffer;
15206 strm.avail_out = uncompressed_size;
15207 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15208
15209 rc = inflateInit (& strm);
15210 while (strm.avail_in > 0)
15211 {
15212 if (rc != Z_OK)
3624a6c1 15213 break;
0e602686
NC
15214 strm.next_out = ((Bytef *) uncompressed_buffer
15215 + (uncompressed_size - strm.avail_out));
15216 rc = inflate (&strm, Z_FINISH);
15217 if (rc != Z_STREAM_END)
3624a6c1 15218 break;
0e602686
NC
15219 rc = inflateReset (& strm);
15220 }
ad92f33d
AM
15221 if (inflateEnd (& strm) != Z_OK
15222 || rc != Z_OK
0e602686
NC
15223 || strm.avail_out != 0)
15224 goto fail;
15225
15226 *buffer = uncompressed_buffer;
15227 *size = uncompressed_size;
015dc7e1 15228 return true;
0e602686
NC
15229
15230 fail:
15231 free (uncompressed_buffer);
15232 /* Indicate decompression failure. */
15233 *buffer = NULL;
015dc7e1 15234 return false;
0e602686 15235}
dd24e3da 15236
015dc7e1 15237static bool
dda8d76d 15238dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15239{
015dc7e1
AM
15240 Elf_Internal_Shdr *relsec;
15241 bfd_size_type num_bytes;
15242 unsigned char *data;
15243 unsigned char *end;
15244 unsigned char *real_start;
15245 unsigned char *start;
15246 bool some_strings_shown;
cf13d699 15247
dda8d76d 15248 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15249 if (start == NULL)
c6b78c96 15250 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15251 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15252
0e602686 15253 num_bytes = section->sh_size;
cf13d699 15254
835f2fae
NC
15255 if (filedata->is_separate)
15256 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15257 printable_section_name (filedata, section),
15258 filedata->file_name);
15259 else
15260 printf (_("\nString dump of section '%s':\n"),
15261 printable_section_name (filedata, section));
cf13d699 15262
0e602686
NC
15263 if (decompress_dumps)
15264 {
15265 dwarf_size_type new_size = num_bytes;
15266 dwarf_size_type uncompressed_size = 0;
15267
15268 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15269 {
15270 Elf_Internal_Chdr chdr;
15271 unsigned int compression_header_size
ebdf1ebf
NC
15272 = get_compression_header (& chdr, (unsigned char *) start,
15273 num_bytes);
5844b465
NC
15274 if (compression_header_size == 0)
15275 /* An error message will have already been generated
15276 by get_compression_header. */
15277 goto error_out;
0e602686 15278
813dabb9 15279 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15280 {
813dabb9 15281 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15282 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15283 goto error_out;
813dabb9 15284 }
813dabb9
L
15285 uncompressed_size = chdr.ch_size;
15286 start += compression_header_size;
15287 new_size -= compression_header_size;
0e602686
NC
15288 }
15289 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15290 {
15291 /* Read the zlib header. In this case, it should be "ZLIB"
15292 followed by the uncompressed section size, 8 bytes in
15293 big-endian order. */
15294 uncompressed_size = start[4]; uncompressed_size <<= 8;
15295 uncompressed_size += start[5]; uncompressed_size <<= 8;
15296 uncompressed_size += start[6]; uncompressed_size <<= 8;
15297 uncompressed_size += start[7]; uncompressed_size <<= 8;
15298 uncompressed_size += start[8]; uncompressed_size <<= 8;
15299 uncompressed_size += start[9]; uncompressed_size <<= 8;
15300 uncompressed_size += start[10]; uncompressed_size <<= 8;
15301 uncompressed_size += start[11];
15302 start += 12;
15303 new_size -= 12;
15304 }
15305
1835f746
NC
15306 if (uncompressed_size)
15307 {
15308 if (uncompress_section_contents (& start,
15309 uncompressed_size, & new_size))
15310 num_bytes = new_size;
15311 else
15312 {
15313 error (_("Unable to decompress section %s\n"),
dda8d76d 15314 printable_section_name (filedata, section));
f761cb13 15315 goto error_out;
1835f746
NC
15316 }
15317 }
bc303e5d
NC
15318 else
15319 start = real_start;
0e602686 15320 }
fd8008d8 15321
cf13d699
NC
15322 /* If the section being dumped has relocations against it the user might
15323 be expecting these relocations to have been applied. Check for this
15324 case and issue a warning message in order to avoid confusion.
15325 FIXME: Maybe we ought to have an option that dumps a section with
15326 relocs applied ? */
dda8d76d
NC
15327 for (relsec = filedata->section_headers;
15328 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15329 ++relsec)
15330 {
15331 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15332 || relsec->sh_info >= filedata->file_header.e_shnum
15333 || filedata->section_headers + relsec->sh_info != section
cf13d699 15334 || relsec->sh_size == 0
dda8d76d 15335 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15336 continue;
15337
15338 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15339 break;
15340 }
15341
cf13d699
NC
15342 data = start;
15343 end = start + num_bytes;
015dc7e1 15344 some_strings_shown = false;
cf13d699 15345
ba3265d0
NC
15346#ifdef HAVE_MBSTATE_T
15347 mbstate_t state;
15348 /* Initialise the multibyte conversion state. */
15349 memset (& state, 0, sizeof (state));
15350#endif
15351
015dc7e1 15352 bool continuing = false;
ba3265d0 15353
cf13d699
NC
15354 while (data < end)
15355 {
15356 while (!ISPRINT (* data))
15357 if (++ data >= end)
15358 break;
15359
15360 if (data < end)
15361 {
071436c6
NC
15362 size_t maxlen = end - data;
15363
ba3265d0
NC
15364 if (continuing)
15365 {
15366 printf (" ");
015dc7e1 15367 continuing = false;
ba3265d0
NC
15368 }
15369 else
15370 {
d1ce973e 15371 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15372 }
15373
4082ef84
NC
15374 if (maxlen > 0)
15375 {
f3da8a96 15376 char c = 0;
ba3265d0
NC
15377
15378 while (maxlen)
15379 {
15380 c = *data++;
15381
15382 if (c == 0)
15383 break;
15384
15385 /* PR 25543: Treat new-lines as string-ending characters. */
15386 if (c == '\n')
15387 {
15388 printf ("\\n\n");
15389 if (*data != 0)
015dc7e1 15390 continuing = true;
ba3265d0
NC
15391 break;
15392 }
15393
15394 /* Do not print control characters directly as they can affect terminal
15395 settings. Such characters usually appear in the names generated
15396 by the assembler for local labels. */
15397 if (ISCNTRL (c))
15398 {
15399 printf ("^%c", c + 0x40);
15400 }
15401 else if (ISPRINT (c))
15402 {
15403 putchar (c);
15404 }
15405 else
15406 {
15407 size_t n;
15408#ifdef HAVE_MBSTATE_T
15409 wchar_t w;
15410#endif
15411 /* Let printf do the hard work of displaying multibyte characters. */
15412 printf ("%.1s", data - 1);
15413#ifdef HAVE_MBSTATE_T
15414 /* Try to find out how many bytes made up the character that was
15415 just printed. Advance the symbol pointer past the bytes that
15416 were displayed. */
15417 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15418#else
15419 n = 1;
15420#endif
15421 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15422 data += (n - 1);
15423 }
15424 }
15425
15426 if (c != '\n')
15427 putchar ('\n');
4082ef84
NC
15428 }
15429 else
15430 {
15431 printf (_("<corrupt>\n"));
15432 data = end;
15433 }
015dc7e1 15434 some_strings_shown = true;
cf13d699
NC
15435 }
15436 }
15437
15438 if (! some_strings_shown)
15439 printf (_(" No strings found in this section."));
15440
0e602686 15441 free (real_start);
cf13d699
NC
15442
15443 putchar ('\n');
015dc7e1 15444 return true;
f761cb13
AM
15445
15446error_out:
15447 free (real_start);
015dc7e1 15448 return false;
cf13d699
NC
15449}
15450
015dc7e1
AM
15451static bool
15452dump_section_as_bytes (Elf_Internal_Shdr *section,
15453 Filedata *filedata,
15454 bool relocate)
cf13d699
NC
15455{
15456 Elf_Internal_Shdr * relsec;
0e602686
NC
15457 bfd_size_type bytes;
15458 bfd_size_type section_size;
15459 bfd_vma addr;
15460 unsigned char * data;
15461 unsigned char * real_start;
15462 unsigned char * start;
15463
dda8d76d 15464 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15465 if (start == NULL)
c6b78c96 15466 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15467 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15468
0e602686 15469 section_size = section->sh_size;
cf13d699 15470
835f2fae
NC
15471 if (filedata->is_separate)
15472 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15473 printable_section_name (filedata, section),
15474 filedata->file_name);
15475 else
15476 printf (_("\nHex dump of section '%s':\n"),
15477 printable_section_name (filedata, section));
cf13d699 15478
0e602686
NC
15479 if (decompress_dumps)
15480 {
15481 dwarf_size_type new_size = section_size;
15482 dwarf_size_type uncompressed_size = 0;
15483
15484 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15485 {
15486 Elf_Internal_Chdr chdr;
15487 unsigned int compression_header_size
ebdf1ebf 15488 = get_compression_header (& chdr, start, section_size);
0e602686 15489
5844b465
NC
15490 if (compression_header_size == 0)
15491 /* An error message will have already been generated
15492 by get_compression_header. */
15493 goto error_out;
15494
813dabb9 15495 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15496 {
813dabb9 15497 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15498 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15499 goto error_out;
0e602686 15500 }
813dabb9
L
15501 uncompressed_size = chdr.ch_size;
15502 start += compression_header_size;
15503 new_size -= compression_header_size;
0e602686
NC
15504 }
15505 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15506 {
15507 /* Read the zlib header. In this case, it should be "ZLIB"
15508 followed by the uncompressed section size, 8 bytes in
15509 big-endian order. */
15510 uncompressed_size = start[4]; uncompressed_size <<= 8;
15511 uncompressed_size += start[5]; uncompressed_size <<= 8;
15512 uncompressed_size += start[6]; uncompressed_size <<= 8;
15513 uncompressed_size += start[7]; uncompressed_size <<= 8;
15514 uncompressed_size += start[8]; uncompressed_size <<= 8;
15515 uncompressed_size += start[9]; uncompressed_size <<= 8;
15516 uncompressed_size += start[10]; uncompressed_size <<= 8;
15517 uncompressed_size += start[11];
15518 start += 12;
15519 new_size -= 12;
15520 }
15521
f055032e
NC
15522 if (uncompressed_size)
15523 {
15524 if (uncompress_section_contents (& start, uncompressed_size,
15525 & new_size))
bc303e5d
NC
15526 {
15527 section_size = new_size;
15528 }
f055032e
NC
15529 else
15530 {
15531 error (_("Unable to decompress section %s\n"),
dda8d76d 15532 printable_section_name (filedata, section));
bc303e5d 15533 /* FIXME: Print the section anyway ? */
f761cb13 15534 goto error_out;
f055032e
NC
15535 }
15536 }
bc303e5d
NC
15537 else
15538 start = real_start;
0e602686 15539 }
14ae95f2 15540
cf13d699
NC
15541 if (relocate)
15542 {
dda8d76d 15543 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15544 goto error_out;
cf13d699
NC
15545 }
15546 else
15547 {
15548 /* If the section being dumped has relocations against it the user might
15549 be expecting these relocations to have been applied. Check for this
15550 case and issue a warning message in order to avoid confusion.
15551 FIXME: Maybe we ought to have an option that dumps a section with
15552 relocs applied ? */
dda8d76d
NC
15553 for (relsec = filedata->section_headers;
15554 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15555 ++relsec)
15556 {
15557 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15558 || relsec->sh_info >= filedata->file_header.e_shnum
15559 || filedata->section_headers + relsec->sh_info != section
cf13d699 15560 || relsec->sh_size == 0
dda8d76d 15561 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15562 continue;
15563
15564 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15565 break;
15566 }
15567 }
15568
15569 addr = section->sh_addr;
0e602686 15570 bytes = section_size;
cf13d699
NC
15571 data = start;
15572
15573 while (bytes)
15574 {
15575 int j;
15576 int k;
15577 int lbytes;
15578
15579 lbytes = (bytes > 16 ? 16 : bytes);
15580
15581 printf (" 0x%8.8lx ", (unsigned long) addr);
15582
15583 for (j = 0; j < 16; j++)
15584 {
15585 if (j < lbytes)
15586 printf ("%2.2x", data[j]);
15587 else
15588 printf (" ");
15589
15590 if ((j & 3) == 3)
15591 printf (" ");
15592 }
15593
15594 for (j = 0; j < lbytes; j++)
15595 {
15596 k = data[j];
15597 if (k >= ' ' && k < 0x7f)
15598 printf ("%c", k);
15599 else
15600 printf (".");
15601 }
15602
15603 putchar ('\n');
15604
15605 data += lbytes;
15606 addr += lbytes;
15607 bytes -= lbytes;
15608 }
15609
0e602686 15610 free (real_start);
cf13d699
NC
15611
15612 putchar ('\n');
015dc7e1 15613 return true;
f761cb13
AM
15614
15615 error_out:
15616 free (real_start);
015dc7e1 15617 return false;
cf13d699
NC
15618}
15619
094e34f2 15620#ifdef ENABLE_LIBCTF
7d9813f1
NA
15621static ctf_sect_t *
15622shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15623{
84714f86 15624 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15625 buf->cts_size = shdr->sh_size;
15626 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15627
15628 return buf;
15629}
15630
15631/* Formatting callback function passed to ctf_dump. Returns either the pointer
15632 it is passed, or a pointer to newly-allocated storage, in which case
15633 dump_ctf() will free it when it no longer needs it. */
15634
2f6ecaed
NA
15635static char *
15636dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15637 char *s, void *arg)
7d9813f1 15638{
3e50a591 15639 const char *blanks = arg;
7d9813f1
NA
15640 char *new_s;
15641
3e50a591 15642 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15643 return s;
15644 return new_s;
15645}
15646
926c9e76
NA
15647/* Dump CTF errors/warnings. */
15648static void
139633c3 15649dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15650{
15651 ctf_next_t *it = NULL;
15652 char *errtext;
15653 int is_warning;
15654 int err;
15655
15656 /* Dump accumulated errors and warnings. */
15657 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15658 {
5e9b84f7 15659 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15660 errtext);
15661 free (errtext);
15662 }
15663 if (err != ECTF_NEXT_END)
15664 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15665}
15666
2f6ecaed
NA
15667/* Dump one CTF archive member. */
15668
80b56fad
NA
15669static void
15670dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15671 size_t member)
2f6ecaed 15672{
2f6ecaed
NA
15673 const char *things[] = {"Header", "Labels", "Data objects",
15674 "Function objects", "Variables", "Types", "Strings",
15675 ""};
15676 const char **thing;
15677 size_t i;
15678
80b56fad
NA
15679 /* Don't print out the name of the default-named archive member if it appears
15680 first in the list. The name .ctf appears everywhere, even for things that
15681 aren't really archives, so printing it out is liable to be confusing; also,
15682 the common case by far is for only one archive member to exist, and hiding
15683 it in that case seems worthwhile. */
2f6ecaed 15684
80b56fad
NA
15685 if (strcmp (name, ".ctf") != 0 || member != 0)
15686 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15687
80b56fad
NA
15688 if (ctf_parent_name (ctf) != NULL)
15689 ctf_import (ctf, parent);
2f6ecaed
NA
15690
15691 for (i = 0, thing = things; *thing[0]; thing++, i++)
15692 {
15693 ctf_dump_state_t *s = NULL;
15694 char *item;
15695
15696 printf ("\n %s:\n", *thing);
15697 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15698 (void *) " ")) != NULL)
15699 {
15700 printf ("%s\n", item);
15701 free (item);
15702 }
15703
15704 if (ctf_errno (ctf))
15705 {
15706 error (_("Iteration failed: %s, %s\n"), *thing,
15707 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15708 break;
2f6ecaed
NA
15709 }
15710 }
8b37e7b6 15711
926c9e76 15712 dump_ctf_errs (ctf);
2f6ecaed
NA
15713}
15714
015dc7e1 15715static bool
7d9813f1
NA
15716dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15717{
7d9813f1
NA
15718 Elf_Internal_Shdr * symtab_sec = NULL;
15719 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15720 void * data = NULL;
15721 void * symdata = NULL;
15722 void * strdata = NULL;
80b56fad 15723 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15724 ctf_sect_t * symsectp = NULL;
15725 ctf_sect_t * strsectp = NULL;
2f6ecaed 15726 ctf_archive_t * ctfa = NULL;
139633c3 15727 ctf_dict_t * parent = NULL;
80b56fad 15728 ctf_dict_t * fp;
7d9813f1 15729
80b56fad
NA
15730 ctf_next_t *i = NULL;
15731 const char *name;
15732 size_t member = 0;
7d9813f1 15733 int err;
015dc7e1 15734 bool ret = false;
7d9813f1
NA
15735
15736 shdr_to_ctf_sect (&ctfsect, section, filedata);
15737 data = get_section_contents (section, filedata);
15738 ctfsect.cts_data = data;
15739
616febde 15740 if (!dump_ctf_symtab_name)
3d16b64e 15741 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15742
15743 if (!dump_ctf_strtab_name)
3d16b64e 15744 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15745
15746 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15747 {
15748 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15749 {
15750 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15751 goto fail;
15752 }
15753 if ((symdata = (void *) get_data (NULL, filedata,
15754 symtab_sec->sh_offset, 1,
15755 symtab_sec->sh_size,
15756 _("symbols"))) == NULL)
15757 goto fail;
15758 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15759 symsect.cts_data = symdata;
15760 }
835f2fae 15761
df16e041 15762 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15763 {
15764 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15765 {
15766 error (_("No string table section named %s\n"),
15767 dump_ctf_strtab_name);
15768 goto fail;
15769 }
15770 if ((strdata = (void *) get_data (NULL, filedata,
15771 strtab_sec->sh_offset, 1,
15772 strtab_sec->sh_size,
15773 _("strings"))) == NULL)
15774 goto fail;
15775 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15776 strsect.cts_data = strdata;
15777 }
835f2fae 15778
2f6ecaed
NA
15779 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15780 libctf papers over the difference, so we can pretend it is always an
80b56fad 15781 archive. */
7d9813f1 15782
2f6ecaed 15783 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15784 {
926c9e76 15785 dump_ctf_errs (NULL);
7d9813f1
NA
15786 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15787 goto fail;
15788 }
15789
96c61be5
NA
15790 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15791 != ELFDATA2MSB);
15792
80b56fad
NA
15793 /* Preload the parent dict, since it will need to be imported into every
15794 child in turn. */
15795 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15796 {
926c9e76 15797 dump_ctf_errs (NULL);
2f6ecaed
NA
15798 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15799 goto fail;
7d9813f1
NA
15800 }
15801
015dc7e1 15802 ret = true;
7d9813f1 15803
835f2fae
NC
15804 if (filedata->is_separate)
15805 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15806 printable_section_name (filedata, section),
15807 filedata->file_name);
15808 else
15809 printf (_("\nDump of CTF section '%s':\n"),
15810 printable_section_name (filedata, section));
7d9813f1 15811
80b56fad
NA
15812 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15813 dump_ctf_archive_member (fp, name, parent, member++);
15814 if (err != ECTF_NEXT_END)
15815 {
15816 dump_ctf_errs (NULL);
15817 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15818 ret = false;
15819 }
7d9813f1
NA
15820
15821 fail:
139633c3 15822 ctf_dict_close (parent);
2f6ecaed 15823 ctf_close (ctfa);
7d9813f1
NA
15824 free (data);
15825 free (symdata);
15826 free (strdata);
15827 return ret;
15828}
094e34f2 15829#endif
7d9813f1 15830
015dc7e1 15831static bool
dda8d76d
NC
15832load_specific_debug_section (enum dwarf_section_display_enum debug,
15833 const Elf_Internal_Shdr * sec,
15834 void * data)
1007acb3 15835{
2cf0635d 15836 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15837 char buf [64];
dda8d76d 15838 Filedata * filedata = (Filedata *) data;
9abca702 15839
19e6b90e 15840 if (section->start != NULL)
dda8d76d
NC
15841 {
15842 /* If it is already loaded, do nothing. */
15843 if (streq (section->filename, filedata->file_name))
015dc7e1 15844 return true;
dda8d76d
NC
15845 free (section->start);
15846 }
1007acb3 15847
19e6b90e
L
15848 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15849 section->address = sec->sh_addr;
dda8d76d
NC
15850 section->filename = filedata->file_name;
15851 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15852 sec->sh_offset, 1,
15853 sec->sh_size, buf);
59245841
NC
15854 if (section->start == NULL)
15855 section->size = 0;
15856 else
15857 {
77115a4a
L
15858 unsigned char *start = section->start;
15859 dwarf_size_type size = sec->sh_size;
dab394de 15860 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15861
15862 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15863 {
15864 Elf_Internal_Chdr chdr;
d8024a91
NC
15865 unsigned int compression_header_size;
15866
f53be977
L
15867 if (size < (is_32bit_elf
15868 ? sizeof (Elf32_External_Chdr)
15869 : sizeof (Elf64_External_Chdr)))
d8024a91 15870 {
55be8fd0 15871 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15872 section->name);
015dc7e1 15873 return false;
d8024a91
NC
15874 }
15875
ebdf1ebf 15876 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15877 if (compression_header_size == 0)
15878 /* An error message will have already been generated
15879 by get_compression_header. */
015dc7e1 15880 return false;
d8024a91 15881
813dabb9
L
15882 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15883 {
15884 warn (_("section '%s' has unsupported compress type: %d\n"),
15885 section->name, chdr.ch_type);
015dc7e1 15886 return false;
813dabb9 15887 }
dab394de 15888 uncompressed_size = chdr.ch_size;
77115a4a
L
15889 start += compression_header_size;
15890 size -= compression_header_size;
15891 }
dab394de
L
15892 else if (size > 12 && streq ((char *) start, "ZLIB"))
15893 {
15894 /* Read the zlib header. In this case, it should be "ZLIB"
15895 followed by the uncompressed section size, 8 bytes in
15896 big-endian order. */
15897 uncompressed_size = start[4]; uncompressed_size <<= 8;
15898 uncompressed_size += start[5]; uncompressed_size <<= 8;
15899 uncompressed_size += start[6]; uncompressed_size <<= 8;
15900 uncompressed_size += start[7]; uncompressed_size <<= 8;
15901 uncompressed_size += start[8]; uncompressed_size <<= 8;
15902 uncompressed_size += start[9]; uncompressed_size <<= 8;
15903 uncompressed_size += start[10]; uncompressed_size <<= 8;
15904 uncompressed_size += start[11];
15905 start += 12;
15906 size -= 12;
15907 }
15908
1835f746 15909 if (uncompressed_size)
77115a4a 15910 {
1835f746
NC
15911 if (uncompress_section_contents (&start, uncompressed_size,
15912 &size))
15913 {
15914 /* Free the compressed buffer, update the section buffer
15915 and the section size if uncompress is successful. */
15916 free (section->start);
15917 section->start = start;
15918 }
15919 else
15920 {
15921 error (_("Unable to decompress section %s\n"),
dda8d76d 15922 printable_section_name (filedata, sec));
015dc7e1 15923 return false;
1835f746 15924 }
77115a4a 15925 }
bc303e5d 15926
77115a4a 15927 section->size = size;
59245841 15928 }
4a114e3e 15929
1b315056 15930 if (section->start == NULL)
015dc7e1 15931 return false;
1b315056 15932
19e6b90e 15933 if (debug_displays [debug].relocate)
32ec8896 15934 {
dda8d76d 15935 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15936 & section->reloc_info, & section->num_relocs))
015dc7e1 15937 return false;
32ec8896 15938 }
d1c4b12b
NC
15939 else
15940 {
15941 section->reloc_info = NULL;
15942 section->num_relocs = 0;
15943 }
1007acb3 15944
015dc7e1 15945 return true;
1007acb3
L
15946}
15947
301a9420
AM
15948#if HAVE_LIBDEBUGINFOD
15949/* Return a hex string representation of the build-id. */
15950unsigned char *
15951get_build_id (void * data)
15952{
ca0e11aa 15953 Filedata * filedata = (Filedata *) data;
301a9420
AM
15954 Elf_Internal_Shdr * shdr;
15955 unsigned long i;
15956
55be8fd0
NC
15957 /* Iterate through notes to find note.gnu.build-id.
15958 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15959 for (i = 0, shdr = filedata->section_headers;
15960 i < filedata->file_header.e_shnum && shdr != NULL;
15961 i++, shdr++)
15962 {
15963 if (shdr->sh_type != SHT_NOTE)
15964 continue;
15965
15966 char * next;
15967 char * end;
15968 size_t data_remaining;
15969 size_t min_notesz;
15970 Elf_External_Note * enote;
15971 Elf_Internal_Note inote;
15972
15973 bfd_vma offset = shdr->sh_offset;
15974 bfd_vma align = shdr->sh_addralign;
15975 bfd_vma length = shdr->sh_size;
15976
15977 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15978 if (enote == NULL)
15979 continue;
15980
15981 if (align < 4)
15982 align = 4;
15983 else if (align != 4 && align != 8)
f761cb13
AM
15984 {
15985 free (enote);
15986 continue;
15987 }
301a9420
AM
15988
15989 end = (char *) enote + length;
15990 data_remaining = end - (char *) enote;
15991
15992 if (!is_ia64_vms (filedata))
15993 {
15994 min_notesz = offsetof (Elf_External_Note, name);
15995 if (data_remaining < min_notesz)
15996 {
55be8fd0
NC
15997 warn (_("\
15998malformed note encountered in section %s whilst scanning for build-id note\n"),
15999 printable_section_name (filedata, shdr));
f761cb13 16000 free (enote);
55be8fd0 16001 continue;
301a9420
AM
16002 }
16003 data_remaining -= min_notesz;
16004
16005 inote.type = BYTE_GET (enote->type);
16006 inote.namesz = BYTE_GET (enote->namesz);
16007 inote.namedata = enote->name;
16008 inote.descsz = BYTE_GET (enote->descsz);
16009 inote.descdata = ((char *) enote
16010 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16011 inote.descpos = offset + (inote.descdata - (char *) enote);
16012 next = ((char *) enote
16013 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16014 }
16015 else
16016 {
16017 Elf64_External_VMS_Note *vms_enote;
16018
16019 /* PR binutils/15191
16020 Make sure that there is enough data to read. */
16021 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16022 if (data_remaining < min_notesz)
16023 {
55be8fd0
NC
16024 warn (_("\
16025malformed note encountered in section %s whilst scanning for build-id note\n"),
16026 printable_section_name (filedata, shdr));
f761cb13 16027 free (enote);
55be8fd0 16028 continue;
301a9420
AM
16029 }
16030 data_remaining -= min_notesz;
16031
16032 vms_enote = (Elf64_External_VMS_Note *) enote;
16033 inote.type = BYTE_GET (vms_enote->type);
16034 inote.namesz = BYTE_GET (vms_enote->namesz);
16035 inote.namedata = vms_enote->name;
16036 inote.descsz = BYTE_GET (vms_enote->descsz);
16037 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16038 inote.descpos = offset + (inote.descdata - (char *) enote);
16039 next = inote.descdata + align_power (inote.descsz, 3);
16040 }
16041
16042 /* Skip malformed notes. */
16043 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16044 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16045 || (size_t) (next - inote.descdata) < inote.descsz
16046 || ((size_t) (next - inote.descdata)
16047 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16048 {
55be8fd0
NC
16049 warn (_("\
16050malformed note encountered in section %s whilst scanning for build-id note\n"),
16051 printable_section_name (filedata, shdr));
f761cb13 16052 free (enote);
301a9420
AM
16053 continue;
16054 }
16055
16056 /* Check if this is the build-id note. If so then convert the build-id
16057 bytes to a hex string. */
16058 if (inote.namesz > 0
24d127aa 16059 && startswith (inote.namedata, "GNU")
301a9420
AM
16060 && inote.type == NT_GNU_BUILD_ID)
16061 {
16062 unsigned long j;
16063 char * build_id;
16064
16065 build_id = malloc (inote.descsz * 2 + 1);
16066 if (build_id == NULL)
f761cb13
AM
16067 {
16068 free (enote);
16069 return NULL;
16070 }
301a9420
AM
16071
16072 for (j = 0; j < inote.descsz; ++j)
16073 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16074 build_id[inote.descsz * 2] = '\0';
f761cb13 16075 free (enote);
301a9420 16076
55be8fd0 16077 return (unsigned char *) build_id;
301a9420 16078 }
f761cb13 16079 free (enote);
301a9420
AM
16080 }
16081
16082 return NULL;
16083}
16084#endif /* HAVE_LIBDEBUGINFOD */
16085
657d0d47
CC
16086/* If this is not NULL, load_debug_section will only look for sections
16087 within the list of sections given here. */
32ec8896 16088static unsigned int * section_subset = NULL;
657d0d47 16089
015dc7e1 16090bool
dda8d76d 16091load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16092{
2cf0635d
NC
16093 struct dwarf_section * section = &debug_displays [debug].section;
16094 Elf_Internal_Shdr * sec;
dda8d76d
NC
16095 Filedata * filedata = (Filedata *) data;
16096
e1dbfc17
L
16097 if (!dump_any_debugging)
16098 return false;
16099
f425ec66
NC
16100 /* Without section headers we cannot find any sections. */
16101 if (filedata->section_headers == NULL)
015dc7e1 16102 return false;
f425ec66 16103
9c1ce108
AM
16104 if (filedata->string_table == NULL
16105 && filedata->file_header.e_shstrndx != SHN_UNDEF
16106 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16107 {
16108 Elf_Internal_Shdr * strs;
16109
16110 /* Read in the string table, so that we have section names to scan. */
16111 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16112
4dff97b2 16113 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16114 {
9c1ce108
AM
16115 filedata->string_table
16116 = (char *) get_data (NULL, filedata, strs->sh_offset,
16117 1, strs->sh_size, _("string table"));
dda8d76d 16118
9c1ce108
AM
16119 filedata->string_table_length
16120 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16121 }
16122 }
d966045b
DJ
16123
16124 /* Locate the debug section. */
dda8d76d 16125 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16126 if (sec != NULL)
16127 section->name = section->uncompressed_name;
16128 else
16129 {
dda8d76d 16130 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16131 if (sec != NULL)
16132 section->name = section->compressed_name;
16133 }
16134 if (sec == NULL)
015dc7e1 16135 return false;
d966045b 16136
657d0d47
CC
16137 /* If we're loading from a subset of sections, and we've loaded
16138 a section matching this name before, it's likely that it's a
16139 different one. */
16140 if (section_subset != NULL)
16141 free_debug_section (debug);
16142
dda8d76d 16143 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16144}
16145
19e6b90e
L
16146void
16147free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16148{
2cf0635d 16149 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16150
19e6b90e
L
16151 if (section->start == NULL)
16152 return;
1007acb3 16153
19e6b90e
L
16154 free ((char *) section->start);
16155 section->start = NULL;
16156 section->address = 0;
16157 section->size = 0;
a788aedd 16158
9db70fc3
AM
16159 free (section->reloc_info);
16160 section->reloc_info = NULL;
16161 section->num_relocs = 0;
1007acb3
L
16162}
16163
015dc7e1 16164static bool
dda8d76d 16165display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16166{
84714f86
AM
16167 const char *name = (section_name_valid (filedata, section)
16168 ? section_name (filedata, section) : "");
16169 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16170 bfd_size_type length;
015dc7e1 16171 bool result = true;
3f5e193b 16172 int i;
1007acb3 16173
19e6b90e
L
16174 length = section->sh_size;
16175 if (length == 0)
1007acb3 16176 {
74e1a04b 16177 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16178 return true;
1007acb3 16179 }
5dff79d8
NC
16180 if (section->sh_type == SHT_NOBITS)
16181 {
16182 /* There is no point in dumping the contents of a debugging section
16183 which has the NOBITS type - the bits in the file will be random.
16184 This can happen when a file containing a .eh_frame section is
16185 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16186 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16187 print_name);
015dc7e1 16188 return false;
5dff79d8 16189 }
1007acb3 16190
24d127aa 16191 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16192 name = ".debug_info";
1007acb3 16193
19e6b90e
L
16194 /* See if we know how to display the contents of this section. */
16195 for (i = 0; i < max; i++)
d85bf2ba
NC
16196 {
16197 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16198 struct dwarf_section_display * display = debug_displays + i;
16199 struct dwarf_section * sec = & display->section;
d966045b 16200
d85bf2ba 16201 if (streq (sec->uncompressed_name, name)
24d127aa 16202 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16203 || streq (sec->compressed_name, name))
16204 {
015dc7e1 16205 bool secondary = (section != find_section (filedata, name));
1007acb3 16206
d85bf2ba
NC
16207 if (secondary)
16208 free_debug_section (id);
dda8d76d 16209
24d127aa 16210 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16211 sec->name = name;
16212 else if (streq (sec->uncompressed_name, name))
16213 sec->name = sec->uncompressed_name;
16214 else
16215 sec->name = sec->compressed_name;
657d0d47 16216
d85bf2ba
NC
16217 if (load_specific_debug_section (id, section, filedata))
16218 {
16219 /* If this debug section is part of a CU/TU set in a .dwp file,
16220 restrict load_debug_section to the sections in that set. */
16221 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16222
d85bf2ba 16223 result &= display->display (sec, filedata);
657d0d47 16224
d85bf2ba 16225 section_subset = NULL;
1007acb3 16226
44266f36 16227 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16228 free_debug_section (id);
16229 }
16230 break;
16231 }
16232 }
1007acb3 16233
19e6b90e 16234 if (i == max)
1007acb3 16235 {
74e1a04b 16236 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16237 result = false;
1007acb3
L
16238 }
16239
19e6b90e 16240 return result;
5b18a4bc 16241}
103f02d3 16242
aef1f6d0
DJ
16243/* Set DUMP_SECTS for all sections where dumps were requested
16244 based on section name. */
16245
16246static void
dda8d76d 16247initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16248{
2cf0635d 16249 struct dump_list_entry * cur;
aef1f6d0
DJ
16250
16251 for (cur = dump_sects_byname; cur; cur = cur->next)
16252 {
16253 unsigned int i;
015dc7e1 16254 bool any = false;
aef1f6d0 16255
dda8d76d 16256 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16257 if (section_name_valid (filedata, filedata->section_headers + i)
16258 && streq (section_name (filedata, filedata->section_headers + i),
16259 cur->name))
aef1f6d0 16260 {
6431e409 16261 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16262 any = true;
aef1f6d0
DJ
16263 }
16264
835f2fae
NC
16265 if (!any && !filedata->is_separate)
16266 warn (_("Section '%s' was not dumped because it does not exist\n"),
16267 cur->name);
aef1f6d0
DJ
16268 }
16269}
16270
015dc7e1 16271static bool
dda8d76d 16272process_section_contents (Filedata * filedata)
5b18a4bc 16273{
2cf0635d 16274 Elf_Internal_Shdr * section;
19e6b90e 16275 unsigned int i;
015dc7e1 16276 bool res = true;
103f02d3 16277
19e6b90e 16278 if (! do_dump)
015dc7e1 16279 return true;
103f02d3 16280
dda8d76d 16281 initialise_dumps_byname (filedata);
aef1f6d0 16282
dda8d76d 16283 for (i = 0, section = filedata->section_headers;
6431e409 16284 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16285 i++, section++)
16286 {
6431e409 16287 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16288
d6bfbc39
NC
16289 if (filedata->is_separate && ! process_links)
16290 dump &= DEBUG_DUMP;
047c3dbf 16291
19e6b90e 16292#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16293 if (dump & DISASS_DUMP)
16294 {
16295 if (! disassemble_section (section, filedata))
015dc7e1 16296 res = false;
dda8d76d 16297 }
19e6b90e 16298#endif
dda8d76d 16299 if (dump & HEX_DUMP)
32ec8896 16300 {
015dc7e1
AM
16301 if (! dump_section_as_bytes (section, filedata, false))
16302 res = false;
32ec8896 16303 }
103f02d3 16304
dda8d76d 16305 if (dump & RELOC_DUMP)
32ec8896 16306 {
015dc7e1
AM
16307 if (! dump_section_as_bytes (section, filedata, true))
16308 res = false;
32ec8896 16309 }
09c11c86 16310
dda8d76d 16311 if (dump & STRING_DUMP)
32ec8896 16312 {
dda8d76d 16313 if (! dump_section_as_strings (section, filedata))
015dc7e1 16314 res = false;
32ec8896 16315 }
cf13d699 16316
dda8d76d 16317 if (dump & DEBUG_DUMP)
32ec8896 16318 {
dda8d76d 16319 if (! display_debug_section (i, section, filedata))
015dc7e1 16320 res = false;
32ec8896 16321 }
7d9813f1 16322
094e34f2 16323#ifdef ENABLE_LIBCTF
7d9813f1
NA
16324 if (dump & CTF_DUMP)
16325 {
16326 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16327 res = false;
7d9813f1 16328 }
094e34f2 16329#endif
5b18a4bc 16330 }
103f02d3 16331
835f2fae 16332 if (! filedata->is_separate)
0ee3043f 16333 {
835f2fae
NC
16334 /* Check to see if the user requested a
16335 dump of a section that does not exist. */
16336 for (; i < filedata->dump.num_dump_sects; i++)
16337 if (filedata->dump.dump_sects[i])
16338 {
ca0e11aa 16339 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16340 res = false;
835f2fae 16341 }
0ee3043f 16342 }
32ec8896
NC
16343
16344 return res;
5b18a4bc 16345}
103f02d3 16346
5b18a4bc 16347static void
19e6b90e 16348process_mips_fpe_exception (int mask)
5b18a4bc 16349{
19e6b90e
L
16350 if (mask)
16351 {
015dc7e1 16352 bool first = true;
32ec8896 16353
19e6b90e 16354 if (mask & OEX_FPU_INEX)
015dc7e1 16355 fputs ("INEX", stdout), first = false;
19e6b90e 16356 if (mask & OEX_FPU_UFLO)
015dc7e1 16357 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16358 if (mask & OEX_FPU_OFLO)
015dc7e1 16359 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16360 if (mask & OEX_FPU_DIV0)
015dc7e1 16361 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16362 if (mask & OEX_FPU_INVAL)
16363 printf ("%sINVAL", first ? "" : "|");
16364 }
5b18a4bc 16365 else
19e6b90e 16366 fputs ("0", stdout);
5b18a4bc 16367}
103f02d3 16368
f6f0e17b
NC
16369/* Display's the value of TAG at location P. If TAG is
16370 greater than 0 it is assumed to be an unknown tag, and
16371 a message is printed to this effect. Otherwise it is
16372 assumed that a message has already been printed.
16373
16374 If the bottom bit of TAG is set it assumed to have a
16375 string value, otherwise it is assumed to have an integer
16376 value.
16377
16378 Returns an updated P pointing to the first unread byte
16379 beyond the end of TAG's value.
16380
16381 Reads at or beyond END will not be made. */
16382
16383static unsigned char *
60abdbed 16384display_tag_value (signed int tag,
f6f0e17b
NC
16385 unsigned char * p,
16386 const unsigned char * const end)
16387{
16388 unsigned long val;
16389
16390 if (tag > 0)
16391 printf (" Tag_unknown_%d: ", tag);
16392
16393 if (p >= end)
16394 {
4082ef84 16395 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16396 }
16397 else if (tag & 1)
16398 {
071436c6
NC
16399 /* PR 17531 file: 027-19978-0.004. */
16400 size_t maxlen = (end - p) - 1;
16401
16402 putchar ('"');
4082ef84
NC
16403 if (maxlen > 0)
16404 {
16405 print_symbol ((int) maxlen, (const char *) p);
16406 p += strnlen ((char *) p, maxlen) + 1;
16407 }
16408 else
16409 {
16410 printf (_("<corrupt string tag>"));
16411 p = (unsigned char *) end;
16412 }
071436c6 16413 printf ("\"\n");
f6f0e17b
NC
16414 }
16415 else
16416 {
cd30bcef 16417 READ_ULEB (val, p, end);
f6f0e17b
NC
16418 printf ("%ld (0x%lx)\n", val, val);
16419 }
16420
4082ef84 16421 assert (p <= end);
f6f0e17b
NC
16422 return p;
16423}
16424
53a346d8
CZ
16425/* ARC ABI attributes section. */
16426
16427static unsigned char *
16428display_arc_attribute (unsigned char * p,
16429 const unsigned char * const end)
16430{
16431 unsigned int tag;
53a346d8
CZ
16432 unsigned int val;
16433
cd30bcef 16434 READ_ULEB (tag, p, end);
53a346d8
CZ
16435
16436 switch (tag)
16437 {
16438 case Tag_ARC_PCS_config:
cd30bcef 16439 READ_ULEB (val, p, end);
53a346d8
CZ
16440 printf (" Tag_ARC_PCS_config: ");
16441 switch (val)
16442 {
16443 case 0:
16444 printf (_("Absent/Non standard\n"));
16445 break;
16446 case 1:
16447 printf (_("Bare metal/mwdt\n"));
16448 break;
16449 case 2:
16450 printf (_("Bare metal/newlib\n"));
16451 break;
16452 case 3:
16453 printf (_("Linux/uclibc\n"));
16454 break;
16455 case 4:
16456 printf (_("Linux/glibc\n"));
16457 break;
16458 default:
16459 printf (_("Unknown\n"));
16460 break;
16461 }
16462 break;
16463
16464 case Tag_ARC_CPU_base:
cd30bcef 16465 READ_ULEB (val, p, end);
53a346d8
CZ
16466 printf (" Tag_ARC_CPU_base: ");
16467 switch (val)
16468 {
16469 default:
16470 case TAG_CPU_NONE:
16471 printf (_("Absent\n"));
16472 break;
16473 case TAG_CPU_ARC6xx:
16474 printf ("ARC6xx\n");
16475 break;
16476 case TAG_CPU_ARC7xx:
16477 printf ("ARC7xx\n");
16478 break;
16479 case TAG_CPU_ARCEM:
16480 printf ("ARCEM\n");
16481 break;
16482 case TAG_CPU_ARCHS:
16483 printf ("ARCHS\n");
16484 break;
16485 }
16486 break;
16487
16488 case Tag_ARC_CPU_variation:
cd30bcef 16489 READ_ULEB (val, p, end);
53a346d8
CZ
16490 printf (" Tag_ARC_CPU_variation: ");
16491 switch (val)
16492 {
16493 default:
16494 if (val > 0 && val < 16)
53a346d8 16495 printf ("Core%d\n", val);
d8cbc93b
JL
16496 else
16497 printf ("Unknown\n");
16498 break;
16499
53a346d8
CZ
16500 case 0:
16501 printf (_("Absent\n"));
16502 break;
16503 }
16504 break;
16505
16506 case Tag_ARC_CPU_name:
16507 printf (" Tag_ARC_CPU_name: ");
16508 p = display_tag_value (-1, p, end);
16509 break;
16510
16511 case Tag_ARC_ABI_rf16:
cd30bcef 16512 READ_ULEB (val, p, end);
53a346d8
CZ
16513 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16514 break;
16515
16516 case Tag_ARC_ABI_osver:
cd30bcef 16517 READ_ULEB (val, p, end);
53a346d8
CZ
16518 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16519 break;
16520
16521 case Tag_ARC_ABI_pic:
16522 case Tag_ARC_ABI_sda:
cd30bcef 16523 READ_ULEB (val, p, end);
53a346d8
CZ
16524 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16525 : " Tag_ARC_ABI_pic: ");
16526 switch (val)
16527 {
16528 case 0:
16529 printf (_("Absent\n"));
16530 break;
16531 case 1:
16532 printf ("MWDT\n");
16533 break;
16534 case 2:
16535 printf ("GNU\n");
16536 break;
16537 default:
16538 printf (_("Unknown\n"));
16539 break;
16540 }
16541 break;
16542
16543 case Tag_ARC_ABI_tls:
cd30bcef 16544 READ_ULEB (val, p, end);
53a346d8
CZ
16545 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16546 break;
16547
16548 case Tag_ARC_ABI_enumsize:
cd30bcef 16549 READ_ULEB (val, p, end);
53a346d8
CZ
16550 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16551 _("smallest"));
16552 break;
16553
16554 case Tag_ARC_ABI_exceptions:
cd30bcef 16555 READ_ULEB (val, p, end);
53a346d8
CZ
16556 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16557 : _("default"));
16558 break;
16559
16560 case Tag_ARC_ABI_double_size:
cd30bcef 16561 READ_ULEB (val, p, end);
53a346d8
CZ
16562 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16563 break;
16564
16565 case Tag_ARC_ISA_config:
16566 printf (" Tag_ARC_ISA_config: ");
16567 p = display_tag_value (-1, p, end);
16568 break;
16569
16570 case Tag_ARC_ISA_apex:
16571 printf (" Tag_ARC_ISA_apex: ");
16572 p = display_tag_value (-1, p, end);
16573 break;
16574
16575 case Tag_ARC_ISA_mpy_option:
cd30bcef 16576 READ_ULEB (val, p, end);
53a346d8
CZ
16577 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16578 break;
16579
db1e1b45 16580 case Tag_ARC_ATR_version:
cd30bcef 16581 READ_ULEB (val, p, end);
db1e1b45 16582 printf (" Tag_ARC_ATR_version: %d\n", val);
16583 break;
16584
53a346d8
CZ
16585 default:
16586 return display_tag_value (tag & 1, p, end);
16587 }
16588
16589 return p;
16590}
16591
11c1ff18
PB
16592/* ARM EABI attributes section. */
16593typedef struct
16594{
70e99720 16595 unsigned int tag;
2cf0635d 16596 const char * name;
11c1ff18 16597 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16598 unsigned int type;
288f0ba2 16599 const char *const *table;
11c1ff18
PB
16600} arm_attr_public_tag;
16601
288f0ba2 16602static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16603 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16604 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16605 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16606 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16607static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16608static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16609 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16610static const char *const arm_attr_tag_FP_arch[] =
bca38921 16611 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16612 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16613static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16614static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16615 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16616 "NEON for ARMv8.1"};
288f0ba2 16617static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16618 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16619 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16620static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16621 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16622static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16623 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16624static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16625 {"Absolute", "PC-relative", "None"};
288f0ba2 16626static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16627 {"None", "direct", "GOT-indirect"};
288f0ba2 16628static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16629 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16630static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16631static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16632 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16633static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16634static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16635static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16636 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16637static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16638 {"Unused", "small", "int", "forced to int"};
288f0ba2 16639static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16640 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16641static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16642 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16643static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16644 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16645static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16646 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16647 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16648static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16649 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16650 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16651static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16652static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16653 {"Not Allowed", "Allowed"};
288f0ba2 16654static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16655 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16656static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16657 {"Follow architecture", "Allowed"};
288f0ba2 16658static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16659 {"Not Allowed", "Allowed"};
288f0ba2 16660static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16661 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16662 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16663static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16664static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16665 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16666 "TrustZone and Virtualization Extensions"};
288f0ba2 16667static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16668 {"Not Allowed", "Allowed"};
11c1ff18 16669
288f0ba2 16670static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16671 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16672
99db83d0
AC
16673static const char * arm_attr_tag_PAC_extension[] =
16674 {"No PAC/AUT instructions",
16675 "PAC/AUT instructions permitted in the NOP space",
16676 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16677
4b535030
AC
16678static const char * arm_attr_tag_BTI_extension[] =
16679 {"BTI instructions not permitted",
16680 "BTI instructions permitted in the NOP space",
16681 "BTI instructions permitted in the NOP and in the non-NOP space"};
16682
b81ee92f
AC
16683static const char * arm_attr_tag_BTI_use[] =
16684 {"Compiled without branch target enforcement",
16685 "Compiled with branch target enforcement"};
16686
c9fed665
AC
16687static const char * arm_attr_tag_PACRET_use[] =
16688 {"Compiled without return address signing and authentication",
16689 "Compiled with return address signing and authentication"};
16690
11c1ff18
PB
16691#define LOOKUP(id, name) \
16692 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16693static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16694{
16695 {4, "CPU_raw_name", 1, NULL},
16696 {5, "CPU_name", 1, NULL},
16697 LOOKUP(6, CPU_arch),
16698 {7, "CPU_arch_profile", 0, NULL},
16699 LOOKUP(8, ARM_ISA_use),
16700 LOOKUP(9, THUMB_ISA_use),
75375b3e 16701 LOOKUP(10, FP_arch),
11c1ff18 16702 LOOKUP(11, WMMX_arch),
f5f53991
AS
16703 LOOKUP(12, Advanced_SIMD_arch),
16704 LOOKUP(13, PCS_config),
11c1ff18
PB
16705 LOOKUP(14, ABI_PCS_R9_use),
16706 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16707 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16708 LOOKUP(17, ABI_PCS_GOT_use),
16709 LOOKUP(18, ABI_PCS_wchar_t),
16710 LOOKUP(19, ABI_FP_rounding),
16711 LOOKUP(20, ABI_FP_denormal),
16712 LOOKUP(21, ABI_FP_exceptions),
16713 LOOKUP(22, ABI_FP_user_exceptions),
16714 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16715 {24, "ABI_align_needed", 0, NULL},
16716 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16717 LOOKUP(26, ABI_enum_size),
16718 LOOKUP(27, ABI_HardFP_use),
16719 LOOKUP(28, ABI_VFP_args),
16720 LOOKUP(29, ABI_WMMX_args),
16721 LOOKUP(30, ABI_optimization_goals),
16722 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16723 {32, "compatibility", 0, NULL},
f5f53991 16724 LOOKUP(34, CPU_unaligned_access),
75375b3e 16725 LOOKUP(36, FP_HP_extension),
8e79c3df 16726 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16727 LOOKUP(42, MPextension_use),
16728 LOOKUP(44, DIV_use),
15afaa63 16729 LOOKUP(46, DSP_extension),
a7ad558c 16730 LOOKUP(48, MVE_arch),
99db83d0 16731 LOOKUP(50, PAC_extension),
4b535030 16732 LOOKUP(52, BTI_extension),
b81ee92f 16733 LOOKUP(74, BTI_use),
c9fed665 16734 LOOKUP(76, PACRET_use),
f5f53991
AS
16735 {64, "nodefaults", 0, NULL},
16736 {65, "also_compatible_with", 0, NULL},
16737 LOOKUP(66, T2EE_use),
16738 {67, "conformance", 1, NULL},
16739 LOOKUP(68, Virtualization_use),
cd21e546 16740 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16741};
16742#undef LOOKUP
16743
11c1ff18 16744static unsigned char *
f6f0e17b
NC
16745display_arm_attribute (unsigned char * p,
16746 const unsigned char * const end)
11c1ff18 16747{
70e99720 16748 unsigned int tag;
70e99720 16749 unsigned int val;
2cf0635d 16750 arm_attr_public_tag * attr;
11c1ff18 16751 unsigned i;
70e99720 16752 unsigned int type;
11c1ff18 16753
cd30bcef 16754 READ_ULEB (tag, p, end);
11c1ff18 16755 attr = NULL;
2cf0635d 16756 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16757 {
16758 if (arm_attr_public_tags[i].tag == tag)
16759 {
16760 attr = &arm_attr_public_tags[i];
16761 break;
16762 }
16763 }
16764
16765 if (attr)
16766 {
16767 printf (" Tag_%s: ", attr->name);
16768 switch (attr->type)
16769 {
16770 case 0:
16771 switch (tag)
16772 {
16773 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16774 READ_ULEB (val, p, end);
11c1ff18
PB
16775 switch (val)
16776 {
2b692964
NC
16777 case 0: printf (_("None\n")); break;
16778 case 'A': printf (_("Application\n")); break;
16779 case 'R': printf (_("Realtime\n")); break;
16780 case 'M': printf (_("Microcontroller\n")); break;
16781 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16782 default: printf ("??? (%d)\n", val); break;
16783 }
16784 break;
16785
75375b3e 16786 case 24: /* Tag_align_needed. */
cd30bcef 16787 READ_ULEB (val, p, end);
75375b3e
MGD
16788 switch (val)
16789 {
2b692964
NC
16790 case 0: printf (_("None\n")); break;
16791 case 1: printf (_("8-byte\n")); break;
16792 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16793 case 3: printf ("??? 3\n"); break;
16794 default:
16795 if (val <= 12)
dd24e3da 16796 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16797 1 << val);
16798 else
16799 printf ("??? (%d)\n", val);
16800 break;
16801 }
16802 break;
16803
16804 case 25: /* Tag_align_preserved. */
cd30bcef 16805 READ_ULEB (val, p, end);
75375b3e
MGD
16806 switch (val)
16807 {
2b692964
NC
16808 case 0: printf (_("None\n")); break;
16809 case 1: printf (_("8-byte, except leaf SP\n")); break;
16810 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16811 case 3: printf ("??? 3\n"); break;
16812 default:
16813 if (val <= 12)
dd24e3da 16814 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16815 1 << val);
16816 else
16817 printf ("??? (%d)\n", val);
16818 break;
16819 }
16820 break;
16821
11c1ff18 16822 case 32: /* Tag_compatibility. */
071436c6 16823 {
cd30bcef 16824 READ_ULEB (val, p, end);
071436c6 16825 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16826 if (p < end - 1)
16827 {
16828 size_t maxlen = (end - p) - 1;
16829
16830 print_symbol ((int) maxlen, (const char *) p);
16831 p += strnlen ((char *) p, maxlen) + 1;
16832 }
16833 else
16834 {
16835 printf (_("<corrupt>"));
16836 p = (unsigned char *) end;
16837 }
071436c6 16838 putchar ('\n');
071436c6 16839 }
11c1ff18
PB
16840 break;
16841
f5f53991 16842 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16843 /* PR 17531: file: 001-505008-0.01. */
16844 if (p < end)
16845 p++;
2b692964 16846 printf (_("True\n"));
f5f53991
AS
16847 break;
16848
16849 case 65: /* Tag_also_compatible_with. */
cd30bcef 16850 READ_ULEB (val, p, end);
f5f53991
AS
16851 if (val == 6 /* Tag_CPU_arch. */)
16852 {
cd30bcef 16853 READ_ULEB (val, p, end);
071436c6 16854 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16855 printf ("??? (%d)\n", val);
16856 else
16857 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16858 }
16859 else
16860 printf ("???\n");
071436c6
NC
16861 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16862 ;
f5f53991
AS
16863 break;
16864
11c1ff18 16865 default:
bee0ee85
NC
16866 printf (_("<unknown: %d>\n"), tag);
16867 break;
11c1ff18
PB
16868 }
16869 return p;
16870
16871 case 1:
f6f0e17b 16872 return display_tag_value (-1, p, end);
11c1ff18 16873 case 2:
f6f0e17b 16874 return display_tag_value (0, p, end);
11c1ff18
PB
16875
16876 default:
16877 assert (attr->type & 0x80);
cd30bcef 16878 READ_ULEB (val, p, end);
11c1ff18
PB
16879 type = attr->type & 0x7f;
16880 if (val >= type)
16881 printf ("??? (%d)\n", val);
16882 else
16883 printf ("%s\n", attr->table[val]);
16884 return p;
16885 }
16886 }
11c1ff18 16887
f6f0e17b 16888 return display_tag_value (tag, p, end);
11c1ff18
PB
16889}
16890
104d59d1 16891static unsigned char *
60bca95a 16892display_gnu_attribute (unsigned char * p,
60abdbed 16893 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16894 const unsigned char * const end)
104d59d1 16895{
cd30bcef 16896 unsigned int tag;
60abdbed 16897 unsigned int val;
104d59d1 16898
cd30bcef 16899 READ_ULEB (tag, p, end);
104d59d1
JM
16900
16901 /* Tag_compatibility is the only generic GNU attribute defined at
16902 present. */
16903 if (tag == 32)
16904 {
cd30bcef 16905 READ_ULEB (val, p, end);
071436c6
NC
16906
16907 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16908 if (p == end)
16909 {
071436c6 16910 printf (_("<corrupt>\n"));
f6f0e17b
NC
16911 warn (_("corrupt vendor attribute\n"));
16912 }
16913 else
16914 {
4082ef84
NC
16915 if (p < end - 1)
16916 {
16917 size_t maxlen = (end - p) - 1;
071436c6 16918
4082ef84
NC
16919 print_symbol ((int) maxlen, (const char *) p);
16920 p += strnlen ((char *) p, maxlen) + 1;
16921 }
16922 else
16923 {
16924 printf (_("<corrupt>"));
16925 p = (unsigned char *) end;
16926 }
071436c6 16927 putchar ('\n');
f6f0e17b 16928 }
104d59d1
JM
16929 return p;
16930 }
16931
16932 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16933 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16934
f6f0e17b 16935 return display_tag_value (tag, p, end);
104d59d1
JM
16936}
16937
85f7484a
PB
16938static unsigned char *
16939display_m68k_gnu_attribute (unsigned char * p,
16940 unsigned int tag,
16941 const unsigned char * const end)
16942{
16943 unsigned int val;
16944
16945 if (tag == Tag_GNU_M68K_ABI_FP)
16946 {
16947 printf (" Tag_GNU_M68K_ABI_FP: ");
16948 if (p == end)
16949 {
16950 printf (_("<corrupt>\n"));
16951 return p;
16952 }
16953 READ_ULEB (val, p, end);
16954
16955 if (val > 3)
16956 printf ("(%#x), ", val);
16957
16958 switch (val & 3)
16959 {
16960 case 0:
16961 printf (_("unspecified hard/soft float\n"));
16962 break;
16963 case 1:
16964 printf (_("hard float\n"));
16965 break;
16966 case 2:
16967 printf (_("soft float\n"));
16968 break;
16969 }
16970 return p;
16971 }
16972
16973 return display_tag_value (tag & 1, p, end);
16974}
16975
34c8bcba 16976static unsigned char *
f6f0e17b 16977display_power_gnu_attribute (unsigned char * p,
60abdbed 16978 unsigned int tag,
f6f0e17b 16979 const unsigned char * const end)
34c8bcba 16980{
005d79fd 16981 unsigned int val;
34c8bcba
JM
16982
16983 if (tag == Tag_GNU_Power_ABI_FP)
16984 {
34c8bcba 16985 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16986 if (p == end)
005d79fd
AM
16987 {
16988 printf (_("<corrupt>\n"));
16989 return p;
16990 }
cd30bcef 16991 READ_ULEB (val, p, end);
60bca95a 16992
005d79fd
AM
16993 if (val > 15)
16994 printf ("(%#x), ", val);
16995
16996 switch (val & 3)
34c8bcba
JM
16997 {
16998 case 0:
005d79fd 16999 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17000 break;
17001 case 1:
005d79fd 17002 printf (_("hard float, "));
34c8bcba
JM
17003 break;
17004 case 2:
005d79fd 17005 printf (_("soft float, "));
34c8bcba 17006 break;
3c7b9897 17007 case 3:
005d79fd 17008 printf (_("single-precision hard float, "));
3c7b9897 17009 break;
005d79fd
AM
17010 }
17011
17012 switch (val & 0xC)
17013 {
17014 case 0:
17015 printf (_("unspecified long double\n"));
17016 break;
17017 case 4:
17018 printf (_("128-bit IBM long double\n"));
17019 break;
17020 case 8:
17021 printf (_("64-bit long double\n"));
17022 break;
17023 case 12:
17024 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17025 break;
17026 }
17027 return p;
005d79fd 17028 }
34c8bcba 17029
c6e65352
DJ
17030 if (tag == Tag_GNU_Power_ABI_Vector)
17031 {
c6e65352 17032 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17033 if (p == end)
005d79fd
AM
17034 {
17035 printf (_("<corrupt>\n"));
17036 return p;
17037 }
cd30bcef 17038 READ_ULEB (val, p, end);
005d79fd
AM
17039
17040 if (val > 3)
17041 printf ("(%#x), ", val);
17042
17043 switch (val & 3)
c6e65352
DJ
17044 {
17045 case 0:
005d79fd 17046 printf (_("unspecified\n"));
c6e65352
DJ
17047 break;
17048 case 1:
005d79fd 17049 printf (_("generic\n"));
c6e65352
DJ
17050 break;
17051 case 2:
17052 printf ("AltiVec\n");
17053 break;
17054 case 3:
17055 printf ("SPE\n");
17056 break;
c6e65352
DJ
17057 }
17058 return p;
005d79fd 17059 }
c6e65352 17060
f82e0623
NF
17061 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17062 {
005d79fd 17063 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17064 if (p == end)
f6f0e17b 17065 {
005d79fd 17066 printf (_("<corrupt>\n"));
f6f0e17b
NC
17067 return p;
17068 }
cd30bcef 17069 READ_ULEB (val, p, end);
0b4362b0 17070
005d79fd
AM
17071 if (val > 2)
17072 printf ("(%#x), ", val);
17073
17074 switch (val & 3)
17075 {
17076 case 0:
17077 printf (_("unspecified\n"));
17078 break;
17079 case 1:
17080 printf ("r3/r4\n");
17081 break;
17082 case 2:
17083 printf (_("memory\n"));
17084 break;
17085 case 3:
17086 printf ("???\n");
17087 break;
17088 }
f82e0623
NF
17089 return p;
17090 }
17091
f6f0e17b 17092 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17093}
17094
643f7afb
AK
17095static unsigned char *
17096display_s390_gnu_attribute (unsigned char * p,
60abdbed 17097 unsigned int tag,
643f7afb
AK
17098 const unsigned char * const end)
17099{
cd30bcef 17100 unsigned int val;
643f7afb
AK
17101
17102 if (tag == Tag_GNU_S390_ABI_Vector)
17103 {
643f7afb 17104 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17105 READ_ULEB (val, p, end);
643f7afb
AK
17106
17107 switch (val)
17108 {
17109 case 0:
17110 printf (_("any\n"));
17111 break;
17112 case 1:
17113 printf (_("software\n"));
17114 break;
17115 case 2:
17116 printf (_("hardware\n"));
17117 break;
17118 default:
17119 printf ("??? (%d)\n", val);
17120 break;
17121 }
17122 return p;
17123 }
17124
17125 return display_tag_value (tag & 1, p, end);
17126}
17127
9e8c70f9 17128static void
60abdbed 17129display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17130{
17131 if (mask)
17132 {
015dc7e1 17133 bool first = true;
071436c6 17134
9e8c70f9 17135 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17136 fputs ("mul32", stdout), first = false;
9e8c70f9 17137 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17138 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17139 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17140 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17141 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17142 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17143 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17144 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17145 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17146 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17147 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17148 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17149 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17150 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17151 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17152 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17153 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17154 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17155 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17156 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17157 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17158 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17159 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17160 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17161 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17162 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17163 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17164 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17165 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17166 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17167 }
17168 else
071436c6
NC
17169 fputc ('0', stdout);
17170 fputc ('\n', stdout);
9e8c70f9
DM
17171}
17172
3d68f91c 17173static void
60abdbed 17174display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17175{
17176 if (mask)
17177 {
015dc7e1 17178 bool first = true;
071436c6 17179
3d68f91c 17180 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17181 fputs ("fjathplus", stdout), first = false;
3d68f91c 17182 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17183 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17184 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17185 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17186 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17187 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17188 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17189 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17190 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17191 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17192 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17193 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17194 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17195 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17196 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17197 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17198 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17199 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17200 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17201 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17202 }
17203 else
071436c6
NC
17204 fputc ('0', stdout);
17205 fputc ('\n', stdout);
3d68f91c
JM
17206}
17207
9e8c70f9 17208static unsigned char *
f6f0e17b 17209display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17210 unsigned int tag,
f6f0e17b 17211 const unsigned char * const end)
9e8c70f9 17212{
cd30bcef 17213 unsigned int val;
3d68f91c 17214
9e8c70f9
DM
17215 if (tag == Tag_GNU_Sparc_HWCAPS)
17216 {
cd30bcef 17217 READ_ULEB (val, p, end);
9e8c70f9 17218 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17219 display_sparc_hwcaps (val);
17220 return p;
3d68f91c
JM
17221 }
17222 if (tag == Tag_GNU_Sparc_HWCAPS2)
17223 {
cd30bcef 17224 READ_ULEB (val, p, end);
3d68f91c
JM
17225 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17226 display_sparc_hwcaps2 (val);
17227 return p;
17228 }
9e8c70f9 17229
f6f0e17b 17230 return display_tag_value (tag, p, end);
9e8c70f9
DM
17231}
17232
351cdf24 17233static void
32ec8896 17234print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17235{
17236 switch (val)
17237 {
17238 case Val_GNU_MIPS_ABI_FP_ANY:
17239 printf (_("Hard or soft float\n"));
17240 break;
17241 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17242 printf (_("Hard float (double precision)\n"));
17243 break;
17244 case Val_GNU_MIPS_ABI_FP_SINGLE:
17245 printf (_("Hard float (single precision)\n"));
17246 break;
17247 case Val_GNU_MIPS_ABI_FP_SOFT:
17248 printf (_("Soft float\n"));
17249 break;
17250 case Val_GNU_MIPS_ABI_FP_OLD_64:
17251 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17252 break;
17253 case Val_GNU_MIPS_ABI_FP_XX:
17254 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17255 break;
17256 case Val_GNU_MIPS_ABI_FP_64:
17257 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17258 break;
17259 case Val_GNU_MIPS_ABI_FP_64A:
17260 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17261 break;
3350cc01
CM
17262 case Val_GNU_MIPS_ABI_FP_NAN2008:
17263 printf (_("NaN 2008 compatibility\n"));
17264 break;
351cdf24
MF
17265 default:
17266 printf ("??? (%d)\n", val);
17267 break;
17268 }
17269}
17270
2cf19d5c 17271static unsigned char *
f6f0e17b 17272display_mips_gnu_attribute (unsigned char * p,
60abdbed 17273 unsigned int tag,
f6f0e17b 17274 const unsigned char * const end)
2cf19d5c 17275{
2cf19d5c
JM
17276 if (tag == Tag_GNU_MIPS_ABI_FP)
17277 {
32ec8896 17278 unsigned int val;
f6f0e17b 17279
2cf19d5c 17280 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17281 READ_ULEB (val, p, end);
351cdf24 17282 print_mips_fp_abi_value (val);
2cf19d5c
JM
17283 return p;
17284 }
17285
a9f58168
CF
17286 if (tag == Tag_GNU_MIPS_ABI_MSA)
17287 {
32ec8896 17288 unsigned int val;
a9f58168 17289
a9f58168 17290 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17291 READ_ULEB (val, p, end);
a9f58168
CF
17292
17293 switch (val)
17294 {
17295 case Val_GNU_MIPS_ABI_MSA_ANY:
17296 printf (_("Any MSA or not\n"));
17297 break;
17298 case Val_GNU_MIPS_ABI_MSA_128:
17299 printf (_("128-bit MSA\n"));
17300 break;
17301 default:
17302 printf ("??? (%d)\n", val);
17303 break;
17304 }
17305 return p;
17306 }
17307
f6f0e17b 17308 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17309}
17310
59e6276b 17311static unsigned char *
f6f0e17b
NC
17312display_tic6x_attribute (unsigned char * p,
17313 const unsigned char * const end)
59e6276b 17314{
60abdbed 17315 unsigned int tag;
cd30bcef 17316 unsigned int val;
59e6276b 17317
cd30bcef 17318 READ_ULEB (tag, p, end);
59e6276b
JM
17319
17320 switch (tag)
17321 {
75fa6dc1 17322 case Tag_ISA:
75fa6dc1 17323 printf (" Tag_ISA: ");
cd30bcef 17324 READ_ULEB (val, p, end);
59e6276b
JM
17325
17326 switch (val)
17327 {
75fa6dc1 17328 case C6XABI_Tag_ISA_none:
59e6276b
JM
17329 printf (_("None\n"));
17330 break;
75fa6dc1 17331 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17332 printf ("C62x\n");
17333 break;
75fa6dc1 17334 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17335 printf ("C67x\n");
17336 break;
75fa6dc1 17337 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17338 printf ("C67x+\n");
17339 break;
75fa6dc1 17340 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17341 printf ("C64x\n");
17342 break;
75fa6dc1 17343 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17344 printf ("C64x+\n");
17345 break;
75fa6dc1 17346 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17347 printf ("C674x\n");
17348 break;
17349 default:
17350 printf ("??? (%d)\n", val);
17351 break;
17352 }
17353 return p;
17354
87779176 17355 case Tag_ABI_wchar_t:
87779176 17356 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17357 READ_ULEB (val, p, end);
87779176
JM
17358 switch (val)
17359 {
17360 case 0:
17361 printf (_("Not used\n"));
17362 break;
17363 case 1:
17364 printf (_("2 bytes\n"));
17365 break;
17366 case 2:
17367 printf (_("4 bytes\n"));
17368 break;
17369 default:
17370 printf ("??? (%d)\n", val);
17371 break;
17372 }
17373 return p;
17374
17375 case Tag_ABI_stack_align_needed:
87779176 17376 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17377 READ_ULEB (val, p, end);
87779176
JM
17378 switch (val)
17379 {
17380 case 0:
17381 printf (_("8-byte\n"));
17382 break;
17383 case 1:
17384 printf (_("16-byte\n"));
17385 break;
17386 default:
17387 printf ("??? (%d)\n", val);
17388 break;
17389 }
17390 return p;
17391
17392 case Tag_ABI_stack_align_preserved:
cd30bcef 17393 READ_ULEB (val, p, end);
87779176
JM
17394 printf (" Tag_ABI_stack_align_preserved: ");
17395 switch (val)
17396 {
17397 case 0:
17398 printf (_("8-byte\n"));
17399 break;
17400 case 1:
17401 printf (_("16-byte\n"));
17402 break;
17403 default:
17404 printf ("??? (%d)\n", val);
17405 break;
17406 }
17407 return p;
17408
b5593623 17409 case Tag_ABI_DSBT:
cd30bcef 17410 READ_ULEB (val, p, end);
b5593623
JM
17411 printf (" Tag_ABI_DSBT: ");
17412 switch (val)
17413 {
17414 case 0:
17415 printf (_("DSBT addressing not used\n"));
17416 break;
17417 case 1:
17418 printf (_("DSBT addressing used\n"));
17419 break;
17420 default:
17421 printf ("??? (%d)\n", val);
17422 break;
17423 }
17424 return p;
17425
87779176 17426 case Tag_ABI_PID:
cd30bcef 17427 READ_ULEB (val, p, end);
87779176
JM
17428 printf (" Tag_ABI_PID: ");
17429 switch (val)
17430 {
17431 case 0:
17432 printf (_("Data addressing position-dependent\n"));
17433 break;
17434 case 1:
17435 printf (_("Data addressing position-independent, GOT near DP\n"));
17436 break;
17437 case 2:
17438 printf (_("Data addressing position-independent, GOT far from DP\n"));
17439 break;
17440 default:
17441 printf ("??? (%d)\n", val);
17442 break;
17443 }
17444 return p;
17445
17446 case Tag_ABI_PIC:
cd30bcef 17447 READ_ULEB (val, p, end);
87779176
JM
17448 printf (" Tag_ABI_PIC: ");
17449 switch (val)
17450 {
17451 case 0:
17452 printf (_("Code addressing position-dependent\n"));
17453 break;
17454 case 1:
17455 printf (_("Code addressing position-independent\n"));
17456 break;
17457 default:
17458 printf ("??? (%d)\n", val);
17459 break;
17460 }
17461 return p;
17462
17463 case Tag_ABI_array_object_alignment:
cd30bcef 17464 READ_ULEB (val, p, end);
87779176
JM
17465 printf (" Tag_ABI_array_object_alignment: ");
17466 switch (val)
17467 {
17468 case 0:
17469 printf (_("8-byte\n"));
17470 break;
17471 case 1:
17472 printf (_("4-byte\n"));
17473 break;
17474 case 2:
17475 printf (_("16-byte\n"));
17476 break;
17477 default:
17478 printf ("??? (%d)\n", val);
17479 break;
17480 }
17481 return p;
17482
17483 case Tag_ABI_array_object_align_expected:
cd30bcef 17484 READ_ULEB (val, p, end);
87779176
JM
17485 printf (" Tag_ABI_array_object_align_expected: ");
17486 switch (val)
17487 {
17488 case 0:
17489 printf (_("8-byte\n"));
17490 break;
17491 case 1:
17492 printf (_("4-byte\n"));
17493 break;
17494 case 2:
17495 printf (_("16-byte\n"));
17496 break;
17497 default:
17498 printf ("??? (%d)\n", val);
17499 break;
17500 }
17501 return p;
17502
3cbd1c06 17503 case Tag_ABI_compatibility:
071436c6 17504 {
cd30bcef 17505 READ_ULEB (val, p, end);
071436c6 17506 printf (" Tag_ABI_compatibility: ");
071436c6 17507 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17508 if (p < end - 1)
17509 {
17510 size_t maxlen = (end - p) - 1;
17511
17512 print_symbol ((int) maxlen, (const char *) p);
17513 p += strnlen ((char *) p, maxlen) + 1;
17514 }
17515 else
17516 {
17517 printf (_("<corrupt>"));
17518 p = (unsigned char *) end;
17519 }
071436c6 17520 putchar ('\n');
071436c6
NC
17521 return p;
17522 }
87779176
JM
17523
17524 case Tag_ABI_conformance:
071436c6 17525 {
4082ef84
NC
17526 printf (" Tag_ABI_conformance: \"");
17527 if (p < end - 1)
17528 {
17529 size_t maxlen = (end - p) - 1;
071436c6 17530
4082ef84
NC
17531 print_symbol ((int) maxlen, (const char *) p);
17532 p += strnlen ((char *) p, maxlen) + 1;
17533 }
17534 else
17535 {
17536 printf (_("<corrupt>"));
17537 p = (unsigned char *) end;
17538 }
071436c6 17539 printf ("\"\n");
071436c6
NC
17540 return p;
17541 }
59e6276b
JM
17542 }
17543
f6f0e17b
NC
17544 return display_tag_value (tag, p, end);
17545}
59e6276b 17546
f6f0e17b 17547static void
60abdbed 17548display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17549{
17550 unsigned long addr = 0;
17551 size_t bytes = end - p;
17552
feceaa59 17553 assert (end >= p);
f6f0e17b 17554 while (bytes)
87779176 17555 {
f6f0e17b
NC
17556 int j;
17557 int k;
17558 int lbytes = (bytes > 16 ? 16 : bytes);
17559
17560 printf (" 0x%8.8lx ", addr);
17561
17562 for (j = 0; j < 16; j++)
17563 {
17564 if (j < lbytes)
17565 printf ("%2.2x", p[j]);
17566 else
17567 printf (" ");
17568
17569 if ((j & 3) == 3)
17570 printf (" ");
17571 }
17572
17573 for (j = 0; j < lbytes; j++)
17574 {
17575 k = p[j];
17576 if (k >= ' ' && k < 0x7f)
17577 printf ("%c", k);
17578 else
17579 printf (".");
17580 }
17581
17582 putchar ('\n');
17583
17584 p += lbytes;
17585 bytes -= lbytes;
17586 addr += lbytes;
87779176 17587 }
59e6276b 17588
f6f0e17b 17589 putchar ('\n');
59e6276b
JM
17590}
17591
13761a11 17592static unsigned char *
b0191216 17593display_msp430_attribute (unsigned char * p,
13761a11
NC
17594 const unsigned char * const end)
17595{
60abdbed
NC
17596 unsigned int val;
17597 unsigned int tag;
13761a11 17598
cd30bcef 17599 READ_ULEB (tag, p, end);
0b4362b0 17600
13761a11
NC
17601 switch (tag)
17602 {
17603 case OFBA_MSPABI_Tag_ISA:
13761a11 17604 printf (" Tag_ISA: ");
cd30bcef 17605 READ_ULEB (val, p, end);
13761a11
NC
17606 switch (val)
17607 {
17608 case 0: printf (_("None\n")); break;
17609 case 1: printf (_("MSP430\n")); break;
17610 case 2: printf (_("MSP430X\n")); break;
17611 default: printf ("??? (%d)\n", val); break;
17612 }
17613 break;
17614
17615 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17616 printf (" Tag_Code_Model: ");
cd30bcef 17617 READ_ULEB (val, p, end);
13761a11
NC
17618 switch (val)
17619 {
17620 case 0: printf (_("None\n")); break;
17621 case 1: printf (_("Small\n")); break;
17622 case 2: printf (_("Large\n")); break;
17623 default: printf ("??? (%d)\n", val); break;
17624 }
17625 break;
17626
17627 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17628 printf (" Tag_Data_Model: ");
cd30bcef 17629 READ_ULEB (val, p, end);
13761a11
NC
17630 switch (val)
17631 {
17632 case 0: printf (_("None\n")); break;
17633 case 1: printf (_("Small\n")); break;
17634 case 2: printf (_("Large\n")); break;
17635 case 3: printf (_("Restricted Large\n")); break;
17636 default: printf ("??? (%d)\n", val); break;
17637 }
17638 break;
17639
17640 default:
17641 printf (_(" <unknown tag %d>: "), tag);
17642
17643 if (tag & 1)
17644 {
071436c6 17645 putchar ('"');
4082ef84
NC
17646 if (p < end - 1)
17647 {
17648 size_t maxlen = (end - p) - 1;
17649
17650 print_symbol ((int) maxlen, (const char *) p);
17651 p += strnlen ((char *) p, maxlen) + 1;
17652 }
17653 else
17654 {
17655 printf (_("<corrupt>"));
17656 p = (unsigned char *) end;
17657 }
071436c6 17658 printf ("\"\n");
13761a11
NC
17659 }
17660 else
17661 {
cd30bcef 17662 READ_ULEB (val, p, end);
13761a11
NC
17663 printf ("%d (0x%x)\n", val, val);
17664 }
17665 break;
17666 }
17667
4082ef84 17668 assert (p <= end);
13761a11
NC
17669 return p;
17670}
17671
c0ea7c52
JL
17672static unsigned char *
17673display_msp430_gnu_attribute (unsigned char * p,
17674 unsigned int tag,
17675 const unsigned char * const end)
17676{
17677 if (tag == Tag_GNU_MSP430_Data_Region)
17678 {
cd30bcef 17679 unsigned int val;
c0ea7c52 17680
c0ea7c52 17681 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17682 READ_ULEB (val, p, end);
c0ea7c52
JL
17683
17684 switch (val)
17685 {
17686 case Val_GNU_MSP430_Data_Region_Any:
17687 printf (_("Any Region\n"));
17688 break;
17689 case Val_GNU_MSP430_Data_Region_Lower:
17690 printf (_("Lower Region Only\n"));
17691 break;
17692 default:
cd30bcef 17693 printf ("??? (%u)\n", val);
c0ea7c52
JL
17694 }
17695 return p;
17696 }
17697 return display_tag_value (tag & 1, p, end);
17698}
17699
2dc8dd17
JW
17700struct riscv_attr_tag_t {
17701 const char *name;
cd30bcef 17702 unsigned int tag;
2dc8dd17
JW
17703};
17704
17705static struct riscv_attr_tag_t riscv_attr_tag[] =
17706{
17707#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17708 T(arch),
17709 T(priv_spec),
17710 T(priv_spec_minor),
17711 T(priv_spec_revision),
17712 T(unaligned_access),
17713 T(stack_align),
17714#undef T
17715};
17716
17717static unsigned char *
17718display_riscv_attribute (unsigned char *p,
17719 const unsigned char * const end)
17720{
cd30bcef
AM
17721 unsigned int val;
17722 unsigned int tag;
2dc8dd17
JW
17723 struct riscv_attr_tag_t *attr = NULL;
17724 unsigned i;
17725
cd30bcef 17726 READ_ULEB (tag, p, end);
2dc8dd17
JW
17727
17728 /* Find the name of attribute. */
17729 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17730 {
17731 if (riscv_attr_tag[i].tag == tag)
17732 {
17733 attr = &riscv_attr_tag[i];
17734 break;
17735 }
17736 }
17737
17738 if (attr)
17739 printf (" %s: ", attr->name);
17740 else
17741 return display_tag_value (tag, p, end);
17742
17743 switch (tag)
17744 {
17745 case Tag_RISCV_priv_spec:
17746 case Tag_RISCV_priv_spec_minor:
17747 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17748 READ_ULEB (val, p, end);
17749 printf (_("%u\n"), val);
2dc8dd17
JW
17750 break;
17751 case Tag_RISCV_unaligned_access:
cd30bcef 17752 READ_ULEB (val, p, end);
2dc8dd17
JW
17753 switch (val)
17754 {
17755 case 0:
17756 printf (_("No unaligned access\n"));
17757 break;
17758 case 1:
17759 printf (_("Unaligned access\n"));
17760 break;
17761 }
17762 break;
17763 case Tag_RISCV_stack_align:
cd30bcef
AM
17764 READ_ULEB (val, p, end);
17765 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17766 break;
17767 case Tag_RISCV_arch:
17768 p = display_tag_value (-1, p, end);
17769 break;
17770 default:
17771 return display_tag_value (tag, p, end);
17772 }
17773
17774 return p;
17775}
17776
0861f561
CQ
17777static unsigned char *
17778display_csky_attribute (unsigned char * p,
17779 const unsigned char * const end)
17780{
17781 unsigned int tag;
17782 unsigned int val;
17783 READ_ULEB (tag, p, end);
17784
17785 if (tag >= Tag_CSKY_MAX)
17786 {
17787 return display_tag_value (-1, p, end);
17788 }
17789
17790 switch (tag)
17791 {
17792 case Tag_CSKY_ARCH_NAME:
17793 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17794 return display_tag_value (-1, p, end);
17795 case Tag_CSKY_CPU_NAME:
17796 printf (" Tag_CSKY_CPU_NAME:\t\t");
17797 return display_tag_value (-1, p, end);
17798
17799 case Tag_CSKY_ISA_FLAGS:
17800 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17801 return display_tag_value (0, p, end);
17802 case Tag_CSKY_ISA_EXT_FLAGS:
17803 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17804 return display_tag_value (0, p, end);
17805
17806 case Tag_CSKY_DSP_VERSION:
17807 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17808 READ_ULEB (val, p, end);
17809 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17810 printf ("DSP Extension\n");
17811 else if (val == VAL_CSKY_DSP_VERSION_2)
17812 printf ("DSP 2.0\n");
17813 break;
17814
17815 case Tag_CSKY_VDSP_VERSION:
17816 printf (" Tag_CSKY_VDSP_VERSION:\t");
17817 READ_ULEB (val, p, end);
17818 printf ("VDSP Version %d\n", val);
17819 break;
17820
17821 case Tag_CSKY_FPU_VERSION:
17822 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17823 READ_ULEB (val, p, end);
17824 if (val == VAL_CSKY_FPU_VERSION_1)
17825 printf ("ABIV1 FPU Version 1\n");
17826 else if (val == VAL_CSKY_FPU_VERSION_2)
17827 printf ("FPU Version 2\n");
17828 break;
17829
17830 case Tag_CSKY_FPU_ABI:
17831 printf (" Tag_CSKY_FPU_ABI:\t\t");
17832 READ_ULEB (val, p, end);
17833 if (val == VAL_CSKY_FPU_ABI_HARD)
17834 printf ("Hard\n");
17835 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17836 printf ("SoftFP\n");
17837 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17838 printf ("Soft\n");
17839 break;
17840 case Tag_CSKY_FPU_ROUNDING:
17841 READ_ULEB (val, p, end);
f253158f
NC
17842 if (val == 1)
17843 {
17844 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17845 printf ("Needed\n");
17846 }
0861f561
CQ
17847 break;
17848 case Tag_CSKY_FPU_DENORMAL:
17849 READ_ULEB (val, p, end);
f253158f
NC
17850 if (val == 1)
17851 {
17852 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17853 printf ("Needed\n");
17854 }
0861f561
CQ
17855 break;
17856 case Tag_CSKY_FPU_Exception:
17857 READ_ULEB (val, p, end);
f253158f
NC
17858 if (val == 1)
17859 {
17860 printf (" Tag_CSKY_FPU_Exception:\t");
17861 printf ("Needed\n");
17862 }
0861f561
CQ
17863 break;
17864 case Tag_CSKY_FPU_NUMBER_MODULE:
17865 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17866 return display_tag_value (-1, p, end);
17867 case Tag_CSKY_FPU_HARDFP:
17868 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17869 READ_ULEB (val, p, end);
17870 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17871 printf (" Half");
17872 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17873 printf (" Single");
17874 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17875 printf (" Double");
17876 printf ("\n");
17877 break;
17878 default:
17879 return display_tag_value (tag, p, end);
17880 }
17881 return p;
17882}
17883
015dc7e1 17884static bool
dda8d76d 17885process_attributes (Filedata * filedata,
60bca95a 17886 const char * public_name,
104d59d1 17887 unsigned int proc_type,
f6f0e17b 17888 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17889 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17890{
2cf0635d 17891 Elf_Internal_Shdr * sect;
11c1ff18 17892 unsigned i;
015dc7e1 17893 bool res = true;
11c1ff18
PB
17894
17895 /* Find the section header so that we get the size. */
dda8d76d
NC
17896 for (i = 0, sect = filedata->section_headers;
17897 i < filedata->file_header.e_shnum;
11c1ff18
PB
17898 i++, sect++)
17899 {
071436c6
NC
17900 unsigned char * contents;
17901 unsigned char * p;
17902
104d59d1 17903 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17904 continue;
17905
dda8d76d 17906 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17907 sect->sh_size, _("attributes"));
60bca95a 17908 if (contents == NULL)
32ec8896 17909 {
015dc7e1 17910 res = false;
32ec8896
NC
17911 continue;
17912 }
60bca95a 17913
11c1ff18 17914 p = contents;
60abdbed
NC
17915 /* The first character is the version of the attributes.
17916 Currently only version 1, (aka 'A') is recognised here. */
17917 if (*p != 'A')
32ec8896
NC
17918 {
17919 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17920 res = false;
32ec8896 17921 }
60abdbed 17922 else
11c1ff18 17923 {
071436c6
NC
17924 bfd_vma section_len;
17925
17926 section_len = sect->sh_size - 1;
11c1ff18 17927 p++;
60bca95a 17928
071436c6 17929 while (section_len > 0)
11c1ff18 17930 {
071436c6 17931 bfd_vma attr_len;
e9847026 17932 unsigned int namelen;
015dc7e1
AM
17933 bool public_section;
17934 bool gnu_section;
11c1ff18 17935
071436c6 17936 if (section_len <= 4)
e0a31db1
NC
17937 {
17938 error (_("Tag section ends prematurely\n"));
015dc7e1 17939 res = false;
e0a31db1
NC
17940 break;
17941 }
071436c6 17942 attr_len = byte_get (p, 4);
11c1ff18 17943 p += 4;
60bca95a 17944
071436c6 17945 if (attr_len > section_len)
11c1ff18 17946 {
071436c6
NC
17947 error (_("Bad attribute length (%u > %u)\n"),
17948 (unsigned) attr_len, (unsigned) section_len);
17949 attr_len = section_len;
015dc7e1 17950 res = false;
11c1ff18 17951 }
74e1a04b 17952 /* PR 17531: file: 001-101425-0.004 */
071436c6 17953 else if (attr_len < 5)
74e1a04b 17954 {
071436c6 17955 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17956 res = false;
74e1a04b
NC
17957 break;
17958 }
e9847026 17959
071436c6
NC
17960 section_len -= attr_len;
17961 attr_len -= 4;
17962
17963 namelen = strnlen ((char *) p, attr_len) + 1;
17964 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17965 {
17966 error (_("Corrupt attribute section name\n"));
015dc7e1 17967 res = false;
e9847026
NC
17968 break;
17969 }
17970
071436c6
NC
17971 printf (_("Attribute Section: "));
17972 print_symbol (INT_MAX, (const char *) p);
17973 putchar ('\n');
60bca95a
NC
17974
17975 if (public_name && streq ((char *) p, public_name))
015dc7e1 17976 public_section = true;
11c1ff18 17977 else
015dc7e1 17978 public_section = false;
60bca95a
NC
17979
17980 if (streq ((char *) p, "gnu"))
015dc7e1 17981 gnu_section = true;
104d59d1 17982 else
015dc7e1 17983 gnu_section = false;
60bca95a 17984
11c1ff18 17985 p += namelen;
071436c6 17986 attr_len -= namelen;
e0a31db1 17987
071436c6 17988 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17989 {
e0a31db1 17990 int tag;
cd30bcef 17991 unsigned int val;
11c1ff18 17992 bfd_vma size;
071436c6 17993 unsigned char * end;
60bca95a 17994
e0a31db1 17995 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17996 if (attr_len < 6)
e0a31db1
NC
17997 {
17998 error (_("Unused bytes at end of section\n"));
015dc7e1 17999 res = false;
e0a31db1
NC
18000 section_len = 0;
18001 break;
18002 }
18003
18004 tag = *(p++);
11c1ff18 18005 size = byte_get (p, 4);
071436c6 18006 if (size > attr_len)
11c1ff18 18007 {
e9847026 18008 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18009 (unsigned) size, (unsigned) attr_len);
015dc7e1 18010 res = false;
071436c6 18011 size = attr_len;
11c1ff18 18012 }
e0a31db1
NC
18013 /* PR binutils/17531: Safe handling of corrupt files. */
18014 if (size < 6)
18015 {
18016 error (_("Bad subsection length (%u < 6)\n"),
18017 (unsigned) size);
015dc7e1 18018 res = false;
e0a31db1
NC
18019 section_len = 0;
18020 break;
18021 }
60bca95a 18022
071436c6 18023 attr_len -= size;
11c1ff18 18024 end = p + size - 1;
071436c6 18025 assert (end <= contents + sect->sh_size);
11c1ff18 18026 p += 4;
60bca95a 18027
11c1ff18
PB
18028 switch (tag)
18029 {
18030 case 1:
2b692964 18031 printf (_("File Attributes\n"));
11c1ff18
PB
18032 break;
18033 case 2:
2b692964 18034 printf (_("Section Attributes:"));
11c1ff18
PB
18035 goto do_numlist;
18036 case 3:
2b692964 18037 printf (_("Symbol Attributes:"));
1a0670f3 18038 /* Fall through. */
11c1ff18
PB
18039 do_numlist:
18040 for (;;)
18041 {
cd30bcef 18042 READ_ULEB (val, p, end);
11c1ff18
PB
18043 if (val == 0)
18044 break;
18045 printf (" %d", val);
18046 }
18047 printf ("\n");
18048 break;
18049 default:
2b692964 18050 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18051 public_section = false;
11c1ff18
PB
18052 break;
18053 }
60bca95a 18054
071436c6 18055 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18056 {
18057 while (p < end)
f6f0e17b 18058 p = display_pub_attribute (p, end);
60abdbed 18059 assert (p == end);
104d59d1 18060 }
071436c6 18061 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18062 {
18063 while (p < end)
18064 p = display_gnu_attribute (p,
f6f0e17b
NC
18065 display_proc_gnu_attribute,
18066 end);
60abdbed 18067 assert (p == end);
11c1ff18 18068 }
071436c6 18069 else if (p < end)
11c1ff18 18070 {
071436c6 18071 printf (_(" Unknown attribute:\n"));
f6f0e17b 18072 display_raw_attribute (p, end);
11c1ff18
PB
18073 p = end;
18074 }
071436c6
NC
18075 else
18076 attr_len = 0;
11c1ff18
PB
18077 }
18078 }
18079 }
d70c5fc7 18080
60bca95a 18081 free (contents);
11c1ff18 18082 }
32ec8896
NC
18083
18084 return res;
11c1ff18
PB
18085}
18086
ccb4c951
RS
18087/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18088 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18089 and return the VMA of the next entry, or -1 if there was a problem.
18090 Does not read from DATA_END or beyond. */
ccb4c951
RS
18091
18092static bfd_vma
82b1b41b
NC
18093print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
18094 unsigned char * data_end)
ccb4c951
RS
18095{
18096 printf (" ");
18097 print_vma (addr, LONG_HEX);
18098 printf (" ");
18099 if (addr < pltgot + 0xfff0)
18100 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18101 else
18102 printf ("%10s", "");
18103 printf (" ");
18104 if (data == NULL)
2b692964 18105 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18106 else
18107 {
18108 bfd_vma entry;
82b1b41b 18109 unsigned char * from = data + addr - pltgot;
ccb4c951 18110
82b1b41b
NC
18111 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18112 {
18113 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18114 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18115 return (bfd_vma) -1;
18116 }
18117 else
18118 {
18119 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18120 print_vma (entry, LONG_HEX);
18121 }
ccb4c951
RS
18122 }
18123 return addr + (is_32bit_elf ? 4 : 8);
18124}
18125
861fb55a
DJ
18126/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18127 PLTGOT. Print the Address and Initial fields of an entry at VMA
18128 ADDR and return the VMA of the next entry. */
18129
18130static bfd_vma
2cf0635d 18131print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
18132{
18133 printf (" ");
18134 print_vma (addr, LONG_HEX);
18135 printf (" ");
18136 if (data == NULL)
2b692964 18137 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18138 else
18139 {
18140 bfd_vma entry;
18141
18142 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18143 print_vma (entry, LONG_HEX);
18144 }
18145 return addr + (is_32bit_elf ? 4 : 8);
18146}
18147
351cdf24
MF
18148static void
18149print_mips_ases (unsigned int mask)
18150{
18151 if (mask & AFL_ASE_DSP)
18152 fputs ("\n\tDSP ASE", stdout);
18153 if (mask & AFL_ASE_DSPR2)
18154 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18155 if (mask & AFL_ASE_DSPR3)
18156 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18157 if (mask & AFL_ASE_EVA)
18158 fputs ("\n\tEnhanced VA Scheme", stdout);
18159 if (mask & AFL_ASE_MCU)
18160 fputs ("\n\tMCU (MicroController) ASE", stdout);
18161 if (mask & AFL_ASE_MDMX)
18162 fputs ("\n\tMDMX ASE", stdout);
18163 if (mask & AFL_ASE_MIPS3D)
18164 fputs ("\n\tMIPS-3D ASE", stdout);
18165 if (mask & AFL_ASE_MT)
18166 fputs ("\n\tMT ASE", stdout);
18167 if (mask & AFL_ASE_SMARTMIPS)
18168 fputs ("\n\tSmartMIPS ASE", stdout);
18169 if (mask & AFL_ASE_VIRT)
18170 fputs ("\n\tVZ ASE", stdout);
18171 if (mask & AFL_ASE_MSA)
18172 fputs ("\n\tMSA ASE", stdout);
18173 if (mask & AFL_ASE_MIPS16)
18174 fputs ("\n\tMIPS16 ASE", stdout);
18175 if (mask & AFL_ASE_MICROMIPS)
18176 fputs ("\n\tMICROMIPS ASE", stdout);
18177 if (mask & AFL_ASE_XPA)
18178 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18179 if (mask & AFL_ASE_MIPS16E2)
18180 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18181 if (mask & AFL_ASE_CRC)
18182 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18183 if (mask & AFL_ASE_GINV)
18184 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18185 if (mask & AFL_ASE_LOONGSON_MMI)
18186 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18187 if (mask & AFL_ASE_LOONGSON_CAM)
18188 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18189 if (mask & AFL_ASE_LOONGSON_EXT)
18190 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18191 if (mask & AFL_ASE_LOONGSON_EXT2)
18192 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18193 if (mask == 0)
18194 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18195 else if ((mask & ~AFL_ASE_MASK) != 0)
18196 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18197}
18198
18199static void
18200print_mips_isa_ext (unsigned int isa_ext)
18201{
18202 switch (isa_ext)
18203 {
18204 case 0:
18205 fputs (_("None"), stdout);
18206 break;
18207 case AFL_EXT_XLR:
18208 fputs ("RMI XLR", stdout);
18209 break;
2c629856
N
18210 case AFL_EXT_OCTEON3:
18211 fputs ("Cavium Networks Octeon3", stdout);
18212 break;
351cdf24
MF
18213 case AFL_EXT_OCTEON2:
18214 fputs ("Cavium Networks Octeon2", stdout);
18215 break;
18216 case AFL_EXT_OCTEONP:
18217 fputs ("Cavium Networks OcteonP", stdout);
18218 break;
351cdf24
MF
18219 case AFL_EXT_OCTEON:
18220 fputs ("Cavium Networks Octeon", stdout);
18221 break;
18222 case AFL_EXT_5900:
18223 fputs ("Toshiba R5900", stdout);
18224 break;
18225 case AFL_EXT_4650:
18226 fputs ("MIPS R4650", stdout);
18227 break;
18228 case AFL_EXT_4010:
18229 fputs ("LSI R4010", stdout);
18230 break;
18231 case AFL_EXT_4100:
18232 fputs ("NEC VR4100", stdout);
18233 break;
18234 case AFL_EXT_3900:
18235 fputs ("Toshiba R3900", stdout);
18236 break;
18237 case AFL_EXT_10000:
18238 fputs ("MIPS R10000", stdout);
18239 break;
18240 case AFL_EXT_SB1:
18241 fputs ("Broadcom SB-1", stdout);
18242 break;
18243 case AFL_EXT_4111:
18244 fputs ("NEC VR4111/VR4181", stdout);
18245 break;
18246 case AFL_EXT_4120:
18247 fputs ("NEC VR4120", stdout);
18248 break;
18249 case AFL_EXT_5400:
18250 fputs ("NEC VR5400", stdout);
18251 break;
18252 case AFL_EXT_5500:
18253 fputs ("NEC VR5500", stdout);
18254 break;
18255 case AFL_EXT_LOONGSON_2E:
18256 fputs ("ST Microelectronics Loongson 2E", stdout);
18257 break;
18258 case AFL_EXT_LOONGSON_2F:
18259 fputs ("ST Microelectronics Loongson 2F", stdout);
18260 break;
38bf472a
MR
18261 case AFL_EXT_INTERAPTIV_MR2:
18262 fputs ("Imagination interAptiv MR2", stdout);
18263 break;
351cdf24 18264 default:
00ac7aa0 18265 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18266 }
18267}
18268
32ec8896 18269static signed int
351cdf24
MF
18270get_mips_reg_size (int reg_size)
18271{
18272 return (reg_size == AFL_REG_NONE) ? 0
18273 : (reg_size == AFL_REG_32) ? 32
18274 : (reg_size == AFL_REG_64) ? 64
18275 : (reg_size == AFL_REG_128) ? 128
18276 : -1;
18277}
18278
015dc7e1 18279static bool
dda8d76d 18280process_mips_specific (Filedata * filedata)
5b18a4bc 18281{
2cf0635d 18282 Elf_Internal_Dyn * entry;
351cdf24 18283 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18284 size_t liblist_offset = 0;
18285 size_t liblistno = 0;
18286 size_t conflictsno = 0;
18287 size_t options_offset = 0;
18288 size_t conflicts_offset = 0;
861fb55a
DJ
18289 size_t pltrelsz = 0;
18290 size_t pltrel = 0;
ccb4c951 18291 bfd_vma pltgot = 0;
861fb55a
DJ
18292 bfd_vma mips_pltgot = 0;
18293 bfd_vma jmprel = 0;
ccb4c951
RS
18294 bfd_vma local_gotno = 0;
18295 bfd_vma gotsym = 0;
18296 bfd_vma symtabno = 0;
015dc7e1 18297 bool res = true;
103f02d3 18298
dda8d76d 18299 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18300 display_mips_gnu_attribute))
015dc7e1 18301 res = false;
2cf19d5c 18302
dda8d76d 18303 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18304
18305 if (sect != NULL)
18306 {
18307 Elf_External_ABIFlags_v0 *abiflags_ext;
18308 Elf_Internal_ABIFlags_v0 abiflags_in;
18309
18310 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18311 {
18312 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18313 res = false;
32ec8896 18314 }
351cdf24
MF
18315 else
18316 {
dda8d76d 18317 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18318 sect->sh_size, _("MIPS ABI Flags section"));
18319 if (abiflags_ext)
18320 {
18321 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18322 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18323 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18324 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18325 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18326 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18327 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18328 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18329 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18330 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18331 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18332
18333 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18334 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18335 if (abiflags_in.isa_rev > 1)
18336 printf ("r%d", abiflags_in.isa_rev);
18337 printf ("\nGPR size: %d",
18338 get_mips_reg_size (abiflags_in.gpr_size));
18339 printf ("\nCPR1 size: %d",
18340 get_mips_reg_size (abiflags_in.cpr1_size));
18341 printf ("\nCPR2 size: %d",
18342 get_mips_reg_size (abiflags_in.cpr2_size));
18343 fputs ("\nFP ABI: ", stdout);
18344 print_mips_fp_abi_value (abiflags_in.fp_abi);
18345 fputs ("ISA Extension: ", stdout);
18346 print_mips_isa_ext (abiflags_in.isa_ext);
18347 fputs ("\nASEs:", stdout);
18348 print_mips_ases (abiflags_in.ases);
18349 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18350 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18351 fputc ('\n', stdout);
18352 free (abiflags_ext);
18353 }
18354 }
18355 }
18356
19e6b90e 18357 /* We have a lot of special sections. Thanks SGI! */
978c4450 18358 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18359 {
18360 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18361 sect = find_section (filedata, ".got");
bbdd9a68
MR
18362 if (sect != NULL)
18363 {
18364 unsigned char *data_end;
18365 unsigned char *data;
18366 bfd_vma ent, end;
18367 int addr_size;
18368
18369 pltgot = sect->sh_addr;
18370
18371 ent = pltgot;
18372 addr_size = (is_32bit_elf ? 4 : 8);
18373 end = pltgot + sect->sh_size;
18374
dda8d76d 18375 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18376 end - pltgot, 1,
18377 _("Global Offset Table data"));
18378 /* PR 12855: Null data is handled gracefully throughout. */
18379 data_end = data + (end - pltgot);
18380
18381 printf (_("\nStatic GOT:\n"));
18382 printf (_(" Canonical gp value: "));
18383 print_vma (ent + 0x7ff0, LONG_HEX);
18384 printf ("\n\n");
18385
18386 /* In a dynamic binary GOT[0] is reserved for the dynamic
18387 loader to store the lazy resolver pointer, however in
18388 a static binary it may well have been omitted and GOT
18389 reduced to a table of addresses.
18390 PR 21344: Check for the entry being fully available
18391 before fetching it. */
18392 if (data
18393 && data + ent - pltgot + addr_size <= data_end
18394 && byte_get (data + ent - pltgot, addr_size) == 0)
18395 {
18396 printf (_(" Reserved entries:\n"));
18397 printf (_(" %*s %10s %*s\n"),
18398 addr_size * 2, _("Address"), _("Access"),
18399 addr_size * 2, _("Value"));
18400 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18401 printf ("\n");
18402 if (ent == (bfd_vma) -1)
18403 goto sgot_print_fail;
18404
18405 /* Check for the MSB of GOT[1] being set, identifying a
18406 GNU object. This entry will be used by some runtime
18407 loaders, to store the module pointer. Otherwise this
18408 is an ordinary local entry.
18409 PR 21344: Check for the entry being fully available
18410 before fetching it. */
18411 if (data
18412 && data + ent - pltgot + addr_size <= data_end
18413 && (byte_get (data + ent - pltgot, addr_size)
18414 >> (addr_size * 8 - 1)) != 0)
18415 {
18416 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18417 printf ("\n");
18418 if (ent == (bfd_vma) -1)
18419 goto sgot_print_fail;
18420 }
18421 printf ("\n");
18422 }
18423
f17e9d8a 18424 if (data != NULL && ent < end)
bbdd9a68
MR
18425 {
18426 printf (_(" Local entries:\n"));
18427 printf (" %*s %10s %*s\n",
18428 addr_size * 2, _("Address"), _("Access"),
18429 addr_size * 2, _("Value"));
18430 while (ent < end)
18431 {
18432 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18433 printf ("\n");
18434 if (ent == (bfd_vma) -1)
18435 goto sgot_print_fail;
18436 }
18437 printf ("\n");
18438 }
18439
18440 sgot_print_fail:
9db70fc3 18441 free (data);
bbdd9a68
MR
18442 }
18443 return res;
18444 }
252b5132 18445
978c4450 18446 for (entry = filedata->dynamic_section;
071436c6 18447 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18448 (entry < filedata->dynamic_section + filedata->dynamic_nent
18449 && entry->d_tag != DT_NULL);
071436c6 18450 ++entry)
252b5132
RH
18451 switch (entry->d_tag)
18452 {
18453 case DT_MIPS_LIBLIST:
d93f0186 18454 liblist_offset
dda8d76d 18455 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18456 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18457 break;
18458 case DT_MIPS_LIBLISTNO:
18459 liblistno = entry->d_un.d_val;
18460 break;
18461 case DT_MIPS_OPTIONS:
dda8d76d 18462 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18463 break;
18464 case DT_MIPS_CONFLICT:
d93f0186 18465 conflicts_offset
dda8d76d 18466 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18467 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18468 break;
18469 case DT_MIPS_CONFLICTNO:
18470 conflictsno = entry->d_un.d_val;
18471 break;
ccb4c951 18472 case DT_PLTGOT:
861fb55a
DJ
18473 pltgot = entry->d_un.d_ptr;
18474 break;
ccb4c951
RS
18475 case DT_MIPS_LOCAL_GOTNO:
18476 local_gotno = entry->d_un.d_val;
18477 break;
18478 case DT_MIPS_GOTSYM:
18479 gotsym = entry->d_un.d_val;
18480 break;
18481 case DT_MIPS_SYMTABNO:
18482 symtabno = entry->d_un.d_val;
18483 break;
861fb55a
DJ
18484 case DT_MIPS_PLTGOT:
18485 mips_pltgot = entry->d_un.d_ptr;
18486 break;
18487 case DT_PLTREL:
18488 pltrel = entry->d_un.d_val;
18489 break;
18490 case DT_PLTRELSZ:
18491 pltrelsz = entry->d_un.d_val;
18492 break;
18493 case DT_JMPREL:
18494 jmprel = entry->d_un.d_ptr;
18495 break;
252b5132
RH
18496 default:
18497 break;
18498 }
18499
18500 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18501 {
2cf0635d 18502 Elf32_External_Lib * elib;
252b5132
RH
18503 size_t cnt;
18504
dda8d76d 18505 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18506 sizeof (Elf32_External_Lib),
18507 liblistno,
18508 _("liblist section data"));
a6e9f9df 18509 if (elib)
252b5132 18510 {
d3a49aa8
AM
18511 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18512 "\nSection '.liblist' contains %lu entries:\n",
18513 (unsigned long) liblistno),
a6e9f9df 18514 (unsigned long) liblistno);
2b692964 18515 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18516 stdout);
18517
18518 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18519 {
a6e9f9df 18520 Elf32_Lib liblist;
91d6fa6a 18521 time_t atime;
d5b07ef4 18522 char timebuf[128];
2cf0635d 18523 struct tm * tmp;
a6e9f9df
AM
18524
18525 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18526 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18527 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18528 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18529 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18530
91d6fa6a 18531 tmp = gmtime (&atime);
e9e44622
JJ
18532 snprintf (timebuf, sizeof (timebuf),
18533 "%04u-%02u-%02uT%02u:%02u:%02u",
18534 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18535 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18536
31104126 18537 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18538 if (valid_dynamic_name (filedata, liblist.l_name))
18539 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18540 else
2b692964 18541 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18542 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18543 liblist.l_version);
a6e9f9df
AM
18544
18545 if (liblist.l_flags == 0)
2b692964 18546 puts (_(" NONE"));
a6e9f9df
AM
18547 else
18548 {
18549 static const struct
252b5132 18550 {
2cf0635d 18551 const char * name;
a6e9f9df 18552 int bit;
252b5132 18553 }
a6e9f9df
AM
18554 l_flags_vals[] =
18555 {
18556 { " EXACT_MATCH", LL_EXACT_MATCH },
18557 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18558 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18559 { " EXPORTS", LL_EXPORTS },
18560 { " DELAY_LOAD", LL_DELAY_LOAD },
18561 { " DELTA", LL_DELTA }
18562 };
18563 int flags = liblist.l_flags;
18564 size_t fcnt;
18565
60bca95a 18566 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18567 if ((flags & l_flags_vals[fcnt].bit) != 0)
18568 {
18569 fputs (l_flags_vals[fcnt].name, stdout);
18570 flags ^= l_flags_vals[fcnt].bit;
18571 }
18572 if (flags != 0)
18573 printf (" %#x", (unsigned int) flags);
252b5132 18574
a6e9f9df
AM
18575 puts ("");
18576 }
252b5132 18577 }
252b5132 18578
a6e9f9df
AM
18579 free (elib);
18580 }
32ec8896 18581 else
015dc7e1 18582 res = false;
252b5132
RH
18583 }
18584
18585 if (options_offset != 0)
18586 {
2cf0635d 18587 Elf_External_Options * eopt;
252b5132
RH
18588 size_t offset;
18589 int cnt;
18590
18591 /* Find the section header so that we get the size. */
dda8d76d 18592 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18593 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18594 if (sect == NULL)
18595 {
18596 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18597 return false;
071436c6 18598 }
7fc0c668
NC
18599 /* PR 24243 */
18600 if (sect->sh_size < sizeof (* eopt))
18601 {
18602 error (_("The MIPS options section is too small.\n"));
015dc7e1 18603 return false;
7fc0c668 18604 }
252b5132 18605
dda8d76d 18606 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18607 sect->sh_size, _("options"));
a6e9f9df 18608 if (eopt)
252b5132 18609 {
fd17d1e6 18610 Elf_Internal_Options option;
76da6bbe 18611
a6e9f9df 18612 offset = cnt = 0;
82b1b41b 18613 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18614 {
2cf0635d 18615 Elf_External_Options * eoption;
fd17d1e6 18616 unsigned int optsize;
252b5132 18617
a6e9f9df 18618 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18619
fd17d1e6 18620 optsize = BYTE_GET (eoption->size);
76da6bbe 18621
82b1b41b 18622 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18623 if (optsize < sizeof (* eopt)
18624 || optsize > sect->sh_size - offset)
82b1b41b 18625 {
645f43a8 18626 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18627 optsize);
645f43a8 18628 free (eopt);
015dc7e1 18629 return false;
82b1b41b 18630 }
fd17d1e6 18631 offset += optsize;
a6e9f9df
AM
18632 ++cnt;
18633 }
252b5132 18634
d3a49aa8
AM
18635 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18636 "\nSection '%s' contains %d entries:\n",
18637 cnt),
dda8d76d 18638 printable_section_name (filedata, sect), cnt);
76da6bbe 18639
82b1b41b 18640 offset = 0;
a6e9f9df 18641 while (cnt-- > 0)
252b5132 18642 {
a6e9f9df 18643 size_t len;
fd17d1e6
AM
18644 Elf_External_Options * eoption;
18645
18646 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18647
18648 option.kind = BYTE_GET (eoption->kind);
18649 option.size = BYTE_GET (eoption->size);
18650 option.section = BYTE_GET (eoption->section);
18651 option.info = BYTE_GET (eoption->info);
a6e9f9df 18652
fd17d1e6 18653 switch (option.kind)
252b5132 18654 {
a6e9f9df
AM
18655 case ODK_NULL:
18656 /* This shouldn't happen. */
d0c4e780 18657 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18658 option.section, option.info);
a6e9f9df 18659 break;
2e6be59c 18660
a6e9f9df
AM
18661 case ODK_REGINFO:
18662 printf (" REGINFO ");
dda8d76d 18663 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18664 {
2cf0635d 18665 Elf32_External_RegInfo * ereg;
b34976b6 18666 Elf32_RegInfo reginfo;
a6e9f9df 18667
2e6be59c 18668 /* 32bit form. */
fd17d1e6
AM
18669 if (option.size < (sizeof (Elf_External_Options)
18670 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18671 {
18672 printf (_("<corrupt>\n"));
18673 error (_("Truncated MIPS REGINFO option\n"));
18674 cnt = 0;
18675 break;
18676 }
18677
fd17d1e6 18678 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18679
a6e9f9df
AM
18680 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18681 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18682 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18683 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18684 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18685 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18686
d0c4e780
AM
18687 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18688 reginfo.ri_gprmask, reginfo.ri_gp_value);
18689 printf (" "
18690 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18691 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18692 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18693 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18694 }
18695 else
18696 {
18697 /* 64 bit form. */
2cf0635d 18698 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18699 Elf64_Internal_RegInfo reginfo;
18700
fd17d1e6
AM
18701 if (option.size < (sizeof (Elf_External_Options)
18702 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18703 {
18704 printf (_("<corrupt>\n"));
18705 error (_("Truncated MIPS REGINFO option\n"));
18706 cnt = 0;
18707 break;
18708 }
18709
fd17d1e6 18710 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18711 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18712 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18713 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18714 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18715 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18716 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18717
d0c4e780
AM
18718 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18719 reginfo.ri_gprmask, reginfo.ri_gp_value);
18720 printf (" "
18721 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18722 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18723 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18724 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18725 }
fd17d1e6 18726 offset += option.size;
a6e9f9df 18727 continue;
2e6be59c 18728
a6e9f9df
AM
18729 case ODK_EXCEPTIONS:
18730 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18731 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18732 fputs (") fpe_max(", stdout);
fd17d1e6 18733 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18734 fputs (")", stdout);
18735
fd17d1e6 18736 if (option.info & OEX_PAGE0)
a6e9f9df 18737 fputs (" PAGE0", stdout);
fd17d1e6 18738 if (option.info & OEX_SMM)
a6e9f9df 18739 fputs (" SMM", stdout);
fd17d1e6 18740 if (option.info & OEX_FPDBUG)
a6e9f9df 18741 fputs (" FPDBUG", stdout);
fd17d1e6 18742 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18743 fputs (" DISMISS", stdout);
18744 break;
2e6be59c 18745
a6e9f9df
AM
18746 case ODK_PAD:
18747 fputs (" PAD ", stdout);
fd17d1e6 18748 if (option.info & OPAD_PREFIX)
a6e9f9df 18749 fputs (" PREFIX", stdout);
fd17d1e6 18750 if (option.info & OPAD_POSTFIX)
a6e9f9df 18751 fputs (" POSTFIX", stdout);
fd17d1e6 18752 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18753 fputs (" SYMBOL", stdout);
18754 break;
2e6be59c 18755
a6e9f9df
AM
18756 case ODK_HWPATCH:
18757 fputs (" HWPATCH ", stdout);
fd17d1e6 18758 if (option.info & OHW_R4KEOP)
a6e9f9df 18759 fputs (" R4KEOP", stdout);
fd17d1e6 18760 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18761 fputs (" R8KPFETCH", stdout);
fd17d1e6 18762 if (option.info & OHW_R5KEOP)
a6e9f9df 18763 fputs (" R5KEOP", stdout);
fd17d1e6 18764 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18765 fputs (" R5KCVTL", stdout);
18766 break;
2e6be59c 18767
a6e9f9df
AM
18768 case ODK_FILL:
18769 fputs (" FILL ", stdout);
18770 /* XXX Print content of info word? */
18771 break;
2e6be59c 18772
a6e9f9df
AM
18773 case ODK_TAGS:
18774 fputs (" TAGS ", stdout);
18775 /* XXX Print content of info word? */
18776 break;
2e6be59c 18777
a6e9f9df
AM
18778 case ODK_HWAND:
18779 fputs (" HWAND ", stdout);
fd17d1e6 18780 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18781 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18782 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18783 fputs (" R4KEOP_CLEAN", stdout);
18784 break;
2e6be59c 18785
a6e9f9df
AM
18786 case ODK_HWOR:
18787 fputs (" HWOR ", stdout);
fd17d1e6 18788 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18789 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18790 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18791 fputs (" R4KEOP_CLEAN", stdout);
18792 break;
2e6be59c 18793
a6e9f9df 18794 case ODK_GP_GROUP:
d0c4e780 18795 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18796 option.info & OGP_GROUP,
18797 (option.info & OGP_SELF) >> 16);
a6e9f9df 18798 break;
2e6be59c 18799
a6e9f9df 18800 case ODK_IDENT:
d0c4e780 18801 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18802 option.info & OGP_GROUP,
18803 (option.info & OGP_SELF) >> 16);
a6e9f9df 18804 break;
2e6be59c 18805
a6e9f9df
AM
18806 default:
18807 /* This shouldn't happen. */
d0c4e780 18808 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18809 option.kind, option.section, option.info);
a6e9f9df 18810 break;
252b5132 18811 }
a6e9f9df 18812
2cf0635d 18813 len = sizeof (* eopt);
fd17d1e6 18814 while (len < option.size)
82b1b41b 18815 {
fd17d1e6 18816 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18817
82b1b41b
NC
18818 if (ISPRINT (datum))
18819 printf ("%c", datum);
18820 else
18821 printf ("\\%03o", datum);
18822 len ++;
18823 }
a6e9f9df 18824 fputs ("\n", stdout);
82b1b41b 18825
fd17d1e6 18826 offset += option.size;
252b5132 18827 }
a6e9f9df 18828 free (eopt);
252b5132 18829 }
32ec8896 18830 else
015dc7e1 18831 res = false;
252b5132
RH
18832 }
18833
18834 if (conflicts_offset != 0 && conflictsno != 0)
18835 {
2cf0635d 18836 Elf32_Conflict * iconf;
252b5132
RH
18837 size_t cnt;
18838
978c4450 18839 if (filedata->dynamic_symbols == NULL)
252b5132 18840 {
591a748a 18841 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18842 return false;
252b5132
RH
18843 }
18844
7296a62a
NC
18845 /* PR 21345 - print a slightly more helpful error message
18846 if we are sure that the cmalloc will fail. */
645f43a8 18847 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18848 {
18849 error (_("Overlarge number of conflicts detected: %lx\n"),
18850 (long) conflictsno);
015dc7e1 18851 return false;
7296a62a
NC
18852 }
18853
3f5e193b 18854 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18855 if (iconf == NULL)
18856 {
8b73c356 18857 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18858 return false;
252b5132
RH
18859 }
18860
9ea033b2 18861 if (is_32bit_elf)
252b5132 18862 {
2cf0635d 18863 Elf32_External_Conflict * econf32;
a6e9f9df 18864
3f5e193b 18865 econf32 = (Elf32_External_Conflict *)
95099889
AM
18866 get_data (NULL, filedata, conflicts_offset,
18867 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18868 if (!econf32)
5a814d6d
AM
18869 {
18870 free (iconf);
015dc7e1 18871 return false;
5a814d6d 18872 }
252b5132
RH
18873
18874 for (cnt = 0; cnt < conflictsno; ++cnt)
18875 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18876
18877 free (econf32);
252b5132
RH
18878 }
18879 else
18880 {
2cf0635d 18881 Elf64_External_Conflict * econf64;
a6e9f9df 18882
3f5e193b 18883 econf64 = (Elf64_External_Conflict *)
95099889
AM
18884 get_data (NULL, filedata, conflicts_offset,
18885 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18886 if (!econf64)
5a814d6d
AM
18887 {
18888 free (iconf);
015dc7e1 18889 return false;
5a814d6d 18890 }
252b5132
RH
18891
18892 for (cnt = 0; cnt < conflictsno; ++cnt)
18893 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18894
18895 free (econf64);
252b5132
RH
18896 }
18897
d3a49aa8
AM
18898 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18899 "\nSection '.conflict' contains %lu entries:\n",
18900 (unsigned long) conflictsno),
c7e7ca54 18901 (unsigned long) conflictsno);
252b5132
RH
18902 puts (_(" Num: Index Value Name"));
18903
18904 for (cnt = 0; cnt < conflictsno; ++cnt)
18905 {
b34976b6 18906 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18907
978c4450 18908 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18909 printf (_("<corrupt symbol index>"));
d79b3d50 18910 else
e0a31db1
NC
18911 {
18912 Elf_Internal_Sym * psym;
18913
978c4450 18914 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18915 print_vma (psym->st_value, FULL_HEX);
18916 putchar (' ');
84714f86
AM
18917 if (valid_dynamic_name (filedata, psym->st_name))
18918 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18919 else
18920 printf (_("<corrupt: %14ld>"), psym->st_name);
18921 }
31104126 18922 putchar ('\n');
252b5132
RH
18923 }
18924
252b5132
RH
18925 free (iconf);
18926 }
18927
ccb4c951
RS
18928 if (pltgot != 0 && local_gotno != 0)
18929 {
91d6fa6a 18930 bfd_vma ent, local_end, global_end;
bbeee7ea 18931 size_t i, offset;
2cf0635d 18932 unsigned char * data;
82b1b41b 18933 unsigned char * data_end;
bbeee7ea 18934 int addr_size;
ccb4c951 18935
91d6fa6a 18936 ent = pltgot;
ccb4c951
RS
18937 addr_size = (is_32bit_elf ? 4 : 8);
18938 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18939
74e1a04b
NC
18940 /* PR binutils/17533 file: 012-111227-0.004 */
18941 if (symtabno < gotsym)
18942 {
18943 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18944 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18945 return false;
74e1a04b 18946 }
82b1b41b 18947
74e1a04b 18948 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18949 /* PR 17531: file: 54c91a34. */
18950 if (global_end < local_end)
18951 {
18952 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18953 return false;
82b1b41b 18954 }
948f632f 18955
dda8d76d
NC
18956 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18957 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18958 global_end - pltgot, 1,
18959 _("Global Offset Table data"));
919383ac 18960 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18961 data_end = data + (global_end - pltgot);
59245841 18962
ccb4c951
RS
18963 printf (_("\nPrimary GOT:\n"));
18964 printf (_(" Canonical gp value: "));
18965 print_vma (pltgot + 0x7ff0, LONG_HEX);
18966 printf ("\n\n");
18967
18968 printf (_(" Reserved entries:\n"));
18969 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18970 addr_size * 2, _("Address"), _("Access"),
18971 addr_size * 2, _("Initial"));
82b1b41b 18972 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18973 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18974 if (ent == (bfd_vma) -1)
18975 goto got_print_fail;
75ec1fdb 18976
c4ab9505
MR
18977 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18978 This entry will be used by some runtime loaders, to store the
18979 module pointer. Otherwise this is an ordinary local entry.
18980 PR 21344: Check for the entry being fully available before
18981 fetching it. */
18982 if (data
18983 && data + ent - pltgot + addr_size <= data_end
18984 && (byte_get (data + ent - pltgot, addr_size)
18985 >> (addr_size * 8 - 1)) != 0)
18986 {
18987 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18988 printf (_(" Module pointer (GNU extension)\n"));
18989 if (ent == (bfd_vma) -1)
18990 goto got_print_fail;
ccb4c951
RS
18991 }
18992 printf ("\n");
18993
f17e9d8a 18994 if (data != NULL && ent < local_end)
ccb4c951
RS
18995 {
18996 printf (_(" Local entries:\n"));
cc5914eb 18997 printf (" %*s %10s %*s\n",
2b692964
NC
18998 addr_size * 2, _("Address"), _("Access"),
18999 addr_size * 2, _("Initial"));
91d6fa6a 19000 while (ent < local_end)
ccb4c951 19001 {
82b1b41b 19002 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19003 printf ("\n");
82b1b41b
NC
19004 if (ent == (bfd_vma) -1)
19005 goto got_print_fail;
ccb4c951
RS
19006 }
19007 printf ("\n");
19008 }
19009
f17e9d8a 19010 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19011 {
19012 int sym_width;
19013
19014 printf (_(" Global entries:\n"));
cc5914eb 19015 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19016 addr_size * 2, _("Address"),
19017 _("Access"),
2b692964 19018 addr_size * 2, _("Initial"),
9cf03b7e
NC
19019 addr_size * 2, _("Sym.Val."),
19020 _("Type"),
19021 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19022 _("Ndx"), _("Name"));
0b4362b0 19023
ccb4c951 19024 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19025
ccb4c951
RS
19026 for (i = gotsym; i < symtabno; i++)
19027 {
82b1b41b 19028 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19029 printf (" ");
e0a31db1 19030
978c4450 19031 if (filedata->dynamic_symbols == NULL)
e0a31db1 19032 printf (_("<no dynamic symbols>"));
978c4450 19033 else if (i < filedata->num_dynamic_syms)
e0a31db1 19034 {
978c4450 19035 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19036
19037 print_vma (psym->st_value, LONG_HEX);
19038 printf (" %-7s %3s ",
dda8d76d
NC
19039 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19040 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19041
84714f86 19042 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19043 print_symbol (sym_width,
84714f86 19044 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19045 else
19046 printf (_("<corrupt: %14ld>"), psym->st_name);
19047 }
ccb4c951 19048 else
7fc5ac57
JBG
19049 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19050 (unsigned long) i);
e0a31db1 19051
ccb4c951 19052 printf ("\n");
82b1b41b
NC
19053 if (ent == (bfd_vma) -1)
19054 break;
ccb4c951
RS
19055 }
19056 printf ("\n");
19057 }
19058
82b1b41b 19059 got_print_fail:
9db70fc3 19060 free (data);
ccb4c951
RS
19061 }
19062
861fb55a
DJ
19063 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19064 {
91d6fa6a 19065 bfd_vma ent, end;
861fb55a
DJ
19066 size_t offset, rel_offset;
19067 unsigned long count, i;
2cf0635d 19068 unsigned char * data;
861fb55a 19069 int addr_size, sym_width;
2cf0635d 19070 Elf_Internal_Rela * rels;
861fb55a 19071
dda8d76d 19072 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19073 if (pltrel == DT_RELA)
19074 {
dda8d76d 19075 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19076 return false;
861fb55a
DJ
19077 }
19078 else
19079 {
dda8d76d 19080 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19081 return false;
861fb55a
DJ
19082 }
19083
91d6fa6a 19084 ent = mips_pltgot;
861fb55a
DJ
19085 addr_size = (is_32bit_elf ? 4 : 8);
19086 end = mips_pltgot + (2 + count) * addr_size;
19087
dda8d76d
NC
19088 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19089 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19090 1, _("Procedure Linkage Table data"));
59245841 19091 if (data == NULL)
288f0ba2
AM
19092 {
19093 free (rels);
015dc7e1 19094 return false;
288f0ba2 19095 }
59245841 19096
9cf03b7e 19097 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19098 printf (_(" Reserved entries:\n"));
19099 printf (_(" %*s %*s Purpose\n"),
2b692964 19100 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19101 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19102 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19103 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19104 printf (_(" Module pointer\n"));
861fb55a
DJ
19105 printf ("\n");
19106
19107 printf (_(" Entries:\n"));
cc5914eb 19108 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19109 addr_size * 2, _("Address"),
19110 addr_size * 2, _("Initial"),
19111 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19112 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19113 for (i = 0; i < count; i++)
19114 {
df97ab2a 19115 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19116
91d6fa6a 19117 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19118 printf (" ");
e0a31db1 19119
978c4450 19120 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19121 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19122 else
e0a31db1 19123 {
978c4450 19124 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19125
19126 print_vma (psym->st_value, LONG_HEX);
19127 printf (" %-7s %3s ",
dda8d76d
NC
19128 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19129 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19130 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19131 print_symbol (sym_width,
84714f86 19132 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19133 else
19134 printf (_("<corrupt: %14ld>"), psym->st_name);
19135 }
861fb55a
DJ
19136 printf ("\n");
19137 }
19138 printf ("\n");
19139
9db70fc3 19140 free (data);
861fb55a
DJ
19141 free (rels);
19142 }
19143
32ec8896 19144 return res;
252b5132
RH
19145}
19146
015dc7e1 19147static bool
dda8d76d 19148process_nds32_specific (Filedata * filedata)
35c08157
KLC
19149{
19150 Elf_Internal_Shdr *sect = NULL;
19151
dda8d76d 19152 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19153 if (sect != NULL && sect->sh_size >= 4)
35c08157 19154 {
9c7b8e9b
AM
19155 unsigned char *buf;
19156 unsigned int flag;
35c08157
KLC
19157
19158 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19159 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19160 _("NDS32 elf flags section"));
35c08157 19161
9c7b8e9b 19162 if (buf == NULL)
015dc7e1 19163 return false;
32ec8896 19164
9c7b8e9b
AM
19165 flag = byte_get (buf, 4);
19166 free (buf);
19167 switch (flag & 0x3)
35c08157
KLC
19168 {
19169 case 0:
19170 printf ("(VEC_SIZE):\tNo entry.\n");
19171 break;
19172 case 1:
19173 printf ("(VEC_SIZE):\t4 bytes\n");
19174 break;
19175 case 2:
19176 printf ("(VEC_SIZE):\t16 bytes\n");
19177 break;
19178 case 3:
19179 printf ("(VEC_SIZE):\treserved\n");
19180 break;
19181 }
19182 }
19183
015dc7e1 19184 return true;
35c08157
KLC
19185}
19186
015dc7e1 19187static bool
dda8d76d 19188process_gnu_liblist (Filedata * filedata)
047b2264 19189{
2cf0635d
NC
19190 Elf_Internal_Shdr * section;
19191 Elf_Internal_Shdr * string_sec;
19192 Elf32_External_Lib * elib;
19193 char * strtab;
c256ffe7 19194 size_t strtab_size;
047b2264 19195 size_t cnt;
d3a49aa8 19196 unsigned long num_liblist;
047b2264 19197 unsigned i;
015dc7e1 19198 bool res = true;
047b2264
JJ
19199
19200 if (! do_arch)
015dc7e1 19201 return true;
047b2264 19202
dda8d76d
NC
19203 for (i = 0, section = filedata->section_headers;
19204 i < filedata->file_header.e_shnum;
b34976b6 19205 i++, section++)
047b2264
JJ
19206 {
19207 switch (section->sh_type)
19208 {
19209 case SHT_GNU_LIBLIST:
dda8d76d 19210 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19211 break;
19212
3f5e193b 19213 elib = (Elf32_External_Lib *)
dda8d76d 19214 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19215 _("liblist section data"));
047b2264
JJ
19216
19217 if (elib == NULL)
32ec8896 19218 {
015dc7e1 19219 res = false;
32ec8896
NC
19220 break;
19221 }
047b2264 19222
dda8d76d
NC
19223 string_sec = filedata->section_headers + section->sh_link;
19224 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19225 string_sec->sh_size,
19226 _("liblist string table"));
047b2264
JJ
19227 if (strtab == NULL
19228 || section->sh_entsize != sizeof (Elf32_External_Lib))
19229 {
19230 free (elib);
2842702f 19231 free (strtab);
015dc7e1 19232 res = false;
047b2264
JJ
19233 break;
19234 }
59245841 19235 strtab_size = string_sec->sh_size;
047b2264 19236
d3a49aa8
AM
19237 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19238 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19239 "\nLibrary list section '%s' contains %lu entries:\n",
19240 num_liblist),
dda8d76d 19241 printable_section_name (filedata, section),
d3a49aa8 19242 num_liblist);
047b2264 19243
2b692964 19244 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19245
19246 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19247 ++cnt)
19248 {
19249 Elf32_Lib liblist;
91d6fa6a 19250 time_t atime;
d5b07ef4 19251 char timebuf[128];
2cf0635d 19252 struct tm * tmp;
047b2264
JJ
19253
19254 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19255 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19256 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19257 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19258 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19259
91d6fa6a 19260 tmp = gmtime (&atime);
e9e44622
JJ
19261 snprintf (timebuf, sizeof (timebuf),
19262 "%04u-%02u-%02uT%02u:%02u:%02u",
19263 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19264 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19265
19266 printf ("%3lu: ", (unsigned long) cnt);
19267 if (do_wide)
c256ffe7 19268 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19269 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19270 else
c256ffe7 19271 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19272 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19273 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19274 liblist.l_version, liblist.l_flags);
19275 }
19276
19277 free (elib);
2842702f 19278 free (strtab);
047b2264
JJ
19279 }
19280 }
19281
32ec8896 19282 return res;
047b2264
JJ
19283}
19284
9437c45b 19285static const char *
dda8d76d 19286get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19287{
19288 static char buff[64];
103f02d3 19289
dda8d76d 19290 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19291 switch (e_type)
19292 {
57346661 19293 case NT_AUXV:
1ec5cd37 19294 return _("NT_AUXV (auxiliary vector)");
57346661 19295 case NT_PRSTATUS:
1ec5cd37 19296 return _("NT_PRSTATUS (prstatus structure)");
57346661 19297 case NT_FPREGSET:
1ec5cd37 19298 return _("NT_FPREGSET (floating point registers)");
57346661 19299 case NT_PRPSINFO:
1ec5cd37 19300 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19301 case NT_TASKSTRUCT:
1ec5cd37 19302 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19303 case NT_GDB_TDESC:
19304 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19305 case NT_PRXFPREG:
1ec5cd37 19306 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19307 case NT_PPC_VMX:
19308 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19309 case NT_PPC_VSX:
19310 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19311 case NT_PPC_TAR:
19312 return _("NT_PPC_TAR (ppc TAR register)");
19313 case NT_PPC_PPR:
19314 return _("NT_PPC_PPR (ppc PPR register)");
19315 case NT_PPC_DSCR:
19316 return _("NT_PPC_DSCR (ppc DSCR register)");
19317 case NT_PPC_EBB:
19318 return _("NT_PPC_EBB (ppc EBB registers)");
19319 case NT_PPC_PMU:
19320 return _("NT_PPC_PMU (ppc PMU registers)");
19321 case NT_PPC_TM_CGPR:
19322 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19323 case NT_PPC_TM_CFPR:
19324 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19325 case NT_PPC_TM_CVMX:
19326 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19327 case NT_PPC_TM_CVSX:
3fd21718 19328 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19329 case NT_PPC_TM_SPR:
19330 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19331 case NT_PPC_TM_CTAR:
19332 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19333 case NT_PPC_TM_CPPR:
19334 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19335 case NT_PPC_TM_CDSCR:
19336 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19337 case NT_386_TLS:
19338 return _("NT_386_TLS (x86 TLS information)");
19339 case NT_386_IOPERM:
19340 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19341 case NT_X86_XSTATE:
19342 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19343 case NT_X86_CET:
19344 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19345 case NT_S390_HIGH_GPRS:
19346 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19347 case NT_S390_TIMER:
19348 return _("NT_S390_TIMER (s390 timer register)");
19349 case NT_S390_TODCMP:
19350 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19351 case NT_S390_TODPREG:
19352 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19353 case NT_S390_CTRS:
19354 return _("NT_S390_CTRS (s390 control registers)");
19355 case NT_S390_PREFIX:
19356 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19357 case NT_S390_LAST_BREAK:
19358 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19359 case NT_S390_SYSTEM_CALL:
19360 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19361 case NT_S390_TDB:
19362 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19363 case NT_S390_VXRS_LOW:
19364 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19365 case NT_S390_VXRS_HIGH:
19366 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19367 case NT_S390_GS_CB:
19368 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19369 case NT_S390_GS_BC:
19370 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19371 case NT_ARM_VFP:
19372 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19373 case NT_ARM_TLS:
19374 return _("NT_ARM_TLS (AArch TLS registers)");
19375 case NT_ARM_HW_BREAK:
19376 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19377 case NT_ARM_HW_WATCH:
19378 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19379 case NT_ARM_SYSTEM_CALL:
19380 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19381 case NT_ARM_SVE:
19382 return _("NT_ARM_SVE (AArch SVE registers)");
19383 case NT_ARM_PAC_MASK:
19384 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19385 case NT_ARM_PACA_KEYS:
19386 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19387 case NT_ARM_PACG_KEYS:
19388 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19389 case NT_ARM_TAGGED_ADDR_CTRL:
19390 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19391 case NT_ARM_PAC_ENABLED_KEYS:
19392 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19393 case NT_ARC_V2:
19394 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19395 case NT_RISCV_CSR:
19396 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19397 case NT_PSTATUS:
1ec5cd37 19398 return _("NT_PSTATUS (pstatus structure)");
57346661 19399 case NT_FPREGS:
1ec5cd37 19400 return _("NT_FPREGS (floating point registers)");
57346661 19401 case NT_PSINFO:
1ec5cd37 19402 return _("NT_PSINFO (psinfo structure)");
57346661 19403 case NT_LWPSTATUS:
1ec5cd37 19404 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19405 case NT_LWPSINFO:
1ec5cd37 19406 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19407 case NT_WIN32PSTATUS:
1ec5cd37 19408 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19409 case NT_SIGINFO:
19410 return _("NT_SIGINFO (siginfo_t data)");
19411 case NT_FILE:
19412 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19413 default:
19414 break;
19415 }
19416 else
19417 switch (e_type)
19418 {
19419 case NT_VERSION:
19420 return _("NT_VERSION (version)");
19421 case NT_ARCH:
19422 return _("NT_ARCH (architecture)");
9ef920e9 19423 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19424 return _("OPEN");
9ef920e9 19425 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19426 return _("func");
c8795e1f
NC
19427 case NT_GO_BUILDID:
19428 return _("GO BUILDID");
3ac925fc
LB
19429 case FDO_PACKAGING_METADATA:
19430 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19431 default:
19432 break;
19433 }
19434
e9e44622 19435 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19436 return buff;
779fe533
NC
19437}
19438
015dc7e1 19439static bool
9ece1fa9
TT
19440print_core_note (Elf_Internal_Note *pnote)
19441{
19442 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19443 bfd_vma count, page_size;
19444 unsigned char *descdata, *filenames, *descend;
19445
19446 if (pnote->type != NT_FILE)
04ac15ab
AS
19447 {
19448 if (do_wide)
19449 printf ("\n");
015dc7e1 19450 return true;
04ac15ab 19451 }
9ece1fa9
TT
19452
19453#ifndef BFD64
19454 if (!is_32bit_elf)
19455 {
19456 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19457 /* Still "successful". */
015dc7e1 19458 return true;
9ece1fa9
TT
19459 }
19460#endif
19461
19462 if (pnote->descsz < 2 * addr_size)
19463 {
32ec8896 19464 error (_(" Malformed note - too short for header\n"));
015dc7e1 19465 return false;
9ece1fa9
TT
19466 }
19467
19468 descdata = (unsigned char *) pnote->descdata;
19469 descend = descdata + pnote->descsz;
19470
19471 if (descdata[pnote->descsz - 1] != '\0')
19472 {
32ec8896 19473 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19474 return false;
9ece1fa9
TT
19475 }
19476
19477 count = byte_get (descdata, addr_size);
19478 descdata += addr_size;
19479
19480 page_size = byte_get (descdata, addr_size);
19481 descdata += addr_size;
19482
5396a86e
AM
19483 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19484 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19485 {
32ec8896 19486 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19487 return false;
9ece1fa9
TT
19488 }
19489
19490 printf (_(" Page size: "));
19491 print_vma (page_size, DEC);
19492 printf ("\n");
19493
19494 printf (_(" %*s%*s%*s\n"),
19495 (int) (2 + 2 * addr_size), _("Start"),
19496 (int) (4 + 2 * addr_size), _("End"),
19497 (int) (4 + 2 * addr_size), _("Page Offset"));
19498 filenames = descdata + count * 3 * addr_size;
595712bb 19499 while (count-- > 0)
9ece1fa9
TT
19500 {
19501 bfd_vma start, end, file_ofs;
19502
19503 if (filenames == descend)
19504 {
32ec8896 19505 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19506 return false;
9ece1fa9
TT
19507 }
19508
19509 start = byte_get (descdata, addr_size);
19510 descdata += addr_size;
19511 end = byte_get (descdata, addr_size);
19512 descdata += addr_size;
19513 file_ofs = byte_get (descdata, addr_size);
19514 descdata += addr_size;
19515
19516 printf (" ");
19517 print_vma (start, FULL_HEX);
19518 printf (" ");
19519 print_vma (end, FULL_HEX);
19520 printf (" ");
19521 print_vma (file_ofs, FULL_HEX);
19522 printf ("\n %s\n", filenames);
19523
19524 filenames += 1 + strlen ((char *) filenames);
19525 }
19526
015dc7e1 19527 return true;
9ece1fa9
TT
19528}
19529
1118d252
RM
19530static const char *
19531get_gnu_elf_note_type (unsigned e_type)
19532{
1449284b 19533 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19534 switch (e_type)
19535 {
19536 case NT_GNU_ABI_TAG:
19537 return _("NT_GNU_ABI_TAG (ABI version tag)");
19538 case NT_GNU_HWCAP:
19539 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19540 case NT_GNU_BUILD_ID:
19541 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19542 case NT_GNU_GOLD_VERSION:
19543 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19544 case NT_GNU_PROPERTY_TYPE_0:
19545 return _("NT_GNU_PROPERTY_TYPE_0");
19546 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19547 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19548 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19549 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19550 default:
1449284b
NC
19551 {
19552 static char buff[64];
1118d252 19553
1449284b
NC
19554 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19555 return buff;
19556 }
19557 }
1118d252
RM
19558}
19559
a9eafb08
L
19560static void
19561decode_x86_compat_isa (unsigned int bitmask)
19562{
19563 while (bitmask)
19564 {
19565 unsigned int bit = bitmask & (- bitmask);
19566
19567 bitmask &= ~ bit;
19568 switch (bit)
19569 {
19570 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19571 printf ("i486");
19572 break;
19573 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19574 printf ("586");
19575 break;
19576 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19577 printf ("686");
19578 break;
19579 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19580 printf ("SSE");
19581 break;
19582 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19583 printf ("SSE2");
19584 break;
19585 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19586 printf ("SSE3");
19587 break;
19588 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19589 printf ("SSSE3");
19590 break;
19591 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19592 printf ("SSE4_1");
19593 break;
19594 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19595 printf ("SSE4_2");
19596 break;
19597 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19598 printf ("AVX");
19599 break;
19600 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19601 printf ("AVX2");
19602 break;
19603 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19604 printf ("AVX512F");
19605 break;
19606 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19607 printf ("AVX512CD");
19608 break;
19609 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19610 printf ("AVX512ER");
19611 break;
19612 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19613 printf ("AVX512PF");
19614 break;
19615 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19616 printf ("AVX512VL");
19617 break;
19618 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19619 printf ("AVX512DQ");
19620 break;
19621 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19622 printf ("AVX512BW");
19623 break;
65b3d26e
L
19624 default:
19625 printf (_("<unknown: %x>"), bit);
19626 break;
a9eafb08
L
19627 }
19628 if (bitmask)
19629 printf (", ");
19630 }
19631}
19632
9ef920e9 19633static void
32930e4e 19634decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19635{
0a59decb 19636 if (!bitmask)
90c745dc
L
19637 {
19638 printf (_("<None>"));
19639 return;
19640 }
90c745dc 19641
9ef920e9
NC
19642 while (bitmask)
19643 {
1fc87489 19644 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19645
19646 bitmask &= ~ bit;
19647 switch (bit)
19648 {
32930e4e 19649 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19650 printf ("CMOV");
19651 break;
32930e4e 19652 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19653 printf ("SSE");
19654 break;
32930e4e 19655 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19656 printf ("SSE2");
19657 break;
32930e4e 19658 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19659 printf ("SSE3");
19660 break;
32930e4e 19661 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19662 printf ("SSSE3");
19663 break;
32930e4e 19664 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19665 printf ("SSE4_1");
19666 break;
32930e4e 19667 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19668 printf ("SSE4_2");
19669 break;
32930e4e 19670 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19671 printf ("AVX");
19672 break;
32930e4e 19673 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19674 printf ("AVX2");
19675 break;
32930e4e 19676 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19677 printf ("FMA");
19678 break;
32930e4e 19679 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19680 printf ("AVX512F");
19681 break;
32930e4e 19682 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19683 printf ("AVX512CD");
19684 break;
32930e4e 19685 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19686 printf ("AVX512ER");
19687 break;
32930e4e 19688 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19689 printf ("AVX512PF");
19690 break;
32930e4e 19691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19692 printf ("AVX512VL");
19693 break;
32930e4e 19694 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19695 printf ("AVX512DQ");
19696 break;
32930e4e 19697 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19698 printf ("AVX512BW");
19699 break;
32930e4e 19700 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19701 printf ("AVX512_4FMAPS");
19702 break;
32930e4e 19703 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19704 printf ("AVX512_4VNNIW");
19705 break;
32930e4e 19706 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19707 printf ("AVX512_BITALG");
19708 break;
32930e4e 19709 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19710 printf ("AVX512_IFMA");
19711 break;
32930e4e 19712 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19713 printf ("AVX512_VBMI");
19714 break;
32930e4e 19715 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19716 printf ("AVX512_VBMI2");
19717 break;
32930e4e 19718 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19719 printf ("AVX512_VNNI");
19720 break;
32930e4e 19721 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19722 printf ("AVX512_BF16");
19723 break;
65b3d26e
L
19724 default:
19725 printf (_("<unknown: %x>"), bit);
19726 break;
9ef920e9
NC
19727 }
19728 if (bitmask)
19729 printf (", ");
19730 }
19731}
19732
28cdbb18
SM
19733static const char *
19734get_amdgpu_elf_note_type (unsigned int e_type)
19735{
19736 switch (e_type)
19737 {
19738 case NT_AMDGPU_METADATA:
19739 return _("NT_AMDGPU_METADATA (code object metadata)");
19740 default:
19741 {
19742 static char buf[64];
19743 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19744 return buf;
19745 }
19746 }
19747}
19748
32930e4e
L
19749static void
19750decode_x86_isa (unsigned int bitmask)
19751{
32930e4e
L
19752 while (bitmask)
19753 {
19754 unsigned int bit = bitmask & (- bitmask);
19755
19756 bitmask &= ~ bit;
19757 switch (bit)
19758 {
b0ab0693
L
19759 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19760 printf ("x86-64-baseline");
19761 break;
32930e4e
L
19762 case GNU_PROPERTY_X86_ISA_1_V2:
19763 printf ("x86-64-v2");
19764 break;
19765 case GNU_PROPERTY_X86_ISA_1_V3:
19766 printf ("x86-64-v3");
19767 break;
19768 case GNU_PROPERTY_X86_ISA_1_V4:
19769 printf ("x86-64-v4");
19770 break;
19771 default:
19772 printf (_("<unknown: %x>"), bit);
19773 break;
19774 }
19775 if (bitmask)
19776 printf (", ");
19777 }
19778}
19779
ee2fdd6f 19780static void
a9eafb08 19781decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19782{
0a59decb 19783 if (!bitmask)
90c745dc
L
19784 {
19785 printf (_("<None>"));
19786 return;
19787 }
90c745dc 19788
ee2fdd6f
L
19789 while (bitmask)
19790 {
19791 unsigned int bit = bitmask & (- bitmask);
19792
19793 bitmask &= ~ bit;
19794 switch (bit)
19795 {
19796 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19797 printf ("IBT");
ee2fdd6f 19798 break;
48580982 19799 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19800 printf ("SHSTK");
48580982 19801 break;
279d901e
L
19802 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19803 printf ("LAM_U48");
19804 break;
19805 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19806 printf ("LAM_U57");
19807 break;
ee2fdd6f
L
19808 default:
19809 printf (_("<unknown: %x>"), bit);
19810 break;
19811 }
19812 if (bitmask)
19813 printf (", ");
19814 }
19815}
19816
a9eafb08
L
19817static void
19818decode_x86_feature_2 (unsigned int bitmask)
19819{
0a59decb 19820 if (!bitmask)
90c745dc
L
19821 {
19822 printf (_("<None>"));
19823 return;
19824 }
90c745dc 19825
a9eafb08
L
19826 while (bitmask)
19827 {
19828 unsigned int bit = bitmask & (- bitmask);
19829
19830 bitmask &= ~ bit;
19831 switch (bit)
19832 {
19833 case GNU_PROPERTY_X86_FEATURE_2_X86:
19834 printf ("x86");
19835 break;
19836 case GNU_PROPERTY_X86_FEATURE_2_X87:
19837 printf ("x87");
19838 break;
19839 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19840 printf ("MMX");
19841 break;
19842 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19843 printf ("XMM");
19844 break;
19845 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19846 printf ("YMM");
19847 break;
19848 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19849 printf ("ZMM");
19850 break;
a308b89d
L
19851 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19852 printf ("TMM");
19853 break;
32930e4e
L
19854 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19855 printf ("MASK");
19856 break;
a9eafb08
L
19857 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19858 printf ("FXSR");
19859 break;
19860 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19861 printf ("XSAVE");
19862 break;
19863 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19864 printf ("XSAVEOPT");
19865 break;
19866 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19867 printf ("XSAVEC");
19868 break;
65b3d26e
L
19869 default:
19870 printf (_("<unknown: %x>"), bit);
19871 break;
a9eafb08
L
19872 }
19873 if (bitmask)
19874 printf (", ");
19875 }
19876}
19877
cd702818
SD
19878static void
19879decode_aarch64_feature_1_and (unsigned int bitmask)
19880{
19881 while (bitmask)
19882 {
19883 unsigned int bit = bitmask & (- bitmask);
19884
19885 bitmask &= ~ bit;
19886 switch (bit)
19887 {
19888 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19889 printf ("BTI");
19890 break;
19891
19892 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19893 printf ("PAC");
19894 break;
19895
19896 default:
19897 printf (_("<unknown: %x>"), bit);
19898 break;
19899 }
19900 if (bitmask)
19901 printf (", ");
19902 }
19903}
19904
6320fd00
L
19905static void
19906decode_1_needed (unsigned int bitmask)
19907{
19908 while (bitmask)
19909 {
19910 unsigned int bit = bitmask & (- bitmask);
19911
19912 bitmask &= ~ bit;
19913 switch (bit)
19914 {
19915 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19916 printf ("indirect external access");
19917 break;
19918 default:
19919 printf (_("<unknown: %x>"), bit);
19920 break;
19921 }
19922 if (bitmask)
19923 printf (", ");
19924 }
19925}
19926
9ef920e9 19927static void
dda8d76d 19928print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19929{
19930 unsigned char * ptr = (unsigned char *) pnote->descdata;
19931 unsigned char * ptr_end = ptr + pnote->descsz;
19932 unsigned int size = is_32bit_elf ? 4 : 8;
19933
19934 printf (_(" Properties: "));
19935
1fc87489 19936 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19937 {
19938 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19939 return;
19940 }
19941
6ab2c4ed 19942 while (ptr < ptr_end)
9ef920e9 19943 {
1fc87489 19944 unsigned int j;
6ab2c4ed
MC
19945 unsigned int type;
19946 unsigned int datasz;
19947
19948 if ((size_t) (ptr_end - ptr) < 8)
19949 {
19950 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19951 break;
19952 }
19953
19954 type = byte_get (ptr, 4);
19955 datasz = byte_get (ptr + 4, 4);
9ef920e9 19956
1fc87489 19957 ptr += 8;
9ef920e9 19958
6ab2c4ed 19959 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19960 {
1fc87489
L
19961 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19962 type, datasz);
9ef920e9 19963 break;
1fc87489 19964 }
9ef920e9 19965
1fc87489
L
19966 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19967 {
dda8d76d
NC
19968 if (filedata->file_header.e_machine == EM_X86_64
19969 || filedata->file_header.e_machine == EM_IAMCU
19970 || filedata->file_header.e_machine == EM_386)
1fc87489 19971 {
aa7bca9b
L
19972 unsigned int bitmask;
19973
19974 if (datasz == 4)
0a59decb 19975 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19976 else
19977 bitmask = 0;
19978
1fc87489
L
19979 switch (type)
19980 {
19981 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19982 if (datasz != 4)
aa7bca9b
L
19983 printf (_("x86 ISA used: <corrupt length: %#x> "),
19984 datasz);
1fc87489 19985 else
aa7bca9b
L
19986 {
19987 printf ("x86 ISA used: ");
19988 decode_x86_isa (bitmask);
19989 }
1fc87489 19990 goto next;
9ef920e9 19991
1fc87489 19992 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19993 if (datasz != 4)
aa7bca9b
L
19994 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19995 datasz);
1fc87489 19996 else
aa7bca9b
L
19997 {
19998 printf ("x86 ISA needed: ");
19999 decode_x86_isa (bitmask);
20000 }
1fc87489 20001 goto next;
9ef920e9 20002
ee2fdd6f 20003 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20004 if (datasz != 4)
aa7bca9b
L
20005 printf (_("x86 feature: <corrupt length: %#x> "),
20006 datasz);
ee2fdd6f 20007 else
aa7bca9b
L
20008 {
20009 printf ("x86 feature: ");
a9eafb08
L
20010 decode_x86_feature_1 (bitmask);
20011 }
20012 goto next;
20013
20014 case GNU_PROPERTY_X86_FEATURE_2_USED:
20015 if (datasz != 4)
20016 printf (_("x86 feature used: <corrupt length: %#x> "),
20017 datasz);
20018 else
20019 {
20020 printf ("x86 feature used: ");
20021 decode_x86_feature_2 (bitmask);
20022 }
20023 goto next;
20024
20025 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20026 if (datasz != 4)
20027 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20028 else
20029 {
20030 printf ("x86 feature needed: ");
20031 decode_x86_feature_2 (bitmask);
20032 }
20033 goto next;
20034
20035 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20036 if (datasz != 4)
20037 printf (_("x86 ISA used: <corrupt length: %#x> "),
20038 datasz);
20039 else
20040 {
20041 printf ("x86 ISA used: ");
20042 decode_x86_compat_isa (bitmask);
20043 }
20044 goto next;
20045
20046 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20047 if (datasz != 4)
20048 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20049 datasz);
20050 else
20051 {
20052 printf ("x86 ISA needed: ");
20053 decode_x86_compat_isa (bitmask);
aa7bca9b 20054 }
ee2fdd6f
L
20055 goto next;
20056
32930e4e
L
20057 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20058 if (datasz != 4)
20059 printf (_("x86 ISA used: <corrupt length: %#x> "),
20060 datasz);
20061 else
20062 {
20063 printf ("x86 ISA used: ");
20064 decode_x86_compat_2_isa (bitmask);
20065 }
20066 goto next;
20067
20068 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20069 if (datasz != 4)
20070 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20071 datasz);
20072 else
20073 {
20074 printf ("x86 ISA needed: ");
20075 decode_x86_compat_2_isa (bitmask);
20076 }
20077 goto next;
20078
1fc87489
L
20079 default:
20080 break;
20081 }
20082 }
cd702818
SD
20083 else if (filedata->file_header.e_machine == EM_AARCH64)
20084 {
20085 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20086 {
20087 printf ("AArch64 feature: ");
20088 if (datasz != 4)
20089 printf (_("<corrupt length: %#x> "), datasz);
20090 else
20091 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20092 goto next;
20093 }
20094 }
1fc87489
L
20095 }
20096 else
20097 {
20098 switch (type)
9ef920e9 20099 {
1fc87489
L
20100 case GNU_PROPERTY_STACK_SIZE:
20101 printf (_("stack size: "));
20102 if (datasz != size)
20103 printf (_("<corrupt length: %#x> "), datasz);
20104 else
20105 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20106 goto next;
20107
20108 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20109 printf ("no copy on protected ");
20110 if (datasz)
20111 printf (_("<corrupt length: %#x> "), datasz);
20112 goto next;
20113
20114 default:
5a767724
L
20115 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20116 && type <= GNU_PROPERTY_UINT32_AND_HI)
20117 || (type >= GNU_PROPERTY_UINT32_OR_LO
20118 && type <= GNU_PROPERTY_UINT32_OR_HI))
20119 {
6320fd00
L
20120 switch (type)
20121 {
20122 case GNU_PROPERTY_1_NEEDED:
20123 if (datasz != 4)
20124 printf (_("1_needed: <corrupt length: %#x> "),
20125 datasz);
20126 else
20127 {
20128 unsigned int bitmask = byte_get (ptr, 4);
20129 printf ("1_needed: ");
20130 decode_1_needed (bitmask);
20131 }
20132 goto next;
20133
20134 default:
20135 break;
20136 }
5a767724
L
20137 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20138 printf (_("UINT32_AND (%#x): "), type);
20139 else
20140 printf (_("UINT32_OR (%#x): "), type);
20141 if (datasz != 4)
20142 printf (_("<corrupt length: %#x> "), datasz);
20143 else
20144 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20145 goto next;
20146 }
9ef920e9
NC
20147 break;
20148 }
9ef920e9
NC
20149 }
20150
1fc87489
L
20151 if (type < GNU_PROPERTY_LOPROC)
20152 printf (_("<unknown type %#x data: "), type);
20153 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20154 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20155 else
20156 printf (_("<application-specific type %#x data: "), type);
20157 for (j = 0; j < datasz; ++j)
20158 printf ("%02x ", ptr[j] & 0xff);
20159 printf (">");
20160
dc1e8a47 20161 next:
9ef920e9 20162 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20163 if (ptr == ptr_end)
20164 break;
1fc87489 20165
6ab2c4ed
MC
20166 if (do_wide)
20167 printf (", ");
20168 else
20169 printf ("\n\t");
9ef920e9
NC
20170 }
20171
20172 printf ("\n");
20173}
20174
015dc7e1 20175static bool
dda8d76d 20176print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20177{
1449284b 20178 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20179 switch (pnote->type)
20180 {
20181 case NT_GNU_BUILD_ID:
20182 {
20183 unsigned long i;
20184
20185 printf (_(" Build ID: "));
20186 for (i = 0; i < pnote->descsz; ++i)
20187 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20188 printf ("\n");
664f90a3
TT
20189 }
20190 break;
20191
20192 case NT_GNU_ABI_TAG:
20193 {
20194 unsigned long os, major, minor, subminor;
20195 const char *osname;
20196
3102e897
NC
20197 /* PR 17531: file: 030-599401-0.004. */
20198 if (pnote->descsz < 16)
20199 {
20200 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20201 break;
20202 }
20203
664f90a3
TT
20204 os = byte_get ((unsigned char *) pnote->descdata, 4);
20205 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20206 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20207 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20208
20209 switch (os)
20210 {
20211 case GNU_ABI_TAG_LINUX:
20212 osname = "Linux";
20213 break;
20214 case GNU_ABI_TAG_HURD:
20215 osname = "Hurd";
20216 break;
20217 case GNU_ABI_TAG_SOLARIS:
20218 osname = "Solaris";
20219 break;
20220 case GNU_ABI_TAG_FREEBSD:
20221 osname = "FreeBSD";
20222 break;
20223 case GNU_ABI_TAG_NETBSD:
20224 osname = "NetBSD";
20225 break;
14ae95f2
RM
20226 case GNU_ABI_TAG_SYLLABLE:
20227 osname = "Syllable";
20228 break;
20229 case GNU_ABI_TAG_NACL:
20230 osname = "NaCl";
20231 break;
664f90a3
TT
20232 default:
20233 osname = "Unknown";
20234 break;
20235 }
20236
20237 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20238 major, minor, subminor);
20239 }
20240 break;
926c5385
CC
20241
20242 case NT_GNU_GOLD_VERSION:
20243 {
20244 unsigned long i;
20245
20246 printf (_(" Version: "));
20247 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20248 printf ("%c", pnote->descdata[i]);
20249 printf ("\n");
20250 }
20251 break;
1449284b
NC
20252
20253 case NT_GNU_HWCAP:
20254 {
20255 unsigned long num_entries, mask;
20256
20257 /* Hardware capabilities information. Word 0 is the number of entries.
20258 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20259 is a series of entries, where each entry is a single byte followed
20260 by a nul terminated string. The byte gives the bit number to test
20261 if enabled in the bitmask. */
20262 printf (_(" Hardware Capabilities: "));
20263 if (pnote->descsz < 8)
20264 {
32ec8896 20265 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20266 return false;
1449284b
NC
20267 }
20268 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20269 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20270 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20271 /* FIXME: Add code to display the entries... */
20272 }
20273 break;
20274
9ef920e9 20275 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20276 print_gnu_property_note (filedata, pnote);
9ef920e9 20277 break;
9abca702 20278
1449284b
NC
20279 default:
20280 /* Handle unrecognised types. An error message should have already been
20281 created by get_gnu_elf_note_type(), so all that we need to do is to
20282 display the data. */
20283 {
20284 unsigned long i;
20285
20286 printf (_(" Description data: "));
20287 for (i = 0; i < pnote->descsz; ++i)
20288 printf ("%02x ", pnote->descdata[i] & 0xff);
20289 printf ("\n");
20290 }
20291 break;
664f90a3
TT
20292 }
20293
015dc7e1 20294 return true;
664f90a3
TT
20295}
20296
685080f2
NC
20297static const char *
20298get_v850_elf_note_type (enum v850_notes n_type)
20299{
20300 static char buff[64];
20301
20302 switch (n_type)
20303 {
20304 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20305 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20306 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20307 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20308 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20309 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20310 default:
20311 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20312 return buff;
20313 }
20314}
20315
015dc7e1 20316static bool
685080f2
NC
20317print_v850_note (Elf_Internal_Note * pnote)
20318{
20319 unsigned int val;
20320
20321 if (pnote->descsz != 4)
015dc7e1 20322 return false;
32ec8896 20323
685080f2
NC
20324 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20325
20326 if (val == 0)
20327 {
20328 printf (_("not set\n"));
015dc7e1 20329 return true;
685080f2
NC
20330 }
20331
20332 switch (pnote->type)
20333 {
20334 case V850_NOTE_ALIGNMENT:
20335 switch (val)
20336 {
015dc7e1
AM
20337 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20338 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20339 }
20340 break;
14ae95f2 20341
685080f2
NC
20342 case V850_NOTE_DATA_SIZE:
20343 switch (val)
20344 {
015dc7e1
AM
20345 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20346 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20347 }
20348 break;
14ae95f2 20349
685080f2
NC
20350 case V850_NOTE_FPU_INFO:
20351 switch (val)
20352 {
015dc7e1
AM
20353 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20354 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20355 }
20356 break;
14ae95f2 20357
685080f2
NC
20358 case V850_NOTE_MMU_INFO:
20359 case V850_NOTE_CACHE_INFO:
20360 case V850_NOTE_SIMD_INFO:
20361 if (val == EF_RH850_SIMD)
20362 {
20363 printf (_("yes\n"));
015dc7e1 20364 return true;
685080f2
NC
20365 }
20366 break;
20367
20368 default:
20369 /* An 'unknown note type' message will already have been displayed. */
20370 break;
20371 }
20372
20373 printf (_("unknown value: %x\n"), val);
015dc7e1 20374 return false;
685080f2
NC
20375}
20376
015dc7e1 20377static bool
c6056a74
SF
20378process_netbsd_elf_note (Elf_Internal_Note * pnote)
20379{
20380 unsigned int version;
20381
20382 switch (pnote->type)
20383 {
20384 case NT_NETBSD_IDENT:
b966f55f
AM
20385 if (pnote->descsz < 1)
20386 break;
c6056a74
SF
20387 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20388 if ((version / 10000) % 100)
b966f55f 20389 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20390 version, version / 100000000, (version / 1000000) % 100,
20391 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20392 'A' + (version / 10000) % 26);
c6056a74
SF
20393 else
20394 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20395 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20396 (version / 100) % 100);
015dc7e1 20397 return true;
c6056a74
SF
20398
20399 case NT_NETBSD_MARCH:
9abca702 20400 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20401 pnote->descdata);
015dc7e1 20402 return true;
c6056a74 20403
9abca702 20404 case NT_NETBSD_PAX:
b966f55f
AM
20405 if (pnote->descsz < 1)
20406 break;
9abca702
CZ
20407 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20408 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20409 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20410 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20411 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20412 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20413 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20414 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20415 return true;
c6056a74 20416 }
b966f55f
AM
20417
20418 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20419 pnote->descsz, pnote->type);
015dc7e1 20420 return false;
c6056a74
SF
20421}
20422
f4ddf30f 20423static const char *
dda8d76d 20424get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20425{
f4ddf30f
JB
20426 switch (e_type)
20427 {
20428 case NT_FREEBSD_THRMISC:
20429 return _("NT_THRMISC (thrmisc structure)");
20430 case NT_FREEBSD_PROCSTAT_PROC:
20431 return _("NT_PROCSTAT_PROC (proc data)");
20432 case NT_FREEBSD_PROCSTAT_FILES:
20433 return _("NT_PROCSTAT_FILES (files data)");
20434 case NT_FREEBSD_PROCSTAT_VMMAP:
20435 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20436 case NT_FREEBSD_PROCSTAT_GROUPS:
20437 return _("NT_PROCSTAT_GROUPS (groups data)");
20438 case NT_FREEBSD_PROCSTAT_UMASK:
20439 return _("NT_PROCSTAT_UMASK (umask data)");
20440 case NT_FREEBSD_PROCSTAT_RLIMIT:
20441 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20442 case NT_FREEBSD_PROCSTAT_OSREL:
20443 return _("NT_PROCSTAT_OSREL (osreldate data)");
20444 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20445 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20446 case NT_FREEBSD_PROCSTAT_AUXV:
20447 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20448 case NT_FREEBSD_PTLWPINFO:
20449 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20450 case NT_FREEBSD_X86_SEGBASES:
20451 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20452 }
dda8d76d 20453 return get_note_type (filedata, e_type);
f4ddf30f
JB
20454}
20455
9437c45b 20456static const char *
dda8d76d 20457get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20458{
20459 static char buff[64];
20460
540e6170
CZ
20461 switch (e_type)
20462 {
20463 case NT_NETBSDCORE_PROCINFO:
20464 /* NetBSD core "procinfo" structure. */
20465 return _("NetBSD procinfo structure");
9437c45b 20466
540e6170
CZ
20467 case NT_NETBSDCORE_AUXV:
20468 return _("NetBSD ELF auxiliary vector data");
9437c45b 20469
06d949ec
KR
20470 case NT_NETBSDCORE_LWPSTATUS:
20471 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20472
540e6170 20473 default:
06d949ec 20474 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20475 defined for NetBSD core files. If the note type is less
20476 than the start of the machine-dependent note types, we don't
20477 understand it. */
20478
20479 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20480 {
20481 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20482 return buff;
20483 }
20484 break;
9437c45b
JT
20485 }
20486
dda8d76d 20487 switch (filedata->file_header.e_machine)
9437c45b
JT
20488 {
20489 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20490 and PT_GETFPREGS == mach+2. */
20491
20492 case EM_OLD_ALPHA:
20493 case EM_ALPHA:
20494 case EM_SPARC:
20495 case EM_SPARC32PLUS:
20496 case EM_SPARCV9:
20497 switch (e_type)
20498 {
2b692964 20499 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20500 return _("PT_GETREGS (reg structure)");
2b692964 20501 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20502 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20503 default:
20504 break;
20505 }
20506 break;
20507
c0d38b0e
CZ
20508 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20509 There's also old PT___GETREGS40 == mach + 1 for old reg
20510 structure which lacks GBR. */
20511 case EM_SH:
20512 switch (e_type)
20513 {
20514 case NT_NETBSDCORE_FIRSTMACH + 1:
20515 return _("PT___GETREGS40 (old reg structure)");
20516 case NT_NETBSDCORE_FIRSTMACH + 3:
20517 return _("PT_GETREGS (reg structure)");
20518 case NT_NETBSDCORE_FIRSTMACH + 5:
20519 return _("PT_GETFPREGS (fpreg structure)");
20520 default:
20521 break;
20522 }
20523 break;
20524
9437c45b
JT
20525 /* On all other arch's, PT_GETREGS == mach+1 and
20526 PT_GETFPREGS == mach+3. */
20527 default:
20528 switch (e_type)
20529 {
2b692964 20530 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20531 return _("PT_GETREGS (reg structure)");
2b692964 20532 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20533 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20534 default:
20535 break;
20536 }
20537 }
20538
9cf03b7e 20539 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20540 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20541 return buff;
20542}
20543
98ca73af
FC
20544static const char *
20545get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20546{
20547 switch (e_type)
20548 {
20549 case NT_OPENBSD_PROCINFO:
20550 return _("OpenBSD procinfo structure");
20551 case NT_OPENBSD_AUXV:
20552 return _("OpenBSD ELF auxiliary vector data");
20553 case NT_OPENBSD_REGS:
20554 return _("OpenBSD regular registers");
20555 case NT_OPENBSD_FPREGS:
20556 return _("OpenBSD floating point registers");
20557 case NT_OPENBSD_WCOOKIE:
20558 return _("OpenBSD window cookie");
20559 }
20560
20561 return get_note_type (filedata, e_type);
20562}
20563
70616151
TT
20564static const char *
20565get_stapsdt_note_type (unsigned e_type)
20566{
20567 static char buff[64];
20568
20569 switch (e_type)
20570 {
20571 case NT_STAPSDT:
20572 return _("NT_STAPSDT (SystemTap probe descriptors)");
20573
20574 default:
20575 break;
20576 }
20577
20578 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20579 return buff;
20580}
20581
015dc7e1 20582static bool
c6a9fc58
TT
20583print_stapsdt_note (Elf_Internal_Note *pnote)
20584{
3ca60c57
NC
20585 size_t len, maxlen;
20586 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20587 char *data = pnote->descdata;
20588 char *data_end = pnote->descdata + pnote->descsz;
20589 bfd_vma pc, base_addr, semaphore;
20590 char *provider, *probe, *arg_fmt;
20591
3ca60c57
NC
20592 if (pnote->descsz < (addr_size * 3))
20593 goto stapdt_note_too_small;
20594
c6a9fc58
TT
20595 pc = byte_get ((unsigned char *) data, addr_size);
20596 data += addr_size;
3ca60c57 20597
c6a9fc58
TT
20598 base_addr = byte_get ((unsigned char *) data, addr_size);
20599 data += addr_size;
3ca60c57 20600
c6a9fc58
TT
20601 semaphore = byte_get ((unsigned char *) data, addr_size);
20602 data += addr_size;
20603
3ca60c57
NC
20604 if (data >= data_end)
20605 goto stapdt_note_too_small;
20606 maxlen = data_end - data;
20607 len = strnlen (data, maxlen);
20608 if (len < maxlen)
20609 {
20610 provider = data;
20611 data += len + 1;
20612 }
20613 else
20614 goto stapdt_note_too_small;
20615
20616 if (data >= data_end)
20617 goto stapdt_note_too_small;
20618 maxlen = data_end - data;
20619 len = strnlen (data, maxlen);
20620 if (len < maxlen)
20621 {
20622 probe = data;
20623 data += len + 1;
20624 }
20625 else
20626 goto stapdt_note_too_small;
9abca702 20627
3ca60c57
NC
20628 if (data >= data_end)
20629 goto stapdt_note_too_small;
20630 maxlen = data_end - data;
20631 len = strnlen (data, maxlen);
20632 if (len < maxlen)
20633 {
20634 arg_fmt = data;
20635 data += len + 1;
20636 }
20637 else
20638 goto stapdt_note_too_small;
c6a9fc58
TT
20639
20640 printf (_(" Provider: %s\n"), provider);
20641 printf (_(" Name: %s\n"), probe);
20642 printf (_(" Location: "));
20643 print_vma (pc, FULL_HEX);
20644 printf (_(", Base: "));
20645 print_vma (base_addr, FULL_HEX);
20646 printf (_(", Semaphore: "));
20647 print_vma (semaphore, FULL_HEX);
9cf03b7e 20648 printf ("\n");
c6a9fc58
TT
20649 printf (_(" Arguments: %s\n"), arg_fmt);
20650
20651 return data == data_end;
3ca60c57
NC
20652
20653 stapdt_note_too_small:
20654 printf (_(" <corrupt - note is too small>\n"));
20655 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20656 return false;
c6a9fc58
TT
20657}
20658
e5382207
LB
20659static bool
20660print_fdo_note (Elf_Internal_Note * pnote)
20661{
20662 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20663 {
20664 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20665 return true;
20666 }
20667 return false;
20668}
20669
00e98fc7
TG
20670static const char *
20671get_ia64_vms_note_type (unsigned e_type)
20672{
20673 static char buff[64];
20674
20675 switch (e_type)
20676 {
20677 case NT_VMS_MHD:
20678 return _("NT_VMS_MHD (module header)");
20679 case NT_VMS_LNM:
20680 return _("NT_VMS_LNM (language name)");
20681 case NT_VMS_SRC:
20682 return _("NT_VMS_SRC (source files)");
20683 case NT_VMS_TITLE:
9cf03b7e 20684 return "NT_VMS_TITLE";
00e98fc7
TG
20685 case NT_VMS_EIDC:
20686 return _("NT_VMS_EIDC (consistency check)");
20687 case NT_VMS_FPMODE:
20688 return _("NT_VMS_FPMODE (FP mode)");
20689 case NT_VMS_LINKTIME:
9cf03b7e 20690 return "NT_VMS_LINKTIME";
00e98fc7
TG
20691 case NT_VMS_IMGNAM:
20692 return _("NT_VMS_IMGNAM (image name)");
20693 case NT_VMS_IMGID:
20694 return _("NT_VMS_IMGID (image id)");
20695 case NT_VMS_LINKID:
20696 return _("NT_VMS_LINKID (link id)");
20697 case NT_VMS_IMGBID:
20698 return _("NT_VMS_IMGBID (build id)");
20699 case NT_VMS_GSTNAM:
20700 return _("NT_VMS_GSTNAM (sym table name)");
20701 case NT_VMS_ORIG_DYN:
9cf03b7e 20702 return "NT_VMS_ORIG_DYN";
00e98fc7 20703 case NT_VMS_PATCHTIME:
9cf03b7e 20704 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20705 default:
20706 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20707 return buff;
20708 }
20709}
20710
015dc7e1 20711static bool
00e98fc7
TG
20712print_ia64_vms_note (Elf_Internal_Note * pnote)
20713{
8d18bf79
NC
20714 int maxlen = pnote->descsz;
20715
20716 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20717 goto desc_size_fail;
20718
00e98fc7
TG
20719 switch (pnote->type)
20720 {
20721 case NT_VMS_MHD:
8d18bf79
NC
20722 if (maxlen <= 36)
20723 goto desc_size_fail;
20724
20725 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20726
20727 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20728 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20729 if (l + 34 < maxlen)
20730 {
20731 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20732 if (l + 35 < maxlen)
20733 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20734 else
20735 printf (_(" Module version : <missing>\n"));
20736 }
00e98fc7 20737 else
8d18bf79
NC
20738 {
20739 printf (_(" Module name : <missing>\n"));
20740 printf (_(" Module version : <missing>\n"));
20741 }
00e98fc7 20742 break;
8d18bf79 20743
00e98fc7 20744 case NT_VMS_LNM:
8d18bf79 20745 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20746 break;
8d18bf79 20747
00e98fc7
TG
20748#ifdef BFD64
20749 case NT_VMS_FPMODE:
9cf03b7e 20750 printf (_(" Floating Point mode: "));
8d18bf79
NC
20751 if (maxlen < 8)
20752 goto desc_size_fail;
20753 /* FIXME: Generate an error if descsz > 8 ? */
20754
4a5cb34f 20755 printf ("0x%016" BFD_VMA_FMT "x\n",
0e3c1eeb 20756 (bfd_vma) byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20757 break;
8d18bf79 20758
00e98fc7
TG
20759 case NT_VMS_LINKTIME:
20760 printf (_(" Link time: "));
8d18bf79
NC
20761 if (maxlen < 8)
20762 goto desc_size_fail;
20763 /* FIXME: Generate an error if descsz > 8 ? */
20764
0e3c1eeb 20765 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20766 printf ("\n");
20767 break;
8d18bf79 20768
00e98fc7
TG
20769 case NT_VMS_PATCHTIME:
20770 printf (_(" Patch time: "));
8d18bf79
NC
20771 if (maxlen < 8)
20772 goto desc_size_fail;
20773 /* FIXME: Generate an error if descsz > 8 ? */
20774
0e3c1eeb 20775 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20776 printf ("\n");
20777 break;
8d18bf79 20778
00e98fc7 20779 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20780 if (maxlen < 34)
20781 goto desc_size_fail;
20782
00e98fc7 20783 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20784 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20785 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20786 printf (_(" Last modified : "));
0e3c1eeb 20787 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20788 printf (_("\n Link flags : "));
4a5cb34f 20789 printf ("0x%016" BFD_VMA_FMT "x\n",
0e3c1eeb 20790 (bfd_vma) byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20791 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20792 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20793 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20794 break;
20795#endif
8d18bf79 20796
00e98fc7 20797 case NT_VMS_IMGNAM:
8d18bf79 20798 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20799 break;
8d18bf79 20800
00e98fc7 20801 case NT_VMS_GSTNAM:
8d18bf79 20802 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20803 break;
8d18bf79 20804
00e98fc7 20805 case NT_VMS_IMGID:
8d18bf79 20806 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20807 break;
8d18bf79 20808
00e98fc7 20809 case NT_VMS_LINKID:
8d18bf79 20810 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20811 break;
8d18bf79 20812
00e98fc7 20813 default:
015dc7e1 20814 return false;
00e98fc7 20815 }
8d18bf79 20816
015dc7e1 20817 return true;
8d18bf79
NC
20818
20819 desc_size_fail:
20820 printf (_(" <corrupt - data size is too small>\n"));
20821 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20822 return false;
00e98fc7
TG
20823}
20824
fd486f32
AM
20825struct build_attr_cache {
20826 Filedata *filedata;
20827 char *strtab;
20828 unsigned long strtablen;
20829 Elf_Internal_Sym *symtab;
20830 unsigned long nsyms;
20831} ba_cache;
20832
6f156d7a
NC
20833/* Find the symbol associated with a build attribute that is attached
20834 to address OFFSET. If PNAME is non-NULL then store the name of
20835 the symbol (if found) in the provided pointer, Returns NULL if a
20836 symbol could not be found. */
c799a79d 20837
6f156d7a 20838static Elf_Internal_Sym *
015dc7e1
AM
20839get_symbol_for_build_attribute (Filedata *filedata,
20840 unsigned long offset,
20841 bool is_open_attr,
20842 const char **pname)
9ef920e9 20843{
fd486f32
AM
20844 Elf_Internal_Sym *saved_sym = NULL;
20845 Elf_Internal_Sym *sym;
9ef920e9 20846
dda8d76d 20847 if (filedata->section_headers != NULL
fd486f32 20848 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20849 {
c799a79d 20850 Elf_Internal_Shdr * symsec;
9ef920e9 20851
fd486f32
AM
20852 free (ba_cache.strtab);
20853 ba_cache.strtab = NULL;
20854 free (ba_cache.symtab);
20855 ba_cache.symtab = NULL;
20856
c799a79d 20857 /* Load the symbol and string sections. */
dda8d76d
NC
20858 for (symsec = filedata->section_headers;
20859 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20860 symsec ++)
9ef920e9 20861 {
28d13567
AM
20862 if (symsec->sh_type == SHT_SYMTAB
20863 && get_symtab (filedata, symsec,
20864 &ba_cache.symtab, &ba_cache.nsyms,
20865 &ba_cache.strtab, &ba_cache.strtablen))
20866 break;
9ef920e9 20867 }
fd486f32 20868 ba_cache.filedata = filedata;
9ef920e9
NC
20869 }
20870
fd486f32 20871 if (ba_cache.symtab == NULL)
6f156d7a 20872 return NULL;
9ef920e9 20873
c799a79d 20874 /* Find a symbol whose value matches offset. */
fd486f32 20875 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20876 if (sym->st_value == offset)
20877 {
fd486f32 20878 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20879 /* Huh ? This should not happen. */
20880 continue;
9ef920e9 20881
fd486f32 20882 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20883 continue;
9ef920e9 20884
9b9b1092 20885 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20886 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20887 if (ba_cache.strtab[sym->st_name] == '$'
20888 && ba_cache.strtab[sym->st_name + 1] != 0
20889 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20890 continue;
20891
c799a79d
NC
20892 if (is_open_attr)
20893 {
20894 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20895 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20896 FUNC symbols entirely. */
20897 switch (ELF_ST_TYPE (sym->st_info))
20898 {
c799a79d 20899 case STT_OBJECT:
6f156d7a 20900 case STT_FILE:
c799a79d 20901 saved_sym = sym;
6f156d7a
NC
20902 if (sym->st_size)
20903 {
20904 /* If the symbol has a size associated
20905 with it then we can stop searching. */
fd486f32 20906 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20907 }
c799a79d 20908 continue;
9ef920e9 20909
c799a79d
NC
20910 case STT_FUNC:
20911 /* Ignore function symbols. */
20912 continue;
20913
20914 default:
20915 break;
20916 }
20917
20918 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20919 {
c799a79d
NC
20920 case STB_GLOBAL:
20921 if (saved_sym == NULL
20922 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20923 saved_sym = sym;
20924 break;
c871dade 20925
c799a79d
NC
20926 case STB_LOCAL:
20927 if (saved_sym == NULL)
20928 saved_sym = sym;
20929 break;
20930
20931 default:
9ef920e9
NC
20932 break;
20933 }
20934 }
c799a79d
NC
20935 else
20936 {
20937 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20938 continue;
20939
20940 saved_sym = sym;
20941 break;
20942 }
20943 }
20944
6f156d7a 20945 if (saved_sym && pname)
fd486f32 20946 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20947
20948 return saved_sym;
c799a79d
NC
20949}
20950
d20e98ab
NC
20951/* Returns true iff addr1 and addr2 are in the same section. */
20952
015dc7e1 20953static bool
d20e98ab
NC
20954same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20955{
20956 Elf_Internal_Shdr * a1;
20957 Elf_Internal_Shdr * a2;
20958
20959 a1 = find_section_by_address (filedata, addr1);
20960 a2 = find_section_by_address (filedata, addr2);
9abca702 20961
d20e98ab
NC
20962 return a1 == a2 && a1 != NULL;
20963}
20964
015dc7e1 20965static bool
dda8d76d
NC
20966print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20967 Filedata * filedata)
c799a79d 20968{
015dc7e1
AM
20969 static unsigned long global_offset = 0;
20970 static unsigned long global_end = 0;
20971 static unsigned long func_offset = 0;
20972 static unsigned long func_end = 0;
c871dade 20973
015dc7e1
AM
20974 Elf_Internal_Sym *sym;
20975 const char *name;
20976 unsigned long start;
20977 unsigned long end;
20978 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20979
20980 switch (pnote->descsz)
c799a79d 20981 {
6f156d7a
NC
20982 case 0:
20983 /* A zero-length description means that the range of
20984 the previous note of the same type should be used. */
c799a79d 20985 if (is_open_attr)
c871dade 20986 {
6f156d7a
NC
20987 if (global_end > global_offset)
20988 printf (_(" Applies to region from %#lx to %#lx\n"),
20989 global_offset, global_end);
20990 else
20991 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20992 }
20993 else
20994 {
6f156d7a
NC
20995 if (func_end > func_offset)
20996 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20997 else
20998 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20999 }
015dc7e1 21000 return true;
9ef920e9 21001
6f156d7a
NC
21002 case 4:
21003 start = byte_get ((unsigned char *) pnote->descdata, 4);
21004 end = 0;
21005 break;
21006
21007 case 8:
c74147bb
NC
21008 start = byte_get ((unsigned char *) pnote->descdata, 4);
21009 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21010 break;
21011
21012 case 16:
21013 start = byte_get ((unsigned char *) pnote->descdata, 8);
21014 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21015 break;
9abca702 21016
6f156d7a 21017 default:
c799a79d
NC
21018 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21019 printf (_(" <invalid descsz>"));
015dc7e1 21020 return false;
c799a79d
NC
21021 }
21022
6f156d7a
NC
21023 name = NULL;
21024 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21025 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21026 in order to avoid them being confused with the start address of the
21027 first function in the file... */
21028 if (sym == NULL && is_open_attr)
21029 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21030 & name);
6f156d7a
NC
21031
21032 if (end == 0 && sym != NULL && sym->st_size > 0)
21033 end = start + sym->st_size;
c799a79d
NC
21034
21035 if (is_open_attr)
21036 {
d20e98ab
NC
21037 /* FIXME: Need to properly allow for section alignment.
21038 16 is just the alignment used on x86_64. */
21039 if (global_end > 0
21040 && start > BFD_ALIGN (global_end, 16)
21041 /* Build notes are not guaranteed to be organised in order of
21042 increasing address, but we should find the all of the notes
21043 for one section in the same place. */
21044 && same_section (filedata, start, global_end))
6f156d7a
NC
21045 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21046 global_end + 1, start - 1);
21047
21048 printf (_(" Applies to region from %#lx"), start);
21049 global_offset = start;
21050
21051 if (end)
21052 {
21053 printf (_(" to %#lx"), end);
21054 global_end = end;
21055 }
c799a79d
NC
21056 }
21057 else
21058 {
6f156d7a
NC
21059 printf (_(" Applies to region from %#lx"), start);
21060 func_offset = start;
21061
21062 if (end)
21063 {
21064 printf (_(" to %#lx"), end);
21065 func_end = end;
21066 }
c799a79d
NC
21067 }
21068
6f156d7a
NC
21069 if (sym && name)
21070 printf (_(" (%s)"), name);
21071
21072 printf ("\n");
015dc7e1 21073 return true;
9ef920e9
NC
21074}
21075
015dc7e1 21076static bool
9ef920e9
NC
21077print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21078{
1d15e434
NC
21079 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21080 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21081 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21082 char name_type;
21083 char name_attribute;
1d15e434 21084 const char * expected_types;
9ef920e9
NC
21085 const char * name = pnote->namedata;
21086 const char * text;
88305e1b 21087 signed int left;
9ef920e9
NC
21088
21089 if (name == NULL || pnote->namesz < 2)
21090 {
21091 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21092 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21093 return false;
9ef920e9
NC
21094 }
21095
6f156d7a
NC
21096 if (do_wide)
21097 left = 28;
21098 else
21099 left = 20;
88305e1b
NC
21100
21101 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21102 if (name[0] == 'G' && name[1] == 'A')
21103 {
6f156d7a
NC
21104 if (pnote->namesz < 4)
21105 {
21106 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21107 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21108 return false;
6f156d7a
NC
21109 }
21110
88305e1b
NC
21111 printf ("GA");
21112 name += 2;
21113 left -= 2;
21114 }
21115
9ef920e9
NC
21116 switch ((name_type = * name))
21117 {
21118 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21119 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21120 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21121 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21122 printf ("%c", * name);
88305e1b 21123 left --;
9ef920e9
NC
21124 break;
21125 default:
21126 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21127 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21128 return false;
9ef920e9
NC
21129 }
21130
9ef920e9
NC
21131 ++ name;
21132 text = NULL;
21133
21134 switch ((name_attribute = * name))
21135 {
21136 case GNU_BUILD_ATTRIBUTE_VERSION:
21137 text = _("<version>");
1d15e434 21138 expected_types = string_expected;
9ef920e9
NC
21139 ++ name;
21140 break;
21141 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21142 text = _("<stack prot>");
75d7d298 21143 expected_types = "!+*";
9ef920e9
NC
21144 ++ name;
21145 break;
21146 case GNU_BUILD_ATTRIBUTE_RELRO:
21147 text = _("<relro>");
1d15e434 21148 expected_types = bool_expected;
9ef920e9
NC
21149 ++ name;
21150 break;
21151 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21152 text = _("<stack size>");
1d15e434 21153 expected_types = number_expected;
9ef920e9
NC
21154 ++ name;
21155 break;
21156 case GNU_BUILD_ATTRIBUTE_TOOL:
21157 text = _("<tool>");
1d15e434 21158 expected_types = string_expected;
9ef920e9
NC
21159 ++ name;
21160 break;
21161 case GNU_BUILD_ATTRIBUTE_ABI:
21162 text = _("<ABI>");
21163 expected_types = "$*";
21164 ++ name;
21165 break;
21166 case GNU_BUILD_ATTRIBUTE_PIC:
21167 text = _("<PIC>");
1d15e434 21168 expected_types = number_expected;
9ef920e9
NC
21169 ++ name;
21170 break;
a8be5506
NC
21171 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21172 text = _("<short enum>");
1d15e434 21173 expected_types = bool_expected;
a8be5506
NC
21174 ++ name;
21175 break;
9ef920e9
NC
21176 default:
21177 if (ISPRINT (* name))
21178 {
21179 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21180
21181 if (len > left && ! do_wide)
21182 len = left;
75d7d298 21183 printf ("%.*s:", len, name);
9ef920e9 21184 left -= len;
0dd6ae21 21185 name += len;
9ef920e9
NC
21186 }
21187 else
21188 {
3e6b6445 21189 static char tmpbuf [128];
88305e1b 21190
3e6b6445
NC
21191 error (_("unrecognised byte in name field: %d\n"), * name);
21192 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21193 text = tmpbuf;
21194 name ++;
9ef920e9
NC
21195 }
21196 expected_types = "*$!+";
21197 break;
21198 }
21199
21200 if (text)
88305e1b 21201 left -= printf ("%s", text);
9ef920e9
NC
21202
21203 if (strchr (expected_types, name_type) == NULL)
75d7d298 21204 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21205
21206 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21207 {
21208 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21209 (unsigned long) pnote->namesz,
21210 (long) (name - pnote->namedata));
015dc7e1 21211 return false;
9ef920e9
NC
21212 }
21213
21214 if (left < 1 && ! do_wide)
015dc7e1 21215 return true;
9ef920e9
NC
21216
21217 switch (name_type)
21218 {
21219 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21220 {
b06b2c92 21221 unsigned int bytes;
ddef72cd
NC
21222 unsigned long long val = 0;
21223 unsigned int shift = 0;
21224 char * decoded = NULL;
21225
b06b2c92
NC
21226 bytes = pnote->namesz - (name - pnote->namedata);
21227 if (bytes > 0)
21228 /* The -1 is because the name field is always 0 terminated, and we
21229 want to be able to ensure that the shift in the while loop below
21230 will not overflow. */
21231 -- bytes;
21232
ddef72cd
NC
21233 if (bytes > sizeof (val))
21234 {
3e6b6445
NC
21235 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21236 bytes);
21237 bytes = sizeof (val);
ddef72cd 21238 }
3e6b6445
NC
21239 /* We do not bother to warn if bytes == 0 as this can
21240 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21241
21242 while (bytes --)
21243 {
54b8331d 21244 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21245
21246 val |= byte << shift;
9ef920e9
NC
21247 shift += 8;
21248 }
21249
75d7d298 21250 switch (name_attribute)
9ef920e9 21251 {
75d7d298 21252 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21253 switch (val)
21254 {
75d7d298
NC
21255 case 0: decoded = "static"; break;
21256 case 1: decoded = "pic"; break;
21257 case 2: decoded = "PIC"; break;
21258 case 3: decoded = "pie"; break;
21259 case 4: decoded = "PIE"; break;
21260 default: break;
9ef920e9 21261 }
75d7d298
NC
21262 break;
21263 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21264 switch (val)
9ef920e9 21265 {
75d7d298
NC
21266 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21267 case 0: decoded = "off"; break;
21268 case 1: decoded = "on"; break;
21269 case 2: decoded = "all"; break;
21270 case 3: decoded = "strong"; break;
21271 case 4: decoded = "explicit"; break;
21272 default: break;
9ef920e9 21273 }
75d7d298
NC
21274 break;
21275 default:
21276 break;
9ef920e9
NC
21277 }
21278
75d7d298 21279 if (decoded != NULL)
3e6b6445
NC
21280 {
21281 print_symbol (-left, decoded);
21282 left = 0;
21283 }
21284 else if (val == 0)
21285 {
21286 printf ("0x0");
21287 left -= 3;
21288 }
9ef920e9 21289 else
75d7d298
NC
21290 {
21291 if (do_wide)
ddef72cd 21292 left -= printf ("0x%llx", val);
75d7d298 21293 else
ddef72cd 21294 left -= printf ("0x%-.*llx", left, val);
75d7d298 21295 }
9ef920e9
NC
21296 }
21297 break;
21298 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21299 left -= print_symbol (- left, name);
21300 break;
21301 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21302 left -= print_symbol (- left, "true");
21303 break;
21304 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21305 left -= print_symbol (- left, "false");
21306 break;
21307 }
21308
21309 if (do_wide && left > 0)
21310 printf ("%-*s", left, " ");
9abca702 21311
015dc7e1 21312 return true;
9ef920e9
NC
21313}
21314
2952f10c
SM
21315/* Print the contents of PNOTE as hex. */
21316
21317static void
21318print_note_contents_hex (Elf_Internal_Note *pnote)
21319{
21320 if (pnote->descsz)
21321 {
21322 unsigned long i;
21323
21324 printf (_(" description data: "));
21325 for (i = 0; i < pnote->descsz; i++)
21326 printf ("%02x ", pnote->descdata[i] & 0xff);
21327 if (!do_wide)
21328 printf ("\n");
21329 }
21330
21331 if (do_wide)
21332 printf ("\n");
21333}
21334
21335#if defined HAVE_MSGPACK
21336
21337static void
21338print_indents (int n)
21339{
21340 printf (" ");
21341
21342 for (int i = 0; i < n; i++)
21343 printf (" ");
21344}
21345
21346/* Print OBJ in human-readable form. */
21347
21348static void
21349dump_msgpack_obj (const msgpack_object *obj, int indent)
21350{
21351 switch (obj->type)
21352 {
21353 case MSGPACK_OBJECT_NIL:
21354 printf ("(nil)");
21355 break;
21356
21357 case MSGPACK_OBJECT_BOOLEAN:
21358 printf ("%s", obj->via.boolean ? "true" : "false");
21359 break;
21360
21361 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21362 printf ("%" PRIu64, obj->via.u64);
21363 break;
21364
21365 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21366 printf ("%" PRIi64, obj->via.i64);
21367 break;
21368
21369 case MSGPACK_OBJECT_FLOAT32:
21370 case MSGPACK_OBJECT_FLOAT64:
21371 printf ("%f", obj->via.f64);
21372 break;
21373
21374 case MSGPACK_OBJECT_STR:
21375 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21376 break;
21377
21378 case MSGPACK_OBJECT_ARRAY:
21379 {
21380 const msgpack_object_array *array = &obj->via.array;
21381
21382 printf ("[\n");
21383 ++indent;
21384
21385 for (uint32_t i = 0; i < array->size; ++i)
21386 {
21387 const msgpack_object *item = &array->ptr[i];
21388
21389 print_indents (indent);
21390 dump_msgpack_obj (item, indent);
21391 printf (",\n");
21392 }
21393
21394 --indent;
21395 print_indents (indent);
21396 printf ("]");
21397 break;
21398 }
21399 break;
21400
21401 case MSGPACK_OBJECT_MAP:
21402 {
21403 const msgpack_object_map *map = &obj->via.map;
21404
21405 printf ("{\n");
21406 ++indent;
21407
21408 for (uint32_t i = 0; i < map->size; ++i)
21409 {
21410 const msgpack_object_kv *kv = &map->ptr[i];
21411 const msgpack_object *key = &kv->key;
21412 const msgpack_object *val = &kv->val;
21413
21414 print_indents (indent);
21415 dump_msgpack_obj (key, indent);
21416 printf (": ");
21417 dump_msgpack_obj (val, indent);
21418
21419 printf (",\n");
21420 }
21421
21422 --indent;
21423 print_indents (indent);
21424 printf ("}");
21425
21426 break;
21427 }
21428
21429 case MSGPACK_OBJECT_BIN:
21430 printf ("(bin)");
21431 break;
21432
21433 case MSGPACK_OBJECT_EXT:
21434 printf ("(ext)");
21435 break;
21436 }
21437}
21438
21439static void
21440dump_msgpack (const msgpack_unpacked *msg)
21441{
21442 print_indents (0);
21443 dump_msgpack_obj (&msg->data, 0);
21444 printf ("\n");
21445}
21446
21447#endif /* defined HAVE_MSGPACK */
21448
21449static bool
21450print_amdgpu_note (Elf_Internal_Note *pnote)
21451{
21452#if defined HAVE_MSGPACK
21453 /* If msgpack is available, decode and dump the note's content. */
21454 bool ret;
21455 msgpack_unpacked msg;
21456 msgpack_unpack_return msgpack_ret;
21457
21458 assert (pnote->type == NT_AMDGPU_METADATA);
21459
21460 msgpack_unpacked_init (&msg);
21461 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21462 NULL);
21463
21464 switch (msgpack_ret)
21465 {
21466 case MSGPACK_UNPACK_SUCCESS:
21467 dump_msgpack (&msg);
21468 ret = true;
21469 break;
21470
21471 default:
21472 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21473 ret = false;
21474 break;
21475 }
21476
21477 msgpack_unpacked_destroy (&msg);
21478 return ret;
21479#else
21480 /* msgpack is not available, dump contents as hex. */
21481 print_note_contents_hex (pnote);
21482 return true;
21483#endif
21484}
21485
6d118b09
NC
21486/* Note that by the ELF standard, the name field is already null byte
21487 terminated, and namesz includes the terminating null byte.
21488 I.E. the value of namesz for the name "FSF" is 4.
21489
e3c8793a 21490 If the value of namesz is zero, there is no name present. */
9ef920e9 21491
015dc7e1 21492static bool
9ef920e9 21493process_note (Elf_Internal_Note * pnote,
dda8d76d 21494 Filedata * filedata)
779fe533 21495{
2cf0635d
NC
21496 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21497 const char * nt;
9437c45b
JT
21498
21499 if (pnote->namesz == 0)
1ec5cd37
NC
21500 /* If there is no note name, then use the default set of
21501 note type strings. */
dda8d76d 21502 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21503
24d127aa 21504 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21505 /* GNU-specific object file notes. */
21506 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21507
28cdbb18
SM
21508 else if (startswith (pnote->namedata, "AMDGPU"))
21509 /* AMDGPU-specific object file notes. */
21510 nt = get_amdgpu_elf_note_type (pnote->type);
21511
24d127aa 21512 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21513 /* FreeBSD-specific core file notes. */
dda8d76d 21514 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21515
24d127aa 21516 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21517 /* NetBSD-specific core file notes. */
dda8d76d 21518 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21519
24d127aa 21520 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21521 /* NetBSD-specific core file notes. */
21522 return process_netbsd_elf_note (pnote);
21523
24d127aa 21524 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21525 /* NetBSD-specific core file notes. */
21526 return process_netbsd_elf_note (pnote);
21527
98ca73af
FC
21528 else if (startswith (pnote->namedata, "OpenBSD"))
21529 /* OpenBSD-specific core file notes. */
21530 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21531
e9b095a5 21532 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21533 {
21534 /* SPU-specific core file notes. */
21535 nt = pnote->namedata + 4;
21536 name = "SPU";
21537 }
21538
24d127aa 21539 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21540 /* VMS/ia64-specific file notes. */
21541 nt = get_ia64_vms_note_type (pnote->type);
21542
24d127aa 21543 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21544 nt = get_stapsdt_note_type (pnote->type);
21545
9437c45b 21546 else
1ec5cd37
NC
21547 /* Don't recognize this note name; just use the default set of
21548 note type strings. */
dda8d76d 21549 nt = get_note_type (filedata, pnote->type);
9437c45b 21550
1449284b 21551 printf (" ");
9ef920e9 21552
24d127aa 21553 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21554 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21555 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21556 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21557 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21558 print_gnu_build_attribute_name (pnote);
21559 else
21560 print_symbol (-20, name);
21561
21562 if (do_wide)
21563 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21564 else
21565 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21566
24d127aa 21567 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21568 return print_ia64_vms_note (pnote);
24d127aa 21569 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21570 return print_gnu_note (filedata, pnote);
24d127aa 21571 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21572 return print_stapsdt_note (pnote);
24d127aa 21573 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21574 return print_core_note (pnote);
e5382207
LB
21575 else if (startswith (pnote->namedata, "FDO"))
21576 return print_fdo_note (pnote);
24d127aa 21577 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21578 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21579 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21580 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21581 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21582 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21583 else if (startswith (pnote->namedata, "AMDGPU")
21584 && pnote->type == NT_AMDGPU_METADATA)
21585 return print_amdgpu_note (pnote);
779fe533 21586
2952f10c 21587 print_note_contents_hex (pnote);
015dc7e1 21588 return true;
1449284b 21589}
6d118b09 21590
015dc7e1 21591static bool
dda8d76d
NC
21592process_notes_at (Filedata * filedata,
21593 Elf_Internal_Shdr * section,
21594 bfd_vma offset,
82ed9683
L
21595 bfd_vma length,
21596 bfd_vma align)
779fe533 21597{
015dc7e1
AM
21598 Elf_External_Note *pnotes;
21599 Elf_External_Note *external;
21600 char *end;
21601 bool res = true;
103f02d3 21602
779fe533 21603 if (length <= 0)
015dc7e1 21604 return false;
103f02d3 21605
1449284b
NC
21606 if (section)
21607 {
dda8d76d 21608 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21609 if (pnotes)
32ec8896 21610 {
dda8d76d 21611 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21612 {
21613 free (pnotes);
015dc7e1 21614 return false;
f761cb13 21615 }
32ec8896 21616 }
1449284b
NC
21617 }
21618 else
82ed9683 21619 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21620 _("notes"));
4dff97b2 21621
dd24e3da 21622 if (pnotes == NULL)
015dc7e1 21623 return false;
779fe533 21624
103f02d3 21625 external = pnotes;
103f02d3 21626
ca0e11aa
NC
21627 if (filedata->is_separate)
21628 printf (_("In linked file '%s': "), filedata->file_name);
21629 else
21630 printf ("\n");
1449284b 21631 if (section)
ca0e11aa 21632 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21633 else
ca0e11aa 21634 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21635 (unsigned long) offset, (unsigned long) length);
21636
82ed9683
L
21637 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21638 specifies that notes should be aligned to 4 bytes in 32-bit
21639 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21640 we also support 4 byte alignment in 64-bit objects. If section
21641 alignment is less than 4, we treate alignment as 4 bytes. */
21642 if (align < 4)
21643 align = 4;
21644 else if (align != 4 && align != 8)
21645 {
21646 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21647 (long) align);
a788aedd 21648 free (pnotes);
015dc7e1 21649 return false;
82ed9683
L
21650 }
21651
dbe15e4e 21652 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21653
c8071705
NC
21654 end = (char *) pnotes + length;
21655 while ((char *) external < end)
779fe533 21656 {
b34976b6 21657 Elf_Internal_Note inote;
15b42fb0 21658 size_t min_notesz;
4dff97b2 21659 char * next;
2cf0635d 21660 char * temp = NULL;
c8071705 21661 size_t data_remaining = end - (char *) external;
6d118b09 21662
dda8d76d 21663 if (!is_ia64_vms (filedata))
15b42fb0 21664 {
9dd3a467
NC
21665 /* PR binutils/15191
21666 Make sure that there is enough data to read. */
15b42fb0
AM
21667 min_notesz = offsetof (Elf_External_Note, name);
21668 if (data_remaining < min_notesz)
9dd3a467 21669 {
d3a49aa8
AM
21670 warn (ngettext ("Corrupt note: only %ld byte remains, "
21671 "not enough for a full note\n",
21672 "Corrupt note: only %ld bytes remain, "
21673 "not enough for a full note\n",
21674 data_remaining),
21675 (long) data_remaining);
9dd3a467
NC
21676 break;
21677 }
5396a86e
AM
21678 data_remaining -= min_notesz;
21679
15b42fb0
AM
21680 inote.type = BYTE_GET (external->type);
21681 inote.namesz = BYTE_GET (external->namesz);
21682 inote.namedata = external->name;
21683 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21684 inote.descdata = ((char *) external
4dff97b2 21685 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21686 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21687 next = ((char *) external
4dff97b2 21688 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21689 }
00e98fc7 21690 else
15b42fb0
AM
21691 {
21692 Elf64_External_VMS_Note *vms_external;
00e98fc7 21693
9dd3a467
NC
21694 /* PR binutils/15191
21695 Make sure that there is enough data to read. */
15b42fb0
AM
21696 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21697 if (data_remaining < min_notesz)
9dd3a467 21698 {
d3a49aa8
AM
21699 warn (ngettext ("Corrupt note: only %ld byte remains, "
21700 "not enough for a full note\n",
21701 "Corrupt note: only %ld bytes remain, "
21702 "not enough for a full note\n",
21703 data_remaining),
21704 (long) data_remaining);
9dd3a467
NC
21705 break;
21706 }
5396a86e 21707 data_remaining -= min_notesz;
3e55a963 21708
15b42fb0
AM
21709 vms_external = (Elf64_External_VMS_Note *) external;
21710 inote.type = BYTE_GET (vms_external->type);
21711 inote.namesz = BYTE_GET (vms_external->namesz);
21712 inote.namedata = vms_external->name;
21713 inote.descsz = BYTE_GET (vms_external->descsz);
21714 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21715 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21716 next = inote.descdata + align_power (inote.descsz, 3);
21717 }
21718
5396a86e
AM
21719 /* PR 17531: file: 3443835e. */
21720 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21721 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21722 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21723 || (size_t) (next - inote.descdata) < inote.descsz
21724 || ((size_t) (next - inote.descdata)
21725 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21726 {
15b42fb0 21727 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21728 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21729 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21730 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21731 break;
21732 }
21733
15b42fb0 21734 external = (Elf_External_Note *) next;
dd24e3da 21735
6d118b09
NC
21736 /* Verify that name is null terminated. It appears that at least
21737 one version of Linux (RedHat 6.0) generates corefiles that don't
21738 comply with the ELF spec by failing to include the null byte in
21739 namesz. */
18344509 21740 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21741 {
5396a86e 21742 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21743 {
5396a86e
AM
21744 temp = (char *) malloc (inote.namesz + 1);
21745 if (temp == NULL)
21746 {
21747 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21748 res = false;
5396a86e
AM
21749 break;
21750 }
76da6bbe 21751
5396a86e
AM
21752 memcpy (temp, inote.namedata, inote.namesz);
21753 inote.namedata = temp;
21754 }
21755 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21756 }
21757
dda8d76d 21758 if (! process_note (& inote, filedata))
015dc7e1 21759 res = false;
103f02d3 21760
9db70fc3
AM
21761 free (temp);
21762 temp = NULL;
779fe533
NC
21763 }
21764
21765 free (pnotes);
103f02d3 21766
779fe533
NC
21767 return res;
21768}
21769
015dc7e1 21770static bool
dda8d76d 21771process_corefile_note_segments (Filedata * filedata)
779fe533 21772{
015dc7e1 21773 Elf_Internal_Phdr *segment;
b34976b6 21774 unsigned int i;
015dc7e1 21775 bool res = true;
103f02d3 21776
dda8d76d 21777 if (! get_program_headers (filedata))
015dc7e1 21778 return true;
103f02d3 21779
dda8d76d
NC
21780 for (i = 0, segment = filedata->program_headers;
21781 i < filedata->file_header.e_phnum;
b34976b6 21782 i++, segment++)
779fe533
NC
21783 {
21784 if (segment->p_type == PT_NOTE)
dda8d76d 21785 if (! process_notes_at (filedata, NULL,
32ec8896 21786 (bfd_vma) segment->p_offset,
82ed9683
L
21787 (bfd_vma) segment->p_filesz,
21788 (bfd_vma) segment->p_align))
015dc7e1 21789 res = false;
779fe533 21790 }
103f02d3 21791
779fe533
NC
21792 return res;
21793}
21794
015dc7e1 21795static bool
dda8d76d 21796process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21797{
21798 Elf_External_Note * pnotes;
21799 Elf_External_Note * external;
c8071705 21800 char * end;
015dc7e1 21801 bool res = true;
685080f2
NC
21802
21803 if (length <= 0)
015dc7e1 21804 return false;
685080f2 21805
dda8d76d 21806 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21807 _("v850 notes"));
21808 if (pnotes == NULL)
015dc7e1 21809 return false;
685080f2
NC
21810
21811 external = pnotes;
c8071705 21812 end = (char*) pnotes + length;
685080f2
NC
21813
21814 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21815 (unsigned long) offset, (unsigned long) length);
21816
c8071705 21817 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21818 {
21819 Elf_External_Note * next;
21820 Elf_Internal_Note inote;
21821
21822 inote.type = BYTE_GET (external->type);
21823 inote.namesz = BYTE_GET (external->namesz);
21824 inote.namedata = external->name;
21825 inote.descsz = BYTE_GET (external->descsz);
21826 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21827 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21828
c8071705
NC
21829 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21830 {
21831 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21832 inote.descdata = inote.namedata;
21833 inote.namesz = 0;
21834 }
21835
685080f2
NC
21836 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21837
c8071705 21838 if ( ((char *) next > end)
685080f2
NC
21839 || ((char *) next < (char *) pnotes))
21840 {
21841 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21842 (unsigned long) ((char *) external - (char *) pnotes));
21843 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21844 inote.type, inote.namesz, inote.descsz);
21845 break;
21846 }
21847
21848 external = next;
21849
21850 /* Prevent out-of-bounds indexing. */
c8071705 21851 if ( inote.namedata + inote.namesz > end
685080f2
NC
21852 || inote.namedata + inote.namesz < inote.namedata)
21853 {
21854 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21855 (unsigned long) ((char *) external - (char *) pnotes));
21856 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21857 inote.type, inote.namesz, inote.descsz);
21858 break;
21859 }
21860
21861 printf (" %s: ", get_v850_elf_note_type (inote.type));
21862
21863 if (! print_v850_note (& inote))
21864 {
015dc7e1 21865 res = false;
685080f2
NC
21866 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21867 inote.namesz, inote.descsz);
21868 }
21869 }
21870
21871 free (pnotes);
21872
21873 return res;
21874}
21875
015dc7e1 21876static bool
dda8d76d 21877process_note_sections (Filedata * filedata)
1ec5cd37 21878{
015dc7e1 21879 Elf_Internal_Shdr *section;
1ec5cd37 21880 unsigned long i;
32ec8896 21881 unsigned int n = 0;
015dc7e1 21882 bool res = true;
1ec5cd37 21883
dda8d76d
NC
21884 for (i = 0, section = filedata->section_headers;
21885 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21886 i++, section++)
685080f2
NC
21887 {
21888 if (section->sh_type == SHT_NOTE)
21889 {
dda8d76d 21890 if (! process_notes_at (filedata, section,
32ec8896 21891 (bfd_vma) section->sh_offset,
82ed9683
L
21892 (bfd_vma) section->sh_size,
21893 (bfd_vma) section->sh_addralign))
015dc7e1 21894 res = false;
685080f2
NC
21895 n++;
21896 }
21897
dda8d76d
NC
21898 if (( filedata->file_header.e_machine == EM_V800
21899 || filedata->file_header.e_machine == EM_V850
21900 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21901 && section->sh_type == SHT_RENESAS_INFO)
21902 {
dda8d76d 21903 if (! process_v850_notes (filedata,
32ec8896
NC
21904 (bfd_vma) section->sh_offset,
21905 (bfd_vma) section->sh_size))
015dc7e1 21906 res = false;
685080f2
NC
21907 n++;
21908 }
21909 }
df565f32
NC
21910
21911 if (n == 0)
21912 /* Try processing NOTE segments instead. */
dda8d76d 21913 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21914
21915 return res;
21916}
21917
015dc7e1 21918static bool
dda8d76d 21919process_notes (Filedata * filedata)
779fe533
NC
21920{
21921 /* If we have not been asked to display the notes then do nothing. */
21922 if (! do_notes)
015dc7e1 21923 return true;
103f02d3 21924
dda8d76d
NC
21925 if (filedata->file_header.e_type != ET_CORE)
21926 return process_note_sections (filedata);
103f02d3 21927
779fe533 21928 /* No program headers means no NOTE segment. */
dda8d76d
NC
21929 if (filedata->file_header.e_phnum > 0)
21930 return process_corefile_note_segments (filedata);
779fe533 21931
ca0e11aa
NC
21932 if (filedata->is_separate)
21933 printf (_("No notes found in linked file '%s'.\n"),
21934 filedata->file_name);
21935 else
21936 printf (_("No notes found file.\n"));
21937
015dc7e1 21938 return true;
779fe533
NC
21939}
21940
60abdbed
NC
21941static unsigned char *
21942display_public_gnu_attributes (unsigned char * start,
21943 const unsigned char * const end)
21944{
21945 printf (_(" Unknown GNU attribute: %s\n"), start);
21946
21947 start += strnlen ((char *) start, end - start);
21948 display_raw_attribute (start, end);
21949
21950 return (unsigned char *) end;
21951}
21952
21953static unsigned char *
21954display_generic_attribute (unsigned char * start,
21955 unsigned int tag,
21956 const unsigned char * const end)
21957{
21958 if (tag == 0)
21959 return (unsigned char *) end;
21960
21961 return display_tag_value (tag, start, end);
21962}
21963
015dc7e1 21964static bool
dda8d76d 21965process_arch_specific (Filedata * filedata)
252b5132 21966{
a952a375 21967 if (! do_arch)
015dc7e1 21968 return true;
a952a375 21969
dda8d76d 21970 switch (filedata->file_header.e_machine)
252b5132 21971 {
53a346d8
CZ
21972 case EM_ARC:
21973 case EM_ARC_COMPACT:
21974 case EM_ARC_COMPACT2:
dda8d76d 21975 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21976 display_arc_attribute,
21977 display_generic_attribute);
11c1ff18 21978 case EM_ARM:
dda8d76d 21979 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21980 display_arm_attribute,
21981 display_generic_attribute);
21982
252b5132 21983 case EM_MIPS:
4fe85591 21984 case EM_MIPS_RS3_LE:
dda8d76d 21985 return process_mips_specific (filedata);
60abdbed
NC
21986
21987 case EM_MSP430:
dda8d76d 21988 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21989 display_msp430_attribute,
c0ea7c52 21990 display_msp430_gnu_attribute);
60abdbed 21991
2dc8dd17
JW
21992 case EM_RISCV:
21993 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21994 display_riscv_attribute,
21995 display_generic_attribute);
21996
35c08157 21997 case EM_NDS32:
dda8d76d 21998 return process_nds32_specific (filedata);
60abdbed 21999
85f7484a
PB
22000 case EM_68K:
22001 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22002 display_m68k_gnu_attribute);
22003
34c8bcba 22004 case EM_PPC:
b82317dd 22005 case EM_PPC64:
dda8d76d 22006 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22007 display_power_gnu_attribute);
22008
643f7afb
AK
22009 case EM_S390:
22010 case EM_S390_OLD:
dda8d76d 22011 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22012 display_s390_gnu_attribute);
22013
9e8c70f9
DM
22014 case EM_SPARC:
22015 case EM_SPARC32PLUS:
22016 case EM_SPARCV9:
dda8d76d 22017 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22018 display_sparc_gnu_attribute);
22019
59e6276b 22020 case EM_TI_C6000:
dda8d76d 22021 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22022 display_tic6x_attribute,
22023 display_generic_attribute);
22024
0861f561
CQ
22025 case EM_CSKY:
22026 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22027 display_csky_attribute, NULL);
22028
252b5132 22029 default:
dda8d76d 22030 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22031 display_public_gnu_attributes,
22032 display_generic_attribute);
252b5132 22033 }
252b5132
RH
22034}
22035
015dc7e1 22036static bool
dda8d76d 22037get_file_header (Filedata * filedata)
252b5132 22038{
9ea033b2 22039 /* Read in the identity array. */
dda8d76d 22040 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22041 return false;
252b5132 22042
9ea033b2 22043 /* Determine how to read the rest of the header. */
dda8d76d 22044 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22045 {
1a0670f3
AM
22046 default:
22047 case ELFDATANONE:
adab8cdc
AO
22048 case ELFDATA2LSB:
22049 byte_get = byte_get_little_endian;
22050 byte_put = byte_put_little_endian;
22051 break;
22052 case ELFDATA2MSB:
22053 byte_get = byte_get_big_endian;
22054 byte_put = byte_put_big_endian;
22055 break;
9ea033b2
NC
22056 }
22057
22058 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22059 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22060
22061 /* Read in the rest of the header. */
22062 if (is_32bit_elf)
22063 {
22064 Elf32_External_Ehdr ehdr32;
252b5132 22065
dda8d76d 22066 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22067 return false;
103f02d3 22068
dda8d76d
NC
22069 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22070 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22071 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22072 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22073 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22074 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22075 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22076 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22077 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22078 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22079 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22080 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22081 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22082 }
252b5132 22083 else
9ea033b2
NC
22084 {
22085 Elf64_External_Ehdr ehdr64;
a952a375
NC
22086
22087 /* If we have been compiled with sizeof (bfd_vma) == 4, then
22088 we will not be able to cope with the 64bit data found in
22089 64 ELF files. Detect this now and abort before we start
50c2245b 22090 overwriting things. */
a952a375
NC
22091 if (sizeof (bfd_vma) < 8)
22092 {
e3c8793a
NC
22093 error (_("This instance of readelf has been built without support for a\n\
2209464 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 22095 return false;
a952a375 22096 }
103f02d3 22097
dda8d76d 22098 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22099 return false;
103f02d3 22100
dda8d76d
NC
22101 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22102 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22103 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22104 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22105 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22106 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22107 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22108 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22109 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22110 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22111 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22112 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22113 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22114 }
252b5132 22115
015dc7e1 22116 return true;
252b5132
RH
22117}
22118
13acb58d
AM
22119static void
22120free_filedata (Filedata *filedata)
22121{
22122 free (filedata->program_interpreter);
13acb58d 22123 free (filedata->program_headers);
13acb58d 22124 free (filedata->section_headers);
13acb58d 22125 free (filedata->string_table);
13acb58d 22126 free (filedata->dump.dump_sects);
13acb58d 22127 free (filedata->dynamic_strings);
13acb58d 22128 free (filedata->dynamic_symbols);
13acb58d 22129 free (filedata->dynamic_syminfo);
13acb58d 22130 free (filedata->dynamic_section);
13acb58d
AM
22131
22132 while (filedata->symtab_shndx_list != NULL)
22133 {
22134 elf_section_list *next = filedata->symtab_shndx_list->next;
22135 free (filedata->symtab_shndx_list);
22136 filedata->symtab_shndx_list = next;
22137 }
22138
22139 free (filedata->section_headers_groups);
13acb58d
AM
22140
22141 if (filedata->section_groups)
22142 {
22143 size_t i;
22144 struct group_list * g;
22145 struct group_list * next;
22146
22147 for (i = 0; i < filedata->group_count; i++)
22148 {
22149 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22150 {
22151 next = g->next;
22152 free (g);
22153 }
22154 }
22155
22156 free (filedata->section_groups);
13acb58d 22157 }
066f8fbe
AM
22158 memset (&filedata->section_headers, 0,
22159 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22160}
22161
dda8d76d
NC
22162static void
22163close_file (Filedata * filedata)
22164{
22165 if (filedata)
22166 {
22167 if (filedata->handle)
22168 fclose (filedata->handle);
22169 free (filedata);
22170 }
22171}
22172
22173void
22174close_debug_file (void * data)
22175{
13acb58d 22176 free_filedata ((Filedata *) data);
dda8d76d
NC
22177 close_file ((Filedata *) data);
22178}
22179
22180static Filedata *
015dc7e1 22181open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22182{
22183 struct stat statbuf;
22184 Filedata * filedata = NULL;
22185
22186 if (stat (pathname, & statbuf) < 0
22187 || ! S_ISREG (statbuf.st_mode))
22188 goto fail;
22189
22190 filedata = calloc (1, sizeof * filedata);
22191 if (filedata == NULL)
22192 goto fail;
22193
22194 filedata->handle = fopen (pathname, "rb");
22195 if (filedata->handle == NULL)
22196 goto fail;
22197
22198 filedata->file_size = (bfd_size_type) statbuf.st_size;
22199 filedata->file_name = pathname;
ca0e11aa 22200 filedata->is_separate = is_separate;
dda8d76d
NC
22201
22202 if (! get_file_header (filedata))
22203 goto fail;
22204
4de91c10
AM
22205 if (!get_section_headers (filedata, false))
22206 goto fail;
dda8d76d
NC
22207
22208 return filedata;
22209
22210 fail:
22211 if (filedata)
22212 {
22213 if (filedata->handle)
22214 fclose (filedata->handle);
22215 free (filedata);
22216 }
22217 return NULL;
22218}
22219
22220void *
22221open_debug_file (const char * pathname)
22222{
015dc7e1 22223 return open_file (pathname, true);
dda8d76d
NC
22224}
22225
835f2fae
NC
22226static void
22227initialise_dump_sects (Filedata * filedata)
22228{
22229 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22230 Note we do this even if cmdline_dump_sects is empty because we
22231 must make sure that the dump_sets array is zeroed out before each
22232 object file is processed. */
22233 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22234 memset (filedata->dump.dump_sects, 0,
22235 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22236
22237 if (cmdline.num_dump_sects > 0)
22238 {
22239 if (filedata->dump.num_dump_sects == 0)
22240 /* A sneaky way of allocating the dump_sects array. */
22241 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22242
22243 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22244 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22245 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22246 }
22247}
22248
94585d6d
NC
22249static bool
22250might_need_separate_debug_info (Filedata * filedata)
22251{
22252 /* Debuginfo files do not need further separate file loading. */
22253 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22254 return false;
22255
22256 /* Since do_follow_links might be enabled by default, only treat it as an
22257 indication that separate files should be loaded if setting it was a
22258 deliberate user action. */
22259 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22260 return true;
22261
22262 if (process_links || do_syms || do_unwind
22263 || dump_any_debugging || do_dump || do_debugging)
22264 return true;
22265
22266 return false;
22267}
22268
fb52b2f4
NC
22269/* Process one ELF object file according to the command line options.
22270 This file may actually be stored in an archive. The file is
32ec8896
NC
22271 positioned at the start of the ELF object. Returns TRUE if no
22272 problems were encountered, FALSE otherwise. */
fb52b2f4 22273
015dc7e1 22274static bool
dda8d76d 22275process_object (Filedata * filedata)
252b5132 22276{
015dc7e1 22277 bool have_separate_files;
252b5132 22278 unsigned int i;
015dc7e1 22279 bool res;
252b5132 22280
dda8d76d 22281 if (! get_file_header (filedata))
252b5132 22282 {
dda8d76d 22283 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22284 return false;
252b5132
RH
22285 }
22286
22287 /* Initialise per file variables. */
978c4450
AM
22288 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22289 filedata->version_info[i] = 0;
252b5132 22290
978c4450
AM
22291 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22292 filedata->dynamic_info[i] = 0;
22293 filedata->dynamic_info_DT_GNU_HASH = 0;
22294 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22295
22296 /* Process the file. */
22297 if (show_name)
dda8d76d 22298 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22299
835f2fae 22300 initialise_dump_sects (filedata);
d70c5fc7 22301
4de91c10
AM
22302 /* There may be some extensions in the first section header. Don't
22303 bomb if we can't read it. */
22304 get_section_headers (filedata, true);
22305
dda8d76d 22306 if (! process_file_header (filedata))
4de91c10
AM
22307 {
22308 res = false;
22309 goto out;
22310 }
252b5132 22311
e331b18d
AM
22312 /* Throw away the single section header read above, so that we
22313 re-read the entire set. */
22314 free (filedata->section_headers);
22315 filedata->section_headers = NULL;
22316
dda8d76d 22317 if (! process_section_headers (filedata))
2f62977e 22318 {
32ec8896 22319 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22320 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22321
2f62977e 22322 if (! do_using_dynamic)
015dc7e1 22323 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22324 }
252b5132 22325
dda8d76d 22326 if (! process_section_groups (filedata))
32ec8896 22327 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22328 do_unwind = false;
d1f5c6e3 22329
93df3340
AM
22330 process_program_headers (filedata);
22331
22332 res = process_dynamic_section (filedata);
252b5132 22333
dda8d76d 22334 if (! process_relocs (filedata))
015dc7e1 22335 res = false;
252b5132 22336
dda8d76d 22337 if (! process_unwind (filedata))
015dc7e1 22338 res = false;
4d6ed7c8 22339
dda8d76d 22340 if (! process_symbol_table (filedata))
015dc7e1 22341 res = false;
252b5132 22342
0f03783c 22343 if (! process_lto_symbol_tables (filedata))
015dc7e1 22344 res = false;
b9e920ec 22345
dda8d76d 22346 if (! process_syminfo (filedata))
015dc7e1 22347 res = false;
252b5132 22348
dda8d76d 22349 if (! process_version_sections (filedata))
015dc7e1 22350 res = false;
252b5132 22351
94585d6d 22352 if (might_need_separate_debug_info (filedata))
24841daa 22353 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22354 else
015dc7e1 22355 have_separate_files = false;
dda8d76d
NC
22356
22357 if (! process_section_contents (filedata))
015dc7e1 22358 res = false;
f5842774 22359
24841daa 22360 if (have_separate_files)
dda8d76d 22361 {
24841daa
NC
22362 separate_info * d;
22363
22364 for (d = first_separate_info; d != NULL; d = d->next)
22365 {
835f2fae
NC
22366 initialise_dump_sects (d->handle);
22367
ca0e11aa 22368 if (process_links && ! process_file_header (d->handle))
015dc7e1 22369 res = false;
ca0e11aa 22370 else if (! process_section_headers (d->handle))
015dc7e1 22371 res = false;
d6bfbc39 22372 else if (! process_section_contents (d->handle))
015dc7e1 22373 res = false;
ca0e11aa
NC
22374 else if (process_links)
22375 {
ca0e11aa 22376 if (! process_section_groups (d->handle))
015dc7e1 22377 res = false;
93df3340 22378 process_program_headers (d->handle);
ca0e11aa 22379 if (! process_dynamic_section (d->handle))
015dc7e1 22380 res = false;
ca0e11aa 22381 if (! process_relocs (d->handle))
015dc7e1 22382 res = false;
ca0e11aa 22383 if (! process_unwind (d->handle))
015dc7e1 22384 res = false;
ca0e11aa 22385 if (! process_symbol_table (d->handle))
015dc7e1 22386 res = false;
ca0e11aa 22387 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22388 res = false;
ca0e11aa 22389 if (! process_syminfo (d->handle))
015dc7e1 22390 res = false;
ca0e11aa 22391 if (! process_version_sections (d->handle))
015dc7e1 22392 res = false;
ca0e11aa 22393 if (! process_notes (d->handle))
015dc7e1 22394 res = false;
ca0e11aa 22395 }
24841daa
NC
22396 }
22397
22398 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22399 }
22400
22401 if (! process_notes (filedata))
015dc7e1 22402 res = false;
103f02d3 22403
dda8d76d 22404 if (! process_gnu_liblist (filedata))
015dc7e1 22405 res = false;
047b2264 22406
dda8d76d 22407 if (! process_arch_specific (filedata))
015dc7e1 22408 res = false;
252b5132 22409
4de91c10 22410 out:
13acb58d 22411 free_filedata (filedata);
e4b17d5c 22412
19e6b90e 22413 free_debug_memory ();
18bd398b 22414
32ec8896 22415 return res;
252b5132
RH
22416}
22417
2cf0635d 22418/* Process an ELF archive.
32ec8896
NC
22419 On entry the file is positioned just after the ARMAG string.
22420 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22421
015dc7e1
AM
22422static bool
22423process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22424{
22425 struct archive_info arch;
22426 struct archive_info nested_arch;
22427 size_t got;
015dc7e1 22428 bool ret = true;
2cf0635d 22429
015dc7e1 22430 show_name = true;
2cf0635d
NC
22431
22432 /* The ARCH structure is used to hold information about this archive. */
22433 arch.file_name = NULL;
22434 arch.file = NULL;
22435 arch.index_array = NULL;
22436 arch.sym_table = NULL;
22437 arch.longnames = NULL;
22438
22439 /* The NESTED_ARCH structure is used as a single-item cache of information
22440 about a nested archive (when members of a thin archive reside within
22441 another regular archive file). */
22442 nested_arch.file_name = NULL;
22443 nested_arch.file = NULL;
22444 nested_arch.index_array = NULL;
22445 nested_arch.sym_table = NULL;
22446 nested_arch.longnames = NULL;
22447
dda8d76d 22448 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22449 filedata->file_size, is_thin_archive,
22450 do_archive_index) != 0)
2cf0635d 22451 {
015dc7e1 22452 ret = false;
2cf0635d 22453 goto out;
4145f1d5 22454 }
fb52b2f4 22455
4145f1d5
NC
22456 if (do_archive_index)
22457 {
2cf0635d 22458 if (arch.sym_table == NULL)
1cb7d8b1
AM
22459 error (_("%s: unable to dump the index as none was found\n"),
22460 filedata->file_name);
4145f1d5
NC
22461 else
22462 {
591f7597 22463 unsigned long i, l;
4145f1d5
NC
22464 unsigned long current_pos;
22465
1cb7d8b1
AM
22466 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22467 "in the symbol table)\n"),
22468 filedata->file_name, (unsigned long) arch.index_num,
22469 arch.sym_size);
dda8d76d
NC
22470
22471 current_pos = ftell (filedata->handle);
4145f1d5 22472
2cf0635d 22473 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22474 {
1cb7d8b1
AM
22475 if (i == 0
22476 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22477 {
22478 char * member_name
22479 = get_archive_member_name_at (&arch, arch.index_array[i],
22480 &nested_arch);
2cf0635d 22481
1cb7d8b1
AM
22482 if (member_name != NULL)
22483 {
22484 char * qualified_name
22485 = make_qualified_name (&arch, &nested_arch,
22486 member_name);
2cf0635d 22487
1cb7d8b1
AM
22488 if (qualified_name != NULL)
22489 {
22490 printf (_("Contents of binary %s at offset "),
22491 qualified_name);
c2a7d3f5
NC
22492 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22493 putchar ('\n');
1cb7d8b1
AM
22494 free (qualified_name);
22495 }
fd486f32 22496 free (member_name);
4145f1d5
NC
22497 }
22498 }
2cf0635d
NC
22499
22500 if (l >= arch.sym_size)
4145f1d5 22501 {
1cb7d8b1
AM
22502 error (_("%s: end of the symbol table reached "
22503 "before the end of the index\n"),
dda8d76d 22504 filedata->file_name);
015dc7e1 22505 ret = false;
cb8f3167 22506 break;
4145f1d5 22507 }
591f7597 22508 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22509 printf ("\t%.*s\n",
22510 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22511 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22512 }
22513
67ce483b 22514 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22515 l = (l + 7) & ~ 7;
22516 else
22517 l += l & 1;
22518
2cf0635d 22519 if (l < arch.sym_size)
32ec8896 22520 {
d3a49aa8
AM
22521 error (ngettext ("%s: %ld byte remains in the symbol table, "
22522 "but without corresponding entries in "
22523 "the index table\n",
22524 "%s: %ld bytes remain in the symbol table, "
22525 "but without corresponding entries in "
22526 "the index table\n",
22527 arch.sym_size - l),
dda8d76d 22528 filedata->file_name, arch.sym_size - l);
015dc7e1 22529 ret = false;
32ec8896 22530 }
4145f1d5 22531
dda8d76d 22532 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22533 {
1cb7d8b1
AM
22534 error (_("%s: failed to seek back to start of object files "
22535 "in the archive\n"),
dda8d76d 22536 filedata->file_name);
015dc7e1 22537 ret = false;
2cf0635d 22538 goto out;
4145f1d5 22539 }
fb52b2f4 22540 }
4145f1d5
NC
22541
22542 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22543 && !do_segments && !do_header && !do_dump && !do_version
22544 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22545 && !do_section_groups && !do_dyn_syms)
2cf0635d 22546 {
015dc7e1 22547 ret = true; /* Archive index only. */
2cf0635d
NC
22548 goto out;
22549 }
fb52b2f4
NC
22550 }
22551
fb52b2f4
NC
22552 while (1)
22553 {
2cf0635d
NC
22554 char * name;
22555 size_t namelen;
22556 char * qualified_name;
22557
22558 /* Read the next archive header. */
dda8d76d 22559 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22560 {
22561 error (_("%s: failed to seek to next archive header\n"),
22562 arch.file_name);
015dc7e1 22563 ret = false;
1cb7d8b1
AM
22564 break;
22565 }
dda8d76d 22566 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22567 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22568 {
22569 if (got == 0)
2cf0635d 22570 break;
28e817cc
NC
22571 /* PR 24049 - we cannot use filedata->file_name as this will
22572 have already been freed. */
22573 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22574
015dc7e1 22575 ret = false;
1cb7d8b1
AM
22576 break;
22577 }
2cf0635d 22578 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22579 {
22580 error (_("%s: did not find a valid archive header\n"),
22581 arch.file_name);
015dc7e1 22582 ret = false;
1cb7d8b1
AM
22583 break;
22584 }
2cf0635d
NC
22585
22586 arch.next_arhdr_offset += sizeof arch.arhdr;
22587
978c4450 22588 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22589
22590 name = get_archive_member_name (&arch, &nested_arch);
22591 if (name == NULL)
fb52b2f4 22592 {
28e817cc 22593 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22594 ret = false;
d989285c 22595 break;
fb52b2f4 22596 }
2cf0635d 22597 namelen = strlen (name);
fb52b2f4 22598
2cf0635d
NC
22599 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22600 if (qualified_name == NULL)
fb52b2f4 22601 {
28e817cc 22602 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22603 free (name);
015dc7e1 22604 ret = false;
d989285c 22605 break;
fb52b2f4
NC
22606 }
22607
2cf0635d 22608 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22609 {
22610 /* This is a proxy for an external member of a thin archive. */
22611 Filedata * member_filedata;
22612 char * member_file_name = adjust_relative_path
dda8d76d 22613 (filedata->file_name, name, namelen);
32ec8896 22614
fd486f32 22615 free (name);
1cb7d8b1
AM
22616 if (member_file_name == NULL)
22617 {
fd486f32 22618 free (qualified_name);
015dc7e1 22619 ret = false;
1cb7d8b1
AM
22620 break;
22621 }
2cf0635d 22622
015dc7e1 22623 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22624 if (member_filedata == NULL)
22625 {
22626 error (_("Input file '%s' is not readable.\n"), member_file_name);
22627 free (member_file_name);
fd486f32 22628 free (qualified_name);
015dc7e1 22629 ret = false;
1cb7d8b1
AM
22630 break;
22631 }
2cf0635d 22632
978c4450 22633 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22634 member_filedata->file_name = qualified_name;
2cf0635d 22635
75a2da57
AH
22636 /* The call to process_object() expects the file to be at the beginning. */
22637 rewind (member_filedata->handle);
22638
1cb7d8b1 22639 if (! process_object (member_filedata))
015dc7e1 22640 ret = false;
2cf0635d 22641
1cb7d8b1
AM
22642 close_file (member_filedata);
22643 free (member_file_name);
1cb7d8b1 22644 }
2cf0635d 22645 else if (is_thin_archive)
1cb7d8b1
AM
22646 {
22647 Filedata thin_filedata;
eb02c04d 22648
1cb7d8b1 22649 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22650
a043396b
NC
22651 /* PR 15140: Allow for corrupt thin archives. */
22652 if (nested_arch.file == NULL)
22653 {
22654 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22655 qualified_name, name);
fd486f32
AM
22656 free (qualified_name);
22657 free (name);
015dc7e1 22658 ret = false;
a043396b
NC
22659 break;
22660 }
fd486f32 22661 free (name);
a043396b 22662
1cb7d8b1 22663 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22664 filedata->archive_file_offset
22665 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22666
1cb7d8b1
AM
22667 /* The nested archive file will have been opened and setup by
22668 get_archive_member_name. */
978c4450
AM
22669 if (fseek (nested_arch.file, filedata->archive_file_offset,
22670 SEEK_SET) != 0)
1cb7d8b1
AM
22671 {
22672 error (_("%s: failed to seek to archive member.\n"),
22673 nested_arch.file_name);
fd486f32 22674 free (qualified_name);
015dc7e1 22675 ret = false;
1cb7d8b1
AM
22676 break;
22677 }
2cf0635d 22678
dda8d76d
NC
22679 thin_filedata.handle = nested_arch.file;
22680 thin_filedata.file_name = qualified_name;
9abca702 22681
1cb7d8b1 22682 if (! process_object (& thin_filedata))
015dc7e1 22683 ret = false;
1cb7d8b1 22684 }
2cf0635d 22685 else
1cb7d8b1 22686 {
fd486f32 22687 free (name);
978c4450 22688 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22689 filedata->file_name = qualified_name;
1cb7d8b1 22690 if (! process_object (filedata))
015dc7e1 22691 ret = false;
237877b8 22692 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22693 /* Stop looping with "negative" archive_file_size. */
978c4450 22694 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22695 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22696 }
fb52b2f4 22697
2cf0635d 22698 free (qualified_name);
fb52b2f4
NC
22699 }
22700
4145f1d5 22701 out:
2cf0635d
NC
22702 if (nested_arch.file != NULL)
22703 fclose (nested_arch.file);
22704 release_archive (&nested_arch);
22705 release_archive (&arch);
fb52b2f4 22706
d989285c 22707 return ret;
fb52b2f4
NC
22708}
22709
015dc7e1 22710static bool
2cf0635d 22711process_file (char * file_name)
fb52b2f4 22712{
dda8d76d 22713 Filedata * filedata = NULL;
fb52b2f4
NC
22714 struct stat statbuf;
22715 char armag[SARMAG];
015dc7e1 22716 bool ret = true;
fb52b2f4
NC
22717
22718 if (stat (file_name, &statbuf) < 0)
22719 {
f24ddbdd
NC
22720 if (errno == ENOENT)
22721 error (_("'%s': No such file\n"), file_name);
22722 else
22723 error (_("Could not locate '%s'. System error message: %s\n"),
22724 file_name, strerror (errno));
015dc7e1 22725 return false;
f24ddbdd
NC
22726 }
22727
22728 if (! S_ISREG (statbuf.st_mode))
22729 {
22730 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22731 return false;
fb52b2f4
NC
22732 }
22733
dda8d76d
NC
22734 filedata = calloc (1, sizeof * filedata);
22735 if (filedata == NULL)
22736 {
22737 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22738 return false;
dda8d76d
NC
22739 }
22740
22741 filedata->file_name = file_name;
22742 filedata->handle = fopen (file_name, "rb");
22743 if (filedata->handle == NULL)
fb52b2f4 22744 {
f24ddbdd 22745 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22746 free (filedata);
015dc7e1 22747 return false;
fb52b2f4
NC
22748 }
22749
dda8d76d 22750 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22751 {
4145f1d5 22752 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22753 fclose (filedata->handle);
22754 free (filedata);
015dc7e1 22755 return false;
fb52b2f4
NC
22756 }
22757
dda8d76d 22758 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22759 filedata->is_separate = false;
f54498b4 22760
fb52b2f4 22761 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22762 {
015dc7e1
AM
22763 if (! process_archive (filedata, false))
22764 ret = false;
32ec8896 22765 }
2cf0635d 22766 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22767 {
015dc7e1
AM
22768 if ( ! process_archive (filedata, true))
22769 ret = false;
32ec8896 22770 }
fb52b2f4
NC
22771 else
22772 {
1b513401 22773 if (do_archive_index && !check_all)
4145f1d5
NC
22774 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22775 file_name);
22776
dda8d76d 22777 rewind (filedata->handle);
978c4450 22778 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22779
dda8d76d 22780 if (! process_object (filedata))
015dc7e1 22781 ret = false;
fb52b2f4
NC
22782 }
22783
dda8d76d 22784 fclose (filedata->handle);
8fb879cd
AM
22785 free (filedata->section_headers);
22786 free (filedata->program_headers);
22787 free (filedata->string_table);
6431e409 22788 free (filedata->dump.dump_sects);
dda8d76d 22789 free (filedata);
32ec8896 22790
fd486f32 22791 free (ba_cache.strtab);
1bd6175a 22792 ba_cache.strtab = NULL;
fd486f32 22793 free (ba_cache.symtab);
1bd6175a 22794 ba_cache.symtab = NULL;
fd486f32
AM
22795 ba_cache.filedata = NULL;
22796
fb52b2f4
NC
22797 return ret;
22798}
22799
252b5132
RH
22800#ifdef SUPPORT_DISASSEMBLY
22801/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22802 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22803 symbols. */
252b5132
RH
22804
22805void
2cf0635d 22806print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22807{
22808 fprintf (outfile,"0x%8.8x", addr);
22809}
22810
e3c8793a 22811/* Needed by the i386 disassembler. */
dda8d76d 22812
252b5132
RH
22813void
22814db_task_printsym (unsigned int addr)
22815{
22816 print_address (addr, stderr);
22817}
22818#endif
22819
22820int
2cf0635d 22821main (int argc, char ** argv)
252b5132 22822{
ff78d6d6
L
22823 int err;
22824
87b9f255 22825#ifdef HAVE_LC_MESSAGES
252b5132 22826 setlocale (LC_MESSAGES, "");
3882b010 22827#endif
3882b010 22828 setlocale (LC_CTYPE, "");
252b5132
RH
22829 bindtextdomain (PACKAGE, LOCALEDIR);
22830 textdomain (PACKAGE);
22831
869b9d07
MM
22832 expandargv (&argc, &argv);
22833
dda8d76d 22834 parse_args (& cmdline, argc, argv);
59f14fc0 22835
18bd398b 22836 if (optind < (argc - 1))
1b513401
NC
22837 /* When displaying information for more than one file,
22838 prefix the information with the file name. */
015dc7e1 22839 show_name = true;
5656ba2c
L
22840 else if (optind >= argc)
22841 {
1b513401 22842 /* Ensure that the warning is always displayed. */
015dc7e1 22843 do_checks = true;
1b513401 22844
5656ba2c
L
22845 warn (_("Nothing to do.\n"));
22846 usage (stderr);
22847 }
18bd398b 22848
015dc7e1 22849 err = false;
252b5132 22850 while (optind < argc)
32ec8896 22851 if (! process_file (argv[optind++]))
015dc7e1 22852 err = true;
252b5132 22853
9db70fc3 22854 free (cmdline.dump_sects);
252b5132 22855
7d9813f1
NA
22856 free (dump_ctf_symtab_name);
22857 free (dump_ctf_strtab_name);
22858 free (dump_ctf_parent_name);
22859
32ec8896 22860 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22861}