]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gprofng: fix build with --disable-shared
[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"
c29aca4a 166#include "elf/xc16x.h"
f6c1a2d5 167#include "elf/xgate.h"
93fbbb04 168#include "elf/xstormy16.h"
88da6820 169#include "elf/xtensa.h"
6655dba2 170#include "elf/z80.h"
e9a0721f 171#include "elf/loongarch.h"
252b5132 172
252b5132 173#include "getopt.h"
566b0d53 174#include "libiberty.h"
09c11c86 175#include "safe-ctype.h"
2cf0635d 176#include "filenames.h"
252b5132 177
15b42fb0
AM
178#ifndef offsetof
179#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
180#endif
181
6a40cf0c
NC
182typedef struct elf_section_list
183{
dda8d76d
NC
184 Elf_Internal_Shdr * hdr;
185 struct elf_section_list * next;
6a40cf0c
NC
186} elf_section_list;
187
dda8d76d
NC
188/* Flag bits indicating particular types of dump. */
189#define HEX_DUMP (1 << 0) /* The -x command line switch. */
190#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
191#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
192#define STRING_DUMP (1 << 3) /* The -p command line switch. */
193#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 194#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
195
196typedef unsigned char dump_type;
197
198/* A linked list of the section names for which dumps were requested. */
199struct dump_list_entry
200{
201 char * name;
202 dump_type type;
203 struct dump_list_entry * next;
204};
205
6431e409
AM
206/* A dynamic array of flags indicating for which sections a dump
207 has been requested via command line switches. */
1b513401
NC
208struct dump_data
209{
6431e409
AM
210 dump_type * dump_sects;
211 unsigned int num_dump_sects;
212};
213
214static struct dump_data cmdline;
215
216static struct dump_list_entry * dump_sects_byname;
217
2cf0635d 218char * program_name = "readelf";
dda8d76d 219
015dc7e1
AM
220static bool show_name = false;
221static bool do_dynamic = false;
222static bool do_syms = false;
223static bool do_dyn_syms = false;
224static bool do_lto_syms = false;
225static bool do_reloc = false;
226static bool do_sections = false;
227static bool do_section_groups = false;
228static bool do_section_details = false;
229static bool do_segments = false;
230static bool do_unwind = false;
231static bool do_using_dynamic = false;
232static bool do_header = false;
233static bool do_dump = false;
234static bool do_version = false;
235static bool do_histogram = false;
236static bool do_debugging = false;
237static bool do_ctf = false;
238static bool do_arch = false;
239static bool do_notes = false;
240static bool do_archive_index = false;
241static bool check_all = false;
242static bool is_32bit_elf = false;
243static bool decompress_dumps = false;
244static bool do_not_show_symbol_truncation = false;
245static bool do_demangle = false; /* Pretty print C++ symbol names. */
246static bool process_links = false;
e1dbfc17 247static bool dump_any_debugging = false;
79bc120c 248static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 249static int sym_base = 0;
252b5132 250
7d9813f1
NA
251static char *dump_ctf_parent_name;
252static char *dump_ctf_symtab_name;
253static char *dump_ctf_strtab_name;
254
e4b17d5c
L
255struct group_list
256{
dda8d76d
NC
257 struct group_list * next;
258 unsigned int section_index;
e4b17d5c
L
259};
260
261struct group
262{
dda8d76d
NC
263 struct group_list * root;
264 unsigned int group_index;
e4b17d5c
L
265};
266
978c4450
AM
267typedef struct filedata
268{
269 const char * file_name;
015dc7e1 270 bool is_separate;
978c4450
AM
271 FILE * handle;
272 bfd_size_type file_size;
273 Elf_Internal_Ehdr file_header;
066f8fbe
AM
274 unsigned long archive_file_offset;
275 unsigned long archive_file_size;
276 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
277 Elf_Internal_Shdr * section_headers;
278 Elf_Internal_Phdr * program_headers;
279 char * string_table;
280 unsigned long string_table_length;
978c4450
AM
281 unsigned long dynamic_addr;
282 bfd_size_type dynamic_size;
283 size_t dynamic_nent;
284 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 285 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
286 char * dynamic_strings;
287 unsigned long dynamic_strings_length;
8ac10c5b 288 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
289 unsigned long num_dynamic_syms;
290 Elf_Internal_Sym * dynamic_symbols;
291 bfd_vma version_info[16];
292 unsigned int dynamic_syminfo_nent;
293 Elf_Internal_Syminfo * dynamic_syminfo;
294 unsigned long dynamic_syminfo_offset;
295 bfd_size_type nbuckets;
296 bfd_size_type nchains;
297 bfd_vma * buckets;
298 bfd_vma * chains;
299 bfd_size_type ngnubuckets;
300 bfd_size_type ngnuchains;
301 bfd_vma * gnubuckets;
302 bfd_vma * gnuchains;
303 bfd_vma * mipsxlat;
304 bfd_vma gnusymidx;
13acb58d 305 char * program_interpreter;
978c4450
AM
306 bfd_vma dynamic_info[DT_ENCODING];
307 bfd_vma dynamic_info_DT_GNU_HASH;
308 bfd_vma dynamic_info_DT_MIPS_XHASH;
309 elf_section_list * symtab_shndx_list;
310 size_t group_count;
311 struct group * section_groups;
312 struct group ** section_headers_groups;
313 /* A dynamic array of flags indicating for which sections a dump of
314 some kind has been requested. It is reset on a per-object file
315 basis and then initialised from the cmdline_dump_sects array,
316 the results of interpreting the -w switch, and the
317 dump_sects_byname list. */
318 struct dump_data dump;
319} Filedata;
aef1f6d0 320
c256ffe7 321/* How to print a vma value. */
843dd992
NC
322typedef enum print_mode
323{
324 HEX,
047c3dbf 325 HEX_5,
843dd992
NC
326 DEC,
327 DEC_5,
328 UNSIGNED,
047c3dbf 329 UNSIGNED_5,
843dd992 330 PREFIX_HEX,
047c3dbf 331 PREFIX_HEX_5,
843dd992 332 FULL_HEX,
047c3dbf
NL
333 LONG_HEX,
334 OCTAL,
335 OCTAL_5
843dd992
NC
336}
337print_mode;
338
b3aa80b4
NC
339typedef enum unicode_display_type
340{
341 unicode_default = 0,
342 unicode_locale,
343 unicode_escape,
344 unicode_hex,
345 unicode_highlight,
346 unicode_invalid
347} unicode_display_type;
348
349static unicode_display_type unicode_display = unicode_default;
350
a7fd1186
FS
351typedef enum
352{
353 reltype_unknown,
354 reltype_rel,
355 reltype_rela,
356 reltype_relr
357} relocation_type;
358
bb4d2ac2
L
359/* Versioned symbol info. */
360enum versioned_symbol_info
361{
362 symbol_undefined,
363 symbol_hidden,
364 symbol_public
365};
366
32ec8896 367static const char * get_symbol_version_string
015dc7e1 368 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 369 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 370
9c19a809
NC
371#define UNKNOWN -1
372
84714f86
AM
373static inline const char *
374section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
375{
376 return filedata->string_table + hdr->sh_name;
377}
b9e920ec 378
84714f86
AM
379static inline bool
380section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
381{
382 return (hdr != NULL
383 && filedata->string_table != NULL
384 && hdr->sh_name < filedata->string_table_length);
385}
b9e920ec 386
84714f86
AM
387static inline const char *
388section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
389{
390 if (hdr == NULL)
391 return _("<none>");
392 if (filedata->string_table == NULL)
393 return _("<no-strings>");
394 if (hdr->sh_name >= filedata->string_table_length)
395 return _("<corrupt>");
396 return section_name (filedata, hdr);
397}
252b5132 398
ee42cf8c 399#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 400
84714f86
AM
401static inline bool
402valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
403{
404 return strtab != NULL && offset < strtab_size;
405}
406
407static inline bool
408valid_dynamic_name (const Filedata *filedata, uint64_t offset)
409{
410 return valid_symbol_name (filedata->dynamic_strings,
411 filedata->dynamic_strings_length, offset);
412}
413
d79b3d50
NC
414/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
415 already been called and verified that the string exists. */
84714f86
AM
416static inline const char *
417get_dynamic_name (const Filedata *filedata, size_t offset)
418{
419 return filedata->dynamic_strings + offset;
420}
18bd398b 421
61865e30
NC
422#define REMOVE_ARCH_BITS(ADDR) \
423 do \
424 { \
dda8d76d 425 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
426 (ADDR) &= ~1; \
427 } \
428 while (0)
f16a9783
MS
429
430/* Get the correct GNU hash section name. */
978c4450
AM
431#define GNU_HASH_SECTION_NAME(filedata) \
432 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 433\f
66cfc0fd
AM
434/* Print a BFD_VMA to an internal buffer, for use in error messages.
435 BFD_FMA_FMT can't be used in translated strings. */
436
437static const char *
438bfd_vmatoa (char *fmtch, bfd_vma value)
439{
440 /* bfd_vmatoa is used more then once in a printf call for output.
441 Cycle through an array of buffers. */
442 static int buf_pos = 0;
443 static struct bfd_vmatoa_buf
444 {
445 char place[64];
446 } buf[4];
447 char *ret;
448 char fmt[32];
449
450 ret = buf[buf_pos++].place;
451 buf_pos %= ARRAY_SIZE (buf);
452
453 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
454 snprintf (ret, sizeof (buf[0].place), fmt, value);
455 return ret;
456}
457
dda8d76d
NC
458/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
459 OFFSET + the offset of the current archive member, if we are examining an
460 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
461 allocate a buffer using malloc and fill that. In either case return the
462 pointer to the start of the retrieved data or NULL if something went wrong.
463 If something does go wrong and REASON is not NULL then emit an error
464 message using REASON as part of the context. */
59245841 465
c256ffe7 466static void *
dda8d76d
NC
467get_data (void * var,
468 Filedata * filedata,
469 unsigned long offset,
470 bfd_size_type size,
471 bfd_size_type nmemb,
472 const char * reason)
a6e9f9df 473{
2cf0635d 474 void * mvar;
57028622 475 bfd_size_type amt = size * nmemb;
a6e9f9df 476
c256ffe7 477 if (size == 0 || nmemb == 0)
a6e9f9df
AM
478 return NULL;
479
57028622
NC
480 /* If the size_t type is smaller than the bfd_size_type, eg because
481 you are building a 32-bit tool on a 64-bit host, then make sure
482 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
483 if ((size_t) size != size
484 || (size_t) nmemb != nmemb
485 || (size_t) amt != amt)
57028622
NC
486 {
487 if (reason)
66cfc0fd
AM
488 error (_("Size truncation prevents reading %s"
489 " elements of size %s for %s\n"),
490 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
491 return NULL;
492 }
493
494 /* Check for size overflow. */
7c1c1904 495 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
496 {
497 if (reason)
66cfc0fd
AM
498 error (_("Size overflow prevents reading %s"
499 " elements of size %s for %s\n"),
500 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
501 return NULL;
502 }
503
c22b42ce 504 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 505 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
506 if (filedata->archive_file_offset > filedata->file_size
507 || offset > filedata->file_size - filedata->archive_file_offset
508 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 509 {
049b0c3a 510 if (reason)
66cfc0fd
AM
511 error (_("Reading %s bytes extends past end of file for %s\n"),
512 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
513 return NULL;
514 }
515
978c4450
AM
516 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
517 SEEK_SET))
071436c6
NC
518 {
519 if (reason)
c9c1d674 520 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 521 filedata->archive_file_offset + offset, reason);
071436c6
NC
522 return NULL;
523 }
524
a6e9f9df
AM
525 mvar = var;
526 if (mvar == NULL)
527 {
7c1c1904
AM
528 /* + 1 so that we can '\0' terminate invalid string table sections. */
529 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
530
531 if (mvar == NULL)
532 {
049b0c3a 533 if (reason)
66cfc0fd
AM
534 error (_("Out of memory allocating %s bytes for %s\n"),
535 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
536 return NULL;
537 }
c256ffe7 538
c9c1d674 539 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
540 }
541
dda8d76d 542 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 543 {
049b0c3a 544 if (reason)
66cfc0fd
AM
545 error (_("Unable to read in %s bytes of %s\n"),
546 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
547 if (mvar != var)
548 free (mvar);
549 return NULL;
550 }
551
552 return mvar;
553}
554
32ec8896
NC
555/* Print a VMA value in the MODE specified.
556 Returns the number of characters displayed. */
cb8f3167 557
32ec8896 558static unsigned int
14a91970 559print_vma (bfd_vma vma, print_mode mode)
66543521 560{
32ec8896 561 unsigned int nc = 0;
66543521 562
14a91970 563 switch (mode)
66543521 564 {
14a91970
AM
565 case FULL_HEX:
566 nc = printf ("0x");
1a0670f3 567 /* Fall through. */
14a91970 568 case LONG_HEX:
f7a99963 569#ifdef BFD64
14a91970 570 if (is_32bit_elf)
437c2fb7 571 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 572#endif
14a91970
AM
573 printf_vma (vma);
574 return nc + 16;
b19aac67 575
14a91970
AM
576 case DEC_5:
577 if (vma <= 99999)
578 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 579 /* Fall through. */
14a91970
AM
580 case PREFIX_HEX:
581 nc = printf ("0x");
1a0670f3 582 /* Fall through. */
14a91970
AM
583 case HEX:
584 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 585
047c3dbf
NL
586 case PREFIX_HEX_5:
587 nc = printf ("0x");
588 /* Fall through. */
589 case HEX_5:
590 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
591
14a91970
AM
592 case DEC:
593 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 594
14a91970
AM
595 case UNSIGNED:
596 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 597
047c3dbf
NL
598 case UNSIGNED_5:
599 return printf ("%5" BFD_VMA_FMT "u", vma);
600
601 case OCTAL:
602 return printf ("%" BFD_VMA_FMT "o", vma);
603
604 case OCTAL_5:
605 return printf ("%5" BFD_VMA_FMT "o", vma);
606
32ec8896
NC
607 default:
608 /* FIXME: Report unrecognised mode ? */
609 return 0;
f7a99963 610 }
f7a99963
NC
611}
612
047c3dbf 613
7bfd842d 614/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 615 multibye characters (assuming the host environment supports them).
31104126 616
7bfd842d
NC
617 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
618
0942c7ab
NC
619 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
620 abs(WIDTH) - 5 characters followed by "[...]".
621
7bfd842d
NC
622 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
623 padding as necessary.
171191ba
NC
624
625 Returns the number of emitted characters. */
626
627static unsigned int
0942c7ab 628print_symbol (signed int width, const char * symbol)
31104126 629{
015dc7e1
AM
630 bool extra_padding = false;
631 bool do_dots = false;
32ec8896 632 signed int num_printed = 0;
3bfcb652 633#ifdef HAVE_MBSTATE_T
7bfd842d 634 mbstate_t state;
3bfcb652 635#endif
32ec8896 636 unsigned int width_remaining;
79bc120c 637 const void * alloced_symbol = NULL;
961c521f 638
7bfd842d 639 if (width < 0)
961c521f 640 {
88305e1b 641 /* Keep the width positive. This helps the code below. */
961c521f 642 width = - width;
015dc7e1 643 extra_padding = true;
0b4362b0 644 }
56d8f8a9
NC
645 else if (width == 0)
646 return 0;
961c521f 647
7bfd842d
NC
648 if (do_wide)
649 /* Set the remaining width to a very large value.
650 This simplifies the code below. */
651 width_remaining = INT_MAX;
652 else
0942c7ab
NC
653 {
654 width_remaining = width;
655 if (! do_not_show_symbol_truncation
656 && (int) strlen (symbol) > width)
657 {
658 width_remaining -= 5;
659 if ((int) width_remaining < 0)
660 width_remaining = 0;
015dc7e1 661 do_dots = true;
0942c7ab
NC
662 }
663 }
cb8f3167 664
3bfcb652 665#ifdef HAVE_MBSTATE_T
7bfd842d
NC
666 /* Initialise the multibyte conversion state. */
667 memset (& state, 0, sizeof (state));
3bfcb652 668#endif
961c521f 669
79bc120c
NC
670 if (do_demangle && *symbol)
671 {
672 const char * res = cplus_demangle (symbol, demangle_flags);
673
674 if (res != NULL)
675 alloced_symbol = symbol = res;
676 }
677
7bfd842d
NC
678 while (width_remaining)
679 {
680 size_t n;
7bfd842d 681 const char c = *symbol++;
961c521f 682
7bfd842d 683 if (c == 0)
961c521f
NC
684 break;
685
b3aa80b4
NC
686 if (ISPRINT (c))
687 {
688 putchar (c);
689 width_remaining --;
690 num_printed ++;
691 }
692 else if (ISCNTRL (c))
961c521f 693 {
b3aa80b4
NC
694 /* Do not print control characters directly as they can affect terminal
695 settings. Such characters usually appear in the names generated
696 by the assembler for local labels. */
697
7bfd842d 698 if (width_remaining < 2)
961c521f
NC
699 break;
700
7bfd842d
NC
701 printf ("^%c", c + 0x40);
702 width_remaining -= 2;
171191ba 703 num_printed += 2;
961c521f 704 }
b3aa80b4 705 else if (c == 0x7f)
7bfd842d 706 {
b3aa80b4
NC
707 if (width_remaining < 5)
708 break;
709 printf ("<DEL>");
710 width_remaining -= 5;
711 num_printed += 5;
712 }
713 else if (unicode_display != unicode_locale
714 && unicode_display != unicode_default)
715 {
716 /* Display unicode characters as something else. */
717 unsigned char bytes[4];
718 bool is_utf8;
795588ae 719 unsigned int nbytes;
b3aa80b4
NC
720
721 bytes[0] = c;
722
723 if (bytes[0] < 0xc0)
724 {
725 nbytes = 1;
726 is_utf8 = false;
727 }
728 else
729 {
730 bytes[1] = *symbol++;
731
732 if ((bytes[1] & 0xc0) != 0x80)
733 {
734 is_utf8 = false;
735 /* Do not consume this character. It may only
736 be the first byte in the sequence that was
737 corrupt. */
738 --symbol;
739 nbytes = 1;
740 }
741 else if ((bytes[0] & 0x20) == 0)
742 {
743 is_utf8 = true;
744 nbytes = 2;
745 }
746 else
747 {
748 bytes[2] = *symbol++;
749
750 if ((bytes[2] & 0xc0) != 0x80)
751 {
752 is_utf8 = false;
753 symbol -= 2;
754 nbytes = 1;
755 }
756 else if ((bytes[0] & 0x10) == 0)
757 {
758 is_utf8 = true;
759 nbytes = 3;
760 }
761 else
762 {
763 bytes[3] = *symbol++;
764
765 nbytes = 4;
766
767 if ((bytes[3] & 0xc0) != 0x80)
768 {
769 is_utf8 = false;
770 symbol -= 3;
771 nbytes = 1;
772 }
773 else
774 is_utf8 = true;
775 }
776 }
777 }
778
779 if (unicode_display == unicode_invalid)
780 is_utf8 = false;
781
782 if (unicode_display == unicode_hex || ! is_utf8)
783 {
795588ae 784 unsigned int i;
b3aa80b4
NC
785
786 if (width_remaining < (nbytes * 2) + 2)
787 break;
788
789 putchar (is_utf8 ? '<' : '{');
790 printf ("0x");
791 for (i = 0; i < nbytes; i++)
792 printf ("%02x", bytes[i]);
793 putchar (is_utf8 ? '>' : '}');
794 }
795 else
796 {
797 if (unicode_display == unicode_highlight && isatty (1))
798 printf ("\x1B[31;47m"); /* Red. */
799
800 switch (nbytes)
801 {
802 case 2:
803 if (width_remaining < 6)
804 break;
805 printf ("\\u%02x%02x",
806 (bytes[0] & 0x1c) >> 2,
807 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
808 break;
809 case 3:
810 if (width_remaining < 6)
811 break;
812 printf ("\\u%02x%02x",
813 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
814 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
815 break;
816 case 4:
817 if (width_remaining < 8)
818 break;
819 printf ("\\u%02x%02x%02x",
820 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
821 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
822 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
823
824 break;
825 default:
826 /* URG. */
827 break;
828 }
829
830 if (unicode_display == unicode_highlight && isatty (1))
831 printf ("\033[0m"); /* Default colour. */
832 }
833
834 if (bytes[nbytes - 1] == 0)
835 break;
7bfd842d 836 }
961c521f
NC
837 else
838 {
3bfcb652
NC
839#ifdef HAVE_MBSTATE_T
840 wchar_t w;
841#endif
7bfd842d
NC
842 /* Let printf do the hard work of displaying multibyte characters. */
843 printf ("%.1s", symbol - 1);
844 width_remaining --;
845 num_printed ++;
846
3bfcb652 847#ifdef HAVE_MBSTATE_T
7bfd842d
NC
848 /* Try to find out how many bytes made up the character that was
849 just printed. Advance the symbol pointer past the bytes that
850 were displayed. */
851 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
852#else
853 n = 1;
854#endif
7bfd842d
NC
855 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
856 symbol += (n - 1);
961c521f 857 }
961c521f 858 }
171191ba 859
0942c7ab
NC
860 if (do_dots)
861 num_printed += printf ("[...]");
862
7bfd842d 863 if (extra_padding && num_printed < width)
171191ba
NC
864 {
865 /* Fill in the remaining spaces. */
7bfd842d
NC
866 printf ("%-*s", width - num_printed, " ");
867 num_printed = width;
171191ba
NC
868 }
869
79bc120c 870 free ((void *) alloced_symbol);
171191ba 871 return num_printed;
31104126
NC
872}
873
1449284b 874/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
875 the given section's name. Like print_symbol, except that it does not try
876 to print multibyte characters, it just interprets them as hex values. */
877
878static const char *
dda8d76d 879printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 880{
ca0e11aa 881#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 882 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 883 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
884 char * buf = sec_name_buf;
885 char c;
886 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
887
888 while ((c = * name ++) != 0)
889 {
890 if (ISCNTRL (c))
891 {
892 if (remaining < 2)
893 break;
948f632f 894
74e1a04b
NC
895 * buf ++ = '^';
896 * buf ++ = c + 0x40;
897 remaining -= 2;
898 }
899 else if (ISPRINT (c))
900 {
901 * buf ++ = c;
902 remaining -= 1;
903 }
904 else
905 {
906 static char hex[17] = "0123456789ABCDEF";
907
908 if (remaining < 4)
909 break;
910 * buf ++ = '<';
911 * buf ++ = hex[(c & 0xf0) >> 4];
912 * buf ++ = hex[c & 0x0f];
913 * buf ++ = '>';
914 remaining -= 4;
915 }
916
917 if (remaining == 0)
918 break;
919 }
920
921 * buf = 0;
922 return sec_name_buf;
923}
924
925static const char *
dda8d76d 926printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 927{
dda8d76d 928 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
929 return _("<corrupt>");
930
dda8d76d 931 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
932}
933
89fac5e3
RS
934/* Return a pointer to section NAME, or NULL if no such section exists. */
935
936static Elf_Internal_Shdr *
dda8d76d 937find_section (Filedata * filedata, const char * name)
89fac5e3
RS
938{
939 unsigned int i;
940
68807c3c
NC
941 if (filedata->section_headers == NULL)
942 return NULL;
dda8d76d
NC
943
944 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
945 if (section_name_valid (filedata, filedata->section_headers + i)
946 && streq (section_name (filedata, filedata->section_headers + i),
947 name))
dda8d76d 948 return filedata->section_headers + i;
89fac5e3
RS
949
950 return NULL;
951}
952
0b6ae522
DJ
953/* Return a pointer to a section containing ADDR, or NULL if no such
954 section exists. */
955
956static Elf_Internal_Shdr *
dda8d76d 957find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
958{
959 unsigned int i;
960
68807c3c
NC
961 if (filedata->section_headers == NULL)
962 return NULL;
963
dda8d76d 964 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 965 {
dda8d76d
NC
966 Elf_Internal_Shdr *sec = filedata->section_headers + i;
967
0b6ae522
DJ
968 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
969 return sec;
970 }
971
972 return NULL;
973}
974
071436c6 975static Elf_Internal_Shdr *
dda8d76d 976find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
977{
978 unsigned int i;
979
68807c3c
NC
980 if (filedata->section_headers == NULL)
981 return NULL;
982
dda8d76d 983 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 984 {
dda8d76d
NC
985 Elf_Internal_Shdr *sec = filedata->section_headers + i;
986
071436c6
NC
987 if (sec->sh_type == type)
988 return sec;
989 }
990
991 return NULL;
992}
993
657d0d47
CC
994/* Return a pointer to section NAME, or NULL if no such section exists,
995 restricted to the list of sections given in SET. */
996
997static Elf_Internal_Shdr *
dda8d76d 998find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
999{
1000 unsigned int i;
1001
68807c3c
NC
1002 if (filedata->section_headers == NULL)
1003 return NULL;
1004
657d0d47
CC
1005 if (set != NULL)
1006 {
1007 while ((i = *set++) > 0)
b814a36d
NC
1008 {
1009 /* See PR 21156 for a reproducer. */
dda8d76d 1010 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1011 continue; /* FIXME: Should we issue an error message ? */
1012
84714f86
AM
1013 if (section_name_valid (filedata, filedata->section_headers + i)
1014 && streq (section_name (filedata, filedata->section_headers + i),
1015 name))
dda8d76d 1016 return filedata->section_headers + i;
b814a36d 1017 }
657d0d47
CC
1018 }
1019
dda8d76d 1020 return find_section (filedata, name);
657d0d47
CC
1021}
1022
32ec8896 1023/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1024 This OS has so many departures from the ELF standard that we test it at
1025 many places. */
1026
015dc7e1 1027static inline bool
dda8d76d 1028is_ia64_vms (Filedata * filedata)
28f997cf 1029{
dda8d76d
NC
1030 return filedata->file_header.e_machine == EM_IA_64
1031 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1032}
1033
bcedfee6 1034/* Guess the relocation size commonly used by the specific machines. */
252b5132 1035
015dc7e1 1036static bool
2dc4cec1 1037guess_is_rela (unsigned int e_machine)
252b5132 1038{
9c19a809 1039 switch (e_machine)
252b5132
RH
1040 {
1041 /* Targets that use REL relocations. */
252b5132 1042 case EM_386:
22abe556 1043 case EM_IAMCU:
f954747f 1044 case EM_960:
e9f53129 1045 case EM_ARM:
2b0337b0 1046 case EM_D10V:
252b5132 1047 case EM_CYGNUS_D10V:
e9f53129 1048 case EM_DLX:
252b5132 1049 case EM_MIPS:
4fe85591 1050 case EM_MIPS_RS3_LE:
e9f53129 1051 case EM_CYGNUS_M32R:
1c0d3aa6 1052 case EM_SCORE:
f6c1a2d5 1053 case EM_XGATE:
fe944acf 1054 case EM_NFP:
aca4efc7 1055 case EM_BPF:
015dc7e1 1056 return false;
103f02d3 1057
252b5132
RH
1058 /* Targets that use RELA relocations. */
1059 case EM_68K:
f954747f 1060 case EM_860:
a06ea964 1061 case EM_AARCH64:
cfb8c092 1062 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1063 case EM_ALPHA:
1064 case EM_ALTERA_NIOS2:
886a2506
NC
1065 case EM_ARC:
1066 case EM_ARC_COMPACT:
1067 case EM_ARC_COMPACT2:
e9f53129
AM
1068 case EM_AVR:
1069 case EM_AVR_OLD:
1070 case EM_BLACKFIN:
60bca95a 1071 case EM_CR16:
e9f53129
AM
1072 case EM_CRIS:
1073 case EM_CRX:
b8891f8d 1074 case EM_CSKY:
2b0337b0 1075 case EM_D30V:
252b5132 1076 case EM_CYGNUS_D30V:
2b0337b0 1077 case EM_FR30:
3f8107ab 1078 case EM_FT32:
252b5132 1079 case EM_CYGNUS_FR30:
5c70f934 1080 case EM_CYGNUS_FRV:
e9f53129
AM
1081 case EM_H8S:
1082 case EM_H8_300:
1083 case EM_H8_300H:
800eeca4 1084 case EM_IA_64:
1e4cf259
NC
1085 case EM_IP2K:
1086 case EM_IP2K_OLD:
3b36097d 1087 case EM_IQ2000:
84e94c90 1088 case EM_LATTICEMICO32:
ff7eeb89 1089 case EM_M32C_OLD:
49f58d10 1090 case EM_M32C:
e9f53129
AM
1091 case EM_M32R:
1092 case EM_MCORE:
15ab5209 1093 case EM_CYGNUS_MEP:
a3c62988 1094 case EM_METAG:
e9f53129
AM
1095 case EM_MMIX:
1096 case EM_MN10200:
1097 case EM_CYGNUS_MN10200:
1098 case EM_MN10300:
1099 case EM_CYGNUS_MN10300:
5506d11a 1100 case EM_MOXIE:
e9f53129
AM
1101 case EM_MSP430:
1102 case EM_MSP430_OLD:
d031aafb 1103 case EM_MT:
35c08157 1104 case EM_NDS32:
64fd6348 1105 case EM_NIOS32:
73589c9d 1106 case EM_OR1K:
e9f53129
AM
1107 case EM_PPC64:
1108 case EM_PPC:
2b100bb5 1109 case EM_TI_PRU:
e23eba97 1110 case EM_RISCV:
99c513f6 1111 case EM_RL78:
c7927a3c 1112 case EM_RX:
e9f53129
AM
1113 case EM_S390:
1114 case EM_S390_OLD:
1115 case EM_SH:
1116 case EM_SPARC:
1117 case EM_SPARC32PLUS:
1118 case EM_SPARCV9:
1119 case EM_SPU:
40b36596 1120 case EM_TI_C6000:
aa137e4d
NC
1121 case EM_TILEGX:
1122 case EM_TILEPRO:
708e2187 1123 case EM_V800:
e9f53129
AM
1124 case EM_V850:
1125 case EM_CYGNUS_V850:
1126 case EM_VAX:
619ed720 1127 case EM_VISIUM:
e9f53129 1128 case EM_X86_64:
8a9036a4 1129 case EM_L1OM:
7a9068fe 1130 case EM_K1OM:
e9f53129
AM
1131 case EM_XSTORMY16:
1132 case EM_XTENSA:
1133 case EM_XTENSA_OLD:
7ba29e2a
NC
1134 case EM_MICROBLAZE:
1135 case EM_MICROBLAZE_OLD:
f96bd6c2 1136 case EM_WEBASSEMBLY:
015dc7e1 1137 return true;
103f02d3 1138
e9f53129
AM
1139 case EM_68HC05:
1140 case EM_68HC08:
1141 case EM_68HC11:
1142 case EM_68HC16:
1143 case EM_FX66:
1144 case EM_ME16:
d1133906 1145 case EM_MMA:
d1133906
NC
1146 case EM_NCPU:
1147 case EM_NDR1:
e9f53129 1148 case EM_PCP:
d1133906 1149 case EM_ST100:
e9f53129 1150 case EM_ST19:
d1133906 1151 case EM_ST7:
e9f53129
AM
1152 case EM_ST9PLUS:
1153 case EM_STARCORE:
d1133906 1154 case EM_SVX:
e9f53129 1155 case EM_TINYJ:
9c19a809
NC
1156 default:
1157 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1158 return false;
9c19a809
NC
1159 }
1160}
252b5132 1161
dda8d76d 1162/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1163 Returns TRUE upon success, FALSE otherwise. If successful then a
1164 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1165 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1166 responsibility to free the allocated buffer. */
1167
015dc7e1 1168static bool
dda8d76d
NC
1169slurp_rela_relocs (Filedata * filedata,
1170 unsigned long rel_offset,
1171 unsigned long rel_size,
1172 Elf_Internal_Rela ** relasp,
1173 unsigned long * nrelasp)
9c19a809 1174{
2cf0635d 1175 Elf_Internal_Rela * relas;
8b73c356 1176 size_t nrelas;
4d6ed7c8 1177 unsigned int i;
252b5132 1178
4d6ed7c8
NC
1179 if (is_32bit_elf)
1180 {
2cf0635d 1181 Elf32_External_Rela * erelas;
103f02d3 1182
dda8d76d 1183 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1184 rel_size, _("32-bit relocation data"));
a6e9f9df 1185 if (!erelas)
015dc7e1 1186 return false;
252b5132 1187
4d6ed7c8 1188 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1189
3f5e193b
NC
1190 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1191 sizeof (Elf_Internal_Rela));
103f02d3 1192
4d6ed7c8
NC
1193 if (relas == NULL)
1194 {
c256ffe7 1195 free (erelas);
591a748a 1196 error (_("out of memory parsing relocs\n"));
015dc7e1 1197 return false;
4d6ed7c8 1198 }
103f02d3 1199
4d6ed7c8
NC
1200 for (i = 0; i < nrelas; i++)
1201 {
1202 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1203 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1204 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1205 }
103f02d3 1206
4d6ed7c8
NC
1207 free (erelas);
1208 }
1209 else
1210 {
2cf0635d 1211 Elf64_External_Rela * erelas;
103f02d3 1212
dda8d76d 1213 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1214 rel_size, _("64-bit relocation data"));
a6e9f9df 1215 if (!erelas)
015dc7e1 1216 return false;
4d6ed7c8
NC
1217
1218 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1219
3f5e193b
NC
1220 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1221 sizeof (Elf_Internal_Rela));
103f02d3 1222
4d6ed7c8
NC
1223 if (relas == NULL)
1224 {
c256ffe7 1225 free (erelas);
591a748a 1226 error (_("out of memory parsing relocs\n"));
015dc7e1 1227 return false;
9c19a809 1228 }
4d6ed7c8
NC
1229
1230 for (i = 0; i < nrelas; i++)
9c19a809 1231 {
66543521
AM
1232 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1233 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1234 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1235
1236 /* The #ifdef BFD64 below is to prevent a compile time
1237 warning. We know that if we do not have a 64 bit data
1238 type that we will never execute this code anyway. */
1239#ifdef BFD64
dda8d76d
NC
1240 if (filedata->file_header.e_machine == EM_MIPS
1241 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1242 {
1243 /* In little-endian objects, r_info isn't really a
1244 64-bit little-endian value: it has a 32-bit
1245 little-endian symbol index followed by four
1246 individual byte fields. Reorder INFO
1247 accordingly. */
91d6fa6a
NC
1248 bfd_vma inf = relas[i].r_info;
1249 inf = (((inf & 0xffffffff) << 32)
1250 | ((inf >> 56) & 0xff)
1251 | ((inf >> 40) & 0xff00)
1252 | ((inf >> 24) & 0xff0000)
1253 | ((inf >> 8) & 0xff000000));
1254 relas[i].r_info = inf;
861fb55a
DJ
1255 }
1256#endif /* BFD64 */
4d6ed7c8 1257 }
103f02d3 1258
4d6ed7c8
NC
1259 free (erelas);
1260 }
32ec8896 1261
4d6ed7c8
NC
1262 *relasp = relas;
1263 *nrelasp = nrelas;
015dc7e1 1264 return true;
4d6ed7c8 1265}
103f02d3 1266
dda8d76d 1267/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1268 Returns TRUE upon success, FALSE otherwise. If successful then a
1269 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1270 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1271 responsibility to free the allocated buffer. */
1272
015dc7e1 1273static bool
dda8d76d
NC
1274slurp_rel_relocs (Filedata * filedata,
1275 unsigned long rel_offset,
1276 unsigned long rel_size,
1277 Elf_Internal_Rela ** relsp,
1278 unsigned long * nrelsp)
4d6ed7c8 1279{
2cf0635d 1280 Elf_Internal_Rela * rels;
8b73c356 1281 size_t nrels;
4d6ed7c8 1282 unsigned int i;
103f02d3 1283
4d6ed7c8
NC
1284 if (is_32bit_elf)
1285 {
2cf0635d 1286 Elf32_External_Rel * erels;
103f02d3 1287
dda8d76d 1288 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1289 rel_size, _("32-bit relocation data"));
a6e9f9df 1290 if (!erels)
015dc7e1 1291 return false;
103f02d3 1292
4d6ed7c8 1293 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1294
3f5e193b 1295 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1296
4d6ed7c8
NC
1297 if (rels == NULL)
1298 {
c256ffe7 1299 free (erels);
591a748a 1300 error (_("out of memory parsing relocs\n"));
015dc7e1 1301 return false;
4d6ed7c8
NC
1302 }
1303
1304 for (i = 0; i < nrels; i++)
1305 {
1306 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1307 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1308 rels[i].r_addend = 0;
9ea033b2 1309 }
4d6ed7c8
NC
1310
1311 free (erels);
9c19a809
NC
1312 }
1313 else
1314 {
2cf0635d 1315 Elf64_External_Rel * erels;
9ea033b2 1316
dda8d76d 1317 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1318 rel_size, _("64-bit relocation data"));
a6e9f9df 1319 if (!erels)
015dc7e1 1320 return false;
103f02d3 1321
4d6ed7c8 1322 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1323
3f5e193b 1324 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1325
4d6ed7c8 1326 if (rels == NULL)
9c19a809 1327 {
c256ffe7 1328 free (erels);
591a748a 1329 error (_("out of memory parsing relocs\n"));
015dc7e1 1330 return false;
4d6ed7c8 1331 }
103f02d3 1332
4d6ed7c8
NC
1333 for (i = 0; i < nrels; i++)
1334 {
66543521
AM
1335 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1336 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1337 rels[i].r_addend = 0;
861fb55a
DJ
1338
1339 /* The #ifdef BFD64 below is to prevent a compile time
1340 warning. We know that if we do not have a 64 bit data
1341 type that we will never execute this code anyway. */
1342#ifdef BFD64
dda8d76d
NC
1343 if (filedata->file_header.e_machine == EM_MIPS
1344 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1345 {
1346 /* In little-endian objects, r_info isn't really a
1347 64-bit little-endian value: it has a 32-bit
1348 little-endian symbol index followed by four
1349 individual byte fields. Reorder INFO
1350 accordingly. */
91d6fa6a
NC
1351 bfd_vma inf = rels[i].r_info;
1352 inf = (((inf & 0xffffffff) << 32)
1353 | ((inf >> 56) & 0xff)
1354 | ((inf >> 40) & 0xff00)
1355 | ((inf >> 24) & 0xff0000)
1356 | ((inf >> 8) & 0xff000000));
1357 rels[i].r_info = inf;
861fb55a
DJ
1358 }
1359#endif /* BFD64 */
4d6ed7c8 1360 }
103f02d3 1361
4d6ed7c8
NC
1362 free (erels);
1363 }
32ec8896 1364
4d6ed7c8
NC
1365 *relsp = rels;
1366 *nrelsp = nrels;
015dc7e1 1367 return true;
4d6ed7c8 1368}
103f02d3 1369
a7fd1186
FS
1370static bool
1371slurp_relr_relocs (Filedata * filedata,
1372 unsigned long relr_offset,
1373 unsigned long relr_size,
1374 bfd_vma ** relrsp,
1375 unsigned long * nrelrsp)
1376{
1377 void *relrs;
1378 size_t size = 0, nentries, i;
1379 bfd_vma base = 0, addr, entry;
1380
1381 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1382 _("RELR relocation data"));
1383 if (!relrs)
1384 return false;
1385
1386 if (is_32bit_elf)
1387 nentries = relr_size / sizeof (Elf32_External_Relr);
1388 else
1389 nentries = relr_size / sizeof (Elf64_External_Relr);
1390 for (i = 0; i < nentries; i++)
1391 {
1392 if (is_32bit_elf)
1393 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1394 else
1395 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1396 if ((entry & 1) == 0)
1397 size++;
1398 else
1399 while ((entry >>= 1) != 0)
1400 if ((entry & 1) == 1)
1401 size++;
1402 }
1403
1404 *relrsp = (bfd_vma *) xmalloc (size * sizeof (bfd_vma));
1405 if (*relrsp == NULL)
1406 {
1407 free (relrs);
1408 error (_("out of memory parsing relocs\n"));
1409 return false;
1410 }
1411
1412 size = 0;
1413 for (i = 0; i < nentries; i++)
1414 {
1415 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1416
1417 if (is_32bit_elf)
1418 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1419 else
1420 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1421 if ((entry & 1) == 0)
1422 {
1423 (*relrsp)[size++] = entry;
1424 base = entry + entry_bytes;
1425 }
1426 else
1427 {
1428 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1429 if ((entry & 1) != 0)
1430 (*relrsp)[size++] = addr;
1431 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1432 }
1433 }
1434
1435 *nrelrsp = size;
1436 free (relrs);
1437 return true;
1438}
1439
aca88567
NC
1440/* Returns the reloc type extracted from the reloc info field. */
1441
1442static unsigned int
dda8d76d 1443get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1444{
1445 if (is_32bit_elf)
1446 return ELF32_R_TYPE (reloc_info);
1447
dda8d76d 1448 switch (filedata->file_header.e_machine)
aca88567
NC
1449 {
1450 case EM_MIPS:
1451 /* Note: We assume that reloc_info has already been adjusted for us. */
1452 return ELF64_MIPS_R_TYPE (reloc_info);
1453
1454 case EM_SPARCV9:
1455 return ELF64_R_TYPE_ID (reloc_info);
1456
1457 default:
1458 return ELF64_R_TYPE (reloc_info);
1459 }
1460}
1461
1462/* Return the symbol index extracted from the reloc info field. */
1463
1464static bfd_vma
1465get_reloc_symindex (bfd_vma reloc_info)
1466{
1467 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1468}
1469
015dc7e1 1470static inline bool
dda8d76d 1471uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1472{
1473 return
dda8d76d 1474 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1475 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1476 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1477 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1478 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1479}
1480
d3ba0551
AM
1481/* Display the contents of the relocation data found at the specified
1482 offset. */
ee42cf8c 1483
015dc7e1 1484static bool
dda8d76d
NC
1485dump_relocations (Filedata * filedata,
1486 unsigned long rel_offset,
1487 unsigned long rel_size,
1488 Elf_Internal_Sym * symtab,
1489 unsigned long nsyms,
1490 char * strtab,
1491 unsigned long strtablen,
a7fd1186 1492 relocation_type rel_type,
015dc7e1 1493 bool is_dynsym)
4d6ed7c8 1494{
32ec8896 1495 unsigned long i;
2cf0635d 1496 Elf_Internal_Rela * rels;
015dc7e1 1497 bool res = true;
103f02d3 1498
a7fd1186
FS
1499 if (rel_type == reltype_unknown)
1500 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1501
a7fd1186 1502 if (rel_type == reltype_rela)
4d6ed7c8 1503 {
dda8d76d 1504 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1505 return false;
4d6ed7c8 1506 }
a7fd1186 1507 else if (rel_type == reltype_rel)
4d6ed7c8 1508 {
dda8d76d 1509 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1510 return false;
252b5132 1511 }
a7fd1186
FS
1512 else if (rel_type == reltype_relr)
1513 {
1514 bfd_vma * relrs;
1515 const char *format
1516 = is_32bit_elf ? "%08" BFD_VMA_FMT "x\n" : "%016" BFD_VMA_FMT "x\n";
1517
1518 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1519 &rel_size))
1520 return false;
1521
1522 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size), rel_size);
1523 for (i = 0; i < rel_size; i++)
1524 printf (format, relrs[i]);
1525 free (relrs);
1526 return true;
1527 }
252b5132 1528
410f7a12
L
1529 if (is_32bit_elf)
1530 {
a7fd1186 1531 if (rel_type == reltype_rela)
2c71103e
NC
1532 {
1533 if (do_wide)
1534 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1535 else
1536 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1537 }
410f7a12 1538 else
2c71103e
NC
1539 {
1540 if (do_wide)
1541 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1542 else
1543 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1544 }
410f7a12 1545 }
252b5132 1546 else
410f7a12 1547 {
a7fd1186 1548 if (rel_type == reltype_rela)
2c71103e
NC
1549 {
1550 if (do_wide)
8beeaeb7 1551 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1552 else
1553 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1554 }
410f7a12 1555 else
2c71103e
NC
1556 {
1557 if (do_wide)
8beeaeb7 1558 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1559 else
1560 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1561 }
410f7a12 1562 }
252b5132
RH
1563
1564 for (i = 0; i < rel_size; i++)
1565 {
2cf0635d 1566 const char * rtype;
b34976b6 1567 bfd_vma offset;
91d6fa6a 1568 bfd_vma inf;
b34976b6
AM
1569 bfd_vma symtab_index;
1570 bfd_vma type;
103f02d3 1571
b34976b6 1572 offset = rels[i].r_offset;
91d6fa6a 1573 inf = rels[i].r_info;
103f02d3 1574
dda8d76d 1575 type = get_reloc_type (filedata, inf);
91d6fa6a 1576 symtab_index = get_reloc_symindex (inf);
252b5132 1577
410f7a12
L
1578 if (is_32bit_elf)
1579 {
39dbeff8
AM
1580 printf ("%8.8lx %8.8lx ",
1581 (unsigned long) offset & 0xffffffff,
91d6fa6a 1582 (unsigned long) inf & 0xffffffff);
410f7a12
L
1583 }
1584 else
1585 {
39dbeff8 1586 printf (do_wide
d1ce973e
AM
1587 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1588 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1589 offset, inf);
410f7a12 1590 }
103f02d3 1591
dda8d76d 1592 switch (filedata->file_header.e_machine)
252b5132
RH
1593 {
1594 default:
1595 rtype = NULL;
1596 break;
1597
a06ea964
NC
1598 case EM_AARCH64:
1599 rtype = elf_aarch64_reloc_type (type);
1600 break;
1601
2b0337b0 1602 case EM_M32R:
252b5132 1603 case EM_CYGNUS_M32R:
9ea033b2 1604 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1605 break;
1606
1607 case EM_386:
22abe556 1608 case EM_IAMCU:
9ea033b2 1609 rtype = elf_i386_reloc_type (type);
252b5132
RH
1610 break;
1611
ba2685cc
AM
1612 case EM_68HC11:
1613 case EM_68HC12:
1614 rtype = elf_m68hc11_reloc_type (type);
1615 break;
75751cd9 1616
7b4ae824
JD
1617 case EM_S12Z:
1618 rtype = elf_s12z_reloc_type (type);
1619 break;
1620
252b5132 1621 case EM_68K:
9ea033b2 1622 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1623 break;
1624
f954747f
AM
1625 case EM_960:
1626 rtype = elf_i960_reloc_type (type);
1627 break;
1628
adde6300 1629 case EM_AVR:
2b0337b0 1630 case EM_AVR_OLD:
adde6300
AM
1631 rtype = elf_avr_reloc_type (type);
1632 break;
1633
9ea033b2
NC
1634 case EM_OLD_SPARCV9:
1635 case EM_SPARC32PLUS:
1636 case EM_SPARCV9:
252b5132 1637 case EM_SPARC:
9ea033b2 1638 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1639 break;
1640
e9f53129
AM
1641 case EM_SPU:
1642 rtype = elf_spu_reloc_type (type);
1643 break;
1644
708e2187
NC
1645 case EM_V800:
1646 rtype = v800_reloc_type (type);
1647 break;
2b0337b0 1648 case EM_V850:
252b5132 1649 case EM_CYGNUS_V850:
9ea033b2 1650 rtype = v850_reloc_type (type);
252b5132
RH
1651 break;
1652
2b0337b0 1653 case EM_D10V:
252b5132 1654 case EM_CYGNUS_D10V:
9ea033b2 1655 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1656 break;
1657
2b0337b0 1658 case EM_D30V:
252b5132 1659 case EM_CYGNUS_D30V:
9ea033b2 1660 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1661 break;
1662
d172d4ba
NC
1663 case EM_DLX:
1664 rtype = elf_dlx_reloc_type (type);
1665 break;
1666
252b5132 1667 case EM_SH:
9ea033b2 1668 rtype = elf_sh_reloc_type (type);
252b5132
RH
1669 break;
1670
2b0337b0 1671 case EM_MN10300:
252b5132 1672 case EM_CYGNUS_MN10300:
9ea033b2 1673 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1674 break;
1675
2b0337b0 1676 case EM_MN10200:
252b5132 1677 case EM_CYGNUS_MN10200:
9ea033b2 1678 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1679 break;
1680
2b0337b0 1681 case EM_FR30:
252b5132 1682 case EM_CYGNUS_FR30:
9ea033b2 1683 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1684 break;
1685
ba2685cc
AM
1686 case EM_CYGNUS_FRV:
1687 rtype = elf_frv_reloc_type (type);
1688 break;
5c70f934 1689
b8891f8d
AJ
1690 case EM_CSKY:
1691 rtype = elf_csky_reloc_type (type);
1692 break;
1693
3f8107ab
AM
1694 case EM_FT32:
1695 rtype = elf_ft32_reloc_type (type);
1696 break;
1697
252b5132 1698 case EM_MCORE:
9ea033b2 1699 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1700 break;
1701
3c3bdf30
NC
1702 case EM_MMIX:
1703 rtype = elf_mmix_reloc_type (type);
1704 break;
1705
5506d11a
AM
1706 case EM_MOXIE:
1707 rtype = elf_moxie_reloc_type (type);
1708 break;
1709
2469cfa2 1710 case EM_MSP430:
dda8d76d 1711 if (uses_msp430x_relocs (filedata))
13761a11
NC
1712 {
1713 rtype = elf_msp430x_reloc_type (type);
1714 break;
1715 }
1a0670f3 1716 /* Fall through. */
2469cfa2
NC
1717 case EM_MSP430_OLD:
1718 rtype = elf_msp430_reloc_type (type);
1719 break;
1720
35c08157
KLC
1721 case EM_NDS32:
1722 rtype = elf_nds32_reloc_type (type);
1723 break;
1724
252b5132 1725 case EM_PPC:
9ea033b2 1726 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1727 break;
1728
c833c019
AM
1729 case EM_PPC64:
1730 rtype = elf_ppc64_reloc_type (type);
1731 break;
1732
252b5132 1733 case EM_MIPS:
4fe85591 1734 case EM_MIPS_RS3_LE:
9ea033b2 1735 rtype = elf_mips_reloc_type (type);
252b5132
RH
1736 break;
1737
e23eba97
NC
1738 case EM_RISCV:
1739 rtype = elf_riscv_reloc_type (type);
1740 break;
1741
252b5132 1742 case EM_ALPHA:
9ea033b2 1743 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1744 break;
1745
1746 case EM_ARM:
9ea033b2 1747 rtype = elf_arm_reloc_type (type);
252b5132
RH
1748 break;
1749
584da044 1750 case EM_ARC:
886a2506
NC
1751 case EM_ARC_COMPACT:
1752 case EM_ARC_COMPACT2:
9ea033b2 1753 rtype = elf_arc_reloc_type (type);
252b5132
RH
1754 break;
1755
1756 case EM_PARISC:
69e617ca 1757 rtype = elf_hppa_reloc_type (type);
252b5132 1758 break;
7d466069 1759
b8720f9d
JL
1760 case EM_H8_300:
1761 case EM_H8_300H:
1762 case EM_H8S:
1763 rtype = elf_h8_reloc_type (type);
1764 break;
1765
73589c9d
CS
1766 case EM_OR1K:
1767 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1768 break;
1769
7d466069 1770 case EM_PJ:
2b0337b0 1771 case EM_PJ_OLD:
7d466069
ILT
1772 rtype = elf_pj_reloc_type (type);
1773 break;
800eeca4
JW
1774 case EM_IA_64:
1775 rtype = elf_ia64_reloc_type (type);
1776 break;
1b61cf92
HPN
1777
1778 case EM_CRIS:
1779 rtype = elf_cris_reloc_type (type);
1780 break;
535c37ff 1781
f954747f
AM
1782 case EM_860:
1783 rtype = elf_i860_reloc_type (type);
1784 break;
1785
bcedfee6 1786 case EM_X86_64:
8a9036a4 1787 case EM_L1OM:
7a9068fe 1788 case EM_K1OM:
bcedfee6
NC
1789 rtype = elf_x86_64_reloc_type (type);
1790 break;
a85d7ed0 1791
f954747f
AM
1792 case EM_S370:
1793 rtype = i370_reloc_type (type);
1794 break;
1795
53c7db4b
KH
1796 case EM_S390_OLD:
1797 case EM_S390:
1798 rtype = elf_s390_reloc_type (type);
1799 break;
93fbbb04 1800
1c0d3aa6
NC
1801 case EM_SCORE:
1802 rtype = elf_score_reloc_type (type);
1803 break;
1804
93fbbb04
GK
1805 case EM_XSTORMY16:
1806 rtype = elf_xstormy16_reloc_type (type);
1807 break;
179d3252 1808
1fe1f39c
NC
1809 case EM_CRX:
1810 rtype = elf_crx_reloc_type (type);
1811 break;
1812
179d3252
JT
1813 case EM_VAX:
1814 rtype = elf_vax_reloc_type (type);
1815 break;
1e4cf259 1816
619ed720
EB
1817 case EM_VISIUM:
1818 rtype = elf_visium_reloc_type (type);
1819 break;
1820
aca4efc7
JM
1821 case EM_BPF:
1822 rtype = elf_bpf_reloc_type (type);
1823 break;
1824
cfb8c092
NC
1825 case EM_ADAPTEVA_EPIPHANY:
1826 rtype = elf_epiphany_reloc_type (type);
1827 break;
1828
1e4cf259
NC
1829 case EM_IP2K:
1830 case EM_IP2K_OLD:
1831 rtype = elf_ip2k_reloc_type (type);
1832 break;
3b36097d
SC
1833
1834 case EM_IQ2000:
1835 rtype = elf_iq2000_reloc_type (type);
1836 break;
88da6820
NC
1837
1838 case EM_XTENSA_OLD:
1839 case EM_XTENSA:
1840 rtype = elf_xtensa_reloc_type (type);
1841 break;
a34e3ecb 1842
84e94c90
NC
1843 case EM_LATTICEMICO32:
1844 rtype = elf_lm32_reloc_type (type);
1845 break;
1846
ff7eeb89 1847 case EM_M32C_OLD:
49f58d10
JB
1848 case EM_M32C:
1849 rtype = elf_m32c_reloc_type (type);
1850 break;
1851
d031aafb
NS
1852 case EM_MT:
1853 rtype = elf_mt_reloc_type (type);
a34e3ecb 1854 break;
1d65ded4
CM
1855
1856 case EM_BLACKFIN:
1857 rtype = elf_bfin_reloc_type (type);
1858 break;
15ab5209
DB
1859
1860 case EM_CYGNUS_MEP:
1861 rtype = elf_mep_reloc_type (type);
1862 break;
60bca95a
NC
1863
1864 case EM_CR16:
1865 rtype = elf_cr16_reloc_type (type);
1866 break;
dd24e3da 1867
7ba29e2a
NC
1868 case EM_MICROBLAZE:
1869 case EM_MICROBLAZE_OLD:
1870 rtype = elf_microblaze_reloc_type (type);
1871 break;
c7927a3c 1872
99c513f6
DD
1873 case EM_RL78:
1874 rtype = elf_rl78_reloc_type (type);
1875 break;
1876
c7927a3c
NC
1877 case EM_RX:
1878 rtype = elf_rx_reloc_type (type);
1879 break;
c29aca4a 1880
a3c62988
NC
1881 case EM_METAG:
1882 rtype = elf_metag_reloc_type (type);
1883 break;
1884
c29aca4a
NC
1885 case EM_XC16X:
1886 case EM_C166:
1887 rtype = elf_xc16x_reloc_type (type);
1888 break;
40b36596
JM
1889
1890 case EM_TI_C6000:
1891 rtype = elf_tic6x_reloc_type (type);
1892 break;
aa137e4d
NC
1893
1894 case EM_TILEGX:
1895 rtype = elf_tilegx_reloc_type (type);
1896 break;
1897
1898 case EM_TILEPRO:
1899 rtype = elf_tilepro_reloc_type (type);
1900 break;
f6c1a2d5 1901
f96bd6c2
PC
1902 case EM_WEBASSEMBLY:
1903 rtype = elf_wasm32_reloc_type (type);
1904 break;
1905
f6c1a2d5
NC
1906 case EM_XGATE:
1907 rtype = elf_xgate_reloc_type (type);
1908 break;
36591ba1
SL
1909
1910 case EM_ALTERA_NIOS2:
1911 rtype = elf_nios2_reloc_type (type);
1912 break;
2b100bb5
DD
1913
1914 case EM_TI_PRU:
1915 rtype = elf_pru_reloc_type (type);
1916 break;
fe944acf
FT
1917
1918 case EM_NFP:
1919 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1920 rtype = elf_nfp3200_reloc_type (type);
1921 else
1922 rtype = elf_nfp_reloc_type (type);
1923 break;
6655dba2
SB
1924
1925 case EM_Z80:
1926 rtype = elf_z80_reloc_type (type);
1927 break;
e9a0721f 1928
1929 case EM_LOONGARCH:
1930 rtype = elf_loongarch_reloc_type (type);
1931 break;
1932
0c857ef4
SM
1933 case EM_AMDGPU:
1934 rtype = elf_amdgpu_reloc_type (type);
1935 break;
252b5132
RH
1936 }
1937
1938 if (rtype == NULL)
39dbeff8 1939 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1940 else
5c144731 1941 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1942
dda8d76d 1943 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1944 && rtype != NULL
7ace3541 1945 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1946 && rel_type == reltype_rela)
7ace3541
RH
1947 {
1948 switch (rels[i].r_addend)
1949 {
1950 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1951 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1952 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1953 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1954 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1955 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1956 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1957 default: rtype = NULL;
1958 }
32ec8896 1959
7ace3541
RH
1960 if (rtype)
1961 printf (" (%s)", rtype);
1962 else
1963 {
1964 putchar (' ');
1965 printf (_("<unknown addend: %lx>"),
1966 (unsigned long) rels[i].r_addend);
015dc7e1 1967 res = false;
7ace3541
RH
1968 }
1969 }
1970 else if (symtab_index)
252b5132 1971 {
af3fc3bc 1972 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1973 {
27a45f42
AS
1974 error (_(" bad symbol index: %08lx in reloc\n"),
1975 (unsigned long) symtab_index);
015dc7e1 1976 res = false;
32ec8896 1977 }
af3fc3bc 1978 else
19936277 1979 {
2cf0635d 1980 Elf_Internal_Sym * psym;
bb4d2ac2
L
1981 const char * version_string;
1982 enum versioned_symbol_info sym_info;
1983 unsigned short vna_other;
19936277 1984
af3fc3bc 1985 psym = symtab + symtab_index;
103f02d3 1986
bb4d2ac2 1987 version_string
dda8d76d 1988 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1989 strtab, strtablen,
1990 symtab_index,
1991 psym,
1992 &sym_info,
1993 &vna_other);
1994
af3fc3bc 1995 printf (" ");
171191ba 1996
d8045f23
NC
1997 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1998 {
1999 const char * name;
2000 unsigned int len;
2001 unsigned int width = is_32bit_elf ? 8 : 14;
2002
2003 /* Relocations against GNU_IFUNC symbols do not use the value
2004 of the symbol as the address to relocate against. Instead
2005 they invoke the function named by the symbol and use its
2006 result as the address for relocation.
2007
2008 To indicate this to the user, do not display the value of
2009 the symbol in the "Symbols's Value" field. Instead show
2010 its name followed by () as a hint that the symbol is
2011 invoked. */
2012
2013 if (strtab == NULL
2014 || psym->st_name == 0
2015 || psym->st_name >= strtablen)
2016 name = "??";
2017 else
2018 name = strtab + psym->st_name;
2019
2020 len = print_symbol (width, name);
bb4d2ac2
L
2021 if (version_string)
2022 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2023 version_string);
d8045f23
NC
2024 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2025 }
2026 else
2027 {
2028 print_vma (psym->st_value, LONG_HEX);
171191ba 2029
d8045f23
NC
2030 printf (is_32bit_elf ? " " : " ");
2031 }
103f02d3 2032
af3fc3bc 2033 if (psym->st_name == 0)
f1ef08cb 2034 {
2cf0635d 2035 const char * sec_name = "<null>";
f1ef08cb
AM
2036 char name_buf[40];
2037
2038 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2039 {
b9af6379
AM
2040 if (psym->st_shndx < filedata->file_header.e_shnum
2041 && filedata->section_headers != NULL)
84714f86
AM
2042 sec_name = section_name_print (filedata,
2043 filedata->section_headers
b9e920ec 2044 + psym->st_shndx);
f1ef08cb
AM
2045 else if (psym->st_shndx == SHN_ABS)
2046 sec_name = "ABS";
2047 else if (psym->st_shndx == SHN_COMMON)
2048 sec_name = "COMMON";
dda8d76d 2049 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2050 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2051 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2052 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2053 sec_name = "SCOMMON";
dda8d76d 2054 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2055 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2056 sec_name = "SUNDEF";
dda8d76d
NC
2057 else if ((filedata->file_header.e_machine == EM_X86_64
2058 || filedata->file_header.e_machine == EM_L1OM
2059 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2060 && psym->st_shndx == SHN_X86_64_LCOMMON)
2061 sec_name = "LARGE_COMMON";
dda8d76d
NC
2062 else if (filedata->file_header.e_machine == EM_IA_64
2063 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2064 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2065 sec_name = "ANSI_COM";
dda8d76d 2066 else if (is_ia64_vms (filedata)
148b93f2
NC
2067 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2068 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2069 else
2070 {
2071 sprintf (name_buf, "<section 0x%x>",
2072 (unsigned int) psym->st_shndx);
2073 sec_name = name_buf;
2074 }
2075 }
2076 print_symbol (22, sec_name);
2077 }
af3fc3bc 2078 else if (strtab == NULL)
d79b3d50 2079 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2080 else if (psym->st_name >= strtablen)
32ec8896 2081 {
27a45f42
AS
2082 error (_("<corrupt string table index: %3ld>\n"),
2083 psym->st_name);
015dc7e1 2084 res = false;
32ec8896 2085 }
af3fc3bc 2086 else
bb4d2ac2
L
2087 {
2088 print_symbol (22, strtab + psym->st_name);
2089 if (version_string)
2090 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2091 version_string);
2092 }
103f02d3 2093
a7fd1186 2094 if (rel_type == reltype_rela)
171191ba 2095 {
7360e63f 2096 bfd_vma off = rels[i].r_addend;
171191ba 2097
7360e63f 2098 if ((bfd_signed_vma) off < 0)
598aaa76 2099 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 2100 else
598aaa76 2101 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 2102 }
19936277 2103 }
252b5132 2104 }
a7fd1186 2105 else if (rel_type == reltype_rela)
f7a99963 2106 {
7360e63f 2107 bfd_vma off = rels[i].r_addend;
e04d7088
L
2108
2109 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2110 if ((bfd_signed_vma) off < 0)
e04d7088
L
2111 printf ("-%" BFD_VMA_FMT "x", - off);
2112 else
2113 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 2114 }
252b5132 2115
dda8d76d 2116 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2117 && rtype != NULL
2118 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2119 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2120
252b5132 2121 putchar ('\n');
2c71103e 2122
aca88567 2123#ifdef BFD64
dda8d76d 2124 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2125 {
91d6fa6a
NC
2126 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2127 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2128 const char * rtype2 = elf_mips_reloc_type (type2);
2129 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2130
2c71103e
NC
2131 printf (" Type2: ");
2132
2133 if (rtype2 == NULL)
39dbeff8
AM
2134 printf (_("unrecognized: %-7lx"),
2135 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2136 else
2137 printf ("%-17.17s", rtype2);
2138
18bd398b 2139 printf ("\n Type3: ");
2c71103e
NC
2140
2141 if (rtype3 == NULL)
39dbeff8
AM
2142 printf (_("unrecognized: %-7lx"),
2143 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2144 else
2145 printf ("%-17.17s", rtype3);
2146
53c7db4b 2147 putchar ('\n');
2c71103e 2148 }
aca88567 2149#endif /* BFD64 */
252b5132
RH
2150 }
2151
c8286bd1 2152 free (rels);
32ec8896
NC
2153
2154 return res;
252b5132
RH
2155}
2156
37c18eed
SD
2157static const char *
2158get_aarch64_dynamic_type (unsigned long type)
2159{
2160 switch (type)
2161 {
2162 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2163 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2164 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2165 default:
2166 return NULL;
2167 }
2168}
2169
252b5132 2170static const char *
d3ba0551 2171get_mips_dynamic_type (unsigned long type)
252b5132
RH
2172{
2173 switch (type)
2174 {
2175 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2176 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2177 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2178 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2179 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2180 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2181 case DT_MIPS_MSYM: return "MIPS_MSYM";
2182 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2183 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2184 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2185 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2186 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2187 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2188 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2189 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2190 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2191 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2192 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2193 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2194 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2195 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2196 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2197 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2198 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2199 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2200 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2201 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2202 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2203 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2204 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2205 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2206 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2207 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2208 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2209 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2210 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2211 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2212 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2213 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2214 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2215 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2216 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2217 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2218 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2219 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2220 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2221 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2222 default:
2223 return NULL;
2224 }
2225}
2226
9a097730 2227static const char *
d3ba0551 2228get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2229{
2230 switch (type)
2231 {
2232 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2233 default:
2234 return NULL;
2235 }
103f02d3
UD
2236}
2237
7490d522
AM
2238static const char *
2239get_ppc_dynamic_type (unsigned long type)
2240{
2241 switch (type)
2242 {
a7f2871e 2243 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2244 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2245 default:
2246 return NULL;
2247 }
2248}
2249
f1cb7e17 2250static const char *
d3ba0551 2251get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2252{
2253 switch (type)
2254 {
a7f2871e
AM
2255 case DT_PPC64_GLINK: return "PPC64_GLINK";
2256 case DT_PPC64_OPD: return "PPC64_OPD";
2257 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2258 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2259 default:
2260 return NULL;
2261 }
2262}
2263
103f02d3 2264static const char *
d3ba0551 2265get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2266{
2267 switch (type)
2268 {
2269 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2270 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2271 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2272 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2273 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2274 case DT_HP_PREINIT: return "HP_PREINIT";
2275 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2276 case DT_HP_NEEDED: return "HP_NEEDED";
2277 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2278 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2279 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2280 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2281 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2282 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2283 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2284 case DT_HP_FILTERED: return "HP_FILTERED";
2285 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2286 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2287 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2288 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2289 case DT_PLT: return "PLT";
2290 case DT_PLT_SIZE: return "PLT_SIZE";
2291 case DT_DLT: return "DLT";
2292 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2293 default:
2294 return NULL;
2295 }
2296}
9a097730 2297
ecc51f48 2298static const char *
d3ba0551 2299get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2300{
2301 switch (type)
2302 {
148b93f2
NC
2303 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2304 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2305 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2306 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2307 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2308 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2309 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2310 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2311 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2312 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2313 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2314 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2315 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2316 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2317 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2318 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2319 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2320 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2321 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2322 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2323 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2324 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2325 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2326 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2327 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2328 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2329 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2330 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2331 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2332 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2333 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2334 default:
2335 return NULL;
2336 }
2337}
2338
fd85a6a1
NC
2339static const char *
2340get_solaris_section_type (unsigned long type)
2341{
2342 switch (type)
2343 {
2344 case 0x6fffffee: return "SUNW_ancillary";
2345 case 0x6fffffef: return "SUNW_capchain";
2346 case 0x6ffffff0: return "SUNW_capinfo";
2347 case 0x6ffffff1: return "SUNW_symsort";
2348 case 0x6ffffff2: return "SUNW_tlssort";
2349 case 0x6ffffff3: return "SUNW_LDYNSYM";
2350 case 0x6ffffff4: return "SUNW_dof";
2351 case 0x6ffffff5: return "SUNW_cap";
2352 case 0x6ffffff6: return "SUNW_SIGNATURE";
2353 case 0x6ffffff7: return "SUNW_ANNOTATE";
2354 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2355 case 0x6ffffff9: return "SUNW_DEBUG";
2356 case 0x6ffffffa: return "SUNW_move";
2357 case 0x6ffffffb: return "SUNW_COMDAT";
2358 case 0x6ffffffc: return "SUNW_syminfo";
2359 case 0x6ffffffd: return "SUNW_verdef";
2360 case 0x6ffffffe: return "SUNW_verneed";
2361 case 0x6fffffff: return "SUNW_versym";
2362 case 0x70000000: return "SPARC_GOTDATA";
2363 default: return NULL;
2364 }
2365}
2366
fabcb361
RH
2367static const char *
2368get_alpha_dynamic_type (unsigned long type)
2369{
2370 switch (type)
2371 {
2372 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2373 default: return NULL;
fabcb361
RH
2374 }
2375}
2376
1c0d3aa6
NC
2377static const char *
2378get_score_dynamic_type (unsigned long type)
2379{
2380 switch (type)
2381 {
2382 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2383 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2384 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2385 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2386 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2387 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2388 default: return NULL;
1c0d3aa6
NC
2389 }
2390}
2391
40b36596
JM
2392static const char *
2393get_tic6x_dynamic_type (unsigned long type)
2394{
2395 switch (type)
2396 {
2397 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2398 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2399 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2400 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2401 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2402 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2403 default: return NULL;
40b36596
JM
2404 }
2405}
1c0d3aa6 2406
36591ba1
SL
2407static const char *
2408get_nios2_dynamic_type (unsigned long type)
2409{
2410 switch (type)
2411 {
2412 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2413 default: return NULL;
36591ba1
SL
2414 }
2415}
2416
fd85a6a1
NC
2417static const char *
2418get_solaris_dynamic_type (unsigned long type)
2419{
2420 switch (type)
2421 {
2422 case 0x6000000d: return "SUNW_AUXILIARY";
2423 case 0x6000000e: return "SUNW_RTLDINF";
2424 case 0x6000000f: return "SUNW_FILTER";
2425 case 0x60000010: return "SUNW_CAP";
2426 case 0x60000011: return "SUNW_SYMTAB";
2427 case 0x60000012: return "SUNW_SYMSZ";
2428 case 0x60000013: return "SUNW_SORTENT";
2429 case 0x60000014: return "SUNW_SYMSORT";
2430 case 0x60000015: return "SUNW_SYMSORTSZ";
2431 case 0x60000016: return "SUNW_TLSSORT";
2432 case 0x60000017: return "SUNW_TLSSORTSZ";
2433 case 0x60000018: return "SUNW_CAPINFO";
2434 case 0x60000019: return "SUNW_STRPAD";
2435 case 0x6000001a: return "SUNW_CAPCHAIN";
2436 case 0x6000001b: return "SUNW_LDMACH";
2437 case 0x6000001d: return "SUNW_CAPCHAINENT";
2438 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2439 case 0x60000021: return "SUNW_PARENT";
2440 case 0x60000023: return "SUNW_ASLR";
2441 case 0x60000025: return "SUNW_RELAX";
2442 case 0x60000029: return "SUNW_NXHEAP";
2443 case 0x6000002b: return "SUNW_NXSTACK";
2444
2445 case 0x70000001: return "SPARC_REGISTER";
2446 case 0x7ffffffd: return "AUXILIARY";
2447 case 0x7ffffffe: return "USED";
2448 case 0x7fffffff: return "FILTER";
2449
15f205b1 2450 default: return NULL;
fd85a6a1
NC
2451 }
2452}
2453
8155b853
NC
2454static const char *
2455get_riscv_dynamic_type (unsigned long type)
2456{
2457 switch (type)
2458 {
2459 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2460 default:
2461 return NULL;
2462 }
2463}
2464
252b5132 2465static const char *
dda8d76d 2466get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2467{
e9e44622 2468 static char buff[64];
252b5132
RH
2469
2470 switch (type)
2471 {
2472 case DT_NULL: return "NULL";
2473 case DT_NEEDED: return "NEEDED";
2474 case DT_PLTRELSZ: return "PLTRELSZ";
2475 case DT_PLTGOT: return "PLTGOT";
2476 case DT_HASH: return "HASH";
2477 case DT_STRTAB: return "STRTAB";
2478 case DT_SYMTAB: return "SYMTAB";
2479 case DT_RELA: return "RELA";
2480 case DT_RELASZ: return "RELASZ";
2481 case DT_RELAENT: return "RELAENT";
2482 case DT_STRSZ: return "STRSZ";
2483 case DT_SYMENT: return "SYMENT";
2484 case DT_INIT: return "INIT";
2485 case DT_FINI: return "FINI";
2486 case DT_SONAME: return "SONAME";
2487 case DT_RPATH: return "RPATH";
2488 case DT_SYMBOLIC: return "SYMBOLIC";
2489 case DT_REL: return "REL";
2490 case DT_RELSZ: return "RELSZ";
2491 case DT_RELENT: return "RELENT";
dd207c13
FS
2492 case DT_RELR: return "RELR";
2493 case DT_RELRSZ: return "RELRSZ";
2494 case DT_RELRENT: return "RELRENT";
252b5132
RH
2495 case DT_PLTREL: return "PLTREL";
2496 case DT_DEBUG: return "DEBUG";
2497 case DT_TEXTREL: return "TEXTREL";
2498 case DT_JMPREL: return "JMPREL";
2499 case DT_BIND_NOW: return "BIND_NOW";
2500 case DT_INIT_ARRAY: return "INIT_ARRAY";
2501 case DT_FINI_ARRAY: return "FINI_ARRAY";
2502 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2503 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2504 case DT_RUNPATH: return "RUNPATH";
2505 case DT_FLAGS: return "FLAGS";
2d0e6f43 2506
d1133906
NC
2507 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2508 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2509 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2510
05107a46 2511 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2512 case DT_PLTPADSZ: return "PLTPADSZ";
2513 case DT_MOVEENT: return "MOVEENT";
2514 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2515 case DT_FEATURE: return "FEATURE";
252b5132
RH
2516 case DT_POSFLAG_1: return "POSFLAG_1";
2517 case DT_SYMINSZ: return "SYMINSZ";
2518 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2519
252b5132 2520 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2521 case DT_CONFIG: return "CONFIG";
2522 case DT_DEPAUDIT: return "DEPAUDIT";
2523 case DT_AUDIT: return "AUDIT";
2524 case DT_PLTPAD: return "PLTPAD";
2525 case DT_MOVETAB: return "MOVETAB";
252b5132 2526 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2527
252b5132 2528 case DT_VERSYM: return "VERSYM";
103f02d3 2529
67a4f2b7
AO
2530 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2531 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2532 case DT_RELACOUNT: return "RELACOUNT";
2533 case DT_RELCOUNT: return "RELCOUNT";
2534 case DT_FLAGS_1: return "FLAGS_1";
2535 case DT_VERDEF: return "VERDEF";
2536 case DT_VERDEFNUM: return "VERDEFNUM";
2537 case DT_VERNEED: return "VERNEED";
2538 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2539
019148e4 2540 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2541 case DT_USED: return "USED";
2542 case DT_FILTER: return "FILTER";
103f02d3 2543
047b2264
JJ
2544 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2545 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2546 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2547 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2548 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2549 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2550 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2551
252b5132
RH
2552 default:
2553 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2554 {
2cf0635d 2555 const char * result;
103f02d3 2556
dda8d76d 2557 switch (filedata->file_header.e_machine)
252b5132 2558 {
37c18eed
SD
2559 case EM_AARCH64:
2560 result = get_aarch64_dynamic_type (type);
2561 break;
252b5132 2562 case EM_MIPS:
4fe85591 2563 case EM_MIPS_RS3_LE:
252b5132
RH
2564 result = get_mips_dynamic_type (type);
2565 break;
9a097730
RH
2566 case EM_SPARCV9:
2567 result = get_sparc64_dynamic_type (type);
2568 break;
7490d522
AM
2569 case EM_PPC:
2570 result = get_ppc_dynamic_type (type);
2571 break;
f1cb7e17
AM
2572 case EM_PPC64:
2573 result = get_ppc64_dynamic_type (type);
2574 break;
ecc51f48
NC
2575 case EM_IA_64:
2576 result = get_ia64_dynamic_type (type);
2577 break;
fabcb361
RH
2578 case EM_ALPHA:
2579 result = get_alpha_dynamic_type (type);
2580 break;
1c0d3aa6
NC
2581 case EM_SCORE:
2582 result = get_score_dynamic_type (type);
2583 break;
40b36596
JM
2584 case EM_TI_C6000:
2585 result = get_tic6x_dynamic_type (type);
2586 break;
36591ba1
SL
2587 case EM_ALTERA_NIOS2:
2588 result = get_nios2_dynamic_type (type);
2589 break;
8155b853
NC
2590 case EM_RISCV:
2591 result = get_riscv_dynamic_type (type);
2592 break;
252b5132 2593 default:
dda8d76d 2594 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2595 result = get_solaris_dynamic_type (type);
2596 else
2597 result = NULL;
252b5132
RH
2598 break;
2599 }
2600
2601 if (result != NULL)
2602 return result;
2603
e9e44622 2604 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2605 }
eec8f817 2606 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2607 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2608 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2609 {
2cf0635d 2610 const char * result;
103f02d3 2611
dda8d76d 2612 switch (filedata->file_header.e_machine)
103f02d3
UD
2613 {
2614 case EM_PARISC:
2615 result = get_parisc_dynamic_type (type);
2616 break;
148b93f2
NC
2617 case EM_IA_64:
2618 result = get_ia64_dynamic_type (type);
2619 break;
103f02d3 2620 default:
dda8d76d 2621 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2622 result = get_solaris_dynamic_type (type);
2623 else
2624 result = NULL;
103f02d3
UD
2625 break;
2626 }
2627
2628 if (result != NULL)
2629 return result;
2630
e9e44622
JJ
2631 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2632 type);
103f02d3 2633 }
252b5132 2634 else
e9e44622 2635 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2636
252b5132
RH
2637 return buff;
2638 }
2639}
2640
93df3340
AM
2641static bool get_program_headers (Filedata *);
2642static bool get_dynamic_section (Filedata *);
2643
2644static void
2645locate_dynamic_section (Filedata *filedata)
2646{
2647 unsigned long dynamic_addr = 0;
2648 bfd_size_type dynamic_size = 0;
2649
2650 if (filedata->file_header.e_phnum != 0
2651 && get_program_headers (filedata))
2652 {
2653 Elf_Internal_Phdr *segment;
2654 unsigned int i;
2655
2656 for (i = 0, segment = filedata->program_headers;
2657 i < filedata->file_header.e_phnum;
2658 i++, segment++)
2659 {
2660 if (segment->p_type == PT_DYNAMIC)
2661 {
2662 dynamic_addr = segment->p_offset;
2663 dynamic_size = segment->p_filesz;
2664
2665 if (filedata->section_headers != NULL)
2666 {
2667 Elf_Internal_Shdr *sec;
2668
2669 sec = find_section (filedata, ".dynamic");
2670 if (sec != NULL)
2671 {
2672 if (sec->sh_size == 0
2673 || sec->sh_type == SHT_NOBITS)
2674 {
2675 dynamic_addr = 0;
2676 dynamic_size = 0;
2677 }
2678 else
2679 {
2680 dynamic_addr = sec->sh_offset;
2681 dynamic_size = sec->sh_size;
2682 }
2683 }
2684 }
2685
2686 if (dynamic_addr > filedata->file_size
2687 || (dynamic_size > filedata->file_size - dynamic_addr))
2688 {
2689 dynamic_addr = 0;
2690 dynamic_size = 0;
2691 }
2692 break;
2693 }
2694 }
2695 }
2696 filedata->dynamic_addr = dynamic_addr;
2697 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2698}
2699
2700static bool
2701is_pie (Filedata *filedata)
2702{
2703 Elf_Internal_Dyn *entry;
2704
2705 if (filedata->dynamic_size == 0)
2706 locate_dynamic_section (filedata);
2707 if (filedata->dynamic_size <= 1)
2708 return false;
2709
2710 if (!get_dynamic_section (filedata))
2711 return false;
2712
2713 for (entry = filedata->dynamic_section;
2714 entry < filedata->dynamic_section + filedata->dynamic_nent;
2715 entry++)
2716 {
2717 if (entry->d_tag == DT_FLAGS_1)
2718 {
2719 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2720 return true;
2721 break;
2722 }
2723 }
2724 return false;
2725}
2726
252b5132 2727static char *
93df3340 2728get_file_type (Filedata *filedata)
252b5132 2729{
93df3340 2730 unsigned e_type = filedata->file_header.e_type;
89246a0e 2731 static char buff[64];
252b5132
RH
2732
2733 switch (e_type)
2734 {
32ec8896
NC
2735 case ET_NONE: return _("NONE (None)");
2736 case ET_REL: return _("REL (Relocatable file)");
2737 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2738 case ET_DYN:
2739 if (is_pie (filedata))
2740 return _("DYN (Position-Independent Executable file)");
2741 else
2742 return _("DYN (Shared object file)");
32ec8896 2743 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2744
2745 default:
2746 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2747 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2748 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2749 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2750 else
e9e44622 2751 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2752 return buff;
2753 }
2754}
2755
2756static char *
d3ba0551 2757get_machine_name (unsigned e_machine)
252b5132 2758{
b34976b6 2759 static char buff[64]; /* XXX */
252b5132
RH
2760
2761 switch (e_machine)
2762 {
55e22ca8
NC
2763 /* Please keep this switch table sorted by increasing EM_ value. */
2764 /* 0 */
c45021f2
NC
2765 case EM_NONE: return _("None");
2766 case EM_M32: return "WE32100";
2767 case EM_SPARC: return "Sparc";
2768 case EM_386: return "Intel 80386";
2769 case EM_68K: return "MC68000";
2770 case EM_88K: return "MC88000";
22abe556 2771 case EM_IAMCU: return "Intel MCU";
fb70ec17 2772 case EM_860: return "Intel 80860";
c45021f2
NC
2773 case EM_MIPS: return "MIPS R3000";
2774 case EM_S370: return "IBM System/370";
55e22ca8 2775 /* 10 */
7036c0e1 2776 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2777 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2778 case EM_PARISC: return "HPPA";
55e22ca8 2779 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2780 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2781 case EM_960: return "Intel 80960";
c45021f2 2782 case EM_PPC: return "PowerPC";
55e22ca8 2783 /* 20 */
285d1771 2784 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2785 case EM_S390_OLD:
2786 case EM_S390: return "IBM S/390";
2787 case EM_SPU: return "SPU";
2788 /* 30 */
2789 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2790 case EM_FR20: return "Fujitsu FR20";
2791 case EM_RH32: return "TRW RH32";
b34976b6 2792 case EM_MCORE: return "MCORE";
55e22ca8 2793 /* 40 */
7036c0e1
AJ
2794 case EM_ARM: return "ARM";
2795 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2796 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2797 case EM_SPARCV9: return "Sparc v9";
2798 case EM_TRICORE: return "Siemens Tricore";
584da044 2799 case EM_ARC: return "ARC";
c2dcd04e
NC
2800 case EM_H8_300: return "Renesas H8/300";
2801 case EM_H8_300H: return "Renesas H8/300H";
2802 case EM_H8S: return "Renesas H8S";
2803 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2804 /* 50 */
30800947 2805 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2806 case EM_MIPS_X: return "Stanford MIPS-X";
2807 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2808 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2809 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2810 case EM_PCP: return "Siemens PCP";
2811 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2812 case EM_NDR1: return "Denso NDR1 microprocesspr";
2813 case EM_STARCORE: return "Motorola Star*Core processor";
2814 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2815 /* 60 */
7036c0e1
AJ
2816 case EM_ST100: return "STMicroelectronics ST100 processor";
2817 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2818 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2819 case EM_PDSP: return "Sony DSP processor";
2820 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2821 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2822 case EM_FX66: return "Siemens FX66 microcontroller";
2823 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2824 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2825 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2826 /* 70 */
7036c0e1
AJ
2827 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2828 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2829 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2830 case EM_SVX: return "Silicon Graphics SVx";
2831 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2832 case EM_VAX: return "Digital VAX";
1b61cf92 2833 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2834 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2835 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2836 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2837 /* 80 */
b34976b6 2838 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2839 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2840 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2841 case EM_AVR_OLD:
2842 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2843 case EM_CYGNUS_FR30:
2844 case EM_FR30: return "Fujitsu FR30";
2845 case EM_CYGNUS_D10V:
2846 case EM_D10V: return "d10v";
2847 case EM_CYGNUS_D30V:
2848 case EM_D30V: return "d30v";
2849 case EM_CYGNUS_V850:
2850 case EM_V850: return "Renesas V850";
2851 case EM_CYGNUS_M32R:
2852 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2853 case EM_CYGNUS_MN10300:
2854 case EM_MN10300: return "mn10300";
2855 /* 90 */
2856 case EM_CYGNUS_MN10200:
2857 case EM_MN10200: return "mn10200";
2858 case EM_PJ: return "picoJava";
73589c9d 2859 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2860 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2861 case EM_XTENSA_OLD:
2862 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2863 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2864 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2865 case EM_NS32K: return "National Semiconductor 32000 series";
2866 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2867 case EM_SNP1K: return "Trebia SNP 1000 processor";
2868 /* 100 */
9abca702 2869 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2870 case EM_IP2K_OLD:
2871 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2872 case EM_MAX: return "MAX Processor";
2873 case EM_CR: return "National Semiconductor CompactRISC";
2874 case EM_F2MC16: return "Fujitsu F2MC16";
2875 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2876 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2877 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2878 case EM_SEP: return "Sharp embedded microprocessor";
2879 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2880 /* 110 */
11636f9e
JM
2881 case EM_UNICORE: return "Unicore";
2882 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2883 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2884 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2885 case EM_CRX: return "National Semiconductor CRX microprocessor";
2886 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2887 case EM_C166:
d70c5fc7 2888 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2889 case EM_M16C: return "Renesas M16C series microprocessors";
2890 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2891 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2892 /* 120 */
2893 case EM_M32C: return "Renesas M32c";
2894 /* 130 */
11636f9e
JM
2895 case EM_TSK3000: return "Altium TSK3000 core";
2896 case EM_RS08: return "Freescale RS08 embedded processor";
2897 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2898 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2899 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2900 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2901 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2902 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2903 /* 140 */
11636f9e
JM
2904 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2905 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2906 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2907 case EM_TI_PRU: return "TI PRU I/O processor";
2908 /* 160 */
11636f9e
JM
2909 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2910 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2911 case EM_R32C: return "Renesas R32C series microprocessors";
2912 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2913 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2914 case EM_8051: return "Intel 8051 and variants";
2915 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2916 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2917 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2918 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2919 /* 170 */
11636f9e
JM
2920 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2921 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2922 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2923 case EM_RX: return "Renesas RX";
a3c62988 2924 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2925 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2926 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2927 case EM_CR16:
2928 case EM_MICROBLAZE:
2929 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2930 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2931 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2932 /* 180 */
2933 case EM_L1OM: return "Intel L1OM";
2934 case EM_K1OM: return "Intel K1OM";
2935 case EM_INTEL182: return "Intel (reserved)";
2936 case EM_AARCH64: return "AArch64";
2937 case EM_ARM184: return "ARM (reserved)";
2938 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2939 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2940 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2941 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2942 /* 190 */
11636f9e 2943 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2944 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2945 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2946 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2947 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2948 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2949 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2950 case EM_RL78: return "Renesas RL78";
6d913794 2951 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2952 case EM_78K0R: return "Renesas 78K0R";
2953 /* 200 */
6d913794 2954 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2955 case EM_BA1: return "Beyond BA1 CPU architecture";
2956 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2957 case EM_XCORE: return "XMOS xCORE processor family";
2958 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2959 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2960 /* 210 */
6d913794
NC
2961 case EM_KM32: return "KM211 KM32 32-bit processor";
2962 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2963 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2964 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2965 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2966 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2967 case EM_COGE: return "Cognitive Smart Memory Processor";
2968 case EM_COOL: return "Bluechip Systems CoolEngine";
2969 case EM_NORC: return "Nanoradio Optimized RISC";
2970 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2971 /* 220 */
15f205b1 2972 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2973 case EM_VISIUM: return "CDS VISIUMcore processor";
2974 case EM_FT32: return "FTDI Chip FT32";
2975 case EM_MOXIE: return "Moxie";
2976 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2977 /* 230 (all reserved) */
2978 /* 240 */
55e22ca8
NC
2979 case EM_RISCV: return "RISC-V";
2980 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2981 case EM_CEVA: return "CEVA Processor Architecture Family";
2982 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2983 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2984 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2985 case EM_IMG1: return "Imagination Technologies";
2986 /* 250 */
fe944acf 2987 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2988 case EM_VE: return "NEC Vector Engine";
2989 case EM_CSKY: return "C-SKY";
2990 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2991 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2992 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2993 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2994 case EM_65816: return "WDC 65816/65C816";
01a8c731 2995 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2996 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2997
2998 /* Large numbers... */
2999 case EM_MT: return "Morpho Techologies MT processor";
3000 case EM_ALPHA: return "Alpha";
3001 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3002 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3003 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3004 case EM_IQ2000: return "Vitesse IQ2000";
3005 case EM_M32C_OLD:
3006 case EM_NIOS32: return "Altera Nios";
3007 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3008 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3009 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3010 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3011
252b5132 3012 default:
35d9dd2f 3013 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3014 return buff;
3015 }
3016}
3017
a9522a21
AB
3018static void
3019decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3020{
3021 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3022 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3023 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3024 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3025 architectures.
3026
3027 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3028 but also sets a specific architecture type in the e_flags field.
3029
3030 However, when decoding the flags we don't worry if we see an
3031 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3032 ARCEM architecture type. */
3033
3034 switch (e_flags & EF_ARC_MACH_MSK)
3035 {
3036 /* We only expect these to occur for EM_ARC_COMPACT2. */
3037 case EF_ARC_CPU_ARCV2EM:
3038 strcat (buf, ", ARC EM");
3039 break;
3040 case EF_ARC_CPU_ARCV2HS:
3041 strcat (buf, ", ARC HS");
3042 break;
3043
3044 /* We only expect these to occur for EM_ARC_COMPACT. */
3045 case E_ARC_MACH_ARC600:
3046 strcat (buf, ", ARC600");
3047 break;
3048 case E_ARC_MACH_ARC601:
3049 strcat (buf, ", ARC601");
3050 break;
3051 case E_ARC_MACH_ARC700:
3052 strcat (buf, ", ARC700");
3053 break;
3054
3055 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3056 new ELF with new architecture being read by an old version of
3057 readelf, or (c) An ELF built with non-GNU compiler that does not
3058 set the architecture in the e_flags. */
3059 default:
3060 if (e_machine == EM_ARC_COMPACT)
3061 strcat (buf, ", Unknown ARCompact");
3062 else
3063 strcat (buf, ", Unknown ARC");
3064 break;
3065 }
3066
3067 switch (e_flags & EF_ARC_OSABI_MSK)
3068 {
3069 case E_ARC_OSABI_ORIG:
3070 strcat (buf, ", (ABI:legacy)");
3071 break;
3072 case E_ARC_OSABI_V2:
3073 strcat (buf, ", (ABI:v2)");
3074 break;
3075 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3076 case E_ARC_OSABI_V3:
3077 strcat (buf, ", v3 no-legacy-syscalls ABI");
3078 break;
53a346d8
CZ
3079 case E_ARC_OSABI_V4:
3080 strcat (buf, ", v4 ABI");
3081 break;
a9522a21
AB
3082 default:
3083 strcat (buf, ", unrecognised ARC OSABI flag");
3084 break;
3085 }
3086}
3087
f3485b74 3088static void
d3ba0551 3089decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3090{
3091 unsigned eabi;
015dc7e1 3092 bool unknown = false;
f3485b74
NC
3093
3094 eabi = EF_ARM_EABI_VERSION (e_flags);
3095 e_flags &= ~ EF_ARM_EABIMASK;
3096
3097 /* Handle "generic" ARM flags. */
3098 if (e_flags & EF_ARM_RELEXEC)
3099 {
3100 strcat (buf, ", relocatable executable");
3101 e_flags &= ~ EF_ARM_RELEXEC;
3102 }
76da6bbe 3103
18a20338
CL
3104 if (e_flags & EF_ARM_PIC)
3105 {
3106 strcat (buf, ", position independent");
3107 e_flags &= ~ EF_ARM_PIC;
3108 }
3109
f3485b74
NC
3110 /* Now handle EABI specific flags. */
3111 switch (eabi)
3112 {
3113 default:
2c71103e 3114 strcat (buf, ", <unrecognized EABI>");
f3485b74 3115 if (e_flags)
015dc7e1 3116 unknown = true;
f3485b74
NC
3117 break;
3118
3119 case EF_ARM_EABI_VER1:
a5bcd848 3120 strcat (buf, ", Version1 EABI");
f3485b74
NC
3121 while (e_flags)
3122 {
3123 unsigned flag;
76da6bbe 3124
f3485b74
NC
3125 /* Process flags one bit at a time. */
3126 flag = e_flags & - e_flags;
3127 e_flags &= ~ flag;
76da6bbe 3128
f3485b74
NC
3129 switch (flag)
3130 {
a5bcd848 3131 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3132 strcat (buf, ", sorted symbol tables");
3133 break;
76da6bbe 3134
f3485b74 3135 default:
015dc7e1 3136 unknown = true;
f3485b74
NC
3137 break;
3138 }
3139 }
3140 break;
76da6bbe 3141
a5bcd848
PB
3142 case EF_ARM_EABI_VER2:
3143 strcat (buf, ", Version2 EABI");
3144 while (e_flags)
3145 {
3146 unsigned flag;
3147
3148 /* Process flags one bit at a time. */
3149 flag = e_flags & - e_flags;
3150 e_flags &= ~ flag;
3151
3152 switch (flag)
3153 {
3154 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3155 strcat (buf, ", sorted symbol tables");
3156 break;
3157
3158 case EF_ARM_DYNSYMSUSESEGIDX:
3159 strcat (buf, ", dynamic symbols use segment index");
3160 break;
3161
3162 case EF_ARM_MAPSYMSFIRST:
3163 strcat (buf, ", mapping symbols precede others");
3164 break;
3165
3166 default:
015dc7e1 3167 unknown = true;
a5bcd848
PB
3168 break;
3169 }
3170 }
3171 break;
3172
d507cf36
PB
3173 case EF_ARM_EABI_VER3:
3174 strcat (buf, ", Version3 EABI");
8cb51566
PB
3175 break;
3176
3177 case EF_ARM_EABI_VER4:
3178 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3179 while (e_flags)
3180 {
3181 unsigned flag;
3182
3183 /* Process flags one bit at a time. */
3184 flag = e_flags & - e_flags;
3185 e_flags &= ~ flag;
3186
3187 switch (flag)
3188 {
3189 case EF_ARM_BE8:
3190 strcat (buf, ", BE8");
3191 break;
3192
3193 case EF_ARM_LE8:
3194 strcat (buf, ", LE8");
3195 break;
3196
3197 default:
015dc7e1 3198 unknown = true;
3bfcb652
NC
3199 break;
3200 }
3bfcb652
NC
3201 }
3202 break;
3a4a14e9
PB
3203
3204 case EF_ARM_EABI_VER5:
3205 strcat (buf, ", Version5 EABI");
d507cf36
PB
3206 while (e_flags)
3207 {
3208 unsigned flag;
3209
3210 /* Process flags one bit at a time. */
3211 flag = e_flags & - e_flags;
3212 e_flags &= ~ flag;
3213
3214 switch (flag)
3215 {
3216 case EF_ARM_BE8:
3217 strcat (buf, ", BE8");
3218 break;
3219
3220 case EF_ARM_LE8:
3221 strcat (buf, ", LE8");
3222 break;
3223
3bfcb652
NC
3224 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3225 strcat (buf, ", soft-float ABI");
3226 break;
3227
3228 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3229 strcat (buf, ", hard-float ABI");
3230 break;
3231
d507cf36 3232 default:
015dc7e1 3233 unknown = true;
d507cf36
PB
3234 break;
3235 }
3236 }
3237 break;
3238
f3485b74 3239 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3240 strcat (buf, ", GNU EABI");
f3485b74
NC
3241 while (e_flags)
3242 {
3243 unsigned flag;
76da6bbe 3244
f3485b74
NC
3245 /* Process flags one bit at a time. */
3246 flag = e_flags & - e_flags;
3247 e_flags &= ~ flag;
76da6bbe 3248
f3485b74
NC
3249 switch (flag)
3250 {
a5bcd848 3251 case EF_ARM_INTERWORK:
f3485b74
NC
3252 strcat (buf, ", interworking enabled");
3253 break;
76da6bbe 3254
a5bcd848 3255 case EF_ARM_APCS_26:
f3485b74
NC
3256 strcat (buf, ", uses APCS/26");
3257 break;
76da6bbe 3258
a5bcd848 3259 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3260 strcat (buf, ", uses APCS/float");
3261 break;
76da6bbe 3262
a5bcd848 3263 case EF_ARM_PIC:
f3485b74
NC
3264 strcat (buf, ", position independent");
3265 break;
76da6bbe 3266
a5bcd848 3267 case EF_ARM_ALIGN8:
f3485b74
NC
3268 strcat (buf, ", 8 bit structure alignment");
3269 break;
76da6bbe 3270
a5bcd848 3271 case EF_ARM_NEW_ABI:
f3485b74
NC
3272 strcat (buf, ", uses new ABI");
3273 break;
76da6bbe 3274
a5bcd848 3275 case EF_ARM_OLD_ABI:
f3485b74
NC
3276 strcat (buf, ", uses old ABI");
3277 break;
76da6bbe 3278
a5bcd848 3279 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3280 strcat (buf, ", software FP");
3281 break;
76da6bbe 3282
90e01f86
ILT
3283 case EF_ARM_VFP_FLOAT:
3284 strcat (buf, ", VFP");
3285 break;
3286
fde78edd
NC
3287 case EF_ARM_MAVERICK_FLOAT:
3288 strcat (buf, ", Maverick FP");
3289 break;
3290
f3485b74 3291 default:
015dc7e1 3292 unknown = true;
f3485b74
NC
3293 break;
3294 }
3295 }
3296 }
f3485b74
NC
3297
3298 if (unknown)
2b692964 3299 strcat (buf,_(", <unknown>"));
f3485b74
NC
3300}
3301
343433df
AB
3302static void
3303decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3304{
3305 --size; /* Leave space for null terminator. */
3306
3307 switch (e_flags & EF_AVR_MACH)
3308 {
3309 case E_AVR_MACH_AVR1:
3310 strncat (buf, ", avr:1", size);
3311 break;
3312 case E_AVR_MACH_AVR2:
3313 strncat (buf, ", avr:2", size);
3314 break;
3315 case E_AVR_MACH_AVR25:
3316 strncat (buf, ", avr:25", size);
3317 break;
3318 case E_AVR_MACH_AVR3:
3319 strncat (buf, ", avr:3", size);
3320 break;
3321 case E_AVR_MACH_AVR31:
3322 strncat (buf, ", avr:31", size);
3323 break;
3324 case E_AVR_MACH_AVR35:
3325 strncat (buf, ", avr:35", size);
3326 break;
3327 case E_AVR_MACH_AVR4:
3328 strncat (buf, ", avr:4", size);
3329 break;
3330 case E_AVR_MACH_AVR5:
3331 strncat (buf, ", avr:5", size);
3332 break;
3333 case E_AVR_MACH_AVR51:
3334 strncat (buf, ", avr:51", size);
3335 break;
3336 case E_AVR_MACH_AVR6:
3337 strncat (buf, ", avr:6", size);
3338 break;
3339 case E_AVR_MACH_AVRTINY:
3340 strncat (buf, ", avr:100", size);
3341 break;
3342 case E_AVR_MACH_XMEGA1:
3343 strncat (buf, ", avr:101", size);
3344 break;
3345 case E_AVR_MACH_XMEGA2:
3346 strncat (buf, ", avr:102", size);
3347 break;
3348 case E_AVR_MACH_XMEGA3:
3349 strncat (buf, ", avr:103", size);
3350 break;
3351 case E_AVR_MACH_XMEGA4:
3352 strncat (buf, ", avr:104", size);
3353 break;
3354 case E_AVR_MACH_XMEGA5:
3355 strncat (buf, ", avr:105", size);
3356 break;
3357 case E_AVR_MACH_XMEGA6:
3358 strncat (buf, ", avr:106", size);
3359 break;
3360 case E_AVR_MACH_XMEGA7:
3361 strncat (buf, ", avr:107", size);
3362 break;
3363 default:
3364 strncat (buf, ", avr:<unknown>", size);
3365 break;
3366 }
3367
3368 size -= strlen (buf);
3369 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3370 strncat (buf, ", link-relax", size);
3371}
3372
35c08157
KLC
3373static void
3374decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3375{
3376 unsigned abi;
3377 unsigned arch;
3378 unsigned config;
3379 unsigned version;
015dc7e1 3380 bool has_fpu = false;
32ec8896 3381 unsigned int r = 0;
35c08157
KLC
3382
3383 static const char *ABI_STRINGS[] =
3384 {
3385 "ABI v0", /* use r5 as return register; only used in N1213HC */
3386 "ABI v1", /* use r0 as return register */
3387 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3388 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3389 "AABI",
3390 "ABI2 FP+"
35c08157
KLC
3391 };
3392 static const char *VER_STRINGS[] =
3393 {
3394 "Andes ELF V1.3 or older",
3395 "Andes ELF V1.3.1",
3396 "Andes ELF V1.4"
3397 };
3398 static const char *ARCH_STRINGS[] =
3399 {
3400 "",
3401 "Andes Star v1.0",
3402 "Andes Star v2.0",
3403 "Andes Star v3.0",
3404 "Andes Star v3.0m"
3405 };
3406
3407 abi = EF_NDS_ABI & e_flags;
3408 arch = EF_NDS_ARCH & e_flags;
3409 config = EF_NDS_INST & e_flags;
3410 version = EF_NDS32_ELF_VERSION & e_flags;
3411
3412 memset (buf, 0, size);
3413
3414 switch (abi)
3415 {
3416 case E_NDS_ABI_V0:
3417 case E_NDS_ABI_V1:
3418 case E_NDS_ABI_V2:
3419 case E_NDS_ABI_V2FP:
3420 case E_NDS_ABI_AABI:
40c7a7cb 3421 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3422 /* In case there are holes in the array. */
3423 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3424 break;
3425
3426 default:
3427 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3428 break;
3429 }
3430
3431 switch (version)
3432 {
3433 case E_NDS32_ELF_VER_1_2:
3434 case E_NDS32_ELF_VER_1_3:
3435 case E_NDS32_ELF_VER_1_4:
3436 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3437 break;
3438
3439 default:
3440 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3441 break;
3442 }
3443
3444 if (E_NDS_ABI_V0 == abi)
3445 {
3446 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3447 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3448 if (arch == E_NDS_ARCH_STAR_V1_0)
3449 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3450 return;
3451 }
3452
3453 switch (arch)
3454 {
3455 case E_NDS_ARCH_STAR_V1_0:
3456 case E_NDS_ARCH_STAR_V2_0:
3457 case E_NDS_ARCH_STAR_V3_0:
3458 case E_NDS_ARCH_STAR_V3_M:
3459 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3460 break;
3461
3462 default:
3463 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3464 /* ARCH version determines how the e_flags are interpreted.
3465 If it is unknown, we cannot proceed. */
3466 return;
3467 }
3468
3469 /* Newer ABI; Now handle architecture specific flags. */
3470 if (arch == E_NDS_ARCH_STAR_V1_0)
3471 {
3472 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3473 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3474
3475 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3476 r += snprintf (buf + r, size -r, ", MAC");
3477
3478 if (config & E_NDS32_HAS_DIV_INST)
3479 r += snprintf (buf + r, size -r, ", DIV");
3480
3481 if (config & E_NDS32_HAS_16BIT_INST)
3482 r += snprintf (buf + r, size -r, ", 16b");
3483 }
3484 else
3485 {
3486 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3487 {
3488 if (version <= E_NDS32_ELF_VER_1_3)
3489 r += snprintf (buf + r, size -r, ", [B8]");
3490 else
3491 r += snprintf (buf + r, size -r, ", EX9");
3492 }
3493
3494 if (config & E_NDS32_HAS_MAC_DX_INST)
3495 r += snprintf (buf + r, size -r, ", MAC_DX");
3496
3497 if (config & E_NDS32_HAS_DIV_DX_INST)
3498 r += snprintf (buf + r, size -r, ", DIV_DX");
3499
3500 if (config & E_NDS32_HAS_16BIT_INST)
3501 {
3502 if (version <= E_NDS32_ELF_VER_1_3)
3503 r += snprintf (buf + r, size -r, ", 16b");
3504 else
3505 r += snprintf (buf + r, size -r, ", IFC");
3506 }
3507 }
3508
3509 if (config & E_NDS32_HAS_EXT_INST)
3510 r += snprintf (buf + r, size -r, ", PERF1");
3511
3512 if (config & E_NDS32_HAS_EXT2_INST)
3513 r += snprintf (buf + r, size -r, ", PERF2");
3514
3515 if (config & E_NDS32_HAS_FPU_INST)
3516 {
015dc7e1 3517 has_fpu = true;
35c08157
KLC
3518 r += snprintf (buf + r, size -r, ", FPU_SP");
3519 }
3520
3521 if (config & E_NDS32_HAS_FPU_DP_INST)
3522 {
015dc7e1 3523 has_fpu = true;
35c08157
KLC
3524 r += snprintf (buf + r, size -r, ", FPU_DP");
3525 }
3526
3527 if (config & E_NDS32_HAS_FPU_MAC_INST)
3528 {
015dc7e1 3529 has_fpu = true;
35c08157
KLC
3530 r += snprintf (buf + r, size -r, ", FPU_MAC");
3531 }
3532
3533 if (has_fpu)
3534 {
3535 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3536 {
3537 case E_NDS32_FPU_REG_8SP_4DP:
3538 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3539 break;
3540 case E_NDS32_FPU_REG_16SP_8DP:
3541 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3542 break;
3543 case E_NDS32_FPU_REG_32SP_16DP:
3544 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3545 break;
3546 case E_NDS32_FPU_REG_32SP_32DP:
3547 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3548 break;
3549 }
3550 }
3551
3552 if (config & E_NDS32_HAS_AUDIO_INST)
3553 r += snprintf (buf + r, size -r, ", AUDIO");
3554
3555 if (config & E_NDS32_HAS_STRING_INST)
3556 r += snprintf (buf + r, size -r, ", STR");
3557
3558 if (config & E_NDS32_HAS_REDUCED_REGS)
3559 r += snprintf (buf + r, size -r, ", 16REG");
3560
3561 if (config & E_NDS32_HAS_VIDEO_INST)
3562 {
3563 if (version <= E_NDS32_ELF_VER_1_3)
3564 r += snprintf (buf + r, size -r, ", VIDEO");
3565 else
3566 r += snprintf (buf + r, size -r, ", SATURATION");
3567 }
3568
3569 if (config & E_NDS32_HAS_ENCRIPT_INST)
3570 r += snprintf (buf + r, size -r, ", ENCRP");
3571
3572 if (config & E_NDS32_HAS_L2C_INST)
3573 r += snprintf (buf + r, size -r, ", L2C");
3574}
3575
c077c580
SM
3576static void
3577decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3578 char *buf)
3579{
3580 unsigned char *e_ident = filedata->file_header.e_ident;
3581 unsigned char osabi = e_ident[EI_OSABI];
3582 unsigned char abiversion = e_ident[EI_ABIVERSION];
3583 unsigned int mach;
3584
3585 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3586 it has been deprecated for a while.
3587
3588 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3589 of writing, they use the same flags as HSA v3, so the code below uses that
3590 assumption. */
3591 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3592 return;
3593
3594 mach = e_flags & EF_AMDGPU_MACH;
3595 switch (mach)
3596 {
3597#define AMDGPU_CASE(code, string) \
3598 case code: strcat (buf, ", " string); break;
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3614 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3615 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3616 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3617 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3618 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3619 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3620 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3621 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3622 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3623 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3624 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3625 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3626 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3627 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3628 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3629 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3630 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3631 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3632 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3633 default:
3634 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3635 break;
3636#undef AMDGPU_CASE
3637 }
3638
3639 buf += strlen (buf);
3640 e_flags &= ~EF_AMDGPU_MACH;
3641
3642 if ((osabi == ELFOSABI_AMDGPU_HSA
3643 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3644 || osabi != ELFOSABI_AMDGPU_HSA)
3645 {
3646 /* For HSA v3 and other OS ABIs. */
3647 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3648 {
3649 strcat (buf, ", xnack on");
3650 buf += strlen (buf);
3651 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3652 }
3653
3654 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3655 {
3656 strcat (buf, ", sramecc on");
3657 buf += strlen (buf);
3658 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3659 }
3660 }
3661 else
3662 {
3663 /* For HSA v4+. */
3664 int xnack, sramecc;
3665
3666 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3667 switch (xnack)
3668 {
3669 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3670 break;
3671
3672 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3673 strcat (buf, ", xnack any");
3674 break;
3675
3676 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3677 strcat (buf, ", xnack off");
3678 break;
3679
3680 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3681 strcat (buf, ", xnack on");
3682 break;
3683
3684 default:
3685 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3686 break;
3687 }
3688
3689 buf += strlen (buf);
3690 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3691
3692 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3693 switch (sramecc)
3694 {
3695 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3696 break;
3697
3698 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3699 strcat (buf, ", sramecc any");
3700 break;
3701
3702 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3703 strcat (buf, ", sramecc off");
3704 break;
3705
3706 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3707 strcat (buf, ", sramecc on");
3708 break;
3709
3710 default:
3711 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3712 break;
3713 }
3714
3715 buf += strlen (buf);
3716 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3717 }
3718
3719 if (e_flags != 0)
3720 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3721}
3722
252b5132 3723static char *
dda8d76d 3724get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3725{
b34976b6 3726 static char buf[1024];
252b5132
RH
3727
3728 buf[0] = '\0';
76da6bbe 3729
252b5132
RH
3730 if (e_flags)
3731 {
3732 switch (e_machine)
3733 {
3734 default:
3735 break;
3736
886a2506 3737 case EM_ARC_COMPACT2:
886a2506 3738 case EM_ARC_COMPACT:
a9522a21
AB
3739 decode_ARC_machine_flags (e_flags, e_machine, buf);
3740 break;
886a2506 3741
f3485b74
NC
3742 case EM_ARM:
3743 decode_ARM_machine_flags (e_flags, buf);
3744 break;
76da6bbe 3745
343433df
AB
3746 case EM_AVR:
3747 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3748 break;
3749
781303ce
MF
3750 case EM_BLACKFIN:
3751 if (e_flags & EF_BFIN_PIC)
3752 strcat (buf, ", PIC");
3753
3754 if (e_flags & EF_BFIN_FDPIC)
3755 strcat (buf, ", FDPIC");
3756
3757 if (e_flags & EF_BFIN_CODE_IN_L1)
3758 strcat (buf, ", code in L1");
3759
3760 if (e_flags & EF_BFIN_DATA_IN_L1)
3761 strcat (buf, ", data in L1");
3762
3763 break;
3764
ec2dfb42
AO
3765 case EM_CYGNUS_FRV:
3766 switch (e_flags & EF_FRV_CPU_MASK)
3767 {
3768 case EF_FRV_CPU_GENERIC:
3769 break;
3770
3771 default:
3772 strcat (buf, ", fr???");
3773 break;
57346661 3774
ec2dfb42
AO
3775 case EF_FRV_CPU_FR300:
3776 strcat (buf, ", fr300");
3777 break;
3778
3779 case EF_FRV_CPU_FR400:
3780 strcat (buf, ", fr400");
3781 break;
3782 case EF_FRV_CPU_FR405:
3783 strcat (buf, ", fr405");
3784 break;
3785
3786 case EF_FRV_CPU_FR450:
3787 strcat (buf, ", fr450");
3788 break;
3789
3790 case EF_FRV_CPU_FR500:
3791 strcat (buf, ", fr500");
3792 break;
3793 case EF_FRV_CPU_FR550:
3794 strcat (buf, ", fr550");
3795 break;
3796
3797 case EF_FRV_CPU_SIMPLE:
3798 strcat (buf, ", simple");
3799 break;
3800 case EF_FRV_CPU_TOMCAT:
3801 strcat (buf, ", tomcat");
3802 break;
3803 }
1c877e87 3804 break;
ec2dfb42 3805
53c7db4b 3806 case EM_68K:
425c6cb0 3807 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3808 strcat (buf, ", m68000");
425c6cb0 3809 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3810 strcat (buf, ", cpu32");
3811 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3812 strcat (buf, ", fido_a");
425c6cb0 3813 else
266abb8f 3814 {
2cf0635d
NC
3815 char const * isa = _("unknown");
3816 char const * mac = _("unknown mac");
3817 char const * additional = NULL;
0112cd26 3818
c694fd50 3819 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3820 {
c694fd50 3821 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3822 isa = "A";
3823 additional = ", nodiv";
3824 break;
c694fd50 3825 case EF_M68K_CF_ISA_A:
266abb8f
NS
3826 isa = "A";
3827 break;
c694fd50 3828 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3829 isa = "A+";
3830 break;
c694fd50 3831 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3832 isa = "B";
3833 additional = ", nousp";
3834 break;
c694fd50 3835 case EF_M68K_CF_ISA_B:
266abb8f
NS
3836 isa = "B";
3837 break;
f608cd77
NS
3838 case EF_M68K_CF_ISA_C:
3839 isa = "C";
3840 break;
3841 case EF_M68K_CF_ISA_C_NODIV:
3842 isa = "C";
3843 additional = ", nodiv";
3844 break;
266abb8f
NS
3845 }
3846 strcat (buf, ", cf, isa ");
3847 strcat (buf, isa);
0b2e31dc
NS
3848 if (additional)
3849 strcat (buf, additional);
c694fd50 3850 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3851 strcat (buf, ", float");
c694fd50 3852 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3853 {
3854 case 0:
3855 mac = NULL;
3856 break;
c694fd50 3857 case EF_M68K_CF_MAC:
266abb8f
NS
3858 mac = "mac";
3859 break;
c694fd50 3860 case EF_M68K_CF_EMAC:
266abb8f
NS
3861 mac = "emac";
3862 break;
f608cd77
NS
3863 case EF_M68K_CF_EMAC_B:
3864 mac = "emac_b";
3865 break;
266abb8f
NS
3866 }
3867 if (mac)
3868 {
3869 strcat (buf, ", ");
3870 strcat (buf, mac);
3871 }
266abb8f 3872 }
53c7db4b 3873 break;
33c63f9d 3874
c077c580
SM
3875 case EM_AMDGPU:
3876 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3877 break;
3878
153a2776
NC
3879 case EM_CYGNUS_MEP:
3880 switch (e_flags & EF_MEP_CPU_MASK)
3881 {
3882 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3883 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3884 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3885 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3886 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3887 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3888 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3889 }
3890
3891 switch (e_flags & EF_MEP_COP_MASK)
3892 {
3893 case EF_MEP_COP_NONE: break;
3894 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3895 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3896 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3897 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3898 default: strcat (buf, _("<unknown MeP copro type>")); break;
3899 }
3900
3901 if (e_flags & EF_MEP_LIBRARY)
3902 strcat (buf, ", Built for Library");
3903
3904 if (e_flags & EF_MEP_INDEX_MASK)
3905 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3906 e_flags & EF_MEP_INDEX_MASK);
3907
3908 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3909 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3910 e_flags & ~ EF_MEP_ALL_FLAGS);
3911 break;
3912
252b5132
RH
3913 case EM_PPC:
3914 if (e_flags & EF_PPC_EMB)
3915 strcat (buf, ", emb");
3916
3917 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3918 strcat (buf, _(", relocatable"));
252b5132
RH
3919
3920 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3921 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3922 break;
3923
ee67d69a
AM
3924 case EM_PPC64:
3925 if (e_flags & EF_PPC64_ABI)
3926 {
3927 char abi[] = ", abiv0";
3928
3929 abi[6] += e_flags & EF_PPC64_ABI;
3930 strcat (buf, abi);
3931 }
3932 break;
3933
708e2187
NC
3934 case EM_V800:
3935 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3936 strcat (buf, ", RH850 ABI");
0b4362b0 3937
708e2187
NC
3938 if (e_flags & EF_V800_850E3)
3939 strcat (buf, ", V3 architecture");
3940
3941 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3942 strcat (buf, ", FPU not used");
3943
3944 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3945 strcat (buf, ", regmode: COMMON");
3946
3947 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3948 strcat (buf, ", r4 not used");
3949
3950 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3951 strcat (buf, ", r30 not used");
3952
3953 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3954 strcat (buf, ", r5 not used");
3955
3956 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3957 strcat (buf, ", r2 not used");
3958
3959 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3960 {
3961 switch (e_flags & - e_flags)
3962 {
3963 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3964 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3965 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3966 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3967 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3968 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3969 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3970 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3971 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3972 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3973 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3974 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3975 default: break;
3976 }
3977 }
3978 break;
3979
2b0337b0 3980 case EM_V850:
252b5132
RH
3981 case EM_CYGNUS_V850:
3982 switch (e_flags & EF_V850_ARCH)
3983 {
78c8d46c
NC
3984 case E_V850E3V5_ARCH:
3985 strcat (buf, ", v850e3v5");
3986 break;
1cd986c5
NC
3987 case E_V850E2V3_ARCH:
3988 strcat (buf, ", v850e2v3");
3989 break;
3990 case E_V850E2_ARCH:
3991 strcat (buf, ", v850e2");
3992 break;
3993 case E_V850E1_ARCH:
3994 strcat (buf, ", v850e1");
8ad30312 3995 break;
252b5132
RH
3996 case E_V850E_ARCH:
3997 strcat (buf, ", v850e");
3998 break;
252b5132
RH
3999 case E_V850_ARCH:
4000 strcat (buf, ", v850");
4001 break;
4002 default:
2b692964 4003 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
4004 break;
4005 }
4006 break;
4007
2b0337b0 4008 case EM_M32R:
252b5132
RH
4009 case EM_CYGNUS_M32R:
4010 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4011 strcat (buf, ", m32r");
252b5132
RH
4012 break;
4013
4014 case EM_MIPS:
4fe85591 4015 case EM_MIPS_RS3_LE:
252b5132
RH
4016 if (e_flags & EF_MIPS_NOREORDER)
4017 strcat (buf, ", noreorder");
4018
4019 if (e_flags & EF_MIPS_PIC)
4020 strcat (buf, ", pic");
4021
4022 if (e_flags & EF_MIPS_CPIC)
4023 strcat (buf, ", cpic");
4024
d1bdd336
TS
4025 if (e_flags & EF_MIPS_UCODE)
4026 strcat (buf, ", ugen_reserved");
4027
252b5132
RH
4028 if (e_flags & EF_MIPS_ABI2)
4029 strcat (buf, ", abi2");
4030
43521d43
TS
4031 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4032 strcat (buf, ", odk first");
4033
a5d22d2a
TS
4034 if (e_flags & EF_MIPS_32BITMODE)
4035 strcat (buf, ", 32bitmode");
4036
ba92f887
MR
4037 if (e_flags & EF_MIPS_NAN2008)
4038 strcat (buf, ", nan2008");
4039
fef1b0b3
SE
4040 if (e_flags & EF_MIPS_FP64)
4041 strcat (buf, ", fp64");
4042
156c2f8b
NC
4043 switch ((e_flags & EF_MIPS_MACH))
4044 {
4045 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4046 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4047 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4048 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4049 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4050 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4051 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4052 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4053 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4054 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4055 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4056 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4057 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4058 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4059 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4060 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4061 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4062 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4063 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4064 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4065 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4066 case 0:
4067 /* We simply ignore the field in this case to avoid confusion:
4068 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4069 extension. */
4070 break;
2b692964 4071 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4072 }
43521d43
TS
4073
4074 switch ((e_flags & EF_MIPS_ABI))
4075 {
4076 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4077 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4078 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4079 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4080 case 0:
4081 /* We simply ignore the field in this case to avoid confusion:
4082 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4083 This means it is likely to be an o32 file, but not for
4084 sure. */
4085 break;
2b692964 4086 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4087 }
4088
4089 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4090 strcat (buf, ", mdmx");
4091
4092 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4093 strcat (buf, ", mips16");
4094
df58fc94
RS
4095 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4096 strcat (buf, ", micromips");
4097
43521d43
TS
4098 switch ((e_flags & EF_MIPS_ARCH))
4099 {
4100 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4101 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4102 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4103 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4104 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4105 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4106 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4107 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4108 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4109 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4110 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4111 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4112 }
252b5132 4113 break;
351b4b40 4114
35c08157
KLC
4115 case EM_NDS32:
4116 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4117 break;
4118
fe944acf
FT
4119 case EM_NFP:
4120 switch (EF_NFP_MACH (e_flags))
4121 {
4122 case E_NFP_MACH_3200:
4123 strcat (buf, ", NFP-32xx");
4124 break;
4125 case E_NFP_MACH_6000:
4126 strcat (buf, ", NFP-6xxx");
4127 break;
4128 }
4129 break;
4130
e23eba97
NC
4131 case EM_RISCV:
4132 if (e_flags & EF_RISCV_RVC)
4133 strcat (buf, ", RVC");
2922d21d 4134
7f999549
JW
4135 if (e_flags & EF_RISCV_RVE)
4136 strcat (buf, ", RVE");
4137
2922d21d
AW
4138 switch (e_flags & EF_RISCV_FLOAT_ABI)
4139 {
4140 case EF_RISCV_FLOAT_ABI_SOFT:
4141 strcat (buf, ", soft-float ABI");
4142 break;
4143
4144 case EF_RISCV_FLOAT_ABI_SINGLE:
4145 strcat (buf, ", single-float ABI");
4146 break;
4147
4148 case EF_RISCV_FLOAT_ABI_DOUBLE:
4149 strcat (buf, ", double-float ABI");
4150 break;
4151
4152 case EF_RISCV_FLOAT_ABI_QUAD:
4153 strcat (buf, ", quad-float ABI");
4154 break;
4155 }
e23eba97
NC
4156 break;
4157
ccde1100
AO
4158 case EM_SH:
4159 switch ((e_flags & EF_SH_MACH_MASK))
4160 {
4161 case EF_SH1: strcat (buf, ", sh1"); break;
4162 case EF_SH2: strcat (buf, ", sh2"); break;
4163 case EF_SH3: strcat (buf, ", sh3"); break;
4164 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4165 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4166 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4167 case EF_SH3E: strcat (buf, ", sh3e"); break;
4168 case EF_SH4: strcat (buf, ", sh4"); break;
4169 case EF_SH5: strcat (buf, ", sh5"); break;
4170 case EF_SH2E: strcat (buf, ", sh2e"); break;
4171 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4172 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4173 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4174 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4175 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4176 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4177 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4178 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4179 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4180 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4181 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4182 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4183 }
4184
cec6a5b8
MR
4185 if (e_flags & EF_SH_PIC)
4186 strcat (buf, ", pic");
4187
4188 if (e_flags & EF_SH_FDPIC)
4189 strcat (buf, ", fdpic");
ccde1100 4190 break;
948f632f 4191
73589c9d
CS
4192 case EM_OR1K:
4193 if (e_flags & EF_OR1K_NODELAY)
4194 strcat (buf, ", no delay");
4195 break;
57346661 4196
351b4b40
RH
4197 case EM_SPARCV9:
4198 if (e_flags & EF_SPARC_32PLUS)
4199 strcat (buf, ", v8+");
4200
4201 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4202 strcat (buf, ", ultrasparcI");
4203
4204 if (e_flags & EF_SPARC_SUN_US3)
4205 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4206
4207 if (e_flags & EF_SPARC_HAL_R1)
4208 strcat (buf, ", halr1");
4209
4210 if (e_flags & EF_SPARC_LEDATA)
4211 strcat (buf, ", ledata");
4212
4213 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4214 strcat (buf, ", tso");
4215
4216 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4217 strcat (buf, ", pso");
4218
4219 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4220 strcat (buf, ", rmo");
4221 break;
7d466069 4222
103f02d3
UD
4223 case EM_PARISC:
4224 switch (e_flags & EF_PARISC_ARCH)
4225 {
4226 case EFA_PARISC_1_0:
4227 strcpy (buf, ", PA-RISC 1.0");
4228 break;
4229 case EFA_PARISC_1_1:
4230 strcpy (buf, ", PA-RISC 1.1");
4231 break;
4232 case EFA_PARISC_2_0:
4233 strcpy (buf, ", PA-RISC 2.0");
4234 break;
4235 default:
4236 break;
4237 }
4238 if (e_flags & EF_PARISC_TRAPNIL)
4239 strcat (buf, ", trapnil");
4240 if (e_flags & EF_PARISC_EXT)
4241 strcat (buf, ", ext");
4242 if (e_flags & EF_PARISC_LSB)
4243 strcat (buf, ", lsb");
4244 if (e_flags & EF_PARISC_WIDE)
4245 strcat (buf, ", wide");
4246 if (e_flags & EF_PARISC_NO_KABP)
4247 strcat (buf, ", no kabp");
4248 if (e_flags & EF_PARISC_LAZYSWAP)
4249 strcat (buf, ", lazyswap");
30800947 4250 break;
76da6bbe 4251
7d466069 4252 case EM_PJ:
2b0337b0 4253 case EM_PJ_OLD:
7d466069
ILT
4254 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4255 strcat (buf, ", new calling convention");
4256
4257 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4258 strcat (buf, ", gnu calling convention");
4259 break;
4d6ed7c8
NC
4260
4261 case EM_IA_64:
4262 if ((e_flags & EF_IA_64_ABI64))
4263 strcat (buf, ", 64-bit");
4264 else
4265 strcat (buf, ", 32-bit");
4266 if ((e_flags & EF_IA_64_REDUCEDFP))
4267 strcat (buf, ", reduced fp model");
4268 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4269 strcat (buf, ", no function descriptors, constant gp");
4270 else if ((e_flags & EF_IA_64_CONS_GP))
4271 strcat (buf, ", constant gp");
4272 if ((e_flags & EF_IA_64_ABSOLUTE))
4273 strcat (buf, ", absolute");
dda8d76d 4274 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4275 {
4276 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4277 strcat (buf, ", vms_linkages");
4278 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4279 {
4280 case EF_IA_64_VMS_COMCOD_SUCCESS:
4281 break;
4282 case EF_IA_64_VMS_COMCOD_WARNING:
4283 strcat (buf, ", warning");
4284 break;
4285 case EF_IA_64_VMS_COMCOD_ERROR:
4286 strcat (buf, ", error");
4287 break;
4288 case EF_IA_64_VMS_COMCOD_ABORT:
4289 strcat (buf, ", abort");
4290 break;
4291 default:
bee0ee85
NC
4292 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4293 e_flags & EF_IA_64_VMS_COMCOD);
4294 strcat (buf, ", <unknown>");
28f997cf
TG
4295 }
4296 }
4d6ed7c8 4297 break;
179d3252
JT
4298
4299 case EM_VAX:
4300 if ((e_flags & EF_VAX_NONPIC))
4301 strcat (buf, ", non-PIC");
4302 if ((e_flags & EF_VAX_DFLOAT))
4303 strcat (buf, ", D-Float");
4304 if ((e_flags & EF_VAX_GFLOAT))
4305 strcat (buf, ", G-Float");
4306 break;
c7927a3c 4307
619ed720
EB
4308 case EM_VISIUM:
4309 if (e_flags & EF_VISIUM_ARCH_MCM)
4310 strcat (buf, ", mcm");
4311 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4312 strcat (buf, ", mcm24");
4313 if (e_flags & EF_VISIUM_ARCH_GR6)
4314 strcat (buf, ", gr6");
4315 break;
4316
4046d87a 4317 case EM_RL78:
1740ba0c
NC
4318 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4319 {
4320 case E_FLAG_RL78_ANY_CPU: break;
4321 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4322 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4323 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4324 }
856ea05c
KP
4325 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4326 strcat (buf, ", 64-bit doubles");
4046d87a 4327 break;
0b4362b0 4328
c7927a3c
NC
4329 case EM_RX:
4330 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4331 strcat (buf, ", 64-bit doubles");
4332 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4333 strcat (buf, ", dsp");
d4cb0ea0 4334 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4335 strcat (buf, ", pid");
708e2187
NC
4336 if (e_flags & E_FLAG_RX_ABI)
4337 strcat (buf, ", RX ABI");
3525236c
NC
4338 if (e_flags & E_FLAG_RX_SINSNS_SET)
4339 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4340 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4341 if (e_flags & E_FLAG_RX_V2)
4342 strcat (buf, ", V2");
f87673e0
YS
4343 if (e_flags & E_FLAG_RX_V3)
4344 strcat (buf, ", V3");
d4cb0ea0 4345 break;
55786da2
AK
4346
4347 case EM_S390:
4348 if (e_flags & EF_S390_HIGH_GPRS)
4349 strcat (buf, ", highgprs");
d4cb0ea0 4350 break;
40b36596
JM
4351
4352 case EM_TI_C6000:
4353 if ((e_flags & EF_C6000_REL))
4354 strcat (buf, ", relocatable module");
d4cb0ea0 4355 break;
13761a11
NC
4356
4357 case EM_MSP430:
4358 strcat (buf, _(": architecture variant: "));
4359 switch (e_flags & EF_MSP430_MACH)
4360 {
4361 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4362 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4363 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4364 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4365 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4366 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4367 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4368 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4369 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4370 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4371 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4372 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4373 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4374 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4375 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4376 default:
4377 strcat (buf, _(": unknown")); break;
4378 }
4379
4380 if (e_flags & ~ EF_MSP430_MACH)
4381 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4382 break;
4383
4384 case EM_Z80:
4385 switch (e_flags & EF_Z80_MACH_MSK)
4386 {
4387 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4388 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4389 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4390 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4391 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4392 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4393 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4394 default:
4395 strcat (buf, _(", unknown")); break;
4396 }
4397 break;
e9a0721f 4398 case EM_LOONGARCH:
4399 if (EF_LOONGARCH_IS_LP64 (e_flags))
4400 strcat (buf, ", LP64");
4401 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4402 strcat (buf, ", ILP32");
4403
4404 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4405 strcat (buf, ", SOFT-FLOAT");
4406 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4407 strcat (buf, ", SINGLE-FLOAT");
4408 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4409 strcat (buf, ", DOUBLE-FLOAT");
4410
4411 break;
252b5132
RH
4412 }
4413 }
4414
4415 return buf;
4416}
4417
252b5132 4418static const char *
dda8d76d 4419get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4420{
4421 static char buff[32];
4422
4423 switch (osabi)
4424 {
4425 case ELFOSABI_NONE: return "UNIX - System V";
4426 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4427 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4428 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4429 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4430 case ELFOSABI_AIX: return "UNIX - AIX";
4431 case ELFOSABI_IRIX: return "UNIX - IRIX";
4432 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4433 case ELFOSABI_TRU64: return "UNIX - TRU64";
4434 case ELFOSABI_MODESTO: return "Novell - Modesto";
4435 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4436 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4437 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4438 case ELFOSABI_AROS: return "AROS";
11636f9e 4439 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4440 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4441 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4442 default:
40b36596 4443 if (osabi >= 64)
dda8d76d 4444 switch (filedata->file_header.e_machine)
40b36596 4445 {
37870be8
SM
4446 case EM_AMDGPU:
4447 switch (osabi)
4448 {
4449 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4450 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4451 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4452 default:
4453 break;
4454 }
4455 break;
4456
40b36596
JM
4457 case EM_ARM:
4458 switch (osabi)
4459 {
4460 case ELFOSABI_ARM: return "ARM";
18a20338 4461 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4462 default:
4463 break;
4464 }
4465 break;
4466
4467 case EM_MSP430:
4468 case EM_MSP430_OLD:
619ed720 4469 case EM_VISIUM:
40b36596
JM
4470 switch (osabi)
4471 {
4472 case ELFOSABI_STANDALONE: return _("Standalone App");
4473 default:
4474 break;
4475 }
4476 break;
4477
4478 case EM_TI_C6000:
4479 switch (osabi)
4480 {
4481 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4482 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4483 default:
4484 break;
4485 }
4486 break;
4487
4488 default:
4489 break;
4490 }
e9e44622 4491 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4492 return buff;
4493 }
4494}
4495
a06ea964
NC
4496static const char *
4497get_aarch64_segment_type (unsigned long type)
4498{
4499 switch (type)
4500 {
32ec8896
NC
4501 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4502 default: return NULL;
a06ea964 4503 }
a06ea964
NC
4504}
4505
b294bdf8
MM
4506static const char *
4507get_arm_segment_type (unsigned long type)
4508{
4509 switch (type)
4510 {
32ec8896
NC
4511 case PT_ARM_EXIDX: return "EXIDX";
4512 default: return NULL;
b294bdf8 4513 }
b294bdf8
MM
4514}
4515
b4cbbe8f
AK
4516static const char *
4517get_s390_segment_type (unsigned long type)
4518{
4519 switch (type)
4520 {
4521 case PT_S390_PGSTE: return "S390_PGSTE";
4522 default: return NULL;
4523 }
4524}
4525
d3ba0551
AM
4526static const char *
4527get_mips_segment_type (unsigned long type)
252b5132
RH
4528{
4529 switch (type)
4530 {
32ec8896
NC
4531 case PT_MIPS_REGINFO: return "REGINFO";
4532 case PT_MIPS_RTPROC: return "RTPROC";
4533 case PT_MIPS_OPTIONS: return "OPTIONS";
4534 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4535 default: return NULL;
252b5132 4536 }
252b5132
RH
4537}
4538
103f02d3 4539static const char *
d3ba0551 4540get_parisc_segment_type (unsigned long type)
103f02d3
UD
4541{
4542 switch (type)
4543 {
103f02d3
UD
4544 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4545 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4546 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4547 default: return NULL;
103f02d3 4548 }
103f02d3
UD
4549}
4550
4d6ed7c8 4551static const char *
d3ba0551 4552get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4553{
4554 switch (type)
4555 {
4556 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4557 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4558 default: return NULL;
4d6ed7c8 4559 }
4d6ed7c8
NC
4560}
4561
40b36596
JM
4562static const char *
4563get_tic6x_segment_type (unsigned long type)
4564{
4565 switch (type)
4566 {
32ec8896
NC
4567 case PT_C6000_PHATTR: return "C6000_PHATTR";
4568 default: return NULL;
40b36596 4569 }
40b36596
JM
4570}
4571
fbc95f1e
KC
4572static const char *
4573get_riscv_segment_type (unsigned long type)
4574{
4575 switch (type)
4576 {
4577 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4578 default: return NULL;
4579 }
4580}
4581
df3a023b
AM
4582static const char *
4583get_hpux_segment_type (unsigned long type, unsigned e_machine)
4584{
4585 if (e_machine == EM_PARISC)
4586 switch (type)
4587 {
4588 case PT_HP_TLS: return "HP_TLS";
4589 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4590 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4591 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4592 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4593 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4594 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4595 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4596 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4597 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4598 case PT_HP_PARALLEL: return "HP_PARALLEL";
4599 case PT_HP_FASTBIND: return "HP_FASTBIND";
4600 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4601 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4602 case PT_HP_STACK: return "HP_STACK";
4603 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4604 default: return NULL;
4605 }
4606
4607 if (e_machine == EM_IA_64)
4608 switch (type)
4609 {
4610 case PT_HP_TLS: return "HP_TLS";
4611 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4612 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4613 case PT_IA_64_HP_STACK: return "HP_STACK";
4614 default: return NULL;
4615 }
4616
4617 return NULL;
4618}
4619
5522f910
NC
4620static const char *
4621get_solaris_segment_type (unsigned long type)
4622{
4623 switch (type)
4624 {
4625 case 0x6464e550: return "PT_SUNW_UNWIND";
4626 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4627 case 0x6ffffff7: return "PT_LOSUNW";
4628 case 0x6ffffffa: return "PT_SUNWBSS";
4629 case 0x6ffffffb: return "PT_SUNWSTACK";
4630 case 0x6ffffffc: return "PT_SUNWDTRACE";
4631 case 0x6ffffffd: return "PT_SUNWCAP";
4632 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4633 default: return NULL;
5522f910
NC
4634 }
4635}
4636
252b5132 4637static const char *
dda8d76d 4638get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4639{
b34976b6 4640 static char buff[32];
252b5132
RH
4641
4642 switch (p_type)
4643 {
b34976b6
AM
4644 case PT_NULL: return "NULL";
4645 case PT_LOAD: return "LOAD";
252b5132 4646 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4647 case PT_INTERP: return "INTERP";
4648 case PT_NOTE: return "NOTE";
4649 case PT_SHLIB: return "SHLIB";
4650 case PT_PHDR: return "PHDR";
13ae64f3 4651 case PT_TLS: return "TLS";
32ec8896 4652 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4653 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4654 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4655 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4656
3eba3ef3
NC
4657 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4658 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4659 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4660
252b5132 4661 default:
df3a023b 4662 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4663 {
2cf0635d 4664 const char * result;
103f02d3 4665
dda8d76d 4666 switch (filedata->file_header.e_machine)
252b5132 4667 {
a06ea964
NC
4668 case EM_AARCH64:
4669 result = get_aarch64_segment_type (p_type);
4670 break;
b294bdf8
MM
4671 case EM_ARM:
4672 result = get_arm_segment_type (p_type);
4673 break;
252b5132 4674 case EM_MIPS:
4fe85591 4675 case EM_MIPS_RS3_LE:
252b5132
RH
4676 result = get_mips_segment_type (p_type);
4677 break;
103f02d3
UD
4678 case EM_PARISC:
4679 result = get_parisc_segment_type (p_type);
4680 break;
4d6ed7c8
NC
4681 case EM_IA_64:
4682 result = get_ia64_segment_type (p_type);
4683 break;
40b36596
JM
4684 case EM_TI_C6000:
4685 result = get_tic6x_segment_type (p_type);
4686 break;
b4cbbe8f
AK
4687 case EM_S390:
4688 case EM_S390_OLD:
4689 result = get_s390_segment_type (p_type);
4690 break;
fbc95f1e
KC
4691 case EM_RISCV:
4692 result = get_riscv_segment_type (p_type);
4693 break;
252b5132
RH
4694 default:
4695 result = NULL;
4696 break;
4697 }
103f02d3 4698
252b5132
RH
4699 if (result != NULL)
4700 return result;
103f02d3 4701
1a9ccd70 4702 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4703 }
4704 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4705 {
df3a023b 4706 const char * result = NULL;
103f02d3 4707
df3a023b 4708 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4709 {
df3a023b
AM
4710 case ELFOSABI_GNU:
4711 case ELFOSABI_FREEBSD:
4712 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4713 {
4714 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4715 result = buff;
4716 }
103f02d3 4717 break;
df3a023b
AM
4718 case ELFOSABI_HPUX:
4719 result = get_hpux_segment_type (p_type,
4720 filedata->file_header.e_machine);
4721 break;
4722 case ELFOSABI_SOLARIS:
4723 result = get_solaris_segment_type (p_type);
00428cca 4724 break;
103f02d3 4725 default:
103f02d3
UD
4726 break;
4727 }
103f02d3
UD
4728 if (result != NULL)
4729 return result;
4730
1a9ccd70 4731 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4732 }
252b5132 4733 else
e9e44622 4734 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4735
4736 return buff;
4737 }
4738}
4739
53a346d8
CZ
4740static const char *
4741get_arc_section_type_name (unsigned int sh_type)
4742{
4743 switch (sh_type)
4744 {
4745 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4746 default:
4747 break;
4748 }
4749 return NULL;
4750}
4751
252b5132 4752static const char *
d3ba0551 4753get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4754{
4755 switch (sh_type)
4756 {
b34976b6
AM
4757 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4758 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4759 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4760 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4761 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4762 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4763 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4764 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4765 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4766 case SHT_MIPS_RELD: return "MIPS_RELD";
4767 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4768 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4769 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4770 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4771 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4772 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4773 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4774 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4775 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4776 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4777 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4778 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4779 case SHT_MIPS_LINE: return "MIPS_LINE";
4780 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4781 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4782 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4783 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4784 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4785 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4786 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4787 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4788 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4789 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4790 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4791 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4792 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4793 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4794 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4795 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4796 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4797 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4798 default:
4799 break;
4800 }
4801 return NULL;
4802}
4803
103f02d3 4804static const char *
d3ba0551 4805get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4806{
4807 switch (sh_type)
4808 {
4809 case SHT_PARISC_EXT: return "PARISC_EXT";
4810 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4811 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4812 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4813 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4814 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4815 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4816 default: return NULL;
103f02d3 4817 }
103f02d3
UD
4818}
4819
4d6ed7c8 4820static const char *
dda8d76d 4821get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4822{
18bd398b 4823 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4824 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4825 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4826
4d6ed7c8
NC
4827 switch (sh_type)
4828 {
148b93f2
NC
4829 case SHT_IA_64_EXT: return "IA_64_EXT";
4830 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4831 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4832 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4833 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4834 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4835 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4836 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4837 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4838 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4839 default:
4840 break;
4841 }
4842 return NULL;
4843}
4844
d2b2c203
DJ
4845static const char *
4846get_x86_64_section_type_name (unsigned int sh_type)
4847{
4848 switch (sh_type)
4849 {
4850 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4851 default: return NULL;
d2b2c203 4852 }
d2b2c203
DJ
4853}
4854
a06ea964
NC
4855static const char *
4856get_aarch64_section_type_name (unsigned int sh_type)
4857{
4858 switch (sh_type)
4859 {
32ec8896
NC
4860 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4861 default: return NULL;
a06ea964 4862 }
a06ea964
NC
4863}
4864
40a18ebd
NC
4865static const char *
4866get_arm_section_type_name (unsigned int sh_type)
4867{
4868 switch (sh_type)
4869 {
7f6fed87
NC
4870 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4871 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4872 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4873 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4874 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4875 default: return NULL;
40a18ebd 4876 }
40a18ebd
NC
4877}
4878
40b36596
JM
4879static const char *
4880get_tic6x_section_type_name (unsigned int sh_type)
4881{
4882 switch (sh_type)
4883 {
32ec8896
NC
4884 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4885 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4886 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4887 case SHT_TI_ICODE: return "TI_ICODE";
4888 case SHT_TI_XREF: return "TI_XREF";
4889 case SHT_TI_HANDLER: return "TI_HANDLER";
4890 case SHT_TI_INITINFO: return "TI_INITINFO";
4891 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4892 default: return NULL;
40b36596 4893 }
40b36596
JM
4894}
4895
13761a11 4896static const char *
b0191216 4897get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4898{
4899 switch (sh_type)
4900 {
32ec8896
NC
4901 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4902 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4903 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4904 default: return NULL;
13761a11
NC
4905 }
4906}
4907
fe944acf
FT
4908static const char *
4909get_nfp_section_type_name (unsigned int sh_type)
4910{
4911 switch (sh_type)
4912 {
4913 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4914 case SHT_NFP_INITREG: return "NFP_INITREG";
4915 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4916 default: return NULL;
4917 }
4918}
4919
685080f2
NC
4920static const char *
4921get_v850_section_type_name (unsigned int sh_type)
4922{
4923 switch (sh_type)
4924 {
32ec8896
NC
4925 case SHT_V850_SCOMMON: return "V850 Small Common";
4926 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4927 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4928 case SHT_RENESAS_IOP: return "RENESAS IOP";
4929 case SHT_RENESAS_INFO: return "RENESAS INFO";
4930 default: return NULL;
685080f2
NC
4931 }
4932}
4933
2dc8dd17
JW
4934static const char *
4935get_riscv_section_type_name (unsigned int sh_type)
4936{
4937 switch (sh_type)
4938 {
4939 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4940 default: return NULL;
4941 }
4942}
4943
0861f561
CQ
4944static const char *
4945get_csky_section_type_name (unsigned int sh_type)
4946{
4947 switch (sh_type)
4948 {
4949 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4950 default: return NULL;
4951 }
4952}
4953
252b5132 4954static const char *
dda8d76d 4955get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4956{
b34976b6 4957 static char buff[32];
9fb71ee4 4958 const char * result;
252b5132
RH
4959
4960 switch (sh_type)
4961 {
4962 case SHT_NULL: return "NULL";
4963 case SHT_PROGBITS: return "PROGBITS";
4964 case SHT_SYMTAB: return "SYMTAB";
4965 case SHT_STRTAB: return "STRTAB";
4966 case SHT_RELA: return "RELA";
dd207c13 4967 case SHT_RELR: return "RELR";
252b5132
RH
4968 case SHT_HASH: return "HASH";
4969 case SHT_DYNAMIC: return "DYNAMIC";
4970 case SHT_NOTE: return "NOTE";
4971 case SHT_NOBITS: return "NOBITS";
4972 case SHT_REL: return "REL";
4973 case SHT_SHLIB: return "SHLIB";
4974 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4975 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4976 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4977 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4978 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4979 case SHT_GROUP: return "GROUP";
67ce483b 4980 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4981 case SHT_GNU_verdef: return "VERDEF";
4982 case SHT_GNU_verneed: return "VERNEED";
4983 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4984 case 0x6ffffff0: return "VERSYM";
4985 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4986 case 0x7ffffffd: return "AUXILIARY";
4987 case 0x7fffffff: return "FILTER";
047b2264 4988 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4989
4990 default:
4991 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4992 {
dda8d76d 4993 switch (filedata->file_header.e_machine)
252b5132 4994 {
53a346d8
CZ
4995 case EM_ARC:
4996 case EM_ARC_COMPACT:
4997 case EM_ARC_COMPACT2:
4998 result = get_arc_section_type_name (sh_type);
4999 break;
252b5132 5000 case EM_MIPS:
4fe85591 5001 case EM_MIPS_RS3_LE:
252b5132
RH
5002 result = get_mips_section_type_name (sh_type);
5003 break;
103f02d3
UD
5004 case EM_PARISC:
5005 result = get_parisc_section_type_name (sh_type);
5006 break;
4d6ed7c8 5007 case EM_IA_64:
dda8d76d 5008 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5009 break;
d2b2c203 5010 case EM_X86_64:
8a9036a4 5011 case EM_L1OM:
7a9068fe 5012 case EM_K1OM:
d2b2c203
DJ
5013 result = get_x86_64_section_type_name (sh_type);
5014 break;
a06ea964
NC
5015 case EM_AARCH64:
5016 result = get_aarch64_section_type_name (sh_type);
5017 break;
40a18ebd
NC
5018 case EM_ARM:
5019 result = get_arm_section_type_name (sh_type);
5020 break;
40b36596
JM
5021 case EM_TI_C6000:
5022 result = get_tic6x_section_type_name (sh_type);
5023 break;
13761a11 5024 case EM_MSP430:
b0191216 5025 result = get_msp430_section_type_name (sh_type);
13761a11 5026 break;
fe944acf
FT
5027 case EM_NFP:
5028 result = get_nfp_section_type_name (sh_type);
5029 break;
685080f2
NC
5030 case EM_V800:
5031 case EM_V850:
5032 case EM_CYGNUS_V850:
5033 result = get_v850_section_type_name (sh_type);
5034 break;
2dc8dd17
JW
5035 case EM_RISCV:
5036 result = get_riscv_section_type_name (sh_type);
5037 break;
0861f561
CQ
5038 case EM_CSKY:
5039 result = get_csky_section_type_name (sh_type);
5040 break;
252b5132
RH
5041 default:
5042 result = NULL;
5043 break;
5044 }
5045
5046 if (result != NULL)
5047 return result;
5048
9fb71ee4 5049 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5050 }
5051 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5052 {
dda8d76d 5053 switch (filedata->file_header.e_machine)
148b93f2
NC
5054 {
5055 case EM_IA_64:
dda8d76d 5056 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5057 break;
5058 default:
dda8d76d 5059 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5060 result = get_solaris_section_type (sh_type);
5061 else
1b4b80bf
NC
5062 {
5063 switch (sh_type)
5064 {
5065 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5066 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5067 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5068 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5069 default:
5070 result = NULL;
5071 break;
5072 }
5073 }
148b93f2
NC
5074 break;
5075 }
5076
5077 if (result != NULL)
5078 return result;
5079
9fb71ee4 5080 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5081 }
252b5132 5082 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5083 {
dda8d76d 5084 switch (filedata->file_header.e_machine)
685080f2
NC
5085 {
5086 case EM_V800:
5087 case EM_V850:
5088 case EM_CYGNUS_V850:
9fb71ee4 5089 result = get_v850_section_type_name (sh_type);
a9fb83be 5090 break;
685080f2 5091 default:
9fb71ee4 5092 result = NULL;
685080f2
NC
5093 break;
5094 }
5095
9fb71ee4
NC
5096 if (result != NULL)
5097 return result;
5098
5099 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5100 }
252b5132 5101 else
a7dbfd1c
NC
5102 /* This message is probably going to be displayed in a 15
5103 character wide field, so put the hex value first. */
5104 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5105
252b5132
RH
5106 return buff;
5107 }
5108}
5109
79bc120c
NC
5110enum long_option_values
5111{
5112 OPTION_DEBUG_DUMP = 512,
5113 OPTION_DYN_SYMS,
0f03783c 5114 OPTION_LTO_SYMS,
79bc120c
NC
5115 OPTION_DWARF_DEPTH,
5116 OPTION_DWARF_START,
5117 OPTION_DWARF_CHECK,
5118 OPTION_CTF_DUMP,
5119 OPTION_CTF_PARENT,
5120 OPTION_CTF_SYMBOLS,
5121 OPTION_CTF_STRINGS,
5122 OPTION_WITH_SYMBOL_VERSIONS,
5123 OPTION_RECURSE_LIMIT,
5124 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5125 OPTION_NO_DEMANGLING,
5126 OPTION_SYM_BASE
79bc120c 5127};
2979dc34 5128
85b1c36d 5129static struct option options[] =
252b5132 5130{
79bc120c
NC
5131 /* Note - This table is alpha-sorted on the 'val'
5132 field in order to make adding new options easier. */
5133 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5134 {"all", no_argument, 0, 'a'},
79bc120c
NC
5135 {"demangle", optional_argument, 0, 'C'},
5136 {"archive-index", no_argument, 0, 'c'},
5137 {"use-dynamic", no_argument, 0, 'D'},
5138 {"dynamic", no_argument, 0, 'd'},
b34976b6 5139 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5140 {"section-groups", no_argument, 0, 'g'},
5141 {"help", no_argument, 0, 'H'},
5142 {"file-header", no_argument, 0, 'h'},
b34976b6 5143 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5144 {"lint", no_argument, 0, 'L'},
5145 {"enable-checks", no_argument, 0, 'L'},
5146 {"program-headers", no_argument, 0, 'l'},
b34976b6 5147 {"segments", no_argument, 0, 'l'},
595cf52e 5148 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5149 {"notes", no_argument, 0, 'n'},
ca0e11aa 5150 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5151 {"string-dump", required_argument, 0, 'p'},
5152 {"relocated-dump", required_argument, 0, 'R'},
5153 {"relocs", no_argument, 0, 'r'},
5154 {"section-headers", no_argument, 0, 'S'},
5155 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5156 {"symbols", no_argument, 0, 's'},
5157 {"syms", no_argument, 0, 's'},
79bc120c
NC
5158 {"silent-truncation",no_argument, 0, 'T'},
5159 {"section-details", no_argument, 0, 't'},
b3aa80b4 5160 {"unicode", required_argument, NULL, 'U'},
09c11c86 5161 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5162 {"version-info", no_argument, 0, 'V'},
5163 {"version", no_argument, 0, 'v'},
5164 {"wide", no_argument, 0, 'W'},
b34976b6 5165 {"hex-dump", required_argument, 0, 'x'},
0e602686 5166 {"decompress", no_argument, 0, 'z'},
252b5132 5167
79bc120c
NC
5168 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5169 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5170 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5171 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5172 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5173 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5174 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5175 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5176 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5177 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5178#ifdef ENABLE_LIBCTF
d344b407 5179 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5180 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5181 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5182 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5183#endif
047c3dbf 5184 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5185
b34976b6 5186 {0, no_argument, 0, 0}
252b5132
RH
5187};
5188
5189static void
2cf0635d 5190usage (FILE * stream)
252b5132 5191{
92f01d61
JM
5192 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5193 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5194 fprintf (stream, _(" Options are:\n"));
5195 fprintf (stream, _("\
5196 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5197 fprintf (stream, _("\
5198 -h --file-header Display the ELF file header\n"));
5199 fprintf (stream, _("\
5200 -l --program-headers Display the program headers\n"));
5201 fprintf (stream, _("\
5202 --segments An alias for --program-headers\n"));
5203 fprintf (stream, _("\
5204 -S --section-headers Display the sections' header\n"));
5205 fprintf (stream, _("\
5206 --sections An alias for --section-headers\n"));
5207 fprintf (stream, _("\
5208 -g --section-groups Display the section groups\n"));
5209 fprintf (stream, _("\
5210 -t --section-details Display the section details\n"));
5211 fprintf (stream, _("\
5212 -e --headers Equivalent to: -h -l -S\n"));
5213 fprintf (stream, _("\
5214 -s --syms Display the symbol table\n"));
5215 fprintf (stream, _("\
5216 --symbols An alias for --syms\n"));
5217 fprintf (stream, _("\
5218 --dyn-syms Display the dynamic symbol table\n"));
5219 fprintf (stream, _("\
5220 --lto-syms Display LTO symbol tables\n"));
5221 fprintf (stream, _("\
047c3dbf
NL
5222 --sym-base=[0|8|10|16] \n\
5223 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5224 mixed (the default), octal, decimal, hexadecimal.\n"));
5225 fprintf (stream, _("\
0d646226
AM
5226 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5227 display_demangler_styles (stream, _("\
5228 STYLE can be "));
d6249f5f
AM
5229 fprintf (stream, _("\
5230 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5231 fprintf (stream, _("\
5232 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5233 fprintf (stream, _("\
5234 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5235 fprintf (stream, _("\
5236 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5237 Display unicode characters as determined by the current locale\n\
5238 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5239 escape sequences, or treat them as invalid and display as\n\
5240 \"{hex sequences}\"\n"));
d6249f5f
AM
5241 fprintf (stream, _("\
5242 -n --notes Display the core notes (if present)\n"));
5243 fprintf (stream, _("\
5244 -r --relocs Display the relocations (if present)\n"));
5245 fprintf (stream, _("\
5246 -u --unwind Display the unwind info (if present)\n"));
5247 fprintf (stream, _("\
5248 -d --dynamic Display the dynamic section (if present)\n"));
5249 fprintf (stream, _("\
5250 -V --version-info Display the version sections (if present)\n"));
5251 fprintf (stream, _("\
5252 -A --arch-specific Display architecture specific information (if any)\n"));
5253 fprintf (stream, _("\
5254 -c --archive-index Display the symbol/file index in an archive\n"));
5255 fprintf (stream, _("\
5256 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5257 fprintf (stream, _("\
5258 -L --lint|--enable-checks\n\
5259 Display warning messages for possible problems\n"));
5260 fprintf (stream, _("\
09c11c86 5261 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5262 Dump the contents of section <number|name> as bytes\n"));
5263 fprintf (stream, _("\
09c11c86 5264 -p --string-dump=<number|name>\n\
d6249f5f
AM
5265 Dump the contents of section <number|name> as strings\n"));
5266 fprintf (stream, _("\
cf13d699 5267 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5268 Dump the relocated contents of section <number|name>\n"));
5269 fprintf (stream, _("\
5270 -z --decompress Decompress section before dumping it\n"));
5271 fprintf (stream, _("\
5272 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5273 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5274 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5275 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5276 U/=trace_info]\n\
5277 Display the contents of DWARF debug sections\n"));
5278 fprintf (stream, _("\
5279 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5280 debuginfo files\n"));
5281 fprintf (stream, _("\
5282 -P --process-links Display the contents of non-debug sections in separate\n\
5283 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5284#if DEFAULT_FOR_FOLLOW_LINKS
5285 fprintf (stream, _("\
d6249f5f
AM
5286 -wK --debug-dump=follow-links\n\
5287 Follow links to separate debug info files (default)\n"));
5288 fprintf (stream, _("\
5289 -wN --debug-dump=no-follow-links\n\
5290 Do not follow links to separate debug info files\n"));
c46b7066
NC
5291#else
5292 fprintf (stream, _("\
d6249f5f
AM
5293 -wK --debug-dump=follow-links\n\
5294 Follow links to separate debug info files\n"));
5295 fprintf (stream, _("\
5296 -wN --debug-dump=no-follow-links\n\
5297 Do not follow links to separate debug info files\n\
5298 (default)\n"));
bed566bb
NC
5299#endif
5300#if HAVE_LIBDEBUGINFOD
5301 fprintf (stream, _("\
5302 -wD --debug-dump=use-debuginfod\n\
5303 When following links, also query debuginfod servers (default)\n"));
5304 fprintf (stream, _("\
5305 -wE --debug-dump=do-not-use-debuginfod\n\
5306 When following links, do not query debuginfod servers\n"));
c46b7066 5307#endif
fd2f0033 5308 fprintf (stream, _("\
d6249f5f
AM
5309 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5310 fprintf (stream, _("\
5311 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5312#ifdef ENABLE_LIBCTF
7d9813f1 5313 fprintf (stream, _("\
d6249f5f
AM
5314 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5315 fprintf (stream, _("\
80b56fad 5316 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5317 fprintf (stream, _("\
7d9813f1 5318 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5319 Use section <number|name> as the CTF external symtab\n"));
5320 fprintf (stream, _("\
7d9813f1 5321 --ctf-strings=<number|name>\n\
d6249f5f 5322 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5323#endif
7d9813f1 5324
252b5132 5325#ifdef SUPPORT_DISASSEMBLY
92f01d61 5326 fprintf (stream, _("\
09c11c86
NC
5327 -i --instruction-dump=<number|name>\n\
5328 Disassemble the contents of section <number|name>\n"));
252b5132 5329#endif
92f01d61 5330 fprintf (stream, _("\
d6249f5f
AM
5331 -I --histogram Display histogram of bucket list lengths\n"));
5332 fprintf (stream, _("\
5333 -W --wide Allow output width to exceed 80 characters\n"));
5334 fprintf (stream, _("\
5335 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5336 fprintf (stream, _("\
5337 @<file> Read options from <file>\n"));
5338 fprintf (stream, _("\
5339 -H --help Display this information\n"));
5340 fprintf (stream, _("\
8b53311e 5341 -v --version Display the version number of readelf\n"));
1118d252 5342
92f01d61
JM
5343 if (REPORT_BUGS_TO[0] && stream == stdout)
5344 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5345
92f01d61 5346 exit (stream == stdout ? 0 : 1);
252b5132
RH
5347}
5348
18bd398b
NC
5349/* Record the fact that the user wants the contents of section number
5350 SECTION to be displayed using the method(s) encoded as flags bits
5351 in TYPE. Note, TYPE can be zero if we are creating the array for
5352 the first time. */
5353
252b5132 5354static void
6431e409
AM
5355request_dump_bynumber (struct dump_data *dumpdata,
5356 unsigned int section, dump_type type)
252b5132 5357{
6431e409 5358 if (section >= dumpdata->num_dump_sects)
252b5132 5359 {
2cf0635d 5360 dump_type * new_dump_sects;
252b5132 5361
3f5e193b 5362 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5363 sizeof (* new_dump_sects));
252b5132
RH
5364
5365 if (new_dump_sects == NULL)
591a748a 5366 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5367 else
5368 {
6431e409 5369 if (dumpdata->dump_sects)
21b65bac
NC
5370 {
5371 /* Copy current flag settings. */
6431e409
AM
5372 memcpy (new_dump_sects, dumpdata->dump_sects,
5373 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5374
6431e409 5375 free (dumpdata->dump_sects);
21b65bac 5376 }
252b5132 5377
6431e409
AM
5378 dumpdata->dump_sects = new_dump_sects;
5379 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5380 }
5381 }
5382
6431e409
AM
5383 if (dumpdata->dump_sects)
5384 dumpdata->dump_sects[section] |= type;
252b5132
RH
5385}
5386
aef1f6d0
DJ
5387/* Request a dump by section name. */
5388
5389static void
2cf0635d 5390request_dump_byname (const char * section, dump_type type)
aef1f6d0 5391{
2cf0635d 5392 struct dump_list_entry * new_request;
aef1f6d0 5393
3f5e193b
NC
5394 new_request = (struct dump_list_entry *)
5395 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5396 if (!new_request)
591a748a 5397 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5398
5399 new_request->name = strdup (section);
5400 if (!new_request->name)
591a748a 5401 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5402
5403 new_request->type = type;
5404
5405 new_request->next = dump_sects_byname;
5406 dump_sects_byname = new_request;
5407}
5408
cf13d699 5409static inline void
6431e409 5410request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5411{
5412 int section;
5413 char * cp;
5414
015dc7e1 5415 do_dump = true;
cf13d699
NC
5416 section = strtoul (optarg, & cp, 0);
5417
5418 if (! *cp && section >= 0)
6431e409 5419 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5420 else
5421 request_dump_byname (optarg, type);
5422}
5423
252b5132 5424static void
6431e409 5425parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5426{
5427 int c;
5428
5429 if (argc < 2)
92f01d61 5430 usage (stderr);
252b5132
RH
5431
5432 while ((c = getopt_long
b3aa80b4 5433 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5434 {
252b5132
RH
5435 switch (c)
5436 {
5437 case 0:
5438 /* Long options. */
5439 break;
5440 case 'H':
92f01d61 5441 usage (stdout);
252b5132
RH
5442 break;
5443
5444 case 'a':
015dc7e1
AM
5445 do_syms = true;
5446 do_reloc = true;
5447 do_unwind = true;
5448 do_dynamic = true;
5449 do_header = true;
5450 do_sections = true;
5451 do_section_groups = true;
5452 do_segments = true;
5453 do_version = true;
5454 do_histogram = true;
5455 do_arch = true;
5456 do_notes = true;
252b5132 5457 break;
79bc120c 5458
f5842774 5459 case 'g':
015dc7e1 5460 do_section_groups = true;
f5842774 5461 break;
5477e8a0 5462 case 't':
595cf52e 5463 case 'N':
015dc7e1
AM
5464 do_sections = true;
5465 do_section_details = true;
595cf52e 5466 break;
252b5132 5467 case 'e':
015dc7e1
AM
5468 do_header = true;
5469 do_sections = true;
5470 do_segments = true;
252b5132 5471 break;
a952a375 5472 case 'A':
015dc7e1 5473 do_arch = true;
a952a375 5474 break;
252b5132 5475 case 'D':
015dc7e1 5476 do_using_dynamic = true;
252b5132
RH
5477 break;
5478 case 'r':
015dc7e1 5479 do_reloc = true;
252b5132 5480 break;
4d6ed7c8 5481 case 'u':
015dc7e1 5482 do_unwind = true;
4d6ed7c8 5483 break;
252b5132 5484 case 'h':
015dc7e1 5485 do_header = true;
252b5132
RH
5486 break;
5487 case 'l':
015dc7e1 5488 do_segments = true;
252b5132
RH
5489 break;
5490 case 's':
015dc7e1 5491 do_syms = true;
252b5132
RH
5492 break;
5493 case 'S':
015dc7e1 5494 do_sections = true;
252b5132
RH
5495 break;
5496 case 'd':
015dc7e1 5497 do_dynamic = true;
252b5132 5498 break;
a952a375 5499 case 'I':
015dc7e1 5500 do_histogram = true;
a952a375 5501 break;
779fe533 5502 case 'n':
015dc7e1 5503 do_notes = true;
779fe533 5504 break;
4145f1d5 5505 case 'c':
015dc7e1 5506 do_archive_index = true;
4145f1d5 5507 break;
1b513401 5508 case 'L':
015dc7e1 5509 do_checks = true;
1b513401 5510 break;
ca0e11aa 5511 case 'P':
015dc7e1
AM
5512 process_links = true;
5513 do_follow_links = true;
e1dbfc17 5514 dump_any_debugging = true;
ca0e11aa 5515 break;
252b5132 5516 case 'x':
6431e409 5517 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5518 break;
09c11c86 5519 case 'p':
6431e409 5520 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5521 break;
5522 case 'R':
6431e409 5523 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5524 break;
0e602686 5525 case 'z':
015dc7e1 5526 decompress_dumps = true;
0e602686 5527 break;
252b5132 5528 case 'w':
0f03783c 5529 if (optarg == NULL)
613ff48b 5530 {
015dc7e1 5531 do_debugging = true;
94585d6d
NC
5532 do_dump = true;
5533 dump_any_debugging = true;
613ff48b
CC
5534 dwarf_select_sections_all ();
5535 }
252b5132
RH
5536 else
5537 {
015dc7e1 5538 do_debugging = false;
94585d6d
NC
5539 if (dwarf_select_sections_by_letters (optarg))
5540 {
5541 do_dump = true;
5542 dump_any_debugging = true;
5543 }
252b5132
RH
5544 }
5545 break;
2979dc34 5546 case OPTION_DEBUG_DUMP:
0f03783c 5547 if (optarg == NULL)
d6249f5f 5548 {
94585d6d 5549 do_dump = true;
d6249f5f 5550 do_debugging = true;
94585d6d 5551 dump_any_debugging = true;
d6249f5f
AM
5552 dwarf_select_sections_all ();
5553 }
2979dc34
JJ
5554 else
5555 {
015dc7e1 5556 do_debugging = false;
94585d6d
NC
5557 if (dwarf_select_sections_by_names (optarg))
5558 {
5559 do_dump = true;
5560 dump_any_debugging = true;
5561 }
2979dc34
JJ
5562 }
5563 break;
fd2f0033
TT
5564 case OPTION_DWARF_DEPTH:
5565 {
5566 char *cp;
5567
5568 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5569 }
5570 break;
5571 case OPTION_DWARF_START:
5572 {
5573 char *cp;
5574
5575 dwarf_start_die = strtoul (optarg, & cp, 0);
5576 }
5577 break;
4723351a 5578 case OPTION_DWARF_CHECK:
015dc7e1 5579 dwarf_check = true;
4723351a 5580 break;
7d9813f1 5581 case OPTION_CTF_DUMP:
015dc7e1 5582 do_ctf = true;
6431e409 5583 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5584 break;
5585 case OPTION_CTF_SYMBOLS:
df16e041 5586 free (dump_ctf_symtab_name);
7d9813f1
NA
5587 dump_ctf_symtab_name = strdup (optarg);
5588 break;
5589 case OPTION_CTF_STRINGS:
df16e041 5590 free (dump_ctf_strtab_name);
7d9813f1
NA
5591 dump_ctf_strtab_name = strdup (optarg);
5592 break;
5593 case OPTION_CTF_PARENT:
df16e041 5594 free (dump_ctf_parent_name);
7d9813f1
NA
5595 dump_ctf_parent_name = strdup (optarg);
5596 break;
2c610e4b 5597 case OPTION_DYN_SYMS:
015dc7e1 5598 do_dyn_syms = true;
2c610e4b 5599 break;
0f03783c 5600 case OPTION_LTO_SYMS:
015dc7e1 5601 do_lto_syms = true;
0f03783c 5602 break;
252b5132
RH
5603#ifdef SUPPORT_DISASSEMBLY
5604 case 'i':
6431e409 5605 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5606 break;
252b5132
RH
5607#endif
5608 case 'v':
5609 print_version (program_name);
5610 break;
5611 case 'V':
015dc7e1 5612 do_version = true;
252b5132 5613 break;
d974e256 5614 case 'W':
015dc7e1 5615 do_wide = true;
d974e256 5616 break;
0942c7ab 5617 case 'T':
015dc7e1 5618 do_not_show_symbol_truncation = true;
0942c7ab 5619 break;
79bc120c 5620 case 'C':
015dc7e1 5621 do_demangle = true;
79bc120c
NC
5622 if (optarg != NULL)
5623 {
5624 enum demangling_styles style;
5625
5626 style = cplus_demangle_name_to_style (optarg);
5627 if (style == unknown_demangling)
5628 error (_("unknown demangling style `%s'"), optarg);
5629
5630 cplus_demangle_set_style (style);
5631 }
5632 break;
5633 case OPTION_NO_DEMANGLING:
015dc7e1 5634 do_demangle = false;
79bc120c
NC
5635 break;
5636 case OPTION_RECURSE_LIMIT:
5637 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5638 break;
5639 case OPTION_NO_RECURSE_LIMIT:
5640 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5641 break;
5642 case OPTION_WITH_SYMBOL_VERSIONS:
5643 /* Ignored for backward compatibility. */
5644 break;
b9e920ec 5645
b3aa80b4
NC
5646 case 'U':
5647 if (optarg == NULL)
5648 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5649 else if (streq (optarg, "default") || streq (optarg, "d"))
5650 unicode_display = unicode_default;
5651 else if (streq (optarg, "locale") || streq (optarg, "l"))
5652 unicode_display = unicode_locale;
5653 else if (streq (optarg, "escape") || streq (optarg, "e"))
5654 unicode_display = unicode_escape;
5655 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5656 unicode_display = unicode_invalid;
5657 else if (streq (optarg, "hex") || streq (optarg, "x"))
5658 unicode_display = unicode_hex;
5659 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5660 unicode_display = unicode_highlight;
5661 else
5662 error (_("invalid argument to -U/--unicode: %s"), optarg);
5663 break;
5664
047c3dbf
NL
5665 case OPTION_SYM_BASE:
5666 sym_base = 0;
5667 if (optarg != NULL)
5668 {
5669 sym_base = strtoul (optarg, NULL, 0);
5670 switch (sym_base)
5671 {
5672 case 0:
5673 case 8:
5674 case 10:
5675 case 16:
5676 break;
5677
5678 default:
5679 sym_base = 0;
5680 break;
5681 }
5682 }
5683 break;
5684
252b5132 5685 default:
252b5132
RH
5686 /* xgettext:c-format */
5687 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5688 /* Fall through. */
252b5132 5689 case '?':
92f01d61 5690 usage (stderr);
252b5132
RH
5691 }
5692 }
5693
4d6ed7c8 5694 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5695 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5696 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5697 && !do_section_groups && !do_archive_index
0f03783c 5698 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5699 {
5700 if (do_checks)
5701 {
015dc7e1
AM
5702 check_all = true;
5703 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5704 do_segments = do_header = do_dump = do_version = true;
5705 do_histogram = do_debugging = do_arch = do_notes = true;
5706 do_section_groups = do_archive_index = do_dyn_syms = true;
5707 do_lto_syms = true;
1b513401
NC
5708 }
5709 else
5710 usage (stderr);
5711 }
252b5132
RH
5712}
5713
5714static const char *
d3ba0551 5715get_elf_class (unsigned int elf_class)
252b5132 5716{
b34976b6 5717 static char buff[32];
103f02d3 5718
252b5132
RH
5719 switch (elf_class)
5720 {
5721 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5722 case ELFCLASS32: return "ELF32";
5723 case ELFCLASS64: return "ELF64";
ab5e7794 5724 default:
e9e44622 5725 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5726 return buff;
252b5132
RH
5727 }
5728}
5729
5730static const char *
d3ba0551 5731get_data_encoding (unsigned int encoding)
252b5132 5732{
b34976b6 5733 static char buff[32];
103f02d3 5734
252b5132
RH
5735 switch (encoding)
5736 {
5737 case ELFDATANONE: return _("none");
33c63f9d
CM
5738 case ELFDATA2LSB: return _("2's complement, little endian");
5739 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5740 default:
e9e44622 5741 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5742 return buff;
252b5132
RH
5743 }
5744}
5745
dda8d76d 5746/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5747
015dc7e1 5748static bool
dda8d76d 5749process_file_header (Filedata * filedata)
252b5132 5750{
dda8d76d
NC
5751 Elf_Internal_Ehdr * header = & filedata->file_header;
5752
5753 if ( header->e_ident[EI_MAG0] != ELFMAG0
5754 || header->e_ident[EI_MAG1] != ELFMAG1
5755 || header->e_ident[EI_MAG2] != ELFMAG2
5756 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5757 {
5758 error
5759 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5760 return false;
252b5132
RH
5761 }
5762
ca0e11aa
NC
5763 if (! filedata->is_separate)
5764 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5765
252b5132
RH
5766 if (do_header)
5767 {
32ec8896 5768 unsigned i;
252b5132 5769
ca0e11aa
NC
5770 if (filedata->is_separate)
5771 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5772 else
5773 printf (_("ELF Header:\n"));
252b5132 5774 printf (_(" Magic: "));
b34976b6 5775 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5776 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5777 printf ("\n");
5778 printf (_(" Class: %s\n"),
dda8d76d 5779 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5780 printf (_(" Data: %s\n"),
dda8d76d 5781 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5782 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5783 header->e_ident[EI_VERSION],
5784 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5785 ? _(" (current)")
dda8d76d 5786 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5787 ? _(" <unknown>")
789be9f7 5788 : "")));
252b5132 5789 printf (_(" OS/ABI: %s\n"),
dda8d76d 5790 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5791 printf (_(" ABI Version: %d\n"),
dda8d76d 5792 header->e_ident[EI_ABIVERSION]);
252b5132 5793 printf (_(" Type: %s\n"),
93df3340 5794 get_file_type (filedata));
252b5132 5795 printf (_(" Machine: %s\n"),
dda8d76d 5796 get_machine_name (header->e_machine));
252b5132 5797 printf (_(" Version: 0x%lx\n"),
e8a64888 5798 header->e_version);
76da6bbe 5799
f7a99963 5800 printf (_(" Entry point address: "));
e8a64888 5801 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5802 printf (_("\n Start of program headers: "));
e8a64888 5803 print_vma (header->e_phoff, DEC);
f7a99963 5804 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5805 print_vma (header->e_shoff, DEC);
f7a99963 5806 printf (_(" (bytes into file)\n"));
76da6bbe 5807
252b5132 5808 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5809 header->e_flags,
dda8d76d 5810 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5811 printf (_(" Size of this header: %u (bytes)\n"),
5812 header->e_ehsize);
5813 printf (_(" Size of program headers: %u (bytes)\n"),
5814 header->e_phentsize);
5815 printf (_(" Number of program headers: %u"),
5816 header->e_phnum);
dda8d76d
NC
5817 if (filedata->section_headers != NULL
5818 && header->e_phnum == PN_XNUM
5819 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5820 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5821 putc ('\n', stdout);
e8a64888
AM
5822 printf (_(" Size of section headers: %u (bytes)\n"),
5823 header->e_shentsize);
5824 printf (_(" Number of section headers: %u"),
5825 header->e_shnum);
dda8d76d 5826 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5827 {
5828 header->e_shnum = filedata->section_headers[0].sh_size;
5829 printf (" (%u)", header->e_shnum);
5830 }
560f3c1c 5831 putc ('\n', stdout);
e8a64888
AM
5832 printf (_(" Section header string table index: %u"),
5833 header->e_shstrndx);
dda8d76d
NC
5834 if (filedata->section_headers != NULL
5835 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5836 {
5837 header->e_shstrndx = filedata->section_headers[0].sh_link;
5838 printf (" (%u)", header->e_shstrndx);
5839 }
5840 if (header->e_shstrndx != SHN_UNDEF
5841 && header->e_shstrndx >= header->e_shnum)
5842 {
5843 header->e_shstrndx = SHN_UNDEF;
5844 printf (_(" <corrupt: out of range>"));
5845 }
560f3c1c
AM
5846 putc ('\n', stdout);
5847 }
5848
dda8d76d 5849 if (filedata->section_headers != NULL)
560f3c1c 5850 {
dda8d76d
NC
5851 if (header->e_phnum == PN_XNUM
5852 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5853 {
5854 /* Throw away any cached read of PN_XNUM headers. */
5855 free (filedata->program_headers);
5856 filedata->program_headers = NULL;
5857 header->e_phnum = filedata->section_headers[0].sh_info;
5858 }
dda8d76d
NC
5859 if (header->e_shnum == SHN_UNDEF)
5860 header->e_shnum = filedata->section_headers[0].sh_size;
5861 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5862 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5863 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5864 header->e_shstrndx = SHN_UNDEF;
252b5132 5865 }
103f02d3 5866
015dc7e1 5867 return true;
9ea033b2
NC
5868}
5869
dda8d76d
NC
5870/* Read in the program headers from FILEDATA and store them in PHEADERS.
5871 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5872
015dc7e1 5873static bool
dda8d76d 5874get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5875{
2cf0635d
NC
5876 Elf32_External_Phdr * phdrs;
5877 Elf32_External_Phdr * external;
5878 Elf_Internal_Phdr * internal;
b34976b6 5879 unsigned int i;
dda8d76d
NC
5880 unsigned int size = filedata->file_header.e_phentsize;
5881 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5882
5883 /* PR binutils/17531: Cope with unexpected section header sizes. */
5884 if (size == 0 || num == 0)
015dc7e1 5885 return false;
e0a31db1
NC
5886 if (size < sizeof * phdrs)
5887 {
5888 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5889 return false;
e0a31db1
NC
5890 }
5891 if (size > sizeof * phdrs)
5892 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5893
dda8d76d 5894 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5895 size, num, _("program headers"));
5896 if (phdrs == NULL)
015dc7e1 5897 return false;
9ea033b2 5898
91d6fa6a 5899 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5900 i < filedata->file_header.e_phnum;
b34976b6 5901 i++, internal++, external++)
252b5132 5902 {
9ea033b2
NC
5903 internal->p_type = BYTE_GET (external->p_type);
5904 internal->p_offset = BYTE_GET (external->p_offset);
5905 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5906 internal->p_paddr = BYTE_GET (external->p_paddr);
5907 internal->p_filesz = BYTE_GET (external->p_filesz);
5908 internal->p_memsz = BYTE_GET (external->p_memsz);
5909 internal->p_flags = BYTE_GET (external->p_flags);
5910 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5911 }
5912
9ea033b2 5913 free (phdrs);
015dc7e1 5914 return true;
252b5132
RH
5915}
5916
dda8d76d
NC
5917/* Read in the program headers from FILEDATA and store them in PHEADERS.
5918 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5919
015dc7e1 5920static bool
dda8d76d 5921get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5922{
2cf0635d
NC
5923 Elf64_External_Phdr * phdrs;
5924 Elf64_External_Phdr * external;
5925 Elf_Internal_Phdr * internal;
b34976b6 5926 unsigned int i;
dda8d76d
NC
5927 unsigned int size = filedata->file_header.e_phentsize;
5928 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5929
5930 /* PR binutils/17531: Cope with unexpected section header sizes. */
5931 if (size == 0 || num == 0)
015dc7e1 5932 return false;
e0a31db1
NC
5933 if (size < sizeof * phdrs)
5934 {
5935 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5936 return false;
e0a31db1
NC
5937 }
5938 if (size > sizeof * phdrs)
5939 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5940
dda8d76d 5941 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5942 size, num, _("program headers"));
a6e9f9df 5943 if (!phdrs)
015dc7e1 5944 return false;
9ea033b2 5945
91d6fa6a 5946 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5947 i < filedata->file_header.e_phnum;
b34976b6 5948 i++, internal++, external++)
9ea033b2
NC
5949 {
5950 internal->p_type = BYTE_GET (external->p_type);
5951 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5952 internal->p_offset = BYTE_GET (external->p_offset);
5953 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5954 internal->p_paddr = BYTE_GET (external->p_paddr);
5955 internal->p_filesz = BYTE_GET (external->p_filesz);
5956 internal->p_memsz = BYTE_GET (external->p_memsz);
5957 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5958 }
5959
5960 free (phdrs);
015dc7e1 5961 return true;
9ea033b2 5962}
252b5132 5963
32ec8896 5964/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5965
015dc7e1 5966static bool
dda8d76d 5967get_program_headers (Filedata * filedata)
d93f0186 5968{
2cf0635d 5969 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5970
5971 /* Check cache of prior read. */
dda8d76d 5972 if (filedata->program_headers != NULL)
015dc7e1 5973 return true;
d93f0186 5974
82156ab7
NC
5975 /* Be kind to memory checkers by looking for
5976 e_phnum values which we know must be invalid. */
dda8d76d 5977 if (filedata->file_header.e_phnum
82156ab7 5978 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5979 >= filedata->file_size)
82156ab7
NC
5980 {
5981 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5982 filedata->file_header.e_phnum);
015dc7e1 5983 return false;
82156ab7 5984 }
d93f0186 5985
dda8d76d 5986 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5987 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5988 if (phdrs == NULL)
5989 {
8b73c356 5990 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5991 filedata->file_header.e_phnum);
015dc7e1 5992 return false;
d93f0186
NC
5993 }
5994
5995 if (is_32bit_elf
dda8d76d
NC
5996 ? get_32bit_program_headers (filedata, phdrs)
5997 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5998 {
dda8d76d 5999 filedata->program_headers = phdrs;
015dc7e1 6000 return true;
d93f0186
NC
6001 }
6002
6003 free (phdrs);
015dc7e1 6004 return false;
d93f0186
NC
6005}
6006
93df3340 6007/* Print program header info and locate dynamic section. */
2f62977e 6008
93df3340 6009static void
dda8d76d 6010process_program_headers (Filedata * filedata)
252b5132 6011{
2cf0635d 6012 Elf_Internal_Phdr * segment;
b34976b6 6013 unsigned int i;
1a9ccd70 6014 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6015
dda8d76d 6016 if (filedata->file_header.e_phnum == 0)
252b5132 6017 {
82f2dbf7 6018 /* PR binutils/12467. */
dda8d76d 6019 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6020 warn (_("possibly corrupt ELF header - it has a non-zero program"
6021 " header offset, but no program headers\n"));
82f2dbf7 6022 else if (do_segments)
ca0e11aa
NC
6023 {
6024 if (filedata->is_separate)
6025 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6026 filedata->file_name);
6027 else
6028 printf (_("\nThere are no program headers in this file.\n"));
6029 }
93df3340 6030 goto no_headers;
252b5132
RH
6031 }
6032
6033 if (do_segments && !do_header)
6034 {
ca0e11aa
NC
6035 if (filedata->is_separate)
6036 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6037 filedata->file_name, get_file_type (filedata));
ca0e11aa 6038 else
93df3340 6039 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 6040 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
6041 printf (ngettext ("There is %d program header, starting at offset %s\n",
6042 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
6043 filedata->file_header.e_phnum),
6044 filedata->file_header.e_phnum,
6045 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
6046 }
6047
dda8d76d 6048 if (! get_program_headers (filedata))
93df3340 6049 goto no_headers;
103f02d3 6050
252b5132
RH
6051 if (do_segments)
6052 {
dda8d76d 6053 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6054 printf (_("\nProgram Headers:\n"));
6055 else
6056 printf (_("\nProgram Headers:\n"));
76da6bbe 6057
f7a99963
NC
6058 if (is_32bit_elf)
6059 printf
6060 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6061 else if (do_wide)
6062 printf
6063 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6064 else
6065 {
6066 printf
6067 (_(" Type Offset VirtAddr PhysAddr\n"));
6068 printf
6069 (_(" FileSiz MemSiz Flags Align\n"));
6070 }
252b5132
RH
6071 }
6072
93df3340
AM
6073 unsigned long dynamic_addr = 0;
6074 bfd_size_type dynamic_size = 0;
dda8d76d
NC
6075 for (i = 0, segment = filedata->program_headers;
6076 i < filedata->file_header.e_phnum;
b34976b6 6077 i++, segment++)
252b5132
RH
6078 {
6079 if (do_segments)
6080 {
dda8d76d 6081 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6082
6083 if (is_32bit_elf)
6084 {
6085 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6086 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6087 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6088 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6089 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6090 printf ("%c%c%c ",
6091 (segment->p_flags & PF_R ? 'R' : ' '),
6092 (segment->p_flags & PF_W ? 'W' : ' '),
6093 (segment->p_flags & PF_X ? 'E' : ' '));
6094 printf ("%#lx", (unsigned long) segment->p_align);
6095 }
d974e256
JJ
6096 else if (do_wide)
6097 {
6098 if ((unsigned long) segment->p_offset == segment->p_offset)
6099 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6100 else
6101 {
6102 print_vma (segment->p_offset, FULL_HEX);
6103 putchar (' ');
6104 }
6105
6106 print_vma (segment->p_vaddr, FULL_HEX);
6107 putchar (' ');
6108 print_vma (segment->p_paddr, FULL_HEX);
6109 putchar (' ');
6110
6111 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6112 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6113 else
6114 {
6115 print_vma (segment->p_filesz, FULL_HEX);
6116 putchar (' ');
6117 }
6118
6119 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6120 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6121 else
6122 {
f48e6c45 6123 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6124 }
6125
6126 printf (" %c%c%c ",
6127 (segment->p_flags & PF_R ? 'R' : ' '),
6128 (segment->p_flags & PF_W ? 'W' : ' '),
6129 (segment->p_flags & PF_X ? 'E' : ' '));
6130
6131 if ((unsigned long) segment->p_align == segment->p_align)
6132 printf ("%#lx", (unsigned long) segment->p_align);
6133 else
6134 {
6135 print_vma (segment->p_align, PREFIX_HEX);
6136 }
6137 }
f7a99963
NC
6138 else
6139 {
6140 print_vma (segment->p_offset, FULL_HEX);
6141 putchar (' ');
6142 print_vma (segment->p_vaddr, FULL_HEX);
6143 putchar (' ');
6144 print_vma (segment->p_paddr, FULL_HEX);
6145 printf ("\n ");
6146 print_vma (segment->p_filesz, FULL_HEX);
6147 putchar (' ');
6148 print_vma (segment->p_memsz, FULL_HEX);
6149 printf (" %c%c%c ",
6150 (segment->p_flags & PF_R ? 'R' : ' '),
6151 (segment->p_flags & PF_W ? 'W' : ' '),
6152 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6153 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6154 }
252b5132 6155
1a9ccd70
NC
6156 putc ('\n', stdout);
6157 }
f54498b4 6158
252b5132
RH
6159 switch (segment->p_type)
6160 {
1a9ccd70 6161 case PT_LOAD:
502d895c
NC
6162#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6163 required by the ELF standard, several programs, including the Linux
6164 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6165 if (previous_load
6166 && previous_load->p_vaddr > segment->p_vaddr)
6167 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6168#endif
1a9ccd70
NC
6169 if (segment->p_memsz < segment->p_filesz)
6170 error (_("the segment's file size is larger than its memory size\n"));
6171 previous_load = segment;
6172 break;
6173
6174 case PT_PHDR:
6175 /* PR 20815 - Verify that the program header is loaded into memory. */
6176 if (i > 0 && previous_load != NULL)
6177 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6178 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6179 {
6180 unsigned int j;
6181
dda8d76d 6182 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6183 {
6184 Elf_Internal_Phdr *load = filedata->program_headers + j;
6185 if (load->p_type == PT_LOAD
6186 && load->p_offset <= segment->p_offset
6187 && (load->p_offset + load->p_filesz
6188 >= segment->p_offset + segment->p_filesz)
6189 && load->p_vaddr <= segment->p_vaddr
6190 && (load->p_vaddr + load->p_filesz
6191 >= segment->p_vaddr + segment->p_filesz))
6192 break;
6193 }
dda8d76d 6194 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6195 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6196 }
6197 break;
6198
252b5132 6199 case PT_DYNAMIC:
93df3340 6200 if (dynamic_addr)
252b5132
RH
6201 error (_("more than one dynamic segment\n"));
6202
20737c13
AM
6203 /* By default, assume that the .dynamic section is the first
6204 section in the DYNAMIC segment. */
93df3340
AM
6205 dynamic_addr = segment->p_offset;
6206 dynamic_size = segment->p_filesz;
20737c13 6207
b2d38a17
NC
6208 /* Try to locate the .dynamic section. If there is
6209 a section header table, we can easily locate it. */
dda8d76d 6210 if (filedata->section_headers != NULL)
b2d38a17 6211 {
2cf0635d 6212 Elf_Internal_Shdr * sec;
b2d38a17 6213
dda8d76d 6214 sec = find_section (filedata, ".dynamic");
89fac5e3 6215 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6216 {
93df3340
AM
6217 /* A corresponding .dynamic section is expected, but on
6218 IA-64/OpenVMS it is OK for it to be missing. */
6219 if (!is_ia64_vms (filedata))
6220 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6221 break;
6222 }
6223
42bb2e33 6224 if (sec->sh_type == SHT_NOBITS)
20737c13 6225 {
93df3340
AM
6226 dynamic_addr = 0;
6227 dynamic_size = 0;
20737c13
AM
6228 break;
6229 }
42bb2e33 6230
93df3340
AM
6231 dynamic_addr = sec->sh_offset;
6232 dynamic_size = sec->sh_size;
b2d38a17 6233
8ac10c5b
L
6234 /* The PT_DYNAMIC segment, which is used by the run-time
6235 loader, should exactly match the .dynamic section. */
6236 if (do_checks
93df3340
AM
6237 && (dynamic_addr != segment->p_offset
6238 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6239 warn (_("\
6240the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6241 }
39e224f6
MW
6242
6243 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6244 segment. Check this after matching against the section headers
6245 so we don't warn on debuginfo file (which have NOBITS .dynamic
6246 sections). */
93df3340
AM
6247 if (dynamic_addr > filedata->file_size
6248 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6249 {
6250 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6251 dynamic_addr = 0;
6252 dynamic_size = 0;
39e224f6 6253 }
252b5132
RH
6254 break;
6255
6256 case PT_INTERP:
13acb58d
AM
6257 if (segment->p_offset >= filedata->file_size
6258 || segment->p_filesz > filedata->file_size - segment->p_offset
6259 || segment->p_filesz - 1 >= (size_t) -2
6260 || fseek (filedata->handle,
6261 filedata->archive_file_offset + (long) segment->p_offset,
6262 SEEK_SET))
252b5132
RH
6263 error (_("Unable to find program interpreter name\n"));
6264 else
6265 {
13acb58d
AM
6266 size_t len = segment->p_filesz;
6267 free (filedata->program_interpreter);
6268 filedata->program_interpreter = xmalloc (len + 1);
6269 len = fread (filedata->program_interpreter, 1, len,
6270 filedata->handle);
6271 filedata->program_interpreter[len] = 0;
252b5132
RH
6272
6273 if (do_segments)
f54498b4 6274 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6275 filedata->program_interpreter);
252b5132
RH
6276 }
6277 break;
6278 }
252b5132
RH
6279 }
6280
dda8d76d
NC
6281 if (do_segments
6282 && filedata->section_headers != NULL
6283 && filedata->string_table != NULL)
252b5132
RH
6284 {
6285 printf (_("\n Section to Segment mapping:\n"));
6286 printf (_(" Segment Sections...\n"));
6287
dda8d76d 6288 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6289 {
9ad5cbcf 6290 unsigned int j;
2cf0635d 6291 Elf_Internal_Shdr * section;
252b5132 6292
dda8d76d
NC
6293 segment = filedata->program_headers + i;
6294 section = filedata->section_headers + 1;
252b5132
RH
6295
6296 printf (" %2.2d ", i);
6297
dda8d76d 6298 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6299 {
f4638467
AM
6300 if (!ELF_TBSS_SPECIAL (section, segment)
6301 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6302 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6303 }
6304
6305 putc ('\n',stdout);
6306 }
6307 }
6308
93df3340
AM
6309 filedata->dynamic_addr = dynamic_addr;
6310 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6311 return;
6312
6313 no_headers:
6314 filedata->dynamic_addr = 0;
6315 filedata->dynamic_size = 1;
252b5132
RH
6316}
6317
6318
d93f0186
NC
6319/* Find the file offset corresponding to VMA by using the program headers. */
6320
6321static long
dda8d76d 6322offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6323{
2cf0635d 6324 Elf_Internal_Phdr * seg;
d93f0186 6325
dda8d76d 6326 if (! get_program_headers (filedata))
d93f0186
NC
6327 {
6328 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6329 return (long) vma;
6330 }
6331
dda8d76d
NC
6332 for (seg = filedata->program_headers;
6333 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6334 ++seg)
6335 {
6336 if (seg->p_type != PT_LOAD)
6337 continue;
6338
6339 if (vma >= (seg->p_vaddr & -seg->p_align)
6340 && vma + size <= seg->p_vaddr + seg->p_filesz)
6341 return vma - seg->p_vaddr + seg->p_offset;
6342 }
6343
6344 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6345 (unsigned long) vma);
d93f0186
NC
6346 return (long) vma;
6347}
6348
6349
dda8d76d
NC
6350/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6351 If PROBE is true, this is just a probe and we do not generate any error
6352 messages if the load fails. */
049b0c3a 6353
015dc7e1
AM
6354static bool
6355get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6356{
2cf0635d
NC
6357 Elf32_External_Shdr * shdrs;
6358 Elf_Internal_Shdr * internal;
dda8d76d
NC
6359 unsigned int i;
6360 unsigned int size = filedata->file_header.e_shentsize;
6361 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6362
6363 /* PR binutils/17531: Cope with unexpected section header sizes. */
6364 if (size == 0 || num == 0)
015dc7e1 6365 return false;
049b0c3a
NC
6366 if (size < sizeof * shdrs)
6367 {
6368 if (! probe)
6369 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6370 return false;
049b0c3a
NC
6371 }
6372 if (!probe && size > sizeof * shdrs)
6373 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6374
dda8d76d 6375 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6376 size, num,
6377 probe ? NULL : _("section headers"));
6378 if (shdrs == NULL)
015dc7e1 6379 return false;
252b5132 6380
dda8d76d
NC
6381 filedata->section_headers = (Elf_Internal_Shdr *)
6382 cmalloc (num, sizeof (Elf_Internal_Shdr));
6383 if (filedata->section_headers == NULL)
252b5132 6384 {
049b0c3a 6385 if (!probe)
8b73c356 6386 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6387 free (shdrs);
015dc7e1 6388 return false;
252b5132
RH
6389 }
6390
dda8d76d 6391 for (i = 0, internal = filedata->section_headers;
560f3c1c 6392 i < num;
b34976b6 6393 i++, internal++)
252b5132
RH
6394 {
6395 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6396 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6397 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6398 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6399 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6400 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6401 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6402 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6403 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6404 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6405 if (!probe && internal->sh_link > num)
6406 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6407 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6408 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6409 }
6410
6411 free (shdrs);
015dc7e1 6412 return true;
252b5132
RH
6413}
6414
dda8d76d
NC
6415/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6416
015dc7e1
AM
6417static bool
6418get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6419{
dda8d76d
NC
6420 Elf64_External_Shdr * shdrs;
6421 Elf_Internal_Shdr * internal;
6422 unsigned int i;
6423 unsigned int size = filedata->file_header.e_shentsize;
6424 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6425
6426 /* PR binutils/17531: Cope with unexpected section header sizes. */
6427 if (size == 0 || num == 0)
015dc7e1 6428 return false;
dda8d76d 6429
049b0c3a
NC
6430 if (size < sizeof * shdrs)
6431 {
6432 if (! probe)
6433 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6434 return false;
049b0c3a 6435 }
dda8d76d 6436
049b0c3a
NC
6437 if (! probe && size > sizeof * shdrs)
6438 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6439
dda8d76d
NC
6440 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6441 filedata->file_header.e_shoff,
049b0c3a
NC
6442 size, num,
6443 probe ? NULL : _("section headers"));
6444 if (shdrs == NULL)
015dc7e1 6445 return false;
9ea033b2 6446
dda8d76d
NC
6447 filedata->section_headers = (Elf_Internal_Shdr *)
6448 cmalloc (num, sizeof (Elf_Internal_Shdr));
6449 if (filedata->section_headers == NULL)
9ea033b2 6450 {
049b0c3a 6451 if (! probe)
8b73c356 6452 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6453 free (shdrs);
015dc7e1 6454 return false;
9ea033b2
NC
6455 }
6456
dda8d76d 6457 for (i = 0, internal = filedata->section_headers;
560f3c1c 6458 i < num;
b34976b6 6459 i++, internal++)
9ea033b2
NC
6460 {
6461 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6462 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6463 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6464 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6465 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6466 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6467 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6468 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6469 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6470 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6471 if (!probe && internal->sh_link > num)
6472 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6473 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6474 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6475 }
6476
6477 free (shdrs);
015dc7e1 6478 return true;
9ea033b2
NC
6479}
6480
4de91c10
AM
6481static bool
6482get_section_headers (Filedata *filedata, bool probe)
6483{
6484 if (filedata->section_headers != NULL)
6485 return true;
6486
4de91c10
AM
6487 if (is_32bit_elf)
6488 return get_32bit_section_headers (filedata, probe);
6489 else
6490 return get_64bit_section_headers (filedata, probe);
6491}
6492
252b5132 6493static Elf_Internal_Sym *
dda8d76d
NC
6494get_32bit_elf_symbols (Filedata * filedata,
6495 Elf_Internal_Shdr * section,
6496 unsigned long * num_syms_return)
252b5132 6497{
ba5cdace 6498 unsigned long number = 0;
dd24e3da 6499 Elf32_External_Sym * esyms = NULL;
ba5cdace 6500 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6501 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6502 Elf_Internal_Sym * psym;
b34976b6 6503 unsigned int j;
e3d39609 6504 elf_section_list * entry;
252b5132 6505
c9c1d674
EG
6506 if (section->sh_size == 0)
6507 {
6508 if (num_syms_return != NULL)
6509 * num_syms_return = 0;
6510 return NULL;
6511 }
6512
dd24e3da 6513 /* Run some sanity checks first. */
c9c1d674 6514 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6515 {
c9c1d674 6516 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6517 printable_section_name (filedata, section),
6518 (unsigned long) section->sh_entsize);
ba5cdace 6519 goto exit_point;
dd24e3da
NC
6520 }
6521
dda8d76d 6522 if (section->sh_size > filedata->file_size)
f54498b4
NC
6523 {
6524 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6525 printable_section_name (filedata, section),
6526 (unsigned long) section->sh_size);
f54498b4
NC
6527 goto exit_point;
6528 }
6529
dd24e3da
NC
6530 number = section->sh_size / section->sh_entsize;
6531
6532 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6533 {
c9c1d674 6534 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6535 (unsigned long) section->sh_size,
dda8d76d 6536 printable_section_name (filedata, section),
8066deb1 6537 (unsigned long) section->sh_entsize);
ba5cdace 6538 goto exit_point;
dd24e3da
NC
6539 }
6540
dda8d76d 6541 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6542 section->sh_size, _("symbols"));
dd24e3da 6543 if (esyms == NULL)
ba5cdace 6544 goto exit_point;
252b5132 6545
e3d39609 6546 shndx = NULL;
978c4450 6547 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6548 {
6549 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6550 continue;
6551
6552 if (shndx != NULL)
6553 {
6554 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6555 free (shndx);
6556 }
6557
6558 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6559 entry->hdr->sh_offset,
6560 1, entry->hdr->sh_size,
6561 _("symbol table section indices"));
6562 if (shndx == NULL)
6563 goto exit_point;
6564
6565 /* PR17531: file: heap-buffer-overflow */
6566 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6567 {
6568 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6569 printable_section_name (filedata, entry->hdr),
6570 (unsigned long) entry->hdr->sh_size,
6571 (unsigned long) section->sh_size);
6572 goto exit_point;
c9c1d674 6573 }
e3d39609 6574 }
9ad5cbcf 6575
3f5e193b 6576 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6577
6578 if (isyms == NULL)
6579 {
8b73c356
NC
6580 error (_("Out of memory reading %lu symbols\n"),
6581 (unsigned long) number);
dd24e3da 6582 goto exit_point;
252b5132
RH
6583 }
6584
dd24e3da 6585 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6586 {
6587 psym->st_name = BYTE_GET (esyms[j].st_name);
6588 psym->st_value = BYTE_GET (esyms[j].st_value);
6589 psym->st_size = BYTE_GET (esyms[j].st_size);
6590 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6591 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6592 psym->st_shndx
6593 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6594 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6595 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6596 psym->st_info = BYTE_GET (esyms[j].st_info);
6597 psym->st_other = BYTE_GET (esyms[j].st_other);
6598 }
6599
dd24e3da 6600 exit_point:
e3d39609
NC
6601 free (shndx);
6602 free (esyms);
252b5132 6603
ba5cdace
NC
6604 if (num_syms_return != NULL)
6605 * num_syms_return = isyms == NULL ? 0 : number;
6606
252b5132
RH
6607 return isyms;
6608}
6609
9ea033b2 6610static Elf_Internal_Sym *
dda8d76d
NC
6611get_64bit_elf_symbols (Filedata * filedata,
6612 Elf_Internal_Shdr * section,
6613 unsigned long * num_syms_return)
9ea033b2 6614{
ba5cdace
NC
6615 unsigned long number = 0;
6616 Elf64_External_Sym * esyms = NULL;
6617 Elf_External_Sym_Shndx * shndx = NULL;
6618 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6619 Elf_Internal_Sym * psym;
b34976b6 6620 unsigned int j;
e3d39609 6621 elf_section_list * entry;
9ea033b2 6622
c9c1d674
EG
6623 if (section->sh_size == 0)
6624 {
6625 if (num_syms_return != NULL)
6626 * num_syms_return = 0;
6627 return NULL;
6628 }
6629
dd24e3da 6630 /* Run some sanity checks first. */
c9c1d674 6631 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6632 {
c9c1d674 6633 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6634 printable_section_name (filedata, section),
8066deb1 6635 (unsigned long) section->sh_entsize);
ba5cdace 6636 goto exit_point;
dd24e3da
NC
6637 }
6638
dda8d76d 6639 if (section->sh_size > filedata->file_size)
f54498b4
NC
6640 {
6641 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6642 printable_section_name (filedata, section),
8066deb1 6643 (unsigned long) section->sh_size);
f54498b4
NC
6644 goto exit_point;
6645 }
6646
dd24e3da
NC
6647 number = section->sh_size / section->sh_entsize;
6648
6649 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6650 {
c9c1d674 6651 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6652 (unsigned long) section->sh_size,
dda8d76d 6653 printable_section_name (filedata, section),
8066deb1 6654 (unsigned long) section->sh_entsize);
ba5cdace 6655 goto exit_point;
dd24e3da
NC
6656 }
6657
dda8d76d 6658 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6659 section->sh_size, _("symbols"));
a6e9f9df 6660 if (!esyms)
ba5cdace 6661 goto exit_point;
9ea033b2 6662
e3d39609 6663 shndx = NULL;
978c4450 6664 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6665 {
6666 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6667 continue;
6668
6669 if (shndx != NULL)
6670 {
6671 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6672 free (shndx);
c9c1d674 6673 }
e3d39609
NC
6674
6675 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6676 entry->hdr->sh_offset,
6677 1, entry->hdr->sh_size,
6678 _("symbol table section indices"));
6679 if (shndx == NULL)
6680 goto exit_point;
6681
6682 /* PR17531: file: heap-buffer-overflow */
6683 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6684 {
6685 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6686 printable_section_name (filedata, entry->hdr),
6687 (unsigned long) entry->hdr->sh_size,
6688 (unsigned long) section->sh_size);
6689 goto exit_point;
6690 }
6691 }
9ad5cbcf 6692
3f5e193b 6693 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6694
6695 if (isyms == NULL)
6696 {
8b73c356
NC
6697 error (_("Out of memory reading %lu symbols\n"),
6698 (unsigned long) number);
ba5cdace 6699 goto exit_point;
9ea033b2
NC
6700 }
6701
ba5cdace 6702 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6703 {
6704 psym->st_name = BYTE_GET (esyms[j].st_name);
6705 psym->st_info = BYTE_GET (esyms[j].st_info);
6706 psym->st_other = BYTE_GET (esyms[j].st_other);
6707 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6708
4fbb74a6 6709 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6710 psym->st_shndx
6711 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6712 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6713 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6714
66543521
AM
6715 psym->st_value = BYTE_GET (esyms[j].st_value);
6716 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6717 }
6718
ba5cdace 6719 exit_point:
e3d39609
NC
6720 free (shndx);
6721 free (esyms);
ba5cdace
NC
6722
6723 if (num_syms_return != NULL)
6724 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6725
6726 return isyms;
6727}
6728
4de91c10
AM
6729static Elf_Internal_Sym *
6730get_elf_symbols (Filedata *filedata,
6731 Elf_Internal_Shdr *section,
6732 unsigned long *num_syms_return)
6733{
6734 if (is_32bit_elf)
6735 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6736 else
6737 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6738}
6739
d1133906 6740static const char *
dda8d76d 6741get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6742{
5477e8a0 6743 static char buff[1024];
2cf0635d 6744 char * p = buff;
32ec8896
NC
6745 unsigned int field_size = is_32bit_elf ? 8 : 16;
6746 signed int sindex;
6747 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6748 bfd_vma os_flags = 0;
6749 bfd_vma proc_flags = 0;
6750 bfd_vma unknown_flags = 0;
148b93f2 6751 static const struct
5477e8a0 6752 {
2cf0635d 6753 const char * str;
32ec8896 6754 unsigned int len;
5477e8a0
L
6755 }
6756 flags [] =
6757 {
cfcac11d
NC
6758 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6759 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6760 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6761 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6762 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6763 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6764 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6765 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6766 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6767 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6768 /* IA-64 specific. */
6769 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6770 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6771 /* IA-64 OpenVMS specific. */
6772 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6773 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6774 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6775 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6776 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6777 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6778 /* Generic. */
cfcac11d 6779 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6780 /* SPARC specific. */
77115a4a 6781 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6782 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6783 /* ARM specific. */
6784 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6785 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6786 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6787 /* GNU specific. */
6788 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6789 /* VLE specific. */
6790 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6791 /* GNU specific. */
6792 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6793 };
6794
6795 if (do_section_details)
6796 {
8d5ff12c
L
6797 sprintf (buff, "[%*.*lx]: ",
6798 field_size, field_size, (unsigned long) sh_flags);
6799 p += field_size + 4;
5477e8a0 6800 }
76da6bbe 6801
d1133906
NC
6802 while (sh_flags)
6803 {
6804 bfd_vma flag;
6805
6806 flag = sh_flags & - sh_flags;
6807 sh_flags &= ~ flag;
76da6bbe 6808
5477e8a0 6809 if (do_section_details)
d1133906 6810 {
5477e8a0
L
6811 switch (flag)
6812 {
91d6fa6a
NC
6813 case SHF_WRITE: sindex = 0; break;
6814 case SHF_ALLOC: sindex = 1; break;
6815 case SHF_EXECINSTR: sindex = 2; break;
6816 case SHF_MERGE: sindex = 3; break;
6817 case SHF_STRINGS: sindex = 4; break;
6818 case SHF_INFO_LINK: sindex = 5; break;
6819 case SHF_LINK_ORDER: sindex = 6; break;
6820 case SHF_OS_NONCONFORMING: sindex = 7; break;
6821 case SHF_GROUP: sindex = 8; break;
6822 case SHF_TLS: sindex = 9; break;
18ae9cc1 6823 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6824 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6825
5477e8a0 6826 default:
91d6fa6a 6827 sindex = -1;
dda8d76d 6828 switch (filedata->file_header.e_machine)
148b93f2 6829 {
cfcac11d 6830 case EM_IA_64:
148b93f2 6831 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6832 sindex = 10;
148b93f2 6833 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6834 sindex = 11;
148b93f2 6835#ifdef BFD64
dda8d76d 6836 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6837 switch (flag)
6838 {
91d6fa6a
NC
6839 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6840 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6841 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6842 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6843 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6844 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6845 default: break;
6846 }
6847#endif
cfcac11d
NC
6848 break;
6849
caa83f8b 6850 case EM_386:
22abe556 6851 case EM_IAMCU:
caa83f8b 6852 case EM_X86_64:
7f502d6c 6853 case EM_L1OM:
7a9068fe 6854 case EM_K1OM:
cfcac11d
NC
6855 case EM_OLD_SPARCV9:
6856 case EM_SPARC32PLUS:
6857 case EM_SPARCV9:
6858 case EM_SPARC:
18ae9cc1 6859 if (flag == SHF_ORDERED)
91d6fa6a 6860 sindex = 19;
cfcac11d 6861 break;
ac4c9b04
MG
6862
6863 case EM_ARM:
6864 switch (flag)
6865 {
6866 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6867 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6868 case SHF_COMDEF: sindex = 23; break;
6869 default: break;
6870 }
6871 break;
83eef883
AFB
6872 case EM_PPC:
6873 if (flag == SHF_PPC_VLE)
6874 sindex = 25;
6875 break;
99fabbc9
JL
6876 default:
6877 break;
6878 }
ac4c9b04 6879
99fabbc9
JL
6880 switch (filedata->file_header.e_ident[EI_OSABI])
6881 {
6882 case ELFOSABI_GNU:
6883 case ELFOSABI_FREEBSD:
6884 if (flag == SHF_GNU_RETAIN)
6885 sindex = 26;
6886 /* Fall through */
6887 case ELFOSABI_NONE:
6888 if (flag == SHF_GNU_MBIND)
6889 /* We should not recognize SHF_GNU_MBIND for
6890 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6891 not set the EI_OSABI header byte. */
6892 sindex = 24;
6893 break;
cfcac11d
NC
6894 default:
6895 break;
148b93f2 6896 }
99fabbc9 6897 break;
5477e8a0
L
6898 }
6899
91d6fa6a 6900 if (sindex != -1)
5477e8a0 6901 {
8d5ff12c
L
6902 if (p != buff + field_size + 4)
6903 {
6904 if (size < (10 + 2))
bee0ee85
NC
6905 {
6906 warn (_("Internal error: not enough buffer room for section flag info"));
6907 return _("<unknown>");
6908 }
8d5ff12c
L
6909 size -= 2;
6910 *p++ = ',';
6911 *p++ = ' ';
6912 }
6913
91d6fa6a
NC
6914 size -= flags [sindex].len;
6915 p = stpcpy (p, flags [sindex].str);
5477e8a0 6916 }
3b22753a 6917 else if (flag & SHF_MASKOS)
8d5ff12c 6918 os_flags |= flag;
d1133906 6919 else if (flag & SHF_MASKPROC)
8d5ff12c 6920 proc_flags |= flag;
d1133906 6921 else
8d5ff12c 6922 unknown_flags |= flag;
5477e8a0
L
6923 }
6924 else
6925 {
6926 switch (flag)
6927 {
6928 case SHF_WRITE: *p = 'W'; break;
6929 case SHF_ALLOC: *p = 'A'; break;
6930 case SHF_EXECINSTR: *p = 'X'; break;
6931 case SHF_MERGE: *p = 'M'; break;
6932 case SHF_STRINGS: *p = 'S'; break;
6933 case SHF_INFO_LINK: *p = 'I'; break;
6934 case SHF_LINK_ORDER: *p = 'L'; break;
6935 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6936 case SHF_GROUP: *p = 'G'; break;
6937 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6938 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6939 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6940
6941 default:
dda8d76d
NC
6942 if ((filedata->file_header.e_machine == EM_X86_64
6943 || filedata->file_header.e_machine == EM_L1OM
6944 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6945 && flag == SHF_X86_64_LARGE)
6946 *p = 'l';
dda8d76d 6947 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6948 && flag == SHF_ARM_PURECODE)
99fabbc9 6949 *p = 'y';
dda8d76d 6950 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6951 && flag == SHF_PPC_VLE)
99fabbc9 6952 *p = 'v';
5477e8a0
L
6953 else if (flag & SHF_MASKOS)
6954 {
99fabbc9
JL
6955 switch (filedata->file_header.e_ident[EI_OSABI])
6956 {
6957 case ELFOSABI_GNU:
6958 case ELFOSABI_FREEBSD:
6959 if (flag == SHF_GNU_RETAIN)
6960 {
6961 *p = 'R';
6962 break;
6963 }
6964 /* Fall through */
6965 case ELFOSABI_NONE:
6966 if (flag == SHF_GNU_MBIND)
6967 {
6968 /* We should not recognize SHF_GNU_MBIND for
6969 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6970 not set the EI_OSABI header byte. */
6971 *p = 'D';
6972 break;
6973 }
6974 /* Fall through */
6975 default:
6976 *p = 'o';
6977 sh_flags &= ~SHF_MASKOS;
6978 break;
6979 }
5477e8a0
L
6980 }
6981 else if (flag & SHF_MASKPROC)
6982 {
6983 *p = 'p';
6984 sh_flags &= ~ SHF_MASKPROC;
6985 }
6986 else
6987 *p = 'x';
6988 break;
6989 }
6990 p++;
d1133906
NC
6991 }
6992 }
76da6bbe 6993
8d5ff12c
L
6994 if (do_section_details)
6995 {
6996 if (os_flags)
6997 {
6998 size -= 5 + field_size;
6999 if (p != buff + field_size + 4)
7000 {
7001 if (size < (2 + 1))
bee0ee85
NC
7002 {
7003 warn (_("Internal error: not enough buffer room for section flag info"));
7004 return _("<unknown>");
7005 }
8d5ff12c
L
7006 size -= 2;
7007 *p++ = ',';
7008 *p++ = ' ';
7009 }
7010 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7011 (unsigned long) os_flags);
7012 p += 5 + field_size;
7013 }
7014 if (proc_flags)
7015 {
7016 size -= 7 + field_size;
7017 if (p != buff + field_size + 4)
7018 {
7019 if (size < (2 + 1))
bee0ee85
NC
7020 {
7021 warn (_("Internal error: not enough buffer room for section flag info"));
7022 return _("<unknown>");
7023 }
8d5ff12c
L
7024 size -= 2;
7025 *p++ = ',';
7026 *p++ = ' ';
7027 }
7028 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7029 (unsigned long) proc_flags);
7030 p += 7 + field_size;
7031 }
7032 if (unknown_flags)
7033 {
7034 size -= 10 + field_size;
7035 if (p != buff + field_size + 4)
7036 {
7037 if (size < (2 + 1))
bee0ee85
NC
7038 {
7039 warn (_("Internal error: not enough buffer room for section flag info"));
7040 return _("<unknown>");
7041 }
8d5ff12c
L
7042 size -= 2;
7043 *p++ = ',';
7044 *p++ = ' ';
7045 }
2b692964 7046 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7047 (unsigned long) unknown_flags);
7048 p += 10 + field_size;
7049 }
7050 }
7051
e9e44622 7052 *p = '\0';
d1133906
NC
7053 return buff;
7054}
7055
5844b465 7056static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 7057get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
7058{
7059 if (is_32bit_elf)
7060 {
7061 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7062
ebdf1ebf
NC
7063 if (size < sizeof (* echdr))
7064 {
7065 error (_("Compressed section is too small even for a compression header\n"));
7066 return 0;
7067 }
7068
77115a4a
L
7069 chdr->ch_type = BYTE_GET (echdr->ch_type);
7070 chdr->ch_size = BYTE_GET (echdr->ch_size);
7071 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7072 return sizeof (*echdr);
7073 }
7074 else
7075 {
7076 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7077
ebdf1ebf
NC
7078 if (size < sizeof (* echdr))
7079 {
7080 error (_("Compressed section is too small even for a compression header\n"));
7081 return 0;
7082 }
7083
77115a4a
L
7084 chdr->ch_type = BYTE_GET (echdr->ch_type);
7085 chdr->ch_size = BYTE_GET (echdr->ch_size);
7086 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7087 return sizeof (*echdr);
7088 }
7089}
7090
015dc7e1 7091static bool
dda8d76d 7092process_section_headers (Filedata * filedata)
252b5132 7093{
2cf0635d 7094 Elf_Internal_Shdr * section;
b34976b6 7095 unsigned int i;
252b5132 7096
dda8d76d 7097 if (filedata->file_header.e_shnum == 0)
252b5132 7098 {
82f2dbf7 7099 /* PR binutils/12467. */
dda8d76d 7100 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7101 {
7102 warn (_("possibly corrupt ELF file header - it has a non-zero"
7103 " section header offset, but no section headers\n"));
015dc7e1 7104 return false;
32ec8896 7105 }
82f2dbf7 7106 else if (do_sections)
252b5132
RH
7107 printf (_("\nThere are no sections in this file.\n"));
7108
015dc7e1 7109 return true;
252b5132
RH
7110 }
7111
7112 if (do_sections && !do_header)
ca0e11aa
NC
7113 {
7114 if (filedata->is_separate && process_links)
7115 printf (_("In linked file '%s': "), filedata->file_name);
7116 if (! filedata->is_separate || process_links)
7117 printf (ngettext ("There is %d section header, "
7118 "starting at offset 0x%lx:\n",
7119 "There are %d section headers, "
7120 "starting at offset 0x%lx:\n",
7121 filedata->file_header.e_shnum),
7122 filedata->file_header.e_shnum,
7123 (unsigned long) filedata->file_header.e_shoff);
7124 }
252b5132 7125
4de91c10
AM
7126 if (!get_section_headers (filedata, false))
7127 return false;
252b5132
RH
7128
7129 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7130 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7131 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7132 {
dda8d76d 7133 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7134
c256ffe7
JJ
7135 if (section->sh_size != 0)
7136 {
dda8d76d
NC
7137 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7138 1, section->sh_size,
7139 _("string table"));
0de14b54 7140
dda8d76d 7141 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7142 }
252b5132
RH
7143 }
7144
7145 /* Scan the sections for the dynamic symbol table
e3c8793a 7146 and dynamic string table and debug sections. */
89fac5e3 7147 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7148 switch (filedata->file_header.e_machine)
89fac5e3
RS
7149 {
7150 case EM_MIPS:
7151 case EM_MIPS_RS3_LE:
7152 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7153 FDE addresses. However, the ABI also has a semi-official ILP32
7154 variant for which the normal FDE address size rules apply.
7155
7156 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7157 section, where XX is the size of longs in bits. Unfortunately,
7158 earlier compilers provided no way of distinguishing ILP32 objects
7159 from LP64 objects, so if there's any doubt, we should assume that
7160 the official LP64 form is being used. */
dda8d76d
NC
7161 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7162 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7163 eh_addr_size = 8;
7164 break;
0f56a26a
DD
7165
7166 case EM_H8_300:
7167 case EM_H8_300H:
dda8d76d 7168 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7169 {
7170 case E_H8_MACH_H8300:
7171 case E_H8_MACH_H8300HN:
7172 case E_H8_MACH_H8300SN:
7173 case E_H8_MACH_H8300SXN:
7174 eh_addr_size = 2;
7175 break;
7176 case E_H8_MACH_H8300H:
7177 case E_H8_MACH_H8300S:
7178 case E_H8_MACH_H8300SX:
7179 eh_addr_size = 4;
7180 break;
7181 }
f4236fe4
DD
7182 break;
7183
ff7eeb89 7184 case EM_M32C_OLD:
f4236fe4 7185 case EM_M32C:
dda8d76d 7186 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7187 {
7188 case EF_M32C_CPU_M16C:
7189 eh_addr_size = 2;
7190 break;
7191 }
7192 break;
89fac5e3
RS
7193 }
7194
76ca31c0
NC
7195#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7196 do \
7197 { \
7198 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7199 if (section->sh_entsize != expected_entsize) \
9dd3a467 7200 { \
76ca31c0
NC
7201 char buf[40]; \
7202 sprintf_vma (buf, section->sh_entsize); \
7203 /* Note: coded this way so that there is a single string for \
7204 translation. */ \
7205 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7206 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7207 (unsigned) expected_entsize); \
9dd3a467 7208 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7209 } \
7210 } \
08d8fa11 7211 while (0)
9dd3a467
NC
7212
7213#define CHECK_ENTSIZE(section, i, type) \
1b513401 7214 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7215 sizeof (Elf64_External_##type))
7216
dda8d76d
NC
7217 for (i = 0, section = filedata->section_headers;
7218 i < filedata->file_header.e_shnum;
b34976b6 7219 i++, section++)
252b5132 7220 {
84714f86 7221 const char *name = section_name_print (filedata, section);
252b5132 7222
1b513401
NC
7223 /* Run some sanity checks on the headers and
7224 possibly fill in some file data as well. */
7225 switch (section->sh_type)
252b5132 7226 {
1b513401 7227 case SHT_DYNSYM:
978c4450 7228 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7229 {
7230 error (_("File contains multiple dynamic symbol tables\n"));
7231 continue;
7232 }
7233
08d8fa11 7234 CHECK_ENTSIZE (section, i, Sym);
978c4450 7235 filedata->dynamic_symbols
4de91c10 7236 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7237 filedata->dynamic_symtab_section = section;
1b513401
NC
7238 break;
7239
7240 case SHT_STRTAB:
7241 if (streq (name, ".dynstr"))
252b5132 7242 {
1b513401
NC
7243 if (filedata->dynamic_strings != NULL)
7244 {
7245 error (_("File contains multiple dynamic string tables\n"));
7246 continue;
7247 }
7248
7249 filedata->dynamic_strings
7250 = (char *) get_data (NULL, filedata, section->sh_offset,
7251 1, section->sh_size, _("dynamic strings"));
7252 filedata->dynamic_strings_length
7253 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7254 filedata->dynamic_strtab_section = section;
252b5132 7255 }
1b513401
NC
7256 break;
7257
7258 case SHT_SYMTAB_SHNDX:
7259 {
7260 elf_section_list * entry = xmalloc (sizeof * entry);
7261
7262 entry->hdr = section;
7263 entry->next = filedata->symtab_shndx_list;
7264 filedata->symtab_shndx_list = entry;
7265 }
7266 break;
7267
7268 case SHT_SYMTAB:
7269 CHECK_ENTSIZE (section, i, Sym);
7270 break;
7271
7272 case SHT_GROUP:
7273 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7274 break;
252b5132 7275
1b513401
NC
7276 case SHT_REL:
7277 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7278 if (do_checks && section->sh_size == 0)
1b513401
NC
7279 warn (_("Section '%s': zero-sized relocation section\n"), name);
7280 break;
7281
7282 case SHT_RELA:
7283 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7284 if (do_checks && section->sh_size == 0)
1b513401
NC
7285 warn (_("Section '%s': zero-sized relocation section\n"), name);
7286 break;
7287
682351b9
AM
7288 case SHT_RELR:
7289 CHECK_ENTSIZE (section, i, Relr);
7290 break;
7291
1b513401
NC
7292 case SHT_NOTE:
7293 case SHT_PROGBITS:
546cb2d8
NC
7294 /* Having a zero sized section is not illegal according to the
7295 ELF standard, but it might be an indication that something
7296 is wrong. So issue a warning if we are running in lint mode. */
7297 if (do_checks && section->sh_size == 0)
1b513401
NC
7298 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7299 break;
7300
7301 default:
7302 break;
7303 }
7304
7305 if ((do_debugging || do_debug_info || do_debug_abbrevs
7306 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7307 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7308 || do_debug_str || do_debug_str_offsets || do_debug_loc
7309 || do_debug_ranges
1b513401 7310 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7311 && (startswith (name, ".debug_")
7312 || startswith (name, ".zdebug_")))
252b5132 7313 {
1b315056
CS
7314 if (name[1] == 'z')
7315 name += sizeof (".zdebug_") - 1;
7316 else
7317 name += sizeof (".debug_") - 1;
252b5132
RH
7318
7319 if (do_debugging
24d127aa
ML
7320 || (do_debug_info && startswith (name, "info"))
7321 || (do_debug_info && startswith (name, "types"))
7322 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7323 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7324 || (do_debug_lines && startswith (name, "line."))
7325 || (do_debug_pubnames && startswith (name, "pubnames"))
7326 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7327 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7328 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7329 || (do_debug_aranges && startswith (name, "aranges"))
7330 || (do_debug_ranges && startswith (name, "ranges"))
7331 || (do_debug_ranges && startswith (name, "rnglists"))
7332 || (do_debug_frames && startswith (name, "frame"))
7333 || (do_debug_macinfo && startswith (name, "macinfo"))
7334 || (do_debug_macinfo && startswith (name, "macro"))
7335 || (do_debug_str && startswith (name, "str"))
7336 || (do_debug_links && startswith (name, "sup"))
7337 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7338 || (do_debug_loc && startswith (name, "loc"))
7339 || (do_debug_loc && startswith (name, "loclists"))
7340 || (do_debug_addr && startswith (name, "addr"))
7341 || (do_debug_cu_index && startswith (name, "cu_index"))
7342 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7343 )
6431e409 7344 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7345 }
a262ae96 7346 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7347 else if ((do_debugging || do_debug_info)
24d127aa 7348 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7349 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7350 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7351 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7352 else if (do_gdb_index && (streq (name, ".gdb_index")
7353 || streq (name, ".debug_names")))
6431e409 7354 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7355 /* Trace sections for Itanium VMS. */
7356 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7357 || do_trace_aranges)
24d127aa 7358 && startswith (name, ".trace_"))
6f875884
TG
7359 {
7360 name += sizeof (".trace_") - 1;
7361
7362 if (do_debugging
7363 || (do_trace_info && streq (name, "info"))
7364 || (do_trace_abbrevs && streq (name, "abbrev"))
7365 || (do_trace_aranges && streq (name, "aranges"))
7366 )
6431e409 7367 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7368 }
dda8d76d 7369 else if ((do_debugging || do_debug_links)
24d127aa
ML
7370 && (startswith (name, ".gnu_debuglink")
7371 || startswith (name, ".gnu_debugaltlink")))
6431e409 7372 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7373 }
7374
7375 if (! do_sections)
015dc7e1 7376 return true;
252b5132 7377
ca0e11aa 7378 if (filedata->is_separate && ! process_links)
015dc7e1 7379 return true;
ca0e11aa
NC
7380
7381 if (filedata->is_separate)
7382 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7383 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7384 printf (_("\nSection Headers:\n"));
7385 else
7386 printf (_("\nSection Header:\n"));
76da6bbe 7387
f7a99963 7388 if (is_32bit_elf)
595cf52e 7389 {
5477e8a0 7390 if (do_section_details)
595cf52e
L
7391 {
7392 printf (_(" [Nr] Name\n"));
5477e8a0 7393 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7394 }
7395 else
7396 printf
7397 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7398 }
d974e256 7399 else if (do_wide)
595cf52e 7400 {
5477e8a0 7401 if (do_section_details)
595cf52e
L
7402 {
7403 printf (_(" [Nr] Name\n"));
5477e8a0 7404 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7405 }
7406 else
7407 printf
7408 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7409 }
f7a99963
NC
7410 else
7411 {
5477e8a0 7412 if (do_section_details)
595cf52e
L
7413 {
7414 printf (_(" [Nr] Name\n"));
5477e8a0
L
7415 printf (_(" Type Address Offset Link\n"));
7416 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7417 }
7418 else
7419 {
7420 printf (_(" [Nr] Name Type Address Offset\n"));
7421 printf (_(" Size EntSize Flags Link Info Align\n"));
7422 }
f7a99963 7423 }
252b5132 7424
5477e8a0
L
7425 if (do_section_details)
7426 printf (_(" Flags\n"));
7427
dda8d76d
NC
7428 for (i = 0, section = filedata->section_headers;
7429 i < filedata->file_header.e_shnum;
b34976b6 7430 i++, section++)
252b5132 7431 {
dd905818
NC
7432 /* Run some sanity checks on the section header. */
7433
7434 /* Check the sh_link field. */
7435 switch (section->sh_type)
7436 {
285e3f99
AM
7437 case SHT_REL:
7438 case SHT_RELA:
7439 if (section->sh_link == 0
7440 && (filedata->file_header.e_type == ET_EXEC
7441 || filedata->file_header.e_type == ET_DYN))
7442 /* A dynamic relocation section where all entries use a
7443 zero symbol index need not specify a symtab section. */
7444 break;
7445 /* Fall through. */
dd905818
NC
7446 case SHT_SYMTAB_SHNDX:
7447 case SHT_GROUP:
7448 case SHT_HASH:
7449 case SHT_GNU_HASH:
7450 case SHT_GNU_versym:
285e3f99 7451 if (section->sh_link == 0
dda8d76d
NC
7452 || section->sh_link >= filedata->file_header.e_shnum
7453 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7454 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7455 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7456 i, section->sh_link);
7457 break;
7458
7459 case SHT_DYNAMIC:
7460 case SHT_SYMTAB:
7461 case SHT_DYNSYM:
7462 case SHT_GNU_verneed:
7463 case SHT_GNU_verdef:
7464 case SHT_GNU_LIBLIST:
285e3f99 7465 if (section->sh_link == 0
dda8d76d
NC
7466 || section->sh_link >= filedata->file_header.e_shnum
7467 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7468 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7469 i, section->sh_link);
7470 break;
7471
7472 case SHT_INIT_ARRAY:
7473 case SHT_FINI_ARRAY:
7474 case SHT_PREINIT_ARRAY:
7475 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7476 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7477 i, section->sh_link);
7478 break;
7479
7480 default:
7481 /* FIXME: Add support for target specific section types. */
7482#if 0 /* Currently we do not check other section types as there are too
7483 many special cases. Stab sections for example have a type
7484 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7485 section. */
7486 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7487 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7488 i, section->sh_link);
7489#endif
7490 break;
7491 }
7492
7493 /* Check the sh_info field. */
7494 switch (section->sh_type)
7495 {
7496 case SHT_REL:
7497 case SHT_RELA:
285e3f99
AM
7498 if (section->sh_info == 0
7499 && (filedata->file_header.e_type == ET_EXEC
7500 || filedata->file_header.e_type == ET_DYN))
7501 /* Dynamic relocations apply to segments, so they do not
7502 need to specify the section they relocate. */
7503 break;
7504 if (section->sh_info == 0
dda8d76d
NC
7505 || section->sh_info >= filedata->file_header.e_shnum
7506 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7507 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7508 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7509 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7510 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7511 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7512 /* FIXME: Are other section types valid ? */
dda8d76d 7513 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7514 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7515 i, section->sh_info);
dd905818
NC
7516 break;
7517
7518 case SHT_DYNAMIC:
7519 case SHT_HASH:
7520 case SHT_SYMTAB_SHNDX:
7521 case SHT_INIT_ARRAY:
7522 case SHT_FINI_ARRAY:
7523 case SHT_PREINIT_ARRAY:
7524 if (section->sh_info != 0)
7525 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7526 i, section->sh_info);
7527 break;
7528
7529 case SHT_GROUP:
7530 case SHT_SYMTAB:
7531 case SHT_DYNSYM:
7532 /* A symbol index - we assume that it is valid. */
7533 break;
7534
7535 default:
7536 /* FIXME: Add support for target specific section types. */
7537 if (section->sh_type == SHT_NOBITS)
7538 /* NOBITS section headers with non-zero sh_info fields can be
7539 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7540 information. The stripped sections have their headers
7541 preserved but their types set to SHT_NOBITS. So do not check
7542 this type of section. */
dd905818
NC
7543 ;
7544 else if (section->sh_flags & SHF_INFO_LINK)
7545 {
dda8d76d 7546 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7547 warn (_("[%2u]: Expected link to another section in info field"), i);
7548 }
a91e1603
L
7549 else if (section->sh_type < SHT_LOOS
7550 && (section->sh_flags & SHF_GNU_MBIND) == 0
7551 && section->sh_info != 0)
dd905818
NC
7552 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7553 i, section->sh_info);
7554 break;
7555 }
7556
3e6b6445 7557 /* Check the sh_size field. */
dda8d76d 7558 if (section->sh_size > filedata->file_size
3e6b6445
NC
7559 && section->sh_type != SHT_NOBITS
7560 && section->sh_type != SHT_NULL
7561 && section->sh_type < SHT_LOOS)
7562 warn (_("Size of section %u is larger than the entire file!\n"), i);
7563
7bfd842d 7564 printf (" [%2u] ", i);
5477e8a0 7565 if (do_section_details)
dda8d76d 7566 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7567 else
84714f86 7568 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7569
ea52a088 7570 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7571 get_section_type_name (filedata, section->sh_type));
0b4362b0 7572
f7a99963
NC
7573 if (is_32bit_elf)
7574 {
cfcac11d
NC
7575 const char * link_too_big = NULL;
7576
f7a99963 7577 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7578
f7a99963
NC
7579 printf ( " %6.6lx %6.6lx %2.2lx",
7580 (unsigned long) section->sh_offset,
7581 (unsigned long) section->sh_size,
7582 (unsigned long) section->sh_entsize);
d1133906 7583
5477e8a0
L
7584 if (do_section_details)
7585 fputs (" ", stdout);
7586 else
dda8d76d 7587 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7588
dda8d76d 7589 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7590 {
7591 link_too_big = "";
7592 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7593 an error but it can have special values in Solaris binaries. */
dda8d76d 7594 switch (filedata->file_header.e_machine)
cfcac11d 7595 {
caa83f8b 7596 case EM_386:
22abe556 7597 case EM_IAMCU:
caa83f8b 7598 case EM_X86_64:
7f502d6c 7599 case EM_L1OM:
7a9068fe 7600 case EM_K1OM:
cfcac11d
NC
7601 case EM_OLD_SPARCV9:
7602 case EM_SPARC32PLUS:
7603 case EM_SPARCV9:
7604 case EM_SPARC:
7605 if (section->sh_link == (SHN_BEFORE & 0xffff))
7606 link_too_big = "BEFORE";
7607 else if (section->sh_link == (SHN_AFTER & 0xffff))
7608 link_too_big = "AFTER";
7609 break;
7610 default:
7611 break;
7612 }
7613 }
7614
7615 if (do_section_details)
7616 {
7617 if (link_too_big != NULL && * link_too_big)
7618 printf ("<%s> ", link_too_big);
7619 else
7620 printf ("%2u ", section->sh_link);
7621 printf ("%3u %2lu\n", section->sh_info,
7622 (unsigned long) section->sh_addralign);
7623 }
7624 else
7625 printf ("%2u %3u %2lu\n",
7626 section->sh_link,
7627 section->sh_info,
7628 (unsigned long) section->sh_addralign);
7629
7630 if (link_too_big && ! * link_too_big)
7631 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7632 i, section->sh_link);
f7a99963 7633 }
d974e256
JJ
7634 else if (do_wide)
7635 {
7636 print_vma (section->sh_addr, LONG_HEX);
7637
7638 if ((long) section->sh_offset == section->sh_offset)
7639 printf (" %6.6lx", (unsigned long) section->sh_offset);
7640 else
7641 {
7642 putchar (' ');
7643 print_vma (section->sh_offset, LONG_HEX);
7644 }
7645
7646 if ((unsigned long) section->sh_size == section->sh_size)
7647 printf (" %6.6lx", (unsigned long) section->sh_size);
7648 else
7649 {
7650 putchar (' ');
7651 print_vma (section->sh_size, LONG_HEX);
7652 }
7653
7654 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7655 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7656 else
7657 {
7658 putchar (' ');
7659 print_vma (section->sh_entsize, LONG_HEX);
7660 }
7661
5477e8a0
L
7662 if (do_section_details)
7663 fputs (" ", stdout);
7664 else
dda8d76d 7665 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7666
72de5009 7667 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7668
7669 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7670 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7671 else
7672 {
7673 print_vma (section->sh_addralign, DEC);
7674 putchar ('\n');
7675 }
7676 }
5477e8a0 7677 else if (do_section_details)
595cf52e 7678 {
55cc53e9 7679 putchar (' ');
595cf52e
L
7680 print_vma (section->sh_addr, LONG_HEX);
7681 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7682 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7683 else
7684 {
7685 printf (" ");
7686 print_vma (section->sh_offset, LONG_HEX);
7687 }
72de5009 7688 printf (" %u\n ", section->sh_link);
595cf52e 7689 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7690 putchar (' ');
595cf52e
L
7691 print_vma (section->sh_entsize, LONG_HEX);
7692
72de5009
AM
7693 printf (" %-16u %lu\n",
7694 section->sh_info,
595cf52e
L
7695 (unsigned long) section->sh_addralign);
7696 }
f7a99963
NC
7697 else
7698 {
7699 putchar (' ');
7700 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7701 if ((long) section->sh_offset == section->sh_offset)
7702 printf (" %8.8lx", (unsigned long) section->sh_offset);
7703 else
7704 {
7705 printf (" ");
7706 print_vma (section->sh_offset, LONG_HEX);
7707 }
f7a99963
NC
7708 printf ("\n ");
7709 print_vma (section->sh_size, LONG_HEX);
7710 printf (" ");
7711 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7712
dda8d76d 7713 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7714
72de5009
AM
7715 printf (" %2u %3u %lu\n",
7716 section->sh_link,
7717 section->sh_info,
f7a99963
NC
7718 (unsigned long) section->sh_addralign);
7719 }
5477e8a0
L
7720
7721 if (do_section_details)
77115a4a 7722 {
dda8d76d 7723 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7724 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7725 {
7726 /* Minimum section size is 12 bytes for 32-bit compression
7727 header + 12 bytes for compressed data header. */
7728 unsigned char buf[24];
d8024a91 7729
77115a4a 7730 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7731 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7732 sizeof (buf), _("compression header")))
7733 {
7734 Elf_Internal_Chdr chdr;
d8024a91 7735
5844b465
NC
7736 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7737 printf (_(" [<corrupt>]\n"));
77115a4a 7738 else
5844b465
NC
7739 {
7740 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7741 printf (" ZLIB, ");
7742 else
7743 printf (_(" [<unknown>: 0x%x], "),
7744 chdr.ch_type);
7745 print_vma (chdr.ch_size, LONG_HEX);
7746 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7747 }
77115a4a
L
7748 }
7749 }
7750 }
252b5132
RH
7751 }
7752
5477e8a0 7753 if (!do_section_details)
3dbcc61d 7754 {
9fb71ee4
NC
7755 /* The ordering of the letters shown here matches the ordering of the
7756 corresponding SHF_xxx values, and hence the order in which these
7757 letters will be displayed to the user. */
7758 printf (_("Key to Flags:\n\
7759 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7760 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7761 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7762 switch (filedata->file_header.e_ident[EI_OSABI])
7763 {
7764 case ELFOSABI_GNU:
7765 case ELFOSABI_FREEBSD:
7766 printf (_("R (retain), "));
7767 /* Fall through */
7768 case ELFOSABI_NONE:
7769 printf (_("D (mbind), "));
7770 break;
7771 default:
7772 break;
7773 }
dda8d76d
NC
7774 if (filedata->file_header.e_machine == EM_X86_64
7775 || filedata->file_header.e_machine == EM_L1OM
7776 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7777 printf (_("l (large), "));
dda8d76d 7778 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7779 printf (_("y (purecode), "));
dda8d76d 7780 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7781 printf (_("v (VLE), "));
9fb71ee4 7782 printf ("p (processor specific)\n");
0b4362b0 7783 }
d1133906 7784
015dc7e1 7785 return true;
252b5132
RH
7786}
7787
015dc7e1 7788static bool
28d13567
AM
7789get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7790 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7791 char **strtab, unsigned long *strtablen)
7792{
7793 *strtab = NULL;
7794 *strtablen = 0;
4de91c10 7795 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7796
7797 if (*symtab == NULL)
015dc7e1 7798 return false;
28d13567
AM
7799
7800 if (symsec->sh_link != 0)
7801 {
7802 Elf_Internal_Shdr *strsec;
7803
7804 if (symsec->sh_link >= filedata->file_header.e_shnum)
7805 {
7806 error (_("Bad sh_link in symbol table section\n"));
7807 free (*symtab);
7808 *symtab = NULL;
7809 *nsyms = 0;
015dc7e1 7810 return false;
28d13567
AM
7811 }
7812
7813 strsec = filedata->section_headers + symsec->sh_link;
7814
7815 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7816 1, strsec->sh_size, _("string table"));
7817 if (*strtab == NULL)
7818 {
7819 free (*symtab);
7820 *symtab = NULL;
7821 *nsyms = 0;
015dc7e1 7822 return false;
28d13567
AM
7823 }
7824 *strtablen = strsec->sh_size;
7825 }
015dc7e1 7826 return true;
28d13567
AM
7827}
7828
f5842774
L
7829static const char *
7830get_group_flags (unsigned int flags)
7831{
1449284b 7832 static char buff[128];
220453ec 7833
6d913794
NC
7834 if (flags == 0)
7835 return "";
7836 else if (flags == GRP_COMDAT)
7837 return "COMDAT ";
f5842774 7838
89246a0e
AM
7839 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7840 flags,
7841 flags & GRP_MASKOS ? _("<OS specific>") : "",
7842 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7843 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7844 ? _("<unknown>") : ""));
6d913794 7845
f5842774
L
7846 return buff;
7847}
7848
015dc7e1 7849static bool
dda8d76d 7850process_section_groups (Filedata * filedata)
f5842774 7851{
2cf0635d 7852 Elf_Internal_Shdr * section;
f5842774 7853 unsigned int i;
2cf0635d
NC
7854 struct group * group;
7855 Elf_Internal_Shdr * symtab_sec;
7856 Elf_Internal_Shdr * strtab_sec;
7857 Elf_Internal_Sym * symtab;
ba5cdace 7858 unsigned long num_syms;
2cf0635d 7859 char * strtab;
c256ffe7 7860 size_t strtab_size;
d1f5c6e3
L
7861
7862 /* Don't process section groups unless needed. */
7863 if (!do_unwind && !do_section_groups)
015dc7e1 7864 return true;
f5842774 7865
dda8d76d 7866 if (filedata->file_header.e_shnum == 0)
f5842774
L
7867 {
7868 if (do_section_groups)
ca0e11aa
NC
7869 {
7870 if (filedata->is_separate)
7871 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7872 filedata->file_name);
7873 else
7874 printf (_("\nThere are no section groups in this file.\n"));
7875 }
015dc7e1 7876 return true;
f5842774
L
7877 }
7878
dda8d76d 7879 if (filedata->section_headers == NULL)
f5842774
L
7880 {
7881 error (_("Section headers are not available!\n"));
fa1908fd 7882 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7883 return false;
f5842774
L
7884 }
7885
978c4450
AM
7886 filedata->section_headers_groups
7887 = (struct group **) calloc (filedata->file_header.e_shnum,
7888 sizeof (struct group *));
e4b17d5c 7889
978c4450 7890 if (filedata->section_headers_groups == NULL)
e4b17d5c 7891 {
8b73c356 7892 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7893 filedata->file_header.e_shnum);
015dc7e1 7894 return false;
e4b17d5c
L
7895 }
7896
f5842774 7897 /* Scan the sections for the group section. */
978c4450 7898 filedata->group_count = 0;
dda8d76d
NC
7899 for (i = 0, section = filedata->section_headers;
7900 i < filedata->file_header.e_shnum;
f5842774 7901 i++, section++)
e4b17d5c 7902 if (section->sh_type == SHT_GROUP)
978c4450 7903 filedata->group_count++;
e4b17d5c 7904
978c4450 7905 if (filedata->group_count == 0)
d1f5c6e3
L
7906 {
7907 if (do_section_groups)
ca0e11aa
NC
7908 {
7909 if (filedata->is_separate)
7910 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7911 filedata->file_name);
7912 else
7913 printf (_("\nThere are no section groups in this file.\n"));
7914 }
d1f5c6e3 7915
015dc7e1 7916 return true;
d1f5c6e3
L
7917 }
7918
978c4450
AM
7919 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7920 sizeof (struct group));
e4b17d5c 7921
978c4450 7922 if (filedata->section_groups == NULL)
e4b17d5c 7923 {
8b73c356 7924 error (_("Out of memory reading %lu groups\n"),
978c4450 7925 (unsigned long) filedata->group_count);
015dc7e1 7926 return false;
e4b17d5c
L
7927 }
7928
d1f5c6e3
L
7929 symtab_sec = NULL;
7930 strtab_sec = NULL;
7931 symtab = NULL;
ba5cdace 7932 num_syms = 0;
d1f5c6e3 7933 strtab = NULL;
c256ffe7 7934 strtab_size = 0;
ca0e11aa
NC
7935
7936 if (filedata->is_separate)
7937 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7938
978c4450 7939 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7940 i < filedata->file_header.e_shnum;
e4b17d5c 7941 i++, section++)
f5842774
L
7942 {
7943 if (section->sh_type == SHT_GROUP)
7944 {
dda8d76d 7945 const char * name = printable_section_name (filedata, section);
74e1a04b 7946 const char * group_name;
2cf0635d
NC
7947 unsigned char * start;
7948 unsigned char * indices;
f5842774 7949 unsigned int entry, j, size;
2cf0635d
NC
7950 Elf_Internal_Shdr * sec;
7951 Elf_Internal_Sym * sym;
f5842774
L
7952
7953 /* Get the symbol table. */
dda8d76d
NC
7954 if (section->sh_link >= filedata->file_header.e_shnum
7955 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7956 != SHT_SYMTAB))
f5842774
L
7957 {
7958 error (_("Bad sh_link in group section `%s'\n"), name);
7959 continue;
7960 }
d1f5c6e3
L
7961
7962 if (symtab_sec != sec)
7963 {
7964 symtab_sec = sec;
9db70fc3 7965 free (symtab);
4de91c10 7966 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7967 }
f5842774 7968
dd24e3da
NC
7969 if (symtab == NULL)
7970 {
7971 error (_("Corrupt header in group section `%s'\n"), name);
7972 continue;
7973 }
7974
ba5cdace
NC
7975 if (section->sh_info >= num_syms)
7976 {
7977 error (_("Bad sh_info in group section `%s'\n"), name);
7978 continue;
7979 }
7980
f5842774
L
7981 sym = symtab + section->sh_info;
7982
7983 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7984 {
4fbb74a6 7985 if (sym->st_shndx == 0
dda8d76d 7986 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7987 {
7988 error (_("Bad sh_info in group section `%s'\n"), name);
7989 continue;
7990 }
ba2685cc 7991
84714f86
AM
7992 group_name = section_name_print (filedata,
7993 filedata->section_headers
b9e920ec 7994 + sym->st_shndx);
c256ffe7 7995 strtab_sec = NULL;
9db70fc3 7996 free (strtab);
f5842774 7997 strtab = NULL;
c256ffe7 7998 strtab_size = 0;
f5842774
L
7999 }
8000 else
8001 {
8002 /* Get the string table. */
dda8d76d 8003 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8004 {
8005 strtab_sec = NULL;
9db70fc3 8006 free (strtab);
c256ffe7
JJ
8007 strtab = NULL;
8008 strtab_size = 0;
8009 }
8010 else if (strtab_sec
dda8d76d 8011 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8012 {
8013 strtab_sec = sec;
9db70fc3 8014 free (strtab);
071436c6 8015
dda8d76d 8016 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8017 1, strtab_sec->sh_size,
8018 _("string table"));
c256ffe7 8019 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8020 }
c256ffe7 8021 group_name = sym->st_name < strtab_size
2b692964 8022 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8023 }
8024
c9c1d674
EG
8025 /* PR 17531: file: loop. */
8026 if (section->sh_entsize > section->sh_size)
8027 {
8028 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8029 printable_section_name (filedata, section),
8066deb1
AM
8030 (unsigned long) section->sh_entsize,
8031 (unsigned long) section->sh_size);
61dd8e19 8032 continue;
c9c1d674
EG
8033 }
8034
dda8d76d 8035 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8036 1, section->sh_size,
8037 _("section data"));
59245841
NC
8038 if (start == NULL)
8039 continue;
f5842774
L
8040
8041 indices = start;
8042 size = (section->sh_size / section->sh_entsize) - 1;
8043 entry = byte_get (indices, 4);
8044 indices += 4;
e4b17d5c
L
8045
8046 if (do_section_groups)
8047 {
2b692964 8048 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8049 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8050
e4b17d5c
L
8051 printf (_(" [Index] Name\n"));
8052 }
8053
8054 group->group_index = i;
8055
f5842774
L
8056 for (j = 0; j < size; j++)
8057 {
2cf0635d 8058 struct group_list * g;
e4b17d5c 8059
f5842774
L
8060 entry = byte_get (indices, 4);
8061 indices += 4;
8062
dda8d76d 8063 if (entry >= filedata->file_header.e_shnum)
391cb864 8064 {
57028622
NC
8065 static unsigned num_group_errors = 0;
8066
8067 if (num_group_errors ++ < 10)
8068 {
8069 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8070 entry, i, filedata->file_header.e_shnum - 1);
57028622 8071 if (num_group_errors == 10)
67ce483b 8072 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8073 }
391cb864
L
8074 continue;
8075 }
391cb864 8076
978c4450 8077 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8078 {
d1f5c6e3
L
8079 if (entry)
8080 {
57028622
NC
8081 static unsigned num_errs = 0;
8082
8083 if (num_errs ++ < 10)
8084 {
8085 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8086 entry, i,
978c4450 8087 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8088 if (num_errs == 10)
8089 warn (_("Further error messages about already contained group sections suppressed\n"));
8090 }
d1f5c6e3
L
8091 continue;
8092 }
8093 else
8094 {
8095 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8096 section group. We just warn it the first time
d1f5c6e3 8097 and ignore it afterwards. */
015dc7e1 8098 static bool warned = false;
d1f5c6e3
L
8099 if (!warned)
8100 {
8101 error (_("section 0 in group section [%5u]\n"),
978c4450 8102 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8103 warned = true;
d1f5c6e3
L
8104 }
8105 }
e4b17d5c
L
8106 }
8107
978c4450 8108 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8109
8110 if (do_section_groups)
8111 {
dda8d76d
NC
8112 sec = filedata->section_headers + entry;
8113 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8114 }
8115
3f5e193b 8116 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8117 g->section_index = entry;
8118 g->next = group->root;
8119 group->root = g;
f5842774
L
8120 }
8121
9db70fc3 8122 free (start);
e4b17d5c
L
8123
8124 group++;
f5842774
L
8125 }
8126 }
8127
9db70fc3
AM
8128 free (symtab);
8129 free (strtab);
015dc7e1 8130 return true;
f5842774
L
8131}
8132
28f997cf
TG
8133/* Data used to display dynamic fixups. */
8134
8135struct ia64_vms_dynfixup
8136{
8137 bfd_vma needed_ident; /* Library ident number. */
8138 bfd_vma needed; /* Index in the dstrtab of the library name. */
8139 bfd_vma fixup_needed; /* Index of the library. */
8140 bfd_vma fixup_rela_cnt; /* Number of fixups. */
8141 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
8142};
8143
8144/* Data used to display dynamic relocations. */
8145
8146struct ia64_vms_dynimgrela
8147{
8148 bfd_vma img_rela_cnt; /* Number of relocations. */
8149 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
8150};
8151
8152/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8153 library). */
8154
015dc7e1 8155static bool
dda8d76d
NC
8156dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8157 struct ia64_vms_dynfixup * fixup,
8158 const char * strtab,
8159 unsigned int strtab_sz)
28f997cf 8160{
32ec8896 8161 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8162 long i;
32ec8896 8163 const char * lib_name;
28f997cf 8164
978c4450
AM
8165 imfs = get_data (NULL, filedata,
8166 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8167 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8168 _("dynamic section image fixups"));
8169 if (!imfs)
015dc7e1 8170 return false;
28f997cf
TG
8171
8172 if (fixup->needed < strtab_sz)
8173 lib_name = strtab + fixup->needed;
8174 else
8175 {
32ec8896 8176 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8177 (unsigned long) fixup->needed);
28f997cf
TG
8178 lib_name = "???";
8179 }
736990c4 8180
28f997cf
TG
8181 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8182 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8183 printf
8184 (_("Seg Offset Type SymVec DataType\n"));
8185
8186 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8187 {
8188 unsigned int type;
8189 const char *rtype;
8190
8191 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8192 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8193 type = BYTE_GET (imfs [i].type);
8194 rtype = elf_ia64_reloc_type (type);
8195 if (rtype == NULL)
8196 printf (" 0x%08x ", type);
8197 else
8198 printf (" %-32s ", rtype);
8199 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8200 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8201 }
8202
8203 free (imfs);
015dc7e1 8204 return true;
28f997cf
TG
8205}
8206
8207/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8208
015dc7e1 8209static bool
dda8d76d 8210dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8211{
8212 Elf64_External_VMS_IMAGE_RELA *imrs;
8213 long i;
8214
978c4450
AM
8215 imrs = get_data (NULL, filedata,
8216 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8217 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8218 _("dynamic section image relocations"));
28f997cf 8219 if (!imrs)
015dc7e1 8220 return false;
28f997cf
TG
8221
8222 printf (_("\nImage relocs\n"));
8223 printf
8224 (_("Seg Offset Type Addend Seg Sym Off\n"));
8225
8226 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8227 {
8228 unsigned int type;
8229 const char *rtype;
8230
8231 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8232 printf ("%08" BFD_VMA_FMT "x ",
8233 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8234 type = BYTE_GET (imrs [i].type);
8235 rtype = elf_ia64_reloc_type (type);
8236 if (rtype == NULL)
8237 printf ("0x%08x ", type);
8238 else
8239 printf ("%-31s ", rtype);
8240 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8241 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8242 printf ("%08" BFD_VMA_FMT "x\n",
8243 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8244 }
8245
8246 free (imrs);
015dc7e1 8247 return true;
28f997cf
TG
8248}
8249
8250/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8251
015dc7e1 8252static bool
dda8d76d 8253process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8254{
8255 struct ia64_vms_dynfixup fixup;
8256 struct ia64_vms_dynimgrela imgrela;
8257 Elf_Internal_Dyn *entry;
28f997cf
TG
8258 bfd_vma strtab_off = 0;
8259 bfd_vma strtab_sz = 0;
8260 char *strtab = NULL;
015dc7e1 8261 bool res = true;
28f997cf
TG
8262
8263 memset (&fixup, 0, sizeof (fixup));
8264 memset (&imgrela, 0, sizeof (imgrela));
8265
8266 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8267 for (entry = filedata->dynamic_section;
8268 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8269 entry++)
8270 {
8271 switch (entry->d_tag)
8272 {
8273 case DT_IA_64_VMS_STRTAB_OFFSET:
8274 strtab_off = entry->d_un.d_val;
8275 break;
8276 case DT_STRSZ:
8277 strtab_sz = entry->d_un.d_val;
8278 if (strtab == NULL)
978c4450
AM
8279 strtab = get_data (NULL, filedata,
8280 filedata->dynamic_addr + strtab_off,
28f997cf 8281 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8282 if (strtab == NULL)
8283 strtab_sz = 0;
28f997cf
TG
8284 break;
8285
8286 case DT_IA_64_VMS_NEEDED_IDENT:
8287 fixup.needed_ident = entry->d_un.d_val;
8288 break;
8289 case DT_NEEDED:
8290 fixup.needed = entry->d_un.d_val;
8291 break;
8292 case DT_IA_64_VMS_FIXUP_NEEDED:
8293 fixup.fixup_needed = entry->d_un.d_val;
8294 break;
8295 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8296 fixup.fixup_rela_cnt = entry->d_un.d_val;
8297 break;
8298 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8299 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8300 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8301 res = false;
28f997cf 8302 break;
28f997cf
TG
8303 case DT_IA_64_VMS_IMG_RELA_CNT:
8304 imgrela.img_rela_cnt = entry->d_un.d_val;
8305 break;
8306 case DT_IA_64_VMS_IMG_RELA_OFF:
8307 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8308 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8309 res = false;
28f997cf
TG
8310 break;
8311
8312 default:
8313 break;
8314 }
8315 }
8316
9db70fc3 8317 free (strtab);
28f997cf
TG
8318
8319 return res;
8320}
8321
85b1c36d 8322static struct
566b0d53 8323{
2cf0635d 8324 const char * name;
566b0d53
L
8325 int reloc;
8326 int size;
a7fd1186 8327 relocation_type rel_type;
32ec8896
NC
8328}
8329 dynamic_relocations [] =
566b0d53 8330{
a7fd1186
FS
8331 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8332 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8333 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8334 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8335};
8336
252b5132 8337/* Process the reloc section. */
18bd398b 8338
015dc7e1 8339static bool
dda8d76d 8340process_relocs (Filedata * filedata)
252b5132 8341{
b34976b6
AM
8342 unsigned long rel_size;
8343 unsigned long rel_offset;
252b5132 8344
252b5132 8345 if (!do_reloc)
015dc7e1 8346 return true;
252b5132
RH
8347
8348 if (do_using_dynamic)
8349 {
a7fd1186 8350 relocation_type rel_type;
2cf0635d 8351 const char * name;
015dc7e1 8352 bool has_dynamic_reloc;
566b0d53 8353 unsigned int i;
0de14b54 8354
015dc7e1 8355 has_dynamic_reloc = false;
252b5132 8356
566b0d53 8357 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8358 {
a7fd1186 8359 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8360 name = dynamic_relocations [i].name;
978c4450
AM
8361 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8362 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8363
32ec8896 8364 if (rel_size)
015dc7e1 8365 has_dynamic_reloc = true;
566b0d53 8366
a7fd1186 8367 if (rel_type == reltype_unknown)
aa903cfb 8368 {
566b0d53 8369 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8370 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8371 {
8372 case DT_REL:
a7fd1186 8373 rel_type = reltype_rel;
566b0d53
L
8374 break;
8375 case DT_RELA:
a7fd1186 8376 rel_type = reltype_rela;
566b0d53
L
8377 break;
8378 }
aa903cfb 8379 }
252b5132 8380
566b0d53
L
8381 if (rel_size)
8382 {
ca0e11aa
NC
8383 if (filedata->is_separate)
8384 printf
8385 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8386 filedata->file_name, name, rel_offset, rel_size);
8387 else
8388 printf
8389 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8390 name, rel_offset, rel_size);
252b5132 8391
dda8d76d
NC
8392 dump_relocations (filedata,
8393 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8394 rel_size,
978c4450
AM
8395 filedata->dynamic_symbols,
8396 filedata->num_dynamic_syms,
8397 filedata->dynamic_strings,
8398 filedata->dynamic_strings_length,
a7fd1186 8399 rel_type, true /* is_dynamic */);
566b0d53 8400 }
252b5132 8401 }
566b0d53 8402
dda8d76d
NC
8403 if (is_ia64_vms (filedata))
8404 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8405 has_dynamic_reloc = true;
28f997cf 8406
566b0d53 8407 if (! has_dynamic_reloc)
ca0e11aa
NC
8408 {
8409 if (filedata->is_separate)
8410 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8411 filedata->file_name);
8412 else
8413 printf (_("\nThere are no dynamic relocations in this file.\n"));
8414 }
252b5132
RH
8415 }
8416 else
8417 {
2cf0635d 8418 Elf_Internal_Shdr * section;
b34976b6 8419 unsigned long i;
015dc7e1 8420 bool found = false;
252b5132 8421
dda8d76d
NC
8422 for (i = 0, section = filedata->section_headers;
8423 i < filedata->file_header.e_shnum;
b34976b6 8424 i++, section++)
252b5132
RH
8425 {
8426 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8427 && section->sh_type != SHT_REL
8428 && section->sh_type != SHT_RELR)
252b5132
RH
8429 continue;
8430
8431 rel_offset = section->sh_offset;
8432 rel_size = section->sh_size;
8433
8434 if (rel_size)
8435 {
a7fd1186 8436 relocation_type rel_type;
d3a49aa8 8437 unsigned long num_rela;
103f02d3 8438
ca0e11aa
NC
8439 if (filedata->is_separate)
8440 printf (_("\nIn linked file '%s' relocation section "),
8441 filedata->file_name);
8442 else
8443 printf (_("\nRelocation section "));
252b5132 8444
dda8d76d 8445 if (filedata->string_table == NULL)
19936277 8446 printf ("%d", section->sh_name);
252b5132 8447 else
dda8d76d 8448 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8449
d3a49aa8
AM
8450 num_rela = rel_size / section->sh_entsize;
8451 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8452 " at offset 0x%lx contains %lu entries:\n",
8453 num_rela),
8454 rel_offset, num_rela);
252b5132 8455
a7fd1186
FS
8456 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8457 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8458
4fbb74a6 8459 if (section->sh_link != 0
dda8d76d 8460 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8461 {
2cf0635d
NC
8462 Elf_Internal_Shdr * symsec;
8463 Elf_Internal_Sym * symtab;
d79b3d50 8464 unsigned long nsyms;
c256ffe7 8465 unsigned long strtablen = 0;
2cf0635d 8466 char * strtab = NULL;
57346661 8467
dda8d76d 8468 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8469 if (symsec->sh_type != SHT_SYMTAB
8470 && symsec->sh_type != SHT_DYNSYM)
8471 continue;
8472
28d13567
AM
8473 if (!get_symtab (filedata, symsec,
8474 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8475 continue;
252b5132 8476
dda8d76d 8477 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8478 symtab, nsyms, strtab, strtablen,
a7fd1186 8479 rel_type,
bb4d2ac2 8480 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8481 free (strtab);
d79b3d50
NC
8482 free (symtab);
8483 }
8484 else
dda8d76d 8485 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8486 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8487
015dc7e1 8488 found = true;
252b5132
RH
8489 }
8490 }
8491
8492 if (! found)
45ac8f4f
NC
8493 {
8494 /* Users sometimes forget the -D option, so try to be helpful. */
8495 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8496 {
978c4450 8497 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8498 {
ca0e11aa
NC
8499 if (filedata->is_separate)
8500 printf (_("\nThere are no static relocations in linked file '%s'."),
8501 filedata->file_name);
8502 else
8503 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8504 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8505
8506 break;
8507 }
8508 }
8509 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8510 {
8511 if (filedata->is_separate)
8512 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8513 filedata->file_name);
8514 else
8515 printf (_("\nThere are no relocations in this file.\n"));
8516 }
45ac8f4f 8517 }
252b5132
RH
8518 }
8519
015dc7e1 8520 return true;
252b5132
RH
8521}
8522
4d6ed7c8
NC
8523/* An absolute address consists of a section and an offset. If the
8524 section is NULL, the offset itself is the address, otherwise, the
8525 address equals to LOAD_ADDRESS(section) + offset. */
8526
8527struct absaddr
948f632f
DA
8528{
8529 unsigned short section;
8530 bfd_vma offset;
8531};
4d6ed7c8 8532
948f632f
DA
8533/* Find the nearest symbol at or below ADDR. Returns the symbol
8534 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8535
4d6ed7c8 8536static void
dda8d76d
NC
8537find_symbol_for_address (Filedata * filedata,
8538 Elf_Internal_Sym * symtab,
8539 unsigned long nsyms,
8540 const char * strtab,
8541 unsigned long strtab_size,
8542 struct absaddr addr,
8543 const char ** symname,
8544 bfd_vma * offset)
4d6ed7c8 8545{
d3ba0551 8546 bfd_vma dist = 0x100000;
2cf0635d 8547 Elf_Internal_Sym * sym;
948f632f
DA
8548 Elf_Internal_Sym * beg;
8549 Elf_Internal_Sym * end;
2cf0635d 8550 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8551
0b6ae522 8552 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8553 beg = symtab;
8554 end = symtab + nsyms;
0b6ae522 8555
948f632f 8556 while (beg < end)
4d6ed7c8 8557 {
948f632f
DA
8558 bfd_vma value;
8559
8560 sym = beg + (end - beg) / 2;
0b6ae522 8561
948f632f 8562 value = sym->st_value;
0b6ae522
DJ
8563 REMOVE_ARCH_BITS (value);
8564
948f632f 8565 if (sym->st_name != 0
4d6ed7c8 8566 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8567 && addr.offset >= value
8568 && addr.offset - value < dist)
4d6ed7c8
NC
8569 {
8570 best = sym;
0b6ae522 8571 dist = addr.offset - value;
4d6ed7c8
NC
8572 if (!dist)
8573 break;
8574 }
948f632f
DA
8575
8576 if (addr.offset < value)
8577 end = sym;
8578 else
8579 beg = sym + 1;
4d6ed7c8 8580 }
1b31d05e 8581
4d6ed7c8
NC
8582 if (best)
8583 {
57346661 8584 *symname = (best->st_name >= strtab_size
2b692964 8585 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8586 *offset = dist;
8587 return;
8588 }
1b31d05e 8589
4d6ed7c8
NC
8590 *symname = NULL;
8591 *offset = addr.offset;
8592}
8593
32ec8896 8594static /* signed */ int
948f632f
DA
8595symcmp (const void *p, const void *q)
8596{
8597 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8598 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8599
8600 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8601}
8602
8603/* Process the unwind section. */
8604
8605#include "unwind-ia64.h"
8606
8607struct ia64_unw_table_entry
8608{
8609 struct absaddr start;
8610 struct absaddr end;
8611 struct absaddr info;
8612};
8613
8614struct ia64_unw_aux_info
8615{
32ec8896
NC
8616 struct ia64_unw_table_entry * table; /* Unwind table. */
8617 unsigned long table_len; /* Length of unwind table. */
8618 unsigned char * info; /* Unwind info. */
8619 unsigned long info_size; /* Size of unwind info. */
8620 bfd_vma info_addr; /* Starting address of unwind info. */
8621 bfd_vma seg_base; /* Starting address of segment. */
8622 Elf_Internal_Sym * symtab; /* The symbol table. */
8623 unsigned long nsyms; /* Number of symbols. */
8624 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8625 unsigned long nfuns; /* Number of entries in funtab. */
8626 char * strtab; /* The string table. */
8627 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8628};
8629
015dc7e1 8630static bool
dda8d76d 8631dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8632{
2cf0635d 8633 struct ia64_unw_table_entry * tp;
948f632f 8634 unsigned long j, nfuns;
4d6ed7c8 8635 int in_body;
015dc7e1 8636 bool res = true;
7036c0e1 8637
948f632f
DA
8638 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8639 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8640 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8641 aux->funtab[nfuns++] = aux->symtab[j];
8642 aux->nfuns = nfuns;
8643 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8644
4d6ed7c8
NC
8645 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8646 {
8647 bfd_vma stamp;
8648 bfd_vma offset;
2cf0635d
NC
8649 const unsigned char * dp;
8650 const unsigned char * head;
53774b7e 8651 const unsigned char * end;
2cf0635d 8652 const char * procname;
4d6ed7c8 8653
dda8d76d 8654 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8655 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8656
8657 fputs ("\n<", stdout);
8658
8659 if (procname)
8660 {
8661 fputs (procname, stdout);
8662
8663 if (offset)
8664 printf ("+%lx", (unsigned long) offset);
8665 }
8666
8667 fputs (">: [", stdout);
8668 print_vma (tp->start.offset, PREFIX_HEX);
8669 fputc ('-', stdout);
8670 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8671 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8672 (unsigned long) (tp->info.offset - aux->seg_base));
8673
53774b7e
NC
8674 /* PR 17531: file: 86232b32. */
8675 if (aux->info == NULL)
8676 continue;
8677
97c0a079
AM
8678 offset = tp->info.offset;
8679 if (tp->info.section)
8680 {
8681 if (tp->info.section >= filedata->file_header.e_shnum)
8682 {
8683 warn (_("Invalid section %u in table entry %ld\n"),
8684 tp->info.section, (long) (tp - aux->table));
015dc7e1 8685 res = false;
97c0a079
AM
8686 continue;
8687 }
8688 offset += filedata->section_headers[tp->info.section].sh_addr;
8689 }
8690 offset -= aux->info_addr;
53774b7e 8691 /* PR 17531: file: 0997b4d1. */
90679903
AM
8692 if (offset >= aux->info_size
8693 || aux->info_size - offset < 8)
53774b7e
NC
8694 {
8695 warn (_("Invalid offset %lx in table entry %ld\n"),
8696 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8697 res = false;
53774b7e
NC
8698 continue;
8699 }
8700
97c0a079 8701 head = aux->info + offset;
a4a00738 8702 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8703
86f55779 8704 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8705 (unsigned) UNW_VER (stamp),
8706 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8707 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8708 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8709 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8710
8711 if (UNW_VER (stamp) != 1)
8712 {
2b692964 8713 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8714 continue;
8715 }
8716
8717 in_body = 0;
53774b7e
NC
8718 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8719 /* PR 17531: file: 16ceda89. */
8720 if (end > aux->info + aux->info_size)
8721 end = aux->info + aux->info_size;
8722 for (dp = head + 8; dp < end;)
b4477bc8 8723 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8724 }
948f632f
DA
8725
8726 free (aux->funtab);
32ec8896
NC
8727
8728 return res;
4d6ed7c8
NC
8729}
8730
015dc7e1 8731static bool
dda8d76d
NC
8732slurp_ia64_unwind_table (Filedata * filedata,
8733 struct ia64_unw_aux_info * aux,
8734 Elf_Internal_Shdr * sec)
4d6ed7c8 8735{
89fac5e3 8736 unsigned long size, nrelas, i;
2cf0635d
NC
8737 Elf_Internal_Phdr * seg;
8738 struct ia64_unw_table_entry * tep;
8739 Elf_Internal_Shdr * relsec;
8740 Elf_Internal_Rela * rela;
8741 Elf_Internal_Rela * rp;
8742 unsigned char * table;
8743 unsigned char * tp;
8744 Elf_Internal_Sym * sym;
8745 const char * relname;
4d6ed7c8 8746
53774b7e
NC
8747 aux->table_len = 0;
8748
4d6ed7c8
NC
8749 /* First, find the starting address of the segment that includes
8750 this section: */
8751
dda8d76d 8752 if (filedata->file_header.e_phnum)
4d6ed7c8 8753 {
dda8d76d 8754 if (! get_program_headers (filedata))
015dc7e1 8755 return false;
4d6ed7c8 8756
dda8d76d
NC
8757 for (seg = filedata->program_headers;
8758 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8759 ++seg)
4d6ed7c8
NC
8760 {
8761 if (seg->p_type != PT_LOAD)
8762 continue;
8763
8764 if (sec->sh_addr >= seg->p_vaddr
8765 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8766 {
8767 aux->seg_base = seg->p_vaddr;
8768 break;
8769 }
8770 }
4d6ed7c8
NC
8771 }
8772
8773 /* Second, build the unwind table from the contents of the unwind section: */
8774 size = sec->sh_size;
dda8d76d 8775 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8776 _("unwind table"));
a6e9f9df 8777 if (!table)
015dc7e1 8778 return false;
4d6ed7c8 8779
53774b7e 8780 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8781 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8782 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8783 tep = aux->table;
53774b7e
NC
8784
8785 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8786 {
8787 tep->start.section = SHN_UNDEF;
8788 tep->end.section = SHN_UNDEF;
8789 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8790 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8791 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8792 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8793 tep->start.offset += aux->seg_base;
8794 tep->end.offset += aux->seg_base;
8795 tep->info.offset += aux->seg_base;
8796 }
8797 free (table);
8798
41e92641 8799 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8800 for (relsec = filedata->section_headers;
8801 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8802 ++relsec)
8803 {
8804 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8805 || relsec->sh_info >= filedata->file_header.e_shnum
8806 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8807 continue;
8808
dda8d76d 8809 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8810 & rela, & nrelas))
53774b7e
NC
8811 {
8812 free (aux->table);
8813 aux->table = NULL;
8814 aux->table_len = 0;
015dc7e1 8815 return false;
53774b7e 8816 }
4d6ed7c8
NC
8817
8818 for (rp = rela; rp < rela + nrelas; ++rp)
8819 {
4770fb94 8820 unsigned int sym_ndx;
726bd37d
AM
8821 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8822 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8823
82b1b41b
NC
8824 /* PR 17531: file: 9fa67536. */
8825 if (relname == NULL)
8826 {
726bd37d 8827 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8828 continue;
8829 }
948f632f 8830
24d127aa 8831 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8832 {
82b1b41b 8833 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8834 continue;
8835 }
8836
89fac5e3 8837 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8838
53774b7e
NC
8839 /* PR 17531: file: 5bc8d9bf. */
8840 if (i >= aux->table_len)
8841 {
8842 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8843 continue;
8844 }
8845
4770fb94
AM
8846 sym_ndx = get_reloc_symindex (rp->r_info);
8847 if (sym_ndx >= aux->nsyms)
8848 {
8849 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8850 sym_ndx);
8851 continue;
8852 }
8853 sym = aux->symtab + sym_ndx;
8854
53774b7e 8855 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8856 {
8857 case 0:
8858 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8859 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8860 break;
8861 case 1:
8862 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8863 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8864 break;
8865 case 2:
8866 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8867 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8868 break;
8869 default:
8870 break;
8871 }
8872 }
8873
8874 free (rela);
8875 }
8876
015dc7e1 8877 return true;
4d6ed7c8
NC
8878}
8879
015dc7e1 8880static bool
dda8d76d 8881ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8882{
2cf0635d
NC
8883 Elf_Internal_Shdr * sec;
8884 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8885 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8886 struct ia64_unw_aux_info aux;
015dc7e1 8887 bool res = true;
f1467e33 8888
4d6ed7c8
NC
8889 memset (& aux, 0, sizeof (aux));
8890
dda8d76d 8891 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8892 {
28d13567 8893 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8894 {
28d13567 8895 if (aux.symtab)
4082ef84 8896 {
28d13567
AM
8897 error (_("Multiple symbol tables encountered\n"));
8898 free (aux.symtab);
8899 aux.symtab = NULL;
4082ef84 8900 free (aux.strtab);
28d13567 8901 aux.strtab = NULL;
4082ef84 8902 }
28d13567
AM
8903 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8904 &aux.strtab, &aux.strtab_size))
015dc7e1 8905 return false;
4d6ed7c8
NC
8906 }
8907 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8908 unwcount++;
8909 }
8910
8911 if (!unwcount)
8912 printf (_("\nThere are no unwind sections in this file.\n"));
8913
8914 while (unwcount-- > 0)
8915 {
84714f86 8916 const char *suffix;
579f31ac
JJ
8917 size_t len, len2;
8918
dda8d76d
NC
8919 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8920 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8921 if (sec->sh_type == SHT_IA_64_UNWIND)
8922 {
8923 unwsec = sec;
8924 break;
8925 }
4082ef84
NC
8926 /* We have already counted the number of SHT_IA64_UNWIND
8927 sections so the loop above should never fail. */
8928 assert (unwsec != NULL);
579f31ac
JJ
8929
8930 unwstart = i + 1;
8931 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8932
e4b17d5c
L
8933 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8934 {
8935 /* We need to find which section group it is in. */
4082ef84 8936 struct group_list * g;
e4b17d5c 8937
978c4450
AM
8938 if (filedata->section_headers_groups == NULL
8939 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8940 i = filedata->file_header.e_shnum;
4082ef84 8941 else
e4b17d5c 8942 {
978c4450 8943 g = filedata->section_headers_groups[i]->root;
18bd398b 8944
4082ef84
NC
8945 for (; g != NULL; g = g->next)
8946 {
dda8d76d 8947 sec = filedata->section_headers + g->section_index;
e4b17d5c 8948
84714f86
AM
8949 if (section_name_valid (filedata, sec)
8950 && streq (section_name (filedata, sec),
8951 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8952 break;
8953 }
8954
8955 if (g == NULL)
dda8d76d 8956 i = filedata->file_header.e_shnum;
4082ef84 8957 }
e4b17d5c 8958 }
84714f86
AM
8959 else if (section_name_valid (filedata, unwsec)
8960 && startswith (section_name (filedata, unwsec),
e9b095a5 8961 ELF_STRING_ia64_unwind_once))
579f31ac 8962 {
18bd398b 8963 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8964 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8965 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8966 for (i = 0, sec = filedata->section_headers;
8967 i < filedata->file_header.e_shnum;
579f31ac 8968 ++i, ++sec)
84714f86
AM
8969 if (section_name_valid (filedata, sec)
8970 && startswith (section_name (filedata, sec),
e9b095a5 8971 ELF_STRING_ia64_unwind_info_once)
84714f86 8972 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8973 break;
8974 }
8975 else
8976 {
8977 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8978 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8979 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8980 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8981 suffix = "";
84714f86
AM
8982 if (section_name_valid (filedata, unwsec)
8983 && startswith (section_name (filedata, unwsec),
8984 ELF_STRING_ia64_unwind))
8985 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8986 for (i = 0, sec = filedata->section_headers;
8987 i < filedata->file_header.e_shnum;
579f31ac 8988 ++i, ++sec)
84714f86
AM
8989 if (section_name_valid (filedata, sec)
8990 && startswith (section_name (filedata, sec),
8991 ELF_STRING_ia64_unwind_info)
8992 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8993 break;
8994 }
8995
dda8d76d 8996 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8997 {
8998 printf (_("\nCould not find unwind info section for "));
8999
dda8d76d 9000 if (filedata->string_table == NULL)
579f31ac
JJ
9001 printf ("%d", unwsec->sh_name);
9002 else
dda8d76d 9003 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9004 }
9005 else
4d6ed7c8 9006 {
4d6ed7c8 9007 aux.info_addr = sec->sh_addr;
dda8d76d 9008 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9009 sec->sh_size,
9010 _("unwind info"));
59245841 9011 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9012
579f31ac 9013 printf (_("\nUnwind section "));
4d6ed7c8 9014
dda8d76d 9015 if (filedata->string_table == NULL)
579f31ac
JJ
9016 printf ("%d", unwsec->sh_name);
9017 else
dda8d76d 9018 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9019
579f31ac 9020 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9021 (unsigned long) unwsec->sh_offset,
89fac5e3 9022 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9023
dda8d76d 9024 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9025 && aux.table_len > 0)
dda8d76d 9026 dump_ia64_unwind (filedata, & aux);
579f31ac 9027
9db70fc3
AM
9028 free ((char *) aux.table);
9029 free ((char *) aux.info);
579f31ac
JJ
9030 aux.table = NULL;
9031 aux.info = NULL;
9032 }
4d6ed7c8 9033 }
4d6ed7c8 9034
9db70fc3
AM
9035 free (aux.symtab);
9036 free ((char *) aux.strtab);
32ec8896
NC
9037
9038 return res;
4d6ed7c8
NC
9039}
9040
3f5e193b 9041struct hppa_unw_table_entry
32ec8896
NC
9042{
9043 struct absaddr start;
9044 struct absaddr end;
9045 unsigned int Cannot_unwind:1; /* 0 */
9046 unsigned int Millicode:1; /* 1 */
9047 unsigned int Millicode_save_sr0:1; /* 2 */
9048 unsigned int Region_description:2; /* 3..4 */
9049 unsigned int reserved1:1; /* 5 */
9050 unsigned int Entry_SR:1; /* 6 */
9051 unsigned int Entry_FR:4; /* Number saved 7..10 */
9052 unsigned int Entry_GR:5; /* Number saved 11..15 */
9053 unsigned int Args_stored:1; /* 16 */
9054 unsigned int Variable_Frame:1; /* 17 */
9055 unsigned int Separate_Package_Body:1; /* 18 */
9056 unsigned int Frame_Extension_Millicode:1; /* 19 */
9057 unsigned int Stack_Overflow_Check:1; /* 20 */
9058 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9059 unsigned int Ada_Region:1; /* 22 */
9060 unsigned int cxx_info:1; /* 23 */
9061 unsigned int cxx_try_catch:1; /* 24 */
9062 unsigned int sched_entry_seq:1; /* 25 */
9063 unsigned int reserved2:1; /* 26 */
9064 unsigned int Save_SP:1; /* 27 */
9065 unsigned int Save_RP:1; /* 28 */
9066 unsigned int Save_MRP_in_frame:1; /* 29 */
9067 unsigned int extn_ptr_defined:1; /* 30 */
9068 unsigned int Cleanup_defined:1; /* 31 */
9069
9070 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9071 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9072 unsigned int Large_frame:1; /* 2 */
9073 unsigned int Pseudo_SP_Set:1; /* 3 */
9074 unsigned int reserved4:1; /* 4 */
9075 unsigned int Total_frame_size:27; /* 5..31 */
9076};
3f5e193b 9077
57346661 9078struct hppa_unw_aux_info
948f632f 9079{
32ec8896
NC
9080 struct hppa_unw_table_entry * table; /* Unwind table. */
9081 unsigned long table_len; /* Length of unwind table. */
9082 bfd_vma seg_base; /* Starting address of segment. */
9083 Elf_Internal_Sym * symtab; /* The symbol table. */
9084 unsigned long nsyms; /* Number of symbols. */
9085 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9086 unsigned long nfuns; /* Number of entries in funtab. */
9087 char * strtab; /* The string table. */
9088 unsigned long strtab_size; /* Size of string table. */
948f632f 9089};
57346661 9090
015dc7e1 9091static bool
dda8d76d 9092dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9093{
2cf0635d 9094 struct hppa_unw_table_entry * tp;
948f632f 9095 unsigned long j, nfuns;
015dc7e1 9096 bool res = true;
948f632f
DA
9097
9098 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9099 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9100 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9101 aux->funtab[nfuns++] = aux->symtab[j];
9102 aux->nfuns = nfuns;
9103 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9104
57346661
AM
9105 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9106 {
9107 bfd_vma offset;
2cf0635d 9108 const char * procname;
57346661 9109
dda8d76d 9110 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9111 aux->strtab_size, tp->start, &procname,
9112 &offset);
9113
9114 fputs ("\n<", stdout);
9115
9116 if (procname)
9117 {
9118 fputs (procname, stdout);
9119
9120 if (offset)
9121 printf ("+%lx", (unsigned long) offset);
9122 }
9123
9124 fputs (">: [", stdout);
9125 print_vma (tp->start.offset, PREFIX_HEX);
9126 fputc ('-', stdout);
9127 print_vma (tp->end.offset, PREFIX_HEX);
9128 printf ("]\n\t");
9129
18bd398b
NC
9130#define PF(_m) if (tp->_m) printf (#_m " ");
9131#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9132 PF(Cannot_unwind);
9133 PF(Millicode);
9134 PF(Millicode_save_sr0);
18bd398b 9135 /* PV(Region_description); */
57346661
AM
9136 PF(Entry_SR);
9137 PV(Entry_FR);
9138 PV(Entry_GR);
9139 PF(Args_stored);
9140 PF(Variable_Frame);
9141 PF(Separate_Package_Body);
9142 PF(Frame_Extension_Millicode);
9143 PF(Stack_Overflow_Check);
9144 PF(Two_Instruction_SP_Increment);
9145 PF(Ada_Region);
9146 PF(cxx_info);
9147 PF(cxx_try_catch);
9148 PF(sched_entry_seq);
9149 PF(Save_SP);
9150 PF(Save_RP);
9151 PF(Save_MRP_in_frame);
9152 PF(extn_ptr_defined);
9153 PF(Cleanup_defined);
9154 PF(MPE_XL_interrupt_marker);
9155 PF(HP_UX_interrupt_marker);
9156 PF(Large_frame);
9157 PF(Pseudo_SP_Set);
9158 PV(Total_frame_size);
9159#undef PF
9160#undef PV
9161 }
9162
18bd398b 9163 printf ("\n");
948f632f
DA
9164
9165 free (aux->funtab);
32ec8896
NC
9166
9167 return res;
57346661
AM
9168}
9169
015dc7e1 9170static bool
dda8d76d
NC
9171slurp_hppa_unwind_table (Filedata * filedata,
9172 struct hppa_unw_aux_info * aux,
9173 Elf_Internal_Shdr * sec)
57346661 9174{
1c0751b2 9175 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9176 Elf_Internal_Phdr * seg;
9177 struct hppa_unw_table_entry * tep;
9178 Elf_Internal_Shdr * relsec;
9179 Elf_Internal_Rela * rela;
9180 Elf_Internal_Rela * rp;
9181 unsigned char * table;
9182 unsigned char * tp;
9183 Elf_Internal_Sym * sym;
9184 const char * relname;
57346661 9185
57346661
AM
9186 /* First, find the starting address of the segment that includes
9187 this section. */
dda8d76d 9188 if (filedata->file_header.e_phnum)
57346661 9189 {
dda8d76d 9190 if (! get_program_headers (filedata))
015dc7e1 9191 return false;
57346661 9192
dda8d76d
NC
9193 for (seg = filedata->program_headers;
9194 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9195 ++seg)
9196 {
9197 if (seg->p_type != PT_LOAD)
9198 continue;
9199
9200 if (sec->sh_addr >= seg->p_vaddr
9201 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9202 {
9203 aux->seg_base = seg->p_vaddr;
9204 break;
9205 }
9206 }
9207 }
9208
9209 /* Second, build the unwind table from the contents of the unwind
9210 section. */
9211 size = sec->sh_size;
dda8d76d 9212 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9213 _("unwind table"));
57346661 9214 if (!table)
015dc7e1 9215 return false;
57346661 9216
1c0751b2
DA
9217 unw_ent_size = 16;
9218 nentries = size / unw_ent_size;
9219 size = unw_ent_size * nentries;
57346661 9220
e3fdc001 9221 aux->table_len = nentries;
3f5e193b
NC
9222 tep = aux->table = (struct hppa_unw_table_entry *)
9223 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9224
1c0751b2 9225 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9226 {
9227 unsigned int tmp1, tmp2;
9228
9229 tep->start.section = SHN_UNDEF;
9230 tep->end.section = SHN_UNDEF;
9231
1c0751b2
DA
9232 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9233 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9234 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9235 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9236
9237 tep->start.offset += aux->seg_base;
9238 tep->end.offset += aux->seg_base;
57346661
AM
9239
9240 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9241 tep->Millicode = (tmp1 >> 30) & 0x1;
9242 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9243 tep->Region_description = (tmp1 >> 27) & 0x3;
9244 tep->reserved1 = (tmp1 >> 26) & 0x1;
9245 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9246 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9247 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9248 tep->Args_stored = (tmp1 >> 15) & 0x1;
9249 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9250 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9251 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9252 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9253 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9254 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9255 tep->cxx_info = (tmp1 >> 8) & 0x1;
9256 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9257 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9258 tep->reserved2 = (tmp1 >> 5) & 0x1;
9259 tep->Save_SP = (tmp1 >> 4) & 0x1;
9260 tep->Save_RP = (tmp1 >> 3) & 0x1;
9261 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9262 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9263 tep->Cleanup_defined = tmp1 & 0x1;
9264
9265 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9266 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9267 tep->Large_frame = (tmp2 >> 29) & 0x1;
9268 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9269 tep->reserved4 = (tmp2 >> 27) & 0x1;
9270 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9271 }
9272 free (table);
9273
9274 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9275 for (relsec = filedata->section_headers;
9276 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9277 ++relsec)
9278 {
9279 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9280 || relsec->sh_info >= filedata->file_header.e_shnum
9281 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9282 continue;
9283
dda8d76d 9284 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9285 & rela, & nrelas))
015dc7e1 9286 return false;
57346661
AM
9287
9288 for (rp = rela; rp < rela + nrelas; ++rp)
9289 {
4770fb94 9290 unsigned int sym_ndx;
726bd37d
AM
9291 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9292 relname = elf_hppa_reloc_type (r_type);
57346661 9293
726bd37d
AM
9294 if (relname == NULL)
9295 {
9296 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9297 continue;
9298 }
9299
57346661 9300 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9301 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9302 {
726bd37d 9303 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9304 continue;
9305 }
9306
9307 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9308 if (i >= aux->table_len)
9309 {
9310 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9311 continue;
9312 }
57346661 9313
4770fb94
AM
9314 sym_ndx = get_reloc_symindex (rp->r_info);
9315 if (sym_ndx >= aux->nsyms)
9316 {
9317 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9318 sym_ndx);
9319 continue;
9320 }
9321 sym = aux->symtab + sym_ndx;
9322
43f6cd05 9323 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9324 {
9325 case 0:
9326 aux->table[i].start.section = sym->st_shndx;
1e456d54 9327 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9328 break;
9329 case 1:
9330 aux->table[i].end.section = sym->st_shndx;
1e456d54 9331 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9332 break;
9333 default:
9334 break;
9335 }
9336 }
9337
9338 free (rela);
9339 }
9340
015dc7e1 9341 return true;
57346661
AM
9342}
9343
015dc7e1 9344static bool
dda8d76d 9345hppa_process_unwind (Filedata * filedata)
57346661 9346{
57346661 9347 struct hppa_unw_aux_info aux;
2cf0635d 9348 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9349 Elf_Internal_Shdr * sec;
18bd398b 9350 unsigned long i;
015dc7e1 9351 bool res = true;
57346661 9352
dda8d76d 9353 if (filedata->string_table == NULL)
015dc7e1 9354 return false;
1b31d05e
NC
9355
9356 memset (& aux, 0, sizeof (aux));
57346661 9357
dda8d76d 9358 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9359 {
28d13567 9360 if (sec->sh_type == SHT_SYMTAB)
57346661 9361 {
28d13567 9362 if (aux.symtab)
4082ef84 9363 {
28d13567
AM
9364 error (_("Multiple symbol tables encountered\n"));
9365 free (aux.symtab);
9366 aux.symtab = NULL;
4082ef84 9367 free (aux.strtab);
28d13567 9368 aux.strtab = NULL;
4082ef84 9369 }
28d13567
AM
9370 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9371 &aux.strtab, &aux.strtab_size))
015dc7e1 9372 return false;
57346661 9373 }
84714f86
AM
9374 else if (section_name_valid (filedata, sec)
9375 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9376 unwsec = sec;
9377 }
9378
9379 if (!unwsec)
9380 printf (_("\nThere are no unwind sections in this file.\n"));
9381
dda8d76d 9382 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9383 {
84714f86
AM
9384 if (section_name_valid (filedata, sec)
9385 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9386 {
43f6cd05 9387 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9388
d3a49aa8
AM
9389 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9390 "contains %lu entry:\n",
9391 "\nUnwind section '%s' at offset 0x%lx "
9392 "contains %lu entries:\n",
9393 num_unwind),
dda8d76d 9394 printable_section_name (filedata, sec),
57346661 9395 (unsigned long) sec->sh_offset,
d3a49aa8 9396 num_unwind);
57346661 9397
dda8d76d 9398 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9399 res = false;
66b09c7e
S
9400
9401 if (res && aux.table_len > 0)
32ec8896 9402 {
dda8d76d 9403 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9404 res = false;
32ec8896 9405 }
57346661 9406
9db70fc3 9407 free ((char *) aux.table);
57346661
AM
9408 aux.table = NULL;
9409 }
9410 }
9411
9db70fc3
AM
9412 free (aux.symtab);
9413 free ((char *) aux.strtab);
32ec8896
NC
9414
9415 return res;
57346661
AM
9416}
9417
0b6ae522
DJ
9418struct arm_section
9419{
a734115a
NC
9420 unsigned char * data; /* The unwind data. */
9421 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9422 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9423 unsigned long nrelas; /* The number of relocations. */
9424 unsigned int rel_type; /* REL or RELA ? */
9425 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9426};
9427
9428struct arm_unw_aux_info
9429{
dda8d76d 9430 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9431 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9432 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9433 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9434 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9435 char * strtab; /* The file's string table. */
9436 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9437};
9438
9439static const char *
dda8d76d
NC
9440arm_print_vma_and_name (Filedata * filedata,
9441 struct arm_unw_aux_info * aux,
9442 bfd_vma fn,
9443 struct absaddr addr)
0b6ae522
DJ
9444{
9445 const char *procname;
9446 bfd_vma sym_offset;
9447
9448 if (addr.section == SHN_UNDEF)
9449 addr.offset = fn;
9450
dda8d76d 9451 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9452 aux->strtab_size, addr, &procname,
9453 &sym_offset);
9454
9455 print_vma (fn, PREFIX_HEX);
9456
9457 if (procname)
9458 {
9459 fputs (" <", stdout);
9460 fputs (procname, stdout);
9461
9462 if (sym_offset)
9463 printf ("+0x%lx", (unsigned long) sym_offset);
9464 fputc ('>', stdout);
9465 }
9466
9467 return procname;
9468}
9469
9470static void
9471arm_free_section (struct arm_section *arm_sec)
9472{
9db70fc3
AM
9473 free (arm_sec->data);
9474 free (arm_sec->rela);
0b6ae522
DJ
9475}
9476
a734115a
NC
9477/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9478 cached section and install SEC instead.
9479 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9480 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9481 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9482 relocation's offset in ADDR.
1b31d05e
NC
9483 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9484 into the string table of the symbol associated with the reloc. If no
9485 reloc was applied store -1 there.
9486 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9487
015dc7e1 9488static bool
dda8d76d
NC
9489get_unwind_section_word (Filedata * filedata,
9490 struct arm_unw_aux_info * aux,
1b31d05e
NC
9491 struct arm_section * arm_sec,
9492 Elf_Internal_Shdr * sec,
9493 bfd_vma word_offset,
9494 unsigned int * wordp,
9495 struct absaddr * addr,
9496 bfd_vma * sym_name)
0b6ae522
DJ
9497{
9498 Elf_Internal_Rela *rp;
9499 Elf_Internal_Sym *sym;
9500 const char * relname;
9501 unsigned int word;
015dc7e1 9502 bool wrapped;
0b6ae522 9503
e0a31db1 9504 if (sec == NULL || arm_sec == NULL)
015dc7e1 9505 return false;
e0a31db1 9506
0b6ae522
DJ
9507 addr->section = SHN_UNDEF;
9508 addr->offset = 0;
9509
1b31d05e
NC
9510 if (sym_name != NULL)
9511 *sym_name = (bfd_vma) -1;
9512
a734115a 9513 /* If necessary, update the section cache. */
0b6ae522
DJ
9514 if (sec != arm_sec->sec)
9515 {
9516 Elf_Internal_Shdr *relsec;
9517
9518 arm_free_section (arm_sec);
9519
9520 arm_sec->sec = sec;
dda8d76d 9521 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9522 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9523 arm_sec->rela = NULL;
9524 arm_sec->nrelas = 0;
9525
dda8d76d
NC
9526 for (relsec = filedata->section_headers;
9527 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9528 ++relsec)
9529 {
dda8d76d
NC
9530 if (relsec->sh_info >= filedata->file_header.e_shnum
9531 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9532 /* PR 15745: Check the section type as well. */
9533 || (relsec->sh_type != SHT_REL
9534 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9535 continue;
9536
a734115a 9537 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9538 if (relsec->sh_type == SHT_REL)
9539 {
dda8d76d 9540 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9541 relsec->sh_size,
9542 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9543 return false;
0b6ae522 9544 }
1ae40aa4 9545 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9546 {
dda8d76d 9547 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9548 relsec->sh_size,
9549 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9550 return false;
0b6ae522 9551 }
1ae40aa4 9552 break;
0b6ae522
DJ
9553 }
9554
9555 arm_sec->next_rela = arm_sec->rela;
9556 }
9557
a734115a 9558 /* If there is no unwind data we can do nothing. */
0b6ae522 9559 if (arm_sec->data == NULL)
015dc7e1 9560 return false;
0b6ae522 9561
e0a31db1 9562 /* If the offset is invalid then fail. */
f32ba729
NC
9563 if (/* PR 21343 *//* PR 18879 */
9564 sec->sh_size < 4
9565 || word_offset > (sec->sh_size - 4)
1a915552 9566 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9567 return false;
e0a31db1 9568
a734115a 9569 /* Get the word at the required offset. */
0b6ae522
DJ
9570 word = byte_get (arm_sec->data + word_offset, 4);
9571
0eff7165
NC
9572 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9573 if (arm_sec->rela == NULL)
9574 {
9575 * wordp = word;
015dc7e1 9576 return true;
0eff7165
NC
9577 }
9578
a734115a 9579 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9580 wrapped = false;
0b6ae522
DJ
9581 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9582 {
9583 bfd_vma prelval, offset;
9584
9585 if (rp->r_offset > word_offset && !wrapped)
9586 {
9587 rp = arm_sec->rela;
015dc7e1 9588 wrapped = true;
0b6ae522
DJ
9589 }
9590 if (rp->r_offset > word_offset)
9591 break;
9592
9593 if (rp->r_offset & 3)
9594 {
9595 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9596 (unsigned long) rp->r_offset);
9597 continue;
9598 }
9599
9600 if (rp->r_offset < word_offset)
9601 continue;
9602
74e1a04b
NC
9603 /* PR 17531: file: 027-161405-0.004 */
9604 if (aux->symtab == NULL)
9605 continue;
9606
0b6ae522
DJ
9607 if (arm_sec->rel_type == SHT_REL)
9608 {
9609 offset = word & 0x7fffffff;
9610 if (offset & 0x40000000)
9611 offset |= ~ (bfd_vma) 0x7fffffff;
9612 }
a734115a 9613 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9614 offset = rp->r_addend;
a734115a 9615 else
74e1a04b
NC
9616 {
9617 error (_("Unknown section relocation type %d encountered\n"),
9618 arm_sec->rel_type);
9619 break;
9620 }
0b6ae522 9621
071436c6
NC
9622 /* PR 17531 file: 027-1241568-0.004. */
9623 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9624 {
9625 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9626 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9627 break;
9628 }
9629
9630 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9631 offset += sym->st_value;
9632 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9633
a734115a 9634 /* Check that we are processing the expected reloc type. */
dda8d76d 9635 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9636 {
9637 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9638 if (relname == NULL)
9639 {
9640 warn (_("Skipping unknown ARM relocation type: %d\n"),
9641 (int) ELF32_R_TYPE (rp->r_info));
9642 continue;
9643 }
a734115a
NC
9644
9645 if (streq (relname, "R_ARM_NONE"))
9646 continue;
0b4362b0 9647
a734115a
NC
9648 if (! streq (relname, "R_ARM_PREL31"))
9649 {
071436c6 9650 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9651 continue;
9652 }
9653 }
dda8d76d 9654 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9655 {
9656 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9657 if (relname == NULL)
9658 {
9659 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9660 (int) ELF32_R_TYPE (rp->r_info));
9661 continue;
9662 }
0b4362b0 9663
a734115a
NC
9664 if (streq (relname, "R_C6000_NONE"))
9665 continue;
9666
9667 if (! streq (relname, "R_C6000_PREL31"))
9668 {
071436c6 9669 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9670 continue;
9671 }
9672
9673 prelval >>= 1;
9674 }
9675 else
74e1a04b
NC
9676 {
9677 /* This function currently only supports ARM and TI unwinders. */
9678 warn (_("Only TI and ARM unwinders are currently supported\n"));
9679 break;
9680 }
fa197c1c 9681
0b6ae522
DJ
9682 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9683 addr->section = sym->st_shndx;
9684 addr->offset = offset;
74e1a04b 9685
1b31d05e
NC
9686 if (sym_name)
9687 * sym_name = sym->st_name;
0b6ae522
DJ
9688 break;
9689 }
9690
9691 *wordp = word;
9692 arm_sec->next_rela = rp;
9693
015dc7e1 9694 return true;
0b6ae522
DJ
9695}
9696
a734115a
NC
9697static const char *tic6x_unwind_regnames[16] =
9698{
0b4362b0
RM
9699 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9700 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9701 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9702};
fa197c1c 9703
0b6ae522 9704static void
fa197c1c 9705decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9706{
fa197c1c
PB
9707 int i;
9708
9709 for (i = 12; mask; mask >>= 1, i--)
9710 {
9711 if (mask & 1)
9712 {
9713 fputs (tic6x_unwind_regnames[i], stdout);
9714 if (mask > 1)
9715 fputs (", ", stdout);
9716 }
9717 }
9718}
0b6ae522
DJ
9719
9720#define ADVANCE \
9721 if (remaining == 0 && more_words) \
9722 { \
9723 data_offset += 4; \
dda8d76d 9724 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9725 data_offset, & word, & addr, NULL)) \
015dc7e1 9726 return false; \
0b6ae522
DJ
9727 remaining = 4; \
9728 more_words--; \
9729 } \
9730
9731#define GET_OP(OP) \
9732 ADVANCE; \
9733 if (remaining) \
9734 { \
9735 remaining--; \
9736 (OP) = word >> 24; \
9737 word <<= 8; \
9738 } \
9739 else \
9740 { \
2b692964 9741 printf (_("[Truncated opcode]\n")); \
015dc7e1 9742 return false; \
0b6ae522 9743 } \
cc5914eb 9744 printf ("0x%02x ", OP)
0b6ae522 9745
015dc7e1 9746static bool
dda8d76d
NC
9747decode_arm_unwind_bytecode (Filedata * filedata,
9748 struct arm_unw_aux_info * aux,
948f632f
DA
9749 unsigned int word,
9750 unsigned int remaining,
9751 unsigned int more_words,
9752 bfd_vma data_offset,
9753 Elf_Internal_Shdr * data_sec,
9754 struct arm_section * data_arm_sec)
fa197c1c
PB
9755{
9756 struct absaddr addr;
015dc7e1 9757 bool res = true;
0b6ae522
DJ
9758
9759 /* Decode the unwinding instructions. */
9760 while (1)
9761 {
9762 unsigned int op, op2;
9763
9764 ADVANCE;
9765 if (remaining == 0)
9766 break;
9767 remaining--;
9768 op = word >> 24;
9769 word <<= 8;
9770
cc5914eb 9771 printf (" 0x%02x ", op);
0b6ae522
DJ
9772
9773 if ((op & 0xc0) == 0x00)
9774 {
9775 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9776
cc5914eb 9777 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9778 }
9779 else if ((op & 0xc0) == 0x40)
9780 {
9781 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9782
cc5914eb 9783 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9784 }
9785 else if ((op & 0xf0) == 0x80)
9786 {
9787 GET_OP (op2);
9788 if (op == 0x80 && op2 == 0)
9789 printf (_("Refuse to unwind"));
9790 else
9791 {
9792 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9793 bool first = true;
0b6ae522 9794 int i;
2b692964 9795
0b6ae522
DJ
9796 printf ("pop {");
9797 for (i = 0; i < 12; i++)
9798 if (mask & (1 << i))
9799 {
9800 if (first)
015dc7e1 9801 first = false;
0b6ae522
DJ
9802 else
9803 printf (", ");
9804 printf ("r%d", 4 + i);
9805 }
9806 printf ("}");
9807 }
9808 }
9809 else if ((op & 0xf0) == 0x90)
9810 {
9811 if (op == 0x9d || op == 0x9f)
9812 printf (_(" [Reserved]"));
9813 else
cc5914eb 9814 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9815 }
9816 else if ((op & 0xf0) == 0xa0)
9817 {
9818 int end = 4 + (op & 0x07);
015dc7e1 9819 bool first = true;
0b6ae522 9820 int i;
61865e30 9821
0b6ae522
DJ
9822 printf (" pop {");
9823 for (i = 4; i <= end; i++)
9824 {
9825 if (first)
015dc7e1 9826 first = false;
0b6ae522
DJ
9827 else
9828 printf (", ");
9829 printf ("r%d", i);
9830 }
9831 if (op & 0x08)
9832 {
1b31d05e 9833 if (!first)
0b6ae522
DJ
9834 printf (", ");
9835 printf ("r14");
9836 }
9837 printf ("}");
9838 }
9839 else if (op == 0xb0)
9840 printf (_(" finish"));
9841 else if (op == 0xb1)
9842 {
9843 GET_OP (op2);
9844 if (op2 == 0 || (op2 & 0xf0) != 0)
9845 printf (_("[Spare]"));
9846 else
9847 {
9848 unsigned int mask = op2 & 0x0f;
015dc7e1 9849 bool first = true;
0b6ae522 9850 int i;
61865e30 9851
0b6ae522
DJ
9852 printf ("pop {");
9853 for (i = 0; i < 12; i++)
9854 if (mask & (1 << i))
9855 {
9856 if (first)
015dc7e1 9857 first = false;
0b6ae522
DJ
9858 else
9859 printf (", ");
9860 printf ("r%d", i);
9861 }
9862 printf ("}");
9863 }
9864 }
9865 else if (op == 0xb2)
9866 {
b115cf96 9867 unsigned char buf[9];
0b6ae522
DJ
9868 unsigned int i, len;
9869 unsigned long offset;
61865e30 9870
b115cf96 9871 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9872 {
9873 GET_OP (buf[i]);
9874 if ((buf[i] & 0x80) == 0)
9875 break;
9876 }
4082ef84 9877 if (i == sizeof (buf))
32ec8896 9878 {
27a45f42 9879 error (_("corrupt change to vsp\n"));
015dc7e1 9880 res = false;
32ec8896 9881 }
4082ef84
NC
9882 else
9883 {
015dc7e1 9884 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9885 assert (len == i + 1);
9886 offset = offset * 4 + 0x204;
9887 printf ("vsp = vsp + %ld", offset);
9888 }
0b6ae522 9889 }
61865e30 9890 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9891 {
61865e30
NC
9892 unsigned int first, last;
9893
9894 GET_OP (op2);
9895 first = op2 >> 4;
9896 last = op2 & 0x0f;
9897 if (op == 0xc8)
9898 first = first + 16;
9899 printf ("pop {D%d", first);
9900 if (last)
9901 printf ("-D%d", first + last);
9902 printf ("}");
9903 }
09854a88
TB
9904 else if (op == 0xb4)
9905 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9906 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9907 {
9908 unsigned int count = op & 0x07;
9909
9910 printf ("pop {D8");
9911 if (count)
9912 printf ("-D%d", 8 + count);
9913 printf ("}");
9914 }
9915 else if (op >= 0xc0 && op <= 0xc5)
9916 {
9917 unsigned int count = op & 0x07;
9918
9919 printf (" pop {wR10");
9920 if (count)
9921 printf ("-wR%d", 10 + count);
9922 printf ("}");
9923 }
9924 else if (op == 0xc6)
9925 {
9926 unsigned int first, last;
9927
9928 GET_OP (op2);
9929 first = op2 >> 4;
9930 last = op2 & 0x0f;
9931 printf ("pop {wR%d", first);
9932 if (last)
9933 printf ("-wR%d", first + last);
9934 printf ("}");
9935 }
9936 else if (op == 0xc7)
9937 {
9938 GET_OP (op2);
9939 if (op2 == 0 || (op2 & 0xf0) != 0)
9940 printf (_("[Spare]"));
0b6ae522
DJ
9941 else
9942 {
61865e30 9943 unsigned int mask = op2 & 0x0f;
015dc7e1 9944 bool first = true;
61865e30
NC
9945 int i;
9946
9947 printf ("pop {");
9948 for (i = 0; i < 4; i++)
9949 if (mask & (1 << i))
9950 {
9951 if (first)
015dc7e1 9952 first = false;
61865e30
NC
9953 else
9954 printf (", ");
9955 printf ("wCGR%d", i);
9956 }
9957 printf ("}");
0b6ae522
DJ
9958 }
9959 }
61865e30 9960 else
32ec8896
NC
9961 {
9962 printf (_(" [unsupported opcode]"));
015dc7e1 9963 res = false;
32ec8896
NC
9964 }
9965
0b6ae522
DJ
9966 printf ("\n");
9967 }
32ec8896
NC
9968
9969 return res;
fa197c1c
PB
9970}
9971
015dc7e1 9972static bool
dda8d76d
NC
9973decode_tic6x_unwind_bytecode (Filedata * filedata,
9974 struct arm_unw_aux_info * aux,
948f632f
DA
9975 unsigned int word,
9976 unsigned int remaining,
9977 unsigned int more_words,
9978 bfd_vma data_offset,
9979 Elf_Internal_Shdr * data_sec,
9980 struct arm_section * data_arm_sec)
fa197c1c
PB
9981{
9982 struct absaddr addr;
9983
9984 /* Decode the unwinding instructions. */
9985 while (1)
9986 {
9987 unsigned int op, op2;
9988
9989 ADVANCE;
9990 if (remaining == 0)
9991 break;
9992 remaining--;
9993 op = word >> 24;
9994 word <<= 8;
9995
9cf03b7e 9996 printf (" 0x%02x ", op);
fa197c1c
PB
9997
9998 if ((op & 0xc0) == 0x00)
9999 {
10000 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10001 printf (" sp = sp + %d", offset);
fa197c1c
PB
10002 }
10003 else if ((op & 0xc0) == 0x80)
10004 {
10005 GET_OP (op2);
10006 if (op == 0x80 && op2 == 0)
10007 printf (_("Refuse to unwind"));
10008 else
10009 {
10010 unsigned int mask = ((op & 0x1f) << 8) | op2;
10011 if (op & 0x20)
10012 printf ("pop compact {");
10013 else
10014 printf ("pop {");
10015
10016 decode_tic6x_unwind_regmask (mask);
10017 printf("}");
10018 }
10019 }
10020 else if ((op & 0xf0) == 0xc0)
10021 {
10022 unsigned int reg;
10023 unsigned int nregs;
10024 unsigned int i;
10025 const char *name;
a734115a
NC
10026 struct
10027 {
32ec8896
NC
10028 unsigned int offset;
10029 unsigned int reg;
fa197c1c
PB
10030 } regpos[16];
10031
10032 /* Scan entire instruction first so that GET_OP output is not
10033 interleaved with disassembly. */
10034 nregs = 0;
10035 for (i = 0; nregs < (op & 0xf); i++)
10036 {
10037 GET_OP (op2);
10038 reg = op2 >> 4;
10039 if (reg != 0xf)
10040 {
10041 regpos[nregs].offset = i * 2;
10042 regpos[nregs].reg = reg;
10043 nregs++;
10044 }
10045
10046 reg = op2 & 0xf;
10047 if (reg != 0xf)
10048 {
10049 regpos[nregs].offset = i * 2 + 1;
10050 regpos[nregs].reg = reg;
10051 nregs++;
10052 }
10053 }
10054
10055 printf (_("pop frame {"));
18344509 10056 if (nregs == 0)
fa197c1c 10057 {
18344509
NC
10058 printf (_("*corrupt* - no registers specified"));
10059 }
10060 else
10061 {
10062 reg = nregs - 1;
10063 for (i = i * 2; i > 0; i--)
fa197c1c 10064 {
18344509
NC
10065 if (regpos[reg].offset == i - 1)
10066 {
10067 name = tic6x_unwind_regnames[regpos[reg].reg];
10068 if (reg > 0)
10069 reg--;
10070 }
10071 else
10072 name = _("[pad]");
fa197c1c 10073
18344509
NC
10074 fputs (name, stdout);
10075 if (i > 1)
10076 printf (", ");
10077 }
fa197c1c
PB
10078 }
10079
10080 printf ("}");
10081 }
10082 else if (op == 0xd0)
10083 printf (" MOV FP, SP");
10084 else if (op == 0xd1)
10085 printf (" __c6xabi_pop_rts");
10086 else if (op == 0xd2)
10087 {
10088 unsigned char buf[9];
10089 unsigned int i, len;
10090 unsigned long offset;
a734115a 10091
fa197c1c
PB
10092 for (i = 0; i < sizeof (buf); i++)
10093 {
10094 GET_OP (buf[i]);
10095 if ((buf[i] & 0x80) == 0)
10096 break;
10097 }
0eff7165
NC
10098 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10099 if (i == sizeof (buf))
10100 {
0eff7165 10101 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10102 return false;
0eff7165 10103 }
948f632f 10104
015dc7e1 10105 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10106 assert (len == i + 1);
10107 offset = offset * 8 + 0x408;
10108 printf (_("sp = sp + %ld"), offset);
10109 }
10110 else if ((op & 0xf0) == 0xe0)
10111 {
10112 if ((op & 0x0f) == 7)
10113 printf (" RETURN");
10114 else
10115 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10116 }
10117 else
10118 {
10119 printf (_(" [unsupported opcode]"));
10120 }
10121 putchar ('\n');
10122 }
32ec8896 10123
015dc7e1 10124 return true;
fa197c1c
PB
10125}
10126
10127static bfd_vma
dda8d76d 10128arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
10129{
10130 bfd_vma offset;
10131
10132 offset = word & 0x7fffffff;
10133 if (offset & 0x40000000)
10134 offset |= ~ (bfd_vma) 0x7fffffff;
10135
dda8d76d 10136 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10137 offset <<= 1;
10138
10139 return offset + where;
10140}
10141
015dc7e1 10142static bool
dda8d76d
NC
10143decode_arm_unwind (Filedata * filedata,
10144 struct arm_unw_aux_info * aux,
1b31d05e
NC
10145 unsigned int word,
10146 unsigned int remaining,
10147 bfd_vma data_offset,
10148 Elf_Internal_Shdr * data_sec,
10149 struct arm_section * data_arm_sec)
fa197c1c
PB
10150{
10151 int per_index;
10152 unsigned int more_words = 0;
37e14bc3 10153 struct absaddr addr;
1b31d05e 10154 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 10155 bool res = true;
fa197c1c
PB
10156
10157 if (remaining == 0)
10158 {
1b31d05e
NC
10159 /* Fetch the first word.
10160 Note - when decoding an object file the address extracted
10161 here will always be 0. So we also pass in the sym_name
10162 parameter so that we can find the symbol associated with
10163 the personality routine. */
dda8d76d 10164 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10165 & word, & addr, & sym_name))
015dc7e1 10166 return false;
1b31d05e 10167
fa197c1c
PB
10168 remaining = 4;
10169 }
c93dbb25
CZ
10170 else
10171 {
10172 addr.section = SHN_UNDEF;
10173 addr.offset = 0;
10174 }
fa197c1c
PB
10175
10176 if ((word & 0x80000000) == 0)
10177 {
10178 /* Expand prel31 for personality routine. */
10179 bfd_vma fn;
10180 const char *procname;
10181
dda8d76d 10182 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10183 printf (_(" Personality routine: "));
1b31d05e
NC
10184 if (fn == 0
10185 && addr.section == SHN_UNDEF && addr.offset == 0
10186 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10187 {
10188 procname = aux->strtab + sym_name;
10189 print_vma (fn, PREFIX_HEX);
10190 if (procname)
10191 {
10192 fputs (" <", stdout);
10193 fputs (procname, stdout);
10194 fputc ('>', stdout);
10195 }
10196 }
10197 else
dda8d76d 10198 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10199 fputc ('\n', stdout);
10200
10201 /* The GCC personality routines use the standard compact
10202 encoding, starting with one byte giving the number of
10203 words. */
10204 if (procname != NULL
24d127aa
ML
10205 && (startswith (procname, "__gcc_personality_v0")
10206 || startswith (procname, "__gxx_personality_v0")
10207 || startswith (procname, "__gcj_personality_v0")
10208 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10209 {
10210 remaining = 0;
10211 more_words = 1;
10212 ADVANCE;
10213 if (!remaining)
10214 {
10215 printf (_(" [Truncated data]\n"));
015dc7e1 10216 return false;
fa197c1c
PB
10217 }
10218 more_words = word >> 24;
10219 word <<= 8;
10220 remaining--;
10221 per_index = -1;
10222 }
10223 else
015dc7e1 10224 return true;
fa197c1c
PB
10225 }
10226 else
10227 {
1b31d05e 10228 /* ARM EHABI Section 6.3:
0b4362b0 10229
1b31d05e 10230 An exception-handling table entry for the compact model looks like:
0b4362b0 10231
1b31d05e
NC
10232 31 30-28 27-24 23-0
10233 -- ----- ----- ----
10234 1 0 index Data for personalityRoutine[index] */
10235
dda8d76d 10236 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10237 && (word & 0x70000000))
32ec8896
NC
10238 {
10239 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10240 res = false;
32ec8896 10241 }
1b31d05e 10242
fa197c1c 10243 per_index = (word >> 24) & 0x7f;
1b31d05e 10244 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10245 if (per_index == 0)
10246 {
10247 more_words = 0;
10248 word <<= 8;
10249 remaining--;
10250 }
10251 else if (per_index < 3)
10252 {
10253 more_words = (word >> 16) & 0xff;
10254 word <<= 16;
10255 remaining -= 2;
10256 }
10257 }
10258
dda8d76d 10259 switch (filedata->file_header.e_machine)
fa197c1c
PB
10260 {
10261 case EM_ARM:
10262 if (per_index < 3)
10263 {
dda8d76d 10264 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10265 data_offset, data_sec, data_arm_sec))
015dc7e1 10266 res = false;
fa197c1c
PB
10267 }
10268 else
1b31d05e
NC
10269 {
10270 warn (_("Unknown ARM compact model index encountered\n"));
10271 printf (_(" [reserved]\n"));
015dc7e1 10272 res = false;
1b31d05e 10273 }
fa197c1c
PB
10274 break;
10275
10276 case EM_TI_C6000:
10277 if (per_index < 3)
10278 {
dda8d76d 10279 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10280 data_offset, data_sec, data_arm_sec))
015dc7e1 10281 res = false;
fa197c1c
PB
10282 }
10283 else if (per_index < 5)
10284 {
10285 if (((word >> 17) & 0x7f) == 0x7f)
10286 printf (_(" Restore stack from frame pointer\n"));
10287 else
10288 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10289 printf (_(" Registers restored: "));
10290 if (per_index == 4)
10291 printf (" (compact) ");
10292 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10293 putchar ('\n');
10294 printf (_(" Return register: %s\n"),
10295 tic6x_unwind_regnames[word & 0xf]);
10296 }
10297 else
1b31d05e 10298 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10299 break;
10300
10301 default:
74e1a04b 10302 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10303 filedata->file_header.e_machine);
015dc7e1 10304 res = false;
fa197c1c 10305 }
0b6ae522
DJ
10306
10307 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10308
10309 return res;
0b6ae522
DJ
10310}
10311
015dc7e1 10312static bool
dda8d76d
NC
10313dump_arm_unwind (Filedata * filedata,
10314 struct arm_unw_aux_info * aux,
10315 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10316{
10317 struct arm_section exidx_arm_sec, extab_arm_sec;
10318 unsigned int i, exidx_len;
948f632f 10319 unsigned long j, nfuns;
015dc7e1 10320 bool res = true;
0b6ae522
DJ
10321
10322 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10323 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10324 exidx_len = exidx_sec->sh_size / 8;
10325
948f632f
DA
10326 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10327 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10328 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10329 aux->funtab[nfuns++] = aux->symtab[j];
10330 aux->nfuns = nfuns;
10331 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10332
0b6ae522
DJ
10333 for (i = 0; i < exidx_len; i++)
10334 {
10335 unsigned int exidx_fn, exidx_entry;
10336 struct absaddr fn_addr, entry_addr;
10337 bfd_vma fn;
10338
10339 fputc ('\n', stdout);
10340
dda8d76d 10341 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10342 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10343 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10344 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10345 {
948f632f 10346 free (aux->funtab);
1b31d05e
NC
10347 arm_free_section (& exidx_arm_sec);
10348 arm_free_section (& extab_arm_sec);
015dc7e1 10349 return false;
0b6ae522
DJ
10350 }
10351
83c257ca
NC
10352 /* ARM EHABI, Section 5:
10353 An index table entry consists of 2 words.
10354 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10355 if (exidx_fn & 0x80000000)
32ec8896
NC
10356 {
10357 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10358 res = false;
32ec8896 10359 }
83c257ca 10360
dda8d76d 10361 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10362
dda8d76d 10363 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10364 fputs (": ", stdout);
10365
10366 if (exidx_entry == 1)
10367 {
10368 print_vma (exidx_entry, PREFIX_HEX);
10369 fputs (" [cantunwind]\n", stdout);
10370 }
10371 else if (exidx_entry & 0x80000000)
10372 {
10373 print_vma (exidx_entry, PREFIX_HEX);
10374 fputc ('\n', stdout);
dda8d76d 10375 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10376 }
10377 else
10378 {
8f73510c 10379 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10380 Elf_Internal_Shdr *table_sec;
10381
10382 fputs ("@", stdout);
dda8d76d 10383 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10384 print_vma (table, PREFIX_HEX);
10385 printf ("\n");
10386
10387 /* Locate the matching .ARM.extab. */
10388 if (entry_addr.section != SHN_UNDEF
dda8d76d 10389 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10390 {
dda8d76d 10391 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10392 table_offset = entry_addr.offset;
1a915552
NC
10393 /* PR 18879 */
10394 if (table_offset > table_sec->sh_size
10395 || ((bfd_signed_vma) table_offset) < 0)
10396 {
10397 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10398 (unsigned long) table_offset,
dda8d76d 10399 printable_section_name (filedata, table_sec));
015dc7e1 10400 res = false;
1a915552
NC
10401 continue;
10402 }
0b6ae522
DJ
10403 }
10404 else
10405 {
dda8d76d 10406 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10407 if (table_sec != NULL)
10408 table_offset = table - table_sec->sh_addr;
10409 }
32ec8896 10410
0b6ae522
DJ
10411 if (table_sec == NULL)
10412 {
10413 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10414 (unsigned long) table);
015dc7e1 10415 res = false;
0b6ae522
DJ
10416 continue;
10417 }
32ec8896 10418
dda8d76d 10419 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10420 &extab_arm_sec))
015dc7e1 10421 res = false;
0b6ae522
DJ
10422 }
10423 }
10424
10425 printf ("\n");
10426
948f632f 10427 free (aux->funtab);
0b6ae522
DJ
10428 arm_free_section (&exidx_arm_sec);
10429 arm_free_section (&extab_arm_sec);
32ec8896
NC
10430
10431 return res;
0b6ae522
DJ
10432}
10433
fa197c1c 10434/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10435
015dc7e1 10436static bool
dda8d76d 10437arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10438{
10439 struct arm_unw_aux_info aux;
10440 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10441 Elf_Internal_Shdr *sec;
10442 unsigned long i;
fa197c1c 10443 unsigned int sec_type;
015dc7e1 10444 bool res = true;
0b6ae522 10445
dda8d76d 10446 switch (filedata->file_header.e_machine)
fa197c1c
PB
10447 {
10448 case EM_ARM:
10449 sec_type = SHT_ARM_EXIDX;
10450 break;
10451
10452 case EM_TI_C6000:
10453 sec_type = SHT_C6000_UNWIND;
10454 break;
10455
0b4362b0 10456 default:
74e1a04b 10457 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10458 filedata->file_header.e_machine);
015dc7e1 10459 return false;
fa197c1c
PB
10460 }
10461
dda8d76d 10462 if (filedata->string_table == NULL)
015dc7e1 10463 return false;
1b31d05e
NC
10464
10465 memset (& aux, 0, sizeof (aux));
dda8d76d 10466 aux.filedata = filedata;
0b6ae522 10467
dda8d76d 10468 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10469 {
28d13567 10470 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10471 {
28d13567 10472 if (aux.symtab)
74e1a04b 10473 {
28d13567
AM
10474 error (_("Multiple symbol tables encountered\n"));
10475 free (aux.symtab);
10476 aux.symtab = NULL;
74e1a04b 10477 free (aux.strtab);
28d13567 10478 aux.strtab = NULL;
74e1a04b 10479 }
28d13567
AM
10480 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10481 &aux.strtab, &aux.strtab_size))
015dc7e1 10482 return false;
0b6ae522 10483 }
fa197c1c 10484 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10485 unwsec = sec;
10486 }
10487
1b31d05e 10488 if (unwsec == NULL)
0b6ae522 10489 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10490 else
dda8d76d 10491 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10492 {
10493 if (sec->sh_type == sec_type)
10494 {
d3a49aa8
AM
10495 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10496 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10497 "contains %lu entry:\n",
10498 "\nUnwind section '%s' at offset 0x%lx "
10499 "contains %lu entries:\n",
10500 num_unwind),
dda8d76d 10501 printable_section_name (filedata, sec),
1b31d05e 10502 (unsigned long) sec->sh_offset,
d3a49aa8 10503 num_unwind);
0b6ae522 10504
dda8d76d 10505 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10506 res = false;
1b31d05e
NC
10507 }
10508 }
0b6ae522 10509
9db70fc3
AM
10510 free (aux.symtab);
10511 free ((char *) aux.strtab);
32ec8896
NC
10512
10513 return res;
0b6ae522
DJ
10514}
10515
3ecc00ec
NC
10516static bool
10517no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10518{
10519 printf (_("No processor specific unwind information to decode\n"));
10520 return true;
10521}
10522
015dc7e1 10523static bool
dda8d76d 10524process_unwind (Filedata * filedata)
57346661 10525{
2cf0635d
NC
10526 struct unwind_handler
10527 {
32ec8896 10528 unsigned int machtype;
015dc7e1 10529 bool (* handler)(Filedata *);
2cf0635d
NC
10530 } handlers[] =
10531 {
0b6ae522 10532 { EM_ARM, arm_process_unwind },
57346661
AM
10533 { EM_IA_64, ia64_process_unwind },
10534 { EM_PARISC, hppa_process_unwind },
fa197c1c 10535 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10536 { EM_386, no_processor_specific_unwind },
10537 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10538 { 0, NULL }
57346661
AM
10539 };
10540 int i;
10541
10542 if (!do_unwind)
015dc7e1 10543 return true;
57346661
AM
10544
10545 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10546 if (filedata->file_header.e_machine == handlers[i].machtype)
10547 return handlers[i].handler (filedata);
57346661 10548
1b31d05e 10549 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10550 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10551 return true;
57346661
AM
10552}
10553
37c18eed
SD
10554static void
10555dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10556{
10557 switch (entry->d_tag)
10558 {
10559 case DT_AARCH64_BTI_PLT:
1dbade74 10560 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10561 break;
10562 default:
10563 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10564 break;
10565 }
10566 putchar ('\n');
10567}
10568
252b5132 10569static void
978c4450 10570dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10571{
10572 switch (entry->d_tag)
10573 {
10574 case DT_MIPS_FLAGS:
10575 if (entry->d_un.d_val == 0)
4b68bca3 10576 printf (_("NONE"));
252b5132
RH
10577 else
10578 {
10579 static const char * opts[] =
10580 {
10581 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10582 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10583 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10584 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10585 "RLD_ORDER_SAFE"
10586 };
10587 unsigned int cnt;
015dc7e1 10588 bool first = true;
2b692964 10589
60bca95a 10590 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10591 if (entry->d_un.d_val & (1 << cnt))
10592 {
10593 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10594 first = false;
252b5132 10595 }
252b5132
RH
10596 }
10597 break;
103f02d3 10598
252b5132 10599 case DT_MIPS_IVERSION:
84714f86 10600 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10601 printf (_("Interface Version: %s"),
84714f86 10602 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10603 else
76ca31c0
NC
10604 {
10605 char buf[40];
10606 sprintf_vma (buf, entry->d_un.d_ptr);
10607 /* Note: coded this way so that there is a single string for translation. */
10608 printf (_("<corrupt: %s>"), buf);
10609 }
252b5132 10610 break;
103f02d3 10611
252b5132
RH
10612 case DT_MIPS_TIME_STAMP:
10613 {
d5b07ef4 10614 char timebuf[128];
2cf0635d 10615 struct tm * tmp;
91d6fa6a 10616 time_t atime = entry->d_un.d_val;
82b1b41b 10617
91d6fa6a 10618 tmp = gmtime (&atime);
82b1b41b
NC
10619 /* PR 17531: file: 6accc532. */
10620 if (tmp == NULL)
10621 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10622 else
10623 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10624 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10625 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10626 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10627 }
10628 break;
103f02d3 10629
252b5132
RH
10630 case DT_MIPS_RLD_VERSION:
10631 case DT_MIPS_LOCAL_GOTNO:
10632 case DT_MIPS_CONFLICTNO:
10633 case DT_MIPS_LIBLISTNO:
10634 case DT_MIPS_SYMTABNO:
10635 case DT_MIPS_UNREFEXTNO:
10636 case DT_MIPS_HIPAGENO:
10637 case DT_MIPS_DELTA_CLASS_NO:
10638 case DT_MIPS_DELTA_INSTANCE_NO:
10639 case DT_MIPS_DELTA_RELOC_NO:
10640 case DT_MIPS_DELTA_SYM_NO:
10641 case DT_MIPS_DELTA_CLASSSYM_NO:
10642 case DT_MIPS_COMPACT_SIZE:
c69075ac 10643 print_vma (entry->d_un.d_val, DEC);
252b5132 10644 break;
103f02d3 10645
f16a9783 10646 case DT_MIPS_XHASH:
978c4450
AM
10647 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10648 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10649 /* Falls through. */
10650
103f02d3 10651 default:
4b68bca3 10652 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10653 }
4b68bca3 10654 putchar ('\n');
103f02d3
UD
10655}
10656
103f02d3 10657static void
2cf0635d 10658dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10659{
10660 switch (entry->d_tag)
10661 {
10662 case DT_HP_DLD_FLAGS:
10663 {
10664 static struct
10665 {
10666 long int bit;
2cf0635d 10667 const char * str;
5e220199
NC
10668 }
10669 flags[] =
10670 {
10671 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10672 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10673 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10674 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10675 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10676 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10677 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10678 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10679 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10680 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10681 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10682 { DT_HP_GST, "HP_GST" },
10683 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10684 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10685 { DT_HP_NODELETE, "HP_NODELETE" },
10686 { DT_HP_GROUP, "HP_GROUP" },
10687 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10688 };
015dc7e1 10689 bool first = true;
5e220199 10690 size_t cnt;
f7a99963 10691 bfd_vma val = entry->d_un.d_val;
103f02d3 10692
60bca95a 10693 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10694 if (val & flags[cnt].bit)
30800947
NC
10695 {
10696 if (! first)
10697 putchar (' ');
10698 fputs (flags[cnt].str, stdout);
015dc7e1 10699 first = false;
30800947
NC
10700 val ^= flags[cnt].bit;
10701 }
76da6bbe 10702
103f02d3 10703 if (val != 0 || first)
f7a99963
NC
10704 {
10705 if (! first)
10706 putchar (' ');
10707 print_vma (val, HEX);
10708 }
103f02d3
UD
10709 }
10710 break;
76da6bbe 10711
252b5132 10712 default:
f7a99963
NC
10713 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10714 break;
252b5132 10715 }
35b1837e 10716 putchar ('\n');
252b5132
RH
10717}
10718
28f997cf
TG
10719#ifdef BFD64
10720
10721/* VMS vs Unix time offset and factor. */
10722
10723#define VMS_EPOCH_OFFSET 35067168000000000LL
10724#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10725#ifndef INT64_MIN
10726#define INT64_MIN (-9223372036854775807LL - 1)
10727#endif
28f997cf
TG
10728
10729/* Display a VMS time in a human readable format. */
10730
10731static void
10732print_vms_time (bfd_int64_t vmstime)
10733{
dccc31de 10734 struct tm *tm = NULL;
28f997cf
TG
10735 time_t unxtime;
10736
dccc31de
AM
10737 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10738 {
10739 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10740 unxtime = vmstime;
10741 if (unxtime == vmstime)
10742 tm = gmtime (&unxtime);
10743 }
10744 if (tm != NULL)
10745 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10746 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10747 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10748}
10749#endif /* BFD64 */
10750
ecc51f48 10751static void
2cf0635d 10752dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10753{
10754 switch (entry->d_tag)
10755 {
0de14b54 10756 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10757 /* First 3 slots reserved. */
ecc51f48
NC
10758 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10759 printf (" -- ");
10760 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10761 break;
10762
28f997cf
TG
10763 case DT_IA_64_VMS_LINKTIME:
10764#ifdef BFD64
10765 print_vms_time (entry->d_un.d_val);
10766#endif
10767 break;
10768
10769 case DT_IA_64_VMS_LNKFLAGS:
10770 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10771 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10772 printf (" CALL_DEBUG");
10773 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10774 printf (" NOP0BUFS");
10775 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10776 printf (" P0IMAGE");
10777 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10778 printf (" MKTHREADS");
10779 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10780 printf (" UPCALLS");
10781 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10782 printf (" IMGSTA");
10783 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10784 printf (" INITIALIZE");
10785 if (entry->d_un.d_val & VMS_LF_MAIN)
10786 printf (" MAIN");
10787 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10788 printf (" EXE_INIT");
10789 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10790 printf (" TBK_IN_IMG");
10791 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10792 printf (" DBG_IN_IMG");
10793 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10794 printf (" TBK_IN_DSF");
10795 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10796 printf (" DBG_IN_DSF");
10797 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10798 printf (" SIGNATURES");
10799 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10800 printf (" REL_SEG_OFF");
10801 break;
10802
bdf4d63a
JJ
10803 default:
10804 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10805 break;
ecc51f48 10806 }
bdf4d63a 10807 putchar ('\n');
ecc51f48
NC
10808}
10809
015dc7e1 10810static bool
dda8d76d 10811get_32bit_dynamic_section (Filedata * filedata)
252b5132 10812{
2cf0635d
NC
10813 Elf32_External_Dyn * edyn;
10814 Elf32_External_Dyn * ext;
10815 Elf_Internal_Dyn * entry;
103f02d3 10816
978c4450
AM
10817 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10818 filedata->dynamic_addr, 1,
10819 filedata->dynamic_size,
10820 _("dynamic section"));
a6e9f9df 10821 if (!edyn)
015dc7e1 10822 return false;
103f02d3 10823
071436c6
NC
10824 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10825 might not have the luxury of section headers. Look for the DT_NULL
10826 terminator to determine the number of entries. */
978c4450
AM
10827 for (ext = edyn, filedata->dynamic_nent = 0;
10828 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10829 ext++)
10830 {
978c4450 10831 filedata->dynamic_nent++;
ba2685cc
AM
10832 if (BYTE_GET (ext->d_tag) == DT_NULL)
10833 break;
10834 }
252b5132 10835
978c4450
AM
10836 filedata->dynamic_section
10837 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10838 if (filedata->dynamic_section == NULL)
252b5132 10839 {
8b73c356 10840 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10841 (unsigned long) filedata->dynamic_nent);
9ea033b2 10842 free (edyn);
015dc7e1 10843 return false;
9ea033b2 10844 }
252b5132 10845
978c4450
AM
10846 for (ext = edyn, entry = filedata->dynamic_section;
10847 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10848 ext++, entry++)
9ea033b2 10849 {
fb514b26
AM
10850 entry->d_tag = BYTE_GET (ext->d_tag);
10851 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10852 }
10853
9ea033b2
NC
10854 free (edyn);
10855
015dc7e1 10856 return true;
9ea033b2
NC
10857}
10858
015dc7e1 10859static bool
dda8d76d 10860get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10861{
2cf0635d
NC
10862 Elf64_External_Dyn * edyn;
10863 Elf64_External_Dyn * ext;
10864 Elf_Internal_Dyn * entry;
103f02d3 10865
071436c6 10866 /* Read in the data. */
978c4450
AM
10867 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10868 filedata->dynamic_addr, 1,
10869 filedata->dynamic_size,
10870 _("dynamic section"));
a6e9f9df 10871 if (!edyn)
015dc7e1 10872 return false;
103f02d3 10873
071436c6
NC
10874 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10875 might not have the luxury of section headers. Look for the DT_NULL
10876 terminator to determine the number of entries. */
978c4450 10877 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10878 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10879 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10880 ext++)
10881 {
978c4450 10882 filedata->dynamic_nent++;
66543521 10883 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10884 break;
10885 }
252b5132 10886
978c4450
AM
10887 filedata->dynamic_section
10888 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10889 if (filedata->dynamic_section == NULL)
252b5132 10890 {
8b73c356 10891 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10892 (unsigned long) filedata->dynamic_nent);
252b5132 10893 free (edyn);
015dc7e1 10894 return false;
252b5132
RH
10895 }
10896
071436c6 10897 /* Convert from external to internal formats. */
978c4450
AM
10898 for (ext = edyn, entry = filedata->dynamic_section;
10899 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10900 ext++, entry++)
252b5132 10901 {
66543521
AM
10902 entry->d_tag = BYTE_GET (ext->d_tag);
10903 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10904 }
10905
10906 free (edyn);
10907
015dc7e1 10908 return true;
9ea033b2
NC
10909}
10910
4de91c10
AM
10911static bool
10912get_dynamic_section (Filedata *filedata)
10913{
10914 if (filedata->dynamic_section)
10915 return true;
10916
10917 if (is_32bit_elf)
10918 return get_32bit_dynamic_section (filedata);
10919 else
10920 return get_64bit_dynamic_section (filedata);
10921}
10922
e9e44622
JJ
10923static void
10924print_dynamic_flags (bfd_vma flags)
d1133906 10925{
015dc7e1 10926 bool first = true;
13ae64f3 10927
d1133906
NC
10928 while (flags)
10929 {
10930 bfd_vma flag;
10931
10932 flag = flags & - flags;
10933 flags &= ~ flag;
10934
e9e44622 10935 if (first)
015dc7e1 10936 first = false;
e9e44622
JJ
10937 else
10938 putc (' ', stdout);
13ae64f3 10939
d1133906
NC
10940 switch (flag)
10941 {
e9e44622
JJ
10942 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10943 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10944 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10945 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10946 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10947 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10948 }
10949 }
e9e44622 10950 puts ("");
d1133906
NC
10951}
10952
10ca4b04
L
10953static bfd_vma *
10954get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10955{
10956 unsigned char * e_data;
10957 bfd_vma * i_data;
10958
10959 /* If the size_t type is smaller than the bfd_size_type, eg because
10960 you are building a 32-bit tool on a 64-bit host, then make sure
10961 that when (number) is cast to (size_t) no information is lost. */
10962 if (sizeof (size_t) < sizeof (bfd_size_type)
10963 && (bfd_size_type) ((size_t) number) != number)
10964 {
10965 error (_("Size truncation prevents reading %s elements of size %u\n"),
10966 bfd_vmatoa ("u", number), ent_size);
10967 return NULL;
10968 }
10969
10970 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10971 attempting to allocate memory when the read is bound to fail. */
10972 if (ent_size * number > filedata->file_size)
10973 {
10974 error (_("Invalid number of dynamic entries: %s\n"),
10975 bfd_vmatoa ("u", number));
10976 return NULL;
10977 }
10978
10979 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10980 if (e_data == NULL)
10981 {
10982 error (_("Out of memory reading %s dynamic entries\n"),
10983 bfd_vmatoa ("u", number));
10984 return NULL;
10985 }
10986
10987 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10988 {
10989 error (_("Unable to read in %s bytes of dynamic data\n"),
10990 bfd_vmatoa ("u", number * ent_size));
10991 free (e_data);
10992 return NULL;
10993 }
10994
10995 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10996 if (i_data == NULL)
10997 {
10998 error (_("Out of memory allocating space for %s dynamic entries\n"),
10999 bfd_vmatoa ("u", number));
11000 free (e_data);
11001 return NULL;
11002 }
11003
11004 while (number--)
11005 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11006
11007 free (e_data);
11008
11009 return i_data;
11010}
11011
11012static unsigned long
11013get_num_dynamic_syms (Filedata * filedata)
11014{
11015 unsigned long num_of_syms = 0;
11016
11017 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11018 return num_of_syms;
11019
978c4450 11020 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11021 {
11022 unsigned char nb[8];
11023 unsigned char nc[8];
11024 unsigned int hash_ent_size = 4;
11025
11026 if ((filedata->file_header.e_machine == EM_ALPHA
11027 || filedata->file_header.e_machine == EM_S390
11028 || filedata->file_header.e_machine == EM_S390_OLD)
11029 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11030 hash_ent_size = 8;
11031
11032 if (fseek (filedata->handle,
978c4450
AM
11033 (filedata->archive_file_offset
11034 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11035 sizeof nb + sizeof nc)),
11036 SEEK_SET))
11037 {
11038 error (_("Unable to seek to start of dynamic information\n"));
11039 goto no_hash;
11040 }
11041
11042 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11043 {
11044 error (_("Failed to read in number of buckets\n"));
11045 goto no_hash;
11046 }
11047
11048 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11049 {
11050 error (_("Failed to read in number of chains\n"));
11051 goto no_hash;
11052 }
11053
978c4450
AM
11054 filedata->nbuckets = byte_get (nb, hash_ent_size);
11055 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11056
2482f306
AM
11057 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11058 {
11059 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11060 hash_ent_size);
11061 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11062 hash_ent_size);
001890e1 11063
2482f306
AM
11064 if (filedata->buckets != NULL && filedata->chains != NULL)
11065 num_of_syms = filedata->nchains;
11066 }
ceb9bf11 11067 no_hash:
10ca4b04
L
11068 if (num_of_syms == 0)
11069 {
9db70fc3
AM
11070 free (filedata->buckets);
11071 filedata->buckets = NULL;
11072 free (filedata->chains);
11073 filedata->chains = NULL;
978c4450 11074 filedata->nbuckets = 0;
10ca4b04
L
11075 }
11076 }
11077
978c4450 11078 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11079 {
11080 unsigned char nb[16];
11081 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11082 bfd_vma buckets_vma;
11083 unsigned long hn;
10ca4b04
L
11084
11085 if (fseek (filedata->handle,
978c4450
AM
11086 (filedata->archive_file_offset
11087 + offset_from_vma (filedata,
11088 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11089 sizeof nb)),
11090 SEEK_SET))
11091 {
11092 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11093 goto no_gnu_hash;
11094 }
11095
11096 if (fread (nb, 16, 1, filedata->handle) != 1)
11097 {
11098 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11099 goto no_gnu_hash;
11100 }
11101
978c4450
AM
11102 filedata->ngnubuckets = byte_get (nb, 4);
11103 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11104 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11105 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11106 if (is_32bit_elf)
11107 buckets_vma += bitmaskwords * 4;
11108 else
11109 buckets_vma += bitmaskwords * 8;
11110
11111 if (fseek (filedata->handle,
978c4450 11112 (filedata->archive_file_offset
10ca4b04
L
11113 + offset_from_vma (filedata, buckets_vma, 4)),
11114 SEEK_SET))
11115 {
11116 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11117 goto no_gnu_hash;
11118 }
11119
978c4450
AM
11120 filedata->gnubuckets
11121 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11122
978c4450 11123 if (filedata->gnubuckets == NULL)
90837ea7 11124 goto no_gnu_hash;
10ca4b04 11125
978c4450
AM
11126 for (i = 0; i < filedata->ngnubuckets; i++)
11127 if (filedata->gnubuckets[i] != 0)
10ca4b04 11128 {
978c4450 11129 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11130 goto no_gnu_hash;
10ca4b04 11131
978c4450
AM
11132 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11133 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11134 }
11135
11136 if (maxchain == 0xffffffff)
90837ea7 11137 goto no_gnu_hash;
10ca4b04 11138
978c4450 11139 maxchain -= filedata->gnusymidx;
10ca4b04
L
11140
11141 if (fseek (filedata->handle,
978c4450
AM
11142 (filedata->archive_file_offset
11143 + offset_from_vma (filedata,
11144 buckets_vma + 4 * (filedata->ngnubuckets
11145 + maxchain),
11146 4)),
10ca4b04
L
11147 SEEK_SET))
11148 {
11149 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11150 goto no_gnu_hash;
11151 }
11152
11153 do
11154 {
11155 if (fread (nb, 4, 1, filedata->handle) != 1)
11156 {
11157 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11158 goto no_gnu_hash;
11159 }
11160
11161 if (maxchain + 1 == 0)
90837ea7 11162 goto no_gnu_hash;
10ca4b04
L
11163
11164 ++maxchain;
11165 }
11166 while ((byte_get (nb, 4) & 1) == 0);
11167
11168 if (fseek (filedata->handle,
978c4450
AM
11169 (filedata->archive_file_offset
11170 + offset_from_vma (filedata, (buckets_vma
11171 + 4 * filedata->ngnubuckets),
11172 4)),
10ca4b04
L
11173 SEEK_SET))
11174 {
11175 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11176 goto no_gnu_hash;
11177 }
11178
978c4450
AM
11179 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11180 filedata->ngnuchains = maxchain;
10ca4b04 11181
978c4450 11182 if (filedata->gnuchains == NULL)
90837ea7 11183 goto no_gnu_hash;
10ca4b04 11184
978c4450 11185 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11186 {
11187 if (fseek (filedata->handle,
978c4450 11188 (filedata->archive_file_offset
10ca4b04 11189 + offset_from_vma (filedata, (buckets_vma
978c4450 11190 + 4 * (filedata->ngnubuckets
10ca4b04
L
11191 + maxchain)), 4)),
11192 SEEK_SET))
11193 {
11194 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11195 goto no_gnu_hash;
11196 }
11197
978c4450 11198 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11199 if (filedata->mipsxlat == NULL)
11200 goto no_gnu_hash;
10ca4b04
L
11201 }
11202
978c4450
AM
11203 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11204 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11205 {
978c4450
AM
11206 bfd_vma si = filedata->gnubuckets[hn];
11207 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11208
11209 do
11210 {
978c4450 11211 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11212 {
c31ab5a0
AM
11213 if (off < filedata->ngnuchains
11214 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11215 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11216 }
11217 else
11218 {
11219 if (si >= num_of_syms)
11220 num_of_syms = si + 1;
11221 }
11222 si++;
11223 }
978c4450
AM
11224 while (off < filedata->ngnuchains
11225 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11226 }
11227
90837ea7 11228 if (num_of_syms == 0)
10ca4b04 11229 {
90837ea7 11230 no_gnu_hash:
9db70fc3
AM
11231 free (filedata->mipsxlat);
11232 filedata->mipsxlat = NULL;
11233 free (filedata->gnuchains);
11234 filedata->gnuchains = NULL;
11235 free (filedata->gnubuckets);
11236 filedata->gnubuckets = NULL;
978c4450
AM
11237 filedata->ngnubuckets = 0;
11238 filedata->ngnuchains = 0;
10ca4b04
L
11239 }
11240 }
11241
11242 return num_of_syms;
11243}
11244
b2d38a17
NC
11245/* Parse and display the contents of the dynamic section. */
11246
015dc7e1 11247static bool
dda8d76d 11248process_dynamic_section (Filedata * filedata)
9ea033b2 11249{
2cf0635d 11250 Elf_Internal_Dyn * entry;
9ea033b2 11251
93df3340 11252 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11253 {
11254 if (do_dynamic)
ca0e11aa
NC
11255 {
11256 if (filedata->is_separate)
11257 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11258 filedata->file_name);
11259 else
11260 printf (_("\nThere is no dynamic section in this file.\n"));
11261 }
9ea033b2 11262
015dc7e1 11263 return true;
9ea033b2
NC
11264 }
11265
4de91c10
AM
11266 if (!get_dynamic_section (filedata))
11267 return false;
9ea033b2 11268
252b5132 11269 /* Find the appropriate symbol table. */
978c4450 11270 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11271 {
2482f306
AM
11272 unsigned long num_of_syms;
11273
978c4450
AM
11274 for (entry = filedata->dynamic_section;
11275 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11276 ++entry)
10ca4b04 11277 if (entry->d_tag == DT_SYMTAB)
978c4450 11278 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11279 else if (entry->d_tag == DT_SYMENT)
978c4450 11280 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11281 else if (entry->d_tag == DT_HASH)
978c4450 11282 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11283 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11284 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11285 else if ((filedata->file_header.e_machine == EM_MIPS
11286 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11287 && entry->d_tag == DT_MIPS_XHASH)
11288 {
978c4450
AM
11289 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11290 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11291 }
252b5132 11292
2482f306
AM
11293 num_of_syms = get_num_dynamic_syms (filedata);
11294
11295 if (num_of_syms != 0
11296 && filedata->dynamic_symbols == NULL
11297 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11298 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11299 {
11300 Elf_Internal_Phdr *seg;
2482f306 11301 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11302
2482f306
AM
11303 if (! get_program_headers (filedata))
11304 {
11305 error (_("Cannot interpret virtual addresses "
11306 "without program headers.\n"));
015dc7e1 11307 return false;
2482f306 11308 }
252b5132 11309
2482f306
AM
11310 for (seg = filedata->program_headers;
11311 seg < filedata->program_headers + filedata->file_header.e_phnum;
11312 ++seg)
11313 {
11314 if (seg->p_type != PT_LOAD)
11315 continue;
252b5132 11316
2482f306
AM
11317 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11318 {
11319 /* See PR 21379 for a reproducer. */
11320 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11321 return false;
2482f306 11322 }
252b5132 11323
2482f306
AM
11324 if (vma >= (seg->p_vaddr & -seg->p_align)
11325 && vma < seg->p_vaddr + seg->p_filesz)
11326 {
11327 /* Since we do not know how big the symbol table is,
11328 we default to reading in up to the end of PT_LOAD
11329 segment and processing that. This is overkill, I
11330 know, but it should work. */
11331 Elf_Internal_Shdr section;
11332 section.sh_offset = (vma - seg->p_vaddr
11333 + seg->p_offset);
11334 section.sh_size = (num_of_syms
11335 * filedata->dynamic_info[DT_SYMENT]);
11336 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11337
11338 if (do_checks
11339 && filedata->dynamic_symtab_section != NULL
11340 && ((filedata->dynamic_symtab_section->sh_offset
11341 != section.sh_offset)
11342 || (filedata->dynamic_symtab_section->sh_size
11343 != section.sh_size)
11344 || (filedata->dynamic_symtab_section->sh_entsize
11345 != section.sh_entsize)))
11346 warn (_("\
11347the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11348
2482f306
AM
11349 section.sh_name = filedata->string_table_length;
11350 filedata->dynamic_symbols
4de91c10 11351 = get_elf_symbols (filedata, &section,
2482f306
AM
11352 &filedata->num_dynamic_syms);
11353 if (filedata->dynamic_symbols == NULL
11354 || filedata->num_dynamic_syms != num_of_syms)
11355 {
11356 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11357 return false;
2482f306
AM
11358 }
11359 break;
11360 }
11361 }
11362 }
11363 }
252b5132
RH
11364
11365 /* Similarly find a string table. */
978c4450
AM
11366 if (filedata->dynamic_strings == NULL)
11367 for (entry = filedata->dynamic_section;
11368 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11369 ++entry)
11370 {
11371 if (entry->d_tag == DT_STRTAB)
978c4450 11372 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11373
10ca4b04 11374 if (entry->d_tag == DT_STRSZ)
978c4450 11375 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11376
978c4450
AM
11377 if (filedata->dynamic_info[DT_STRTAB]
11378 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11379 {
11380 unsigned long offset;
978c4450 11381 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11382
11383 offset = offset_from_vma (filedata,
978c4450 11384 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11385 str_tab_len);
8ac10c5b
L
11386 if (do_checks
11387 && filedata->dynamic_strtab_section
11388 && ((filedata->dynamic_strtab_section->sh_offset
11389 != (file_ptr) offset)
11390 || (filedata->dynamic_strtab_section->sh_size
11391 != str_tab_len)))
11392 warn (_("\
11393the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11394
978c4450
AM
11395 filedata->dynamic_strings
11396 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11397 _("dynamic string table"));
11398 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11399 {
11400 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11401 break;
11402 }
e3d39609 11403
978c4450 11404 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11405 break;
11406 }
11407 }
252b5132
RH
11408
11409 /* And find the syminfo section if available. */
978c4450 11410 if (filedata->dynamic_syminfo == NULL)
252b5132 11411 {
3e8bba36 11412 unsigned long syminsz = 0;
252b5132 11413
978c4450
AM
11414 for (entry = filedata->dynamic_section;
11415 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11416 ++entry)
252b5132
RH
11417 {
11418 if (entry->d_tag == DT_SYMINENT)
11419 {
11420 /* Note: these braces are necessary to avoid a syntax
11421 error from the SunOS4 C compiler. */
049b0c3a
NC
11422 /* PR binutils/17531: A corrupt file can trigger this test.
11423 So do not use an assert, instead generate an error message. */
11424 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11425 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11426 (int) entry->d_un.d_val);
252b5132
RH
11427 }
11428 else if (entry->d_tag == DT_SYMINSZ)
11429 syminsz = entry->d_un.d_val;
11430 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11431 filedata->dynamic_syminfo_offset
11432 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11433 }
11434
978c4450 11435 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11436 {
2cf0635d
NC
11437 Elf_External_Syminfo * extsyminfo;
11438 Elf_External_Syminfo * extsym;
11439 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11440
11441 /* There is a syminfo section. Read the data. */
3f5e193b 11442 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11443 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11444 1, syminsz, _("symbol information"));
a6e9f9df 11445 if (!extsyminfo)
015dc7e1 11446 return false;
252b5132 11447
978c4450 11448 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11449 {
11450 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11451 free (filedata->dynamic_syminfo);
e3d39609 11452 }
978c4450
AM
11453 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11454 if (filedata->dynamic_syminfo == NULL)
252b5132 11455 {
2482f306
AM
11456 error (_("Out of memory allocating %lu bytes "
11457 "for dynamic symbol info\n"),
8b73c356 11458 (unsigned long) syminsz);
015dc7e1 11459 return false;
252b5132
RH
11460 }
11461
2482f306
AM
11462 filedata->dynamic_syminfo_nent
11463 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11464 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11465 syminfo < (filedata->dynamic_syminfo
11466 + filedata->dynamic_syminfo_nent);
86dba8ee 11467 ++syminfo, ++extsym)
252b5132 11468 {
86dba8ee
AM
11469 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11470 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11471 }
11472
11473 free (extsyminfo);
11474 }
11475 }
11476
978c4450 11477 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11478 {
f253158f
NC
11479 if (filedata->is_separate)
11480 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11481 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11482 (unsigned long) filedata->dynamic_nent),
11483 filedata->file_name,
11484 filedata->dynamic_addr,
11485 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11486 else
11487 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11488 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11489 (unsigned long) filedata->dynamic_nent),
11490 filedata->dynamic_addr,
11491 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11492 }
252b5132
RH
11493 if (do_dynamic)
11494 printf (_(" Tag Type Name/Value\n"));
11495
978c4450
AM
11496 for (entry = filedata->dynamic_section;
11497 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11498 entry++)
252b5132
RH
11499 {
11500 if (do_dynamic)
f7a99963 11501 {
2cf0635d 11502 const char * dtype;
e699b9ff 11503
f7a99963
NC
11504 putchar (' ');
11505 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11506 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11507 printf (" (%s)%*s", dtype,
32ec8896 11508 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11509 }
252b5132
RH
11510
11511 switch (entry->d_tag)
11512 {
d1133906
NC
11513 case DT_FLAGS:
11514 if (do_dynamic)
e9e44622 11515 print_dynamic_flags (entry->d_un.d_val);
d1133906 11516 break;
76da6bbe 11517
252b5132
RH
11518 case DT_AUXILIARY:
11519 case DT_FILTER:
019148e4
L
11520 case DT_CONFIG:
11521 case DT_DEPAUDIT:
11522 case DT_AUDIT:
252b5132
RH
11523 if (do_dynamic)
11524 {
019148e4 11525 switch (entry->d_tag)
b34976b6 11526 {
019148e4
L
11527 case DT_AUXILIARY:
11528 printf (_("Auxiliary library"));
11529 break;
11530
11531 case DT_FILTER:
11532 printf (_("Filter library"));
11533 break;
11534
b34976b6 11535 case DT_CONFIG:
019148e4
L
11536 printf (_("Configuration file"));
11537 break;
11538
11539 case DT_DEPAUDIT:
11540 printf (_("Dependency audit library"));
11541 break;
11542
11543 case DT_AUDIT:
11544 printf (_("Audit library"));
11545 break;
11546 }
252b5132 11547
84714f86 11548 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11549 printf (": [%s]\n",
84714f86 11550 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11551 else
f7a99963
NC
11552 {
11553 printf (": ");
11554 print_vma (entry->d_un.d_val, PREFIX_HEX);
11555 putchar ('\n');
11556 }
252b5132
RH
11557 }
11558 break;
11559
dcefbbbd 11560 case DT_FEATURE:
252b5132
RH
11561 if (do_dynamic)
11562 {
11563 printf (_("Flags:"));
86f55779 11564
252b5132
RH
11565 if (entry->d_un.d_val == 0)
11566 printf (_(" None\n"));
11567 else
11568 {
11569 unsigned long int val = entry->d_un.d_val;
86f55779 11570
252b5132
RH
11571 if (val & DTF_1_PARINIT)
11572 {
11573 printf (" PARINIT");
11574 val ^= DTF_1_PARINIT;
11575 }
dcefbbbd
L
11576 if (val & DTF_1_CONFEXP)
11577 {
11578 printf (" CONFEXP");
11579 val ^= DTF_1_CONFEXP;
11580 }
252b5132
RH
11581 if (val != 0)
11582 printf (" %lx", val);
11583 puts ("");
11584 }
11585 }
11586 break;
11587
11588 case DT_POSFLAG_1:
11589 if (do_dynamic)
11590 {
11591 printf (_("Flags:"));
86f55779 11592
252b5132
RH
11593 if (entry->d_un.d_val == 0)
11594 printf (_(" None\n"));
11595 else
11596 {
11597 unsigned long int val = entry->d_un.d_val;
86f55779 11598
252b5132
RH
11599 if (val & DF_P1_LAZYLOAD)
11600 {
11601 printf (" LAZYLOAD");
11602 val ^= DF_P1_LAZYLOAD;
11603 }
11604 if (val & DF_P1_GROUPPERM)
11605 {
11606 printf (" GROUPPERM");
11607 val ^= DF_P1_GROUPPERM;
11608 }
11609 if (val != 0)
11610 printf (" %lx", val);
11611 puts ("");
11612 }
11613 }
11614 break;
11615
11616 case DT_FLAGS_1:
11617 if (do_dynamic)
11618 {
11619 printf (_("Flags:"));
11620 if (entry->d_un.d_val == 0)
11621 printf (_(" None\n"));
11622 else
11623 {
11624 unsigned long int val = entry->d_un.d_val;
86f55779 11625
252b5132
RH
11626 if (val & DF_1_NOW)
11627 {
11628 printf (" NOW");
11629 val ^= DF_1_NOW;
11630 }
11631 if (val & DF_1_GLOBAL)
11632 {
11633 printf (" GLOBAL");
11634 val ^= DF_1_GLOBAL;
11635 }
11636 if (val & DF_1_GROUP)
11637 {
11638 printf (" GROUP");
11639 val ^= DF_1_GROUP;
11640 }
11641 if (val & DF_1_NODELETE)
11642 {
11643 printf (" NODELETE");
11644 val ^= DF_1_NODELETE;
11645 }
11646 if (val & DF_1_LOADFLTR)
11647 {
11648 printf (" LOADFLTR");
11649 val ^= DF_1_LOADFLTR;
11650 }
11651 if (val & DF_1_INITFIRST)
11652 {
11653 printf (" INITFIRST");
11654 val ^= DF_1_INITFIRST;
11655 }
11656 if (val & DF_1_NOOPEN)
11657 {
11658 printf (" NOOPEN");
11659 val ^= DF_1_NOOPEN;
11660 }
11661 if (val & DF_1_ORIGIN)
11662 {
11663 printf (" ORIGIN");
11664 val ^= DF_1_ORIGIN;
11665 }
11666 if (val & DF_1_DIRECT)
11667 {
11668 printf (" DIRECT");
11669 val ^= DF_1_DIRECT;
11670 }
11671 if (val & DF_1_TRANS)
11672 {
11673 printf (" TRANS");
11674 val ^= DF_1_TRANS;
11675 }
11676 if (val & DF_1_INTERPOSE)
11677 {
11678 printf (" INTERPOSE");
11679 val ^= DF_1_INTERPOSE;
11680 }
f7db6139 11681 if (val & DF_1_NODEFLIB)
dcefbbbd 11682 {
f7db6139
L
11683 printf (" NODEFLIB");
11684 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11685 }
11686 if (val & DF_1_NODUMP)
11687 {
11688 printf (" NODUMP");
11689 val ^= DF_1_NODUMP;
11690 }
34b60028 11691 if (val & DF_1_CONFALT)
dcefbbbd 11692 {
34b60028
L
11693 printf (" CONFALT");
11694 val ^= DF_1_CONFALT;
11695 }
11696 if (val & DF_1_ENDFILTEE)
11697 {
11698 printf (" ENDFILTEE");
11699 val ^= DF_1_ENDFILTEE;
11700 }
11701 if (val & DF_1_DISPRELDNE)
11702 {
11703 printf (" DISPRELDNE");
11704 val ^= DF_1_DISPRELDNE;
11705 }
11706 if (val & DF_1_DISPRELPND)
11707 {
11708 printf (" DISPRELPND");
11709 val ^= DF_1_DISPRELPND;
11710 }
11711 if (val & DF_1_NODIRECT)
11712 {
11713 printf (" NODIRECT");
11714 val ^= DF_1_NODIRECT;
11715 }
11716 if (val & DF_1_IGNMULDEF)
11717 {
11718 printf (" IGNMULDEF");
11719 val ^= DF_1_IGNMULDEF;
11720 }
11721 if (val & DF_1_NOKSYMS)
11722 {
11723 printf (" NOKSYMS");
11724 val ^= DF_1_NOKSYMS;
11725 }
11726 if (val & DF_1_NOHDR)
11727 {
11728 printf (" NOHDR");
11729 val ^= DF_1_NOHDR;
11730 }
11731 if (val & DF_1_EDITED)
11732 {
11733 printf (" EDITED");
11734 val ^= DF_1_EDITED;
11735 }
11736 if (val & DF_1_NORELOC)
11737 {
11738 printf (" NORELOC");
11739 val ^= DF_1_NORELOC;
11740 }
11741 if (val & DF_1_SYMINTPOSE)
11742 {
11743 printf (" SYMINTPOSE");
11744 val ^= DF_1_SYMINTPOSE;
11745 }
11746 if (val & DF_1_GLOBAUDIT)
11747 {
11748 printf (" GLOBAUDIT");
11749 val ^= DF_1_GLOBAUDIT;
11750 }
11751 if (val & DF_1_SINGLETON)
11752 {
11753 printf (" SINGLETON");
11754 val ^= DF_1_SINGLETON;
dcefbbbd 11755 }
5c383f02
RO
11756 if (val & DF_1_STUB)
11757 {
11758 printf (" STUB");
11759 val ^= DF_1_STUB;
11760 }
11761 if (val & DF_1_PIE)
11762 {
11763 printf (" PIE");
11764 val ^= DF_1_PIE;
11765 }
b1202ffa
L
11766 if (val & DF_1_KMOD)
11767 {
11768 printf (" KMOD");
11769 val ^= DF_1_KMOD;
11770 }
11771 if (val & DF_1_WEAKFILTER)
11772 {
11773 printf (" WEAKFILTER");
11774 val ^= DF_1_WEAKFILTER;
11775 }
11776 if (val & DF_1_NOCOMMON)
11777 {
11778 printf (" NOCOMMON");
11779 val ^= DF_1_NOCOMMON;
11780 }
252b5132
RH
11781 if (val != 0)
11782 printf (" %lx", val);
11783 puts ("");
11784 }
11785 }
11786 break;
11787
11788 case DT_PLTREL:
978c4450 11789 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11790 if (do_dynamic)
dda8d76d 11791 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11792 break;
11793
11794 case DT_NULL :
11795 case DT_NEEDED :
11796 case DT_PLTGOT :
11797 case DT_HASH :
11798 case DT_STRTAB :
11799 case DT_SYMTAB :
11800 case DT_RELA :
11801 case DT_INIT :
11802 case DT_FINI :
11803 case DT_SONAME :
11804 case DT_RPATH :
11805 case DT_SYMBOLIC:
11806 case DT_REL :
a7fd1186 11807 case DT_RELR :
252b5132
RH
11808 case DT_DEBUG :
11809 case DT_TEXTREL :
11810 case DT_JMPREL :
019148e4 11811 case DT_RUNPATH :
978c4450 11812 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11813
11814 if (do_dynamic)
11815 {
84714f86 11816 const char *name;
252b5132 11817
84714f86
AM
11818 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11819 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11820 else
d79b3d50 11821 name = NULL;
252b5132
RH
11822
11823 if (name)
11824 {
11825 switch (entry->d_tag)
11826 {
11827 case DT_NEEDED:
11828 printf (_("Shared library: [%s]"), name);
11829
13acb58d
AM
11830 if (filedata->program_interpreter
11831 && streq (name, filedata->program_interpreter))
f7a99963 11832 printf (_(" program interpreter"));
252b5132
RH
11833 break;
11834
11835 case DT_SONAME:
f7a99963 11836 printf (_("Library soname: [%s]"), name);
252b5132
RH
11837 break;
11838
11839 case DT_RPATH:
f7a99963 11840 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11841 break;
11842
019148e4
L
11843 case DT_RUNPATH:
11844 printf (_("Library runpath: [%s]"), name);
11845 break;
11846
252b5132 11847 default:
f7a99963
NC
11848 print_vma (entry->d_un.d_val, PREFIX_HEX);
11849 break;
252b5132
RH
11850 }
11851 }
11852 else
f7a99963
NC
11853 print_vma (entry->d_un.d_val, PREFIX_HEX);
11854
11855 putchar ('\n');
252b5132
RH
11856 }
11857 break;
11858
11859 case DT_PLTRELSZ:
11860 case DT_RELASZ :
11861 case DT_STRSZ :
11862 case DT_RELSZ :
11863 case DT_RELAENT :
a7fd1186
FS
11864 case DT_RELRENT :
11865 case DT_RELRSZ :
252b5132
RH
11866 case DT_SYMENT :
11867 case DT_RELENT :
978c4450 11868 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11869 /* Fall through. */
252b5132
RH
11870 case DT_PLTPADSZ:
11871 case DT_MOVEENT :
11872 case DT_MOVESZ :
04d8355a 11873 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11874 case DT_INIT_ARRAYSZ:
11875 case DT_FINI_ARRAYSZ:
047b2264
JJ
11876 case DT_GNU_CONFLICTSZ:
11877 case DT_GNU_LIBLISTSZ:
252b5132 11878 if (do_dynamic)
f7a99963
NC
11879 {
11880 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11881 printf (_(" (bytes)\n"));
f7a99963 11882 }
252b5132
RH
11883 break;
11884
11885 case DT_VERDEFNUM:
11886 case DT_VERNEEDNUM:
11887 case DT_RELACOUNT:
11888 case DT_RELCOUNT:
11889 if (do_dynamic)
f7a99963
NC
11890 {
11891 print_vma (entry->d_un.d_val, UNSIGNED);
11892 putchar ('\n');
11893 }
252b5132
RH
11894 break;
11895
11896 case DT_SYMINSZ:
11897 case DT_SYMINENT:
11898 case DT_SYMINFO:
11899 case DT_USED:
11900 case DT_INIT_ARRAY:
11901 case DT_FINI_ARRAY:
11902 if (do_dynamic)
11903 {
d79b3d50 11904 if (entry->d_tag == DT_USED
84714f86 11905 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11906 {
84714f86
AM
11907 const char *name
11908 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11909
b34976b6 11910 if (*name)
252b5132
RH
11911 {
11912 printf (_("Not needed object: [%s]\n"), name);
11913 break;
11914 }
11915 }
103f02d3 11916
f7a99963
NC
11917 print_vma (entry->d_un.d_val, PREFIX_HEX);
11918 putchar ('\n');
252b5132
RH
11919 }
11920 break;
11921
11922 case DT_BIND_NOW:
11923 /* The value of this entry is ignored. */
35b1837e
AM
11924 if (do_dynamic)
11925 putchar ('\n');
252b5132 11926 break;
103f02d3 11927
047b2264
JJ
11928 case DT_GNU_PRELINKED:
11929 if (do_dynamic)
11930 {
2cf0635d 11931 struct tm * tmp;
91d6fa6a 11932 time_t atime = entry->d_un.d_val;
047b2264 11933
91d6fa6a 11934 tmp = gmtime (&atime);
071436c6
NC
11935 /* PR 17533 file: 041-1244816-0.004. */
11936 if (tmp == NULL)
5a2cbcf4
L
11937 printf (_("<corrupt time val: %lx"),
11938 (unsigned long) atime);
071436c6
NC
11939 else
11940 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11941 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11942 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11943
11944 }
11945 break;
11946
fdc90cb4 11947 case DT_GNU_HASH:
978c4450 11948 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11949 if (do_dynamic)
11950 {
11951 print_vma (entry->d_un.d_val, PREFIX_HEX);
11952 putchar ('\n');
11953 }
11954 break;
11955
a5da3dee
VDM
11956 case DT_GNU_FLAGS_1:
11957 if (do_dynamic)
11958 {
11959 printf (_("Flags:"));
11960 if (entry->d_un.d_val == 0)
11961 printf (_(" None\n"));
11962 else
11963 {
11964 unsigned long int val = entry->d_un.d_val;
11965
11966 if (val & DF_GNU_1_UNIQUE)
11967 {
11968 printf (" UNIQUE");
11969 val ^= DF_GNU_1_UNIQUE;
11970 }
11971 if (val != 0)
11972 printf (" %lx", val);
11973 puts ("");
11974 }
11975 }
11976 break;
11977
252b5132
RH
11978 default:
11979 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11980 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11981 = entry->d_un.d_val;
252b5132
RH
11982
11983 if (do_dynamic)
11984 {
dda8d76d 11985 switch (filedata->file_header.e_machine)
252b5132 11986 {
37c18eed
SD
11987 case EM_AARCH64:
11988 dynamic_section_aarch64_val (entry);
11989 break;
252b5132 11990 case EM_MIPS:
4fe85591 11991 case EM_MIPS_RS3_LE:
978c4450 11992 dynamic_section_mips_val (filedata, entry);
252b5132 11993 break;
103f02d3 11994 case EM_PARISC:
b2d38a17 11995 dynamic_section_parisc_val (entry);
103f02d3 11996 break;
ecc51f48 11997 case EM_IA_64:
b2d38a17 11998 dynamic_section_ia64_val (entry);
ecc51f48 11999 break;
252b5132 12000 default:
f7a99963
NC
12001 print_vma (entry->d_un.d_val, PREFIX_HEX);
12002 putchar ('\n');
252b5132
RH
12003 }
12004 }
12005 break;
12006 }
12007 }
12008
015dc7e1 12009 return true;
252b5132
RH
12010}
12011
12012static char *
d3ba0551 12013get_ver_flags (unsigned int flags)
252b5132 12014{
6d4f21f6 12015 static char buff[128];
252b5132
RH
12016
12017 buff[0] = 0;
12018
12019 if (flags == 0)
12020 return _("none");
12021
12022 if (flags & VER_FLG_BASE)
7bb1ad17 12023 strcat (buff, "BASE");
252b5132
RH
12024
12025 if (flags & VER_FLG_WEAK)
12026 {
12027 if (flags & VER_FLG_BASE)
7bb1ad17 12028 strcat (buff, " | ");
252b5132 12029
7bb1ad17 12030 strcat (buff, "WEAK");
252b5132
RH
12031 }
12032
44ec90b9
RO
12033 if (flags & VER_FLG_INFO)
12034 {
12035 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12036 strcat (buff, " | ");
44ec90b9 12037
7bb1ad17 12038 strcat (buff, "INFO");
44ec90b9
RO
12039 }
12040
12041 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12042 {
12043 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12044 strcat (buff, " | ");
12045
12046 strcat (buff, _("<unknown>"));
12047 }
252b5132
RH
12048
12049 return buff;
12050}
12051
12052/* Display the contents of the version sections. */
98fb390a 12053
015dc7e1 12054static bool
dda8d76d 12055process_version_sections (Filedata * filedata)
252b5132 12056{
2cf0635d 12057 Elf_Internal_Shdr * section;
b34976b6 12058 unsigned i;
015dc7e1 12059 bool found = false;
252b5132
RH
12060
12061 if (! do_version)
015dc7e1 12062 return true;
252b5132 12063
dda8d76d
NC
12064 for (i = 0, section = filedata->section_headers;
12065 i < filedata->file_header.e_shnum;
b34976b6 12066 i++, section++)
252b5132
RH
12067 {
12068 switch (section->sh_type)
12069 {
12070 case SHT_GNU_verdef:
12071 {
2cf0635d 12072 Elf_External_Verdef * edefs;
452bf675
AM
12073 unsigned long idx;
12074 unsigned long cnt;
2cf0635d 12075 char * endbuf;
252b5132 12076
015dc7e1 12077 found = true;
252b5132 12078
ca0e11aa
NC
12079 if (filedata->is_separate)
12080 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12081 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12082 section->sh_info),
12083 filedata->file_name,
12084 printable_section_name (filedata, section),
12085 section->sh_info);
12086 else
12087 printf (ngettext ("\nVersion definition section '%s' "
12088 "contains %u entry:\n",
12089 "\nVersion definition section '%s' "
12090 "contains %u entries:\n",
12091 section->sh_info),
12092 printable_section_name (filedata, section),
12093 section->sh_info);
047c3dbf 12094
ae9ac79e 12095 printf (_(" Addr: 0x"));
252b5132 12096 printf_vma (section->sh_addr);
233f82cf 12097 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12098 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12099 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12100
3f5e193b 12101 edefs = (Elf_External_Verdef *)
dda8d76d 12102 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12103 _("version definition section"));
a6e9f9df
AM
12104 if (!edefs)
12105 break;
59245841 12106 endbuf = (char *) edefs + section->sh_size;
252b5132 12107
1445030f 12108 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12109 {
2cf0635d
NC
12110 char * vstart;
12111 Elf_External_Verdef * edef;
b34976b6 12112 Elf_Internal_Verdef ent;
2cf0635d 12113 Elf_External_Verdaux * eaux;
b34976b6 12114 Elf_Internal_Verdaux aux;
452bf675 12115 unsigned long isum;
b34976b6 12116 int j;
103f02d3 12117
252b5132 12118 vstart = ((char *) edefs) + idx;
54806181
AM
12119 if (vstart + sizeof (*edef) > endbuf)
12120 break;
252b5132
RH
12121
12122 edef = (Elf_External_Verdef *) vstart;
12123
12124 ent.vd_version = BYTE_GET (edef->vd_version);
12125 ent.vd_flags = BYTE_GET (edef->vd_flags);
12126 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12127 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12128 ent.vd_hash = BYTE_GET (edef->vd_hash);
12129 ent.vd_aux = BYTE_GET (edef->vd_aux);
12130 ent.vd_next = BYTE_GET (edef->vd_next);
12131
452bf675 12132 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12133 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12134
12135 printf (_(" Index: %d Cnt: %d "),
12136 ent.vd_ndx, ent.vd_cnt);
12137
452bf675 12138 /* Check for overflow. */
1445030f 12139 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12140 break;
12141
252b5132
RH
12142 vstart += ent.vd_aux;
12143
1445030f
AM
12144 if (vstart + sizeof (*eaux) > endbuf)
12145 break;
252b5132
RH
12146 eaux = (Elf_External_Verdaux *) vstart;
12147
12148 aux.vda_name = BYTE_GET (eaux->vda_name);
12149 aux.vda_next = BYTE_GET (eaux->vda_next);
12150
84714f86 12151 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12152 printf (_("Name: %s\n"),
84714f86 12153 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12154 else
12155 printf (_("Name index: %ld\n"), aux.vda_name);
12156
12157 isum = idx + ent.vd_aux;
12158
b34976b6 12159 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12160 {
1445030f
AM
12161 if (aux.vda_next < sizeof (*eaux)
12162 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12163 {
12164 warn (_("Invalid vda_next field of %lx\n"),
12165 aux.vda_next);
12166 j = ent.vd_cnt;
12167 break;
12168 }
dd24e3da 12169 /* Check for overflow. */
7e26601c 12170 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12171 break;
12172
252b5132
RH
12173 isum += aux.vda_next;
12174 vstart += aux.vda_next;
12175
54806181
AM
12176 if (vstart + sizeof (*eaux) > endbuf)
12177 break;
1445030f 12178 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12179
12180 aux.vda_name = BYTE_GET (eaux->vda_name);
12181 aux.vda_next = BYTE_GET (eaux->vda_next);
12182
84714f86 12183 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12184 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12185 isum, j,
84714f86 12186 get_dynamic_name (filedata, aux.vda_name));
252b5132 12187 else
452bf675 12188 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12189 isum, j, aux.vda_name);
12190 }
dd24e3da 12191
54806181
AM
12192 if (j < ent.vd_cnt)
12193 printf (_(" Version def aux past end of section\n"));
252b5132 12194
c9f02c3e
MR
12195 /* PR 17531:
12196 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12197 if (ent.vd_next < sizeof (*edef)
12198 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12199 {
12200 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12201 cnt = section->sh_info;
12202 break;
12203 }
452bf675 12204 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12205 break;
12206
252b5132
RH
12207 idx += ent.vd_next;
12208 }
dd24e3da 12209
54806181
AM
12210 if (cnt < section->sh_info)
12211 printf (_(" Version definition past end of section\n"));
252b5132
RH
12212
12213 free (edefs);
12214 }
12215 break;
103f02d3 12216
252b5132
RH
12217 case SHT_GNU_verneed:
12218 {
2cf0635d 12219 Elf_External_Verneed * eneed;
452bf675
AM
12220 unsigned long idx;
12221 unsigned long cnt;
2cf0635d 12222 char * endbuf;
252b5132 12223
015dc7e1 12224 found = true;
252b5132 12225
ca0e11aa
NC
12226 if (filedata->is_separate)
12227 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12228 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12229 section->sh_info),
12230 filedata->file_name,
12231 printable_section_name (filedata, section),
12232 section->sh_info);
12233 else
12234 printf (ngettext ("\nVersion needs section '%s' "
12235 "contains %u entry:\n",
12236 "\nVersion needs section '%s' "
12237 "contains %u entries:\n",
12238 section->sh_info),
12239 printable_section_name (filedata, section),
12240 section->sh_info);
047c3dbf 12241
252b5132
RH
12242 printf (_(" Addr: 0x"));
12243 printf_vma (section->sh_addr);
72de5009 12244 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12245 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12246 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12247
dda8d76d 12248 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12249 section->sh_offset, 1,
12250 section->sh_size,
9cf03b7e 12251 _("Version Needs section"));
a6e9f9df
AM
12252 if (!eneed)
12253 break;
59245841 12254 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12255
12256 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12257 {
2cf0635d 12258 Elf_External_Verneed * entry;
b34976b6 12259 Elf_Internal_Verneed ent;
452bf675 12260 unsigned long isum;
b34976b6 12261 int j;
2cf0635d 12262 char * vstart;
252b5132
RH
12263
12264 vstart = ((char *) eneed) + idx;
54806181
AM
12265 if (vstart + sizeof (*entry) > endbuf)
12266 break;
252b5132
RH
12267
12268 entry = (Elf_External_Verneed *) vstart;
12269
12270 ent.vn_version = BYTE_GET (entry->vn_version);
12271 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12272 ent.vn_file = BYTE_GET (entry->vn_file);
12273 ent.vn_aux = BYTE_GET (entry->vn_aux);
12274 ent.vn_next = BYTE_GET (entry->vn_next);
12275
452bf675 12276 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12277
84714f86 12278 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12279 printf (_(" File: %s"),
84714f86 12280 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12281 else
12282 printf (_(" File: %lx"), ent.vn_file);
12283
12284 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12285
dd24e3da 12286 /* Check for overflow. */
7e26601c 12287 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12288 break;
252b5132
RH
12289 vstart += ent.vn_aux;
12290
12291 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12292 {
2cf0635d 12293 Elf_External_Vernaux * eaux;
b34976b6 12294 Elf_Internal_Vernaux aux;
252b5132 12295
54806181
AM
12296 if (vstart + sizeof (*eaux) > endbuf)
12297 break;
252b5132
RH
12298 eaux = (Elf_External_Vernaux *) vstart;
12299
12300 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12301 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12302 aux.vna_other = BYTE_GET (eaux->vna_other);
12303 aux.vna_name = BYTE_GET (eaux->vna_name);
12304 aux.vna_next = BYTE_GET (eaux->vna_next);
12305
84714f86 12306 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12307 printf (_(" %#06lx: Name: %s"),
84714f86 12308 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12309 else
452bf675 12310 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12311 isum, aux.vna_name);
12312
12313 printf (_(" Flags: %s Version: %d\n"),
12314 get_ver_flags (aux.vna_flags), aux.vna_other);
12315
1445030f
AM
12316 if (aux.vna_next < sizeof (*eaux)
12317 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12318 {
12319 warn (_("Invalid vna_next field of %lx\n"),
12320 aux.vna_next);
12321 j = ent.vn_cnt;
12322 break;
12323 }
1445030f
AM
12324 /* Check for overflow. */
12325 if (aux.vna_next > (size_t) (endbuf - vstart))
12326 break;
252b5132
RH
12327 isum += aux.vna_next;
12328 vstart += aux.vna_next;
12329 }
9cf03b7e 12330
54806181 12331 if (j < ent.vn_cnt)
f9a6a8f0 12332 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12333
1445030f
AM
12334 if (ent.vn_next < sizeof (*entry)
12335 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12336 {
452bf675 12337 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12338 cnt = section->sh_info;
12339 break;
12340 }
1445030f
AM
12341 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12342 break;
252b5132
RH
12343 idx += ent.vn_next;
12344 }
9cf03b7e 12345
54806181 12346 if (cnt < section->sh_info)
9cf03b7e 12347 warn (_("Missing Version Needs information\n"));
103f02d3 12348
252b5132
RH
12349 free (eneed);
12350 }
12351 break;
12352
12353 case SHT_GNU_versym:
12354 {
2cf0635d 12355 Elf_Internal_Shdr * link_section;
8b73c356
NC
12356 size_t total;
12357 unsigned int cnt;
2cf0635d
NC
12358 unsigned char * edata;
12359 unsigned short * data;
12360 char * strtab;
12361 Elf_Internal_Sym * symbols;
12362 Elf_Internal_Shdr * string_sec;
ba5cdace 12363 unsigned long num_syms;
d3ba0551 12364 long off;
252b5132 12365
dda8d76d 12366 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12367 break;
12368
dda8d76d 12369 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12370 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12371
dda8d76d 12372 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12373 break;
12374
015dc7e1 12375 found = true;
252b5132 12376
4de91c10 12377 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12378 if (symbols == NULL)
12379 break;
252b5132 12380
dda8d76d 12381 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12382
dda8d76d 12383 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12384 string_sec->sh_size,
12385 _("version string table"));
a6e9f9df 12386 if (!strtab)
0429c154
MS
12387 {
12388 free (symbols);
12389 break;
12390 }
252b5132 12391
ca0e11aa
NC
12392 if (filedata->is_separate)
12393 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12394 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12395 total),
12396 filedata->file_name,
12397 printable_section_name (filedata, section),
12398 (unsigned long) total);
12399 else
12400 printf (ngettext ("\nVersion symbols section '%s' "
12401 "contains %lu entry:\n",
12402 "\nVersion symbols section '%s' "
12403 "contains %lu entries:\n",
12404 total),
12405 printable_section_name (filedata, section),
12406 (unsigned long) total);
252b5132 12407
ae9ac79e 12408 printf (_(" Addr: 0x"));
252b5132 12409 printf_vma (section->sh_addr);
72de5009 12410 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12411 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12412 printable_section_name (filedata, link_section));
252b5132 12413
dda8d76d 12414 off = offset_from_vma (filedata,
978c4450 12415 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12416 total * sizeof (short));
95099889
AM
12417 edata = (unsigned char *) get_data (NULL, filedata, off,
12418 sizeof (short), total,
12419 _("version symbol data"));
a6e9f9df
AM
12420 if (!edata)
12421 {
12422 free (strtab);
0429c154 12423 free (symbols);
a6e9f9df
AM
12424 break;
12425 }
252b5132 12426
3f5e193b 12427 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12428
12429 for (cnt = total; cnt --;)
b34976b6
AM
12430 data[cnt] = byte_get (edata + cnt * sizeof (short),
12431 sizeof (short));
252b5132
RH
12432
12433 free (edata);
12434
12435 for (cnt = 0; cnt < total; cnt += 4)
12436 {
12437 int j, nn;
ab273396
AM
12438 char *name;
12439 char *invalid = _("*invalid*");
252b5132
RH
12440
12441 printf (" %03x:", cnt);
12442
12443 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12444 switch (data[cnt + j])
252b5132
RH
12445 {
12446 case 0:
12447 fputs (_(" 0 (*local*) "), stdout);
12448 break;
12449
12450 case 1:
12451 fputs (_(" 1 (*global*) "), stdout);
12452 break;
12453
12454 default:
c244d050
NC
12455 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12456 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12457
dd24e3da 12458 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12459 array, break to avoid an out-of-bounds read. */
12460 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12461 {
12462 warn (_("invalid index into symbol array\n"));
12463 break;
12464 }
12465
ab273396 12466 name = NULL;
978c4450 12467 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12468 {
b34976b6
AM
12469 Elf_Internal_Verneed ivn;
12470 unsigned long offset;
252b5132 12471
d93f0186 12472 offset = offset_from_vma
978c4450
AM
12473 (filedata,
12474 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12475 sizeof (Elf_External_Verneed));
252b5132 12476
b34976b6 12477 do
252b5132 12478 {
b34976b6
AM
12479 Elf_Internal_Vernaux ivna;
12480 Elf_External_Verneed evn;
12481 Elf_External_Vernaux evna;
12482 unsigned long a_off;
252b5132 12483
dda8d76d 12484 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12485 _("version need")) == NULL)
12486 break;
0b4362b0 12487
252b5132
RH
12488 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12489 ivn.vn_next = BYTE_GET (evn.vn_next);
12490
12491 a_off = offset + ivn.vn_aux;
12492
12493 do
12494 {
dda8d76d 12495 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12496 1, _("version need aux (2)")) == NULL)
12497 {
12498 ivna.vna_next = 0;
12499 ivna.vna_other = 0;
12500 }
12501 else
12502 {
12503 ivna.vna_next = BYTE_GET (evna.vna_next);
12504 ivna.vna_other = BYTE_GET (evna.vna_other);
12505 }
252b5132
RH
12506
12507 a_off += ivna.vna_next;
12508 }
b34976b6 12509 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12510 && ivna.vna_next != 0);
12511
b34976b6 12512 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12513 {
12514 ivna.vna_name = BYTE_GET (evna.vna_name);
12515
54806181 12516 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12517 name = invalid;
54806181
AM
12518 else
12519 name = strtab + ivna.vna_name;
252b5132
RH
12520 break;
12521 }
12522
12523 offset += ivn.vn_next;
12524 }
12525 while (ivn.vn_next);
12526 }
00d93f34 12527
ab273396 12528 if (data[cnt + j] != 0x8001
978c4450 12529 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12530 {
b34976b6
AM
12531 Elf_Internal_Verdef ivd;
12532 Elf_External_Verdef evd;
12533 unsigned long offset;
252b5132 12534
d93f0186 12535 offset = offset_from_vma
978c4450
AM
12536 (filedata,
12537 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12538 sizeof evd);
252b5132
RH
12539
12540 do
12541 {
dda8d76d 12542 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12543 _("version def")) == NULL)
12544 {
12545 ivd.vd_next = 0;
948f632f 12546 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12547 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12548 break;
59245841
NC
12549 }
12550 else
12551 {
12552 ivd.vd_next = BYTE_GET (evd.vd_next);
12553 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12554 }
252b5132
RH
12555
12556 offset += ivd.vd_next;
12557 }
c244d050 12558 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12559 && ivd.vd_next != 0);
12560
c244d050 12561 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12562 {
b34976b6
AM
12563 Elf_External_Verdaux evda;
12564 Elf_Internal_Verdaux ivda;
252b5132
RH
12565
12566 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12567
dda8d76d 12568 if (get_data (&evda, filedata,
59245841
NC
12569 offset - ivd.vd_next + ivd.vd_aux,
12570 sizeof (evda), 1,
12571 _("version def aux")) == NULL)
12572 break;
252b5132
RH
12573
12574 ivda.vda_name = BYTE_GET (evda.vda_name);
12575
54806181 12576 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12577 name = invalid;
12578 else if (name != NULL && name != invalid)
12579 name = _("*both*");
54806181
AM
12580 else
12581 name = strtab + ivda.vda_name;
252b5132
RH
12582 }
12583 }
ab273396
AM
12584 if (name != NULL)
12585 nn += printf ("(%s%-*s",
12586 name,
12587 12 - (int) strlen (name),
12588 ")");
252b5132
RH
12589
12590 if (nn < 18)
12591 printf ("%*c", 18 - nn, ' ');
12592 }
12593
12594 putchar ('\n');
12595 }
12596
12597 free (data);
12598 free (strtab);
12599 free (symbols);
12600 }
12601 break;
103f02d3 12602
252b5132
RH
12603 default:
12604 break;
12605 }
12606 }
12607
12608 if (! found)
ca0e11aa
NC
12609 {
12610 if (filedata->is_separate)
12611 printf (_("\nNo version information found in linked file '%s'.\n"),
12612 filedata->file_name);
12613 else
12614 printf (_("\nNo version information found in this file.\n"));
12615 }
252b5132 12616
015dc7e1 12617 return true;
252b5132
RH
12618}
12619
d1133906 12620static const char *
dda8d76d 12621get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12622{
89246a0e 12623 static char buff[64];
252b5132
RH
12624
12625 switch (binding)
12626 {
b34976b6
AM
12627 case STB_LOCAL: return "LOCAL";
12628 case STB_GLOBAL: return "GLOBAL";
12629 case STB_WEAK: return "WEAK";
252b5132
RH
12630 default:
12631 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12632 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12633 binding);
252b5132 12634 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12635 {
12636 if (binding == STB_GNU_UNIQUE
df3a023b 12637 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12638 return "UNIQUE";
12639 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12640 }
252b5132 12641 else
e9e44622 12642 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12643 return buff;
12644 }
12645}
12646
d1133906 12647static const char *
dda8d76d 12648get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12649{
89246a0e 12650 static char buff[64];
252b5132
RH
12651
12652 switch (type)
12653 {
b34976b6
AM
12654 case STT_NOTYPE: return "NOTYPE";
12655 case STT_OBJECT: return "OBJECT";
12656 case STT_FUNC: return "FUNC";
12657 case STT_SECTION: return "SECTION";
12658 case STT_FILE: return "FILE";
12659 case STT_COMMON: return "COMMON";
12660 case STT_TLS: return "TLS";
15ab5209
DB
12661 case STT_RELC: return "RELC";
12662 case STT_SRELC: return "SRELC";
252b5132
RH
12663 default:
12664 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12665 {
dda8d76d 12666 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12667 return "THUMB_FUNC";
103f02d3 12668
dda8d76d 12669 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12670 return "REGISTER";
12671
dda8d76d 12672 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12673 return "PARISC_MILLI";
12674
e9e44622 12675 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12676 }
252b5132 12677 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12678 {
dda8d76d 12679 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12680 {
12681 if (type == STT_HP_OPAQUE)
12682 return "HP_OPAQUE";
12683 if (type == STT_HP_STUB)
12684 return "HP_STUB";
12685 }
12686
d8045f23 12687 if (type == STT_GNU_IFUNC
dda8d76d 12688 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12689 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12690 return "IFUNC";
12691
e9e44622 12692 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12693 }
252b5132 12694 else
e9e44622 12695 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12696 return buff;
12697 }
12698}
12699
d1133906 12700static const char *
d3ba0551 12701get_symbol_visibility (unsigned int visibility)
d1133906
NC
12702{
12703 switch (visibility)
12704 {
b34976b6
AM
12705 case STV_DEFAULT: return "DEFAULT";
12706 case STV_INTERNAL: return "INTERNAL";
12707 case STV_HIDDEN: return "HIDDEN";
d1133906 12708 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12709 default:
27a45f42 12710 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12711 return _("<unknown>");
d1133906
NC
12712 }
12713}
12714
2057d69d
CZ
12715static const char *
12716get_alpha_symbol_other (unsigned int other)
9abca702 12717{
2057d69d
CZ
12718 switch (other)
12719 {
12720 case STO_ALPHA_NOPV: return "NOPV";
12721 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12722 default:
27a45f42 12723 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12724 return _("<unknown>");
9abca702 12725 }
2057d69d
CZ
12726}
12727
fd85a6a1
NC
12728static const char *
12729get_solaris_symbol_visibility (unsigned int visibility)
12730{
12731 switch (visibility)
12732 {
12733 case 4: return "EXPORTED";
12734 case 5: return "SINGLETON";
12735 case 6: return "ELIMINATE";
12736 default: return get_symbol_visibility (visibility);
12737 }
12738}
12739
2301ed1c
SN
12740static const char *
12741get_aarch64_symbol_other (unsigned int other)
12742{
12743 static char buf[32];
12744
12745 if (other & STO_AARCH64_VARIANT_PCS)
12746 {
12747 other &= ~STO_AARCH64_VARIANT_PCS;
12748 if (other == 0)
12749 return "VARIANT_PCS";
12750 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12751 return buf;
12752 }
12753 return NULL;
12754}
12755
5e2b0d47
NC
12756static const char *
12757get_mips_symbol_other (unsigned int other)
12758{
12759 switch (other)
12760 {
32ec8896
NC
12761 case STO_OPTIONAL: return "OPTIONAL";
12762 case STO_MIPS_PLT: return "MIPS PLT";
12763 case STO_MIPS_PIC: return "MIPS PIC";
12764 case STO_MICROMIPS: return "MICROMIPS";
12765 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12766 case STO_MIPS16: return "MIPS16";
12767 default: return NULL;
5e2b0d47
NC
12768 }
12769}
12770
28f997cf 12771static const char *
dda8d76d 12772get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12773{
dda8d76d 12774 if (is_ia64_vms (filedata))
28f997cf
TG
12775 {
12776 static char res[32];
12777
12778 res[0] = 0;
12779
12780 /* Function types is for images and .STB files only. */
dda8d76d 12781 switch (filedata->file_header.e_type)
28f997cf
TG
12782 {
12783 case ET_DYN:
12784 case ET_EXEC:
12785 switch (VMS_ST_FUNC_TYPE (other))
12786 {
12787 case VMS_SFT_CODE_ADDR:
12788 strcat (res, " CA");
12789 break;
12790 case VMS_SFT_SYMV_IDX:
12791 strcat (res, " VEC");
12792 break;
12793 case VMS_SFT_FD:
12794 strcat (res, " FD");
12795 break;
12796 case VMS_SFT_RESERVE:
12797 strcat (res, " RSV");
12798 break;
12799 default:
bee0ee85
NC
12800 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12801 VMS_ST_FUNC_TYPE (other));
12802 strcat (res, " <unknown>");
12803 break;
28f997cf
TG
12804 }
12805 break;
12806 default:
12807 break;
12808 }
12809 switch (VMS_ST_LINKAGE (other))
12810 {
12811 case VMS_STL_IGNORE:
12812 strcat (res, " IGN");
12813 break;
12814 case VMS_STL_RESERVE:
12815 strcat (res, " RSV");
12816 break;
12817 case VMS_STL_STD:
12818 strcat (res, " STD");
12819 break;
12820 case VMS_STL_LNK:
12821 strcat (res, " LNK");
12822 break;
12823 default:
bee0ee85
NC
12824 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12825 VMS_ST_LINKAGE (other));
12826 strcat (res, " <unknown>");
12827 break;
28f997cf
TG
12828 }
12829
12830 if (res[0] != 0)
12831 return res + 1;
12832 else
12833 return res;
12834 }
12835 return NULL;
12836}
12837
6911b7dc
AM
12838static const char *
12839get_ppc64_symbol_other (unsigned int other)
12840{
14732552
AM
12841 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12842 return NULL;
12843
12844 other >>= STO_PPC64_LOCAL_BIT;
12845 if (other <= 6)
6911b7dc 12846 {
89246a0e 12847 static char buf[64];
14732552
AM
12848 if (other >= 2)
12849 other = ppc64_decode_local_entry (other);
12850 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12851 return buf;
12852 }
12853 return NULL;
12854}
12855
8155b853
NC
12856static const char *
12857get_riscv_symbol_other (unsigned int other)
12858{
12859 static char buf[32];
12860 buf[0] = 0;
12861
12862 if (other & STO_RISCV_VARIANT_CC)
12863 {
12864 strcat (buf, _(" VARIANT_CC"));
12865 other &= ~STO_RISCV_VARIANT_CC;
12866 }
12867
12868 if (other != 0)
12869 snprintf (buf, sizeof buf, " %x", other);
12870
12871
12872 if (buf[0] != 0)
12873 return buf + 1;
12874 else
12875 return buf;
12876}
12877
5e2b0d47 12878static const char *
dda8d76d 12879get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12880{
12881 const char * result = NULL;
89246a0e 12882 static char buff [64];
5e2b0d47
NC
12883
12884 if (other == 0)
12885 return "";
12886
dda8d76d 12887 switch (filedata->file_header.e_machine)
5e2b0d47 12888 {
2057d69d
CZ
12889 case EM_ALPHA:
12890 result = get_alpha_symbol_other (other);
12891 break;
2301ed1c
SN
12892 case EM_AARCH64:
12893 result = get_aarch64_symbol_other (other);
12894 break;
5e2b0d47
NC
12895 case EM_MIPS:
12896 result = get_mips_symbol_other (other);
28f997cf
TG
12897 break;
12898 case EM_IA_64:
dda8d76d 12899 result = get_ia64_symbol_other (filedata, other);
28f997cf 12900 break;
6911b7dc
AM
12901 case EM_PPC64:
12902 result = get_ppc64_symbol_other (other);
12903 break;
8155b853
NC
12904 case EM_RISCV:
12905 result = get_riscv_symbol_other (other);
12906 break;
5e2b0d47 12907 default:
fd85a6a1 12908 result = NULL;
5e2b0d47
NC
12909 break;
12910 }
12911
12912 if (result)
12913 return result;
12914
12915 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12916 return buff;
12917}
12918
d1133906 12919static const char *
dda8d76d 12920get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12921{
b34976b6 12922 static char buff[32];
5cf1065c 12923
252b5132
RH
12924 switch (type)
12925 {
b34976b6
AM
12926 case SHN_UNDEF: return "UND";
12927 case SHN_ABS: return "ABS";
12928 case SHN_COMMON: return "COM";
252b5132 12929 default:
9ce701e2 12930 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12931 && filedata->file_header.e_machine == EM_IA_64
12932 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12933 return "ANSI_COM";
12934 else if ((filedata->file_header.e_machine == EM_X86_64
12935 || filedata->file_header.e_machine == EM_L1OM
12936 || filedata->file_header.e_machine == EM_K1OM)
12937 && type == SHN_X86_64_LCOMMON)
12938 return "LARGE_COM";
12939 else if ((type == SHN_MIPS_SCOMMON
12940 && filedata->file_header.e_machine == EM_MIPS)
12941 || (type == SHN_TIC6X_SCOMMON
12942 && filedata->file_header.e_machine == EM_TI_C6000))
12943 return "SCOM";
12944 else if (type == SHN_MIPS_SUNDEFINED
12945 && filedata->file_header.e_machine == EM_MIPS)
12946 return "SUND";
12947 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12948 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12949 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12950 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12951 else if (type >= SHN_LORESERVE)
12952 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12953 else if (filedata->file_header.e_shnum != 0
12954 && type >= filedata->file_header.e_shnum)
12955 sprintf (buff, _("bad section index[%3d]"), type);
12956 else
12957 sprintf (buff, "%3d", type);
12958 break;
fd85a6a1
NC
12959 }
12960
10ca4b04 12961 return buff;
6bd1a22c
L
12962}
12963
bb4d2ac2 12964static const char *
dda8d76d 12965get_symbol_version_string (Filedata * filedata,
015dc7e1 12966 bool is_dynsym,
1449284b
NC
12967 const char * strtab,
12968 unsigned long int strtab_size,
12969 unsigned int si,
12970 Elf_Internal_Sym * psym,
12971 enum versioned_symbol_info * sym_info,
12972 unsigned short * vna_other)
bb4d2ac2 12973{
ab273396
AM
12974 unsigned char data[2];
12975 unsigned short vers_data;
12976 unsigned long offset;
7a815dd5 12977 unsigned short max_vd_ndx;
bb4d2ac2 12978
ab273396 12979 if (!is_dynsym
978c4450 12980 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12981 return NULL;
bb4d2ac2 12982
978c4450
AM
12983 offset = offset_from_vma (filedata,
12984 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12985 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12986
dda8d76d 12987 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12988 sizeof (data), 1, _("version data")) == NULL)
12989 return NULL;
12990
12991 vers_data = byte_get (data, 2);
bb4d2ac2 12992
1f6f5dba 12993 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12994 return NULL;
bb4d2ac2 12995
0b8b7609 12996 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12997 max_vd_ndx = 0;
12998
ab273396
AM
12999 /* Usually we'd only see verdef for defined symbols, and verneed for
13000 undefined symbols. However, symbols defined by the linker in
13001 .dynbss for variables copied from a shared library in order to
13002 avoid text relocations are defined yet have verneed. We could
13003 use a heuristic to detect the special case, for example, check
13004 for verneed first on symbols defined in SHT_NOBITS sections, but
13005 it is simpler and more reliable to just look for both verdef and
13006 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13007
ab273396
AM
13008 if (psym->st_shndx != SHN_UNDEF
13009 && vers_data != 0x8001
978c4450 13010 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13011 {
13012 Elf_Internal_Verdef ivd;
13013 Elf_Internal_Verdaux ivda;
13014 Elf_External_Verdaux evda;
13015 unsigned long off;
bb4d2ac2 13016
dda8d76d 13017 off = offset_from_vma (filedata,
978c4450 13018 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13019 sizeof (Elf_External_Verdef));
13020
13021 do
bb4d2ac2 13022 {
ab273396
AM
13023 Elf_External_Verdef evd;
13024
dda8d76d 13025 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13026 _("version def")) == NULL)
13027 {
13028 ivd.vd_ndx = 0;
13029 ivd.vd_aux = 0;
13030 ivd.vd_next = 0;
1f6f5dba 13031 ivd.vd_flags = 0;
ab273396
AM
13032 }
13033 else
bb4d2ac2 13034 {
ab273396
AM
13035 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13036 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13037 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13038 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13039 }
bb4d2ac2 13040
7a815dd5
L
13041 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13042 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13043
ab273396
AM
13044 off += ivd.vd_next;
13045 }
13046 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13047
ab273396
AM
13048 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13049 {
9abca702 13050 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13051 return NULL;
13052
ab273396
AM
13053 off -= ivd.vd_next;
13054 off += ivd.vd_aux;
bb4d2ac2 13055
dda8d76d 13056 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13057 _("version def aux")) != NULL)
13058 {
13059 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13060
ab273396 13061 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13062 return (ivda.vda_name < strtab_size
13063 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13064 }
13065 }
13066 }
bb4d2ac2 13067
978c4450 13068 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13069 {
13070 Elf_External_Verneed evn;
13071 Elf_Internal_Verneed ivn;
13072 Elf_Internal_Vernaux ivna;
bb4d2ac2 13073
dda8d76d 13074 offset = offset_from_vma (filedata,
978c4450 13075 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13076 sizeof evn);
13077 do
13078 {
13079 unsigned long vna_off;
bb4d2ac2 13080
dda8d76d 13081 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13082 _("version need")) == NULL)
13083 {
13084 ivna.vna_next = 0;
13085 ivna.vna_other = 0;
13086 ivna.vna_name = 0;
13087 break;
13088 }
bb4d2ac2 13089
ab273396
AM
13090 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13091 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13092
ab273396 13093 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13094
ab273396
AM
13095 do
13096 {
13097 Elf_External_Vernaux evna;
bb4d2ac2 13098
dda8d76d 13099 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13100 _("version need aux (3)")) == NULL)
bb4d2ac2 13101 {
ab273396
AM
13102 ivna.vna_next = 0;
13103 ivna.vna_other = 0;
13104 ivna.vna_name = 0;
bb4d2ac2 13105 }
bb4d2ac2 13106 else
bb4d2ac2 13107 {
ab273396
AM
13108 ivna.vna_other = BYTE_GET (evna.vna_other);
13109 ivna.vna_next = BYTE_GET (evna.vna_next);
13110 ivna.vna_name = BYTE_GET (evna.vna_name);
13111 }
bb4d2ac2 13112
ab273396
AM
13113 vna_off += ivna.vna_next;
13114 }
13115 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13116
ab273396
AM
13117 if (ivna.vna_other == vers_data)
13118 break;
bb4d2ac2 13119
ab273396
AM
13120 offset += ivn.vn_next;
13121 }
13122 while (ivn.vn_next != 0);
bb4d2ac2 13123
ab273396
AM
13124 if (ivna.vna_other == vers_data)
13125 {
13126 *sym_info = symbol_undefined;
13127 *vna_other = ivna.vna_other;
13128 return (ivna.vna_name < strtab_size
13129 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13130 }
7a815dd5
L
13131 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13132 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13133 return _("<corrupt>");
bb4d2ac2 13134 }
ab273396 13135 return NULL;
bb4d2ac2
L
13136}
13137
047c3dbf
NL
13138/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13139
13140static unsigned int
13141print_dynamic_symbol_size (bfd_vma vma, int base)
13142{
13143 switch (base)
13144 {
13145 case 8:
13146 return print_vma (vma, OCTAL_5);
13147
13148 case 10:
13149 return print_vma (vma, UNSIGNED_5);
13150
13151 case 16:
13152 return print_vma (vma, PREFIX_HEX_5);
13153
13154 case 0:
13155 default:
13156 return print_vma (vma, DEC_5);
13157 }
13158}
13159
10ca4b04
L
13160static void
13161print_dynamic_symbol (Filedata *filedata, unsigned long si,
13162 Elf_Internal_Sym *symtab,
13163 Elf_Internal_Shdr *section,
13164 char *strtab, size_t strtab_size)
252b5132 13165{
10ca4b04
L
13166 const char *version_string;
13167 enum versioned_symbol_info sym_info;
13168 unsigned short vna_other;
23356397
NC
13169 bool is_valid;
13170 const char * sstr;
10ca4b04 13171 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13172
10ca4b04
L
13173 printf ("%6ld: ", si);
13174 print_vma (psym->st_value, LONG_HEX);
13175 putchar (' ');
047c3dbf 13176 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13177 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13178 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13179 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13180 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13181 else
252b5132 13182 {
10ca4b04 13183 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13184
10ca4b04
L
13185 printf (" %-7s", get_symbol_visibility (vis));
13186 /* Check to see if any other bits in the st_other field are set.
13187 Note - displaying this information disrupts the layout of the
13188 table being generated, but for the moment this case is very rare. */
13189 if (psym->st_other ^ vis)
13190 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13191 }
10ca4b04 13192 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13193
23356397
NC
13194 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13195 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13196 && filedata->section_headers != NULL
23356397
NC
13197 && psym->st_name == 0)
13198 {
84714f86
AM
13199 is_valid
13200 = section_name_valid (filedata,
13201 filedata->section_headers + psym->st_shndx);
23356397 13202 sstr = is_valid ?
84714f86
AM
13203 section_name_print (filedata,
13204 filedata->section_headers + psym->st_shndx)
23356397
NC
13205 : _("<corrupt>");
13206 }
13207 else
13208 {
84714f86 13209 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13210 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13211 }
10ca4b04
L
13212
13213 version_string
13214 = get_symbol_version_string (filedata,
13215 (section == NULL
13216 || section->sh_type == SHT_DYNSYM),
13217 strtab, strtab_size, si,
13218 psym, &sym_info, &vna_other);
b9e920ec 13219
0942c7ab
NC
13220 int len_avail = 21;
13221 if (! do_wide && version_string != NULL)
13222 {
ddb43bab 13223 char buffer[16];
0942c7ab 13224
ddb43bab 13225 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13226
13227 if (sym_info == symbol_undefined)
13228 len_avail -= sprintf (buffer," (%d)", vna_other);
13229 else if (sym_info != symbol_hidden)
13230 len_avail -= 1;
13231 }
13232
13233 print_symbol (len_avail, sstr);
b9e920ec 13234
10ca4b04
L
13235 if (version_string)
13236 {
13237 if (sym_info == symbol_undefined)
13238 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13239 else
10ca4b04
L
13240 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13241 version_string);
13242 }
6bd1a22c 13243
10ca4b04 13244 putchar ('\n');
6bd1a22c 13245
10ca4b04
L
13246 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13247 && section != NULL
13248 && si >= section->sh_info
13249 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13250 && filedata->file_header.e_machine != EM_MIPS
13251 /* Solaris binaries have been found to violate this requirement as
13252 well. Not sure if this is a bug or an ABI requirement. */
13253 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13254 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13255 si, printable_section_name (filedata, section), section->sh_info);
13256}
f16a9783 13257
0f03783c
NC
13258static const char *
13259get_lto_kind (unsigned int kind)
13260{
13261 switch (kind)
13262 {
13263 case 0: return "DEF";
13264 case 1: return "WEAKDEF";
13265 case 2: return "UNDEF";
13266 case 3: return "WEAKUNDEF";
13267 case 4: return "COMMON";
13268 default:
13269 break;
13270 }
13271
13272 static char buffer[30];
13273 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13274 sprintf (buffer, "<unknown: %u>", kind);
13275 return buffer;
13276}
13277
13278static const char *
13279get_lto_visibility (unsigned int visibility)
13280{
13281 switch (visibility)
13282 {
13283 case 0: return "DEFAULT";
13284 case 1: return "PROTECTED";
13285 case 2: return "INTERNAL";
13286 case 3: return "HIDDEN";
13287 default:
13288 break;
13289 }
13290
13291 static char buffer[30];
13292 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13293 sprintf (buffer, "<unknown: %u>", visibility);
13294 return buffer;
13295}
13296
13297static const char *
13298get_lto_sym_type (unsigned int sym_type)
13299{
13300 switch (sym_type)
13301 {
13302 case 0: return "UNKNOWN";
13303 case 1: return "FUNCTION";
13304 case 2: return "VARIABLE";
13305 default:
13306 break;
13307 }
13308
13309 static char buffer[30];
13310 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13311 sprintf (buffer, "<unknown: %u>", sym_type);
13312 return buffer;
13313}
13314
13315/* Display an LTO format symbol table.
13316 FIXME: The format of LTO symbol tables is not formalized.
13317 So this code could need changing in the future. */
13318
015dc7e1 13319static bool
0f03783c
NC
13320display_lto_symtab (Filedata * filedata,
13321 Elf_Internal_Shdr * section)
13322{
13323 if (section->sh_size == 0)
13324 {
ca0e11aa
NC
13325 if (filedata->is_separate)
13326 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13327 printable_section_name (filedata, section),
13328 filedata->file_name);
13329 else
13330 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13331 printable_section_name (filedata, section));
047c3dbf 13332
015dc7e1 13333 return true;
0f03783c
NC
13334 }
13335
13336 if (section->sh_size > filedata->file_size)
13337 {
13338 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13339 printable_section_name (filedata, section),
13340 (unsigned long) section->sh_size);
015dc7e1 13341 return false;
0f03783c
NC
13342 }
13343
13344 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13345 section->sh_size, 1, _("LTO symbols"));
13346 if (alloced_data == NULL)
015dc7e1 13347 return false;
0f03783c
NC
13348
13349 /* Look for extended data for the symbol table. */
13350 Elf_Internal_Shdr * ext;
13351 void * ext_data_orig = NULL;
13352 char * ext_data = NULL;
13353 char * ext_data_end = NULL;
13354 char * ext_name = NULL;
13355
13356 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13357 (section_name (filedata, section)
13358 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13359 && ext_name != NULL /* Paranoia. */
13360 && (ext = find_section (filedata, ext_name)) != NULL)
13361 {
13362 if (ext->sh_size < 3)
13363 error (_("LTO Symbol extension table '%s' is empty!\n"),
13364 printable_section_name (filedata, ext));
13365 else
13366 {
13367 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13368 ext->sh_size, 1,
13369 _("LTO ext symbol data"));
13370 if (ext_data != NULL)
13371 {
13372 ext_data_end = ext_data + ext->sh_size;
13373 if (* ext_data++ != 1)
13374 error (_("Unexpected version number in symbol extension table\n"));
13375 }
13376 }
13377 }
b9e920ec 13378
0f03783c
NC
13379 const unsigned char * data = (const unsigned char *) alloced_data;
13380 const unsigned char * end = data + section->sh_size;
13381
ca0e11aa
NC
13382 if (filedata->is_separate)
13383 printf (_("\nIn linked file '%s': "), filedata->file_name);
13384 else
13385 printf ("\n");
13386
0f03783c
NC
13387 if (ext_data_orig != NULL)
13388 {
13389 if (do_wide)
ca0e11aa 13390 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13391 printable_section_name (filedata, section),
13392 printable_section_name (filedata, ext));
13393 else
13394 {
ca0e11aa 13395 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13396 printable_section_name (filedata, section));
13397 printf (_(" and extension table '%s' contain:\n"),
13398 printable_section_name (filedata, ext));
13399 }
13400 }
13401 else
ca0e11aa 13402 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13403 printable_section_name (filedata, section));
b9e920ec 13404
0f03783c 13405 /* FIXME: Add a wide version. */
b9e920ec 13406 if (ext_data_orig != NULL)
0f03783c
NC
13407 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13408 else
13409 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13410
13411 /* FIXME: We do not handle style prefixes. */
13412
13413 while (data < end)
13414 {
13415 const unsigned char * sym_name = data;
13416 data += strnlen ((const char *) sym_name, end - data) + 1;
13417 if (data >= end)
13418 goto fail;
13419
13420 const unsigned char * comdat_key = data;
13421 data += strnlen ((const char *) comdat_key, end - data) + 1;
13422 if (data >= end)
13423 goto fail;
13424
13425 if (data + 2 + 8 + 4 > end)
13426 goto fail;
13427
13428 unsigned int kind = *data++;
13429 unsigned int visibility = *data++;
13430
13431 elf_vma size = byte_get (data, 8);
13432 data += 8;
13433
13434 elf_vma slot = byte_get (data, 4);
13435 data += 4;
13436
13437 if (ext_data != NULL)
13438 {
13439 if (ext_data < (ext_data_end - 1))
13440 {
13441 unsigned int sym_type = * ext_data ++;
13442 unsigned int sec_kind = * ext_data ++;
13443
13444 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13445 * comdat_key == 0 ? "-" : (char *) comdat_key,
13446 get_lto_kind (kind),
13447 get_lto_visibility (visibility),
13448 (long) size,
13449 (long) slot,
13450 get_lto_sym_type (sym_type),
13451 (long) sec_kind);
13452 print_symbol (6, (const char *) sym_name);
13453 }
13454 else
13455 {
13456 error (_("Ran out of LTO symbol extension data\n"));
13457 ext_data = NULL;
13458 /* FIXME: return FAIL result ? */
13459 }
13460 }
13461 else
13462 {
13463 printf (" %10s %10s %11s %08lx %08lx _",
13464 * comdat_key == 0 ? "-" : (char *) comdat_key,
13465 get_lto_kind (kind),
13466 get_lto_visibility (visibility),
13467 (long) size,
13468 (long) slot);
13469 print_symbol (21, (const char *) sym_name);
13470 }
13471 putchar ('\n');
13472 }
13473
13474 if (ext_data != NULL && ext_data < ext_data_end)
13475 {
13476 error (_("Data remains in the LTO symbol extension table\n"));
13477 goto fail;
13478 }
13479
13480 free (alloced_data);
13481 free (ext_data_orig);
13482 free (ext_name);
015dc7e1 13483 return true;
b9e920ec 13484
0f03783c
NC
13485 fail:
13486 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13487 free (alloced_data);
13488 free (ext_data_orig);
13489 free (ext_name);
015dc7e1 13490 return false;
0f03783c
NC
13491}
13492
13493/* Display LTO symbol tables. */
13494
015dc7e1 13495static bool
0f03783c
NC
13496process_lto_symbol_tables (Filedata * filedata)
13497{
13498 Elf_Internal_Shdr * section;
13499 unsigned int i;
015dc7e1 13500 bool res = true;
0f03783c
NC
13501
13502 if (!do_lto_syms)
015dc7e1 13503 return true;
0f03783c
NC
13504
13505 if (filedata->section_headers == NULL)
015dc7e1 13506 return true;
0f03783c
NC
13507
13508 for (i = 0, section = filedata->section_headers;
13509 i < filedata->file_header.e_shnum;
13510 i++, section++)
84714f86
AM
13511 if (section_name_valid (filedata, section)
13512 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13513 res &= display_lto_symtab (filedata, section);
13514
b9e920ec 13515 return res;
0f03783c
NC
13516}
13517
10ca4b04 13518/* Dump the symbol table. */
0f03783c 13519
015dc7e1 13520static bool
10ca4b04
L
13521process_symbol_table (Filedata * filedata)
13522{
13523 Elf_Internal_Shdr * section;
f16a9783 13524
10ca4b04 13525 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13526 return true;
6bd1a22c 13527
978c4450 13528 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13529 && do_syms
13530 && do_using_dynamic
978c4450
AM
13531 && filedata->dynamic_strings != NULL
13532 && filedata->dynamic_symbols != NULL)
6bd1a22c 13533 {
10ca4b04 13534 unsigned long si;
6bd1a22c 13535
ca0e11aa
NC
13536 if (filedata->is_separate)
13537 {
13538 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13539 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13540 filedata->num_dynamic_syms),
13541 filedata->file_name,
13542 filedata->num_dynamic_syms);
13543 }
13544 else
13545 {
13546 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13547 "\nSymbol table for image contains %lu entries:\n",
13548 filedata->num_dynamic_syms),
13549 filedata->num_dynamic_syms);
13550 }
10ca4b04
L
13551 if (is_32bit_elf)
13552 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13553 else
13554 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13555
978c4450
AM
13556 for (si = 0; si < filedata->num_dynamic_syms; si++)
13557 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13558 filedata->dynamic_strings,
13559 filedata->dynamic_strings_length);
252b5132 13560 }
8b73c356 13561 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13562 && filedata->section_headers != NULL)
252b5132 13563 {
b34976b6 13564 unsigned int i;
252b5132 13565
dda8d76d
NC
13566 for (i = 0, section = filedata->section_headers;
13567 i < filedata->file_header.e_shnum;
252b5132
RH
13568 i++, section++)
13569 {
2cf0635d 13570 char * strtab = NULL;
c256ffe7 13571 unsigned long int strtab_size = 0;
2cf0635d 13572 Elf_Internal_Sym * symtab;
ef3df110 13573 unsigned long si, num_syms;
252b5132 13574
2c610e4b
L
13575 if ((section->sh_type != SHT_SYMTAB
13576 && section->sh_type != SHT_DYNSYM)
13577 || (!do_syms
13578 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13579 continue;
13580
dd24e3da
NC
13581 if (section->sh_entsize == 0)
13582 {
13583 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13584 printable_section_name (filedata, section));
dd24e3da
NC
13585 continue;
13586 }
13587
d3a49aa8 13588 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13589
13590 if (filedata->is_separate)
13591 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13592 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13593 num_syms),
13594 filedata->file_name,
13595 printable_section_name (filedata, section),
13596 num_syms);
13597 else
13598 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13599 "\nSymbol table '%s' contains %lu entries:\n",
13600 num_syms),
13601 printable_section_name (filedata, section),
13602 num_syms);
dd24e3da 13603
f7a99963 13604 if (is_32bit_elf)
ca47b30c 13605 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13606 else
ca47b30c 13607 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13608
4de91c10 13609 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13610 if (symtab == NULL)
13611 continue;
13612
dda8d76d 13613 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13614 {
dda8d76d
NC
13615 strtab = filedata->string_table;
13616 strtab_size = filedata->string_table_length;
c256ffe7 13617 }
dda8d76d 13618 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13619 {
2cf0635d 13620 Elf_Internal_Shdr * string_sec;
252b5132 13621
dda8d76d 13622 string_sec = filedata->section_headers + section->sh_link;
252b5132 13623
dda8d76d 13624 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13625 1, string_sec->sh_size,
13626 _("string table"));
c256ffe7 13627 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13628 }
13629
10ca4b04
L
13630 for (si = 0; si < num_syms; si++)
13631 print_dynamic_symbol (filedata, si, symtab, section,
13632 strtab, strtab_size);
252b5132
RH
13633
13634 free (symtab);
dda8d76d 13635 if (strtab != filedata->string_table)
252b5132
RH
13636 free (strtab);
13637 }
13638 }
13639 else if (do_syms)
13640 printf
13641 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13642
978c4450 13643 if (do_histogram && filedata->buckets != NULL)
252b5132 13644 {
2cf0635d
NC
13645 unsigned long * lengths;
13646 unsigned long * counts;
66543521
AM
13647 unsigned long hn;
13648 bfd_vma si;
13649 unsigned long maxlength = 0;
13650 unsigned long nzero_counts = 0;
13651 unsigned long nsyms = 0;
6bd6a03d 13652 char *visited;
252b5132 13653
d3a49aa8
AM
13654 printf (ngettext ("\nHistogram for bucket list length "
13655 "(total of %lu bucket):\n",
13656 "\nHistogram for bucket list length "
13657 "(total of %lu buckets):\n",
978c4450
AM
13658 (unsigned long) filedata->nbuckets),
13659 (unsigned long) filedata->nbuckets);
252b5132 13660
978c4450
AM
13661 lengths = (unsigned long *) calloc (filedata->nbuckets,
13662 sizeof (*lengths));
252b5132
RH
13663 if (lengths == NULL)
13664 {
8b73c356 13665 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13666 goto err_out;
252b5132 13667 }
978c4450
AM
13668 visited = xcmalloc (filedata->nchains, 1);
13669 memset (visited, 0, filedata->nchains);
8b73c356
NC
13670
13671 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13672 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13673 {
978c4450 13674 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13675 {
b34976b6 13676 ++nsyms;
252b5132 13677 if (maxlength < ++lengths[hn])
b34976b6 13678 ++maxlength;
978c4450 13679 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13680 {
13681 error (_("histogram chain is corrupt\n"));
13682 break;
13683 }
13684 visited[si] = 1;
252b5132
RH
13685 }
13686 }
6bd6a03d 13687 free (visited);
252b5132 13688
3f5e193b 13689 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13690 if (counts == NULL)
13691 {
b2e951ec 13692 free (lengths);
8b73c356 13693 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13694 goto err_out;
252b5132
RH
13695 }
13696
978c4450 13697 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13698 ++counts[lengths[hn]];
252b5132 13699
978c4450 13700 if (filedata->nbuckets > 0)
252b5132 13701 {
66543521
AM
13702 unsigned long i;
13703 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13704 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13705 for (i = 1; i <= maxlength; ++i)
103f02d3 13706 {
66543521
AM
13707 nzero_counts += counts[i] * i;
13708 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13709 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13710 (nzero_counts * 100.0) / nsyms);
13711 }
252b5132
RH
13712 }
13713
13714 free (counts);
13715 free (lengths);
13716 }
13717
978c4450
AM
13718 free (filedata->buckets);
13719 filedata->buckets = NULL;
13720 filedata->nbuckets = 0;
13721 free (filedata->chains);
13722 filedata->chains = NULL;
252b5132 13723
978c4450 13724 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13725 {
2cf0635d
NC
13726 unsigned long * lengths;
13727 unsigned long * counts;
fdc90cb4
JJ
13728 unsigned long hn;
13729 unsigned long maxlength = 0;
13730 unsigned long nzero_counts = 0;
13731 unsigned long nsyms = 0;
fdc90cb4 13732
f16a9783 13733 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13734 "(total of %lu bucket):\n",
f16a9783 13735 "\nHistogram for `%s' bucket list length "
d3a49aa8 13736 "(total of %lu buckets):\n",
978c4450
AM
13737 (unsigned long) filedata->ngnubuckets),
13738 GNU_HASH_SECTION_NAME (filedata),
13739 (unsigned long) filedata->ngnubuckets);
8b73c356 13740
978c4450
AM
13741 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13742 sizeof (*lengths));
fdc90cb4
JJ
13743 if (lengths == NULL)
13744 {
8b73c356 13745 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13746 goto err_out;
fdc90cb4
JJ
13747 }
13748
fdc90cb4
JJ
13749 printf (_(" Length Number %% of total Coverage\n"));
13750
978c4450
AM
13751 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13752 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13753 {
13754 bfd_vma off, length = 1;
13755
978c4450 13756 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13757 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13758 off < filedata->ngnuchains
13759 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13760 ++off)
fdc90cb4
JJ
13761 ++length;
13762 lengths[hn] = length;
13763 if (length > maxlength)
13764 maxlength = length;
13765 nsyms += length;
13766 }
13767
3f5e193b 13768 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13769 if (counts == NULL)
13770 {
b2e951ec 13771 free (lengths);
8b73c356 13772 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13773 goto err_out;
fdc90cb4
JJ
13774 }
13775
978c4450 13776 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13777 ++counts[lengths[hn]];
13778
978c4450 13779 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13780 {
13781 unsigned long j;
13782 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13783 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13784 for (j = 1; j <= maxlength; ++j)
13785 {
13786 nzero_counts += counts[j] * j;
13787 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13788 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13789 (nzero_counts * 100.0) / nsyms);
13790 }
13791 }
13792
13793 free (counts);
13794 free (lengths);
fdc90cb4 13795 }
978c4450
AM
13796 free (filedata->gnubuckets);
13797 filedata->gnubuckets = NULL;
13798 filedata->ngnubuckets = 0;
13799 free (filedata->gnuchains);
13800 filedata->gnuchains = NULL;
13801 filedata->ngnuchains = 0;
13802 free (filedata->mipsxlat);
13803 filedata->mipsxlat = NULL;
015dc7e1 13804 return true;
fd486f32
AM
13805
13806 err_out:
978c4450
AM
13807 free (filedata->gnubuckets);
13808 filedata->gnubuckets = NULL;
13809 filedata->ngnubuckets = 0;
13810 free (filedata->gnuchains);
13811 filedata->gnuchains = NULL;
13812 filedata->ngnuchains = 0;
13813 free (filedata->mipsxlat);
13814 filedata->mipsxlat = NULL;
13815 free (filedata->buckets);
13816 filedata->buckets = NULL;
13817 filedata->nbuckets = 0;
13818 free (filedata->chains);
13819 filedata->chains = NULL;
015dc7e1 13820 return false;
252b5132
RH
13821}
13822
015dc7e1 13823static bool
ca0e11aa 13824process_syminfo (Filedata * filedata)
252b5132 13825{
b4c96d0d 13826 unsigned int i;
252b5132 13827
978c4450 13828 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13829 || !do_dynamic)
13830 /* No syminfo, this is ok. */
015dc7e1 13831 return true;
252b5132
RH
13832
13833 /* There better should be a dynamic symbol section. */
978c4450 13834 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13835 return false;
252b5132 13836
ca0e11aa
NC
13837 if (filedata->is_separate)
13838 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13839 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13840 filedata->dynamic_syminfo_nent),
13841 filedata->file_name,
13842 filedata->dynamic_syminfo_offset,
13843 filedata->dynamic_syminfo_nent);
13844 else
d3a49aa8
AM
13845 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13846 "contains %d entry:\n",
13847 "\nDynamic info segment at offset 0x%lx "
13848 "contains %d entries:\n",
978c4450 13849 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13850 filedata->dynamic_syminfo_offset,
13851 filedata->dynamic_syminfo_nent);
252b5132
RH
13852
13853 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13854 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13855 {
978c4450 13856 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13857
31104126 13858 printf ("%4d: ", i);
978c4450 13859 if (i >= filedata->num_dynamic_syms)
4082ef84 13860 printf (_("<corrupt index>"));
84714f86
AM
13861 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13862 print_symbol (30, get_dynamic_name (filedata,
978c4450 13863 filedata->dynamic_symbols[i].st_name));
d79b3d50 13864 else
978c4450 13865 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13866 putchar (' ');
252b5132 13867
978c4450 13868 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13869 {
13870 case SYMINFO_BT_SELF:
13871 fputs ("SELF ", stdout);
13872 break;
13873 case SYMINFO_BT_PARENT:
13874 fputs ("PARENT ", stdout);
13875 break;
13876 default:
978c4450
AM
13877 if (filedata->dynamic_syminfo[i].si_boundto > 0
13878 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13879 && valid_dynamic_name (filedata,
978c4450 13880 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13881 {
84714f86 13882 print_symbol (10, get_dynamic_name (filedata,
978c4450 13883 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13884 putchar (' ' );
13885 }
252b5132 13886 else
978c4450 13887 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13888 break;
13889 }
13890
13891 if (flags & SYMINFO_FLG_DIRECT)
13892 printf (" DIRECT");
13893 if (flags & SYMINFO_FLG_PASSTHRU)
13894 printf (" PASSTHRU");
13895 if (flags & SYMINFO_FLG_COPY)
13896 printf (" COPY");
13897 if (flags & SYMINFO_FLG_LAZYLOAD)
13898 printf (" LAZYLOAD");
13899
13900 puts ("");
13901 }
13902
015dc7e1 13903 return true;
252b5132
RH
13904}
13905
75802ccb
CE
13906/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13907 is contained by the region START .. END. The types of ADDR, START
13908 and END should all be the same. Note both ADDR + NELEM and END
13909 point to just beyond the end of the regions that are being tested. */
13910#define IN_RANGE(START,END,ADDR,NELEM) \
13911 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13912
cf13d699
NC
13913/* Check to see if the given reloc needs to be handled in a target specific
13914 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13915 FALSE.
13916
13917 If called with reloc == NULL, then this is a signal that reloc processing
13918 for the current section has finished, and any saved state should be
13919 discarded. */
09c11c86 13920
015dc7e1 13921static bool
dda8d76d
NC
13922target_specific_reloc_handling (Filedata * filedata,
13923 Elf_Internal_Rela * reloc,
13924 unsigned char * start,
13925 unsigned char * end,
13926 Elf_Internal_Sym * symtab,
13927 unsigned long num_syms)
252b5132 13928{
f84ce13b
NC
13929 unsigned int reloc_type = 0;
13930 unsigned long sym_index = 0;
13931
13932 if (reloc)
13933 {
dda8d76d 13934 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13935 sym_index = get_reloc_symindex (reloc->r_info);
13936 }
252b5132 13937
dda8d76d 13938 switch (filedata->file_header.e_machine)
252b5132 13939 {
13761a11
NC
13940 case EM_MSP430:
13941 case EM_MSP430_OLD:
13942 {
13943 static Elf_Internal_Sym * saved_sym = NULL;
13944
f84ce13b
NC
13945 if (reloc == NULL)
13946 {
13947 saved_sym = NULL;
015dc7e1 13948 return true;
f84ce13b
NC
13949 }
13950
13761a11
NC
13951 switch (reloc_type)
13952 {
13953 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13954 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13955 if (uses_msp430x_relocs (filedata))
13761a11 13956 break;
1a0670f3 13957 /* Fall through. */
13761a11 13958 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13959 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13960 /* PR 21139. */
13961 if (sym_index >= num_syms)
13962 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13963 sym_index);
13964 else
13965 saved_sym = symtab + sym_index;
015dc7e1 13966 return true;
13761a11
NC
13967
13968 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13969 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13970 goto handle_sym_diff;
0b4362b0 13971
13761a11
NC
13972 case 5: /* R_MSP430_16_BYTE */
13973 case 9: /* R_MSP430_8 */
7d81bc93 13974 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13975 if (uses_msp430x_relocs (filedata))
13761a11
NC
13976 break;
13977 goto handle_sym_diff;
13978
13979 case 2: /* R_MSP430_ABS16 */
13980 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13981 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13982 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13983 break;
13984 goto handle_sym_diff;
0b4362b0 13985
13761a11
NC
13986 handle_sym_diff:
13987 if (saved_sym != NULL)
13988 {
13989 bfd_vma value;
5a805384 13990 unsigned int reloc_size = 0;
7d81bc93
JL
13991 int leb_ret = 0;
13992 switch (reloc_type)
13993 {
13994 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13995 reloc_size = 4;
13996 break;
13997 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13998 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13999 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14000 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14001 &reloc_size, &leb_ret);
7d81bc93
JL
14002 break;
14003 default:
14004 reloc_size = 2;
14005 break;
14006 }
13761a11 14007
5a805384 14008 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
14009 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
14010 "ULEB128 value\n"),
14011 (long) reloc->r_offset);
14012 else if (sym_index >= num_syms)
f84ce13b
NC
14013 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
14014 sym_index);
03f7786e 14015 else
f84ce13b
NC
14016 {
14017 value = reloc->r_addend + (symtab[sym_index].st_value
14018 - saved_sym->st_value);
14019
b32e566b 14020 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14021 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14022 else
14023 /* PR 21137 */
14024 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14025 (long) reloc->r_offset);
f84ce13b 14026 }
13761a11
NC
14027
14028 saved_sym = NULL;
015dc7e1 14029 return true;
13761a11
NC
14030 }
14031 break;
14032
14033 default:
14034 if (saved_sym != NULL)
071436c6 14035 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14036 break;
14037 }
14038 break;
14039 }
14040
cf13d699
NC
14041 case EM_MN10300:
14042 case EM_CYGNUS_MN10300:
14043 {
14044 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14045
f84ce13b
NC
14046 if (reloc == NULL)
14047 {
14048 saved_sym = NULL;
015dc7e1 14049 return true;
f84ce13b
NC
14050 }
14051
cf13d699
NC
14052 switch (reloc_type)
14053 {
14054 case 34: /* R_MN10300_ALIGN */
015dc7e1 14055 return true;
cf13d699 14056 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14057 if (sym_index >= num_syms)
14058 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14059 sym_index);
14060 else
14061 saved_sym = symtab + sym_index;
015dc7e1 14062 return true;
f84ce13b 14063
cf13d699
NC
14064 case 1: /* R_MN10300_32 */
14065 case 2: /* R_MN10300_16 */
14066 if (saved_sym != NULL)
14067 {
03f7786e 14068 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 14069 bfd_vma value;
252b5132 14070
f84ce13b
NC
14071 if (sym_index >= num_syms)
14072 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14073 sym_index);
03f7786e 14074 else
f84ce13b
NC
14075 {
14076 value = reloc->r_addend + (symtab[sym_index].st_value
14077 - saved_sym->st_value);
14078
b32e566b 14079 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14080 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14081 else
14082 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14083 (long) reloc->r_offset);
f84ce13b 14084 }
252b5132 14085
cf13d699 14086 saved_sym = NULL;
015dc7e1 14087 return true;
cf13d699
NC
14088 }
14089 break;
14090 default:
14091 if (saved_sym != NULL)
071436c6 14092 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14093 break;
14094 }
14095 break;
14096 }
6ff71e76
NC
14097
14098 case EM_RL78:
14099 {
14100 static bfd_vma saved_sym1 = 0;
14101 static bfd_vma saved_sym2 = 0;
14102 static bfd_vma value;
14103
f84ce13b
NC
14104 if (reloc == NULL)
14105 {
14106 saved_sym1 = saved_sym2 = 0;
015dc7e1 14107 return true;
f84ce13b
NC
14108 }
14109
6ff71e76
NC
14110 switch (reloc_type)
14111 {
14112 case 0x80: /* R_RL78_SYM. */
14113 saved_sym1 = saved_sym2;
f84ce13b
NC
14114 if (sym_index >= num_syms)
14115 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14116 sym_index);
14117 else
14118 {
14119 saved_sym2 = symtab[sym_index].st_value;
14120 saved_sym2 += reloc->r_addend;
14121 }
015dc7e1 14122 return true;
6ff71e76
NC
14123
14124 case 0x83: /* R_RL78_OPsub. */
14125 value = saved_sym1 - saved_sym2;
14126 saved_sym2 = saved_sym1 = 0;
015dc7e1 14127 return true;
6ff71e76
NC
14128 break;
14129
14130 case 0x41: /* R_RL78_ABS32. */
b32e566b 14131 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14132 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14133 else
14134 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14135 (long) reloc->r_offset);
6ff71e76 14136 value = 0;
015dc7e1 14137 return true;
6ff71e76
NC
14138
14139 case 0x43: /* R_RL78_ABS16. */
b32e566b 14140 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14141 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14142 else
14143 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14144 (long) reloc->r_offset);
6ff71e76 14145 value = 0;
015dc7e1 14146 return true;
6ff71e76
NC
14147
14148 default:
14149 break;
14150 }
14151 break;
14152 }
252b5132
RH
14153 }
14154
015dc7e1 14155 return false;
252b5132
RH
14156}
14157
aca88567
NC
14158/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14159 DWARF debug sections. This is a target specific test. Note - we do not
14160 go through the whole including-target-headers-multiple-times route, (as
14161 we have already done with <elf/h8.h>) because this would become very
14162 messy and even then this function would have to contain target specific
14163 information (the names of the relocs instead of their numeric values).
14164 FIXME: This is not the correct way to solve this problem. The proper way
14165 is to have target specific reloc sizing and typing functions created by
14166 the reloc-macros.h header, in the same way that it already creates the
14167 reloc naming functions. */
14168
015dc7e1 14169static bool
dda8d76d 14170is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14171{
d347c9df 14172 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14173 switch (filedata->file_header.e_machine)
aca88567 14174 {
41e92641 14175 case EM_386:
22abe556 14176 case EM_IAMCU:
41e92641 14177 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14178 case EM_68K:
14179 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14180 case EM_860:
14181 return reloc_type == 1; /* R_860_32. */
14182 case EM_960:
14183 return reloc_type == 2; /* R_960_32. */
a06ea964 14184 case EM_AARCH64:
9282b95a
JW
14185 return (reloc_type == 258
14186 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14187 case EM_BPF:
14188 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14189 case EM_ADAPTEVA_EPIPHANY:
14190 return reloc_type == 3;
aca88567 14191 case EM_ALPHA:
137b6b5f 14192 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14193 case EM_ARC:
14194 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14195 case EM_ARC_COMPACT:
14196 case EM_ARC_COMPACT2:
14197 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14198 case EM_ARM:
14199 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14200 case EM_AVR_OLD:
aca88567
NC
14201 case EM_AVR:
14202 return reloc_type == 1;
14203 case EM_BLACKFIN:
14204 return reloc_type == 0x12; /* R_byte4_data. */
14205 case EM_CRIS:
14206 return reloc_type == 3; /* R_CRIS_32. */
14207 case EM_CR16:
14208 return reloc_type == 3; /* R_CR16_NUM32. */
14209 case EM_CRX:
14210 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14211 case EM_CSKY:
14212 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14213 case EM_CYGNUS_FRV:
14214 return reloc_type == 1;
41e92641
NC
14215 case EM_CYGNUS_D10V:
14216 case EM_D10V:
14217 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14218 case EM_CYGNUS_D30V:
14219 case EM_D30V:
14220 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14221 case EM_DLX:
14222 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14223 case EM_CYGNUS_FR30:
14224 case EM_FR30:
14225 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14226 case EM_FT32:
14227 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14228 case EM_H8S:
14229 case EM_H8_300:
14230 case EM_H8_300H:
14231 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14232 case EM_IA_64:
262cdac7
AM
14233 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14234 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14235 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14236 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14237 case EM_IP2K_OLD:
14238 case EM_IP2K:
14239 return reloc_type == 2; /* R_IP2K_32. */
14240 case EM_IQ2000:
14241 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14242 case EM_LATTICEMICO32:
14243 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14244 case EM_LOONGARCH:
14245 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14246 case EM_M32C_OLD:
aca88567
NC
14247 case EM_M32C:
14248 return reloc_type == 3; /* R_M32C_32. */
14249 case EM_M32R:
14250 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14251 case EM_68HC11:
14252 case EM_68HC12:
14253 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14254 case EM_S12Z:
2849d19f
JD
14255 return reloc_type == 7 || /* R_S12Z_EXT32 */
14256 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14257 case EM_MCORE:
14258 return reloc_type == 1; /* R_MCORE_ADDR32. */
14259 case EM_CYGNUS_MEP:
14260 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14261 case EM_METAG:
14262 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14263 case EM_MICROBLAZE:
14264 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14265 case EM_MIPS:
14266 return reloc_type == 2; /* R_MIPS_32. */
14267 case EM_MMIX:
14268 return reloc_type == 4; /* R_MMIX_32. */
14269 case EM_CYGNUS_MN10200:
14270 case EM_MN10200:
14271 return reloc_type == 1; /* R_MN10200_32. */
14272 case EM_CYGNUS_MN10300:
14273 case EM_MN10300:
14274 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14275 case EM_MOXIE:
14276 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14277 case EM_MSP430_OLD:
14278 case EM_MSP430:
13761a11 14279 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14280 case EM_MT:
14281 return reloc_type == 2; /* R_MT_32. */
35c08157 14282 case EM_NDS32:
81c5e376 14283 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14284 case EM_ALTERA_NIOS2:
36591ba1 14285 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14286 case EM_NIOS32:
14287 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14288 case EM_OR1K:
14289 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14290 case EM_PARISC:
9abca702 14291 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14292 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14293 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14294 case EM_PJ:
14295 case EM_PJ_OLD:
14296 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14297 case EM_PPC64:
14298 return reloc_type == 1; /* R_PPC64_ADDR32. */
14299 case EM_PPC:
14300 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14301 case EM_TI_PRU:
14302 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14303 case EM_RISCV:
14304 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14305 case EM_RL78:
14306 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14307 case EM_RX:
14308 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14309 case EM_S370:
14310 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14311 case EM_S390_OLD:
14312 case EM_S390:
14313 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14314 case EM_SCORE:
14315 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14316 case EM_SH:
14317 return reloc_type == 1; /* R_SH_DIR32. */
14318 case EM_SPARC32PLUS:
14319 case EM_SPARCV9:
14320 case EM_SPARC:
14321 return reloc_type == 3 /* R_SPARC_32. */
14322 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14323 case EM_SPU:
14324 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14325 case EM_TI_C6000:
14326 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14327 case EM_TILEGX:
14328 return reloc_type == 2; /* R_TILEGX_32. */
14329 case EM_TILEPRO:
14330 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14331 case EM_CYGNUS_V850:
14332 case EM_V850:
14333 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14334 case EM_V800:
14335 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14336 case EM_VAX:
14337 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14338 case EM_VISIUM:
14339 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14340 case EM_WEBASSEMBLY:
14341 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14342 case EM_X86_64:
8a9036a4 14343 case EM_L1OM:
7a9068fe 14344 case EM_K1OM:
aca88567 14345 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14346 case EM_XC16X:
14347 case EM_C166:
14348 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14349 case EM_XGATE:
14350 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14351 case EM_XSTORMY16:
14352 return reloc_type == 1; /* R_XSTROMY16_32. */
14353 case EM_XTENSA_OLD:
14354 case EM_XTENSA:
14355 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14356 case EM_Z80:
14357 return reloc_type == 6; /* R_Z80_32. */
aca88567 14358 default:
bee0ee85
NC
14359 {
14360 static unsigned int prev_warn = 0;
14361
14362 /* Avoid repeating the same warning multiple times. */
dda8d76d 14363 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14364 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14365 filedata->file_header.e_machine);
14366 prev_warn = filedata->file_header.e_machine;
015dc7e1 14367 return false;
bee0ee85 14368 }
aca88567
NC
14369 }
14370}
14371
14372/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14373 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14374
015dc7e1 14375static bool
dda8d76d 14376is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14377{
dda8d76d 14378 switch (filedata->file_header.e_machine)
d347c9df 14379 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14380 {
41e92641 14381 case EM_386:
22abe556 14382 case EM_IAMCU:
3e0873ac 14383 return reloc_type == 2; /* R_386_PC32. */
aca88567 14384 case EM_68K:
3e0873ac 14385 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14386 case EM_AARCH64:
14387 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14388 case EM_ADAPTEVA_EPIPHANY:
14389 return reloc_type == 6;
aca88567
NC
14390 case EM_ALPHA:
14391 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14392 case EM_ARC_COMPACT:
14393 case EM_ARC_COMPACT2:
14394 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14395 case EM_ARM:
3e0873ac 14396 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14397 case EM_AVR_OLD:
14398 case EM_AVR:
14399 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14400 case EM_MICROBLAZE:
14401 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14402 case EM_OR1K:
14403 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14404 case EM_PARISC:
85acf597 14405 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14406 case EM_PPC:
14407 return reloc_type == 26; /* R_PPC_REL32. */
14408 case EM_PPC64:
3e0873ac 14409 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14410 case EM_RISCV:
14411 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14412 case EM_S390_OLD:
14413 case EM_S390:
3e0873ac 14414 return reloc_type == 5; /* R_390_PC32. */
aca88567 14415 case EM_SH:
3e0873ac 14416 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14417 case EM_SPARC32PLUS:
14418 case EM_SPARCV9:
14419 case EM_SPARC:
3e0873ac 14420 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14421 case EM_SPU:
14422 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14423 case EM_TILEGX:
14424 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14425 case EM_TILEPRO:
14426 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14427 case EM_VISIUM:
14428 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14429 case EM_X86_64:
8a9036a4 14430 case EM_L1OM:
7a9068fe 14431 case EM_K1OM:
3e0873ac 14432 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14433 case EM_VAX:
14434 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14435 case EM_XTENSA_OLD:
14436 case EM_XTENSA:
14437 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14438 default:
14439 /* Do not abort or issue an error message here. Not all targets use
14440 pc-relative 32-bit relocs in their DWARF debug information and we
14441 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14442 more helpful warning message will be generated by apply_relocations
14443 anyway, so just return. */
015dc7e1 14444 return false;
aca88567
NC
14445 }
14446}
14447
14448/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14449 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14450
015dc7e1 14451static bool
dda8d76d 14452is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14453{
dda8d76d 14454 switch (filedata->file_header.e_machine)
aca88567 14455 {
a06ea964
NC
14456 case EM_AARCH64:
14457 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14458 case EM_ALPHA:
14459 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14460 case EM_IA_64:
262cdac7
AM
14461 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14462 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14463 case EM_LOONGARCH:
14464 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14465 case EM_PARISC:
14466 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14467 case EM_PPC64:
14468 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14469 case EM_RISCV:
14470 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14471 case EM_SPARC32PLUS:
14472 case EM_SPARCV9:
14473 case EM_SPARC:
714da62f
NC
14474 return reloc_type == 32 /* R_SPARC_64. */
14475 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14476 case EM_X86_64:
8a9036a4 14477 case EM_L1OM:
7a9068fe 14478 case EM_K1OM:
aca88567 14479 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14480 case EM_S390_OLD:
14481 case EM_S390:
aa137e4d
NC
14482 return reloc_type == 22; /* R_S390_64. */
14483 case EM_TILEGX:
14484 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14485 case EM_MIPS:
aa137e4d 14486 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14487 default:
015dc7e1 14488 return false;
aca88567
NC
14489 }
14490}
14491
85acf597
RH
14492/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14493 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14494
015dc7e1 14495static bool
dda8d76d 14496is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14497{
dda8d76d 14498 switch (filedata->file_header.e_machine)
85acf597 14499 {
a06ea964
NC
14500 case EM_AARCH64:
14501 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14502 case EM_ALPHA:
aa137e4d 14503 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14504 case EM_IA_64:
262cdac7
AM
14505 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14506 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14507 case EM_PARISC:
aa137e4d 14508 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14509 case EM_PPC64:
aa137e4d 14510 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14511 case EM_SPARC32PLUS:
14512 case EM_SPARCV9:
14513 case EM_SPARC:
aa137e4d 14514 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14515 case EM_X86_64:
8a9036a4 14516 case EM_L1OM:
7a9068fe 14517 case EM_K1OM:
aa137e4d 14518 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14519 case EM_S390_OLD:
14520 case EM_S390:
aa137e4d
NC
14521 return reloc_type == 23; /* R_S390_PC64. */
14522 case EM_TILEGX:
14523 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14524 default:
015dc7e1 14525 return false;
85acf597
RH
14526 }
14527}
14528
4dc3c23d
AM
14529/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14530 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14531
015dc7e1 14532static bool
dda8d76d 14533is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14534{
dda8d76d 14535 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14536 {
14537 case EM_CYGNUS_MN10200:
14538 case EM_MN10200:
14539 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14540 case EM_FT32:
14541 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14542 case EM_Z80:
14543 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14544 default:
015dc7e1 14545 return false;
4dc3c23d
AM
14546 }
14547}
14548
aca88567
NC
14549/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14550 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14551
015dc7e1 14552static bool
dda8d76d 14553is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14554{
d347c9df 14555 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14556 switch (filedata->file_header.e_machine)
4b78141a 14557 {
886a2506
NC
14558 case EM_ARC:
14559 case EM_ARC_COMPACT:
14560 case EM_ARC_COMPACT2:
14561 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14562 case EM_ADAPTEVA_EPIPHANY:
14563 return reloc_type == 5;
aca88567
NC
14564 case EM_AVR_OLD:
14565 case EM_AVR:
14566 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14567 case EM_CYGNUS_D10V:
14568 case EM_D10V:
14569 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14570 case EM_FT32:
14571 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14572 case EM_H8S:
14573 case EM_H8_300:
14574 case EM_H8_300H:
aca88567
NC
14575 return reloc_type == R_H8_DIR16;
14576 case EM_IP2K_OLD:
14577 case EM_IP2K:
14578 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14579 case EM_M32C_OLD:
f4236fe4
DD
14580 case EM_M32C:
14581 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14582 case EM_CYGNUS_MN10200:
14583 case EM_MN10200:
14584 return reloc_type == 2; /* R_MN10200_16. */
14585 case EM_CYGNUS_MN10300:
14586 case EM_MN10300:
14587 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14588 case EM_MSP430:
dda8d76d 14589 if (uses_msp430x_relocs (filedata))
13761a11 14590 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14591 /* Fall through. */
78c8d46c 14592 case EM_MSP430_OLD:
aca88567 14593 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14594 case EM_NDS32:
81c5e376 14595 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14596 case EM_ALTERA_NIOS2:
36591ba1 14597 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14598 case EM_NIOS32:
14599 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14600 case EM_OR1K:
14601 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14602 case EM_RISCV:
14603 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14604 case EM_TI_PRU:
14605 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14606 case EM_TI_C6000:
14607 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14608 case EM_VISIUM:
14609 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14610 case EM_XC16X:
14611 case EM_C166:
14612 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14613 case EM_XGATE:
14614 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14615 case EM_Z80:
14616 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14617 default:
015dc7e1 14618 return false;
4b78141a
NC
14619 }
14620}
14621
39e07931
AS
14622/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14623 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14624
015dc7e1 14625static bool
39e07931
AS
14626is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14627{
14628 switch (filedata->file_header.e_machine)
14629 {
14630 case EM_RISCV:
14631 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14632 case EM_Z80:
14633 return reloc_type == 1; /* R_Z80_8. */
39e07931 14634 default:
015dc7e1 14635 return false;
39e07931
AS
14636 }
14637}
14638
14639/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14640 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14641
015dc7e1 14642static bool
39e07931
AS
14643is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14644{
14645 switch (filedata->file_header.e_machine)
14646 {
14647 case EM_RISCV:
14648 return reloc_type == 53; /* R_RISCV_SET6. */
14649 default:
015dc7e1 14650 return false;
39e07931
AS
14651 }
14652}
14653
03336641
JW
14654/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14655 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14656
015dc7e1 14657static bool
03336641
JW
14658is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14659{
14660 /* Please keep this table alpha-sorted for ease of visual lookup. */
14661 switch (filedata->file_header.e_machine)
14662 {
14663 case EM_RISCV:
14664 return reloc_type == 35; /* R_RISCV_ADD32. */
14665 default:
015dc7e1 14666 return false;
03336641
JW
14667 }
14668}
14669
14670/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14671 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14672
015dc7e1 14673static bool
03336641
JW
14674is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14675{
14676 /* Please keep this table alpha-sorted for ease of visual lookup. */
14677 switch (filedata->file_header.e_machine)
14678 {
14679 case EM_RISCV:
14680 return reloc_type == 39; /* R_RISCV_SUB32. */
14681 default:
015dc7e1 14682 return false;
03336641
JW
14683 }
14684}
14685
14686/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14687 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14688
015dc7e1 14689static bool
03336641
JW
14690is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14691{
14692 /* Please keep this table alpha-sorted for ease of visual lookup. */
14693 switch (filedata->file_header.e_machine)
14694 {
14695 case EM_RISCV:
14696 return reloc_type == 36; /* R_RISCV_ADD64. */
14697 default:
015dc7e1 14698 return false;
03336641
JW
14699 }
14700}
14701
14702/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14703 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14704
015dc7e1 14705static bool
03336641
JW
14706is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14707{
14708 /* Please keep this table alpha-sorted for ease of visual lookup. */
14709 switch (filedata->file_header.e_machine)
14710 {
14711 case EM_RISCV:
14712 return reloc_type == 40; /* R_RISCV_SUB64. */
14713 default:
015dc7e1 14714 return false;
03336641
JW
14715 }
14716}
14717
14718/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14719 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14720
015dc7e1 14721static bool
03336641
JW
14722is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14723{
14724 /* Please keep this table alpha-sorted for ease of visual lookup. */
14725 switch (filedata->file_header.e_machine)
14726 {
14727 case EM_RISCV:
14728 return reloc_type == 34; /* R_RISCV_ADD16. */
14729 default:
015dc7e1 14730 return false;
03336641
JW
14731 }
14732}
14733
14734/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14735 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14736
015dc7e1 14737static bool
03336641
JW
14738is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14739{
14740 /* Please keep this table alpha-sorted for ease of visual lookup. */
14741 switch (filedata->file_header.e_machine)
14742 {
14743 case EM_RISCV:
14744 return reloc_type == 38; /* R_RISCV_SUB16. */
14745 default:
015dc7e1 14746 return false;
03336641
JW
14747 }
14748}
14749
14750/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14751 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14752
015dc7e1 14753static bool
03336641
JW
14754is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14755{
14756 /* Please keep this table alpha-sorted for ease of visual lookup. */
14757 switch (filedata->file_header.e_machine)
14758 {
14759 case EM_RISCV:
14760 return reloc_type == 33; /* R_RISCV_ADD8. */
14761 default:
015dc7e1 14762 return false;
03336641
JW
14763 }
14764}
14765
14766/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14767 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14768
015dc7e1 14769static bool
03336641
JW
14770is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14771{
14772 /* Please keep this table alpha-sorted for ease of visual lookup. */
14773 switch (filedata->file_header.e_machine)
14774 {
14775 case EM_RISCV:
14776 return reloc_type == 37; /* R_RISCV_SUB8. */
14777 default:
015dc7e1 14778 return false;
03336641
JW
14779 }
14780}
14781
39e07931
AS
14782/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14783 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14784
015dc7e1 14785static bool
39e07931
AS
14786is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14787{
14788 switch (filedata->file_header.e_machine)
14789 {
14790 case EM_RISCV:
14791 return reloc_type == 52; /* R_RISCV_SUB6. */
14792 default:
015dc7e1 14793 return false;
39e07931
AS
14794 }
14795}
14796
2a7b2e88
JK
14797/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14798 relocation entries (possibly formerly used for SHT_GROUP sections). */
14799
015dc7e1 14800static bool
dda8d76d 14801is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14802{
dda8d76d 14803 switch (filedata->file_header.e_machine)
2a7b2e88 14804 {
cb8f3167 14805 case EM_386: /* R_386_NONE. */
d347c9df 14806 case EM_68K: /* R_68K_NONE. */
cfb8c092 14807 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14808 case EM_ALPHA: /* R_ALPHA_NONE. */
14809 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14810 case EM_ARC: /* R_ARC_NONE. */
886a2506 14811 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14812 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14813 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14814 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14815 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14816 case EM_FT32: /* R_FT32_NONE. */
14817 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14818 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14819 case EM_L1OM: /* R_X86_64_NONE. */
14820 case EM_M32R: /* R_M32R_NONE. */
14821 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14822 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14823 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14824 case EM_NIOS32: /* R_NIOS_NONE. */
14825 case EM_OR1K: /* R_OR1K_NONE. */
14826 case EM_PARISC: /* R_PARISC_NONE. */
14827 case EM_PPC64: /* R_PPC64_NONE. */
14828 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14829 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14830 case EM_S390: /* R_390_NONE. */
14831 case EM_S390_OLD:
14832 case EM_SH: /* R_SH_NONE. */
14833 case EM_SPARC32PLUS:
14834 case EM_SPARC: /* R_SPARC_NONE. */
14835 case EM_SPARCV9:
aa137e4d
NC
14836 case EM_TILEGX: /* R_TILEGX_NONE. */
14837 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14838 case EM_TI_C6000:/* R_C6000_NONE. */
14839 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14840 case EM_XC16X:
6655dba2 14841 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14842 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14843 return reloc_type == 0;
d347c9df 14844
a06ea964
NC
14845 case EM_AARCH64:
14846 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14847 case EM_AVR_OLD:
14848 case EM_AVR:
14849 return (reloc_type == 0 /* R_AVR_NONE. */
14850 || reloc_type == 30 /* R_AVR_DIFF8. */
14851 || reloc_type == 31 /* R_AVR_DIFF16. */
14852 || reloc_type == 32 /* R_AVR_DIFF32. */);
14853 case EM_METAG:
14854 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14855 case EM_NDS32:
81c5e376
AM
14856 return (reloc_type == 0 /* R_NDS32_NONE. */
14857 || reloc_type == 205 /* R_NDS32_DIFF8. */
14858 || reloc_type == 206 /* R_NDS32_DIFF16. */
14859 || reloc_type == 207 /* R_NDS32_DIFF32. */
14860 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14861 case EM_TI_PRU:
14862 return (reloc_type == 0 /* R_PRU_NONE. */
14863 || reloc_type == 65 /* R_PRU_DIFF8. */
14864 || reloc_type == 66 /* R_PRU_DIFF16. */
14865 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14866 case EM_XTENSA_OLD:
14867 case EM_XTENSA:
4dc3c23d
AM
14868 return (reloc_type == 0 /* R_XTENSA_NONE. */
14869 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14870 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14871 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14872 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14873 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14874 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14875 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14876 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14877 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14878 }
015dc7e1 14879 return false;
2a7b2e88
JK
14880}
14881
d1c4b12b
NC
14882/* Returns TRUE if there is a relocation against
14883 section NAME at OFFSET bytes. */
14884
015dc7e1 14885bool
d1c4b12b
NC
14886reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14887{
14888 Elf_Internal_Rela * relocs;
14889 Elf_Internal_Rela * rp;
14890
14891 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14892 return false;
d1c4b12b
NC
14893
14894 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14895
14896 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14897 if (rp->r_offset == offset)
015dc7e1 14898 return true;
d1c4b12b 14899
015dc7e1 14900 return false;
d1c4b12b
NC
14901}
14902
cf13d699 14903/* Apply relocations to a section.
32ec8896
NC
14904 Returns TRUE upon success, FALSE otherwise.
14905 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14906 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14907 will be set to the number of relocs loaded.
14908
cf13d699 14909 Note: So far support has been added only for those relocations
32ec8896
NC
14910 which can be found in debug sections. FIXME: Add support for
14911 more relocations ? */
1b315056 14912
015dc7e1 14913static bool
dda8d76d 14914apply_relocations (Filedata * filedata,
d1c4b12b
NC
14915 const Elf_Internal_Shdr * section,
14916 unsigned char * start,
14917 bfd_size_type size,
1449284b 14918 void ** relocs_return,
d1c4b12b 14919 unsigned long * num_relocs_return)
1b315056 14920{
cf13d699 14921 Elf_Internal_Shdr * relsec;
0d2a7a93 14922 unsigned char * end = start + size;
cb8f3167 14923
d1c4b12b
NC
14924 if (relocs_return != NULL)
14925 {
14926 * (Elf_Internal_Rela **) relocs_return = NULL;
14927 * num_relocs_return = 0;
14928 }
14929
dda8d76d 14930 if (filedata->file_header.e_type != ET_REL)
32ec8896 14931 /* No relocs to apply. */
015dc7e1 14932 return true;
1b315056 14933
cf13d699 14934 /* Find the reloc section associated with the section. */
dda8d76d
NC
14935 for (relsec = filedata->section_headers;
14936 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14937 ++relsec)
252b5132 14938 {
015dc7e1 14939 bool is_rela;
41e92641 14940 unsigned long num_relocs;
2cf0635d
NC
14941 Elf_Internal_Rela * relocs;
14942 Elf_Internal_Rela * rp;
14943 Elf_Internal_Shdr * symsec;
14944 Elf_Internal_Sym * symtab;
ba5cdace 14945 unsigned long num_syms;
2cf0635d 14946 Elf_Internal_Sym * sym;
252b5132 14947
41e92641 14948 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14949 || relsec->sh_info >= filedata->file_header.e_shnum
14950 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14951 || relsec->sh_size == 0
dda8d76d 14952 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14953 continue;
428409d5 14954
a788aedd
AM
14955 symsec = filedata->section_headers + relsec->sh_link;
14956 if (symsec->sh_type != SHT_SYMTAB
14957 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14958 return false;
a788aedd 14959
41e92641
NC
14960 is_rela = relsec->sh_type == SHT_RELA;
14961
14962 if (is_rela)
14963 {
dda8d76d 14964 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14965 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14966 return false;
41e92641
NC
14967 }
14968 else
14969 {
dda8d76d 14970 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14971 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14972 return false;
41e92641
NC
14973 }
14974
14975 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14976 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14977 is_rela = false;
428409d5 14978
4de91c10 14979 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14980
41e92641 14981 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14982 {
015dc7e1
AM
14983 bfd_vma addend;
14984 unsigned int reloc_type;
14985 unsigned int reloc_size;
14986 bool reloc_inplace = false;
14987 bool reloc_subtract = false;
14988 unsigned char *rloc;
14989 unsigned long sym_index;
4b78141a 14990
dda8d76d 14991 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14992
dda8d76d 14993 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14994 continue;
dda8d76d 14995 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14996 continue;
dda8d76d
NC
14997 else if (is_32bit_abs_reloc (filedata, reloc_type)
14998 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14999 reloc_size = 4;
dda8d76d
NC
15000 else if (is_64bit_abs_reloc (filedata, reloc_type)
15001 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15002 reloc_size = 8;
dda8d76d 15003 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15004 reloc_size = 3;
dda8d76d 15005 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15006 reloc_size = 2;
39e07931
AS
15007 else if (is_8bit_abs_reloc (filedata, reloc_type)
15008 || is_6bit_abs_reloc (filedata, reloc_type))
15009 reloc_size = 1;
03336641
JW
15010 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15011 reloc_type))
15012 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15013 {
15014 reloc_size = 4;
015dc7e1 15015 reloc_inplace = true;
03336641
JW
15016 }
15017 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15018 reloc_type))
15019 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15020 {
15021 reloc_size = 8;
015dc7e1 15022 reloc_inplace = true;
03336641
JW
15023 }
15024 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15025 reloc_type))
15026 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15027 {
15028 reloc_size = 2;
015dc7e1 15029 reloc_inplace = true;
03336641
JW
15030 }
15031 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15032 reloc_type))
15033 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15034 {
15035 reloc_size = 1;
015dc7e1 15036 reloc_inplace = true;
03336641 15037 }
39e07931
AS
15038 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15039 reloc_type)))
15040 {
15041 reloc_size = 1;
015dc7e1 15042 reloc_inplace = true;
39e07931 15043 }
aca88567 15044 else
4b78141a 15045 {
bee0ee85 15046 static unsigned int prev_reloc = 0;
dda8d76d 15047
bee0ee85
NC
15048 if (reloc_type != prev_reloc)
15049 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15050 reloc_type, printable_section_name (filedata, section));
bee0ee85 15051 prev_reloc = reloc_type;
4b78141a
NC
15052 continue;
15053 }
103f02d3 15054
91d6fa6a 15055 rloc = start + rp->r_offset;
75802ccb 15056 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15057 {
15058 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15059 (unsigned long) rp->r_offset,
dda8d76d 15060 printable_section_name (filedata, section));
700dd8b7
L
15061 continue;
15062 }
103f02d3 15063
ba5cdace
NC
15064 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15065 if (sym_index >= num_syms)
15066 {
15067 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15068 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15069 continue;
15070 }
15071 sym = symtab + sym_index;
41e92641
NC
15072
15073 /* If the reloc has a symbol associated with it,
55f25fc3
L
15074 make sure that it is of an appropriate type.
15075
15076 Relocations against symbols without type can happen.
15077 Gcc -feliminate-dwarf2-dups may generate symbols
15078 without type for debug info.
15079
15080 Icc generates relocations against function symbols
15081 instead of local labels.
15082
15083 Relocations against object symbols can happen, eg when
15084 referencing a global array. For an example of this see
15085 the _clz.o binary in libgcc.a. */
aca88567 15086 if (sym != symtab
b8871f35 15087 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15088 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15089 {
d3a49aa8 15090 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15091 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15092 printable_section_name (filedata, relsec),
d3a49aa8 15093 (long int)(rp - relocs));
aca88567 15094 continue;
5b18a4bc 15095 }
252b5132 15096
4dc3c23d
AM
15097 addend = 0;
15098 if (is_rela)
15099 addend += rp->r_addend;
c47320c3
AM
15100 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15101 partial_inplace. */
4dc3c23d 15102 if (!is_rela
dda8d76d 15103 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15104 && reloc_type == 1)
dda8d76d
NC
15105 || ((filedata->file_header.e_machine == EM_PJ
15106 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15107 && reloc_type == 1)
dda8d76d
NC
15108 || ((filedata->file_header.e_machine == EM_D30V
15109 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15110 && reloc_type == 12)
15111 || reloc_inplace)
39e07931
AS
15112 {
15113 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15114 addend += byte_get (rloc, reloc_size) & 0x3f;
15115 else
15116 addend += byte_get (rloc, reloc_size);
15117 }
cb8f3167 15118
dda8d76d
NC
15119 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15120 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15121 {
15122 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15123 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15124 addend -= 8;
91d6fa6a 15125 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15126 reloc_size);
15127 }
39e07931
AS
15128 else if (is_6bit_abs_reloc (filedata, reloc_type)
15129 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15130 {
15131 if (reloc_subtract)
15132 addend -= sym->st_value;
15133 else
15134 addend += sym->st_value;
15135 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15136 byte_put (rloc, addend, reloc_size);
15137 }
03336641
JW
15138 else if (reloc_subtract)
15139 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15140 else
91d6fa6a 15141 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15142 }
252b5132 15143
5b18a4bc 15144 free (symtab);
f84ce13b
NC
15145 /* Let the target specific reloc processing code know that
15146 we have finished with these relocs. */
dda8d76d 15147 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15148
15149 if (relocs_return)
15150 {
15151 * (Elf_Internal_Rela **) relocs_return = relocs;
15152 * num_relocs_return = num_relocs;
15153 }
15154 else
15155 free (relocs);
15156
5b18a4bc
NC
15157 break;
15158 }
32ec8896 15159
015dc7e1 15160 return true;
5b18a4bc 15161}
103f02d3 15162
cf13d699 15163#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15164static bool
dda8d76d 15165disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15166{
dda8d76d 15167 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15168
74e1a04b 15169 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15170
015dc7e1 15171 return true;
cf13d699
NC
15172}
15173#endif
15174
15175/* Reads in the contents of SECTION from FILE, returning a pointer
15176 to a malloc'ed buffer or NULL if something went wrong. */
15177
15178static char *
dda8d76d 15179get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15180{
dda8d76d 15181 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15182
15183 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15184 {
c6b78c96 15185 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15186 printable_section_name (filedata, section));
cf13d699
NC
15187 return NULL;
15188 }
15189
dda8d76d 15190 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15191 _("section contents"));
cf13d699
NC
15192}
15193
0e602686
NC
15194/* Uncompresses a section that was compressed using zlib, in place. */
15195
015dc7e1 15196static bool
dda8d76d
NC
15197uncompress_section_contents (unsigned char ** buffer,
15198 dwarf_size_type uncompressed_size,
15199 dwarf_size_type * size)
0e602686
NC
15200{
15201 dwarf_size_type compressed_size = *size;
15202 unsigned char * compressed_buffer = *buffer;
15203 unsigned char * uncompressed_buffer;
15204 z_stream strm;
15205 int rc;
15206
15207 /* It is possible the section consists of several compressed
15208 buffers concatenated together, so we uncompress in a loop. */
15209 /* PR 18313: The state field in the z_stream structure is supposed
15210 to be invisible to the user (ie us), but some compilers will
15211 still complain about it being used without initialisation. So
15212 we first zero the entire z_stream structure and then set the fields
15213 that we need. */
15214 memset (& strm, 0, sizeof strm);
15215 strm.avail_in = compressed_size;
15216 strm.next_in = (Bytef *) compressed_buffer;
15217 strm.avail_out = uncompressed_size;
15218 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15219
15220 rc = inflateInit (& strm);
15221 while (strm.avail_in > 0)
15222 {
15223 if (rc != Z_OK)
3624a6c1 15224 break;
0e602686
NC
15225 strm.next_out = ((Bytef *) uncompressed_buffer
15226 + (uncompressed_size - strm.avail_out));
15227 rc = inflate (&strm, Z_FINISH);
15228 if (rc != Z_STREAM_END)
3624a6c1 15229 break;
0e602686
NC
15230 rc = inflateReset (& strm);
15231 }
ad92f33d
AM
15232 if (inflateEnd (& strm) != Z_OK
15233 || rc != Z_OK
0e602686
NC
15234 || strm.avail_out != 0)
15235 goto fail;
15236
15237 *buffer = uncompressed_buffer;
15238 *size = uncompressed_size;
015dc7e1 15239 return true;
0e602686
NC
15240
15241 fail:
15242 free (uncompressed_buffer);
15243 /* Indicate decompression failure. */
15244 *buffer = NULL;
015dc7e1 15245 return false;
0e602686 15246}
dd24e3da 15247
015dc7e1 15248static bool
dda8d76d 15249dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15250{
015dc7e1
AM
15251 Elf_Internal_Shdr *relsec;
15252 bfd_size_type num_bytes;
15253 unsigned char *data;
15254 unsigned char *end;
15255 unsigned char *real_start;
15256 unsigned char *start;
15257 bool some_strings_shown;
cf13d699 15258
dda8d76d 15259 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15260 if (start == NULL)
c6b78c96 15261 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15262 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15263
0e602686 15264 num_bytes = section->sh_size;
cf13d699 15265
835f2fae
NC
15266 if (filedata->is_separate)
15267 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15268 printable_section_name (filedata, section),
15269 filedata->file_name);
15270 else
15271 printf (_("\nString dump of section '%s':\n"),
15272 printable_section_name (filedata, section));
cf13d699 15273
0e602686
NC
15274 if (decompress_dumps)
15275 {
15276 dwarf_size_type new_size = num_bytes;
15277 dwarf_size_type uncompressed_size = 0;
15278
15279 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15280 {
15281 Elf_Internal_Chdr chdr;
15282 unsigned int compression_header_size
ebdf1ebf
NC
15283 = get_compression_header (& chdr, (unsigned char *) start,
15284 num_bytes);
5844b465
NC
15285 if (compression_header_size == 0)
15286 /* An error message will have already been generated
15287 by get_compression_header. */
15288 goto error_out;
0e602686 15289
813dabb9 15290 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15291 {
813dabb9 15292 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15293 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15294 goto error_out;
813dabb9 15295 }
813dabb9
L
15296 uncompressed_size = chdr.ch_size;
15297 start += compression_header_size;
15298 new_size -= compression_header_size;
0e602686
NC
15299 }
15300 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15301 {
15302 /* Read the zlib header. In this case, it should be "ZLIB"
15303 followed by the uncompressed section size, 8 bytes in
15304 big-endian order. */
15305 uncompressed_size = start[4]; uncompressed_size <<= 8;
15306 uncompressed_size += start[5]; uncompressed_size <<= 8;
15307 uncompressed_size += start[6]; uncompressed_size <<= 8;
15308 uncompressed_size += start[7]; uncompressed_size <<= 8;
15309 uncompressed_size += start[8]; uncompressed_size <<= 8;
15310 uncompressed_size += start[9]; uncompressed_size <<= 8;
15311 uncompressed_size += start[10]; uncompressed_size <<= 8;
15312 uncompressed_size += start[11];
15313 start += 12;
15314 new_size -= 12;
15315 }
15316
1835f746
NC
15317 if (uncompressed_size)
15318 {
15319 if (uncompress_section_contents (& start,
15320 uncompressed_size, & new_size))
15321 num_bytes = new_size;
15322 else
15323 {
15324 error (_("Unable to decompress section %s\n"),
dda8d76d 15325 printable_section_name (filedata, section));
f761cb13 15326 goto error_out;
1835f746
NC
15327 }
15328 }
bc303e5d
NC
15329 else
15330 start = real_start;
0e602686 15331 }
fd8008d8 15332
cf13d699
NC
15333 /* If the section being dumped has relocations against it the user might
15334 be expecting these relocations to have been applied. Check for this
15335 case and issue a warning message in order to avoid confusion.
15336 FIXME: Maybe we ought to have an option that dumps a section with
15337 relocs applied ? */
dda8d76d
NC
15338 for (relsec = filedata->section_headers;
15339 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15340 ++relsec)
15341 {
15342 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15343 || relsec->sh_info >= filedata->file_header.e_shnum
15344 || filedata->section_headers + relsec->sh_info != section
cf13d699 15345 || relsec->sh_size == 0
dda8d76d 15346 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15347 continue;
15348
15349 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15350 break;
15351 }
15352
cf13d699
NC
15353 data = start;
15354 end = start + num_bytes;
015dc7e1 15355 some_strings_shown = false;
cf13d699 15356
ba3265d0
NC
15357#ifdef HAVE_MBSTATE_T
15358 mbstate_t state;
15359 /* Initialise the multibyte conversion state. */
15360 memset (& state, 0, sizeof (state));
15361#endif
15362
015dc7e1 15363 bool continuing = false;
ba3265d0 15364
cf13d699
NC
15365 while (data < end)
15366 {
15367 while (!ISPRINT (* data))
15368 if (++ data >= end)
15369 break;
15370
15371 if (data < end)
15372 {
071436c6
NC
15373 size_t maxlen = end - data;
15374
ba3265d0
NC
15375 if (continuing)
15376 {
15377 printf (" ");
015dc7e1 15378 continuing = false;
ba3265d0
NC
15379 }
15380 else
15381 {
d1ce973e 15382 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15383 }
15384
4082ef84
NC
15385 if (maxlen > 0)
15386 {
f3da8a96 15387 char c = 0;
ba3265d0
NC
15388
15389 while (maxlen)
15390 {
15391 c = *data++;
15392
15393 if (c == 0)
15394 break;
15395
15396 /* PR 25543: Treat new-lines as string-ending characters. */
15397 if (c == '\n')
15398 {
15399 printf ("\\n\n");
15400 if (*data != 0)
015dc7e1 15401 continuing = true;
ba3265d0
NC
15402 break;
15403 }
15404
15405 /* Do not print control characters directly as they can affect terminal
15406 settings. Such characters usually appear in the names generated
15407 by the assembler for local labels. */
15408 if (ISCNTRL (c))
15409 {
15410 printf ("^%c", c + 0x40);
15411 }
15412 else if (ISPRINT (c))
15413 {
15414 putchar (c);
15415 }
15416 else
15417 {
15418 size_t n;
15419#ifdef HAVE_MBSTATE_T
15420 wchar_t w;
15421#endif
15422 /* Let printf do the hard work of displaying multibyte characters. */
15423 printf ("%.1s", data - 1);
15424#ifdef HAVE_MBSTATE_T
15425 /* Try to find out how many bytes made up the character that was
15426 just printed. Advance the symbol pointer past the bytes that
15427 were displayed. */
15428 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15429#else
15430 n = 1;
15431#endif
15432 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15433 data += (n - 1);
15434 }
15435 }
15436
15437 if (c != '\n')
15438 putchar ('\n');
4082ef84
NC
15439 }
15440 else
15441 {
15442 printf (_("<corrupt>\n"));
15443 data = end;
15444 }
015dc7e1 15445 some_strings_shown = true;
cf13d699
NC
15446 }
15447 }
15448
15449 if (! some_strings_shown)
15450 printf (_(" No strings found in this section."));
15451
0e602686 15452 free (real_start);
cf13d699
NC
15453
15454 putchar ('\n');
015dc7e1 15455 return true;
f761cb13
AM
15456
15457error_out:
15458 free (real_start);
015dc7e1 15459 return false;
cf13d699
NC
15460}
15461
015dc7e1
AM
15462static bool
15463dump_section_as_bytes (Elf_Internal_Shdr *section,
15464 Filedata *filedata,
15465 bool relocate)
cf13d699
NC
15466{
15467 Elf_Internal_Shdr * relsec;
0e602686
NC
15468 bfd_size_type bytes;
15469 bfd_size_type section_size;
15470 bfd_vma addr;
15471 unsigned char * data;
15472 unsigned char * real_start;
15473 unsigned char * start;
15474
dda8d76d 15475 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15476 if (start == NULL)
c6b78c96 15477 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15478 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15479
0e602686 15480 section_size = section->sh_size;
cf13d699 15481
835f2fae
NC
15482 if (filedata->is_separate)
15483 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15484 printable_section_name (filedata, section),
15485 filedata->file_name);
15486 else
15487 printf (_("\nHex dump of section '%s':\n"),
15488 printable_section_name (filedata, section));
cf13d699 15489
0e602686
NC
15490 if (decompress_dumps)
15491 {
15492 dwarf_size_type new_size = section_size;
15493 dwarf_size_type uncompressed_size = 0;
15494
15495 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15496 {
15497 Elf_Internal_Chdr chdr;
15498 unsigned int compression_header_size
ebdf1ebf 15499 = get_compression_header (& chdr, start, section_size);
0e602686 15500
5844b465
NC
15501 if (compression_header_size == 0)
15502 /* An error message will have already been generated
15503 by get_compression_header. */
15504 goto error_out;
15505
813dabb9 15506 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15507 {
813dabb9 15508 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15509 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15510 goto error_out;
0e602686 15511 }
813dabb9
L
15512 uncompressed_size = chdr.ch_size;
15513 start += compression_header_size;
15514 new_size -= compression_header_size;
0e602686
NC
15515 }
15516 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15517 {
15518 /* Read the zlib header. In this case, it should be "ZLIB"
15519 followed by the uncompressed section size, 8 bytes in
15520 big-endian order. */
15521 uncompressed_size = start[4]; uncompressed_size <<= 8;
15522 uncompressed_size += start[5]; uncompressed_size <<= 8;
15523 uncompressed_size += start[6]; uncompressed_size <<= 8;
15524 uncompressed_size += start[7]; uncompressed_size <<= 8;
15525 uncompressed_size += start[8]; uncompressed_size <<= 8;
15526 uncompressed_size += start[9]; uncompressed_size <<= 8;
15527 uncompressed_size += start[10]; uncompressed_size <<= 8;
15528 uncompressed_size += start[11];
15529 start += 12;
15530 new_size -= 12;
15531 }
15532
f055032e
NC
15533 if (uncompressed_size)
15534 {
15535 if (uncompress_section_contents (& start, uncompressed_size,
15536 & new_size))
bc303e5d
NC
15537 {
15538 section_size = new_size;
15539 }
f055032e
NC
15540 else
15541 {
15542 error (_("Unable to decompress section %s\n"),
dda8d76d 15543 printable_section_name (filedata, section));
bc303e5d 15544 /* FIXME: Print the section anyway ? */
f761cb13 15545 goto error_out;
f055032e
NC
15546 }
15547 }
bc303e5d
NC
15548 else
15549 start = real_start;
0e602686 15550 }
14ae95f2 15551
cf13d699
NC
15552 if (relocate)
15553 {
dda8d76d 15554 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15555 goto error_out;
cf13d699
NC
15556 }
15557 else
15558 {
15559 /* If the section being dumped has relocations against it the user might
15560 be expecting these relocations to have been applied. Check for this
15561 case and issue a warning message in order to avoid confusion.
15562 FIXME: Maybe we ought to have an option that dumps a section with
15563 relocs applied ? */
dda8d76d
NC
15564 for (relsec = filedata->section_headers;
15565 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15566 ++relsec)
15567 {
15568 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15569 || relsec->sh_info >= filedata->file_header.e_shnum
15570 || filedata->section_headers + relsec->sh_info != section
cf13d699 15571 || relsec->sh_size == 0
dda8d76d 15572 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15573 continue;
15574
15575 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15576 break;
15577 }
15578 }
15579
15580 addr = section->sh_addr;
0e602686 15581 bytes = section_size;
cf13d699
NC
15582 data = start;
15583
15584 while (bytes)
15585 {
15586 int j;
15587 int k;
15588 int lbytes;
15589
15590 lbytes = (bytes > 16 ? 16 : bytes);
15591
15592 printf (" 0x%8.8lx ", (unsigned long) addr);
15593
15594 for (j = 0; j < 16; j++)
15595 {
15596 if (j < lbytes)
15597 printf ("%2.2x", data[j]);
15598 else
15599 printf (" ");
15600
15601 if ((j & 3) == 3)
15602 printf (" ");
15603 }
15604
15605 for (j = 0; j < lbytes; j++)
15606 {
15607 k = data[j];
15608 if (k >= ' ' && k < 0x7f)
15609 printf ("%c", k);
15610 else
15611 printf (".");
15612 }
15613
15614 putchar ('\n');
15615
15616 data += lbytes;
15617 addr += lbytes;
15618 bytes -= lbytes;
15619 }
15620
0e602686 15621 free (real_start);
cf13d699
NC
15622
15623 putchar ('\n');
015dc7e1 15624 return true;
f761cb13
AM
15625
15626 error_out:
15627 free (real_start);
015dc7e1 15628 return false;
cf13d699
NC
15629}
15630
094e34f2 15631#ifdef ENABLE_LIBCTF
7d9813f1
NA
15632static ctf_sect_t *
15633shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15634{
84714f86 15635 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15636 buf->cts_size = shdr->sh_size;
15637 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15638
15639 return buf;
15640}
15641
15642/* Formatting callback function passed to ctf_dump. Returns either the pointer
15643 it is passed, or a pointer to newly-allocated storage, in which case
15644 dump_ctf() will free it when it no longer needs it. */
15645
2f6ecaed
NA
15646static char *
15647dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15648 char *s, void *arg)
7d9813f1 15649{
3e50a591 15650 const char *blanks = arg;
7d9813f1
NA
15651 char *new_s;
15652
3e50a591 15653 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15654 return s;
15655 return new_s;
15656}
15657
926c9e76
NA
15658/* Dump CTF errors/warnings. */
15659static void
139633c3 15660dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15661{
15662 ctf_next_t *it = NULL;
15663 char *errtext;
15664 int is_warning;
15665 int err;
15666
15667 /* Dump accumulated errors and warnings. */
15668 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15669 {
5e9b84f7 15670 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15671 errtext);
15672 free (errtext);
15673 }
15674 if (err != ECTF_NEXT_END)
15675 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15676}
15677
2f6ecaed
NA
15678/* Dump one CTF archive member. */
15679
80b56fad
NA
15680static void
15681dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15682 size_t member)
2f6ecaed 15683{
2f6ecaed
NA
15684 const char *things[] = {"Header", "Labels", "Data objects",
15685 "Function objects", "Variables", "Types", "Strings",
15686 ""};
15687 const char **thing;
15688 size_t i;
15689
80b56fad
NA
15690 /* Don't print out the name of the default-named archive member if it appears
15691 first in the list. The name .ctf appears everywhere, even for things that
15692 aren't really archives, so printing it out is liable to be confusing; also,
15693 the common case by far is for only one archive member to exist, and hiding
15694 it in that case seems worthwhile. */
2f6ecaed 15695
80b56fad
NA
15696 if (strcmp (name, ".ctf") != 0 || member != 0)
15697 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15698
80b56fad
NA
15699 if (ctf_parent_name (ctf) != NULL)
15700 ctf_import (ctf, parent);
2f6ecaed
NA
15701
15702 for (i = 0, thing = things; *thing[0]; thing++, i++)
15703 {
15704 ctf_dump_state_t *s = NULL;
15705 char *item;
15706
15707 printf ("\n %s:\n", *thing);
15708 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15709 (void *) " ")) != NULL)
15710 {
15711 printf ("%s\n", item);
15712 free (item);
15713 }
15714
15715 if (ctf_errno (ctf))
15716 {
15717 error (_("Iteration failed: %s, %s\n"), *thing,
15718 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15719 break;
2f6ecaed
NA
15720 }
15721 }
8b37e7b6 15722
926c9e76 15723 dump_ctf_errs (ctf);
2f6ecaed
NA
15724}
15725
015dc7e1 15726static bool
7d9813f1
NA
15727dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15728{
7d9813f1
NA
15729 Elf_Internal_Shdr * symtab_sec = NULL;
15730 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15731 void * data = NULL;
15732 void * symdata = NULL;
15733 void * strdata = NULL;
80b56fad 15734 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15735 ctf_sect_t * symsectp = NULL;
15736 ctf_sect_t * strsectp = NULL;
2f6ecaed 15737 ctf_archive_t * ctfa = NULL;
139633c3 15738 ctf_dict_t * parent = NULL;
80b56fad 15739 ctf_dict_t * fp;
7d9813f1 15740
80b56fad
NA
15741 ctf_next_t *i = NULL;
15742 const char *name;
15743 size_t member = 0;
7d9813f1 15744 int err;
015dc7e1 15745 bool ret = false;
7d9813f1
NA
15746
15747 shdr_to_ctf_sect (&ctfsect, section, filedata);
15748 data = get_section_contents (section, filedata);
15749 ctfsect.cts_data = data;
15750
616febde 15751 if (!dump_ctf_symtab_name)
3d16b64e 15752 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15753
15754 if (!dump_ctf_strtab_name)
3d16b64e 15755 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15756
15757 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15758 {
15759 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15760 {
15761 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15762 goto fail;
15763 }
15764 if ((symdata = (void *) get_data (NULL, filedata,
15765 symtab_sec->sh_offset, 1,
15766 symtab_sec->sh_size,
15767 _("symbols"))) == NULL)
15768 goto fail;
15769 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15770 symsect.cts_data = symdata;
15771 }
835f2fae 15772
df16e041 15773 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15774 {
15775 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15776 {
15777 error (_("No string table section named %s\n"),
15778 dump_ctf_strtab_name);
15779 goto fail;
15780 }
15781 if ((strdata = (void *) get_data (NULL, filedata,
15782 strtab_sec->sh_offset, 1,
15783 strtab_sec->sh_size,
15784 _("strings"))) == NULL)
15785 goto fail;
15786 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15787 strsect.cts_data = strdata;
15788 }
835f2fae 15789
2f6ecaed
NA
15790 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15791 libctf papers over the difference, so we can pretend it is always an
80b56fad 15792 archive. */
7d9813f1 15793
2f6ecaed 15794 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15795 {
926c9e76 15796 dump_ctf_errs (NULL);
7d9813f1
NA
15797 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15798 goto fail;
15799 }
15800
96c61be5
NA
15801 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15802 != ELFDATA2MSB);
15803
80b56fad
NA
15804 /* Preload the parent dict, since it will need to be imported into every
15805 child in turn. */
15806 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15807 {
926c9e76 15808 dump_ctf_errs (NULL);
2f6ecaed
NA
15809 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15810 goto fail;
7d9813f1
NA
15811 }
15812
015dc7e1 15813 ret = true;
7d9813f1 15814
835f2fae
NC
15815 if (filedata->is_separate)
15816 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15817 printable_section_name (filedata, section),
15818 filedata->file_name);
15819 else
15820 printf (_("\nDump of CTF section '%s':\n"),
15821 printable_section_name (filedata, section));
7d9813f1 15822
80b56fad
NA
15823 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15824 dump_ctf_archive_member (fp, name, parent, member++);
15825 if (err != ECTF_NEXT_END)
15826 {
15827 dump_ctf_errs (NULL);
15828 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15829 ret = false;
15830 }
7d9813f1
NA
15831
15832 fail:
139633c3 15833 ctf_dict_close (parent);
2f6ecaed 15834 ctf_close (ctfa);
7d9813f1
NA
15835 free (data);
15836 free (symdata);
15837 free (strdata);
15838 return ret;
15839}
094e34f2 15840#endif
7d9813f1 15841
015dc7e1 15842static bool
dda8d76d
NC
15843load_specific_debug_section (enum dwarf_section_display_enum debug,
15844 const Elf_Internal_Shdr * sec,
15845 void * data)
1007acb3 15846{
2cf0635d 15847 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15848 char buf [64];
dda8d76d 15849 Filedata * filedata = (Filedata *) data;
9abca702 15850
19e6b90e 15851 if (section->start != NULL)
dda8d76d
NC
15852 {
15853 /* If it is already loaded, do nothing. */
15854 if (streq (section->filename, filedata->file_name))
015dc7e1 15855 return true;
dda8d76d
NC
15856 free (section->start);
15857 }
1007acb3 15858
19e6b90e
L
15859 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15860 section->address = sec->sh_addr;
dda8d76d
NC
15861 section->filename = filedata->file_name;
15862 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15863 sec->sh_offset, 1,
15864 sec->sh_size, buf);
59245841
NC
15865 if (section->start == NULL)
15866 section->size = 0;
15867 else
15868 {
77115a4a
L
15869 unsigned char *start = section->start;
15870 dwarf_size_type size = sec->sh_size;
dab394de 15871 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15872
15873 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15874 {
15875 Elf_Internal_Chdr chdr;
d8024a91
NC
15876 unsigned int compression_header_size;
15877
f53be977
L
15878 if (size < (is_32bit_elf
15879 ? sizeof (Elf32_External_Chdr)
15880 : sizeof (Elf64_External_Chdr)))
d8024a91 15881 {
55be8fd0 15882 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15883 section->name);
015dc7e1 15884 return false;
d8024a91
NC
15885 }
15886
ebdf1ebf 15887 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15888 if (compression_header_size == 0)
15889 /* An error message will have already been generated
15890 by get_compression_header. */
015dc7e1 15891 return false;
d8024a91 15892
813dabb9
L
15893 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15894 {
15895 warn (_("section '%s' has unsupported compress type: %d\n"),
15896 section->name, chdr.ch_type);
015dc7e1 15897 return false;
813dabb9 15898 }
dab394de 15899 uncompressed_size = chdr.ch_size;
77115a4a
L
15900 start += compression_header_size;
15901 size -= compression_header_size;
15902 }
dab394de
L
15903 else if (size > 12 && streq ((char *) start, "ZLIB"))
15904 {
15905 /* Read the zlib header. In this case, it should be "ZLIB"
15906 followed by the uncompressed section size, 8 bytes in
15907 big-endian order. */
15908 uncompressed_size = start[4]; uncompressed_size <<= 8;
15909 uncompressed_size += start[5]; uncompressed_size <<= 8;
15910 uncompressed_size += start[6]; uncompressed_size <<= 8;
15911 uncompressed_size += start[7]; uncompressed_size <<= 8;
15912 uncompressed_size += start[8]; uncompressed_size <<= 8;
15913 uncompressed_size += start[9]; uncompressed_size <<= 8;
15914 uncompressed_size += start[10]; uncompressed_size <<= 8;
15915 uncompressed_size += start[11];
15916 start += 12;
15917 size -= 12;
15918 }
15919
1835f746 15920 if (uncompressed_size)
77115a4a 15921 {
1835f746
NC
15922 if (uncompress_section_contents (&start, uncompressed_size,
15923 &size))
15924 {
15925 /* Free the compressed buffer, update the section buffer
15926 and the section size if uncompress is successful. */
15927 free (section->start);
15928 section->start = start;
15929 }
15930 else
15931 {
15932 error (_("Unable to decompress section %s\n"),
dda8d76d 15933 printable_section_name (filedata, sec));
015dc7e1 15934 return false;
1835f746 15935 }
77115a4a 15936 }
bc303e5d 15937
77115a4a 15938 section->size = size;
59245841 15939 }
4a114e3e 15940
1b315056 15941 if (section->start == NULL)
015dc7e1 15942 return false;
1b315056 15943
19e6b90e 15944 if (debug_displays [debug].relocate)
32ec8896 15945 {
dda8d76d 15946 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15947 & section->reloc_info, & section->num_relocs))
015dc7e1 15948 return false;
32ec8896 15949 }
d1c4b12b
NC
15950 else
15951 {
15952 section->reloc_info = NULL;
15953 section->num_relocs = 0;
15954 }
1007acb3 15955
015dc7e1 15956 return true;
1007acb3
L
15957}
15958
301a9420
AM
15959#if HAVE_LIBDEBUGINFOD
15960/* Return a hex string representation of the build-id. */
15961unsigned char *
15962get_build_id (void * data)
15963{
ca0e11aa 15964 Filedata * filedata = (Filedata *) data;
301a9420
AM
15965 Elf_Internal_Shdr * shdr;
15966 unsigned long i;
15967
55be8fd0
NC
15968 /* Iterate through notes to find note.gnu.build-id.
15969 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15970 for (i = 0, shdr = filedata->section_headers;
15971 i < filedata->file_header.e_shnum && shdr != NULL;
15972 i++, shdr++)
15973 {
15974 if (shdr->sh_type != SHT_NOTE)
15975 continue;
15976
15977 char * next;
15978 char * end;
15979 size_t data_remaining;
15980 size_t min_notesz;
15981 Elf_External_Note * enote;
15982 Elf_Internal_Note inote;
15983
15984 bfd_vma offset = shdr->sh_offset;
15985 bfd_vma align = shdr->sh_addralign;
15986 bfd_vma length = shdr->sh_size;
15987
15988 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15989 if (enote == NULL)
15990 continue;
15991
15992 if (align < 4)
15993 align = 4;
15994 else if (align != 4 && align != 8)
f761cb13
AM
15995 {
15996 free (enote);
15997 continue;
15998 }
301a9420
AM
15999
16000 end = (char *) enote + length;
16001 data_remaining = end - (char *) enote;
16002
16003 if (!is_ia64_vms (filedata))
16004 {
16005 min_notesz = offsetof (Elf_External_Note, name);
16006 if (data_remaining < min_notesz)
16007 {
55be8fd0
NC
16008 warn (_("\
16009malformed note encountered in section %s whilst scanning for build-id note\n"),
16010 printable_section_name (filedata, shdr));
f761cb13 16011 free (enote);
55be8fd0 16012 continue;
301a9420
AM
16013 }
16014 data_remaining -= min_notesz;
16015
16016 inote.type = BYTE_GET (enote->type);
16017 inote.namesz = BYTE_GET (enote->namesz);
16018 inote.namedata = enote->name;
16019 inote.descsz = BYTE_GET (enote->descsz);
16020 inote.descdata = ((char *) enote
16021 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16022 inote.descpos = offset + (inote.descdata - (char *) enote);
16023 next = ((char *) enote
16024 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16025 }
16026 else
16027 {
16028 Elf64_External_VMS_Note *vms_enote;
16029
16030 /* PR binutils/15191
16031 Make sure that there is enough data to read. */
16032 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16033 if (data_remaining < min_notesz)
16034 {
55be8fd0
NC
16035 warn (_("\
16036malformed note encountered in section %s whilst scanning for build-id note\n"),
16037 printable_section_name (filedata, shdr));
f761cb13 16038 free (enote);
55be8fd0 16039 continue;
301a9420
AM
16040 }
16041 data_remaining -= min_notesz;
16042
16043 vms_enote = (Elf64_External_VMS_Note *) enote;
16044 inote.type = BYTE_GET (vms_enote->type);
16045 inote.namesz = BYTE_GET (vms_enote->namesz);
16046 inote.namedata = vms_enote->name;
16047 inote.descsz = BYTE_GET (vms_enote->descsz);
16048 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16049 inote.descpos = offset + (inote.descdata - (char *) enote);
16050 next = inote.descdata + align_power (inote.descsz, 3);
16051 }
16052
16053 /* Skip malformed notes. */
16054 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16055 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16056 || (size_t) (next - inote.descdata) < inote.descsz
16057 || ((size_t) (next - inote.descdata)
16058 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16059 {
55be8fd0
NC
16060 warn (_("\
16061malformed note encountered in section %s whilst scanning for build-id note\n"),
16062 printable_section_name (filedata, shdr));
f761cb13 16063 free (enote);
301a9420
AM
16064 continue;
16065 }
16066
16067 /* Check if this is the build-id note. If so then convert the build-id
16068 bytes to a hex string. */
16069 if (inote.namesz > 0
24d127aa 16070 && startswith (inote.namedata, "GNU")
301a9420
AM
16071 && inote.type == NT_GNU_BUILD_ID)
16072 {
16073 unsigned long j;
16074 char * build_id;
16075
16076 build_id = malloc (inote.descsz * 2 + 1);
16077 if (build_id == NULL)
f761cb13
AM
16078 {
16079 free (enote);
16080 return NULL;
16081 }
301a9420
AM
16082
16083 for (j = 0; j < inote.descsz; ++j)
16084 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16085 build_id[inote.descsz * 2] = '\0';
f761cb13 16086 free (enote);
301a9420 16087
55be8fd0 16088 return (unsigned char *) build_id;
301a9420 16089 }
f761cb13 16090 free (enote);
301a9420
AM
16091 }
16092
16093 return NULL;
16094}
16095#endif /* HAVE_LIBDEBUGINFOD */
16096
657d0d47
CC
16097/* If this is not NULL, load_debug_section will only look for sections
16098 within the list of sections given here. */
32ec8896 16099static unsigned int * section_subset = NULL;
657d0d47 16100
015dc7e1 16101bool
dda8d76d 16102load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16103{
2cf0635d
NC
16104 struct dwarf_section * section = &debug_displays [debug].section;
16105 Elf_Internal_Shdr * sec;
dda8d76d
NC
16106 Filedata * filedata = (Filedata *) data;
16107
e1dbfc17
L
16108 if (!dump_any_debugging)
16109 return false;
16110
f425ec66
NC
16111 /* Without section headers we cannot find any sections. */
16112 if (filedata->section_headers == NULL)
015dc7e1 16113 return false;
f425ec66 16114
9c1ce108
AM
16115 if (filedata->string_table == NULL
16116 && filedata->file_header.e_shstrndx != SHN_UNDEF
16117 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16118 {
16119 Elf_Internal_Shdr * strs;
16120
16121 /* Read in the string table, so that we have section names to scan. */
16122 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16123
4dff97b2 16124 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16125 {
9c1ce108
AM
16126 filedata->string_table
16127 = (char *) get_data (NULL, filedata, strs->sh_offset,
16128 1, strs->sh_size, _("string table"));
dda8d76d 16129
9c1ce108
AM
16130 filedata->string_table_length
16131 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16132 }
16133 }
d966045b
DJ
16134
16135 /* Locate the debug section. */
dda8d76d 16136 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16137 if (sec != NULL)
16138 section->name = section->uncompressed_name;
16139 else
16140 {
dda8d76d 16141 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16142 if (sec != NULL)
16143 section->name = section->compressed_name;
16144 }
16145 if (sec == NULL)
015dc7e1 16146 return false;
d966045b 16147
657d0d47
CC
16148 /* If we're loading from a subset of sections, and we've loaded
16149 a section matching this name before, it's likely that it's a
16150 different one. */
16151 if (section_subset != NULL)
16152 free_debug_section (debug);
16153
dda8d76d 16154 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16155}
16156
19e6b90e
L
16157void
16158free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16159{
2cf0635d 16160 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16161
19e6b90e
L
16162 if (section->start == NULL)
16163 return;
1007acb3 16164
19e6b90e
L
16165 free ((char *) section->start);
16166 section->start = NULL;
16167 section->address = 0;
16168 section->size = 0;
a788aedd 16169
9db70fc3
AM
16170 free (section->reloc_info);
16171 section->reloc_info = NULL;
16172 section->num_relocs = 0;
1007acb3
L
16173}
16174
015dc7e1 16175static bool
dda8d76d 16176display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16177{
84714f86
AM
16178 const char *name = (section_name_valid (filedata, section)
16179 ? section_name (filedata, section) : "");
16180 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16181 bfd_size_type length;
015dc7e1 16182 bool result = true;
3f5e193b 16183 int i;
1007acb3 16184
19e6b90e
L
16185 length = section->sh_size;
16186 if (length == 0)
1007acb3 16187 {
74e1a04b 16188 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16189 return true;
1007acb3 16190 }
5dff79d8
NC
16191 if (section->sh_type == SHT_NOBITS)
16192 {
16193 /* There is no point in dumping the contents of a debugging section
16194 which has the NOBITS type - the bits in the file will be random.
16195 This can happen when a file containing a .eh_frame section is
16196 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16197 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16198 print_name);
015dc7e1 16199 return false;
5dff79d8 16200 }
1007acb3 16201
24d127aa 16202 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16203 name = ".debug_info";
1007acb3 16204
19e6b90e
L
16205 /* See if we know how to display the contents of this section. */
16206 for (i = 0; i < max; i++)
d85bf2ba
NC
16207 {
16208 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16209 struct dwarf_section_display * display = debug_displays + i;
16210 struct dwarf_section * sec = & display->section;
d966045b 16211
d85bf2ba 16212 if (streq (sec->uncompressed_name, name)
24d127aa 16213 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16214 || streq (sec->compressed_name, name))
16215 {
015dc7e1 16216 bool secondary = (section != find_section (filedata, name));
1007acb3 16217
d85bf2ba
NC
16218 if (secondary)
16219 free_debug_section (id);
dda8d76d 16220
24d127aa 16221 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16222 sec->name = name;
16223 else if (streq (sec->uncompressed_name, name))
16224 sec->name = sec->uncompressed_name;
16225 else
16226 sec->name = sec->compressed_name;
657d0d47 16227
d85bf2ba
NC
16228 if (load_specific_debug_section (id, section, filedata))
16229 {
16230 /* If this debug section is part of a CU/TU set in a .dwp file,
16231 restrict load_debug_section to the sections in that set. */
16232 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16233
d85bf2ba 16234 result &= display->display (sec, filedata);
657d0d47 16235
d85bf2ba 16236 section_subset = NULL;
1007acb3 16237
44266f36 16238 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16239 free_debug_section (id);
16240 }
16241 break;
16242 }
16243 }
1007acb3 16244
19e6b90e 16245 if (i == max)
1007acb3 16246 {
74e1a04b 16247 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16248 result = false;
1007acb3
L
16249 }
16250
19e6b90e 16251 return result;
5b18a4bc 16252}
103f02d3 16253
aef1f6d0
DJ
16254/* Set DUMP_SECTS for all sections where dumps were requested
16255 based on section name. */
16256
16257static void
dda8d76d 16258initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16259{
2cf0635d 16260 struct dump_list_entry * cur;
aef1f6d0
DJ
16261
16262 for (cur = dump_sects_byname; cur; cur = cur->next)
16263 {
16264 unsigned int i;
015dc7e1 16265 bool any = false;
aef1f6d0 16266
dda8d76d 16267 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16268 if (section_name_valid (filedata, filedata->section_headers + i)
16269 && streq (section_name (filedata, filedata->section_headers + i),
16270 cur->name))
aef1f6d0 16271 {
6431e409 16272 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16273 any = true;
aef1f6d0
DJ
16274 }
16275
835f2fae
NC
16276 if (!any && !filedata->is_separate)
16277 warn (_("Section '%s' was not dumped because it does not exist\n"),
16278 cur->name);
aef1f6d0
DJ
16279 }
16280}
16281
015dc7e1 16282static bool
dda8d76d 16283process_section_contents (Filedata * filedata)
5b18a4bc 16284{
2cf0635d 16285 Elf_Internal_Shdr * section;
19e6b90e 16286 unsigned int i;
015dc7e1 16287 bool res = true;
103f02d3 16288
19e6b90e 16289 if (! do_dump)
015dc7e1 16290 return true;
103f02d3 16291
dda8d76d 16292 initialise_dumps_byname (filedata);
aef1f6d0 16293
dda8d76d 16294 for (i = 0, section = filedata->section_headers;
6431e409 16295 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16296 i++, section++)
16297 {
6431e409 16298 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16299
d6bfbc39
NC
16300 if (filedata->is_separate && ! process_links)
16301 dump &= DEBUG_DUMP;
047c3dbf 16302
19e6b90e 16303#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16304 if (dump & DISASS_DUMP)
16305 {
16306 if (! disassemble_section (section, filedata))
015dc7e1 16307 res = false;
dda8d76d 16308 }
19e6b90e 16309#endif
dda8d76d 16310 if (dump & HEX_DUMP)
32ec8896 16311 {
015dc7e1
AM
16312 if (! dump_section_as_bytes (section, filedata, false))
16313 res = false;
32ec8896 16314 }
103f02d3 16315
dda8d76d 16316 if (dump & RELOC_DUMP)
32ec8896 16317 {
015dc7e1
AM
16318 if (! dump_section_as_bytes (section, filedata, true))
16319 res = false;
32ec8896 16320 }
09c11c86 16321
dda8d76d 16322 if (dump & STRING_DUMP)
32ec8896 16323 {
dda8d76d 16324 if (! dump_section_as_strings (section, filedata))
015dc7e1 16325 res = false;
32ec8896 16326 }
cf13d699 16327
dda8d76d 16328 if (dump & DEBUG_DUMP)
32ec8896 16329 {
dda8d76d 16330 if (! display_debug_section (i, section, filedata))
015dc7e1 16331 res = false;
32ec8896 16332 }
7d9813f1 16333
094e34f2 16334#ifdef ENABLE_LIBCTF
7d9813f1
NA
16335 if (dump & CTF_DUMP)
16336 {
16337 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16338 res = false;
7d9813f1 16339 }
094e34f2 16340#endif
5b18a4bc 16341 }
103f02d3 16342
835f2fae 16343 if (! filedata->is_separate)
0ee3043f 16344 {
835f2fae
NC
16345 /* Check to see if the user requested a
16346 dump of a section that does not exist. */
16347 for (; i < filedata->dump.num_dump_sects; i++)
16348 if (filedata->dump.dump_sects[i])
16349 {
ca0e11aa 16350 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16351 res = false;
835f2fae 16352 }
0ee3043f 16353 }
32ec8896
NC
16354
16355 return res;
5b18a4bc 16356}
103f02d3 16357
5b18a4bc 16358static void
19e6b90e 16359process_mips_fpe_exception (int mask)
5b18a4bc 16360{
19e6b90e
L
16361 if (mask)
16362 {
015dc7e1 16363 bool first = true;
32ec8896 16364
19e6b90e 16365 if (mask & OEX_FPU_INEX)
015dc7e1 16366 fputs ("INEX", stdout), first = false;
19e6b90e 16367 if (mask & OEX_FPU_UFLO)
015dc7e1 16368 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16369 if (mask & OEX_FPU_OFLO)
015dc7e1 16370 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16371 if (mask & OEX_FPU_DIV0)
015dc7e1 16372 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16373 if (mask & OEX_FPU_INVAL)
16374 printf ("%sINVAL", first ? "" : "|");
16375 }
5b18a4bc 16376 else
19e6b90e 16377 fputs ("0", stdout);
5b18a4bc 16378}
103f02d3 16379
f6f0e17b
NC
16380/* Display's the value of TAG at location P. If TAG is
16381 greater than 0 it is assumed to be an unknown tag, and
16382 a message is printed to this effect. Otherwise it is
16383 assumed that a message has already been printed.
16384
16385 If the bottom bit of TAG is set it assumed to have a
16386 string value, otherwise it is assumed to have an integer
16387 value.
16388
16389 Returns an updated P pointing to the first unread byte
16390 beyond the end of TAG's value.
16391
16392 Reads at or beyond END will not be made. */
16393
16394static unsigned char *
60abdbed 16395display_tag_value (signed int tag,
f6f0e17b
NC
16396 unsigned char * p,
16397 const unsigned char * const end)
16398{
16399 unsigned long val;
16400
16401 if (tag > 0)
16402 printf (" Tag_unknown_%d: ", tag);
16403
16404 if (p >= end)
16405 {
4082ef84 16406 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16407 }
16408 else if (tag & 1)
16409 {
071436c6
NC
16410 /* PR 17531 file: 027-19978-0.004. */
16411 size_t maxlen = (end - p) - 1;
16412
16413 putchar ('"');
4082ef84
NC
16414 if (maxlen > 0)
16415 {
16416 print_symbol ((int) maxlen, (const char *) p);
16417 p += strnlen ((char *) p, maxlen) + 1;
16418 }
16419 else
16420 {
16421 printf (_("<corrupt string tag>"));
16422 p = (unsigned char *) end;
16423 }
071436c6 16424 printf ("\"\n");
f6f0e17b
NC
16425 }
16426 else
16427 {
cd30bcef 16428 READ_ULEB (val, p, end);
f6f0e17b
NC
16429 printf ("%ld (0x%lx)\n", val, val);
16430 }
16431
4082ef84 16432 assert (p <= end);
f6f0e17b
NC
16433 return p;
16434}
16435
53a346d8
CZ
16436/* ARC ABI attributes section. */
16437
16438static unsigned char *
16439display_arc_attribute (unsigned char * p,
16440 const unsigned char * const end)
16441{
16442 unsigned int tag;
53a346d8
CZ
16443 unsigned int val;
16444
cd30bcef 16445 READ_ULEB (tag, p, end);
53a346d8
CZ
16446
16447 switch (tag)
16448 {
16449 case Tag_ARC_PCS_config:
cd30bcef 16450 READ_ULEB (val, p, end);
53a346d8
CZ
16451 printf (" Tag_ARC_PCS_config: ");
16452 switch (val)
16453 {
16454 case 0:
16455 printf (_("Absent/Non standard\n"));
16456 break;
16457 case 1:
16458 printf (_("Bare metal/mwdt\n"));
16459 break;
16460 case 2:
16461 printf (_("Bare metal/newlib\n"));
16462 break;
16463 case 3:
16464 printf (_("Linux/uclibc\n"));
16465 break;
16466 case 4:
16467 printf (_("Linux/glibc\n"));
16468 break;
16469 default:
16470 printf (_("Unknown\n"));
16471 break;
16472 }
16473 break;
16474
16475 case Tag_ARC_CPU_base:
cd30bcef 16476 READ_ULEB (val, p, end);
53a346d8
CZ
16477 printf (" Tag_ARC_CPU_base: ");
16478 switch (val)
16479 {
16480 default:
16481 case TAG_CPU_NONE:
16482 printf (_("Absent\n"));
16483 break;
16484 case TAG_CPU_ARC6xx:
16485 printf ("ARC6xx\n");
16486 break;
16487 case TAG_CPU_ARC7xx:
16488 printf ("ARC7xx\n");
16489 break;
16490 case TAG_CPU_ARCEM:
16491 printf ("ARCEM\n");
16492 break;
16493 case TAG_CPU_ARCHS:
16494 printf ("ARCHS\n");
16495 break;
16496 }
16497 break;
16498
16499 case Tag_ARC_CPU_variation:
cd30bcef 16500 READ_ULEB (val, p, end);
53a346d8
CZ
16501 printf (" Tag_ARC_CPU_variation: ");
16502 switch (val)
16503 {
16504 default:
16505 if (val > 0 && val < 16)
53a346d8 16506 printf ("Core%d\n", val);
d8cbc93b
JL
16507 else
16508 printf ("Unknown\n");
16509 break;
16510
53a346d8
CZ
16511 case 0:
16512 printf (_("Absent\n"));
16513 break;
16514 }
16515 break;
16516
16517 case Tag_ARC_CPU_name:
16518 printf (" Tag_ARC_CPU_name: ");
16519 p = display_tag_value (-1, p, end);
16520 break;
16521
16522 case Tag_ARC_ABI_rf16:
cd30bcef 16523 READ_ULEB (val, p, end);
53a346d8
CZ
16524 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16525 break;
16526
16527 case Tag_ARC_ABI_osver:
cd30bcef 16528 READ_ULEB (val, p, end);
53a346d8
CZ
16529 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16530 break;
16531
16532 case Tag_ARC_ABI_pic:
16533 case Tag_ARC_ABI_sda:
cd30bcef 16534 READ_ULEB (val, p, end);
53a346d8
CZ
16535 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16536 : " Tag_ARC_ABI_pic: ");
16537 switch (val)
16538 {
16539 case 0:
16540 printf (_("Absent\n"));
16541 break;
16542 case 1:
16543 printf ("MWDT\n");
16544 break;
16545 case 2:
16546 printf ("GNU\n");
16547 break;
16548 default:
16549 printf (_("Unknown\n"));
16550 break;
16551 }
16552 break;
16553
16554 case Tag_ARC_ABI_tls:
cd30bcef 16555 READ_ULEB (val, p, end);
53a346d8
CZ
16556 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16557 break;
16558
16559 case Tag_ARC_ABI_enumsize:
cd30bcef 16560 READ_ULEB (val, p, end);
53a346d8
CZ
16561 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16562 _("smallest"));
16563 break;
16564
16565 case Tag_ARC_ABI_exceptions:
cd30bcef 16566 READ_ULEB (val, p, end);
53a346d8
CZ
16567 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16568 : _("default"));
16569 break;
16570
16571 case Tag_ARC_ABI_double_size:
cd30bcef 16572 READ_ULEB (val, p, end);
53a346d8
CZ
16573 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16574 break;
16575
16576 case Tag_ARC_ISA_config:
16577 printf (" Tag_ARC_ISA_config: ");
16578 p = display_tag_value (-1, p, end);
16579 break;
16580
16581 case Tag_ARC_ISA_apex:
16582 printf (" Tag_ARC_ISA_apex: ");
16583 p = display_tag_value (-1, p, end);
16584 break;
16585
16586 case Tag_ARC_ISA_mpy_option:
cd30bcef 16587 READ_ULEB (val, p, end);
53a346d8
CZ
16588 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16589 break;
16590
db1e1b45 16591 case Tag_ARC_ATR_version:
cd30bcef 16592 READ_ULEB (val, p, end);
db1e1b45 16593 printf (" Tag_ARC_ATR_version: %d\n", val);
16594 break;
16595
53a346d8
CZ
16596 default:
16597 return display_tag_value (tag & 1, p, end);
16598 }
16599
16600 return p;
16601}
16602
11c1ff18
PB
16603/* ARM EABI attributes section. */
16604typedef struct
16605{
70e99720 16606 unsigned int tag;
2cf0635d 16607 const char * name;
11c1ff18 16608 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16609 unsigned int type;
288f0ba2 16610 const char *const *table;
11c1ff18
PB
16611} arm_attr_public_tag;
16612
288f0ba2 16613static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16614 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16615 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16616 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16617 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16618static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16619static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16620 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16621static const char *const arm_attr_tag_FP_arch[] =
bca38921 16622 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16623 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16624static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16625static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16626 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16627 "NEON for ARMv8.1"};
288f0ba2 16628static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16629 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16630 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16631static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16632 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16633static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16634 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16635static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16636 {"Absolute", "PC-relative", "None"};
288f0ba2 16637static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16638 {"None", "direct", "GOT-indirect"};
288f0ba2 16639static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16640 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16641static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16642static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16643 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16644static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16645static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16646static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16647 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16648static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16649 {"Unused", "small", "int", "forced to int"};
288f0ba2 16650static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16651 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16652static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16653 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16654static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16655 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16656static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16657 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16658 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16659static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16660 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16661 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16662static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16663static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16664 {"Not Allowed", "Allowed"};
288f0ba2 16665static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16666 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16667static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16668 {"Follow architecture", "Allowed"};
288f0ba2 16669static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16670 {"Not Allowed", "Allowed"};
288f0ba2 16671static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16672 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16673 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16674static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16675static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16676 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16677 "TrustZone and Virtualization Extensions"};
288f0ba2 16678static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16679 {"Not Allowed", "Allowed"};
11c1ff18 16680
288f0ba2 16681static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16682 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16683
99db83d0
AC
16684static const char * arm_attr_tag_PAC_extension[] =
16685 {"No PAC/AUT instructions",
16686 "PAC/AUT instructions permitted in the NOP space",
16687 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16688
4b535030
AC
16689static const char * arm_attr_tag_BTI_extension[] =
16690 {"BTI instructions not permitted",
16691 "BTI instructions permitted in the NOP space",
16692 "BTI instructions permitted in the NOP and in the non-NOP space"};
16693
b81ee92f
AC
16694static const char * arm_attr_tag_BTI_use[] =
16695 {"Compiled without branch target enforcement",
16696 "Compiled with branch target enforcement"};
16697
c9fed665
AC
16698static const char * arm_attr_tag_PACRET_use[] =
16699 {"Compiled without return address signing and authentication",
16700 "Compiled with return address signing and authentication"};
16701
11c1ff18
PB
16702#define LOOKUP(id, name) \
16703 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16704static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16705{
16706 {4, "CPU_raw_name", 1, NULL},
16707 {5, "CPU_name", 1, NULL},
16708 LOOKUP(6, CPU_arch),
16709 {7, "CPU_arch_profile", 0, NULL},
16710 LOOKUP(8, ARM_ISA_use),
16711 LOOKUP(9, THUMB_ISA_use),
75375b3e 16712 LOOKUP(10, FP_arch),
11c1ff18 16713 LOOKUP(11, WMMX_arch),
f5f53991
AS
16714 LOOKUP(12, Advanced_SIMD_arch),
16715 LOOKUP(13, PCS_config),
11c1ff18
PB
16716 LOOKUP(14, ABI_PCS_R9_use),
16717 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16718 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16719 LOOKUP(17, ABI_PCS_GOT_use),
16720 LOOKUP(18, ABI_PCS_wchar_t),
16721 LOOKUP(19, ABI_FP_rounding),
16722 LOOKUP(20, ABI_FP_denormal),
16723 LOOKUP(21, ABI_FP_exceptions),
16724 LOOKUP(22, ABI_FP_user_exceptions),
16725 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16726 {24, "ABI_align_needed", 0, NULL},
16727 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16728 LOOKUP(26, ABI_enum_size),
16729 LOOKUP(27, ABI_HardFP_use),
16730 LOOKUP(28, ABI_VFP_args),
16731 LOOKUP(29, ABI_WMMX_args),
16732 LOOKUP(30, ABI_optimization_goals),
16733 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16734 {32, "compatibility", 0, NULL},
f5f53991 16735 LOOKUP(34, CPU_unaligned_access),
75375b3e 16736 LOOKUP(36, FP_HP_extension),
8e79c3df 16737 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16738 LOOKUP(42, MPextension_use),
16739 LOOKUP(44, DIV_use),
15afaa63 16740 LOOKUP(46, DSP_extension),
a7ad558c 16741 LOOKUP(48, MVE_arch),
99db83d0 16742 LOOKUP(50, PAC_extension),
4b535030 16743 LOOKUP(52, BTI_extension),
b81ee92f 16744 LOOKUP(74, BTI_use),
c9fed665 16745 LOOKUP(76, PACRET_use),
f5f53991
AS
16746 {64, "nodefaults", 0, NULL},
16747 {65, "also_compatible_with", 0, NULL},
16748 LOOKUP(66, T2EE_use),
16749 {67, "conformance", 1, NULL},
16750 LOOKUP(68, Virtualization_use),
cd21e546 16751 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16752};
16753#undef LOOKUP
16754
11c1ff18 16755static unsigned char *
f6f0e17b
NC
16756display_arm_attribute (unsigned char * p,
16757 const unsigned char * const end)
11c1ff18 16758{
70e99720 16759 unsigned int tag;
70e99720 16760 unsigned int val;
2cf0635d 16761 arm_attr_public_tag * attr;
11c1ff18 16762 unsigned i;
70e99720 16763 unsigned int type;
11c1ff18 16764
cd30bcef 16765 READ_ULEB (tag, p, end);
11c1ff18 16766 attr = NULL;
2cf0635d 16767 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16768 {
16769 if (arm_attr_public_tags[i].tag == tag)
16770 {
16771 attr = &arm_attr_public_tags[i];
16772 break;
16773 }
16774 }
16775
16776 if (attr)
16777 {
16778 printf (" Tag_%s: ", attr->name);
16779 switch (attr->type)
16780 {
16781 case 0:
16782 switch (tag)
16783 {
16784 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16785 READ_ULEB (val, p, end);
11c1ff18
PB
16786 switch (val)
16787 {
2b692964
NC
16788 case 0: printf (_("None\n")); break;
16789 case 'A': printf (_("Application\n")); break;
16790 case 'R': printf (_("Realtime\n")); break;
16791 case 'M': printf (_("Microcontroller\n")); break;
16792 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16793 default: printf ("??? (%d)\n", val); break;
16794 }
16795 break;
16796
75375b3e 16797 case 24: /* Tag_align_needed. */
cd30bcef 16798 READ_ULEB (val, p, end);
75375b3e
MGD
16799 switch (val)
16800 {
2b692964
NC
16801 case 0: printf (_("None\n")); break;
16802 case 1: printf (_("8-byte\n")); break;
16803 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16804 case 3: printf ("??? 3\n"); break;
16805 default:
16806 if (val <= 12)
dd24e3da 16807 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16808 1 << val);
16809 else
16810 printf ("??? (%d)\n", val);
16811 break;
16812 }
16813 break;
16814
16815 case 25: /* Tag_align_preserved. */
cd30bcef 16816 READ_ULEB (val, p, end);
75375b3e
MGD
16817 switch (val)
16818 {
2b692964
NC
16819 case 0: printf (_("None\n")); break;
16820 case 1: printf (_("8-byte, except leaf SP\n")); break;
16821 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16822 case 3: printf ("??? 3\n"); break;
16823 default:
16824 if (val <= 12)
dd24e3da 16825 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16826 1 << val);
16827 else
16828 printf ("??? (%d)\n", val);
16829 break;
16830 }
16831 break;
16832
11c1ff18 16833 case 32: /* Tag_compatibility. */
071436c6 16834 {
cd30bcef 16835 READ_ULEB (val, p, end);
071436c6 16836 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16837 if (p < end - 1)
16838 {
16839 size_t maxlen = (end - p) - 1;
16840
16841 print_symbol ((int) maxlen, (const char *) p);
16842 p += strnlen ((char *) p, maxlen) + 1;
16843 }
16844 else
16845 {
16846 printf (_("<corrupt>"));
16847 p = (unsigned char *) end;
16848 }
071436c6 16849 putchar ('\n');
071436c6 16850 }
11c1ff18
PB
16851 break;
16852
f5f53991 16853 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16854 /* PR 17531: file: 001-505008-0.01. */
16855 if (p < end)
16856 p++;
2b692964 16857 printf (_("True\n"));
f5f53991
AS
16858 break;
16859
16860 case 65: /* Tag_also_compatible_with. */
cd30bcef 16861 READ_ULEB (val, p, end);
f5f53991
AS
16862 if (val == 6 /* Tag_CPU_arch. */)
16863 {
cd30bcef 16864 READ_ULEB (val, p, end);
071436c6 16865 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16866 printf ("??? (%d)\n", val);
16867 else
16868 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16869 }
16870 else
16871 printf ("???\n");
071436c6
NC
16872 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16873 ;
f5f53991
AS
16874 break;
16875
11c1ff18 16876 default:
bee0ee85
NC
16877 printf (_("<unknown: %d>\n"), tag);
16878 break;
11c1ff18
PB
16879 }
16880 return p;
16881
16882 case 1:
f6f0e17b 16883 return display_tag_value (-1, p, end);
11c1ff18 16884 case 2:
f6f0e17b 16885 return display_tag_value (0, p, end);
11c1ff18
PB
16886
16887 default:
16888 assert (attr->type & 0x80);
cd30bcef 16889 READ_ULEB (val, p, end);
11c1ff18
PB
16890 type = attr->type & 0x7f;
16891 if (val >= type)
16892 printf ("??? (%d)\n", val);
16893 else
16894 printf ("%s\n", attr->table[val]);
16895 return p;
16896 }
16897 }
11c1ff18 16898
f6f0e17b 16899 return display_tag_value (tag, p, end);
11c1ff18
PB
16900}
16901
104d59d1 16902static unsigned char *
60bca95a 16903display_gnu_attribute (unsigned char * p,
60abdbed 16904 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16905 const unsigned char * const end)
104d59d1 16906{
cd30bcef 16907 unsigned int tag;
60abdbed 16908 unsigned int val;
104d59d1 16909
cd30bcef 16910 READ_ULEB (tag, p, end);
104d59d1
JM
16911
16912 /* Tag_compatibility is the only generic GNU attribute defined at
16913 present. */
16914 if (tag == 32)
16915 {
cd30bcef 16916 READ_ULEB (val, p, end);
071436c6
NC
16917
16918 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16919 if (p == end)
16920 {
071436c6 16921 printf (_("<corrupt>\n"));
f6f0e17b
NC
16922 warn (_("corrupt vendor attribute\n"));
16923 }
16924 else
16925 {
4082ef84
NC
16926 if (p < end - 1)
16927 {
16928 size_t maxlen = (end - p) - 1;
071436c6 16929
4082ef84
NC
16930 print_symbol ((int) maxlen, (const char *) p);
16931 p += strnlen ((char *) p, maxlen) + 1;
16932 }
16933 else
16934 {
16935 printf (_("<corrupt>"));
16936 p = (unsigned char *) end;
16937 }
071436c6 16938 putchar ('\n');
f6f0e17b 16939 }
104d59d1
JM
16940 return p;
16941 }
16942
16943 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16944 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16945
f6f0e17b 16946 return display_tag_value (tag, p, end);
104d59d1
JM
16947}
16948
85f7484a
PB
16949static unsigned char *
16950display_m68k_gnu_attribute (unsigned char * p,
16951 unsigned int tag,
16952 const unsigned char * const end)
16953{
16954 unsigned int val;
16955
16956 if (tag == Tag_GNU_M68K_ABI_FP)
16957 {
16958 printf (" Tag_GNU_M68K_ABI_FP: ");
16959 if (p == end)
16960 {
16961 printf (_("<corrupt>\n"));
16962 return p;
16963 }
16964 READ_ULEB (val, p, end);
16965
16966 if (val > 3)
16967 printf ("(%#x), ", val);
16968
16969 switch (val & 3)
16970 {
16971 case 0:
16972 printf (_("unspecified hard/soft float\n"));
16973 break;
16974 case 1:
16975 printf (_("hard float\n"));
16976 break;
16977 case 2:
16978 printf (_("soft float\n"));
16979 break;
16980 }
16981 return p;
16982 }
16983
16984 return display_tag_value (tag & 1, p, end);
16985}
16986
34c8bcba 16987static unsigned char *
f6f0e17b 16988display_power_gnu_attribute (unsigned char * p,
60abdbed 16989 unsigned int tag,
f6f0e17b 16990 const unsigned char * const end)
34c8bcba 16991{
005d79fd 16992 unsigned int val;
34c8bcba
JM
16993
16994 if (tag == Tag_GNU_Power_ABI_FP)
16995 {
34c8bcba 16996 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16997 if (p == end)
005d79fd
AM
16998 {
16999 printf (_("<corrupt>\n"));
17000 return p;
17001 }
cd30bcef 17002 READ_ULEB (val, p, end);
60bca95a 17003
005d79fd
AM
17004 if (val > 15)
17005 printf ("(%#x), ", val);
17006
17007 switch (val & 3)
34c8bcba
JM
17008 {
17009 case 0:
005d79fd 17010 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17011 break;
17012 case 1:
005d79fd 17013 printf (_("hard float, "));
34c8bcba
JM
17014 break;
17015 case 2:
005d79fd 17016 printf (_("soft float, "));
34c8bcba 17017 break;
3c7b9897 17018 case 3:
005d79fd 17019 printf (_("single-precision hard float, "));
3c7b9897 17020 break;
005d79fd
AM
17021 }
17022
17023 switch (val & 0xC)
17024 {
17025 case 0:
17026 printf (_("unspecified long double\n"));
17027 break;
17028 case 4:
17029 printf (_("128-bit IBM long double\n"));
17030 break;
17031 case 8:
17032 printf (_("64-bit long double\n"));
17033 break;
17034 case 12:
17035 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17036 break;
17037 }
17038 return p;
005d79fd 17039 }
34c8bcba 17040
c6e65352
DJ
17041 if (tag == Tag_GNU_Power_ABI_Vector)
17042 {
c6e65352 17043 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17044 if (p == end)
005d79fd
AM
17045 {
17046 printf (_("<corrupt>\n"));
17047 return p;
17048 }
cd30bcef 17049 READ_ULEB (val, p, end);
005d79fd
AM
17050
17051 if (val > 3)
17052 printf ("(%#x), ", val);
17053
17054 switch (val & 3)
c6e65352
DJ
17055 {
17056 case 0:
005d79fd 17057 printf (_("unspecified\n"));
c6e65352
DJ
17058 break;
17059 case 1:
005d79fd 17060 printf (_("generic\n"));
c6e65352
DJ
17061 break;
17062 case 2:
17063 printf ("AltiVec\n");
17064 break;
17065 case 3:
17066 printf ("SPE\n");
17067 break;
c6e65352
DJ
17068 }
17069 return p;
005d79fd 17070 }
c6e65352 17071
f82e0623
NF
17072 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17073 {
005d79fd 17074 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17075 if (p == end)
f6f0e17b 17076 {
005d79fd 17077 printf (_("<corrupt>\n"));
f6f0e17b
NC
17078 return p;
17079 }
cd30bcef 17080 READ_ULEB (val, p, end);
0b4362b0 17081
005d79fd
AM
17082 if (val > 2)
17083 printf ("(%#x), ", val);
17084
17085 switch (val & 3)
17086 {
17087 case 0:
17088 printf (_("unspecified\n"));
17089 break;
17090 case 1:
17091 printf ("r3/r4\n");
17092 break;
17093 case 2:
17094 printf (_("memory\n"));
17095 break;
17096 case 3:
17097 printf ("???\n");
17098 break;
17099 }
f82e0623
NF
17100 return p;
17101 }
17102
f6f0e17b 17103 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17104}
17105
643f7afb
AK
17106static unsigned char *
17107display_s390_gnu_attribute (unsigned char * p,
60abdbed 17108 unsigned int tag,
643f7afb
AK
17109 const unsigned char * const end)
17110{
cd30bcef 17111 unsigned int val;
643f7afb
AK
17112
17113 if (tag == Tag_GNU_S390_ABI_Vector)
17114 {
643f7afb 17115 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17116 READ_ULEB (val, p, end);
643f7afb
AK
17117
17118 switch (val)
17119 {
17120 case 0:
17121 printf (_("any\n"));
17122 break;
17123 case 1:
17124 printf (_("software\n"));
17125 break;
17126 case 2:
17127 printf (_("hardware\n"));
17128 break;
17129 default:
17130 printf ("??? (%d)\n", val);
17131 break;
17132 }
17133 return p;
17134 }
17135
17136 return display_tag_value (tag & 1, p, end);
17137}
17138
9e8c70f9 17139static void
60abdbed 17140display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17141{
17142 if (mask)
17143 {
015dc7e1 17144 bool first = true;
071436c6 17145
9e8c70f9 17146 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17147 fputs ("mul32", stdout), first = false;
9e8c70f9 17148 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17149 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17150 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17151 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17152 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17153 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17154 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17155 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17156 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17157 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17158 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17159 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17160 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17161 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17162 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17163 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17164 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17165 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17166 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17167 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17168 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17169 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17170 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17171 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17172 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17173 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17174 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17175 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17176 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17177 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17178 }
17179 else
071436c6
NC
17180 fputc ('0', stdout);
17181 fputc ('\n', stdout);
9e8c70f9
DM
17182}
17183
3d68f91c 17184static void
60abdbed 17185display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17186{
17187 if (mask)
17188 {
015dc7e1 17189 bool first = true;
071436c6 17190
3d68f91c 17191 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17192 fputs ("fjathplus", stdout), first = false;
3d68f91c 17193 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17194 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17195 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17196 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17197 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17198 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17199 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17200 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17201 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17202 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17203 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17204 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17205 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17206 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17207 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17208 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17209 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17210 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17211 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17212 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17213 }
17214 else
071436c6
NC
17215 fputc ('0', stdout);
17216 fputc ('\n', stdout);
3d68f91c
JM
17217}
17218
9e8c70f9 17219static unsigned char *
f6f0e17b 17220display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17221 unsigned int tag,
f6f0e17b 17222 const unsigned char * const end)
9e8c70f9 17223{
cd30bcef 17224 unsigned int val;
3d68f91c 17225
9e8c70f9
DM
17226 if (tag == Tag_GNU_Sparc_HWCAPS)
17227 {
cd30bcef 17228 READ_ULEB (val, p, end);
9e8c70f9 17229 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17230 display_sparc_hwcaps (val);
17231 return p;
3d68f91c
JM
17232 }
17233 if (tag == Tag_GNU_Sparc_HWCAPS2)
17234 {
cd30bcef 17235 READ_ULEB (val, p, end);
3d68f91c
JM
17236 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17237 display_sparc_hwcaps2 (val);
17238 return p;
17239 }
9e8c70f9 17240
f6f0e17b 17241 return display_tag_value (tag, p, end);
9e8c70f9
DM
17242}
17243
351cdf24 17244static void
32ec8896 17245print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17246{
17247 switch (val)
17248 {
17249 case Val_GNU_MIPS_ABI_FP_ANY:
17250 printf (_("Hard or soft float\n"));
17251 break;
17252 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17253 printf (_("Hard float (double precision)\n"));
17254 break;
17255 case Val_GNU_MIPS_ABI_FP_SINGLE:
17256 printf (_("Hard float (single precision)\n"));
17257 break;
17258 case Val_GNU_MIPS_ABI_FP_SOFT:
17259 printf (_("Soft float\n"));
17260 break;
17261 case Val_GNU_MIPS_ABI_FP_OLD_64:
17262 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17263 break;
17264 case Val_GNU_MIPS_ABI_FP_XX:
17265 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17266 break;
17267 case Val_GNU_MIPS_ABI_FP_64:
17268 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17269 break;
17270 case Val_GNU_MIPS_ABI_FP_64A:
17271 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17272 break;
3350cc01
CM
17273 case Val_GNU_MIPS_ABI_FP_NAN2008:
17274 printf (_("NaN 2008 compatibility\n"));
17275 break;
351cdf24
MF
17276 default:
17277 printf ("??? (%d)\n", val);
17278 break;
17279 }
17280}
17281
2cf19d5c 17282static unsigned char *
f6f0e17b 17283display_mips_gnu_attribute (unsigned char * p,
60abdbed 17284 unsigned int tag,
f6f0e17b 17285 const unsigned char * const end)
2cf19d5c 17286{
2cf19d5c
JM
17287 if (tag == Tag_GNU_MIPS_ABI_FP)
17288 {
32ec8896 17289 unsigned int val;
f6f0e17b 17290
2cf19d5c 17291 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17292 READ_ULEB (val, p, end);
351cdf24 17293 print_mips_fp_abi_value (val);
2cf19d5c
JM
17294 return p;
17295 }
17296
a9f58168
CF
17297 if (tag == Tag_GNU_MIPS_ABI_MSA)
17298 {
32ec8896 17299 unsigned int val;
a9f58168 17300
a9f58168 17301 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17302 READ_ULEB (val, p, end);
a9f58168
CF
17303
17304 switch (val)
17305 {
17306 case Val_GNU_MIPS_ABI_MSA_ANY:
17307 printf (_("Any MSA or not\n"));
17308 break;
17309 case Val_GNU_MIPS_ABI_MSA_128:
17310 printf (_("128-bit MSA\n"));
17311 break;
17312 default:
17313 printf ("??? (%d)\n", val);
17314 break;
17315 }
17316 return p;
17317 }
17318
f6f0e17b 17319 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17320}
17321
59e6276b 17322static unsigned char *
f6f0e17b
NC
17323display_tic6x_attribute (unsigned char * p,
17324 const unsigned char * const end)
59e6276b 17325{
60abdbed 17326 unsigned int tag;
cd30bcef 17327 unsigned int val;
59e6276b 17328
cd30bcef 17329 READ_ULEB (tag, p, end);
59e6276b
JM
17330
17331 switch (tag)
17332 {
75fa6dc1 17333 case Tag_ISA:
75fa6dc1 17334 printf (" Tag_ISA: ");
cd30bcef 17335 READ_ULEB (val, p, end);
59e6276b
JM
17336
17337 switch (val)
17338 {
75fa6dc1 17339 case C6XABI_Tag_ISA_none:
59e6276b
JM
17340 printf (_("None\n"));
17341 break;
75fa6dc1 17342 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17343 printf ("C62x\n");
17344 break;
75fa6dc1 17345 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17346 printf ("C67x\n");
17347 break;
75fa6dc1 17348 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17349 printf ("C67x+\n");
17350 break;
75fa6dc1 17351 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17352 printf ("C64x\n");
17353 break;
75fa6dc1 17354 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17355 printf ("C64x+\n");
17356 break;
75fa6dc1 17357 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17358 printf ("C674x\n");
17359 break;
17360 default:
17361 printf ("??? (%d)\n", val);
17362 break;
17363 }
17364 return p;
17365
87779176 17366 case Tag_ABI_wchar_t:
87779176 17367 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17368 READ_ULEB (val, p, end);
87779176
JM
17369 switch (val)
17370 {
17371 case 0:
17372 printf (_("Not used\n"));
17373 break;
17374 case 1:
17375 printf (_("2 bytes\n"));
17376 break;
17377 case 2:
17378 printf (_("4 bytes\n"));
17379 break;
17380 default:
17381 printf ("??? (%d)\n", val);
17382 break;
17383 }
17384 return p;
17385
17386 case Tag_ABI_stack_align_needed:
87779176 17387 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17388 READ_ULEB (val, p, end);
87779176
JM
17389 switch (val)
17390 {
17391 case 0:
17392 printf (_("8-byte\n"));
17393 break;
17394 case 1:
17395 printf (_("16-byte\n"));
17396 break;
17397 default:
17398 printf ("??? (%d)\n", val);
17399 break;
17400 }
17401 return p;
17402
17403 case Tag_ABI_stack_align_preserved:
cd30bcef 17404 READ_ULEB (val, p, end);
87779176
JM
17405 printf (" Tag_ABI_stack_align_preserved: ");
17406 switch (val)
17407 {
17408 case 0:
17409 printf (_("8-byte\n"));
17410 break;
17411 case 1:
17412 printf (_("16-byte\n"));
17413 break;
17414 default:
17415 printf ("??? (%d)\n", val);
17416 break;
17417 }
17418 return p;
17419
b5593623 17420 case Tag_ABI_DSBT:
cd30bcef 17421 READ_ULEB (val, p, end);
b5593623
JM
17422 printf (" Tag_ABI_DSBT: ");
17423 switch (val)
17424 {
17425 case 0:
17426 printf (_("DSBT addressing not used\n"));
17427 break;
17428 case 1:
17429 printf (_("DSBT addressing used\n"));
17430 break;
17431 default:
17432 printf ("??? (%d)\n", val);
17433 break;
17434 }
17435 return p;
17436
87779176 17437 case Tag_ABI_PID:
cd30bcef 17438 READ_ULEB (val, p, end);
87779176
JM
17439 printf (" Tag_ABI_PID: ");
17440 switch (val)
17441 {
17442 case 0:
17443 printf (_("Data addressing position-dependent\n"));
17444 break;
17445 case 1:
17446 printf (_("Data addressing position-independent, GOT near DP\n"));
17447 break;
17448 case 2:
17449 printf (_("Data addressing position-independent, GOT far from DP\n"));
17450 break;
17451 default:
17452 printf ("??? (%d)\n", val);
17453 break;
17454 }
17455 return p;
17456
17457 case Tag_ABI_PIC:
cd30bcef 17458 READ_ULEB (val, p, end);
87779176
JM
17459 printf (" Tag_ABI_PIC: ");
17460 switch (val)
17461 {
17462 case 0:
17463 printf (_("Code addressing position-dependent\n"));
17464 break;
17465 case 1:
17466 printf (_("Code addressing position-independent\n"));
17467 break;
17468 default:
17469 printf ("??? (%d)\n", val);
17470 break;
17471 }
17472 return p;
17473
17474 case Tag_ABI_array_object_alignment:
cd30bcef 17475 READ_ULEB (val, p, end);
87779176
JM
17476 printf (" Tag_ABI_array_object_alignment: ");
17477 switch (val)
17478 {
17479 case 0:
17480 printf (_("8-byte\n"));
17481 break;
17482 case 1:
17483 printf (_("4-byte\n"));
17484 break;
17485 case 2:
17486 printf (_("16-byte\n"));
17487 break;
17488 default:
17489 printf ("??? (%d)\n", val);
17490 break;
17491 }
17492 return p;
17493
17494 case Tag_ABI_array_object_align_expected:
cd30bcef 17495 READ_ULEB (val, p, end);
87779176
JM
17496 printf (" Tag_ABI_array_object_align_expected: ");
17497 switch (val)
17498 {
17499 case 0:
17500 printf (_("8-byte\n"));
17501 break;
17502 case 1:
17503 printf (_("4-byte\n"));
17504 break;
17505 case 2:
17506 printf (_("16-byte\n"));
17507 break;
17508 default:
17509 printf ("??? (%d)\n", val);
17510 break;
17511 }
17512 return p;
17513
3cbd1c06 17514 case Tag_ABI_compatibility:
071436c6 17515 {
cd30bcef 17516 READ_ULEB (val, p, end);
071436c6 17517 printf (" Tag_ABI_compatibility: ");
071436c6 17518 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17519 if (p < end - 1)
17520 {
17521 size_t maxlen = (end - p) - 1;
17522
17523 print_symbol ((int) maxlen, (const char *) p);
17524 p += strnlen ((char *) p, maxlen) + 1;
17525 }
17526 else
17527 {
17528 printf (_("<corrupt>"));
17529 p = (unsigned char *) end;
17530 }
071436c6 17531 putchar ('\n');
071436c6
NC
17532 return p;
17533 }
87779176
JM
17534
17535 case Tag_ABI_conformance:
071436c6 17536 {
4082ef84
NC
17537 printf (" Tag_ABI_conformance: \"");
17538 if (p < end - 1)
17539 {
17540 size_t maxlen = (end - p) - 1;
071436c6 17541
4082ef84
NC
17542 print_symbol ((int) maxlen, (const char *) p);
17543 p += strnlen ((char *) p, maxlen) + 1;
17544 }
17545 else
17546 {
17547 printf (_("<corrupt>"));
17548 p = (unsigned char *) end;
17549 }
071436c6 17550 printf ("\"\n");
071436c6
NC
17551 return p;
17552 }
59e6276b
JM
17553 }
17554
f6f0e17b
NC
17555 return display_tag_value (tag, p, end);
17556}
59e6276b 17557
f6f0e17b 17558static void
60abdbed 17559display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17560{
17561 unsigned long addr = 0;
17562 size_t bytes = end - p;
17563
feceaa59 17564 assert (end >= p);
f6f0e17b 17565 while (bytes)
87779176 17566 {
f6f0e17b
NC
17567 int j;
17568 int k;
17569 int lbytes = (bytes > 16 ? 16 : bytes);
17570
17571 printf (" 0x%8.8lx ", addr);
17572
17573 for (j = 0; j < 16; j++)
17574 {
17575 if (j < lbytes)
17576 printf ("%2.2x", p[j]);
17577 else
17578 printf (" ");
17579
17580 if ((j & 3) == 3)
17581 printf (" ");
17582 }
17583
17584 for (j = 0; j < lbytes; j++)
17585 {
17586 k = p[j];
17587 if (k >= ' ' && k < 0x7f)
17588 printf ("%c", k);
17589 else
17590 printf (".");
17591 }
17592
17593 putchar ('\n');
17594
17595 p += lbytes;
17596 bytes -= lbytes;
17597 addr += lbytes;
87779176 17598 }
59e6276b 17599
f6f0e17b 17600 putchar ('\n');
59e6276b
JM
17601}
17602
13761a11 17603static unsigned char *
b0191216 17604display_msp430_attribute (unsigned char * p,
13761a11
NC
17605 const unsigned char * const end)
17606{
60abdbed
NC
17607 unsigned int val;
17608 unsigned int tag;
13761a11 17609
cd30bcef 17610 READ_ULEB (tag, p, end);
0b4362b0 17611
13761a11
NC
17612 switch (tag)
17613 {
17614 case OFBA_MSPABI_Tag_ISA:
13761a11 17615 printf (" Tag_ISA: ");
cd30bcef 17616 READ_ULEB (val, p, end);
13761a11
NC
17617 switch (val)
17618 {
17619 case 0: printf (_("None\n")); break;
17620 case 1: printf (_("MSP430\n")); break;
17621 case 2: printf (_("MSP430X\n")); break;
17622 default: printf ("??? (%d)\n", val); break;
17623 }
17624 break;
17625
17626 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17627 printf (" Tag_Code_Model: ");
cd30bcef 17628 READ_ULEB (val, p, end);
13761a11
NC
17629 switch (val)
17630 {
17631 case 0: printf (_("None\n")); break;
17632 case 1: printf (_("Small\n")); break;
17633 case 2: printf (_("Large\n")); break;
17634 default: printf ("??? (%d)\n", val); break;
17635 }
17636 break;
17637
17638 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17639 printf (" Tag_Data_Model: ");
cd30bcef 17640 READ_ULEB (val, p, end);
13761a11
NC
17641 switch (val)
17642 {
17643 case 0: printf (_("None\n")); break;
17644 case 1: printf (_("Small\n")); break;
17645 case 2: printf (_("Large\n")); break;
17646 case 3: printf (_("Restricted Large\n")); break;
17647 default: printf ("??? (%d)\n", val); break;
17648 }
17649 break;
17650
17651 default:
17652 printf (_(" <unknown tag %d>: "), tag);
17653
17654 if (tag & 1)
17655 {
071436c6 17656 putchar ('"');
4082ef84
NC
17657 if (p < end - 1)
17658 {
17659 size_t maxlen = (end - p) - 1;
17660
17661 print_symbol ((int) maxlen, (const char *) p);
17662 p += strnlen ((char *) p, maxlen) + 1;
17663 }
17664 else
17665 {
17666 printf (_("<corrupt>"));
17667 p = (unsigned char *) end;
17668 }
071436c6 17669 printf ("\"\n");
13761a11
NC
17670 }
17671 else
17672 {
cd30bcef 17673 READ_ULEB (val, p, end);
13761a11
NC
17674 printf ("%d (0x%x)\n", val, val);
17675 }
17676 break;
17677 }
17678
4082ef84 17679 assert (p <= end);
13761a11
NC
17680 return p;
17681}
17682
c0ea7c52
JL
17683static unsigned char *
17684display_msp430_gnu_attribute (unsigned char * p,
17685 unsigned int tag,
17686 const unsigned char * const end)
17687{
17688 if (tag == Tag_GNU_MSP430_Data_Region)
17689 {
cd30bcef 17690 unsigned int val;
c0ea7c52 17691
c0ea7c52 17692 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17693 READ_ULEB (val, p, end);
c0ea7c52
JL
17694
17695 switch (val)
17696 {
17697 case Val_GNU_MSP430_Data_Region_Any:
17698 printf (_("Any Region\n"));
17699 break;
17700 case Val_GNU_MSP430_Data_Region_Lower:
17701 printf (_("Lower Region Only\n"));
17702 break;
17703 default:
cd30bcef 17704 printf ("??? (%u)\n", val);
c0ea7c52
JL
17705 }
17706 return p;
17707 }
17708 return display_tag_value (tag & 1, p, end);
17709}
17710
2dc8dd17
JW
17711struct riscv_attr_tag_t {
17712 const char *name;
cd30bcef 17713 unsigned int tag;
2dc8dd17
JW
17714};
17715
17716static struct riscv_attr_tag_t riscv_attr_tag[] =
17717{
17718#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17719 T(arch),
17720 T(priv_spec),
17721 T(priv_spec_minor),
17722 T(priv_spec_revision),
17723 T(unaligned_access),
17724 T(stack_align),
17725#undef T
17726};
17727
17728static unsigned char *
17729display_riscv_attribute (unsigned char *p,
17730 const unsigned char * const end)
17731{
cd30bcef
AM
17732 unsigned int val;
17733 unsigned int tag;
2dc8dd17
JW
17734 struct riscv_attr_tag_t *attr = NULL;
17735 unsigned i;
17736
cd30bcef 17737 READ_ULEB (tag, p, end);
2dc8dd17
JW
17738
17739 /* Find the name of attribute. */
17740 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17741 {
17742 if (riscv_attr_tag[i].tag == tag)
17743 {
17744 attr = &riscv_attr_tag[i];
17745 break;
17746 }
17747 }
17748
17749 if (attr)
17750 printf (" %s: ", attr->name);
17751 else
17752 return display_tag_value (tag, p, end);
17753
17754 switch (tag)
17755 {
17756 case Tag_RISCV_priv_spec:
17757 case Tag_RISCV_priv_spec_minor:
17758 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17759 READ_ULEB (val, p, end);
17760 printf (_("%u\n"), val);
2dc8dd17
JW
17761 break;
17762 case Tag_RISCV_unaligned_access:
cd30bcef 17763 READ_ULEB (val, p, end);
2dc8dd17
JW
17764 switch (val)
17765 {
17766 case 0:
17767 printf (_("No unaligned access\n"));
17768 break;
17769 case 1:
17770 printf (_("Unaligned access\n"));
17771 break;
17772 }
17773 break;
17774 case Tag_RISCV_stack_align:
cd30bcef
AM
17775 READ_ULEB (val, p, end);
17776 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17777 break;
17778 case Tag_RISCV_arch:
17779 p = display_tag_value (-1, p, end);
17780 break;
17781 default:
17782 return display_tag_value (tag, p, end);
17783 }
17784
17785 return p;
17786}
17787
0861f561
CQ
17788static unsigned char *
17789display_csky_attribute (unsigned char * p,
17790 const unsigned char * const end)
17791{
17792 unsigned int tag;
17793 unsigned int val;
17794 READ_ULEB (tag, p, end);
17795
17796 if (tag >= Tag_CSKY_MAX)
17797 {
17798 return display_tag_value (-1, p, end);
17799 }
17800
17801 switch (tag)
17802 {
17803 case Tag_CSKY_ARCH_NAME:
17804 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17805 return display_tag_value (-1, p, end);
17806 case Tag_CSKY_CPU_NAME:
17807 printf (" Tag_CSKY_CPU_NAME:\t\t");
17808 return display_tag_value (-1, p, end);
17809
17810 case Tag_CSKY_ISA_FLAGS:
17811 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17812 return display_tag_value (0, p, end);
17813 case Tag_CSKY_ISA_EXT_FLAGS:
17814 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17815 return display_tag_value (0, p, end);
17816
17817 case Tag_CSKY_DSP_VERSION:
17818 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17819 READ_ULEB (val, p, end);
17820 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17821 printf ("DSP Extension\n");
17822 else if (val == VAL_CSKY_DSP_VERSION_2)
17823 printf ("DSP 2.0\n");
17824 break;
17825
17826 case Tag_CSKY_VDSP_VERSION:
17827 printf (" Tag_CSKY_VDSP_VERSION:\t");
17828 READ_ULEB (val, p, end);
17829 printf ("VDSP Version %d\n", val);
17830 break;
17831
17832 case Tag_CSKY_FPU_VERSION:
17833 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17834 READ_ULEB (val, p, end);
17835 if (val == VAL_CSKY_FPU_VERSION_1)
17836 printf ("ABIV1 FPU Version 1\n");
17837 else if (val == VAL_CSKY_FPU_VERSION_2)
17838 printf ("FPU Version 2\n");
17839 break;
17840
17841 case Tag_CSKY_FPU_ABI:
17842 printf (" Tag_CSKY_FPU_ABI:\t\t");
17843 READ_ULEB (val, p, end);
17844 if (val == VAL_CSKY_FPU_ABI_HARD)
17845 printf ("Hard\n");
17846 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17847 printf ("SoftFP\n");
17848 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17849 printf ("Soft\n");
17850 break;
17851 case Tag_CSKY_FPU_ROUNDING:
17852 READ_ULEB (val, p, end);
f253158f
NC
17853 if (val == 1)
17854 {
17855 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17856 printf ("Needed\n");
17857 }
0861f561
CQ
17858 break;
17859 case Tag_CSKY_FPU_DENORMAL:
17860 READ_ULEB (val, p, end);
f253158f
NC
17861 if (val == 1)
17862 {
17863 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17864 printf ("Needed\n");
17865 }
0861f561
CQ
17866 break;
17867 case Tag_CSKY_FPU_Exception:
17868 READ_ULEB (val, p, end);
f253158f
NC
17869 if (val == 1)
17870 {
17871 printf (" Tag_CSKY_FPU_Exception:\t");
17872 printf ("Needed\n");
17873 }
0861f561
CQ
17874 break;
17875 case Tag_CSKY_FPU_NUMBER_MODULE:
17876 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17877 return display_tag_value (-1, p, end);
17878 case Tag_CSKY_FPU_HARDFP:
17879 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17880 READ_ULEB (val, p, end);
17881 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17882 printf (" Half");
17883 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17884 printf (" Single");
17885 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17886 printf (" Double");
17887 printf ("\n");
17888 break;
17889 default:
17890 return display_tag_value (tag, p, end);
17891 }
17892 return p;
17893}
17894
015dc7e1 17895static bool
dda8d76d 17896process_attributes (Filedata * filedata,
60bca95a 17897 const char * public_name,
104d59d1 17898 unsigned int proc_type,
f6f0e17b 17899 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17900 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17901{
2cf0635d 17902 Elf_Internal_Shdr * sect;
11c1ff18 17903 unsigned i;
015dc7e1 17904 bool res = true;
11c1ff18
PB
17905
17906 /* Find the section header so that we get the size. */
dda8d76d
NC
17907 for (i = 0, sect = filedata->section_headers;
17908 i < filedata->file_header.e_shnum;
11c1ff18
PB
17909 i++, sect++)
17910 {
071436c6
NC
17911 unsigned char * contents;
17912 unsigned char * p;
17913
104d59d1 17914 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17915 continue;
17916
dda8d76d 17917 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17918 sect->sh_size, _("attributes"));
60bca95a 17919 if (contents == NULL)
32ec8896 17920 {
015dc7e1 17921 res = false;
32ec8896
NC
17922 continue;
17923 }
60bca95a 17924
11c1ff18 17925 p = contents;
60abdbed
NC
17926 /* The first character is the version of the attributes.
17927 Currently only version 1, (aka 'A') is recognised here. */
17928 if (*p != 'A')
32ec8896
NC
17929 {
17930 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17931 res = false;
32ec8896 17932 }
60abdbed 17933 else
11c1ff18 17934 {
071436c6
NC
17935 bfd_vma section_len;
17936
17937 section_len = sect->sh_size - 1;
11c1ff18 17938 p++;
60bca95a 17939
071436c6 17940 while (section_len > 0)
11c1ff18 17941 {
071436c6 17942 bfd_vma attr_len;
e9847026 17943 unsigned int namelen;
015dc7e1
AM
17944 bool public_section;
17945 bool gnu_section;
11c1ff18 17946
071436c6 17947 if (section_len <= 4)
e0a31db1
NC
17948 {
17949 error (_("Tag section ends prematurely\n"));
015dc7e1 17950 res = false;
e0a31db1
NC
17951 break;
17952 }
071436c6 17953 attr_len = byte_get (p, 4);
11c1ff18 17954 p += 4;
60bca95a 17955
071436c6 17956 if (attr_len > section_len)
11c1ff18 17957 {
071436c6
NC
17958 error (_("Bad attribute length (%u > %u)\n"),
17959 (unsigned) attr_len, (unsigned) section_len);
17960 attr_len = section_len;
015dc7e1 17961 res = false;
11c1ff18 17962 }
74e1a04b 17963 /* PR 17531: file: 001-101425-0.004 */
071436c6 17964 else if (attr_len < 5)
74e1a04b 17965 {
071436c6 17966 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17967 res = false;
74e1a04b
NC
17968 break;
17969 }
e9847026 17970
071436c6
NC
17971 section_len -= attr_len;
17972 attr_len -= 4;
17973
17974 namelen = strnlen ((char *) p, attr_len) + 1;
17975 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17976 {
17977 error (_("Corrupt attribute section name\n"));
015dc7e1 17978 res = false;
e9847026
NC
17979 break;
17980 }
17981
071436c6
NC
17982 printf (_("Attribute Section: "));
17983 print_symbol (INT_MAX, (const char *) p);
17984 putchar ('\n');
60bca95a
NC
17985
17986 if (public_name && streq ((char *) p, public_name))
015dc7e1 17987 public_section = true;
11c1ff18 17988 else
015dc7e1 17989 public_section = false;
60bca95a
NC
17990
17991 if (streq ((char *) p, "gnu"))
015dc7e1 17992 gnu_section = true;
104d59d1 17993 else
015dc7e1 17994 gnu_section = false;
60bca95a 17995
11c1ff18 17996 p += namelen;
071436c6 17997 attr_len -= namelen;
e0a31db1 17998
071436c6 17999 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18000 {
e0a31db1 18001 int tag;
cd30bcef 18002 unsigned int val;
11c1ff18 18003 bfd_vma size;
071436c6 18004 unsigned char * end;
60bca95a 18005
e0a31db1 18006 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18007 if (attr_len < 6)
e0a31db1
NC
18008 {
18009 error (_("Unused bytes at end of section\n"));
015dc7e1 18010 res = false;
e0a31db1
NC
18011 section_len = 0;
18012 break;
18013 }
18014
18015 tag = *(p++);
11c1ff18 18016 size = byte_get (p, 4);
071436c6 18017 if (size > attr_len)
11c1ff18 18018 {
e9847026 18019 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18020 (unsigned) size, (unsigned) attr_len);
015dc7e1 18021 res = false;
071436c6 18022 size = attr_len;
11c1ff18 18023 }
e0a31db1
NC
18024 /* PR binutils/17531: Safe handling of corrupt files. */
18025 if (size < 6)
18026 {
18027 error (_("Bad subsection length (%u < 6)\n"),
18028 (unsigned) size);
015dc7e1 18029 res = false;
e0a31db1
NC
18030 section_len = 0;
18031 break;
18032 }
60bca95a 18033
071436c6 18034 attr_len -= size;
11c1ff18 18035 end = p + size - 1;
071436c6 18036 assert (end <= contents + sect->sh_size);
11c1ff18 18037 p += 4;
60bca95a 18038
11c1ff18
PB
18039 switch (tag)
18040 {
18041 case 1:
2b692964 18042 printf (_("File Attributes\n"));
11c1ff18
PB
18043 break;
18044 case 2:
2b692964 18045 printf (_("Section Attributes:"));
11c1ff18
PB
18046 goto do_numlist;
18047 case 3:
2b692964 18048 printf (_("Symbol Attributes:"));
1a0670f3 18049 /* Fall through. */
11c1ff18
PB
18050 do_numlist:
18051 for (;;)
18052 {
cd30bcef 18053 READ_ULEB (val, p, end);
11c1ff18
PB
18054 if (val == 0)
18055 break;
18056 printf (" %d", val);
18057 }
18058 printf ("\n");
18059 break;
18060 default:
2b692964 18061 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18062 public_section = false;
11c1ff18
PB
18063 break;
18064 }
60bca95a 18065
071436c6 18066 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18067 {
18068 while (p < end)
f6f0e17b 18069 p = display_pub_attribute (p, end);
60abdbed 18070 assert (p == end);
104d59d1 18071 }
071436c6 18072 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18073 {
18074 while (p < end)
18075 p = display_gnu_attribute (p,
f6f0e17b
NC
18076 display_proc_gnu_attribute,
18077 end);
60abdbed 18078 assert (p == end);
11c1ff18 18079 }
071436c6 18080 else if (p < end)
11c1ff18 18081 {
071436c6 18082 printf (_(" Unknown attribute:\n"));
f6f0e17b 18083 display_raw_attribute (p, end);
11c1ff18
PB
18084 p = end;
18085 }
071436c6
NC
18086 else
18087 attr_len = 0;
11c1ff18
PB
18088 }
18089 }
18090 }
d70c5fc7 18091
60bca95a 18092 free (contents);
11c1ff18 18093 }
32ec8896
NC
18094
18095 return res;
11c1ff18
PB
18096}
18097
ccb4c951
RS
18098/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18099 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18100 and return the VMA of the next entry, or -1 if there was a problem.
18101 Does not read from DATA_END or beyond. */
ccb4c951
RS
18102
18103static bfd_vma
82b1b41b
NC
18104print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
18105 unsigned char * data_end)
ccb4c951
RS
18106{
18107 printf (" ");
18108 print_vma (addr, LONG_HEX);
18109 printf (" ");
18110 if (addr < pltgot + 0xfff0)
18111 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18112 else
18113 printf ("%10s", "");
18114 printf (" ");
18115 if (data == NULL)
2b692964 18116 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18117 else
18118 {
18119 bfd_vma entry;
82b1b41b 18120 unsigned char * from = data + addr - pltgot;
ccb4c951 18121
82b1b41b
NC
18122 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18123 {
18124 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18125 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18126 return (bfd_vma) -1;
18127 }
18128 else
18129 {
18130 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18131 print_vma (entry, LONG_HEX);
18132 }
ccb4c951
RS
18133 }
18134 return addr + (is_32bit_elf ? 4 : 8);
18135}
18136
861fb55a
DJ
18137/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18138 PLTGOT. Print the Address and Initial fields of an entry at VMA
18139 ADDR and return the VMA of the next entry. */
18140
18141static bfd_vma
2cf0635d 18142print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
18143{
18144 printf (" ");
18145 print_vma (addr, LONG_HEX);
18146 printf (" ");
18147 if (data == NULL)
2b692964 18148 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18149 else
18150 {
18151 bfd_vma entry;
18152
18153 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18154 print_vma (entry, LONG_HEX);
18155 }
18156 return addr + (is_32bit_elf ? 4 : 8);
18157}
18158
351cdf24
MF
18159static void
18160print_mips_ases (unsigned int mask)
18161{
18162 if (mask & AFL_ASE_DSP)
18163 fputs ("\n\tDSP ASE", stdout);
18164 if (mask & AFL_ASE_DSPR2)
18165 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18166 if (mask & AFL_ASE_DSPR3)
18167 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18168 if (mask & AFL_ASE_EVA)
18169 fputs ("\n\tEnhanced VA Scheme", stdout);
18170 if (mask & AFL_ASE_MCU)
18171 fputs ("\n\tMCU (MicroController) ASE", stdout);
18172 if (mask & AFL_ASE_MDMX)
18173 fputs ("\n\tMDMX ASE", stdout);
18174 if (mask & AFL_ASE_MIPS3D)
18175 fputs ("\n\tMIPS-3D ASE", stdout);
18176 if (mask & AFL_ASE_MT)
18177 fputs ("\n\tMT ASE", stdout);
18178 if (mask & AFL_ASE_SMARTMIPS)
18179 fputs ("\n\tSmartMIPS ASE", stdout);
18180 if (mask & AFL_ASE_VIRT)
18181 fputs ("\n\tVZ ASE", stdout);
18182 if (mask & AFL_ASE_MSA)
18183 fputs ("\n\tMSA ASE", stdout);
18184 if (mask & AFL_ASE_MIPS16)
18185 fputs ("\n\tMIPS16 ASE", stdout);
18186 if (mask & AFL_ASE_MICROMIPS)
18187 fputs ("\n\tMICROMIPS ASE", stdout);
18188 if (mask & AFL_ASE_XPA)
18189 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18190 if (mask & AFL_ASE_MIPS16E2)
18191 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18192 if (mask & AFL_ASE_CRC)
18193 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18194 if (mask & AFL_ASE_GINV)
18195 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18196 if (mask & AFL_ASE_LOONGSON_MMI)
18197 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18198 if (mask & AFL_ASE_LOONGSON_CAM)
18199 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18200 if (mask & AFL_ASE_LOONGSON_EXT)
18201 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18202 if (mask & AFL_ASE_LOONGSON_EXT2)
18203 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18204 if (mask == 0)
18205 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18206 else if ((mask & ~AFL_ASE_MASK) != 0)
18207 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18208}
18209
18210static void
18211print_mips_isa_ext (unsigned int isa_ext)
18212{
18213 switch (isa_ext)
18214 {
18215 case 0:
18216 fputs (_("None"), stdout);
18217 break;
18218 case AFL_EXT_XLR:
18219 fputs ("RMI XLR", stdout);
18220 break;
2c629856
N
18221 case AFL_EXT_OCTEON3:
18222 fputs ("Cavium Networks Octeon3", stdout);
18223 break;
351cdf24
MF
18224 case AFL_EXT_OCTEON2:
18225 fputs ("Cavium Networks Octeon2", stdout);
18226 break;
18227 case AFL_EXT_OCTEONP:
18228 fputs ("Cavium Networks OcteonP", stdout);
18229 break;
351cdf24
MF
18230 case AFL_EXT_OCTEON:
18231 fputs ("Cavium Networks Octeon", stdout);
18232 break;
18233 case AFL_EXT_5900:
18234 fputs ("Toshiba R5900", stdout);
18235 break;
18236 case AFL_EXT_4650:
18237 fputs ("MIPS R4650", stdout);
18238 break;
18239 case AFL_EXT_4010:
18240 fputs ("LSI R4010", stdout);
18241 break;
18242 case AFL_EXT_4100:
18243 fputs ("NEC VR4100", stdout);
18244 break;
18245 case AFL_EXT_3900:
18246 fputs ("Toshiba R3900", stdout);
18247 break;
18248 case AFL_EXT_10000:
18249 fputs ("MIPS R10000", stdout);
18250 break;
18251 case AFL_EXT_SB1:
18252 fputs ("Broadcom SB-1", stdout);
18253 break;
18254 case AFL_EXT_4111:
18255 fputs ("NEC VR4111/VR4181", stdout);
18256 break;
18257 case AFL_EXT_4120:
18258 fputs ("NEC VR4120", stdout);
18259 break;
18260 case AFL_EXT_5400:
18261 fputs ("NEC VR5400", stdout);
18262 break;
18263 case AFL_EXT_5500:
18264 fputs ("NEC VR5500", stdout);
18265 break;
18266 case AFL_EXT_LOONGSON_2E:
18267 fputs ("ST Microelectronics Loongson 2E", stdout);
18268 break;
18269 case AFL_EXT_LOONGSON_2F:
18270 fputs ("ST Microelectronics Loongson 2F", stdout);
18271 break;
38bf472a
MR
18272 case AFL_EXT_INTERAPTIV_MR2:
18273 fputs ("Imagination interAptiv MR2", stdout);
18274 break;
351cdf24 18275 default:
00ac7aa0 18276 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18277 }
18278}
18279
32ec8896 18280static signed int
351cdf24
MF
18281get_mips_reg_size (int reg_size)
18282{
18283 return (reg_size == AFL_REG_NONE) ? 0
18284 : (reg_size == AFL_REG_32) ? 32
18285 : (reg_size == AFL_REG_64) ? 64
18286 : (reg_size == AFL_REG_128) ? 128
18287 : -1;
18288}
18289
015dc7e1 18290static bool
dda8d76d 18291process_mips_specific (Filedata * filedata)
5b18a4bc 18292{
2cf0635d 18293 Elf_Internal_Dyn * entry;
351cdf24 18294 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18295 size_t liblist_offset = 0;
18296 size_t liblistno = 0;
18297 size_t conflictsno = 0;
18298 size_t options_offset = 0;
18299 size_t conflicts_offset = 0;
861fb55a
DJ
18300 size_t pltrelsz = 0;
18301 size_t pltrel = 0;
ccb4c951 18302 bfd_vma pltgot = 0;
861fb55a
DJ
18303 bfd_vma mips_pltgot = 0;
18304 bfd_vma jmprel = 0;
ccb4c951
RS
18305 bfd_vma local_gotno = 0;
18306 bfd_vma gotsym = 0;
18307 bfd_vma symtabno = 0;
015dc7e1 18308 bool res = true;
103f02d3 18309
dda8d76d 18310 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18311 display_mips_gnu_attribute))
015dc7e1 18312 res = false;
2cf19d5c 18313
dda8d76d 18314 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18315
18316 if (sect != NULL)
18317 {
18318 Elf_External_ABIFlags_v0 *abiflags_ext;
18319 Elf_Internal_ABIFlags_v0 abiflags_in;
18320
18321 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18322 {
18323 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18324 res = false;
32ec8896 18325 }
351cdf24
MF
18326 else
18327 {
dda8d76d 18328 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18329 sect->sh_size, _("MIPS ABI Flags section"));
18330 if (abiflags_ext)
18331 {
18332 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18333 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18334 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18335 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18336 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18337 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18338 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18339 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18340 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18341 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18342 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18343
18344 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18345 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18346 if (abiflags_in.isa_rev > 1)
18347 printf ("r%d", abiflags_in.isa_rev);
18348 printf ("\nGPR size: %d",
18349 get_mips_reg_size (abiflags_in.gpr_size));
18350 printf ("\nCPR1 size: %d",
18351 get_mips_reg_size (abiflags_in.cpr1_size));
18352 printf ("\nCPR2 size: %d",
18353 get_mips_reg_size (abiflags_in.cpr2_size));
18354 fputs ("\nFP ABI: ", stdout);
18355 print_mips_fp_abi_value (abiflags_in.fp_abi);
18356 fputs ("ISA Extension: ", stdout);
18357 print_mips_isa_ext (abiflags_in.isa_ext);
18358 fputs ("\nASEs:", stdout);
18359 print_mips_ases (abiflags_in.ases);
18360 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18361 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18362 fputc ('\n', stdout);
18363 free (abiflags_ext);
18364 }
18365 }
18366 }
18367
19e6b90e 18368 /* We have a lot of special sections. Thanks SGI! */
978c4450 18369 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18370 {
18371 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18372 sect = find_section (filedata, ".got");
bbdd9a68
MR
18373 if (sect != NULL)
18374 {
18375 unsigned char *data_end;
18376 unsigned char *data;
18377 bfd_vma ent, end;
18378 int addr_size;
18379
18380 pltgot = sect->sh_addr;
18381
18382 ent = pltgot;
18383 addr_size = (is_32bit_elf ? 4 : 8);
18384 end = pltgot + sect->sh_size;
18385
dda8d76d 18386 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18387 end - pltgot, 1,
18388 _("Global Offset Table data"));
18389 /* PR 12855: Null data is handled gracefully throughout. */
18390 data_end = data + (end - pltgot);
18391
18392 printf (_("\nStatic GOT:\n"));
18393 printf (_(" Canonical gp value: "));
18394 print_vma (ent + 0x7ff0, LONG_HEX);
18395 printf ("\n\n");
18396
18397 /* In a dynamic binary GOT[0] is reserved for the dynamic
18398 loader to store the lazy resolver pointer, however in
18399 a static binary it may well have been omitted and GOT
18400 reduced to a table of addresses.
18401 PR 21344: Check for the entry being fully available
18402 before fetching it. */
18403 if (data
18404 && data + ent - pltgot + addr_size <= data_end
18405 && byte_get (data + ent - pltgot, addr_size) == 0)
18406 {
18407 printf (_(" Reserved entries:\n"));
18408 printf (_(" %*s %10s %*s\n"),
18409 addr_size * 2, _("Address"), _("Access"),
18410 addr_size * 2, _("Value"));
18411 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18412 printf ("\n");
18413 if (ent == (bfd_vma) -1)
18414 goto sgot_print_fail;
18415
18416 /* Check for the MSB of GOT[1] being set, identifying a
18417 GNU object. This entry will be used by some runtime
18418 loaders, to store the module pointer. Otherwise this
18419 is an ordinary local entry.
18420 PR 21344: Check for the entry being fully available
18421 before fetching it. */
18422 if (data
18423 && data + ent - pltgot + addr_size <= data_end
18424 && (byte_get (data + ent - pltgot, addr_size)
18425 >> (addr_size * 8 - 1)) != 0)
18426 {
18427 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18428 printf ("\n");
18429 if (ent == (bfd_vma) -1)
18430 goto sgot_print_fail;
18431 }
18432 printf ("\n");
18433 }
18434
f17e9d8a 18435 if (data != NULL && ent < end)
bbdd9a68
MR
18436 {
18437 printf (_(" Local entries:\n"));
18438 printf (" %*s %10s %*s\n",
18439 addr_size * 2, _("Address"), _("Access"),
18440 addr_size * 2, _("Value"));
18441 while (ent < end)
18442 {
18443 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18444 printf ("\n");
18445 if (ent == (bfd_vma) -1)
18446 goto sgot_print_fail;
18447 }
18448 printf ("\n");
18449 }
18450
18451 sgot_print_fail:
9db70fc3 18452 free (data);
bbdd9a68
MR
18453 }
18454 return res;
18455 }
252b5132 18456
978c4450 18457 for (entry = filedata->dynamic_section;
071436c6 18458 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18459 (entry < filedata->dynamic_section + filedata->dynamic_nent
18460 && entry->d_tag != DT_NULL);
071436c6 18461 ++entry)
252b5132
RH
18462 switch (entry->d_tag)
18463 {
18464 case DT_MIPS_LIBLIST:
d93f0186 18465 liblist_offset
dda8d76d 18466 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18467 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18468 break;
18469 case DT_MIPS_LIBLISTNO:
18470 liblistno = entry->d_un.d_val;
18471 break;
18472 case DT_MIPS_OPTIONS:
dda8d76d 18473 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18474 break;
18475 case DT_MIPS_CONFLICT:
d93f0186 18476 conflicts_offset
dda8d76d 18477 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18478 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18479 break;
18480 case DT_MIPS_CONFLICTNO:
18481 conflictsno = entry->d_un.d_val;
18482 break;
ccb4c951 18483 case DT_PLTGOT:
861fb55a
DJ
18484 pltgot = entry->d_un.d_ptr;
18485 break;
ccb4c951
RS
18486 case DT_MIPS_LOCAL_GOTNO:
18487 local_gotno = entry->d_un.d_val;
18488 break;
18489 case DT_MIPS_GOTSYM:
18490 gotsym = entry->d_un.d_val;
18491 break;
18492 case DT_MIPS_SYMTABNO:
18493 symtabno = entry->d_un.d_val;
18494 break;
861fb55a
DJ
18495 case DT_MIPS_PLTGOT:
18496 mips_pltgot = entry->d_un.d_ptr;
18497 break;
18498 case DT_PLTREL:
18499 pltrel = entry->d_un.d_val;
18500 break;
18501 case DT_PLTRELSZ:
18502 pltrelsz = entry->d_un.d_val;
18503 break;
18504 case DT_JMPREL:
18505 jmprel = entry->d_un.d_ptr;
18506 break;
252b5132
RH
18507 default:
18508 break;
18509 }
18510
18511 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18512 {
2cf0635d 18513 Elf32_External_Lib * elib;
252b5132
RH
18514 size_t cnt;
18515
dda8d76d 18516 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18517 sizeof (Elf32_External_Lib),
18518 liblistno,
18519 _("liblist section data"));
a6e9f9df 18520 if (elib)
252b5132 18521 {
d3a49aa8
AM
18522 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18523 "\nSection '.liblist' contains %lu entries:\n",
18524 (unsigned long) liblistno),
a6e9f9df 18525 (unsigned long) liblistno);
2b692964 18526 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18527 stdout);
18528
18529 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18530 {
a6e9f9df 18531 Elf32_Lib liblist;
91d6fa6a 18532 time_t atime;
d5b07ef4 18533 char timebuf[128];
2cf0635d 18534 struct tm * tmp;
a6e9f9df
AM
18535
18536 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18537 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18538 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18539 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18540 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18541
91d6fa6a 18542 tmp = gmtime (&atime);
e9e44622
JJ
18543 snprintf (timebuf, sizeof (timebuf),
18544 "%04u-%02u-%02uT%02u:%02u:%02u",
18545 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18546 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18547
31104126 18548 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18549 if (valid_dynamic_name (filedata, liblist.l_name))
18550 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18551 else
2b692964 18552 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18553 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18554 liblist.l_version);
a6e9f9df
AM
18555
18556 if (liblist.l_flags == 0)
2b692964 18557 puts (_(" NONE"));
a6e9f9df
AM
18558 else
18559 {
18560 static const struct
252b5132 18561 {
2cf0635d 18562 const char * name;
a6e9f9df 18563 int bit;
252b5132 18564 }
a6e9f9df
AM
18565 l_flags_vals[] =
18566 {
18567 { " EXACT_MATCH", LL_EXACT_MATCH },
18568 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18569 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18570 { " EXPORTS", LL_EXPORTS },
18571 { " DELAY_LOAD", LL_DELAY_LOAD },
18572 { " DELTA", LL_DELTA }
18573 };
18574 int flags = liblist.l_flags;
18575 size_t fcnt;
18576
60bca95a 18577 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18578 if ((flags & l_flags_vals[fcnt].bit) != 0)
18579 {
18580 fputs (l_flags_vals[fcnt].name, stdout);
18581 flags ^= l_flags_vals[fcnt].bit;
18582 }
18583 if (flags != 0)
18584 printf (" %#x", (unsigned int) flags);
252b5132 18585
a6e9f9df
AM
18586 puts ("");
18587 }
252b5132 18588 }
252b5132 18589
a6e9f9df
AM
18590 free (elib);
18591 }
32ec8896 18592 else
015dc7e1 18593 res = false;
252b5132
RH
18594 }
18595
18596 if (options_offset != 0)
18597 {
2cf0635d 18598 Elf_External_Options * eopt;
252b5132
RH
18599 size_t offset;
18600 int cnt;
18601
18602 /* Find the section header so that we get the size. */
dda8d76d 18603 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18604 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18605 if (sect == NULL)
18606 {
18607 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18608 return false;
071436c6 18609 }
7fc0c668
NC
18610 /* PR 24243 */
18611 if (sect->sh_size < sizeof (* eopt))
18612 {
18613 error (_("The MIPS options section is too small.\n"));
015dc7e1 18614 return false;
7fc0c668 18615 }
252b5132 18616
dda8d76d 18617 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18618 sect->sh_size, _("options"));
a6e9f9df 18619 if (eopt)
252b5132 18620 {
fd17d1e6 18621 Elf_Internal_Options option;
76da6bbe 18622
a6e9f9df 18623 offset = cnt = 0;
82b1b41b 18624 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18625 {
2cf0635d 18626 Elf_External_Options * eoption;
fd17d1e6 18627 unsigned int optsize;
252b5132 18628
a6e9f9df 18629 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18630
fd17d1e6 18631 optsize = BYTE_GET (eoption->size);
76da6bbe 18632
82b1b41b 18633 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18634 if (optsize < sizeof (* eopt)
18635 || optsize > sect->sh_size - offset)
82b1b41b 18636 {
645f43a8 18637 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18638 optsize);
645f43a8 18639 free (eopt);
015dc7e1 18640 return false;
82b1b41b 18641 }
fd17d1e6 18642 offset += optsize;
a6e9f9df
AM
18643 ++cnt;
18644 }
252b5132 18645
d3a49aa8
AM
18646 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18647 "\nSection '%s' contains %d entries:\n",
18648 cnt),
dda8d76d 18649 printable_section_name (filedata, sect), cnt);
76da6bbe 18650
82b1b41b 18651 offset = 0;
a6e9f9df 18652 while (cnt-- > 0)
252b5132 18653 {
a6e9f9df 18654 size_t len;
fd17d1e6
AM
18655 Elf_External_Options * eoption;
18656
18657 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18658
18659 option.kind = BYTE_GET (eoption->kind);
18660 option.size = BYTE_GET (eoption->size);
18661 option.section = BYTE_GET (eoption->section);
18662 option.info = BYTE_GET (eoption->info);
a6e9f9df 18663
fd17d1e6 18664 switch (option.kind)
252b5132 18665 {
a6e9f9df
AM
18666 case ODK_NULL:
18667 /* This shouldn't happen. */
d0c4e780 18668 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18669 option.section, option.info);
a6e9f9df 18670 break;
2e6be59c 18671
a6e9f9df
AM
18672 case ODK_REGINFO:
18673 printf (" REGINFO ");
dda8d76d 18674 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18675 {
2cf0635d 18676 Elf32_External_RegInfo * ereg;
b34976b6 18677 Elf32_RegInfo reginfo;
a6e9f9df 18678
2e6be59c 18679 /* 32bit form. */
fd17d1e6
AM
18680 if (option.size < (sizeof (Elf_External_Options)
18681 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18682 {
18683 printf (_("<corrupt>\n"));
18684 error (_("Truncated MIPS REGINFO option\n"));
18685 cnt = 0;
18686 break;
18687 }
18688
fd17d1e6 18689 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18690
a6e9f9df
AM
18691 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18692 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18693 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18694 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18695 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18696 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18697
d0c4e780
AM
18698 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18699 reginfo.ri_gprmask, reginfo.ri_gp_value);
18700 printf (" "
18701 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18702 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18703 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18704 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18705 }
18706 else
18707 {
18708 /* 64 bit form. */
2cf0635d 18709 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18710 Elf64_Internal_RegInfo reginfo;
18711
fd17d1e6
AM
18712 if (option.size < (sizeof (Elf_External_Options)
18713 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18714 {
18715 printf (_("<corrupt>\n"));
18716 error (_("Truncated MIPS REGINFO option\n"));
18717 cnt = 0;
18718 break;
18719 }
18720
fd17d1e6 18721 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18722 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18723 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18724 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18725 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18726 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18727 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18728
d0c4e780
AM
18729 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18730 reginfo.ri_gprmask, reginfo.ri_gp_value);
18731 printf (" "
18732 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18733 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18734 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18735 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18736 }
fd17d1e6 18737 offset += option.size;
a6e9f9df 18738 continue;
2e6be59c 18739
a6e9f9df
AM
18740 case ODK_EXCEPTIONS:
18741 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18742 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18743 fputs (") fpe_max(", stdout);
fd17d1e6 18744 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18745 fputs (")", stdout);
18746
fd17d1e6 18747 if (option.info & OEX_PAGE0)
a6e9f9df 18748 fputs (" PAGE0", stdout);
fd17d1e6 18749 if (option.info & OEX_SMM)
a6e9f9df 18750 fputs (" SMM", stdout);
fd17d1e6 18751 if (option.info & OEX_FPDBUG)
a6e9f9df 18752 fputs (" FPDBUG", stdout);
fd17d1e6 18753 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18754 fputs (" DISMISS", stdout);
18755 break;
2e6be59c 18756
a6e9f9df
AM
18757 case ODK_PAD:
18758 fputs (" PAD ", stdout);
fd17d1e6 18759 if (option.info & OPAD_PREFIX)
a6e9f9df 18760 fputs (" PREFIX", stdout);
fd17d1e6 18761 if (option.info & OPAD_POSTFIX)
a6e9f9df 18762 fputs (" POSTFIX", stdout);
fd17d1e6 18763 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18764 fputs (" SYMBOL", stdout);
18765 break;
2e6be59c 18766
a6e9f9df
AM
18767 case ODK_HWPATCH:
18768 fputs (" HWPATCH ", stdout);
fd17d1e6 18769 if (option.info & OHW_R4KEOP)
a6e9f9df 18770 fputs (" R4KEOP", stdout);
fd17d1e6 18771 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18772 fputs (" R8KPFETCH", stdout);
fd17d1e6 18773 if (option.info & OHW_R5KEOP)
a6e9f9df 18774 fputs (" R5KEOP", stdout);
fd17d1e6 18775 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18776 fputs (" R5KCVTL", stdout);
18777 break;
2e6be59c 18778
a6e9f9df
AM
18779 case ODK_FILL:
18780 fputs (" FILL ", stdout);
18781 /* XXX Print content of info word? */
18782 break;
2e6be59c 18783
a6e9f9df
AM
18784 case ODK_TAGS:
18785 fputs (" TAGS ", stdout);
18786 /* XXX Print content of info word? */
18787 break;
2e6be59c 18788
a6e9f9df
AM
18789 case ODK_HWAND:
18790 fputs (" HWAND ", stdout);
fd17d1e6 18791 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18792 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18793 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18794 fputs (" R4KEOP_CLEAN", stdout);
18795 break;
2e6be59c 18796
a6e9f9df
AM
18797 case ODK_HWOR:
18798 fputs (" HWOR ", stdout);
fd17d1e6 18799 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18800 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18801 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18802 fputs (" R4KEOP_CLEAN", stdout);
18803 break;
2e6be59c 18804
a6e9f9df 18805 case ODK_GP_GROUP:
d0c4e780 18806 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18807 option.info & OGP_GROUP,
18808 (option.info & OGP_SELF) >> 16);
a6e9f9df 18809 break;
2e6be59c 18810
a6e9f9df 18811 case ODK_IDENT:
d0c4e780 18812 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18813 option.info & OGP_GROUP,
18814 (option.info & OGP_SELF) >> 16);
a6e9f9df 18815 break;
2e6be59c 18816
a6e9f9df
AM
18817 default:
18818 /* This shouldn't happen. */
d0c4e780 18819 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18820 option.kind, option.section, option.info);
a6e9f9df 18821 break;
252b5132 18822 }
a6e9f9df 18823
2cf0635d 18824 len = sizeof (* eopt);
fd17d1e6 18825 while (len < option.size)
82b1b41b 18826 {
fd17d1e6 18827 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18828
82b1b41b
NC
18829 if (ISPRINT (datum))
18830 printf ("%c", datum);
18831 else
18832 printf ("\\%03o", datum);
18833 len ++;
18834 }
a6e9f9df 18835 fputs ("\n", stdout);
82b1b41b 18836
fd17d1e6 18837 offset += option.size;
252b5132 18838 }
a6e9f9df 18839 free (eopt);
252b5132 18840 }
32ec8896 18841 else
015dc7e1 18842 res = false;
252b5132
RH
18843 }
18844
18845 if (conflicts_offset != 0 && conflictsno != 0)
18846 {
2cf0635d 18847 Elf32_Conflict * iconf;
252b5132
RH
18848 size_t cnt;
18849
978c4450 18850 if (filedata->dynamic_symbols == NULL)
252b5132 18851 {
591a748a 18852 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18853 return false;
252b5132
RH
18854 }
18855
7296a62a
NC
18856 /* PR 21345 - print a slightly more helpful error message
18857 if we are sure that the cmalloc will fail. */
645f43a8 18858 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18859 {
18860 error (_("Overlarge number of conflicts detected: %lx\n"),
18861 (long) conflictsno);
015dc7e1 18862 return false;
7296a62a
NC
18863 }
18864
3f5e193b 18865 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18866 if (iconf == NULL)
18867 {
8b73c356 18868 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18869 return false;
252b5132
RH
18870 }
18871
9ea033b2 18872 if (is_32bit_elf)
252b5132 18873 {
2cf0635d 18874 Elf32_External_Conflict * econf32;
a6e9f9df 18875
3f5e193b 18876 econf32 = (Elf32_External_Conflict *)
95099889
AM
18877 get_data (NULL, filedata, conflicts_offset,
18878 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18879 if (!econf32)
5a814d6d
AM
18880 {
18881 free (iconf);
015dc7e1 18882 return false;
5a814d6d 18883 }
252b5132
RH
18884
18885 for (cnt = 0; cnt < conflictsno; ++cnt)
18886 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18887
18888 free (econf32);
252b5132
RH
18889 }
18890 else
18891 {
2cf0635d 18892 Elf64_External_Conflict * econf64;
a6e9f9df 18893
3f5e193b 18894 econf64 = (Elf64_External_Conflict *)
95099889
AM
18895 get_data (NULL, filedata, conflicts_offset,
18896 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18897 if (!econf64)
5a814d6d
AM
18898 {
18899 free (iconf);
015dc7e1 18900 return false;
5a814d6d 18901 }
252b5132
RH
18902
18903 for (cnt = 0; cnt < conflictsno; ++cnt)
18904 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18905
18906 free (econf64);
252b5132
RH
18907 }
18908
d3a49aa8
AM
18909 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18910 "\nSection '.conflict' contains %lu entries:\n",
18911 (unsigned long) conflictsno),
c7e7ca54 18912 (unsigned long) conflictsno);
252b5132
RH
18913 puts (_(" Num: Index Value Name"));
18914
18915 for (cnt = 0; cnt < conflictsno; ++cnt)
18916 {
b34976b6 18917 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18918
978c4450 18919 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18920 printf (_("<corrupt symbol index>"));
d79b3d50 18921 else
e0a31db1
NC
18922 {
18923 Elf_Internal_Sym * psym;
18924
978c4450 18925 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18926 print_vma (psym->st_value, FULL_HEX);
18927 putchar (' ');
84714f86
AM
18928 if (valid_dynamic_name (filedata, psym->st_name))
18929 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18930 else
18931 printf (_("<corrupt: %14ld>"), psym->st_name);
18932 }
31104126 18933 putchar ('\n');
252b5132
RH
18934 }
18935
252b5132
RH
18936 free (iconf);
18937 }
18938
ccb4c951
RS
18939 if (pltgot != 0 && local_gotno != 0)
18940 {
91d6fa6a 18941 bfd_vma ent, local_end, global_end;
bbeee7ea 18942 size_t i, offset;
2cf0635d 18943 unsigned char * data;
82b1b41b 18944 unsigned char * data_end;
bbeee7ea 18945 int addr_size;
ccb4c951 18946
91d6fa6a 18947 ent = pltgot;
ccb4c951
RS
18948 addr_size = (is_32bit_elf ? 4 : 8);
18949 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18950
74e1a04b
NC
18951 /* PR binutils/17533 file: 012-111227-0.004 */
18952 if (symtabno < gotsym)
18953 {
18954 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18955 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18956 return false;
74e1a04b 18957 }
82b1b41b 18958
74e1a04b 18959 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18960 /* PR 17531: file: 54c91a34. */
18961 if (global_end < local_end)
18962 {
18963 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18964 return false;
82b1b41b 18965 }
948f632f 18966
dda8d76d
NC
18967 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18968 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18969 global_end - pltgot, 1,
18970 _("Global Offset Table data"));
919383ac 18971 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18972 data_end = data + (global_end - pltgot);
59245841 18973
ccb4c951
RS
18974 printf (_("\nPrimary GOT:\n"));
18975 printf (_(" Canonical gp value: "));
18976 print_vma (pltgot + 0x7ff0, LONG_HEX);
18977 printf ("\n\n");
18978
18979 printf (_(" Reserved entries:\n"));
18980 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18981 addr_size * 2, _("Address"), _("Access"),
18982 addr_size * 2, _("Initial"));
82b1b41b 18983 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18984 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18985 if (ent == (bfd_vma) -1)
18986 goto got_print_fail;
75ec1fdb 18987
c4ab9505
MR
18988 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18989 This entry will be used by some runtime loaders, to store the
18990 module pointer. Otherwise this is an ordinary local entry.
18991 PR 21344: Check for the entry being fully available before
18992 fetching it. */
18993 if (data
18994 && data + ent - pltgot + addr_size <= data_end
18995 && (byte_get (data + ent - pltgot, addr_size)
18996 >> (addr_size * 8 - 1)) != 0)
18997 {
18998 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18999 printf (_(" Module pointer (GNU extension)\n"));
19000 if (ent == (bfd_vma) -1)
19001 goto got_print_fail;
ccb4c951
RS
19002 }
19003 printf ("\n");
19004
f17e9d8a 19005 if (data != NULL && ent < local_end)
ccb4c951
RS
19006 {
19007 printf (_(" Local entries:\n"));
cc5914eb 19008 printf (" %*s %10s %*s\n",
2b692964
NC
19009 addr_size * 2, _("Address"), _("Access"),
19010 addr_size * 2, _("Initial"));
91d6fa6a 19011 while (ent < local_end)
ccb4c951 19012 {
82b1b41b 19013 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19014 printf ("\n");
82b1b41b
NC
19015 if (ent == (bfd_vma) -1)
19016 goto got_print_fail;
ccb4c951
RS
19017 }
19018 printf ("\n");
19019 }
19020
f17e9d8a 19021 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19022 {
19023 int sym_width;
19024
19025 printf (_(" Global entries:\n"));
cc5914eb 19026 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19027 addr_size * 2, _("Address"),
19028 _("Access"),
2b692964 19029 addr_size * 2, _("Initial"),
9cf03b7e
NC
19030 addr_size * 2, _("Sym.Val."),
19031 _("Type"),
19032 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19033 _("Ndx"), _("Name"));
0b4362b0 19034
ccb4c951 19035 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19036
ccb4c951
RS
19037 for (i = gotsym; i < symtabno; i++)
19038 {
82b1b41b 19039 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19040 printf (" ");
e0a31db1 19041
978c4450 19042 if (filedata->dynamic_symbols == NULL)
e0a31db1 19043 printf (_("<no dynamic symbols>"));
978c4450 19044 else if (i < filedata->num_dynamic_syms)
e0a31db1 19045 {
978c4450 19046 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19047
19048 print_vma (psym->st_value, LONG_HEX);
19049 printf (" %-7s %3s ",
dda8d76d
NC
19050 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19051 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19052
84714f86 19053 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19054 print_symbol (sym_width,
84714f86 19055 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19056 else
19057 printf (_("<corrupt: %14ld>"), psym->st_name);
19058 }
ccb4c951 19059 else
7fc5ac57
JBG
19060 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19061 (unsigned long) i);
e0a31db1 19062
ccb4c951 19063 printf ("\n");
82b1b41b
NC
19064 if (ent == (bfd_vma) -1)
19065 break;
ccb4c951
RS
19066 }
19067 printf ("\n");
19068 }
19069
82b1b41b 19070 got_print_fail:
9db70fc3 19071 free (data);
ccb4c951
RS
19072 }
19073
861fb55a
DJ
19074 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19075 {
91d6fa6a 19076 bfd_vma ent, end;
861fb55a
DJ
19077 size_t offset, rel_offset;
19078 unsigned long count, i;
2cf0635d 19079 unsigned char * data;
861fb55a 19080 int addr_size, sym_width;
2cf0635d 19081 Elf_Internal_Rela * rels;
861fb55a 19082
dda8d76d 19083 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19084 if (pltrel == DT_RELA)
19085 {
dda8d76d 19086 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19087 return false;
861fb55a
DJ
19088 }
19089 else
19090 {
dda8d76d 19091 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19092 return false;
861fb55a
DJ
19093 }
19094
91d6fa6a 19095 ent = mips_pltgot;
861fb55a
DJ
19096 addr_size = (is_32bit_elf ? 4 : 8);
19097 end = mips_pltgot + (2 + count) * addr_size;
19098
dda8d76d
NC
19099 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19100 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19101 1, _("Procedure Linkage Table data"));
59245841 19102 if (data == NULL)
288f0ba2
AM
19103 {
19104 free (rels);
015dc7e1 19105 return false;
288f0ba2 19106 }
59245841 19107
9cf03b7e 19108 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19109 printf (_(" Reserved entries:\n"));
19110 printf (_(" %*s %*s Purpose\n"),
2b692964 19111 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19112 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19113 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19114 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19115 printf (_(" Module pointer\n"));
861fb55a
DJ
19116 printf ("\n");
19117
19118 printf (_(" Entries:\n"));
cc5914eb 19119 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19120 addr_size * 2, _("Address"),
19121 addr_size * 2, _("Initial"),
19122 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19123 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19124 for (i = 0; i < count; i++)
19125 {
df97ab2a 19126 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19127
91d6fa6a 19128 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19129 printf (" ");
e0a31db1 19130
978c4450 19131 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19132 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19133 else
e0a31db1 19134 {
978c4450 19135 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19136
19137 print_vma (psym->st_value, LONG_HEX);
19138 printf (" %-7s %3s ",
dda8d76d
NC
19139 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19140 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19141 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19142 print_symbol (sym_width,
84714f86 19143 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19144 else
19145 printf (_("<corrupt: %14ld>"), psym->st_name);
19146 }
861fb55a
DJ
19147 printf ("\n");
19148 }
19149 printf ("\n");
19150
9db70fc3 19151 free (data);
861fb55a
DJ
19152 free (rels);
19153 }
19154
32ec8896 19155 return res;
252b5132
RH
19156}
19157
015dc7e1 19158static bool
dda8d76d 19159process_nds32_specific (Filedata * filedata)
35c08157
KLC
19160{
19161 Elf_Internal_Shdr *sect = NULL;
19162
dda8d76d 19163 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19164 if (sect != NULL && sect->sh_size >= 4)
35c08157 19165 {
9c7b8e9b
AM
19166 unsigned char *buf;
19167 unsigned int flag;
35c08157
KLC
19168
19169 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19170 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19171 _("NDS32 elf flags section"));
35c08157 19172
9c7b8e9b 19173 if (buf == NULL)
015dc7e1 19174 return false;
32ec8896 19175
9c7b8e9b
AM
19176 flag = byte_get (buf, 4);
19177 free (buf);
19178 switch (flag & 0x3)
35c08157
KLC
19179 {
19180 case 0:
19181 printf ("(VEC_SIZE):\tNo entry.\n");
19182 break;
19183 case 1:
19184 printf ("(VEC_SIZE):\t4 bytes\n");
19185 break;
19186 case 2:
19187 printf ("(VEC_SIZE):\t16 bytes\n");
19188 break;
19189 case 3:
19190 printf ("(VEC_SIZE):\treserved\n");
19191 break;
19192 }
19193 }
19194
015dc7e1 19195 return true;
35c08157
KLC
19196}
19197
015dc7e1 19198static bool
dda8d76d 19199process_gnu_liblist (Filedata * filedata)
047b2264 19200{
2cf0635d
NC
19201 Elf_Internal_Shdr * section;
19202 Elf_Internal_Shdr * string_sec;
19203 Elf32_External_Lib * elib;
19204 char * strtab;
c256ffe7 19205 size_t strtab_size;
047b2264 19206 size_t cnt;
d3a49aa8 19207 unsigned long num_liblist;
047b2264 19208 unsigned i;
015dc7e1 19209 bool res = true;
047b2264
JJ
19210
19211 if (! do_arch)
015dc7e1 19212 return true;
047b2264 19213
dda8d76d
NC
19214 for (i = 0, section = filedata->section_headers;
19215 i < filedata->file_header.e_shnum;
b34976b6 19216 i++, section++)
047b2264
JJ
19217 {
19218 switch (section->sh_type)
19219 {
19220 case SHT_GNU_LIBLIST:
dda8d76d 19221 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19222 break;
19223
3f5e193b 19224 elib = (Elf32_External_Lib *)
dda8d76d 19225 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19226 _("liblist section data"));
047b2264
JJ
19227
19228 if (elib == NULL)
32ec8896 19229 {
015dc7e1 19230 res = false;
32ec8896
NC
19231 break;
19232 }
047b2264 19233
dda8d76d
NC
19234 string_sec = filedata->section_headers + section->sh_link;
19235 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19236 string_sec->sh_size,
19237 _("liblist string table"));
047b2264
JJ
19238 if (strtab == NULL
19239 || section->sh_entsize != sizeof (Elf32_External_Lib))
19240 {
19241 free (elib);
2842702f 19242 free (strtab);
015dc7e1 19243 res = false;
047b2264
JJ
19244 break;
19245 }
59245841 19246 strtab_size = string_sec->sh_size;
047b2264 19247
d3a49aa8
AM
19248 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19249 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19250 "\nLibrary list section '%s' contains %lu entries:\n",
19251 num_liblist),
dda8d76d 19252 printable_section_name (filedata, section),
d3a49aa8 19253 num_liblist);
047b2264 19254
2b692964 19255 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19256
19257 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19258 ++cnt)
19259 {
19260 Elf32_Lib liblist;
91d6fa6a 19261 time_t atime;
d5b07ef4 19262 char timebuf[128];
2cf0635d 19263 struct tm * tmp;
047b2264
JJ
19264
19265 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19266 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19267 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19268 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19269 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19270
91d6fa6a 19271 tmp = gmtime (&atime);
e9e44622
JJ
19272 snprintf (timebuf, sizeof (timebuf),
19273 "%04u-%02u-%02uT%02u:%02u:%02u",
19274 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19275 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19276
19277 printf ("%3lu: ", (unsigned long) cnt);
19278 if (do_wide)
c256ffe7 19279 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19280 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19281 else
c256ffe7 19282 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19283 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19284 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19285 liblist.l_version, liblist.l_flags);
19286 }
19287
19288 free (elib);
2842702f 19289 free (strtab);
047b2264
JJ
19290 }
19291 }
19292
32ec8896 19293 return res;
047b2264
JJ
19294}
19295
9437c45b 19296static const char *
dda8d76d 19297get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19298{
19299 static char buff[64];
103f02d3 19300
dda8d76d 19301 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19302 switch (e_type)
19303 {
57346661 19304 case NT_AUXV:
1ec5cd37 19305 return _("NT_AUXV (auxiliary vector)");
57346661 19306 case NT_PRSTATUS:
1ec5cd37 19307 return _("NT_PRSTATUS (prstatus structure)");
57346661 19308 case NT_FPREGSET:
1ec5cd37 19309 return _("NT_FPREGSET (floating point registers)");
57346661 19310 case NT_PRPSINFO:
1ec5cd37 19311 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19312 case NT_TASKSTRUCT:
1ec5cd37 19313 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19314 case NT_GDB_TDESC:
19315 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19316 case NT_PRXFPREG:
1ec5cd37 19317 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19318 case NT_PPC_VMX:
19319 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19320 case NT_PPC_VSX:
19321 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19322 case NT_PPC_TAR:
19323 return _("NT_PPC_TAR (ppc TAR register)");
19324 case NT_PPC_PPR:
19325 return _("NT_PPC_PPR (ppc PPR register)");
19326 case NT_PPC_DSCR:
19327 return _("NT_PPC_DSCR (ppc DSCR register)");
19328 case NT_PPC_EBB:
19329 return _("NT_PPC_EBB (ppc EBB registers)");
19330 case NT_PPC_PMU:
19331 return _("NT_PPC_PMU (ppc PMU registers)");
19332 case NT_PPC_TM_CGPR:
19333 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19334 case NT_PPC_TM_CFPR:
19335 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19336 case NT_PPC_TM_CVMX:
19337 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19338 case NT_PPC_TM_CVSX:
3fd21718 19339 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19340 case NT_PPC_TM_SPR:
19341 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19342 case NT_PPC_TM_CTAR:
19343 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19344 case NT_PPC_TM_CPPR:
19345 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19346 case NT_PPC_TM_CDSCR:
19347 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19348 case NT_386_TLS:
19349 return _("NT_386_TLS (x86 TLS information)");
19350 case NT_386_IOPERM:
19351 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19352 case NT_X86_XSTATE:
19353 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19354 case NT_X86_CET:
19355 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19356 case NT_S390_HIGH_GPRS:
19357 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19358 case NT_S390_TIMER:
19359 return _("NT_S390_TIMER (s390 timer register)");
19360 case NT_S390_TODCMP:
19361 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19362 case NT_S390_TODPREG:
19363 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19364 case NT_S390_CTRS:
19365 return _("NT_S390_CTRS (s390 control registers)");
19366 case NT_S390_PREFIX:
19367 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19368 case NT_S390_LAST_BREAK:
19369 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19370 case NT_S390_SYSTEM_CALL:
19371 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19372 case NT_S390_TDB:
19373 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19374 case NT_S390_VXRS_LOW:
19375 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19376 case NT_S390_VXRS_HIGH:
19377 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19378 case NT_S390_GS_CB:
19379 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19380 case NT_S390_GS_BC:
19381 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19382 case NT_ARM_VFP:
19383 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19384 case NT_ARM_TLS:
19385 return _("NT_ARM_TLS (AArch TLS registers)");
19386 case NT_ARM_HW_BREAK:
19387 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19388 case NT_ARM_HW_WATCH:
19389 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19390 case NT_ARM_SYSTEM_CALL:
19391 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19392 case NT_ARM_SVE:
19393 return _("NT_ARM_SVE (AArch SVE registers)");
19394 case NT_ARM_PAC_MASK:
19395 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19396 case NT_ARM_PACA_KEYS:
19397 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19398 case NT_ARM_PACG_KEYS:
19399 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19400 case NT_ARM_TAGGED_ADDR_CTRL:
19401 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19402 case NT_ARM_PAC_ENABLED_KEYS:
19403 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19404 case NT_ARC_V2:
19405 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19406 case NT_RISCV_CSR:
19407 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19408 case NT_PSTATUS:
1ec5cd37 19409 return _("NT_PSTATUS (pstatus structure)");
57346661 19410 case NT_FPREGS:
1ec5cd37 19411 return _("NT_FPREGS (floating point registers)");
57346661 19412 case NT_PSINFO:
1ec5cd37 19413 return _("NT_PSINFO (psinfo structure)");
57346661 19414 case NT_LWPSTATUS:
1ec5cd37 19415 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19416 case NT_LWPSINFO:
1ec5cd37 19417 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19418 case NT_WIN32PSTATUS:
1ec5cd37 19419 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19420 case NT_SIGINFO:
19421 return _("NT_SIGINFO (siginfo_t data)");
19422 case NT_FILE:
19423 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19424 default:
19425 break;
19426 }
19427 else
19428 switch (e_type)
19429 {
19430 case NT_VERSION:
19431 return _("NT_VERSION (version)");
19432 case NT_ARCH:
19433 return _("NT_ARCH (architecture)");
9ef920e9 19434 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19435 return _("OPEN");
9ef920e9 19436 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19437 return _("func");
c8795e1f
NC
19438 case NT_GO_BUILDID:
19439 return _("GO BUILDID");
3ac925fc
LB
19440 case FDO_PACKAGING_METADATA:
19441 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19442 default:
19443 break;
19444 }
19445
e9e44622 19446 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19447 return buff;
779fe533
NC
19448}
19449
015dc7e1 19450static bool
9ece1fa9
TT
19451print_core_note (Elf_Internal_Note *pnote)
19452{
19453 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19454 bfd_vma count, page_size;
19455 unsigned char *descdata, *filenames, *descend;
19456
19457 if (pnote->type != NT_FILE)
04ac15ab
AS
19458 {
19459 if (do_wide)
19460 printf ("\n");
015dc7e1 19461 return true;
04ac15ab 19462 }
9ece1fa9
TT
19463
19464#ifndef BFD64
19465 if (!is_32bit_elf)
19466 {
19467 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19468 /* Still "successful". */
015dc7e1 19469 return true;
9ece1fa9
TT
19470 }
19471#endif
19472
19473 if (pnote->descsz < 2 * addr_size)
19474 {
32ec8896 19475 error (_(" Malformed note - too short for header\n"));
015dc7e1 19476 return false;
9ece1fa9
TT
19477 }
19478
19479 descdata = (unsigned char *) pnote->descdata;
19480 descend = descdata + pnote->descsz;
19481
19482 if (descdata[pnote->descsz - 1] != '\0')
19483 {
32ec8896 19484 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19485 return false;
9ece1fa9
TT
19486 }
19487
19488 count = byte_get (descdata, addr_size);
19489 descdata += addr_size;
19490
19491 page_size = byte_get (descdata, addr_size);
19492 descdata += addr_size;
19493
5396a86e
AM
19494 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19495 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19496 {
32ec8896 19497 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19498 return false;
9ece1fa9
TT
19499 }
19500
19501 printf (_(" Page size: "));
19502 print_vma (page_size, DEC);
19503 printf ("\n");
19504
19505 printf (_(" %*s%*s%*s\n"),
19506 (int) (2 + 2 * addr_size), _("Start"),
19507 (int) (4 + 2 * addr_size), _("End"),
19508 (int) (4 + 2 * addr_size), _("Page Offset"));
19509 filenames = descdata + count * 3 * addr_size;
595712bb 19510 while (count-- > 0)
9ece1fa9
TT
19511 {
19512 bfd_vma start, end, file_ofs;
19513
19514 if (filenames == descend)
19515 {
32ec8896 19516 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19517 return false;
9ece1fa9
TT
19518 }
19519
19520 start = byte_get (descdata, addr_size);
19521 descdata += addr_size;
19522 end = byte_get (descdata, addr_size);
19523 descdata += addr_size;
19524 file_ofs = byte_get (descdata, addr_size);
19525 descdata += addr_size;
19526
19527 printf (" ");
19528 print_vma (start, FULL_HEX);
19529 printf (" ");
19530 print_vma (end, FULL_HEX);
19531 printf (" ");
19532 print_vma (file_ofs, FULL_HEX);
19533 printf ("\n %s\n", filenames);
19534
19535 filenames += 1 + strlen ((char *) filenames);
19536 }
19537
015dc7e1 19538 return true;
9ece1fa9
TT
19539}
19540
1118d252
RM
19541static const char *
19542get_gnu_elf_note_type (unsigned e_type)
19543{
1449284b 19544 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19545 switch (e_type)
19546 {
19547 case NT_GNU_ABI_TAG:
19548 return _("NT_GNU_ABI_TAG (ABI version tag)");
19549 case NT_GNU_HWCAP:
19550 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19551 case NT_GNU_BUILD_ID:
19552 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19553 case NT_GNU_GOLD_VERSION:
19554 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19555 case NT_GNU_PROPERTY_TYPE_0:
19556 return _("NT_GNU_PROPERTY_TYPE_0");
19557 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19558 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19559 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19560 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19561 default:
1449284b
NC
19562 {
19563 static char buff[64];
1118d252 19564
1449284b
NC
19565 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19566 return buff;
19567 }
19568 }
1118d252
RM
19569}
19570
a9eafb08
L
19571static void
19572decode_x86_compat_isa (unsigned int bitmask)
19573{
19574 while (bitmask)
19575 {
19576 unsigned int bit = bitmask & (- bitmask);
19577
19578 bitmask &= ~ bit;
19579 switch (bit)
19580 {
19581 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19582 printf ("i486");
19583 break;
19584 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19585 printf ("586");
19586 break;
19587 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19588 printf ("686");
19589 break;
19590 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19591 printf ("SSE");
19592 break;
19593 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19594 printf ("SSE2");
19595 break;
19596 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19597 printf ("SSE3");
19598 break;
19599 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19600 printf ("SSSE3");
19601 break;
19602 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19603 printf ("SSE4_1");
19604 break;
19605 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19606 printf ("SSE4_2");
19607 break;
19608 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19609 printf ("AVX");
19610 break;
19611 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19612 printf ("AVX2");
19613 break;
19614 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19615 printf ("AVX512F");
19616 break;
19617 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19618 printf ("AVX512CD");
19619 break;
19620 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19621 printf ("AVX512ER");
19622 break;
19623 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19624 printf ("AVX512PF");
19625 break;
19626 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19627 printf ("AVX512VL");
19628 break;
19629 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19630 printf ("AVX512DQ");
19631 break;
19632 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19633 printf ("AVX512BW");
19634 break;
65b3d26e
L
19635 default:
19636 printf (_("<unknown: %x>"), bit);
19637 break;
a9eafb08
L
19638 }
19639 if (bitmask)
19640 printf (", ");
19641 }
19642}
19643
9ef920e9 19644static void
32930e4e 19645decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19646{
0a59decb 19647 if (!bitmask)
90c745dc
L
19648 {
19649 printf (_("<None>"));
19650 return;
19651 }
90c745dc 19652
9ef920e9
NC
19653 while (bitmask)
19654 {
1fc87489 19655 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19656
19657 bitmask &= ~ bit;
19658 switch (bit)
19659 {
32930e4e 19660 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19661 printf ("CMOV");
19662 break;
32930e4e 19663 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19664 printf ("SSE");
19665 break;
32930e4e 19666 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19667 printf ("SSE2");
19668 break;
32930e4e 19669 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19670 printf ("SSE3");
19671 break;
32930e4e 19672 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19673 printf ("SSSE3");
19674 break;
32930e4e 19675 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19676 printf ("SSE4_1");
19677 break;
32930e4e 19678 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19679 printf ("SSE4_2");
19680 break;
32930e4e 19681 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19682 printf ("AVX");
19683 break;
32930e4e 19684 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19685 printf ("AVX2");
19686 break;
32930e4e 19687 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19688 printf ("FMA");
19689 break;
32930e4e 19690 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19691 printf ("AVX512F");
19692 break;
32930e4e 19693 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19694 printf ("AVX512CD");
19695 break;
32930e4e 19696 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19697 printf ("AVX512ER");
19698 break;
32930e4e 19699 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19700 printf ("AVX512PF");
19701 break;
32930e4e 19702 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19703 printf ("AVX512VL");
19704 break;
32930e4e 19705 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19706 printf ("AVX512DQ");
19707 break;
32930e4e 19708 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19709 printf ("AVX512BW");
19710 break;
32930e4e 19711 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19712 printf ("AVX512_4FMAPS");
19713 break;
32930e4e 19714 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19715 printf ("AVX512_4VNNIW");
19716 break;
32930e4e 19717 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19718 printf ("AVX512_BITALG");
19719 break;
32930e4e 19720 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19721 printf ("AVX512_IFMA");
19722 break;
32930e4e 19723 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19724 printf ("AVX512_VBMI");
19725 break;
32930e4e 19726 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19727 printf ("AVX512_VBMI2");
19728 break;
32930e4e 19729 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19730 printf ("AVX512_VNNI");
19731 break;
32930e4e 19732 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19733 printf ("AVX512_BF16");
19734 break;
65b3d26e
L
19735 default:
19736 printf (_("<unknown: %x>"), bit);
19737 break;
9ef920e9
NC
19738 }
19739 if (bitmask)
19740 printf (", ");
19741 }
19742}
19743
28cdbb18
SM
19744static const char *
19745get_amdgpu_elf_note_type (unsigned int e_type)
19746{
19747 switch (e_type)
19748 {
19749 case NT_AMDGPU_METADATA:
19750 return _("NT_AMDGPU_METADATA (code object metadata)");
19751 default:
19752 {
19753 static char buf[64];
19754 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19755 return buf;
19756 }
19757 }
19758}
19759
32930e4e
L
19760static void
19761decode_x86_isa (unsigned int bitmask)
19762{
32930e4e
L
19763 while (bitmask)
19764 {
19765 unsigned int bit = bitmask & (- bitmask);
19766
19767 bitmask &= ~ bit;
19768 switch (bit)
19769 {
b0ab0693
L
19770 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19771 printf ("x86-64-baseline");
19772 break;
32930e4e
L
19773 case GNU_PROPERTY_X86_ISA_1_V2:
19774 printf ("x86-64-v2");
19775 break;
19776 case GNU_PROPERTY_X86_ISA_1_V3:
19777 printf ("x86-64-v3");
19778 break;
19779 case GNU_PROPERTY_X86_ISA_1_V4:
19780 printf ("x86-64-v4");
19781 break;
19782 default:
19783 printf (_("<unknown: %x>"), bit);
19784 break;
19785 }
19786 if (bitmask)
19787 printf (", ");
19788 }
19789}
19790
ee2fdd6f 19791static void
a9eafb08 19792decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19793{
0a59decb 19794 if (!bitmask)
90c745dc
L
19795 {
19796 printf (_("<None>"));
19797 return;
19798 }
90c745dc 19799
ee2fdd6f
L
19800 while (bitmask)
19801 {
19802 unsigned int bit = bitmask & (- bitmask);
19803
19804 bitmask &= ~ bit;
19805 switch (bit)
19806 {
19807 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19808 printf ("IBT");
ee2fdd6f 19809 break;
48580982 19810 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19811 printf ("SHSTK");
48580982 19812 break;
279d901e
L
19813 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19814 printf ("LAM_U48");
19815 break;
19816 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19817 printf ("LAM_U57");
19818 break;
ee2fdd6f
L
19819 default:
19820 printf (_("<unknown: %x>"), bit);
19821 break;
19822 }
19823 if (bitmask)
19824 printf (", ");
19825 }
19826}
19827
a9eafb08
L
19828static void
19829decode_x86_feature_2 (unsigned int bitmask)
19830{
0a59decb 19831 if (!bitmask)
90c745dc
L
19832 {
19833 printf (_("<None>"));
19834 return;
19835 }
90c745dc 19836
a9eafb08
L
19837 while (bitmask)
19838 {
19839 unsigned int bit = bitmask & (- bitmask);
19840
19841 bitmask &= ~ bit;
19842 switch (bit)
19843 {
19844 case GNU_PROPERTY_X86_FEATURE_2_X86:
19845 printf ("x86");
19846 break;
19847 case GNU_PROPERTY_X86_FEATURE_2_X87:
19848 printf ("x87");
19849 break;
19850 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19851 printf ("MMX");
19852 break;
19853 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19854 printf ("XMM");
19855 break;
19856 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19857 printf ("YMM");
19858 break;
19859 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19860 printf ("ZMM");
19861 break;
a308b89d
L
19862 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19863 printf ("TMM");
19864 break;
32930e4e
L
19865 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19866 printf ("MASK");
19867 break;
a9eafb08
L
19868 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19869 printf ("FXSR");
19870 break;
19871 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19872 printf ("XSAVE");
19873 break;
19874 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19875 printf ("XSAVEOPT");
19876 break;
19877 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19878 printf ("XSAVEC");
19879 break;
65b3d26e
L
19880 default:
19881 printf (_("<unknown: %x>"), bit);
19882 break;
a9eafb08
L
19883 }
19884 if (bitmask)
19885 printf (", ");
19886 }
19887}
19888
cd702818
SD
19889static void
19890decode_aarch64_feature_1_and (unsigned int bitmask)
19891{
19892 while (bitmask)
19893 {
19894 unsigned int bit = bitmask & (- bitmask);
19895
19896 bitmask &= ~ bit;
19897 switch (bit)
19898 {
19899 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19900 printf ("BTI");
19901 break;
19902
19903 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19904 printf ("PAC");
19905 break;
19906
19907 default:
19908 printf (_("<unknown: %x>"), bit);
19909 break;
19910 }
19911 if (bitmask)
19912 printf (", ");
19913 }
19914}
19915
6320fd00
L
19916static void
19917decode_1_needed (unsigned int bitmask)
19918{
19919 while (bitmask)
19920 {
19921 unsigned int bit = bitmask & (- bitmask);
19922
19923 bitmask &= ~ bit;
19924 switch (bit)
19925 {
19926 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19927 printf ("indirect external access");
19928 break;
19929 default:
19930 printf (_("<unknown: %x>"), bit);
19931 break;
19932 }
19933 if (bitmask)
19934 printf (", ");
19935 }
19936}
19937
9ef920e9 19938static void
dda8d76d 19939print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19940{
19941 unsigned char * ptr = (unsigned char *) pnote->descdata;
19942 unsigned char * ptr_end = ptr + pnote->descsz;
19943 unsigned int size = is_32bit_elf ? 4 : 8;
19944
19945 printf (_(" Properties: "));
19946
1fc87489 19947 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19948 {
19949 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19950 return;
19951 }
19952
6ab2c4ed 19953 while (ptr < ptr_end)
9ef920e9 19954 {
1fc87489 19955 unsigned int j;
6ab2c4ed
MC
19956 unsigned int type;
19957 unsigned int datasz;
19958
19959 if ((size_t) (ptr_end - ptr) < 8)
19960 {
19961 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19962 break;
19963 }
19964
19965 type = byte_get (ptr, 4);
19966 datasz = byte_get (ptr + 4, 4);
9ef920e9 19967
1fc87489 19968 ptr += 8;
9ef920e9 19969
6ab2c4ed 19970 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19971 {
1fc87489
L
19972 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19973 type, datasz);
9ef920e9 19974 break;
1fc87489 19975 }
9ef920e9 19976
1fc87489
L
19977 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19978 {
dda8d76d
NC
19979 if (filedata->file_header.e_machine == EM_X86_64
19980 || filedata->file_header.e_machine == EM_IAMCU
19981 || filedata->file_header.e_machine == EM_386)
1fc87489 19982 {
aa7bca9b
L
19983 unsigned int bitmask;
19984
19985 if (datasz == 4)
0a59decb 19986 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19987 else
19988 bitmask = 0;
19989
1fc87489
L
19990 switch (type)
19991 {
19992 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19993 if (datasz != 4)
aa7bca9b
L
19994 printf (_("x86 ISA used: <corrupt length: %#x> "),
19995 datasz);
1fc87489 19996 else
aa7bca9b
L
19997 {
19998 printf ("x86 ISA used: ");
19999 decode_x86_isa (bitmask);
20000 }
1fc87489 20001 goto next;
9ef920e9 20002
1fc87489 20003 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20004 if (datasz != 4)
aa7bca9b
L
20005 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20006 datasz);
1fc87489 20007 else
aa7bca9b
L
20008 {
20009 printf ("x86 ISA needed: ");
20010 decode_x86_isa (bitmask);
20011 }
1fc87489 20012 goto next;
9ef920e9 20013
ee2fdd6f 20014 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20015 if (datasz != 4)
aa7bca9b
L
20016 printf (_("x86 feature: <corrupt length: %#x> "),
20017 datasz);
ee2fdd6f 20018 else
aa7bca9b
L
20019 {
20020 printf ("x86 feature: ");
a9eafb08
L
20021 decode_x86_feature_1 (bitmask);
20022 }
20023 goto next;
20024
20025 case GNU_PROPERTY_X86_FEATURE_2_USED:
20026 if (datasz != 4)
20027 printf (_("x86 feature used: <corrupt length: %#x> "),
20028 datasz);
20029 else
20030 {
20031 printf ("x86 feature used: ");
20032 decode_x86_feature_2 (bitmask);
20033 }
20034 goto next;
20035
20036 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20037 if (datasz != 4)
20038 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20039 else
20040 {
20041 printf ("x86 feature needed: ");
20042 decode_x86_feature_2 (bitmask);
20043 }
20044 goto next;
20045
20046 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20047 if (datasz != 4)
20048 printf (_("x86 ISA used: <corrupt length: %#x> "),
20049 datasz);
20050 else
20051 {
20052 printf ("x86 ISA used: ");
20053 decode_x86_compat_isa (bitmask);
20054 }
20055 goto next;
20056
20057 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20058 if (datasz != 4)
20059 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20060 datasz);
20061 else
20062 {
20063 printf ("x86 ISA needed: ");
20064 decode_x86_compat_isa (bitmask);
aa7bca9b 20065 }
ee2fdd6f
L
20066 goto next;
20067
32930e4e
L
20068 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20069 if (datasz != 4)
20070 printf (_("x86 ISA used: <corrupt length: %#x> "),
20071 datasz);
20072 else
20073 {
20074 printf ("x86 ISA used: ");
20075 decode_x86_compat_2_isa (bitmask);
20076 }
20077 goto next;
20078
20079 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20080 if (datasz != 4)
20081 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20082 datasz);
20083 else
20084 {
20085 printf ("x86 ISA needed: ");
20086 decode_x86_compat_2_isa (bitmask);
20087 }
20088 goto next;
20089
1fc87489
L
20090 default:
20091 break;
20092 }
20093 }
cd702818
SD
20094 else if (filedata->file_header.e_machine == EM_AARCH64)
20095 {
20096 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20097 {
20098 printf ("AArch64 feature: ");
20099 if (datasz != 4)
20100 printf (_("<corrupt length: %#x> "), datasz);
20101 else
20102 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20103 goto next;
20104 }
20105 }
1fc87489
L
20106 }
20107 else
20108 {
20109 switch (type)
9ef920e9 20110 {
1fc87489
L
20111 case GNU_PROPERTY_STACK_SIZE:
20112 printf (_("stack size: "));
20113 if (datasz != size)
20114 printf (_("<corrupt length: %#x> "), datasz);
20115 else
20116 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20117 goto next;
20118
20119 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20120 printf ("no copy on protected ");
20121 if (datasz)
20122 printf (_("<corrupt length: %#x> "), datasz);
20123 goto next;
20124
20125 default:
5a767724
L
20126 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20127 && type <= GNU_PROPERTY_UINT32_AND_HI)
20128 || (type >= GNU_PROPERTY_UINT32_OR_LO
20129 && type <= GNU_PROPERTY_UINT32_OR_HI))
20130 {
6320fd00
L
20131 switch (type)
20132 {
20133 case GNU_PROPERTY_1_NEEDED:
20134 if (datasz != 4)
20135 printf (_("1_needed: <corrupt length: %#x> "),
20136 datasz);
20137 else
20138 {
20139 unsigned int bitmask = byte_get (ptr, 4);
20140 printf ("1_needed: ");
20141 decode_1_needed (bitmask);
20142 }
20143 goto next;
20144
20145 default:
20146 break;
20147 }
5a767724
L
20148 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20149 printf (_("UINT32_AND (%#x): "), type);
20150 else
20151 printf (_("UINT32_OR (%#x): "), type);
20152 if (datasz != 4)
20153 printf (_("<corrupt length: %#x> "), datasz);
20154 else
20155 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20156 goto next;
20157 }
9ef920e9
NC
20158 break;
20159 }
9ef920e9
NC
20160 }
20161
1fc87489
L
20162 if (type < GNU_PROPERTY_LOPROC)
20163 printf (_("<unknown type %#x data: "), type);
20164 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20165 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20166 else
20167 printf (_("<application-specific type %#x data: "), type);
20168 for (j = 0; j < datasz; ++j)
20169 printf ("%02x ", ptr[j] & 0xff);
20170 printf (">");
20171
dc1e8a47 20172 next:
9ef920e9 20173 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20174 if (ptr == ptr_end)
20175 break;
1fc87489 20176
6ab2c4ed
MC
20177 if (do_wide)
20178 printf (", ");
20179 else
20180 printf ("\n\t");
9ef920e9
NC
20181 }
20182
20183 printf ("\n");
20184}
20185
015dc7e1 20186static bool
dda8d76d 20187print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20188{
1449284b 20189 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20190 switch (pnote->type)
20191 {
20192 case NT_GNU_BUILD_ID:
20193 {
20194 unsigned long i;
20195
20196 printf (_(" Build ID: "));
20197 for (i = 0; i < pnote->descsz; ++i)
20198 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20199 printf ("\n");
664f90a3
TT
20200 }
20201 break;
20202
20203 case NT_GNU_ABI_TAG:
20204 {
20205 unsigned long os, major, minor, subminor;
20206 const char *osname;
20207
3102e897
NC
20208 /* PR 17531: file: 030-599401-0.004. */
20209 if (pnote->descsz < 16)
20210 {
20211 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20212 break;
20213 }
20214
664f90a3
TT
20215 os = byte_get ((unsigned char *) pnote->descdata, 4);
20216 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20217 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20218 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20219
20220 switch (os)
20221 {
20222 case GNU_ABI_TAG_LINUX:
20223 osname = "Linux";
20224 break;
20225 case GNU_ABI_TAG_HURD:
20226 osname = "Hurd";
20227 break;
20228 case GNU_ABI_TAG_SOLARIS:
20229 osname = "Solaris";
20230 break;
20231 case GNU_ABI_TAG_FREEBSD:
20232 osname = "FreeBSD";
20233 break;
20234 case GNU_ABI_TAG_NETBSD:
20235 osname = "NetBSD";
20236 break;
14ae95f2
RM
20237 case GNU_ABI_TAG_SYLLABLE:
20238 osname = "Syllable";
20239 break;
20240 case GNU_ABI_TAG_NACL:
20241 osname = "NaCl";
20242 break;
664f90a3
TT
20243 default:
20244 osname = "Unknown";
20245 break;
20246 }
20247
20248 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20249 major, minor, subminor);
20250 }
20251 break;
926c5385
CC
20252
20253 case NT_GNU_GOLD_VERSION:
20254 {
20255 unsigned long i;
20256
20257 printf (_(" Version: "));
20258 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20259 printf ("%c", pnote->descdata[i]);
20260 printf ("\n");
20261 }
20262 break;
1449284b
NC
20263
20264 case NT_GNU_HWCAP:
20265 {
20266 unsigned long num_entries, mask;
20267
20268 /* Hardware capabilities information. Word 0 is the number of entries.
20269 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20270 is a series of entries, where each entry is a single byte followed
20271 by a nul terminated string. The byte gives the bit number to test
20272 if enabled in the bitmask. */
20273 printf (_(" Hardware Capabilities: "));
20274 if (pnote->descsz < 8)
20275 {
32ec8896 20276 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20277 return false;
1449284b
NC
20278 }
20279 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20280 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20281 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20282 /* FIXME: Add code to display the entries... */
20283 }
20284 break;
20285
9ef920e9 20286 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20287 print_gnu_property_note (filedata, pnote);
9ef920e9 20288 break;
9abca702 20289
1449284b
NC
20290 default:
20291 /* Handle unrecognised types. An error message should have already been
20292 created by get_gnu_elf_note_type(), so all that we need to do is to
20293 display the data. */
20294 {
20295 unsigned long i;
20296
20297 printf (_(" Description data: "));
20298 for (i = 0; i < pnote->descsz; ++i)
20299 printf ("%02x ", pnote->descdata[i] & 0xff);
20300 printf ("\n");
20301 }
20302 break;
664f90a3
TT
20303 }
20304
015dc7e1 20305 return true;
664f90a3
TT
20306}
20307
685080f2
NC
20308static const char *
20309get_v850_elf_note_type (enum v850_notes n_type)
20310{
20311 static char buff[64];
20312
20313 switch (n_type)
20314 {
20315 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20316 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20317 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20318 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20319 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20320 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20321 default:
20322 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20323 return buff;
20324 }
20325}
20326
015dc7e1 20327static bool
685080f2
NC
20328print_v850_note (Elf_Internal_Note * pnote)
20329{
20330 unsigned int val;
20331
20332 if (pnote->descsz != 4)
015dc7e1 20333 return false;
32ec8896 20334
685080f2
NC
20335 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20336
20337 if (val == 0)
20338 {
20339 printf (_("not set\n"));
015dc7e1 20340 return true;
685080f2
NC
20341 }
20342
20343 switch (pnote->type)
20344 {
20345 case V850_NOTE_ALIGNMENT:
20346 switch (val)
20347 {
015dc7e1
AM
20348 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20349 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20350 }
20351 break;
14ae95f2 20352
685080f2
NC
20353 case V850_NOTE_DATA_SIZE:
20354 switch (val)
20355 {
015dc7e1
AM
20356 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20357 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20358 }
20359 break;
14ae95f2 20360
685080f2
NC
20361 case V850_NOTE_FPU_INFO:
20362 switch (val)
20363 {
015dc7e1
AM
20364 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20365 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20366 }
20367 break;
14ae95f2 20368
685080f2
NC
20369 case V850_NOTE_MMU_INFO:
20370 case V850_NOTE_CACHE_INFO:
20371 case V850_NOTE_SIMD_INFO:
20372 if (val == EF_RH850_SIMD)
20373 {
20374 printf (_("yes\n"));
015dc7e1 20375 return true;
685080f2
NC
20376 }
20377 break;
20378
20379 default:
20380 /* An 'unknown note type' message will already have been displayed. */
20381 break;
20382 }
20383
20384 printf (_("unknown value: %x\n"), val);
015dc7e1 20385 return false;
685080f2
NC
20386}
20387
015dc7e1 20388static bool
c6056a74
SF
20389process_netbsd_elf_note (Elf_Internal_Note * pnote)
20390{
20391 unsigned int version;
20392
20393 switch (pnote->type)
20394 {
20395 case NT_NETBSD_IDENT:
b966f55f
AM
20396 if (pnote->descsz < 1)
20397 break;
c6056a74
SF
20398 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20399 if ((version / 10000) % 100)
b966f55f 20400 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20401 version, version / 100000000, (version / 1000000) % 100,
20402 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20403 'A' + (version / 10000) % 26);
c6056a74
SF
20404 else
20405 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20406 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20407 (version / 100) % 100);
015dc7e1 20408 return true;
c6056a74
SF
20409
20410 case NT_NETBSD_MARCH:
9abca702 20411 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20412 pnote->descdata);
015dc7e1 20413 return true;
c6056a74 20414
9abca702 20415 case NT_NETBSD_PAX:
b966f55f
AM
20416 if (pnote->descsz < 1)
20417 break;
9abca702
CZ
20418 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20419 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20420 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20421 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20422 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20423 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20424 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20425 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20426 return true;
c6056a74 20427 }
b966f55f
AM
20428
20429 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20430 pnote->descsz, pnote->type);
015dc7e1 20431 return false;
c6056a74
SF
20432}
20433
f4ddf30f 20434static const char *
dda8d76d 20435get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20436{
f4ddf30f
JB
20437 switch (e_type)
20438 {
20439 case NT_FREEBSD_THRMISC:
20440 return _("NT_THRMISC (thrmisc structure)");
20441 case NT_FREEBSD_PROCSTAT_PROC:
20442 return _("NT_PROCSTAT_PROC (proc data)");
20443 case NT_FREEBSD_PROCSTAT_FILES:
20444 return _("NT_PROCSTAT_FILES (files data)");
20445 case NT_FREEBSD_PROCSTAT_VMMAP:
20446 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20447 case NT_FREEBSD_PROCSTAT_GROUPS:
20448 return _("NT_PROCSTAT_GROUPS (groups data)");
20449 case NT_FREEBSD_PROCSTAT_UMASK:
20450 return _("NT_PROCSTAT_UMASK (umask data)");
20451 case NT_FREEBSD_PROCSTAT_RLIMIT:
20452 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20453 case NT_FREEBSD_PROCSTAT_OSREL:
20454 return _("NT_PROCSTAT_OSREL (osreldate data)");
20455 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20456 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20457 case NT_FREEBSD_PROCSTAT_AUXV:
20458 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20459 case NT_FREEBSD_PTLWPINFO:
20460 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20461 case NT_FREEBSD_X86_SEGBASES:
20462 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20463 }
dda8d76d 20464 return get_note_type (filedata, e_type);
f4ddf30f
JB
20465}
20466
9437c45b 20467static const char *
dda8d76d 20468get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20469{
20470 static char buff[64];
20471
540e6170
CZ
20472 switch (e_type)
20473 {
20474 case NT_NETBSDCORE_PROCINFO:
20475 /* NetBSD core "procinfo" structure. */
20476 return _("NetBSD procinfo structure");
9437c45b 20477
540e6170
CZ
20478 case NT_NETBSDCORE_AUXV:
20479 return _("NetBSD ELF auxiliary vector data");
9437c45b 20480
06d949ec
KR
20481 case NT_NETBSDCORE_LWPSTATUS:
20482 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20483
540e6170 20484 default:
06d949ec 20485 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20486 defined for NetBSD core files. If the note type is less
20487 than the start of the machine-dependent note types, we don't
20488 understand it. */
20489
20490 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20491 {
20492 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20493 return buff;
20494 }
20495 break;
9437c45b
JT
20496 }
20497
dda8d76d 20498 switch (filedata->file_header.e_machine)
9437c45b
JT
20499 {
20500 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20501 and PT_GETFPREGS == mach+2. */
20502
20503 case EM_OLD_ALPHA:
20504 case EM_ALPHA:
20505 case EM_SPARC:
20506 case EM_SPARC32PLUS:
20507 case EM_SPARCV9:
20508 switch (e_type)
20509 {
2b692964 20510 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20511 return _("PT_GETREGS (reg structure)");
2b692964 20512 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20513 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20514 default:
20515 break;
20516 }
20517 break;
20518
c0d38b0e
CZ
20519 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20520 There's also old PT___GETREGS40 == mach + 1 for old reg
20521 structure which lacks GBR. */
20522 case EM_SH:
20523 switch (e_type)
20524 {
20525 case NT_NETBSDCORE_FIRSTMACH + 1:
20526 return _("PT___GETREGS40 (old reg structure)");
20527 case NT_NETBSDCORE_FIRSTMACH + 3:
20528 return _("PT_GETREGS (reg structure)");
20529 case NT_NETBSDCORE_FIRSTMACH + 5:
20530 return _("PT_GETFPREGS (fpreg structure)");
20531 default:
20532 break;
20533 }
20534 break;
20535
9437c45b
JT
20536 /* On all other arch's, PT_GETREGS == mach+1 and
20537 PT_GETFPREGS == mach+3. */
20538 default:
20539 switch (e_type)
20540 {
2b692964 20541 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20542 return _("PT_GETREGS (reg structure)");
2b692964 20543 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20544 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20545 default:
20546 break;
20547 }
20548 }
20549
9cf03b7e 20550 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20551 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20552 return buff;
20553}
20554
98ca73af
FC
20555static const char *
20556get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20557{
20558 switch (e_type)
20559 {
20560 case NT_OPENBSD_PROCINFO:
20561 return _("OpenBSD procinfo structure");
20562 case NT_OPENBSD_AUXV:
20563 return _("OpenBSD ELF auxiliary vector data");
20564 case NT_OPENBSD_REGS:
20565 return _("OpenBSD regular registers");
20566 case NT_OPENBSD_FPREGS:
20567 return _("OpenBSD floating point registers");
20568 case NT_OPENBSD_WCOOKIE:
20569 return _("OpenBSD window cookie");
20570 }
20571
20572 return get_note_type (filedata, e_type);
20573}
20574
70616151
TT
20575static const char *
20576get_stapsdt_note_type (unsigned e_type)
20577{
20578 static char buff[64];
20579
20580 switch (e_type)
20581 {
20582 case NT_STAPSDT:
20583 return _("NT_STAPSDT (SystemTap probe descriptors)");
20584
20585 default:
20586 break;
20587 }
20588
20589 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20590 return buff;
20591}
20592
015dc7e1 20593static bool
c6a9fc58
TT
20594print_stapsdt_note (Elf_Internal_Note *pnote)
20595{
3ca60c57
NC
20596 size_t len, maxlen;
20597 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20598 char *data = pnote->descdata;
20599 char *data_end = pnote->descdata + pnote->descsz;
20600 bfd_vma pc, base_addr, semaphore;
20601 char *provider, *probe, *arg_fmt;
20602
3ca60c57
NC
20603 if (pnote->descsz < (addr_size * 3))
20604 goto stapdt_note_too_small;
20605
c6a9fc58
TT
20606 pc = byte_get ((unsigned char *) data, addr_size);
20607 data += addr_size;
3ca60c57 20608
c6a9fc58
TT
20609 base_addr = byte_get ((unsigned char *) data, addr_size);
20610 data += addr_size;
3ca60c57 20611
c6a9fc58
TT
20612 semaphore = byte_get ((unsigned char *) data, addr_size);
20613 data += addr_size;
20614
3ca60c57
NC
20615 if (data >= data_end)
20616 goto stapdt_note_too_small;
20617 maxlen = data_end - data;
20618 len = strnlen (data, maxlen);
20619 if (len < maxlen)
20620 {
20621 provider = data;
20622 data += len + 1;
20623 }
20624 else
20625 goto stapdt_note_too_small;
20626
20627 if (data >= data_end)
20628 goto stapdt_note_too_small;
20629 maxlen = data_end - data;
20630 len = strnlen (data, maxlen);
20631 if (len < maxlen)
20632 {
20633 probe = data;
20634 data += len + 1;
20635 }
20636 else
20637 goto stapdt_note_too_small;
9abca702 20638
3ca60c57
NC
20639 if (data >= data_end)
20640 goto stapdt_note_too_small;
20641 maxlen = data_end - data;
20642 len = strnlen (data, maxlen);
20643 if (len < maxlen)
20644 {
20645 arg_fmt = data;
20646 data += len + 1;
20647 }
20648 else
20649 goto stapdt_note_too_small;
c6a9fc58
TT
20650
20651 printf (_(" Provider: %s\n"), provider);
20652 printf (_(" Name: %s\n"), probe);
20653 printf (_(" Location: "));
20654 print_vma (pc, FULL_HEX);
20655 printf (_(", Base: "));
20656 print_vma (base_addr, FULL_HEX);
20657 printf (_(", Semaphore: "));
20658 print_vma (semaphore, FULL_HEX);
9cf03b7e 20659 printf ("\n");
c6a9fc58
TT
20660 printf (_(" Arguments: %s\n"), arg_fmt);
20661
20662 return data == data_end;
3ca60c57
NC
20663
20664 stapdt_note_too_small:
20665 printf (_(" <corrupt - note is too small>\n"));
20666 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20667 return false;
c6a9fc58
TT
20668}
20669
e5382207
LB
20670static bool
20671print_fdo_note (Elf_Internal_Note * pnote)
20672{
20673 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20674 {
20675 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20676 return true;
20677 }
20678 return false;
20679}
20680
00e98fc7
TG
20681static const char *
20682get_ia64_vms_note_type (unsigned e_type)
20683{
20684 static char buff[64];
20685
20686 switch (e_type)
20687 {
20688 case NT_VMS_MHD:
20689 return _("NT_VMS_MHD (module header)");
20690 case NT_VMS_LNM:
20691 return _("NT_VMS_LNM (language name)");
20692 case NT_VMS_SRC:
20693 return _("NT_VMS_SRC (source files)");
20694 case NT_VMS_TITLE:
9cf03b7e 20695 return "NT_VMS_TITLE";
00e98fc7
TG
20696 case NT_VMS_EIDC:
20697 return _("NT_VMS_EIDC (consistency check)");
20698 case NT_VMS_FPMODE:
20699 return _("NT_VMS_FPMODE (FP mode)");
20700 case NT_VMS_LINKTIME:
9cf03b7e 20701 return "NT_VMS_LINKTIME";
00e98fc7
TG
20702 case NT_VMS_IMGNAM:
20703 return _("NT_VMS_IMGNAM (image name)");
20704 case NT_VMS_IMGID:
20705 return _("NT_VMS_IMGID (image id)");
20706 case NT_VMS_LINKID:
20707 return _("NT_VMS_LINKID (link id)");
20708 case NT_VMS_IMGBID:
20709 return _("NT_VMS_IMGBID (build id)");
20710 case NT_VMS_GSTNAM:
20711 return _("NT_VMS_GSTNAM (sym table name)");
20712 case NT_VMS_ORIG_DYN:
9cf03b7e 20713 return "NT_VMS_ORIG_DYN";
00e98fc7 20714 case NT_VMS_PATCHTIME:
9cf03b7e 20715 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20716 default:
20717 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20718 return buff;
20719 }
20720}
20721
015dc7e1 20722static bool
00e98fc7
TG
20723print_ia64_vms_note (Elf_Internal_Note * pnote)
20724{
8d18bf79
NC
20725 int maxlen = pnote->descsz;
20726
20727 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20728 goto desc_size_fail;
20729
00e98fc7
TG
20730 switch (pnote->type)
20731 {
20732 case NT_VMS_MHD:
8d18bf79
NC
20733 if (maxlen <= 36)
20734 goto desc_size_fail;
20735
20736 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20737
20738 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20739 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20740 if (l + 34 < maxlen)
20741 {
20742 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20743 if (l + 35 < maxlen)
20744 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20745 else
20746 printf (_(" Module version : <missing>\n"));
20747 }
00e98fc7 20748 else
8d18bf79
NC
20749 {
20750 printf (_(" Module name : <missing>\n"));
20751 printf (_(" Module version : <missing>\n"));
20752 }
00e98fc7 20753 break;
8d18bf79 20754
00e98fc7 20755 case NT_VMS_LNM:
8d18bf79 20756 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20757 break;
8d18bf79 20758
00e98fc7
TG
20759#ifdef BFD64
20760 case NT_VMS_FPMODE:
9cf03b7e 20761 printf (_(" Floating Point mode: "));
8d18bf79
NC
20762 if (maxlen < 8)
20763 goto desc_size_fail;
20764 /* FIXME: Generate an error if descsz > 8 ? */
20765
4a5cb34f 20766 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20767 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20768 break;
8d18bf79 20769
00e98fc7
TG
20770 case NT_VMS_LINKTIME:
20771 printf (_(" Link time: "));
8d18bf79
NC
20772 if (maxlen < 8)
20773 goto desc_size_fail;
20774 /* FIXME: Generate an error if descsz > 8 ? */
20775
00e98fc7 20776 print_vms_time
8d18bf79 20777 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20778 printf ("\n");
20779 break;
8d18bf79 20780
00e98fc7
TG
20781 case NT_VMS_PATCHTIME:
20782 printf (_(" Patch time: "));
8d18bf79
NC
20783 if (maxlen < 8)
20784 goto desc_size_fail;
20785 /* FIXME: Generate an error if descsz > 8 ? */
20786
00e98fc7 20787 print_vms_time
8d18bf79 20788 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20789 printf ("\n");
20790 break;
8d18bf79 20791
00e98fc7 20792 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20793 if (maxlen < 34)
20794 goto desc_size_fail;
20795
00e98fc7
TG
20796 printf (_(" Major id: %u, minor id: %u\n"),
20797 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20798 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20799 printf (_(" Last modified : "));
00e98fc7
TG
20800 print_vms_time
20801 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20802 printf (_("\n Link flags : "));
4a5cb34f 20803 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20804 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20805 printf (_(" Header flags: 0x%08x\n"),
948f632f 20806 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20807 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20808 break;
20809#endif
8d18bf79 20810
00e98fc7 20811 case NT_VMS_IMGNAM:
8d18bf79 20812 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20813 break;
8d18bf79 20814
00e98fc7 20815 case NT_VMS_GSTNAM:
8d18bf79 20816 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20817 break;
8d18bf79 20818
00e98fc7 20819 case NT_VMS_IMGID:
8d18bf79 20820 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20821 break;
8d18bf79 20822
00e98fc7 20823 case NT_VMS_LINKID:
8d18bf79 20824 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20825 break;
8d18bf79 20826
00e98fc7 20827 default:
015dc7e1 20828 return false;
00e98fc7 20829 }
8d18bf79 20830
015dc7e1 20831 return true;
8d18bf79
NC
20832
20833 desc_size_fail:
20834 printf (_(" <corrupt - data size is too small>\n"));
20835 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20836 return false;
00e98fc7
TG
20837}
20838
fd486f32
AM
20839struct build_attr_cache {
20840 Filedata *filedata;
20841 char *strtab;
20842 unsigned long strtablen;
20843 Elf_Internal_Sym *symtab;
20844 unsigned long nsyms;
20845} ba_cache;
20846
6f156d7a
NC
20847/* Find the symbol associated with a build attribute that is attached
20848 to address OFFSET. If PNAME is non-NULL then store the name of
20849 the symbol (if found) in the provided pointer, Returns NULL if a
20850 symbol could not be found. */
c799a79d 20851
6f156d7a 20852static Elf_Internal_Sym *
015dc7e1
AM
20853get_symbol_for_build_attribute (Filedata *filedata,
20854 unsigned long offset,
20855 bool is_open_attr,
20856 const char **pname)
9ef920e9 20857{
fd486f32
AM
20858 Elf_Internal_Sym *saved_sym = NULL;
20859 Elf_Internal_Sym *sym;
9ef920e9 20860
dda8d76d 20861 if (filedata->section_headers != NULL
fd486f32 20862 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20863 {
c799a79d 20864 Elf_Internal_Shdr * symsec;
9ef920e9 20865
fd486f32
AM
20866 free (ba_cache.strtab);
20867 ba_cache.strtab = NULL;
20868 free (ba_cache.symtab);
20869 ba_cache.symtab = NULL;
20870
c799a79d 20871 /* Load the symbol and string sections. */
dda8d76d
NC
20872 for (symsec = filedata->section_headers;
20873 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20874 symsec ++)
9ef920e9 20875 {
28d13567
AM
20876 if (symsec->sh_type == SHT_SYMTAB
20877 && get_symtab (filedata, symsec,
20878 &ba_cache.symtab, &ba_cache.nsyms,
20879 &ba_cache.strtab, &ba_cache.strtablen))
20880 break;
9ef920e9 20881 }
fd486f32 20882 ba_cache.filedata = filedata;
9ef920e9
NC
20883 }
20884
fd486f32 20885 if (ba_cache.symtab == NULL)
6f156d7a 20886 return NULL;
9ef920e9 20887
c799a79d 20888 /* Find a symbol whose value matches offset. */
fd486f32 20889 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20890 if (sym->st_value == offset)
20891 {
fd486f32 20892 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20893 /* Huh ? This should not happen. */
20894 continue;
9ef920e9 20895
fd486f32 20896 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20897 continue;
9ef920e9 20898
9b9b1092 20899 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20900 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20901 if (ba_cache.strtab[sym->st_name] == '$'
20902 && ba_cache.strtab[sym->st_name + 1] != 0
20903 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20904 continue;
20905
c799a79d
NC
20906 if (is_open_attr)
20907 {
20908 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20909 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20910 FUNC symbols entirely. */
20911 switch (ELF_ST_TYPE (sym->st_info))
20912 {
c799a79d 20913 case STT_OBJECT:
6f156d7a 20914 case STT_FILE:
c799a79d 20915 saved_sym = sym;
6f156d7a
NC
20916 if (sym->st_size)
20917 {
20918 /* If the symbol has a size associated
20919 with it then we can stop searching. */
fd486f32 20920 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20921 }
c799a79d 20922 continue;
9ef920e9 20923
c799a79d
NC
20924 case STT_FUNC:
20925 /* Ignore function symbols. */
20926 continue;
20927
20928 default:
20929 break;
20930 }
20931
20932 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20933 {
c799a79d
NC
20934 case STB_GLOBAL:
20935 if (saved_sym == NULL
20936 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20937 saved_sym = sym;
20938 break;
c871dade 20939
c799a79d
NC
20940 case STB_LOCAL:
20941 if (saved_sym == NULL)
20942 saved_sym = sym;
20943 break;
20944
20945 default:
9ef920e9
NC
20946 break;
20947 }
20948 }
c799a79d
NC
20949 else
20950 {
20951 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20952 continue;
20953
20954 saved_sym = sym;
20955 break;
20956 }
20957 }
20958
6f156d7a 20959 if (saved_sym && pname)
fd486f32 20960 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20961
20962 return saved_sym;
c799a79d
NC
20963}
20964
d20e98ab
NC
20965/* Returns true iff addr1 and addr2 are in the same section. */
20966
015dc7e1 20967static bool
d20e98ab
NC
20968same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20969{
20970 Elf_Internal_Shdr * a1;
20971 Elf_Internal_Shdr * a2;
20972
20973 a1 = find_section_by_address (filedata, addr1);
20974 a2 = find_section_by_address (filedata, addr2);
9abca702 20975
d20e98ab
NC
20976 return a1 == a2 && a1 != NULL;
20977}
20978
015dc7e1 20979static bool
dda8d76d
NC
20980print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20981 Filedata * filedata)
c799a79d 20982{
015dc7e1
AM
20983 static unsigned long global_offset = 0;
20984 static unsigned long global_end = 0;
20985 static unsigned long func_offset = 0;
20986 static unsigned long func_end = 0;
c871dade 20987
015dc7e1
AM
20988 Elf_Internal_Sym *sym;
20989 const char *name;
20990 unsigned long start;
20991 unsigned long end;
20992 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20993
20994 switch (pnote->descsz)
c799a79d 20995 {
6f156d7a
NC
20996 case 0:
20997 /* A zero-length description means that the range of
20998 the previous note of the same type should be used. */
c799a79d 20999 if (is_open_attr)
c871dade 21000 {
6f156d7a
NC
21001 if (global_end > global_offset)
21002 printf (_(" Applies to region from %#lx to %#lx\n"),
21003 global_offset, global_end);
21004 else
21005 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
21006 }
21007 else
21008 {
6f156d7a
NC
21009 if (func_end > func_offset)
21010 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
21011 else
21012 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 21013 }
015dc7e1 21014 return true;
9ef920e9 21015
6f156d7a
NC
21016 case 4:
21017 start = byte_get ((unsigned char *) pnote->descdata, 4);
21018 end = 0;
21019 break;
21020
21021 case 8:
c74147bb
NC
21022 start = byte_get ((unsigned char *) pnote->descdata, 4);
21023 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21024 break;
21025
21026 case 16:
21027 start = byte_get ((unsigned char *) pnote->descdata, 8);
21028 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21029 break;
9abca702 21030
6f156d7a 21031 default:
c799a79d
NC
21032 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21033 printf (_(" <invalid descsz>"));
015dc7e1 21034 return false;
c799a79d
NC
21035 }
21036
6f156d7a
NC
21037 name = NULL;
21038 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21039 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21040 in order to avoid them being confused with the start address of the
21041 first function in the file... */
21042 if (sym == NULL && is_open_attr)
21043 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21044 & name);
6f156d7a
NC
21045
21046 if (end == 0 && sym != NULL && sym->st_size > 0)
21047 end = start + sym->st_size;
c799a79d
NC
21048
21049 if (is_open_attr)
21050 {
d20e98ab
NC
21051 /* FIXME: Need to properly allow for section alignment.
21052 16 is just the alignment used on x86_64. */
21053 if (global_end > 0
21054 && start > BFD_ALIGN (global_end, 16)
21055 /* Build notes are not guaranteed to be organised in order of
21056 increasing address, but we should find the all of the notes
21057 for one section in the same place. */
21058 && same_section (filedata, start, global_end))
6f156d7a
NC
21059 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21060 global_end + 1, start - 1);
21061
21062 printf (_(" Applies to region from %#lx"), start);
21063 global_offset = start;
21064
21065 if (end)
21066 {
21067 printf (_(" to %#lx"), end);
21068 global_end = end;
21069 }
c799a79d
NC
21070 }
21071 else
21072 {
6f156d7a
NC
21073 printf (_(" Applies to region from %#lx"), start);
21074 func_offset = start;
21075
21076 if (end)
21077 {
21078 printf (_(" to %#lx"), end);
21079 func_end = end;
21080 }
c799a79d
NC
21081 }
21082
6f156d7a
NC
21083 if (sym && name)
21084 printf (_(" (%s)"), name);
21085
21086 printf ("\n");
015dc7e1 21087 return true;
9ef920e9
NC
21088}
21089
015dc7e1 21090static bool
9ef920e9
NC
21091print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21092{
1d15e434
NC
21093 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21094 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21095 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21096 char name_type;
21097 char name_attribute;
1d15e434 21098 const char * expected_types;
9ef920e9
NC
21099 const char * name = pnote->namedata;
21100 const char * text;
88305e1b 21101 signed int left;
9ef920e9
NC
21102
21103 if (name == NULL || pnote->namesz < 2)
21104 {
21105 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21106 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21107 return false;
9ef920e9
NC
21108 }
21109
6f156d7a
NC
21110 if (do_wide)
21111 left = 28;
21112 else
21113 left = 20;
88305e1b
NC
21114
21115 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21116 if (name[0] == 'G' && name[1] == 'A')
21117 {
6f156d7a
NC
21118 if (pnote->namesz < 4)
21119 {
21120 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21121 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21122 return false;
6f156d7a
NC
21123 }
21124
88305e1b
NC
21125 printf ("GA");
21126 name += 2;
21127 left -= 2;
21128 }
21129
9ef920e9
NC
21130 switch ((name_type = * name))
21131 {
21132 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21133 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21134 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21135 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21136 printf ("%c", * name);
88305e1b 21137 left --;
9ef920e9
NC
21138 break;
21139 default:
21140 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21141 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21142 return false;
9ef920e9
NC
21143 }
21144
9ef920e9
NC
21145 ++ name;
21146 text = NULL;
21147
21148 switch ((name_attribute = * name))
21149 {
21150 case GNU_BUILD_ATTRIBUTE_VERSION:
21151 text = _("<version>");
1d15e434 21152 expected_types = string_expected;
9ef920e9
NC
21153 ++ name;
21154 break;
21155 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21156 text = _("<stack prot>");
75d7d298 21157 expected_types = "!+*";
9ef920e9
NC
21158 ++ name;
21159 break;
21160 case GNU_BUILD_ATTRIBUTE_RELRO:
21161 text = _("<relro>");
1d15e434 21162 expected_types = bool_expected;
9ef920e9
NC
21163 ++ name;
21164 break;
21165 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21166 text = _("<stack size>");
1d15e434 21167 expected_types = number_expected;
9ef920e9
NC
21168 ++ name;
21169 break;
21170 case GNU_BUILD_ATTRIBUTE_TOOL:
21171 text = _("<tool>");
1d15e434 21172 expected_types = string_expected;
9ef920e9
NC
21173 ++ name;
21174 break;
21175 case GNU_BUILD_ATTRIBUTE_ABI:
21176 text = _("<ABI>");
21177 expected_types = "$*";
21178 ++ name;
21179 break;
21180 case GNU_BUILD_ATTRIBUTE_PIC:
21181 text = _("<PIC>");
1d15e434 21182 expected_types = number_expected;
9ef920e9
NC
21183 ++ name;
21184 break;
a8be5506
NC
21185 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21186 text = _("<short enum>");
1d15e434 21187 expected_types = bool_expected;
a8be5506
NC
21188 ++ name;
21189 break;
9ef920e9
NC
21190 default:
21191 if (ISPRINT (* name))
21192 {
21193 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21194
21195 if (len > left && ! do_wide)
21196 len = left;
75d7d298 21197 printf ("%.*s:", len, name);
9ef920e9 21198 left -= len;
0dd6ae21 21199 name += len;
9ef920e9
NC
21200 }
21201 else
21202 {
3e6b6445 21203 static char tmpbuf [128];
88305e1b 21204
3e6b6445
NC
21205 error (_("unrecognised byte in name field: %d\n"), * name);
21206 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21207 text = tmpbuf;
21208 name ++;
9ef920e9
NC
21209 }
21210 expected_types = "*$!+";
21211 break;
21212 }
21213
21214 if (text)
88305e1b 21215 left -= printf ("%s", text);
9ef920e9
NC
21216
21217 if (strchr (expected_types, name_type) == NULL)
75d7d298 21218 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21219
21220 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21221 {
21222 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21223 (unsigned long) pnote->namesz,
21224 (long) (name - pnote->namedata));
015dc7e1 21225 return false;
9ef920e9
NC
21226 }
21227
21228 if (left < 1 && ! do_wide)
015dc7e1 21229 return true;
9ef920e9
NC
21230
21231 switch (name_type)
21232 {
21233 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21234 {
b06b2c92 21235 unsigned int bytes;
ddef72cd
NC
21236 unsigned long long val = 0;
21237 unsigned int shift = 0;
21238 char * decoded = NULL;
21239
b06b2c92
NC
21240 bytes = pnote->namesz - (name - pnote->namedata);
21241 if (bytes > 0)
21242 /* The -1 is because the name field is always 0 terminated, and we
21243 want to be able to ensure that the shift in the while loop below
21244 will not overflow. */
21245 -- bytes;
21246
ddef72cd
NC
21247 if (bytes > sizeof (val))
21248 {
3e6b6445
NC
21249 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21250 bytes);
21251 bytes = sizeof (val);
ddef72cd 21252 }
3e6b6445
NC
21253 /* We do not bother to warn if bytes == 0 as this can
21254 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21255
21256 while (bytes --)
21257 {
54b8331d 21258 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21259
21260 val |= byte << shift;
9ef920e9
NC
21261 shift += 8;
21262 }
21263
75d7d298 21264 switch (name_attribute)
9ef920e9 21265 {
75d7d298 21266 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21267 switch (val)
21268 {
75d7d298
NC
21269 case 0: decoded = "static"; break;
21270 case 1: decoded = "pic"; break;
21271 case 2: decoded = "PIC"; break;
21272 case 3: decoded = "pie"; break;
21273 case 4: decoded = "PIE"; break;
21274 default: break;
9ef920e9 21275 }
75d7d298
NC
21276 break;
21277 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21278 switch (val)
9ef920e9 21279 {
75d7d298
NC
21280 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21281 case 0: decoded = "off"; break;
21282 case 1: decoded = "on"; break;
21283 case 2: decoded = "all"; break;
21284 case 3: decoded = "strong"; break;
21285 case 4: decoded = "explicit"; break;
21286 default: break;
9ef920e9 21287 }
75d7d298
NC
21288 break;
21289 default:
21290 break;
9ef920e9
NC
21291 }
21292
75d7d298 21293 if (decoded != NULL)
3e6b6445
NC
21294 {
21295 print_symbol (-left, decoded);
21296 left = 0;
21297 }
21298 else if (val == 0)
21299 {
21300 printf ("0x0");
21301 left -= 3;
21302 }
9ef920e9 21303 else
75d7d298
NC
21304 {
21305 if (do_wide)
ddef72cd 21306 left -= printf ("0x%llx", val);
75d7d298 21307 else
ddef72cd 21308 left -= printf ("0x%-.*llx", left, val);
75d7d298 21309 }
9ef920e9
NC
21310 }
21311 break;
21312 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21313 left -= print_symbol (- left, name);
21314 break;
21315 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21316 left -= print_symbol (- left, "true");
21317 break;
21318 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21319 left -= print_symbol (- left, "false");
21320 break;
21321 }
21322
21323 if (do_wide && left > 0)
21324 printf ("%-*s", left, " ");
9abca702 21325
015dc7e1 21326 return true;
9ef920e9
NC
21327}
21328
2952f10c
SM
21329/* Print the contents of PNOTE as hex. */
21330
21331static void
21332print_note_contents_hex (Elf_Internal_Note *pnote)
21333{
21334 if (pnote->descsz)
21335 {
21336 unsigned long i;
21337
21338 printf (_(" description data: "));
21339 for (i = 0; i < pnote->descsz; i++)
21340 printf ("%02x ", pnote->descdata[i] & 0xff);
21341 if (!do_wide)
21342 printf ("\n");
21343 }
21344
21345 if (do_wide)
21346 printf ("\n");
21347}
21348
21349#if defined HAVE_MSGPACK
21350
21351static void
21352print_indents (int n)
21353{
21354 printf (" ");
21355
21356 for (int i = 0; i < n; i++)
21357 printf (" ");
21358}
21359
21360/* Print OBJ in human-readable form. */
21361
21362static void
21363dump_msgpack_obj (const msgpack_object *obj, int indent)
21364{
21365 switch (obj->type)
21366 {
21367 case MSGPACK_OBJECT_NIL:
21368 printf ("(nil)");
21369 break;
21370
21371 case MSGPACK_OBJECT_BOOLEAN:
21372 printf ("%s", obj->via.boolean ? "true" : "false");
21373 break;
21374
21375 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21376 printf ("%" PRIu64, obj->via.u64);
21377 break;
21378
21379 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21380 printf ("%" PRIi64, obj->via.i64);
21381 break;
21382
21383 case MSGPACK_OBJECT_FLOAT32:
21384 case MSGPACK_OBJECT_FLOAT64:
21385 printf ("%f", obj->via.f64);
21386 break;
21387
21388 case MSGPACK_OBJECT_STR:
21389 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21390 break;
21391
21392 case MSGPACK_OBJECT_ARRAY:
21393 {
21394 const msgpack_object_array *array = &obj->via.array;
21395
21396 printf ("[\n");
21397 ++indent;
21398
21399 for (uint32_t i = 0; i < array->size; ++i)
21400 {
21401 const msgpack_object *item = &array->ptr[i];
21402
21403 print_indents (indent);
21404 dump_msgpack_obj (item, indent);
21405 printf (",\n");
21406 }
21407
21408 --indent;
21409 print_indents (indent);
21410 printf ("]");
21411 break;
21412 }
21413 break;
21414
21415 case MSGPACK_OBJECT_MAP:
21416 {
21417 const msgpack_object_map *map = &obj->via.map;
21418
21419 printf ("{\n");
21420 ++indent;
21421
21422 for (uint32_t i = 0; i < map->size; ++i)
21423 {
21424 const msgpack_object_kv *kv = &map->ptr[i];
21425 const msgpack_object *key = &kv->key;
21426 const msgpack_object *val = &kv->val;
21427
21428 print_indents (indent);
21429 dump_msgpack_obj (key, indent);
21430 printf (": ");
21431 dump_msgpack_obj (val, indent);
21432
21433 printf (",\n");
21434 }
21435
21436 --indent;
21437 print_indents (indent);
21438 printf ("}");
21439
21440 break;
21441 }
21442
21443 case MSGPACK_OBJECT_BIN:
21444 printf ("(bin)");
21445 break;
21446
21447 case MSGPACK_OBJECT_EXT:
21448 printf ("(ext)");
21449 break;
21450 }
21451}
21452
21453static void
21454dump_msgpack (const msgpack_unpacked *msg)
21455{
21456 print_indents (0);
21457 dump_msgpack_obj (&msg->data, 0);
21458 printf ("\n");
21459}
21460
21461#endif /* defined HAVE_MSGPACK */
21462
21463static bool
21464print_amdgpu_note (Elf_Internal_Note *pnote)
21465{
21466#if defined HAVE_MSGPACK
21467 /* If msgpack is available, decode and dump the note's content. */
21468 bool ret;
21469 msgpack_unpacked msg;
21470 msgpack_unpack_return msgpack_ret;
21471
21472 assert (pnote->type == NT_AMDGPU_METADATA);
21473
21474 msgpack_unpacked_init (&msg);
21475 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21476 NULL);
21477
21478 switch (msgpack_ret)
21479 {
21480 case MSGPACK_UNPACK_SUCCESS:
21481 dump_msgpack (&msg);
21482 ret = true;
21483 break;
21484
21485 default:
21486 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21487 ret = false;
21488 break;
21489 }
21490
21491 msgpack_unpacked_destroy (&msg);
21492 return ret;
21493#else
21494 /* msgpack is not available, dump contents as hex. */
21495 print_note_contents_hex (pnote);
21496 return true;
21497#endif
21498}
21499
6d118b09
NC
21500/* Note that by the ELF standard, the name field is already null byte
21501 terminated, and namesz includes the terminating null byte.
21502 I.E. the value of namesz for the name "FSF" is 4.
21503
e3c8793a 21504 If the value of namesz is zero, there is no name present. */
9ef920e9 21505
015dc7e1 21506static bool
9ef920e9 21507process_note (Elf_Internal_Note * pnote,
dda8d76d 21508 Filedata * filedata)
779fe533 21509{
2cf0635d
NC
21510 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21511 const char * nt;
9437c45b
JT
21512
21513 if (pnote->namesz == 0)
1ec5cd37
NC
21514 /* If there is no note name, then use the default set of
21515 note type strings. */
dda8d76d 21516 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21517
24d127aa 21518 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21519 /* GNU-specific object file notes. */
21520 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21521
28cdbb18
SM
21522 else if (startswith (pnote->namedata, "AMDGPU"))
21523 /* AMDGPU-specific object file notes. */
21524 nt = get_amdgpu_elf_note_type (pnote->type);
21525
24d127aa 21526 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21527 /* FreeBSD-specific core file notes. */
dda8d76d 21528 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21529
24d127aa 21530 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21531 /* NetBSD-specific core file notes. */
dda8d76d 21532 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21533
24d127aa 21534 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21535 /* NetBSD-specific core file notes. */
21536 return process_netbsd_elf_note (pnote);
21537
24d127aa 21538 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21539 /* NetBSD-specific core file notes. */
21540 return process_netbsd_elf_note (pnote);
21541
98ca73af
FC
21542 else if (startswith (pnote->namedata, "OpenBSD"))
21543 /* OpenBSD-specific core file notes. */
21544 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21545
e9b095a5 21546 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21547 {
21548 /* SPU-specific core file notes. */
21549 nt = pnote->namedata + 4;
21550 name = "SPU";
21551 }
21552
24d127aa 21553 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21554 /* VMS/ia64-specific file notes. */
21555 nt = get_ia64_vms_note_type (pnote->type);
21556
24d127aa 21557 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21558 nt = get_stapsdt_note_type (pnote->type);
21559
9437c45b 21560 else
1ec5cd37
NC
21561 /* Don't recognize this note name; just use the default set of
21562 note type strings. */
dda8d76d 21563 nt = get_note_type (filedata, pnote->type);
9437c45b 21564
1449284b 21565 printf (" ");
9ef920e9 21566
24d127aa 21567 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21568 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21569 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21570 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21571 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21572 print_gnu_build_attribute_name (pnote);
21573 else
21574 print_symbol (-20, name);
21575
21576 if (do_wide)
21577 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21578 else
21579 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21580
24d127aa 21581 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21582 return print_ia64_vms_note (pnote);
24d127aa 21583 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21584 return print_gnu_note (filedata, pnote);
24d127aa 21585 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21586 return print_stapsdt_note (pnote);
24d127aa 21587 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21588 return print_core_note (pnote);
e5382207
LB
21589 else if (startswith (pnote->namedata, "FDO"))
21590 return print_fdo_note (pnote);
24d127aa 21591 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21592 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21593 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21594 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21595 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21596 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21597 else if (startswith (pnote->namedata, "AMDGPU")
21598 && pnote->type == NT_AMDGPU_METADATA)
21599 return print_amdgpu_note (pnote);
779fe533 21600
2952f10c 21601 print_note_contents_hex (pnote);
015dc7e1 21602 return true;
1449284b 21603}
6d118b09 21604
015dc7e1 21605static bool
dda8d76d
NC
21606process_notes_at (Filedata * filedata,
21607 Elf_Internal_Shdr * section,
21608 bfd_vma offset,
82ed9683
L
21609 bfd_vma length,
21610 bfd_vma align)
779fe533 21611{
015dc7e1
AM
21612 Elf_External_Note *pnotes;
21613 Elf_External_Note *external;
21614 char *end;
21615 bool res = true;
103f02d3 21616
779fe533 21617 if (length <= 0)
015dc7e1 21618 return false;
103f02d3 21619
1449284b
NC
21620 if (section)
21621 {
dda8d76d 21622 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21623 if (pnotes)
32ec8896 21624 {
dda8d76d 21625 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21626 {
21627 free (pnotes);
015dc7e1 21628 return false;
f761cb13 21629 }
32ec8896 21630 }
1449284b
NC
21631 }
21632 else
82ed9683 21633 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21634 _("notes"));
4dff97b2 21635
dd24e3da 21636 if (pnotes == NULL)
015dc7e1 21637 return false;
779fe533 21638
103f02d3 21639 external = pnotes;
103f02d3 21640
ca0e11aa
NC
21641 if (filedata->is_separate)
21642 printf (_("In linked file '%s': "), filedata->file_name);
21643 else
21644 printf ("\n");
1449284b 21645 if (section)
ca0e11aa 21646 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21647 else
ca0e11aa 21648 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21649 (unsigned long) offset, (unsigned long) length);
21650
82ed9683
L
21651 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21652 specifies that notes should be aligned to 4 bytes in 32-bit
21653 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21654 we also support 4 byte alignment in 64-bit objects. If section
21655 alignment is less than 4, we treate alignment as 4 bytes. */
21656 if (align < 4)
21657 align = 4;
21658 else if (align != 4 && align != 8)
21659 {
21660 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21661 (long) align);
a788aedd 21662 free (pnotes);
015dc7e1 21663 return false;
82ed9683
L
21664 }
21665
dbe15e4e 21666 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21667
c8071705
NC
21668 end = (char *) pnotes + length;
21669 while ((char *) external < end)
779fe533 21670 {
b34976b6 21671 Elf_Internal_Note inote;
15b42fb0 21672 size_t min_notesz;
4dff97b2 21673 char * next;
2cf0635d 21674 char * temp = NULL;
c8071705 21675 size_t data_remaining = end - (char *) external;
6d118b09 21676
dda8d76d 21677 if (!is_ia64_vms (filedata))
15b42fb0 21678 {
9dd3a467
NC
21679 /* PR binutils/15191
21680 Make sure that there is enough data to read. */
15b42fb0
AM
21681 min_notesz = offsetof (Elf_External_Note, name);
21682 if (data_remaining < min_notesz)
9dd3a467 21683 {
d3a49aa8
AM
21684 warn (ngettext ("Corrupt note: only %ld byte remains, "
21685 "not enough for a full note\n",
21686 "Corrupt note: only %ld bytes remain, "
21687 "not enough for a full note\n",
21688 data_remaining),
21689 (long) data_remaining);
9dd3a467
NC
21690 break;
21691 }
5396a86e
AM
21692 data_remaining -= min_notesz;
21693
15b42fb0
AM
21694 inote.type = BYTE_GET (external->type);
21695 inote.namesz = BYTE_GET (external->namesz);
21696 inote.namedata = external->name;
21697 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21698 inote.descdata = ((char *) external
4dff97b2 21699 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21700 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21701 next = ((char *) external
4dff97b2 21702 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21703 }
00e98fc7 21704 else
15b42fb0
AM
21705 {
21706 Elf64_External_VMS_Note *vms_external;
00e98fc7 21707
9dd3a467
NC
21708 /* PR binutils/15191
21709 Make sure that there is enough data to read. */
15b42fb0
AM
21710 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21711 if (data_remaining < min_notesz)
9dd3a467 21712 {
d3a49aa8
AM
21713 warn (ngettext ("Corrupt note: only %ld byte remains, "
21714 "not enough for a full note\n",
21715 "Corrupt note: only %ld bytes remain, "
21716 "not enough for a full note\n",
21717 data_remaining),
21718 (long) data_remaining);
9dd3a467
NC
21719 break;
21720 }
5396a86e 21721 data_remaining -= min_notesz;
3e55a963 21722
15b42fb0
AM
21723 vms_external = (Elf64_External_VMS_Note *) external;
21724 inote.type = BYTE_GET (vms_external->type);
21725 inote.namesz = BYTE_GET (vms_external->namesz);
21726 inote.namedata = vms_external->name;
21727 inote.descsz = BYTE_GET (vms_external->descsz);
21728 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21729 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21730 next = inote.descdata + align_power (inote.descsz, 3);
21731 }
21732
5396a86e
AM
21733 /* PR 17531: file: 3443835e. */
21734 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21735 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21736 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21737 || (size_t) (next - inote.descdata) < inote.descsz
21738 || ((size_t) (next - inote.descdata)
21739 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21740 {
15b42fb0 21741 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21742 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21743 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21744 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21745 break;
21746 }
21747
15b42fb0 21748 external = (Elf_External_Note *) next;
dd24e3da 21749
6d118b09
NC
21750 /* Verify that name is null terminated. It appears that at least
21751 one version of Linux (RedHat 6.0) generates corefiles that don't
21752 comply with the ELF spec by failing to include the null byte in
21753 namesz. */
18344509 21754 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21755 {
5396a86e 21756 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21757 {
5396a86e
AM
21758 temp = (char *) malloc (inote.namesz + 1);
21759 if (temp == NULL)
21760 {
21761 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21762 res = false;
5396a86e
AM
21763 break;
21764 }
76da6bbe 21765
5396a86e
AM
21766 memcpy (temp, inote.namedata, inote.namesz);
21767 inote.namedata = temp;
21768 }
21769 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21770 }
21771
dda8d76d 21772 if (! process_note (& inote, filedata))
015dc7e1 21773 res = false;
103f02d3 21774
9db70fc3
AM
21775 free (temp);
21776 temp = NULL;
779fe533
NC
21777 }
21778
21779 free (pnotes);
103f02d3 21780
779fe533
NC
21781 return res;
21782}
21783
015dc7e1 21784static bool
dda8d76d 21785process_corefile_note_segments (Filedata * filedata)
779fe533 21786{
015dc7e1 21787 Elf_Internal_Phdr *segment;
b34976b6 21788 unsigned int i;
015dc7e1 21789 bool res = true;
103f02d3 21790
dda8d76d 21791 if (! get_program_headers (filedata))
015dc7e1 21792 return true;
103f02d3 21793
dda8d76d
NC
21794 for (i = 0, segment = filedata->program_headers;
21795 i < filedata->file_header.e_phnum;
b34976b6 21796 i++, segment++)
779fe533
NC
21797 {
21798 if (segment->p_type == PT_NOTE)
dda8d76d 21799 if (! process_notes_at (filedata, NULL,
32ec8896 21800 (bfd_vma) segment->p_offset,
82ed9683
L
21801 (bfd_vma) segment->p_filesz,
21802 (bfd_vma) segment->p_align))
015dc7e1 21803 res = false;
779fe533 21804 }
103f02d3 21805
779fe533
NC
21806 return res;
21807}
21808
015dc7e1 21809static bool
dda8d76d 21810process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21811{
21812 Elf_External_Note * pnotes;
21813 Elf_External_Note * external;
c8071705 21814 char * end;
015dc7e1 21815 bool res = true;
685080f2
NC
21816
21817 if (length <= 0)
015dc7e1 21818 return false;
685080f2 21819
dda8d76d 21820 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21821 _("v850 notes"));
21822 if (pnotes == NULL)
015dc7e1 21823 return false;
685080f2
NC
21824
21825 external = pnotes;
c8071705 21826 end = (char*) pnotes + length;
685080f2
NC
21827
21828 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21829 (unsigned long) offset, (unsigned long) length);
21830
c8071705 21831 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21832 {
21833 Elf_External_Note * next;
21834 Elf_Internal_Note inote;
21835
21836 inote.type = BYTE_GET (external->type);
21837 inote.namesz = BYTE_GET (external->namesz);
21838 inote.namedata = external->name;
21839 inote.descsz = BYTE_GET (external->descsz);
21840 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21841 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21842
c8071705
NC
21843 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21844 {
21845 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21846 inote.descdata = inote.namedata;
21847 inote.namesz = 0;
21848 }
21849
685080f2
NC
21850 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21851
c8071705 21852 if ( ((char *) next > end)
685080f2
NC
21853 || ((char *) next < (char *) pnotes))
21854 {
21855 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21856 (unsigned long) ((char *) external - (char *) pnotes));
21857 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21858 inote.type, inote.namesz, inote.descsz);
21859 break;
21860 }
21861
21862 external = next;
21863
21864 /* Prevent out-of-bounds indexing. */
c8071705 21865 if ( inote.namedata + inote.namesz > end
685080f2
NC
21866 || inote.namedata + inote.namesz < inote.namedata)
21867 {
21868 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21869 (unsigned long) ((char *) external - (char *) pnotes));
21870 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21871 inote.type, inote.namesz, inote.descsz);
21872 break;
21873 }
21874
21875 printf (" %s: ", get_v850_elf_note_type (inote.type));
21876
21877 if (! print_v850_note (& inote))
21878 {
015dc7e1 21879 res = false;
685080f2
NC
21880 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21881 inote.namesz, inote.descsz);
21882 }
21883 }
21884
21885 free (pnotes);
21886
21887 return res;
21888}
21889
015dc7e1 21890static bool
dda8d76d 21891process_note_sections (Filedata * filedata)
1ec5cd37 21892{
015dc7e1 21893 Elf_Internal_Shdr *section;
1ec5cd37 21894 unsigned long i;
32ec8896 21895 unsigned int n = 0;
015dc7e1 21896 bool res = true;
1ec5cd37 21897
dda8d76d
NC
21898 for (i = 0, section = filedata->section_headers;
21899 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21900 i++, section++)
685080f2
NC
21901 {
21902 if (section->sh_type == SHT_NOTE)
21903 {
dda8d76d 21904 if (! process_notes_at (filedata, section,
32ec8896 21905 (bfd_vma) section->sh_offset,
82ed9683
L
21906 (bfd_vma) section->sh_size,
21907 (bfd_vma) section->sh_addralign))
015dc7e1 21908 res = false;
685080f2
NC
21909 n++;
21910 }
21911
dda8d76d
NC
21912 if (( filedata->file_header.e_machine == EM_V800
21913 || filedata->file_header.e_machine == EM_V850
21914 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21915 && section->sh_type == SHT_RENESAS_INFO)
21916 {
dda8d76d 21917 if (! process_v850_notes (filedata,
32ec8896
NC
21918 (bfd_vma) section->sh_offset,
21919 (bfd_vma) section->sh_size))
015dc7e1 21920 res = false;
685080f2
NC
21921 n++;
21922 }
21923 }
df565f32
NC
21924
21925 if (n == 0)
21926 /* Try processing NOTE segments instead. */
dda8d76d 21927 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21928
21929 return res;
21930}
21931
015dc7e1 21932static bool
dda8d76d 21933process_notes (Filedata * filedata)
779fe533
NC
21934{
21935 /* If we have not been asked to display the notes then do nothing. */
21936 if (! do_notes)
015dc7e1 21937 return true;
103f02d3 21938
dda8d76d
NC
21939 if (filedata->file_header.e_type != ET_CORE)
21940 return process_note_sections (filedata);
103f02d3 21941
779fe533 21942 /* No program headers means no NOTE segment. */
dda8d76d
NC
21943 if (filedata->file_header.e_phnum > 0)
21944 return process_corefile_note_segments (filedata);
779fe533 21945
ca0e11aa
NC
21946 if (filedata->is_separate)
21947 printf (_("No notes found in linked file '%s'.\n"),
21948 filedata->file_name);
21949 else
21950 printf (_("No notes found file.\n"));
21951
015dc7e1 21952 return true;
779fe533
NC
21953}
21954
60abdbed
NC
21955static unsigned char *
21956display_public_gnu_attributes (unsigned char * start,
21957 const unsigned char * const end)
21958{
21959 printf (_(" Unknown GNU attribute: %s\n"), start);
21960
21961 start += strnlen ((char *) start, end - start);
21962 display_raw_attribute (start, end);
21963
21964 return (unsigned char *) end;
21965}
21966
21967static unsigned char *
21968display_generic_attribute (unsigned char * start,
21969 unsigned int tag,
21970 const unsigned char * const end)
21971{
21972 if (tag == 0)
21973 return (unsigned char *) end;
21974
21975 return display_tag_value (tag, start, end);
21976}
21977
015dc7e1 21978static bool
dda8d76d 21979process_arch_specific (Filedata * filedata)
252b5132 21980{
a952a375 21981 if (! do_arch)
015dc7e1 21982 return true;
a952a375 21983
dda8d76d 21984 switch (filedata->file_header.e_machine)
252b5132 21985 {
53a346d8
CZ
21986 case EM_ARC:
21987 case EM_ARC_COMPACT:
21988 case EM_ARC_COMPACT2:
dda8d76d 21989 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21990 display_arc_attribute,
21991 display_generic_attribute);
11c1ff18 21992 case EM_ARM:
dda8d76d 21993 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21994 display_arm_attribute,
21995 display_generic_attribute);
21996
252b5132 21997 case EM_MIPS:
4fe85591 21998 case EM_MIPS_RS3_LE:
dda8d76d 21999 return process_mips_specific (filedata);
60abdbed
NC
22000
22001 case EM_MSP430:
dda8d76d 22002 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22003 display_msp430_attribute,
c0ea7c52 22004 display_msp430_gnu_attribute);
60abdbed 22005
2dc8dd17
JW
22006 case EM_RISCV:
22007 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22008 display_riscv_attribute,
22009 display_generic_attribute);
22010
35c08157 22011 case EM_NDS32:
dda8d76d 22012 return process_nds32_specific (filedata);
60abdbed 22013
85f7484a
PB
22014 case EM_68K:
22015 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22016 display_m68k_gnu_attribute);
22017
34c8bcba 22018 case EM_PPC:
b82317dd 22019 case EM_PPC64:
dda8d76d 22020 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22021 display_power_gnu_attribute);
22022
643f7afb
AK
22023 case EM_S390:
22024 case EM_S390_OLD:
dda8d76d 22025 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22026 display_s390_gnu_attribute);
22027
9e8c70f9
DM
22028 case EM_SPARC:
22029 case EM_SPARC32PLUS:
22030 case EM_SPARCV9:
dda8d76d 22031 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22032 display_sparc_gnu_attribute);
22033
59e6276b 22034 case EM_TI_C6000:
dda8d76d 22035 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22036 display_tic6x_attribute,
22037 display_generic_attribute);
22038
0861f561
CQ
22039 case EM_CSKY:
22040 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22041 display_csky_attribute, NULL);
22042
252b5132 22043 default:
dda8d76d 22044 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22045 display_public_gnu_attributes,
22046 display_generic_attribute);
252b5132 22047 }
252b5132
RH
22048}
22049
015dc7e1 22050static bool
dda8d76d 22051get_file_header (Filedata * filedata)
252b5132 22052{
9ea033b2 22053 /* Read in the identity array. */
dda8d76d 22054 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22055 return false;
252b5132 22056
9ea033b2 22057 /* Determine how to read the rest of the header. */
dda8d76d 22058 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22059 {
1a0670f3
AM
22060 default:
22061 case ELFDATANONE:
adab8cdc
AO
22062 case ELFDATA2LSB:
22063 byte_get = byte_get_little_endian;
22064 byte_put = byte_put_little_endian;
22065 break;
22066 case ELFDATA2MSB:
22067 byte_get = byte_get_big_endian;
22068 byte_put = byte_put_big_endian;
22069 break;
9ea033b2
NC
22070 }
22071
22072 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22073 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22074
22075 /* Read in the rest of the header. */
22076 if (is_32bit_elf)
22077 {
22078 Elf32_External_Ehdr ehdr32;
252b5132 22079
dda8d76d 22080 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22081 return false;
103f02d3 22082
dda8d76d
NC
22083 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22084 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22085 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22086 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22087 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22088 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22089 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22090 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22091 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22092 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22093 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22094 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22095 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22096 }
252b5132 22097 else
9ea033b2
NC
22098 {
22099 Elf64_External_Ehdr ehdr64;
a952a375
NC
22100
22101 /* If we have been compiled with sizeof (bfd_vma) == 4, then
22102 we will not be able to cope with the 64bit data found in
22103 64 ELF files. Detect this now and abort before we start
50c2245b 22104 overwriting things. */
a952a375
NC
22105 if (sizeof (bfd_vma) < 8)
22106 {
e3c8793a
NC
22107 error (_("This instance of readelf has been built without support for a\n\
2210864 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 22109 return false;
a952a375 22110 }
103f02d3 22111
dda8d76d 22112 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22113 return false;
103f02d3 22114
dda8d76d
NC
22115 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22116 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22117 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22118 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22119 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22120 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22121 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22122 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22123 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22124 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22125 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22126 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22127 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22128 }
252b5132 22129
015dc7e1 22130 return true;
252b5132
RH
22131}
22132
13acb58d
AM
22133static void
22134free_filedata (Filedata *filedata)
22135{
22136 free (filedata->program_interpreter);
13acb58d 22137 free (filedata->program_headers);
13acb58d 22138 free (filedata->section_headers);
13acb58d 22139 free (filedata->string_table);
13acb58d 22140 free (filedata->dump.dump_sects);
13acb58d 22141 free (filedata->dynamic_strings);
13acb58d 22142 free (filedata->dynamic_symbols);
13acb58d 22143 free (filedata->dynamic_syminfo);
13acb58d 22144 free (filedata->dynamic_section);
13acb58d
AM
22145
22146 while (filedata->symtab_shndx_list != NULL)
22147 {
22148 elf_section_list *next = filedata->symtab_shndx_list->next;
22149 free (filedata->symtab_shndx_list);
22150 filedata->symtab_shndx_list = next;
22151 }
22152
22153 free (filedata->section_headers_groups);
13acb58d
AM
22154
22155 if (filedata->section_groups)
22156 {
22157 size_t i;
22158 struct group_list * g;
22159 struct group_list * next;
22160
22161 for (i = 0; i < filedata->group_count; i++)
22162 {
22163 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22164 {
22165 next = g->next;
22166 free (g);
22167 }
22168 }
22169
22170 free (filedata->section_groups);
13acb58d 22171 }
066f8fbe
AM
22172 memset (&filedata->section_headers, 0,
22173 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22174}
22175
dda8d76d
NC
22176static void
22177close_file (Filedata * filedata)
22178{
22179 if (filedata)
22180 {
22181 if (filedata->handle)
22182 fclose (filedata->handle);
22183 free (filedata);
22184 }
22185}
22186
22187void
22188close_debug_file (void * data)
22189{
13acb58d 22190 free_filedata ((Filedata *) data);
dda8d76d
NC
22191 close_file ((Filedata *) data);
22192}
22193
22194static Filedata *
015dc7e1 22195open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22196{
22197 struct stat statbuf;
22198 Filedata * filedata = NULL;
22199
22200 if (stat (pathname, & statbuf) < 0
22201 || ! S_ISREG (statbuf.st_mode))
22202 goto fail;
22203
22204 filedata = calloc (1, sizeof * filedata);
22205 if (filedata == NULL)
22206 goto fail;
22207
22208 filedata->handle = fopen (pathname, "rb");
22209 if (filedata->handle == NULL)
22210 goto fail;
22211
22212 filedata->file_size = (bfd_size_type) statbuf.st_size;
22213 filedata->file_name = pathname;
ca0e11aa 22214 filedata->is_separate = is_separate;
dda8d76d
NC
22215
22216 if (! get_file_header (filedata))
22217 goto fail;
22218
4de91c10
AM
22219 if (!get_section_headers (filedata, false))
22220 goto fail;
dda8d76d
NC
22221
22222 return filedata;
22223
22224 fail:
22225 if (filedata)
22226 {
22227 if (filedata->handle)
22228 fclose (filedata->handle);
22229 free (filedata);
22230 }
22231 return NULL;
22232}
22233
22234void *
22235open_debug_file (const char * pathname)
22236{
015dc7e1 22237 return open_file (pathname, true);
dda8d76d
NC
22238}
22239
835f2fae
NC
22240static void
22241initialise_dump_sects (Filedata * filedata)
22242{
22243 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22244 Note we do this even if cmdline_dump_sects is empty because we
22245 must make sure that the dump_sets array is zeroed out before each
22246 object file is processed. */
22247 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22248 memset (filedata->dump.dump_sects, 0,
22249 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22250
22251 if (cmdline.num_dump_sects > 0)
22252 {
22253 if (filedata->dump.num_dump_sects == 0)
22254 /* A sneaky way of allocating the dump_sects array. */
22255 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22256
22257 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22258 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22259 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22260 }
22261}
22262
94585d6d
NC
22263static bool
22264might_need_separate_debug_info (Filedata * filedata)
22265{
22266 /* Debuginfo files do not need further separate file loading. */
22267 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22268 return false;
22269
22270 /* Since do_follow_links might be enabled by default, only treat it as an
22271 indication that separate files should be loaded if setting it was a
22272 deliberate user action. */
22273 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22274 return true;
22275
22276 if (process_links || do_syms || do_unwind
22277 || dump_any_debugging || do_dump || do_debugging)
22278 return true;
22279
22280 return false;
22281}
22282
fb52b2f4
NC
22283/* Process one ELF object file according to the command line options.
22284 This file may actually be stored in an archive. The file is
32ec8896
NC
22285 positioned at the start of the ELF object. Returns TRUE if no
22286 problems were encountered, FALSE otherwise. */
fb52b2f4 22287
015dc7e1 22288static bool
dda8d76d 22289process_object (Filedata * filedata)
252b5132 22290{
015dc7e1 22291 bool have_separate_files;
252b5132 22292 unsigned int i;
015dc7e1 22293 bool res;
252b5132 22294
dda8d76d 22295 if (! get_file_header (filedata))
252b5132 22296 {
dda8d76d 22297 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22298 return false;
252b5132
RH
22299 }
22300
22301 /* Initialise per file variables. */
978c4450
AM
22302 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22303 filedata->version_info[i] = 0;
252b5132 22304
978c4450
AM
22305 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22306 filedata->dynamic_info[i] = 0;
22307 filedata->dynamic_info_DT_GNU_HASH = 0;
22308 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22309
22310 /* Process the file. */
22311 if (show_name)
dda8d76d 22312 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22313
835f2fae 22314 initialise_dump_sects (filedata);
d70c5fc7 22315
4de91c10
AM
22316 /* There may be some extensions in the first section header. Don't
22317 bomb if we can't read it. */
22318 get_section_headers (filedata, true);
22319
dda8d76d 22320 if (! process_file_header (filedata))
4de91c10
AM
22321 {
22322 res = false;
22323 goto out;
22324 }
252b5132 22325
e331b18d
AM
22326 /* Throw away the single section header read above, so that we
22327 re-read the entire set. */
22328 free (filedata->section_headers);
22329 filedata->section_headers = NULL;
22330
dda8d76d 22331 if (! process_section_headers (filedata))
2f62977e 22332 {
32ec8896 22333 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22334 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22335
2f62977e 22336 if (! do_using_dynamic)
015dc7e1 22337 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22338 }
252b5132 22339
dda8d76d 22340 if (! process_section_groups (filedata))
32ec8896 22341 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22342 do_unwind = false;
d1f5c6e3 22343
93df3340
AM
22344 process_program_headers (filedata);
22345
22346 res = process_dynamic_section (filedata);
252b5132 22347
dda8d76d 22348 if (! process_relocs (filedata))
015dc7e1 22349 res = false;
252b5132 22350
dda8d76d 22351 if (! process_unwind (filedata))
015dc7e1 22352 res = false;
4d6ed7c8 22353
dda8d76d 22354 if (! process_symbol_table (filedata))
015dc7e1 22355 res = false;
252b5132 22356
0f03783c 22357 if (! process_lto_symbol_tables (filedata))
015dc7e1 22358 res = false;
b9e920ec 22359
dda8d76d 22360 if (! process_syminfo (filedata))
015dc7e1 22361 res = false;
252b5132 22362
dda8d76d 22363 if (! process_version_sections (filedata))
015dc7e1 22364 res = false;
252b5132 22365
94585d6d 22366 if (might_need_separate_debug_info (filedata))
24841daa 22367 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22368 else
015dc7e1 22369 have_separate_files = false;
dda8d76d
NC
22370
22371 if (! process_section_contents (filedata))
015dc7e1 22372 res = false;
f5842774 22373
24841daa 22374 if (have_separate_files)
dda8d76d 22375 {
24841daa
NC
22376 separate_info * d;
22377
22378 for (d = first_separate_info; d != NULL; d = d->next)
22379 {
835f2fae
NC
22380 initialise_dump_sects (d->handle);
22381
ca0e11aa 22382 if (process_links && ! process_file_header (d->handle))
015dc7e1 22383 res = false;
ca0e11aa 22384 else if (! process_section_headers (d->handle))
015dc7e1 22385 res = false;
d6bfbc39 22386 else if (! process_section_contents (d->handle))
015dc7e1 22387 res = false;
ca0e11aa
NC
22388 else if (process_links)
22389 {
ca0e11aa 22390 if (! process_section_groups (d->handle))
015dc7e1 22391 res = false;
93df3340 22392 process_program_headers (d->handle);
ca0e11aa 22393 if (! process_dynamic_section (d->handle))
015dc7e1 22394 res = false;
ca0e11aa 22395 if (! process_relocs (d->handle))
015dc7e1 22396 res = false;
ca0e11aa 22397 if (! process_unwind (d->handle))
015dc7e1 22398 res = false;
ca0e11aa 22399 if (! process_symbol_table (d->handle))
015dc7e1 22400 res = false;
ca0e11aa 22401 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22402 res = false;
ca0e11aa 22403 if (! process_syminfo (d->handle))
015dc7e1 22404 res = false;
ca0e11aa 22405 if (! process_version_sections (d->handle))
015dc7e1 22406 res = false;
ca0e11aa 22407 if (! process_notes (d->handle))
015dc7e1 22408 res = false;
ca0e11aa 22409 }
24841daa
NC
22410 }
22411
22412 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22413 }
22414
22415 if (! process_notes (filedata))
015dc7e1 22416 res = false;
103f02d3 22417
dda8d76d 22418 if (! process_gnu_liblist (filedata))
015dc7e1 22419 res = false;
047b2264 22420
dda8d76d 22421 if (! process_arch_specific (filedata))
015dc7e1 22422 res = false;
252b5132 22423
4de91c10 22424 out:
13acb58d 22425 free_filedata (filedata);
e4b17d5c 22426
19e6b90e 22427 free_debug_memory ();
18bd398b 22428
32ec8896 22429 return res;
252b5132
RH
22430}
22431
2cf0635d 22432/* Process an ELF archive.
32ec8896
NC
22433 On entry the file is positioned just after the ARMAG string.
22434 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22435
015dc7e1
AM
22436static bool
22437process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22438{
22439 struct archive_info arch;
22440 struct archive_info nested_arch;
22441 size_t got;
015dc7e1 22442 bool ret = true;
2cf0635d 22443
015dc7e1 22444 show_name = true;
2cf0635d
NC
22445
22446 /* The ARCH structure is used to hold information about this archive. */
22447 arch.file_name = NULL;
22448 arch.file = NULL;
22449 arch.index_array = NULL;
22450 arch.sym_table = NULL;
22451 arch.longnames = NULL;
22452
22453 /* The NESTED_ARCH structure is used as a single-item cache of information
22454 about a nested archive (when members of a thin archive reside within
22455 another regular archive file). */
22456 nested_arch.file_name = NULL;
22457 nested_arch.file = NULL;
22458 nested_arch.index_array = NULL;
22459 nested_arch.sym_table = NULL;
22460 nested_arch.longnames = NULL;
22461
dda8d76d 22462 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22463 filedata->file_size, is_thin_archive,
22464 do_archive_index) != 0)
2cf0635d 22465 {
015dc7e1 22466 ret = false;
2cf0635d 22467 goto out;
4145f1d5 22468 }
fb52b2f4 22469
4145f1d5
NC
22470 if (do_archive_index)
22471 {
2cf0635d 22472 if (arch.sym_table == NULL)
1cb7d8b1
AM
22473 error (_("%s: unable to dump the index as none was found\n"),
22474 filedata->file_name);
4145f1d5
NC
22475 else
22476 {
591f7597 22477 unsigned long i, l;
4145f1d5
NC
22478 unsigned long current_pos;
22479
1cb7d8b1
AM
22480 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22481 "in the symbol table)\n"),
22482 filedata->file_name, (unsigned long) arch.index_num,
22483 arch.sym_size);
dda8d76d
NC
22484
22485 current_pos = ftell (filedata->handle);
4145f1d5 22486
2cf0635d 22487 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22488 {
1cb7d8b1
AM
22489 if (i == 0
22490 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22491 {
22492 char * member_name
22493 = get_archive_member_name_at (&arch, arch.index_array[i],
22494 &nested_arch);
2cf0635d 22495
1cb7d8b1
AM
22496 if (member_name != NULL)
22497 {
22498 char * qualified_name
22499 = make_qualified_name (&arch, &nested_arch,
22500 member_name);
2cf0635d 22501
1cb7d8b1
AM
22502 if (qualified_name != NULL)
22503 {
22504 printf (_("Contents of binary %s at offset "),
22505 qualified_name);
c2a7d3f5
NC
22506 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22507 putchar ('\n');
1cb7d8b1
AM
22508 free (qualified_name);
22509 }
fd486f32 22510 free (member_name);
4145f1d5
NC
22511 }
22512 }
2cf0635d
NC
22513
22514 if (l >= arch.sym_size)
4145f1d5 22515 {
1cb7d8b1
AM
22516 error (_("%s: end of the symbol table reached "
22517 "before the end of the index\n"),
dda8d76d 22518 filedata->file_name);
015dc7e1 22519 ret = false;
cb8f3167 22520 break;
4145f1d5 22521 }
591f7597 22522 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22523 printf ("\t%.*s\n",
22524 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22525 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22526 }
22527
67ce483b 22528 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22529 l = (l + 7) & ~ 7;
22530 else
22531 l += l & 1;
22532
2cf0635d 22533 if (l < arch.sym_size)
32ec8896 22534 {
d3a49aa8
AM
22535 error (ngettext ("%s: %ld byte remains in the symbol table, "
22536 "but without corresponding entries in "
22537 "the index table\n",
22538 "%s: %ld bytes remain in the symbol table, "
22539 "but without corresponding entries in "
22540 "the index table\n",
22541 arch.sym_size - l),
dda8d76d 22542 filedata->file_name, arch.sym_size - l);
015dc7e1 22543 ret = false;
32ec8896 22544 }
4145f1d5 22545
dda8d76d 22546 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22547 {
1cb7d8b1
AM
22548 error (_("%s: failed to seek back to start of object files "
22549 "in the archive\n"),
dda8d76d 22550 filedata->file_name);
015dc7e1 22551 ret = false;
2cf0635d 22552 goto out;
4145f1d5 22553 }
fb52b2f4 22554 }
4145f1d5
NC
22555
22556 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22557 && !do_segments && !do_header && !do_dump && !do_version
22558 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22559 && !do_section_groups && !do_dyn_syms)
2cf0635d 22560 {
015dc7e1 22561 ret = true; /* Archive index only. */
2cf0635d
NC
22562 goto out;
22563 }
fb52b2f4
NC
22564 }
22565
fb52b2f4
NC
22566 while (1)
22567 {
2cf0635d
NC
22568 char * name;
22569 size_t namelen;
22570 char * qualified_name;
22571
22572 /* Read the next archive header. */
dda8d76d 22573 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22574 {
22575 error (_("%s: failed to seek to next archive header\n"),
22576 arch.file_name);
015dc7e1 22577 ret = false;
1cb7d8b1
AM
22578 break;
22579 }
dda8d76d 22580 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22581 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22582 {
22583 if (got == 0)
2cf0635d 22584 break;
28e817cc
NC
22585 /* PR 24049 - we cannot use filedata->file_name as this will
22586 have already been freed. */
22587 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22588
015dc7e1 22589 ret = false;
1cb7d8b1
AM
22590 break;
22591 }
2cf0635d 22592 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22593 {
22594 error (_("%s: did not find a valid archive header\n"),
22595 arch.file_name);
015dc7e1 22596 ret = false;
1cb7d8b1
AM
22597 break;
22598 }
2cf0635d
NC
22599
22600 arch.next_arhdr_offset += sizeof arch.arhdr;
22601
978c4450 22602 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22603
22604 name = get_archive_member_name (&arch, &nested_arch);
22605 if (name == NULL)
fb52b2f4 22606 {
28e817cc 22607 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22608 ret = false;
d989285c 22609 break;
fb52b2f4 22610 }
2cf0635d 22611 namelen = strlen (name);
fb52b2f4 22612
2cf0635d
NC
22613 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22614 if (qualified_name == NULL)
fb52b2f4 22615 {
28e817cc 22616 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22617 free (name);
015dc7e1 22618 ret = false;
d989285c 22619 break;
fb52b2f4
NC
22620 }
22621
2cf0635d 22622 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22623 {
22624 /* This is a proxy for an external member of a thin archive. */
22625 Filedata * member_filedata;
22626 char * member_file_name = adjust_relative_path
dda8d76d 22627 (filedata->file_name, name, namelen);
32ec8896 22628
fd486f32 22629 free (name);
1cb7d8b1
AM
22630 if (member_file_name == NULL)
22631 {
fd486f32 22632 free (qualified_name);
015dc7e1 22633 ret = false;
1cb7d8b1
AM
22634 break;
22635 }
2cf0635d 22636
015dc7e1 22637 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22638 if (member_filedata == NULL)
22639 {
22640 error (_("Input file '%s' is not readable.\n"), member_file_name);
22641 free (member_file_name);
fd486f32 22642 free (qualified_name);
015dc7e1 22643 ret = false;
1cb7d8b1
AM
22644 break;
22645 }
2cf0635d 22646
978c4450 22647 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22648 member_filedata->file_name = qualified_name;
2cf0635d 22649
75a2da57
AH
22650 /* The call to process_object() expects the file to be at the beginning. */
22651 rewind (member_filedata->handle);
22652
1cb7d8b1 22653 if (! process_object (member_filedata))
015dc7e1 22654 ret = false;
2cf0635d 22655
1cb7d8b1
AM
22656 close_file (member_filedata);
22657 free (member_file_name);
1cb7d8b1 22658 }
2cf0635d 22659 else if (is_thin_archive)
1cb7d8b1
AM
22660 {
22661 Filedata thin_filedata;
eb02c04d 22662
1cb7d8b1 22663 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22664
a043396b
NC
22665 /* PR 15140: Allow for corrupt thin archives. */
22666 if (nested_arch.file == NULL)
22667 {
22668 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22669 qualified_name, name);
fd486f32
AM
22670 free (qualified_name);
22671 free (name);
015dc7e1 22672 ret = false;
a043396b
NC
22673 break;
22674 }
fd486f32 22675 free (name);
a043396b 22676
1cb7d8b1 22677 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22678 filedata->archive_file_offset
22679 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22680
1cb7d8b1
AM
22681 /* The nested archive file will have been opened and setup by
22682 get_archive_member_name. */
978c4450
AM
22683 if (fseek (nested_arch.file, filedata->archive_file_offset,
22684 SEEK_SET) != 0)
1cb7d8b1
AM
22685 {
22686 error (_("%s: failed to seek to archive member.\n"),
22687 nested_arch.file_name);
fd486f32 22688 free (qualified_name);
015dc7e1 22689 ret = false;
1cb7d8b1
AM
22690 break;
22691 }
2cf0635d 22692
dda8d76d
NC
22693 thin_filedata.handle = nested_arch.file;
22694 thin_filedata.file_name = qualified_name;
9abca702 22695
1cb7d8b1 22696 if (! process_object (& thin_filedata))
015dc7e1 22697 ret = false;
1cb7d8b1 22698 }
2cf0635d 22699 else
1cb7d8b1 22700 {
fd486f32 22701 free (name);
978c4450 22702 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22703 filedata->file_name = qualified_name;
1cb7d8b1 22704 if (! process_object (filedata))
015dc7e1 22705 ret = false;
237877b8 22706 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22707 /* Stop looping with "negative" archive_file_size. */
978c4450 22708 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22709 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22710 }
fb52b2f4 22711
2cf0635d 22712 free (qualified_name);
fb52b2f4
NC
22713 }
22714
4145f1d5 22715 out:
2cf0635d
NC
22716 if (nested_arch.file != NULL)
22717 fclose (nested_arch.file);
22718 release_archive (&nested_arch);
22719 release_archive (&arch);
fb52b2f4 22720
d989285c 22721 return ret;
fb52b2f4
NC
22722}
22723
015dc7e1 22724static bool
2cf0635d 22725process_file (char * file_name)
fb52b2f4 22726{
dda8d76d 22727 Filedata * filedata = NULL;
fb52b2f4
NC
22728 struct stat statbuf;
22729 char armag[SARMAG];
015dc7e1 22730 bool ret = true;
fb52b2f4
NC
22731
22732 if (stat (file_name, &statbuf) < 0)
22733 {
f24ddbdd
NC
22734 if (errno == ENOENT)
22735 error (_("'%s': No such file\n"), file_name);
22736 else
22737 error (_("Could not locate '%s'. System error message: %s\n"),
22738 file_name, strerror (errno));
015dc7e1 22739 return false;
f24ddbdd
NC
22740 }
22741
22742 if (! S_ISREG (statbuf.st_mode))
22743 {
22744 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22745 return false;
fb52b2f4
NC
22746 }
22747
dda8d76d
NC
22748 filedata = calloc (1, sizeof * filedata);
22749 if (filedata == NULL)
22750 {
22751 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22752 return false;
dda8d76d
NC
22753 }
22754
22755 filedata->file_name = file_name;
22756 filedata->handle = fopen (file_name, "rb");
22757 if (filedata->handle == NULL)
fb52b2f4 22758 {
f24ddbdd 22759 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22760 free (filedata);
015dc7e1 22761 return false;
fb52b2f4
NC
22762 }
22763
dda8d76d 22764 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22765 {
4145f1d5 22766 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22767 fclose (filedata->handle);
22768 free (filedata);
015dc7e1 22769 return false;
fb52b2f4
NC
22770 }
22771
dda8d76d 22772 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22773 filedata->is_separate = false;
f54498b4 22774
fb52b2f4 22775 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22776 {
015dc7e1
AM
22777 if (! process_archive (filedata, false))
22778 ret = false;
32ec8896 22779 }
2cf0635d 22780 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22781 {
015dc7e1
AM
22782 if ( ! process_archive (filedata, true))
22783 ret = false;
32ec8896 22784 }
fb52b2f4
NC
22785 else
22786 {
1b513401 22787 if (do_archive_index && !check_all)
4145f1d5
NC
22788 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22789 file_name);
22790
dda8d76d 22791 rewind (filedata->handle);
978c4450 22792 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22793
dda8d76d 22794 if (! process_object (filedata))
015dc7e1 22795 ret = false;
fb52b2f4
NC
22796 }
22797
dda8d76d 22798 fclose (filedata->handle);
8fb879cd
AM
22799 free (filedata->section_headers);
22800 free (filedata->program_headers);
22801 free (filedata->string_table);
6431e409 22802 free (filedata->dump.dump_sects);
dda8d76d 22803 free (filedata);
32ec8896 22804
fd486f32 22805 free (ba_cache.strtab);
1bd6175a 22806 ba_cache.strtab = NULL;
fd486f32 22807 free (ba_cache.symtab);
1bd6175a 22808 ba_cache.symtab = NULL;
fd486f32
AM
22809 ba_cache.filedata = NULL;
22810
fb52b2f4
NC
22811 return ret;
22812}
22813
252b5132
RH
22814#ifdef SUPPORT_DISASSEMBLY
22815/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22816 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22817 symbols. */
252b5132
RH
22818
22819void
2cf0635d 22820print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22821{
22822 fprintf (outfile,"0x%8.8x", addr);
22823}
22824
e3c8793a 22825/* Needed by the i386 disassembler. */
dda8d76d 22826
252b5132
RH
22827void
22828db_task_printsym (unsigned int addr)
22829{
22830 print_address (addr, stderr);
22831}
22832#endif
22833
22834int
2cf0635d 22835main (int argc, char ** argv)
252b5132 22836{
ff78d6d6
L
22837 int err;
22838
87b9f255 22839#ifdef HAVE_LC_MESSAGES
252b5132 22840 setlocale (LC_MESSAGES, "");
3882b010 22841#endif
3882b010 22842 setlocale (LC_CTYPE, "");
252b5132
RH
22843 bindtextdomain (PACKAGE, LOCALEDIR);
22844 textdomain (PACKAGE);
22845
869b9d07
MM
22846 expandargv (&argc, &argv);
22847
dda8d76d 22848 parse_args (& cmdline, argc, argv);
59f14fc0 22849
18bd398b 22850 if (optind < (argc - 1))
1b513401
NC
22851 /* When displaying information for more than one file,
22852 prefix the information with the file name. */
015dc7e1 22853 show_name = true;
5656ba2c
L
22854 else if (optind >= argc)
22855 {
1b513401 22856 /* Ensure that the warning is always displayed. */
015dc7e1 22857 do_checks = true;
1b513401 22858
5656ba2c
L
22859 warn (_("Nothing to do.\n"));
22860 usage (stderr);
22861 }
18bd398b 22862
015dc7e1 22863 err = false;
252b5132 22864 while (optind < argc)
32ec8896 22865 if (! process_file (argv[optind++]))
015dc7e1 22866 err = true;
252b5132 22867
9db70fc3 22868 free (cmdline.dump_sects);
252b5132 22869
7d9813f1
NA
22870 free (dump_ctf_symtab_name);
22871 free (dump_ctf_strtab_name);
22872 free (dump_ctf_parent_name);
22873
32ec8896 22874 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22875}