]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
binutils/readelf: decode AMDGPU-specific e_flags
[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
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
0d646226 60#include "demanguse.h"
19e6b90e 61#include "dwarf.h"
7d9813f1 62#include "ctf-api.h"
79bc120c 63#include "demangle.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
a06ea964 93#include "elf/aarch64.h"
252b5132 94#include "elf/alpha.h"
c077c580 95#include "elf/amdgpu.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
e9a0721f 167#include "elf/loongarch.h"
252b5132 168
252b5132 169#include "getopt.h"
566b0d53 170#include "libiberty.h"
09c11c86 171#include "safe-ctype.h"
2cf0635d 172#include "filenames.h"
252b5132 173
15b42fb0
AM
174#ifndef offsetof
175#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
176#endif
177
6a40cf0c
NC
178typedef struct elf_section_list
179{
dda8d76d
NC
180 Elf_Internal_Shdr * hdr;
181 struct elf_section_list * next;
6a40cf0c
NC
182} elf_section_list;
183
dda8d76d
NC
184/* Flag bits indicating particular types of dump. */
185#define HEX_DUMP (1 << 0) /* The -x command line switch. */
186#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
187#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
188#define STRING_DUMP (1 << 3) /* The -p command line switch. */
189#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 190#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
191
192typedef unsigned char dump_type;
193
194/* A linked list of the section names for which dumps were requested. */
195struct dump_list_entry
196{
197 char * name;
198 dump_type type;
199 struct dump_list_entry * next;
200};
201
6431e409
AM
202/* A dynamic array of flags indicating for which sections a dump
203 has been requested via command line switches. */
1b513401
NC
204struct dump_data
205{
6431e409
AM
206 dump_type * dump_sects;
207 unsigned int num_dump_sects;
208};
209
210static struct dump_data cmdline;
211
212static struct dump_list_entry * dump_sects_byname;
213
2cf0635d 214char * program_name = "readelf";
dda8d76d 215
015dc7e1
AM
216static bool show_name = false;
217static bool do_dynamic = false;
218static bool do_syms = false;
219static bool do_dyn_syms = false;
220static bool do_lto_syms = false;
221static bool do_reloc = false;
222static bool do_sections = false;
223static bool do_section_groups = false;
224static bool do_section_details = false;
225static bool do_segments = false;
226static bool do_unwind = false;
227static bool do_using_dynamic = false;
228static bool do_header = false;
229static bool do_dump = false;
230static bool do_version = false;
231static bool do_histogram = false;
232static bool do_debugging = false;
233static bool do_ctf = false;
234static bool do_arch = false;
235static bool do_notes = false;
236static bool do_archive_index = false;
237static bool check_all = false;
238static bool is_32bit_elf = false;
239static bool decompress_dumps = false;
240static bool do_not_show_symbol_truncation = false;
241static bool do_demangle = false; /* Pretty print C++ symbol names. */
242static bool process_links = false;
e1dbfc17 243static bool dump_any_debugging = false;
79bc120c 244static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 245static int sym_base = 0;
252b5132 246
7d9813f1
NA
247static char *dump_ctf_parent_name;
248static char *dump_ctf_symtab_name;
249static char *dump_ctf_strtab_name;
250
e4b17d5c
L
251struct group_list
252{
dda8d76d
NC
253 struct group_list * next;
254 unsigned int section_index;
e4b17d5c
L
255};
256
257struct group
258{
dda8d76d
NC
259 struct group_list * root;
260 unsigned int group_index;
e4b17d5c
L
261};
262
978c4450
AM
263typedef struct filedata
264{
265 const char * file_name;
015dc7e1 266 bool is_separate;
978c4450
AM
267 FILE * handle;
268 bfd_size_type file_size;
269 Elf_Internal_Ehdr file_header;
066f8fbe
AM
270 unsigned long archive_file_offset;
271 unsigned long archive_file_size;
272 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
273 Elf_Internal_Shdr * section_headers;
274 Elf_Internal_Phdr * program_headers;
275 char * string_table;
276 unsigned long string_table_length;
978c4450
AM
277 unsigned long dynamic_addr;
278 bfd_size_type dynamic_size;
279 size_t dynamic_nent;
280 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 281 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
282 char * dynamic_strings;
283 unsigned long dynamic_strings_length;
8ac10c5b 284 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
285 unsigned long num_dynamic_syms;
286 Elf_Internal_Sym * dynamic_symbols;
287 bfd_vma version_info[16];
288 unsigned int dynamic_syminfo_nent;
289 Elf_Internal_Syminfo * dynamic_syminfo;
290 unsigned long dynamic_syminfo_offset;
291 bfd_size_type nbuckets;
292 bfd_size_type nchains;
293 bfd_vma * buckets;
294 bfd_vma * chains;
295 bfd_size_type ngnubuckets;
296 bfd_size_type ngnuchains;
297 bfd_vma * gnubuckets;
298 bfd_vma * gnuchains;
299 bfd_vma * mipsxlat;
300 bfd_vma gnusymidx;
13acb58d 301 char * program_interpreter;
978c4450
AM
302 bfd_vma dynamic_info[DT_ENCODING];
303 bfd_vma dynamic_info_DT_GNU_HASH;
304 bfd_vma dynamic_info_DT_MIPS_XHASH;
305 elf_section_list * symtab_shndx_list;
306 size_t group_count;
307 struct group * section_groups;
308 struct group ** section_headers_groups;
309 /* A dynamic array of flags indicating for which sections a dump of
310 some kind has been requested. It is reset on a per-object file
311 basis and then initialised from the cmdline_dump_sects array,
312 the results of interpreting the -w switch, and the
313 dump_sects_byname list. */
314 struct dump_data dump;
315} Filedata;
aef1f6d0 316
c256ffe7 317/* How to print a vma value. */
843dd992
NC
318typedef enum print_mode
319{
320 HEX,
047c3dbf 321 HEX_5,
843dd992
NC
322 DEC,
323 DEC_5,
324 UNSIGNED,
047c3dbf 325 UNSIGNED_5,
843dd992 326 PREFIX_HEX,
047c3dbf 327 PREFIX_HEX_5,
843dd992 328 FULL_HEX,
047c3dbf
NL
329 LONG_HEX,
330 OCTAL,
331 OCTAL_5
843dd992
NC
332}
333print_mode;
334
b3aa80b4
NC
335typedef enum unicode_display_type
336{
337 unicode_default = 0,
338 unicode_locale,
339 unicode_escape,
340 unicode_hex,
341 unicode_highlight,
342 unicode_invalid
343} unicode_display_type;
344
345static unicode_display_type unicode_display = unicode_default;
346
a7fd1186
FS
347typedef enum
348{
349 reltype_unknown,
350 reltype_rel,
351 reltype_rela,
352 reltype_relr
353} relocation_type;
354
bb4d2ac2
L
355/* Versioned symbol info. */
356enum versioned_symbol_info
357{
358 symbol_undefined,
359 symbol_hidden,
360 symbol_public
361};
362
32ec8896 363static const char * get_symbol_version_string
015dc7e1 364 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 365 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 366
9c19a809
NC
367#define UNKNOWN -1
368
84714f86
AM
369static inline const char *
370section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
371{
372 return filedata->string_table + hdr->sh_name;
373}
b9e920ec 374
84714f86
AM
375static inline bool
376section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
377{
378 return (hdr != NULL
379 && filedata->string_table != NULL
380 && hdr->sh_name < filedata->string_table_length);
381}
b9e920ec 382
84714f86
AM
383static inline const char *
384section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
385{
386 if (hdr == NULL)
387 return _("<none>");
388 if (filedata->string_table == NULL)
389 return _("<no-strings>");
390 if (hdr->sh_name >= filedata->string_table_length)
391 return _("<corrupt>");
392 return section_name (filedata, hdr);
393}
252b5132 394
ee42cf8c 395#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 396
84714f86
AM
397static inline bool
398valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
399{
400 return strtab != NULL && offset < strtab_size;
401}
402
403static inline bool
404valid_dynamic_name (const Filedata *filedata, uint64_t offset)
405{
406 return valid_symbol_name (filedata->dynamic_strings,
407 filedata->dynamic_strings_length, offset);
408}
409
d79b3d50
NC
410/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
411 already been called and verified that the string exists. */
84714f86
AM
412static inline const char *
413get_dynamic_name (const Filedata *filedata, size_t offset)
414{
415 return filedata->dynamic_strings + offset;
416}
18bd398b 417
61865e30
NC
418#define REMOVE_ARCH_BITS(ADDR) \
419 do \
420 { \
dda8d76d 421 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
422 (ADDR) &= ~1; \
423 } \
424 while (0)
f16a9783
MS
425
426/* Get the correct GNU hash section name. */
978c4450
AM
427#define GNU_HASH_SECTION_NAME(filedata) \
428 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 429\f
66cfc0fd
AM
430/* Print a BFD_VMA to an internal buffer, for use in error messages.
431 BFD_FMA_FMT can't be used in translated strings. */
432
433static const char *
434bfd_vmatoa (char *fmtch, bfd_vma value)
435{
436 /* bfd_vmatoa is used more then once in a printf call for output.
437 Cycle through an array of buffers. */
438 static int buf_pos = 0;
439 static struct bfd_vmatoa_buf
440 {
441 char place[64];
442 } buf[4];
443 char *ret;
444 char fmt[32];
445
446 ret = buf[buf_pos++].place;
447 buf_pos %= ARRAY_SIZE (buf);
448
449 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
450 snprintf (ret, sizeof (buf[0].place), fmt, value);
451 return ret;
452}
453
dda8d76d
NC
454/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
455 OFFSET + the offset of the current archive member, if we are examining an
456 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
457 allocate a buffer using malloc and fill that. In either case return the
458 pointer to the start of the retrieved data or NULL if something went wrong.
459 If something does go wrong and REASON is not NULL then emit an error
460 message using REASON as part of the context. */
59245841 461
c256ffe7 462static void *
dda8d76d
NC
463get_data (void * var,
464 Filedata * filedata,
465 unsigned long offset,
466 bfd_size_type size,
467 bfd_size_type nmemb,
468 const char * reason)
a6e9f9df 469{
2cf0635d 470 void * mvar;
57028622 471 bfd_size_type amt = size * nmemb;
a6e9f9df 472
c256ffe7 473 if (size == 0 || nmemb == 0)
a6e9f9df
AM
474 return NULL;
475
57028622
NC
476 /* If the size_t type is smaller than the bfd_size_type, eg because
477 you are building a 32-bit tool on a 64-bit host, then make sure
478 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
479 if ((size_t) size != size
480 || (size_t) nmemb != nmemb
481 || (size_t) amt != amt)
57028622
NC
482 {
483 if (reason)
66cfc0fd
AM
484 error (_("Size truncation prevents reading %s"
485 " elements of size %s for %s\n"),
486 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
487 return NULL;
488 }
489
490 /* Check for size overflow. */
7c1c1904 491 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
492 {
493 if (reason)
66cfc0fd
AM
494 error (_("Size overflow prevents reading %s"
495 " elements of size %s for %s\n"),
496 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
497 return NULL;
498 }
499
c22b42ce 500 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 501 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
502 if (filedata->archive_file_offset > filedata->file_size
503 || offset > filedata->file_size - filedata->archive_file_offset
504 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 505 {
049b0c3a 506 if (reason)
66cfc0fd
AM
507 error (_("Reading %s bytes extends past end of file for %s\n"),
508 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
509 return NULL;
510 }
511
978c4450
AM
512 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
513 SEEK_SET))
071436c6
NC
514 {
515 if (reason)
c9c1d674 516 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 517 filedata->archive_file_offset + offset, reason);
071436c6
NC
518 return NULL;
519 }
520
a6e9f9df
AM
521 mvar = var;
522 if (mvar == NULL)
523 {
7c1c1904
AM
524 /* + 1 so that we can '\0' terminate invalid string table sections. */
525 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
526
527 if (mvar == NULL)
528 {
049b0c3a 529 if (reason)
66cfc0fd
AM
530 error (_("Out of memory allocating %s bytes for %s\n"),
531 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
532 return NULL;
533 }
c256ffe7 534
c9c1d674 535 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
536 }
537
dda8d76d 538 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 539 {
049b0c3a 540 if (reason)
66cfc0fd
AM
541 error (_("Unable to read in %s bytes of %s\n"),
542 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
543 if (mvar != var)
544 free (mvar);
545 return NULL;
546 }
547
548 return mvar;
549}
550
32ec8896
NC
551/* Print a VMA value in the MODE specified.
552 Returns the number of characters displayed. */
cb8f3167 553
32ec8896 554static unsigned int
14a91970 555print_vma (bfd_vma vma, print_mode mode)
66543521 556{
32ec8896 557 unsigned int nc = 0;
66543521 558
14a91970 559 switch (mode)
66543521 560 {
14a91970
AM
561 case FULL_HEX:
562 nc = printf ("0x");
1a0670f3 563 /* Fall through. */
14a91970 564 case LONG_HEX:
f7a99963 565#ifdef BFD64
14a91970 566 if (is_32bit_elf)
437c2fb7 567 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 568#endif
14a91970
AM
569 printf_vma (vma);
570 return nc + 16;
b19aac67 571
14a91970
AM
572 case DEC_5:
573 if (vma <= 99999)
574 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 575 /* Fall through. */
14a91970
AM
576 case PREFIX_HEX:
577 nc = printf ("0x");
1a0670f3 578 /* Fall through. */
14a91970
AM
579 case HEX:
580 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 581
047c3dbf
NL
582 case PREFIX_HEX_5:
583 nc = printf ("0x");
584 /* Fall through. */
585 case HEX_5:
586 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
587
14a91970
AM
588 case DEC:
589 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 590
14a91970
AM
591 case UNSIGNED:
592 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 593
047c3dbf
NL
594 case UNSIGNED_5:
595 return printf ("%5" BFD_VMA_FMT "u", vma);
596
597 case OCTAL:
598 return printf ("%" BFD_VMA_FMT "o", vma);
599
600 case OCTAL_5:
601 return printf ("%5" BFD_VMA_FMT "o", vma);
602
32ec8896
NC
603 default:
604 /* FIXME: Report unrecognised mode ? */
605 return 0;
f7a99963 606 }
f7a99963
NC
607}
608
047c3dbf 609
7bfd842d 610/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 611 multibye characters (assuming the host environment supports them).
31104126 612
7bfd842d
NC
613 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
614
0942c7ab
NC
615 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
616 abs(WIDTH) - 5 characters followed by "[...]".
617
7bfd842d
NC
618 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
619 padding as necessary.
171191ba
NC
620
621 Returns the number of emitted characters. */
622
623static unsigned int
0942c7ab 624print_symbol (signed int width, const char * symbol)
31104126 625{
015dc7e1
AM
626 bool extra_padding = false;
627 bool do_dots = false;
32ec8896 628 signed int num_printed = 0;
3bfcb652 629#ifdef HAVE_MBSTATE_T
7bfd842d 630 mbstate_t state;
3bfcb652 631#endif
32ec8896 632 unsigned int width_remaining;
79bc120c 633 const void * alloced_symbol = NULL;
961c521f 634
7bfd842d 635 if (width < 0)
961c521f 636 {
88305e1b 637 /* Keep the width positive. This helps the code below. */
961c521f 638 width = - width;
015dc7e1 639 extra_padding = true;
0b4362b0 640 }
56d8f8a9
NC
641 else if (width == 0)
642 return 0;
961c521f 643
7bfd842d
NC
644 if (do_wide)
645 /* Set the remaining width to a very large value.
646 This simplifies the code below. */
647 width_remaining = INT_MAX;
648 else
0942c7ab
NC
649 {
650 width_remaining = width;
651 if (! do_not_show_symbol_truncation
652 && (int) strlen (symbol) > width)
653 {
654 width_remaining -= 5;
655 if ((int) width_remaining < 0)
656 width_remaining = 0;
015dc7e1 657 do_dots = true;
0942c7ab
NC
658 }
659 }
cb8f3167 660
3bfcb652 661#ifdef HAVE_MBSTATE_T
7bfd842d
NC
662 /* Initialise the multibyte conversion state. */
663 memset (& state, 0, sizeof (state));
3bfcb652 664#endif
961c521f 665
79bc120c
NC
666 if (do_demangle && *symbol)
667 {
668 const char * res = cplus_demangle (symbol, demangle_flags);
669
670 if (res != NULL)
671 alloced_symbol = symbol = res;
672 }
673
7bfd842d
NC
674 while (width_remaining)
675 {
676 size_t n;
7bfd842d 677 const char c = *symbol++;
961c521f 678
7bfd842d 679 if (c == 0)
961c521f
NC
680 break;
681
b3aa80b4
NC
682 if (ISPRINT (c))
683 {
684 putchar (c);
685 width_remaining --;
686 num_printed ++;
687 }
688 else if (ISCNTRL (c))
961c521f 689 {
b3aa80b4
NC
690 /* Do not print control characters directly as they can affect terminal
691 settings. Such characters usually appear in the names generated
692 by the assembler for local labels. */
693
7bfd842d 694 if (width_remaining < 2)
961c521f
NC
695 break;
696
7bfd842d
NC
697 printf ("^%c", c + 0x40);
698 width_remaining -= 2;
171191ba 699 num_printed += 2;
961c521f 700 }
b3aa80b4 701 else if (c == 0x7f)
7bfd842d 702 {
b3aa80b4
NC
703 if (width_remaining < 5)
704 break;
705 printf ("<DEL>");
706 width_remaining -= 5;
707 num_printed += 5;
708 }
709 else if (unicode_display != unicode_locale
710 && unicode_display != unicode_default)
711 {
712 /* Display unicode characters as something else. */
713 unsigned char bytes[4];
714 bool is_utf8;
795588ae 715 unsigned int nbytes;
b3aa80b4
NC
716
717 bytes[0] = c;
718
719 if (bytes[0] < 0xc0)
720 {
721 nbytes = 1;
722 is_utf8 = false;
723 }
724 else
725 {
726 bytes[1] = *symbol++;
727
728 if ((bytes[1] & 0xc0) != 0x80)
729 {
730 is_utf8 = false;
731 /* Do not consume this character. It may only
732 be the first byte in the sequence that was
733 corrupt. */
734 --symbol;
735 nbytes = 1;
736 }
737 else if ((bytes[0] & 0x20) == 0)
738 {
739 is_utf8 = true;
740 nbytes = 2;
741 }
742 else
743 {
744 bytes[2] = *symbol++;
745
746 if ((bytes[2] & 0xc0) != 0x80)
747 {
748 is_utf8 = false;
749 symbol -= 2;
750 nbytes = 1;
751 }
752 else if ((bytes[0] & 0x10) == 0)
753 {
754 is_utf8 = true;
755 nbytes = 3;
756 }
757 else
758 {
759 bytes[3] = *symbol++;
760
761 nbytes = 4;
762
763 if ((bytes[3] & 0xc0) != 0x80)
764 {
765 is_utf8 = false;
766 symbol -= 3;
767 nbytes = 1;
768 }
769 else
770 is_utf8 = true;
771 }
772 }
773 }
774
775 if (unicode_display == unicode_invalid)
776 is_utf8 = false;
777
778 if (unicode_display == unicode_hex || ! is_utf8)
779 {
795588ae 780 unsigned int i;
b3aa80b4
NC
781
782 if (width_remaining < (nbytes * 2) + 2)
783 break;
784
785 putchar (is_utf8 ? '<' : '{');
786 printf ("0x");
787 for (i = 0; i < nbytes; i++)
788 printf ("%02x", bytes[i]);
789 putchar (is_utf8 ? '>' : '}');
790 }
791 else
792 {
793 if (unicode_display == unicode_highlight && isatty (1))
794 printf ("\x1B[31;47m"); /* Red. */
795
796 switch (nbytes)
797 {
798 case 2:
799 if (width_remaining < 6)
800 break;
801 printf ("\\u%02x%02x",
802 (bytes[0] & 0x1c) >> 2,
803 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
804 break;
805 case 3:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
810 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
811 break;
812 case 4:
813 if (width_remaining < 8)
814 break;
815 printf ("\\u%02x%02x%02x",
816 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
818 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
819
820 break;
821 default:
822 /* URG. */
823 break;
824 }
825
826 if (unicode_display == unicode_highlight && isatty (1))
827 printf ("\033[0m"); /* Default colour. */
828 }
829
830 if (bytes[nbytes - 1] == 0)
831 break;
7bfd842d 832 }
961c521f
NC
833 else
834 {
3bfcb652
NC
835#ifdef HAVE_MBSTATE_T
836 wchar_t w;
837#endif
7bfd842d
NC
838 /* Let printf do the hard work of displaying multibyte characters. */
839 printf ("%.1s", symbol - 1);
840 width_remaining --;
841 num_printed ++;
842
3bfcb652 843#ifdef HAVE_MBSTATE_T
7bfd842d
NC
844 /* Try to find out how many bytes made up the character that was
845 just printed. Advance the symbol pointer past the bytes that
846 were displayed. */
847 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
848#else
849 n = 1;
850#endif
7bfd842d
NC
851 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
852 symbol += (n - 1);
961c521f 853 }
961c521f 854 }
171191ba 855
0942c7ab
NC
856 if (do_dots)
857 num_printed += printf ("[...]");
858
7bfd842d 859 if (extra_padding && num_printed < width)
171191ba
NC
860 {
861 /* Fill in the remaining spaces. */
7bfd842d
NC
862 printf ("%-*s", width - num_printed, " ");
863 num_printed = width;
171191ba
NC
864 }
865
79bc120c 866 free ((void *) alloced_symbol);
171191ba 867 return num_printed;
31104126
NC
868}
869
1449284b 870/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
871 the given section's name. Like print_symbol, except that it does not try
872 to print multibyte characters, it just interprets them as hex values. */
873
874static const char *
dda8d76d 875printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 876{
ca0e11aa 877#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 878 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 879 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
880 char * buf = sec_name_buf;
881 char c;
882 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
883
884 while ((c = * name ++) != 0)
885 {
886 if (ISCNTRL (c))
887 {
888 if (remaining < 2)
889 break;
948f632f 890
74e1a04b
NC
891 * buf ++ = '^';
892 * buf ++ = c + 0x40;
893 remaining -= 2;
894 }
895 else if (ISPRINT (c))
896 {
897 * buf ++ = c;
898 remaining -= 1;
899 }
900 else
901 {
902 static char hex[17] = "0123456789ABCDEF";
903
904 if (remaining < 4)
905 break;
906 * buf ++ = '<';
907 * buf ++ = hex[(c & 0xf0) >> 4];
908 * buf ++ = hex[c & 0x0f];
909 * buf ++ = '>';
910 remaining -= 4;
911 }
912
913 if (remaining == 0)
914 break;
915 }
916
917 * buf = 0;
918 return sec_name_buf;
919}
920
921static const char *
dda8d76d 922printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 923{
dda8d76d 924 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
925 return _("<corrupt>");
926
dda8d76d 927 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
928}
929
89fac5e3
RS
930/* Return a pointer to section NAME, or NULL if no such section exists. */
931
932static Elf_Internal_Shdr *
dda8d76d 933find_section (Filedata * filedata, const char * name)
89fac5e3
RS
934{
935 unsigned int i;
936
68807c3c
NC
937 if (filedata->section_headers == NULL)
938 return NULL;
dda8d76d
NC
939
940 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
941 if (section_name_valid (filedata, filedata->section_headers + i)
942 && streq (section_name (filedata, filedata->section_headers + i),
943 name))
dda8d76d 944 return filedata->section_headers + i;
89fac5e3
RS
945
946 return NULL;
947}
948
0b6ae522
DJ
949/* Return a pointer to a section containing ADDR, or NULL if no such
950 section exists. */
951
952static Elf_Internal_Shdr *
dda8d76d 953find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
954{
955 unsigned int i;
956
68807c3c
NC
957 if (filedata->section_headers == NULL)
958 return NULL;
959
dda8d76d 960 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 961 {
dda8d76d
NC
962 Elf_Internal_Shdr *sec = filedata->section_headers + i;
963
0b6ae522
DJ
964 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
965 return sec;
966 }
967
968 return NULL;
969}
970
071436c6 971static Elf_Internal_Shdr *
dda8d76d 972find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
973{
974 unsigned int i;
975
68807c3c
NC
976 if (filedata->section_headers == NULL)
977 return NULL;
978
dda8d76d 979 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 980 {
dda8d76d
NC
981 Elf_Internal_Shdr *sec = filedata->section_headers + i;
982
071436c6
NC
983 if (sec->sh_type == type)
984 return sec;
985 }
986
987 return NULL;
988}
989
657d0d47
CC
990/* Return a pointer to section NAME, or NULL if no such section exists,
991 restricted to the list of sections given in SET. */
992
993static Elf_Internal_Shdr *
dda8d76d 994find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
995{
996 unsigned int i;
997
68807c3c
NC
998 if (filedata->section_headers == NULL)
999 return NULL;
1000
657d0d47
CC
1001 if (set != NULL)
1002 {
1003 while ((i = *set++) > 0)
b814a36d
NC
1004 {
1005 /* See PR 21156 for a reproducer. */
dda8d76d 1006 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1007 continue; /* FIXME: Should we issue an error message ? */
1008
84714f86
AM
1009 if (section_name_valid (filedata, filedata->section_headers + i)
1010 && streq (section_name (filedata, filedata->section_headers + i),
1011 name))
dda8d76d 1012 return filedata->section_headers + i;
b814a36d 1013 }
657d0d47
CC
1014 }
1015
dda8d76d 1016 return find_section (filedata, name);
657d0d47
CC
1017}
1018
32ec8896 1019/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1020 This OS has so many departures from the ELF standard that we test it at
1021 many places. */
1022
015dc7e1 1023static inline bool
dda8d76d 1024is_ia64_vms (Filedata * filedata)
28f997cf 1025{
dda8d76d
NC
1026 return filedata->file_header.e_machine == EM_IA_64
1027 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1028}
1029
bcedfee6 1030/* Guess the relocation size commonly used by the specific machines. */
252b5132 1031
015dc7e1 1032static bool
2dc4cec1 1033guess_is_rela (unsigned int e_machine)
252b5132 1034{
9c19a809 1035 switch (e_machine)
252b5132
RH
1036 {
1037 /* Targets that use REL relocations. */
252b5132 1038 case EM_386:
22abe556 1039 case EM_IAMCU:
f954747f 1040 case EM_960:
e9f53129 1041 case EM_ARM:
2b0337b0 1042 case EM_D10V:
252b5132 1043 case EM_CYGNUS_D10V:
e9f53129 1044 case EM_DLX:
252b5132 1045 case EM_MIPS:
4fe85591 1046 case EM_MIPS_RS3_LE:
e9f53129 1047 case EM_CYGNUS_M32R:
1c0d3aa6 1048 case EM_SCORE:
f6c1a2d5 1049 case EM_XGATE:
fe944acf 1050 case EM_NFP:
aca4efc7 1051 case EM_BPF:
015dc7e1 1052 return false;
103f02d3 1053
252b5132
RH
1054 /* Targets that use RELA relocations. */
1055 case EM_68K:
f954747f 1056 case EM_860:
a06ea964 1057 case EM_AARCH64:
cfb8c092 1058 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1059 case EM_ALPHA:
1060 case EM_ALTERA_NIOS2:
886a2506
NC
1061 case EM_ARC:
1062 case EM_ARC_COMPACT:
1063 case EM_ARC_COMPACT2:
e9f53129
AM
1064 case EM_AVR:
1065 case EM_AVR_OLD:
1066 case EM_BLACKFIN:
60bca95a 1067 case EM_CR16:
e9f53129
AM
1068 case EM_CRIS:
1069 case EM_CRX:
b8891f8d 1070 case EM_CSKY:
2b0337b0 1071 case EM_D30V:
252b5132 1072 case EM_CYGNUS_D30V:
2b0337b0 1073 case EM_FR30:
3f8107ab 1074 case EM_FT32:
252b5132 1075 case EM_CYGNUS_FR30:
5c70f934 1076 case EM_CYGNUS_FRV:
e9f53129
AM
1077 case EM_H8S:
1078 case EM_H8_300:
1079 case EM_H8_300H:
800eeca4 1080 case EM_IA_64:
1e4cf259
NC
1081 case EM_IP2K:
1082 case EM_IP2K_OLD:
3b36097d 1083 case EM_IQ2000:
84e94c90 1084 case EM_LATTICEMICO32:
ff7eeb89 1085 case EM_M32C_OLD:
49f58d10 1086 case EM_M32C:
e9f53129
AM
1087 case EM_M32R:
1088 case EM_MCORE:
15ab5209 1089 case EM_CYGNUS_MEP:
a3c62988 1090 case EM_METAG:
e9f53129
AM
1091 case EM_MMIX:
1092 case EM_MN10200:
1093 case EM_CYGNUS_MN10200:
1094 case EM_MN10300:
1095 case EM_CYGNUS_MN10300:
5506d11a 1096 case EM_MOXIE:
e9f53129
AM
1097 case EM_MSP430:
1098 case EM_MSP430_OLD:
d031aafb 1099 case EM_MT:
35c08157 1100 case EM_NDS32:
64fd6348 1101 case EM_NIOS32:
73589c9d 1102 case EM_OR1K:
e9f53129
AM
1103 case EM_PPC64:
1104 case EM_PPC:
2b100bb5 1105 case EM_TI_PRU:
e23eba97 1106 case EM_RISCV:
99c513f6 1107 case EM_RL78:
c7927a3c 1108 case EM_RX:
e9f53129
AM
1109 case EM_S390:
1110 case EM_S390_OLD:
1111 case EM_SH:
1112 case EM_SPARC:
1113 case EM_SPARC32PLUS:
1114 case EM_SPARCV9:
1115 case EM_SPU:
40b36596 1116 case EM_TI_C6000:
aa137e4d
NC
1117 case EM_TILEGX:
1118 case EM_TILEPRO:
708e2187 1119 case EM_V800:
e9f53129
AM
1120 case EM_V850:
1121 case EM_CYGNUS_V850:
1122 case EM_VAX:
619ed720 1123 case EM_VISIUM:
e9f53129 1124 case EM_X86_64:
8a9036a4 1125 case EM_L1OM:
7a9068fe 1126 case EM_K1OM:
e9f53129
AM
1127 case EM_XSTORMY16:
1128 case EM_XTENSA:
1129 case EM_XTENSA_OLD:
7ba29e2a
NC
1130 case EM_MICROBLAZE:
1131 case EM_MICROBLAZE_OLD:
f96bd6c2 1132 case EM_WEBASSEMBLY:
015dc7e1 1133 return true;
103f02d3 1134
e9f53129
AM
1135 case EM_68HC05:
1136 case EM_68HC08:
1137 case EM_68HC11:
1138 case EM_68HC16:
1139 case EM_FX66:
1140 case EM_ME16:
d1133906 1141 case EM_MMA:
d1133906
NC
1142 case EM_NCPU:
1143 case EM_NDR1:
e9f53129 1144 case EM_PCP:
d1133906 1145 case EM_ST100:
e9f53129 1146 case EM_ST19:
d1133906 1147 case EM_ST7:
e9f53129
AM
1148 case EM_ST9PLUS:
1149 case EM_STARCORE:
d1133906 1150 case EM_SVX:
e9f53129 1151 case EM_TINYJ:
9c19a809
NC
1152 default:
1153 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1154 return false;
9c19a809
NC
1155 }
1156}
252b5132 1157
dda8d76d 1158/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1159 Returns TRUE upon success, FALSE otherwise. If successful then a
1160 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1161 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1162 responsibility to free the allocated buffer. */
1163
015dc7e1 1164static bool
dda8d76d
NC
1165slurp_rela_relocs (Filedata * filedata,
1166 unsigned long rel_offset,
1167 unsigned long rel_size,
1168 Elf_Internal_Rela ** relasp,
1169 unsigned long * nrelasp)
9c19a809 1170{
2cf0635d 1171 Elf_Internal_Rela * relas;
8b73c356 1172 size_t nrelas;
4d6ed7c8 1173 unsigned int i;
252b5132 1174
4d6ed7c8
NC
1175 if (is_32bit_elf)
1176 {
2cf0635d 1177 Elf32_External_Rela * erelas;
103f02d3 1178
dda8d76d 1179 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1180 rel_size, _("32-bit relocation data"));
a6e9f9df 1181 if (!erelas)
015dc7e1 1182 return false;
252b5132 1183
4d6ed7c8 1184 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1185
3f5e193b
NC
1186 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1187 sizeof (Elf_Internal_Rela));
103f02d3 1188
4d6ed7c8
NC
1189 if (relas == NULL)
1190 {
c256ffe7 1191 free (erelas);
591a748a 1192 error (_("out of memory parsing relocs\n"));
015dc7e1 1193 return false;
4d6ed7c8 1194 }
103f02d3 1195
4d6ed7c8
NC
1196 for (i = 0; i < nrelas; i++)
1197 {
1198 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1199 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1200 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1201 }
103f02d3 1202
4d6ed7c8
NC
1203 free (erelas);
1204 }
1205 else
1206 {
2cf0635d 1207 Elf64_External_Rela * erelas;
103f02d3 1208
dda8d76d 1209 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1210 rel_size, _("64-bit relocation data"));
a6e9f9df 1211 if (!erelas)
015dc7e1 1212 return false;
4d6ed7c8
NC
1213
1214 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1215
3f5e193b
NC
1216 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1217 sizeof (Elf_Internal_Rela));
103f02d3 1218
4d6ed7c8
NC
1219 if (relas == NULL)
1220 {
c256ffe7 1221 free (erelas);
591a748a 1222 error (_("out of memory parsing relocs\n"));
015dc7e1 1223 return false;
9c19a809 1224 }
4d6ed7c8
NC
1225
1226 for (i = 0; i < nrelas; i++)
9c19a809 1227 {
66543521
AM
1228 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1229 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1230 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1231
1232 /* The #ifdef BFD64 below is to prevent a compile time
1233 warning. We know that if we do not have a 64 bit data
1234 type that we will never execute this code anyway. */
1235#ifdef BFD64
dda8d76d
NC
1236 if (filedata->file_header.e_machine == EM_MIPS
1237 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1238 {
1239 /* In little-endian objects, r_info isn't really a
1240 64-bit little-endian value: it has a 32-bit
1241 little-endian symbol index followed by four
1242 individual byte fields. Reorder INFO
1243 accordingly. */
91d6fa6a
NC
1244 bfd_vma inf = relas[i].r_info;
1245 inf = (((inf & 0xffffffff) << 32)
1246 | ((inf >> 56) & 0xff)
1247 | ((inf >> 40) & 0xff00)
1248 | ((inf >> 24) & 0xff0000)
1249 | ((inf >> 8) & 0xff000000));
1250 relas[i].r_info = inf;
861fb55a
DJ
1251 }
1252#endif /* BFD64 */
4d6ed7c8 1253 }
103f02d3 1254
4d6ed7c8
NC
1255 free (erelas);
1256 }
32ec8896 1257
4d6ed7c8
NC
1258 *relasp = relas;
1259 *nrelasp = nrelas;
015dc7e1 1260 return true;
4d6ed7c8 1261}
103f02d3 1262
dda8d76d 1263/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1264 Returns TRUE upon success, FALSE otherwise. If successful then a
1265 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1266 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1267 responsibility to free the allocated buffer. */
1268
015dc7e1 1269static bool
dda8d76d
NC
1270slurp_rel_relocs (Filedata * filedata,
1271 unsigned long rel_offset,
1272 unsigned long rel_size,
1273 Elf_Internal_Rela ** relsp,
1274 unsigned long * nrelsp)
4d6ed7c8 1275{
2cf0635d 1276 Elf_Internal_Rela * rels;
8b73c356 1277 size_t nrels;
4d6ed7c8 1278 unsigned int i;
103f02d3 1279
4d6ed7c8
NC
1280 if (is_32bit_elf)
1281 {
2cf0635d 1282 Elf32_External_Rel * erels;
103f02d3 1283
dda8d76d 1284 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1285 rel_size, _("32-bit relocation data"));
a6e9f9df 1286 if (!erels)
015dc7e1 1287 return false;
103f02d3 1288
4d6ed7c8 1289 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1290
3f5e193b 1291 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1292
4d6ed7c8
NC
1293 if (rels == NULL)
1294 {
c256ffe7 1295 free (erels);
591a748a 1296 error (_("out of memory parsing relocs\n"));
015dc7e1 1297 return false;
4d6ed7c8
NC
1298 }
1299
1300 for (i = 0; i < nrels; i++)
1301 {
1302 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1303 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1304 rels[i].r_addend = 0;
9ea033b2 1305 }
4d6ed7c8
NC
1306
1307 free (erels);
9c19a809
NC
1308 }
1309 else
1310 {
2cf0635d 1311 Elf64_External_Rel * erels;
9ea033b2 1312
dda8d76d 1313 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1314 rel_size, _("64-bit relocation data"));
a6e9f9df 1315 if (!erels)
015dc7e1 1316 return false;
103f02d3 1317
4d6ed7c8 1318 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1319
3f5e193b 1320 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1321
4d6ed7c8 1322 if (rels == NULL)
9c19a809 1323 {
c256ffe7 1324 free (erels);
591a748a 1325 error (_("out of memory parsing relocs\n"));
015dc7e1 1326 return false;
4d6ed7c8 1327 }
103f02d3 1328
4d6ed7c8
NC
1329 for (i = 0; i < nrels; i++)
1330 {
66543521
AM
1331 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1332 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1333 rels[i].r_addend = 0;
861fb55a
DJ
1334
1335 /* The #ifdef BFD64 below is to prevent a compile time
1336 warning. We know that if we do not have a 64 bit data
1337 type that we will never execute this code anyway. */
1338#ifdef BFD64
dda8d76d
NC
1339 if (filedata->file_header.e_machine == EM_MIPS
1340 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1341 {
1342 /* In little-endian objects, r_info isn't really a
1343 64-bit little-endian value: it has a 32-bit
1344 little-endian symbol index followed by four
1345 individual byte fields. Reorder INFO
1346 accordingly. */
91d6fa6a
NC
1347 bfd_vma inf = rels[i].r_info;
1348 inf = (((inf & 0xffffffff) << 32)
1349 | ((inf >> 56) & 0xff)
1350 | ((inf >> 40) & 0xff00)
1351 | ((inf >> 24) & 0xff0000)
1352 | ((inf >> 8) & 0xff000000));
1353 rels[i].r_info = inf;
861fb55a
DJ
1354 }
1355#endif /* BFD64 */
4d6ed7c8 1356 }
103f02d3 1357
4d6ed7c8
NC
1358 free (erels);
1359 }
32ec8896 1360
4d6ed7c8
NC
1361 *relsp = rels;
1362 *nrelsp = nrels;
015dc7e1 1363 return true;
4d6ed7c8 1364}
103f02d3 1365
a7fd1186
FS
1366static bool
1367slurp_relr_relocs (Filedata * filedata,
1368 unsigned long relr_offset,
1369 unsigned long relr_size,
1370 bfd_vma ** relrsp,
1371 unsigned long * nrelrsp)
1372{
1373 void *relrs;
1374 size_t size = 0, nentries, i;
1375 bfd_vma base = 0, addr, entry;
1376
1377 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1378 _("RELR relocation data"));
1379 if (!relrs)
1380 return false;
1381
1382 if (is_32bit_elf)
1383 nentries = relr_size / sizeof (Elf32_External_Relr);
1384 else
1385 nentries = relr_size / sizeof (Elf64_External_Relr);
1386 for (i = 0; i < nentries; i++)
1387 {
1388 if (is_32bit_elf)
1389 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1390 else
1391 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1392 if ((entry & 1) == 0)
1393 size++;
1394 else
1395 while ((entry >>= 1) != 0)
1396 if ((entry & 1) == 1)
1397 size++;
1398 }
1399
1400 *relrsp = (bfd_vma *) xmalloc (size * sizeof (bfd_vma));
1401 if (*relrsp == NULL)
1402 {
1403 free (relrs);
1404 error (_("out of memory parsing relocs\n"));
1405 return false;
1406 }
1407
1408 size = 0;
1409 for (i = 0; i < nentries; i++)
1410 {
1411 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1412
1413 if (is_32bit_elf)
1414 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1415 else
1416 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1417 if ((entry & 1) == 0)
1418 {
1419 (*relrsp)[size++] = entry;
1420 base = entry + entry_bytes;
1421 }
1422 else
1423 {
1424 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1425 if ((entry & 1) != 0)
1426 (*relrsp)[size++] = addr;
1427 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1428 }
1429 }
1430
1431 *nrelrsp = size;
1432 free (relrs);
1433 return true;
1434}
1435
aca88567
NC
1436/* Returns the reloc type extracted from the reloc info field. */
1437
1438static unsigned int
dda8d76d 1439get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1440{
1441 if (is_32bit_elf)
1442 return ELF32_R_TYPE (reloc_info);
1443
dda8d76d 1444 switch (filedata->file_header.e_machine)
aca88567
NC
1445 {
1446 case EM_MIPS:
1447 /* Note: We assume that reloc_info has already been adjusted for us. */
1448 return ELF64_MIPS_R_TYPE (reloc_info);
1449
1450 case EM_SPARCV9:
1451 return ELF64_R_TYPE_ID (reloc_info);
1452
1453 default:
1454 return ELF64_R_TYPE (reloc_info);
1455 }
1456}
1457
1458/* Return the symbol index extracted from the reloc info field. */
1459
1460static bfd_vma
1461get_reloc_symindex (bfd_vma reloc_info)
1462{
1463 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1464}
1465
015dc7e1 1466static inline bool
dda8d76d 1467uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1468{
1469 return
dda8d76d 1470 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1471 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1472 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1473 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1474 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1475}
1476
d3ba0551
AM
1477/* Display the contents of the relocation data found at the specified
1478 offset. */
ee42cf8c 1479
015dc7e1 1480static bool
dda8d76d
NC
1481dump_relocations (Filedata * filedata,
1482 unsigned long rel_offset,
1483 unsigned long rel_size,
1484 Elf_Internal_Sym * symtab,
1485 unsigned long nsyms,
1486 char * strtab,
1487 unsigned long strtablen,
a7fd1186 1488 relocation_type rel_type,
015dc7e1 1489 bool is_dynsym)
4d6ed7c8 1490{
32ec8896 1491 unsigned long i;
2cf0635d 1492 Elf_Internal_Rela * rels;
015dc7e1 1493 bool res = true;
103f02d3 1494
a7fd1186
FS
1495 if (rel_type == reltype_unknown)
1496 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1497
a7fd1186 1498 if (rel_type == reltype_rela)
4d6ed7c8 1499 {
dda8d76d 1500 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1501 return false;
4d6ed7c8 1502 }
a7fd1186 1503 else if (rel_type == reltype_rel)
4d6ed7c8 1504 {
dda8d76d 1505 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1506 return false;
252b5132 1507 }
a7fd1186
FS
1508 else if (rel_type == reltype_relr)
1509 {
1510 bfd_vma * relrs;
1511 const char *format
1512 = is_32bit_elf ? "%08" BFD_VMA_FMT "x\n" : "%016" BFD_VMA_FMT "x\n";
1513
1514 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1515 &rel_size))
1516 return false;
1517
1518 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size), rel_size);
1519 for (i = 0; i < rel_size; i++)
1520 printf (format, relrs[i]);
1521 free (relrs);
1522 return true;
1523 }
252b5132 1524
410f7a12
L
1525 if (is_32bit_elf)
1526 {
a7fd1186 1527 if (rel_type == reltype_rela)
2c71103e
NC
1528 {
1529 if (do_wide)
1530 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1531 else
1532 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1533 }
410f7a12 1534 else
2c71103e
NC
1535 {
1536 if (do_wide)
1537 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1538 else
1539 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1540 }
410f7a12 1541 }
252b5132 1542 else
410f7a12 1543 {
a7fd1186 1544 if (rel_type == reltype_rela)
2c71103e
NC
1545 {
1546 if (do_wide)
8beeaeb7 1547 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1548 else
1549 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1550 }
410f7a12 1551 else
2c71103e
NC
1552 {
1553 if (do_wide)
8beeaeb7 1554 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1555 else
1556 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1557 }
410f7a12 1558 }
252b5132
RH
1559
1560 for (i = 0; i < rel_size; i++)
1561 {
2cf0635d 1562 const char * rtype;
b34976b6 1563 bfd_vma offset;
91d6fa6a 1564 bfd_vma inf;
b34976b6
AM
1565 bfd_vma symtab_index;
1566 bfd_vma type;
103f02d3 1567
b34976b6 1568 offset = rels[i].r_offset;
91d6fa6a 1569 inf = rels[i].r_info;
103f02d3 1570
dda8d76d 1571 type = get_reloc_type (filedata, inf);
91d6fa6a 1572 symtab_index = get_reloc_symindex (inf);
252b5132 1573
410f7a12
L
1574 if (is_32bit_elf)
1575 {
39dbeff8
AM
1576 printf ("%8.8lx %8.8lx ",
1577 (unsigned long) offset & 0xffffffff,
91d6fa6a 1578 (unsigned long) inf & 0xffffffff);
410f7a12
L
1579 }
1580 else
1581 {
39dbeff8 1582 printf (do_wide
d1ce973e
AM
1583 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1584 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1585 offset, inf);
410f7a12 1586 }
103f02d3 1587
dda8d76d 1588 switch (filedata->file_header.e_machine)
252b5132
RH
1589 {
1590 default:
1591 rtype = NULL;
1592 break;
1593
a06ea964
NC
1594 case EM_AARCH64:
1595 rtype = elf_aarch64_reloc_type (type);
1596 break;
1597
2b0337b0 1598 case EM_M32R:
252b5132 1599 case EM_CYGNUS_M32R:
9ea033b2 1600 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1601 break;
1602
1603 case EM_386:
22abe556 1604 case EM_IAMCU:
9ea033b2 1605 rtype = elf_i386_reloc_type (type);
252b5132
RH
1606 break;
1607
ba2685cc
AM
1608 case EM_68HC11:
1609 case EM_68HC12:
1610 rtype = elf_m68hc11_reloc_type (type);
1611 break;
75751cd9 1612
7b4ae824
JD
1613 case EM_S12Z:
1614 rtype = elf_s12z_reloc_type (type);
1615 break;
1616
252b5132 1617 case EM_68K:
9ea033b2 1618 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1619 break;
1620
f954747f
AM
1621 case EM_960:
1622 rtype = elf_i960_reloc_type (type);
1623 break;
1624
adde6300 1625 case EM_AVR:
2b0337b0 1626 case EM_AVR_OLD:
adde6300
AM
1627 rtype = elf_avr_reloc_type (type);
1628 break;
1629
9ea033b2
NC
1630 case EM_OLD_SPARCV9:
1631 case EM_SPARC32PLUS:
1632 case EM_SPARCV9:
252b5132 1633 case EM_SPARC:
9ea033b2 1634 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1635 break;
1636
e9f53129
AM
1637 case EM_SPU:
1638 rtype = elf_spu_reloc_type (type);
1639 break;
1640
708e2187
NC
1641 case EM_V800:
1642 rtype = v800_reloc_type (type);
1643 break;
2b0337b0 1644 case EM_V850:
252b5132 1645 case EM_CYGNUS_V850:
9ea033b2 1646 rtype = v850_reloc_type (type);
252b5132
RH
1647 break;
1648
2b0337b0 1649 case EM_D10V:
252b5132 1650 case EM_CYGNUS_D10V:
9ea033b2 1651 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1652 break;
1653
2b0337b0 1654 case EM_D30V:
252b5132 1655 case EM_CYGNUS_D30V:
9ea033b2 1656 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1657 break;
1658
d172d4ba
NC
1659 case EM_DLX:
1660 rtype = elf_dlx_reloc_type (type);
1661 break;
1662
252b5132 1663 case EM_SH:
9ea033b2 1664 rtype = elf_sh_reloc_type (type);
252b5132
RH
1665 break;
1666
2b0337b0 1667 case EM_MN10300:
252b5132 1668 case EM_CYGNUS_MN10300:
9ea033b2 1669 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1670 break;
1671
2b0337b0 1672 case EM_MN10200:
252b5132 1673 case EM_CYGNUS_MN10200:
9ea033b2 1674 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1675 break;
1676
2b0337b0 1677 case EM_FR30:
252b5132 1678 case EM_CYGNUS_FR30:
9ea033b2 1679 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1680 break;
1681
ba2685cc
AM
1682 case EM_CYGNUS_FRV:
1683 rtype = elf_frv_reloc_type (type);
1684 break;
5c70f934 1685
b8891f8d
AJ
1686 case EM_CSKY:
1687 rtype = elf_csky_reloc_type (type);
1688 break;
1689
3f8107ab
AM
1690 case EM_FT32:
1691 rtype = elf_ft32_reloc_type (type);
1692 break;
1693
252b5132 1694 case EM_MCORE:
9ea033b2 1695 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1696 break;
1697
3c3bdf30
NC
1698 case EM_MMIX:
1699 rtype = elf_mmix_reloc_type (type);
1700 break;
1701
5506d11a
AM
1702 case EM_MOXIE:
1703 rtype = elf_moxie_reloc_type (type);
1704 break;
1705
2469cfa2 1706 case EM_MSP430:
dda8d76d 1707 if (uses_msp430x_relocs (filedata))
13761a11
NC
1708 {
1709 rtype = elf_msp430x_reloc_type (type);
1710 break;
1711 }
1a0670f3 1712 /* Fall through. */
2469cfa2
NC
1713 case EM_MSP430_OLD:
1714 rtype = elf_msp430_reloc_type (type);
1715 break;
1716
35c08157
KLC
1717 case EM_NDS32:
1718 rtype = elf_nds32_reloc_type (type);
1719 break;
1720
252b5132 1721 case EM_PPC:
9ea033b2 1722 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1723 break;
1724
c833c019
AM
1725 case EM_PPC64:
1726 rtype = elf_ppc64_reloc_type (type);
1727 break;
1728
252b5132 1729 case EM_MIPS:
4fe85591 1730 case EM_MIPS_RS3_LE:
9ea033b2 1731 rtype = elf_mips_reloc_type (type);
252b5132
RH
1732 break;
1733
e23eba97
NC
1734 case EM_RISCV:
1735 rtype = elf_riscv_reloc_type (type);
1736 break;
1737
252b5132 1738 case EM_ALPHA:
9ea033b2 1739 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1740 break;
1741
1742 case EM_ARM:
9ea033b2 1743 rtype = elf_arm_reloc_type (type);
252b5132
RH
1744 break;
1745
584da044 1746 case EM_ARC:
886a2506
NC
1747 case EM_ARC_COMPACT:
1748 case EM_ARC_COMPACT2:
9ea033b2 1749 rtype = elf_arc_reloc_type (type);
252b5132
RH
1750 break;
1751
1752 case EM_PARISC:
69e617ca 1753 rtype = elf_hppa_reloc_type (type);
252b5132 1754 break;
7d466069 1755
b8720f9d
JL
1756 case EM_H8_300:
1757 case EM_H8_300H:
1758 case EM_H8S:
1759 rtype = elf_h8_reloc_type (type);
1760 break;
1761
73589c9d
CS
1762 case EM_OR1K:
1763 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1764 break;
1765
7d466069 1766 case EM_PJ:
2b0337b0 1767 case EM_PJ_OLD:
7d466069
ILT
1768 rtype = elf_pj_reloc_type (type);
1769 break;
800eeca4
JW
1770 case EM_IA_64:
1771 rtype = elf_ia64_reloc_type (type);
1772 break;
1b61cf92
HPN
1773
1774 case EM_CRIS:
1775 rtype = elf_cris_reloc_type (type);
1776 break;
535c37ff 1777
f954747f
AM
1778 case EM_860:
1779 rtype = elf_i860_reloc_type (type);
1780 break;
1781
bcedfee6 1782 case EM_X86_64:
8a9036a4 1783 case EM_L1OM:
7a9068fe 1784 case EM_K1OM:
bcedfee6
NC
1785 rtype = elf_x86_64_reloc_type (type);
1786 break;
a85d7ed0 1787
f954747f
AM
1788 case EM_S370:
1789 rtype = i370_reloc_type (type);
1790 break;
1791
53c7db4b
KH
1792 case EM_S390_OLD:
1793 case EM_S390:
1794 rtype = elf_s390_reloc_type (type);
1795 break;
93fbbb04 1796
1c0d3aa6
NC
1797 case EM_SCORE:
1798 rtype = elf_score_reloc_type (type);
1799 break;
1800
93fbbb04
GK
1801 case EM_XSTORMY16:
1802 rtype = elf_xstormy16_reloc_type (type);
1803 break;
179d3252 1804
1fe1f39c
NC
1805 case EM_CRX:
1806 rtype = elf_crx_reloc_type (type);
1807 break;
1808
179d3252
JT
1809 case EM_VAX:
1810 rtype = elf_vax_reloc_type (type);
1811 break;
1e4cf259 1812
619ed720
EB
1813 case EM_VISIUM:
1814 rtype = elf_visium_reloc_type (type);
1815 break;
1816
aca4efc7
JM
1817 case EM_BPF:
1818 rtype = elf_bpf_reloc_type (type);
1819 break;
1820
cfb8c092
NC
1821 case EM_ADAPTEVA_EPIPHANY:
1822 rtype = elf_epiphany_reloc_type (type);
1823 break;
1824
1e4cf259
NC
1825 case EM_IP2K:
1826 case EM_IP2K_OLD:
1827 rtype = elf_ip2k_reloc_type (type);
1828 break;
3b36097d
SC
1829
1830 case EM_IQ2000:
1831 rtype = elf_iq2000_reloc_type (type);
1832 break;
88da6820
NC
1833
1834 case EM_XTENSA_OLD:
1835 case EM_XTENSA:
1836 rtype = elf_xtensa_reloc_type (type);
1837 break;
a34e3ecb 1838
84e94c90
NC
1839 case EM_LATTICEMICO32:
1840 rtype = elf_lm32_reloc_type (type);
1841 break;
1842
ff7eeb89 1843 case EM_M32C_OLD:
49f58d10
JB
1844 case EM_M32C:
1845 rtype = elf_m32c_reloc_type (type);
1846 break;
1847
d031aafb
NS
1848 case EM_MT:
1849 rtype = elf_mt_reloc_type (type);
a34e3ecb 1850 break;
1d65ded4
CM
1851
1852 case EM_BLACKFIN:
1853 rtype = elf_bfin_reloc_type (type);
1854 break;
15ab5209
DB
1855
1856 case EM_CYGNUS_MEP:
1857 rtype = elf_mep_reloc_type (type);
1858 break;
60bca95a
NC
1859
1860 case EM_CR16:
1861 rtype = elf_cr16_reloc_type (type);
1862 break;
dd24e3da 1863
7ba29e2a
NC
1864 case EM_MICROBLAZE:
1865 case EM_MICROBLAZE_OLD:
1866 rtype = elf_microblaze_reloc_type (type);
1867 break;
c7927a3c 1868
99c513f6
DD
1869 case EM_RL78:
1870 rtype = elf_rl78_reloc_type (type);
1871 break;
1872
c7927a3c
NC
1873 case EM_RX:
1874 rtype = elf_rx_reloc_type (type);
1875 break;
c29aca4a 1876
a3c62988
NC
1877 case EM_METAG:
1878 rtype = elf_metag_reloc_type (type);
1879 break;
1880
c29aca4a
NC
1881 case EM_XC16X:
1882 case EM_C166:
1883 rtype = elf_xc16x_reloc_type (type);
1884 break;
40b36596
JM
1885
1886 case EM_TI_C6000:
1887 rtype = elf_tic6x_reloc_type (type);
1888 break;
aa137e4d
NC
1889
1890 case EM_TILEGX:
1891 rtype = elf_tilegx_reloc_type (type);
1892 break;
1893
1894 case EM_TILEPRO:
1895 rtype = elf_tilepro_reloc_type (type);
1896 break;
f6c1a2d5 1897
f96bd6c2
PC
1898 case EM_WEBASSEMBLY:
1899 rtype = elf_wasm32_reloc_type (type);
1900 break;
1901
f6c1a2d5
NC
1902 case EM_XGATE:
1903 rtype = elf_xgate_reloc_type (type);
1904 break;
36591ba1
SL
1905
1906 case EM_ALTERA_NIOS2:
1907 rtype = elf_nios2_reloc_type (type);
1908 break;
2b100bb5
DD
1909
1910 case EM_TI_PRU:
1911 rtype = elf_pru_reloc_type (type);
1912 break;
fe944acf
FT
1913
1914 case EM_NFP:
1915 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1916 rtype = elf_nfp3200_reloc_type (type);
1917 else
1918 rtype = elf_nfp_reloc_type (type);
1919 break;
6655dba2
SB
1920
1921 case EM_Z80:
1922 rtype = elf_z80_reloc_type (type);
1923 break;
e9a0721f 1924
1925 case EM_LOONGARCH:
1926 rtype = elf_loongarch_reloc_type (type);
1927 break;
1928
252b5132
RH
1929 }
1930
1931 if (rtype == NULL)
39dbeff8 1932 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1933 else
5c144731 1934 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1935
dda8d76d 1936 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1937 && rtype != NULL
7ace3541 1938 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1939 && rel_type == reltype_rela)
7ace3541
RH
1940 {
1941 switch (rels[i].r_addend)
1942 {
1943 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1944 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1945 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1946 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1947 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1948 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1949 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1950 default: rtype = NULL;
1951 }
32ec8896 1952
7ace3541
RH
1953 if (rtype)
1954 printf (" (%s)", rtype);
1955 else
1956 {
1957 putchar (' ');
1958 printf (_("<unknown addend: %lx>"),
1959 (unsigned long) rels[i].r_addend);
015dc7e1 1960 res = false;
7ace3541
RH
1961 }
1962 }
1963 else if (symtab_index)
252b5132 1964 {
af3fc3bc 1965 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1966 {
27a45f42
AS
1967 error (_(" bad symbol index: %08lx in reloc\n"),
1968 (unsigned long) symtab_index);
015dc7e1 1969 res = false;
32ec8896 1970 }
af3fc3bc 1971 else
19936277 1972 {
2cf0635d 1973 Elf_Internal_Sym * psym;
bb4d2ac2
L
1974 const char * version_string;
1975 enum versioned_symbol_info sym_info;
1976 unsigned short vna_other;
19936277 1977
af3fc3bc 1978 psym = symtab + symtab_index;
103f02d3 1979
bb4d2ac2 1980 version_string
dda8d76d 1981 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1982 strtab, strtablen,
1983 symtab_index,
1984 psym,
1985 &sym_info,
1986 &vna_other);
1987
af3fc3bc 1988 printf (" ");
171191ba 1989
d8045f23
NC
1990 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1991 {
1992 const char * name;
1993 unsigned int len;
1994 unsigned int width = is_32bit_elf ? 8 : 14;
1995
1996 /* Relocations against GNU_IFUNC symbols do not use the value
1997 of the symbol as the address to relocate against. Instead
1998 they invoke the function named by the symbol and use its
1999 result as the address for relocation.
2000
2001 To indicate this to the user, do not display the value of
2002 the symbol in the "Symbols's Value" field. Instead show
2003 its name followed by () as a hint that the symbol is
2004 invoked. */
2005
2006 if (strtab == NULL
2007 || psym->st_name == 0
2008 || psym->st_name >= strtablen)
2009 name = "??";
2010 else
2011 name = strtab + psym->st_name;
2012
2013 len = print_symbol (width, name);
bb4d2ac2
L
2014 if (version_string)
2015 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2016 version_string);
d8045f23
NC
2017 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2018 }
2019 else
2020 {
2021 print_vma (psym->st_value, LONG_HEX);
171191ba 2022
d8045f23
NC
2023 printf (is_32bit_elf ? " " : " ");
2024 }
103f02d3 2025
af3fc3bc 2026 if (psym->st_name == 0)
f1ef08cb 2027 {
2cf0635d 2028 const char * sec_name = "<null>";
f1ef08cb
AM
2029 char name_buf[40];
2030
2031 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2032 {
b9af6379
AM
2033 if (psym->st_shndx < filedata->file_header.e_shnum
2034 && filedata->section_headers != NULL)
84714f86
AM
2035 sec_name = section_name_print (filedata,
2036 filedata->section_headers
b9e920ec 2037 + psym->st_shndx);
f1ef08cb
AM
2038 else if (psym->st_shndx == SHN_ABS)
2039 sec_name = "ABS";
2040 else if (psym->st_shndx == SHN_COMMON)
2041 sec_name = "COMMON";
dda8d76d 2042 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2043 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2044 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2045 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2046 sec_name = "SCOMMON";
dda8d76d 2047 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2048 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2049 sec_name = "SUNDEF";
dda8d76d
NC
2050 else if ((filedata->file_header.e_machine == EM_X86_64
2051 || filedata->file_header.e_machine == EM_L1OM
2052 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2053 && psym->st_shndx == SHN_X86_64_LCOMMON)
2054 sec_name = "LARGE_COMMON";
dda8d76d
NC
2055 else if (filedata->file_header.e_machine == EM_IA_64
2056 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2057 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2058 sec_name = "ANSI_COM";
dda8d76d 2059 else if (is_ia64_vms (filedata)
148b93f2
NC
2060 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2061 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2062 else
2063 {
2064 sprintf (name_buf, "<section 0x%x>",
2065 (unsigned int) psym->st_shndx);
2066 sec_name = name_buf;
2067 }
2068 }
2069 print_symbol (22, sec_name);
2070 }
af3fc3bc 2071 else if (strtab == NULL)
d79b3d50 2072 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2073 else if (psym->st_name >= strtablen)
32ec8896 2074 {
27a45f42
AS
2075 error (_("<corrupt string table index: %3ld>\n"),
2076 psym->st_name);
015dc7e1 2077 res = false;
32ec8896 2078 }
af3fc3bc 2079 else
bb4d2ac2
L
2080 {
2081 print_symbol (22, strtab + psym->st_name);
2082 if (version_string)
2083 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2084 version_string);
2085 }
103f02d3 2086
a7fd1186 2087 if (rel_type == reltype_rela)
171191ba 2088 {
7360e63f 2089 bfd_vma off = rels[i].r_addend;
171191ba 2090
7360e63f 2091 if ((bfd_signed_vma) off < 0)
598aaa76 2092 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 2093 else
598aaa76 2094 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 2095 }
19936277 2096 }
252b5132 2097 }
a7fd1186 2098 else if (rel_type == reltype_rela)
f7a99963 2099 {
7360e63f 2100 bfd_vma off = rels[i].r_addend;
e04d7088
L
2101
2102 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2103 if ((bfd_signed_vma) off < 0)
e04d7088
L
2104 printf ("-%" BFD_VMA_FMT "x", - off);
2105 else
2106 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 2107 }
252b5132 2108
dda8d76d 2109 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2110 && rtype != NULL
2111 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2112 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2113
252b5132 2114 putchar ('\n');
2c71103e 2115
aca88567 2116#ifdef BFD64
dda8d76d 2117 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2118 {
91d6fa6a
NC
2119 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2120 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2121 const char * rtype2 = elf_mips_reloc_type (type2);
2122 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2123
2c71103e
NC
2124 printf (" Type2: ");
2125
2126 if (rtype2 == NULL)
39dbeff8
AM
2127 printf (_("unrecognized: %-7lx"),
2128 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2129 else
2130 printf ("%-17.17s", rtype2);
2131
18bd398b 2132 printf ("\n Type3: ");
2c71103e
NC
2133
2134 if (rtype3 == NULL)
39dbeff8
AM
2135 printf (_("unrecognized: %-7lx"),
2136 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2137 else
2138 printf ("%-17.17s", rtype3);
2139
53c7db4b 2140 putchar ('\n');
2c71103e 2141 }
aca88567 2142#endif /* BFD64 */
252b5132
RH
2143 }
2144
c8286bd1 2145 free (rels);
32ec8896
NC
2146
2147 return res;
252b5132
RH
2148}
2149
37c18eed
SD
2150static const char *
2151get_aarch64_dynamic_type (unsigned long type)
2152{
2153 switch (type)
2154 {
2155 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2156 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2157 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2158 default:
2159 return NULL;
2160 }
2161}
2162
252b5132 2163static const char *
d3ba0551 2164get_mips_dynamic_type (unsigned long type)
252b5132
RH
2165{
2166 switch (type)
2167 {
2168 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2169 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2170 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2171 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2172 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2173 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2174 case DT_MIPS_MSYM: return "MIPS_MSYM";
2175 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2176 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2177 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2178 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2179 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2180 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2181 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2182 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2183 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2184 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2185 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2186 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2187 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2188 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2189 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2190 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2191 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2192 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2193 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2194 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2195 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2196 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2197 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2198 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2199 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2200 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2201 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2202 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2203 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2204 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2205 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2206 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2207 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2208 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2209 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2210 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2211 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2212 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2213 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2214 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2215 default:
2216 return NULL;
2217 }
2218}
2219
9a097730 2220static const char *
d3ba0551 2221get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2222{
2223 switch (type)
2224 {
2225 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2226 default:
2227 return NULL;
2228 }
103f02d3
UD
2229}
2230
7490d522
AM
2231static const char *
2232get_ppc_dynamic_type (unsigned long type)
2233{
2234 switch (type)
2235 {
a7f2871e 2236 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2237 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2238 default:
2239 return NULL;
2240 }
2241}
2242
f1cb7e17 2243static const char *
d3ba0551 2244get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2245{
2246 switch (type)
2247 {
a7f2871e
AM
2248 case DT_PPC64_GLINK: return "PPC64_GLINK";
2249 case DT_PPC64_OPD: return "PPC64_OPD";
2250 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2251 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2252 default:
2253 return NULL;
2254 }
2255}
2256
103f02d3 2257static const char *
d3ba0551 2258get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2259{
2260 switch (type)
2261 {
2262 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2263 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2264 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2265 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2266 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2267 case DT_HP_PREINIT: return "HP_PREINIT";
2268 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2269 case DT_HP_NEEDED: return "HP_NEEDED";
2270 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2271 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2272 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2273 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2274 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2275 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2276 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2277 case DT_HP_FILTERED: return "HP_FILTERED";
2278 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2279 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2280 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2281 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2282 case DT_PLT: return "PLT";
2283 case DT_PLT_SIZE: return "PLT_SIZE";
2284 case DT_DLT: return "DLT";
2285 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2286 default:
2287 return NULL;
2288 }
2289}
9a097730 2290
ecc51f48 2291static const char *
d3ba0551 2292get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2293{
2294 switch (type)
2295 {
148b93f2
NC
2296 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2297 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2298 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2299 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2300 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2301 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2302 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2303 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2304 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2305 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2306 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2307 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2308 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2309 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2310 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2311 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2312 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2313 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2314 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2315 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2316 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2317 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2318 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2319 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2320 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2321 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2322 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2323 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2324 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2325 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2326 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2327 default:
2328 return NULL;
2329 }
2330}
2331
fd85a6a1
NC
2332static const char *
2333get_solaris_section_type (unsigned long type)
2334{
2335 switch (type)
2336 {
2337 case 0x6fffffee: return "SUNW_ancillary";
2338 case 0x6fffffef: return "SUNW_capchain";
2339 case 0x6ffffff0: return "SUNW_capinfo";
2340 case 0x6ffffff1: return "SUNW_symsort";
2341 case 0x6ffffff2: return "SUNW_tlssort";
2342 case 0x6ffffff3: return "SUNW_LDYNSYM";
2343 case 0x6ffffff4: return "SUNW_dof";
2344 case 0x6ffffff5: return "SUNW_cap";
2345 case 0x6ffffff6: return "SUNW_SIGNATURE";
2346 case 0x6ffffff7: return "SUNW_ANNOTATE";
2347 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2348 case 0x6ffffff9: return "SUNW_DEBUG";
2349 case 0x6ffffffa: return "SUNW_move";
2350 case 0x6ffffffb: return "SUNW_COMDAT";
2351 case 0x6ffffffc: return "SUNW_syminfo";
2352 case 0x6ffffffd: return "SUNW_verdef";
2353 case 0x6ffffffe: return "SUNW_verneed";
2354 case 0x6fffffff: return "SUNW_versym";
2355 case 0x70000000: return "SPARC_GOTDATA";
2356 default: return NULL;
2357 }
2358}
2359
fabcb361
RH
2360static const char *
2361get_alpha_dynamic_type (unsigned long type)
2362{
2363 switch (type)
2364 {
2365 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2366 default: return NULL;
fabcb361
RH
2367 }
2368}
2369
1c0d3aa6
NC
2370static const char *
2371get_score_dynamic_type (unsigned long type)
2372{
2373 switch (type)
2374 {
2375 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2376 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2377 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2378 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2379 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2380 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2381 default: return NULL;
1c0d3aa6
NC
2382 }
2383}
2384
40b36596
JM
2385static const char *
2386get_tic6x_dynamic_type (unsigned long type)
2387{
2388 switch (type)
2389 {
2390 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2391 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2392 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2393 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2394 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2395 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2396 default: return NULL;
40b36596
JM
2397 }
2398}
1c0d3aa6 2399
36591ba1
SL
2400static const char *
2401get_nios2_dynamic_type (unsigned long type)
2402{
2403 switch (type)
2404 {
2405 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2406 default: return NULL;
36591ba1
SL
2407 }
2408}
2409
fd85a6a1
NC
2410static const char *
2411get_solaris_dynamic_type (unsigned long type)
2412{
2413 switch (type)
2414 {
2415 case 0x6000000d: return "SUNW_AUXILIARY";
2416 case 0x6000000e: return "SUNW_RTLDINF";
2417 case 0x6000000f: return "SUNW_FILTER";
2418 case 0x60000010: return "SUNW_CAP";
2419 case 0x60000011: return "SUNW_SYMTAB";
2420 case 0x60000012: return "SUNW_SYMSZ";
2421 case 0x60000013: return "SUNW_SORTENT";
2422 case 0x60000014: return "SUNW_SYMSORT";
2423 case 0x60000015: return "SUNW_SYMSORTSZ";
2424 case 0x60000016: return "SUNW_TLSSORT";
2425 case 0x60000017: return "SUNW_TLSSORTSZ";
2426 case 0x60000018: return "SUNW_CAPINFO";
2427 case 0x60000019: return "SUNW_STRPAD";
2428 case 0x6000001a: return "SUNW_CAPCHAIN";
2429 case 0x6000001b: return "SUNW_LDMACH";
2430 case 0x6000001d: return "SUNW_CAPCHAINENT";
2431 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2432 case 0x60000021: return "SUNW_PARENT";
2433 case 0x60000023: return "SUNW_ASLR";
2434 case 0x60000025: return "SUNW_RELAX";
2435 case 0x60000029: return "SUNW_NXHEAP";
2436 case 0x6000002b: return "SUNW_NXSTACK";
2437
2438 case 0x70000001: return "SPARC_REGISTER";
2439 case 0x7ffffffd: return "AUXILIARY";
2440 case 0x7ffffffe: return "USED";
2441 case 0x7fffffff: return "FILTER";
2442
15f205b1 2443 default: return NULL;
fd85a6a1
NC
2444 }
2445}
2446
8155b853
NC
2447static const char *
2448get_riscv_dynamic_type (unsigned long type)
2449{
2450 switch (type)
2451 {
2452 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2453 default:
2454 return NULL;
2455 }
2456}
2457
252b5132 2458static const char *
dda8d76d 2459get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2460{
e9e44622 2461 static char buff[64];
252b5132
RH
2462
2463 switch (type)
2464 {
2465 case DT_NULL: return "NULL";
2466 case DT_NEEDED: return "NEEDED";
2467 case DT_PLTRELSZ: return "PLTRELSZ";
2468 case DT_PLTGOT: return "PLTGOT";
2469 case DT_HASH: return "HASH";
2470 case DT_STRTAB: return "STRTAB";
2471 case DT_SYMTAB: return "SYMTAB";
2472 case DT_RELA: return "RELA";
2473 case DT_RELASZ: return "RELASZ";
2474 case DT_RELAENT: return "RELAENT";
2475 case DT_STRSZ: return "STRSZ";
2476 case DT_SYMENT: return "SYMENT";
2477 case DT_INIT: return "INIT";
2478 case DT_FINI: return "FINI";
2479 case DT_SONAME: return "SONAME";
2480 case DT_RPATH: return "RPATH";
2481 case DT_SYMBOLIC: return "SYMBOLIC";
2482 case DT_REL: return "REL";
2483 case DT_RELSZ: return "RELSZ";
2484 case DT_RELENT: return "RELENT";
dd207c13
FS
2485 case DT_RELR: return "RELR";
2486 case DT_RELRSZ: return "RELRSZ";
2487 case DT_RELRENT: return "RELRENT";
252b5132
RH
2488 case DT_PLTREL: return "PLTREL";
2489 case DT_DEBUG: return "DEBUG";
2490 case DT_TEXTREL: return "TEXTREL";
2491 case DT_JMPREL: return "JMPREL";
2492 case DT_BIND_NOW: return "BIND_NOW";
2493 case DT_INIT_ARRAY: return "INIT_ARRAY";
2494 case DT_FINI_ARRAY: return "FINI_ARRAY";
2495 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2496 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2497 case DT_RUNPATH: return "RUNPATH";
2498 case DT_FLAGS: return "FLAGS";
2d0e6f43 2499
d1133906
NC
2500 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2501 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2502 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2503
05107a46 2504 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2505 case DT_PLTPADSZ: return "PLTPADSZ";
2506 case DT_MOVEENT: return "MOVEENT";
2507 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2508 case DT_FEATURE: return "FEATURE";
252b5132
RH
2509 case DT_POSFLAG_1: return "POSFLAG_1";
2510 case DT_SYMINSZ: return "SYMINSZ";
2511 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2512
252b5132 2513 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2514 case DT_CONFIG: return "CONFIG";
2515 case DT_DEPAUDIT: return "DEPAUDIT";
2516 case DT_AUDIT: return "AUDIT";
2517 case DT_PLTPAD: return "PLTPAD";
2518 case DT_MOVETAB: return "MOVETAB";
252b5132 2519 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2520
252b5132 2521 case DT_VERSYM: return "VERSYM";
103f02d3 2522
67a4f2b7
AO
2523 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2524 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2525 case DT_RELACOUNT: return "RELACOUNT";
2526 case DT_RELCOUNT: return "RELCOUNT";
2527 case DT_FLAGS_1: return "FLAGS_1";
2528 case DT_VERDEF: return "VERDEF";
2529 case DT_VERDEFNUM: return "VERDEFNUM";
2530 case DT_VERNEED: return "VERNEED";
2531 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2532
019148e4 2533 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2534 case DT_USED: return "USED";
2535 case DT_FILTER: return "FILTER";
103f02d3 2536
047b2264
JJ
2537 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2538 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2539 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2540 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2541 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2542 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2543 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2544
252b5132
RH
2545 default:
2546 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2547 {
2cf0635d 2548 const char * result;
103f02d3 2549
dda8d76d 2550 switch (filedata->file_header.e_machine)
252b5132 2551 {
37c18eed
SD
2552 case EM_AARCH64:
2553 result = get_aarch64_dynamic_type (type);
2554 break;
252b5132 2555 case EM_MIPS:
4fe85591 2556 case EM_MIPS_RS3_LE:
252b5132
RH
2557 result = get_mips_dynamic_type (type);
2558 break;
9a097730
RH
2559 case EM_SPARCV9:
2560 result = get_sparc64_dynamic_type (type);
2561 break;
7490d522
AM
2562 case EM_PPC:
2563 result = get_ppc_dynamic_type (type);
2564 break;
f1cb7e17
AM
2565 case EM_PPC64:
2566 result = get_ppc64_dynamic_type (type);
2567 break;
ecc51f48
NC
2568 case EM_IA_64:
2569 result = get_ia64_dynamic_type (type);
2570 break;
fabcb361
RH
2571 case EM_ALPHA:
2572 result = get_alpha_dynamic_type (type);
2573 break;
1c0d3aa6
NC
2574 case EM_SCORE:
2575 result = get_score_dynamic_type (type);
2576 break;
40b36596
JM
2577 case EM_TI_C6000:
2578 result = get_tic6x_dynamic_type (type);
2579 break;
36591ba1
SL
2580 case EM_ALTERA_NIOS2:
2581 result = get_nios2_dynamic_type (type);
2582 break;
8155b853
NC
2583 case EM_RISCV:
2584 result = get_riscv_dynamic_type (type);
2585 break;
252b5132 2586 default:
dda8d76d 2587 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2588 result = get_solaris_dynamic_type (type);
2589 else
2590 result = NULL;
252b5132
RH
2591 break;
2592 }
2593
2594 if (result != NULL)
2595 return result;
2596
e9e44622 2597 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2598 }
eec8f817 2599 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2600 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2601 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2602 {
2cf0635d 2603 const char * result;
103f02d3 2604
dda8d76d 2605 switch (filedata->file_header.e_machine)
103f02d3
UD
2606 {
2607 case EM_PARISC:
2608 result = get_parisc_dynamic_type (type);
2609 break;
148b93f2
NC
2610 case EM_IA_64:
2611 result = get_ia64_dynamic_type (type);
2612 break;
103f02d3 2613 default:
dda8d76d 2614 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2615 result = get_solaris_dynamic_type (type);
2616 else
2617 result = NULL;
103f02d3
UD
2618 break;
2619 }
2620
2621 if (result != NULL)
2622 return result;
2623
e9e44622
JJ
2624 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2625 type);
103f02d3 2626 }
252b5132 2627 else
e9e44622 2628 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2629
252b5132
RH
2630 return buff;
2631 }
2632}
2633
93df3340
AM
2634static bool get_program_headers (Filedata *);
2635static bool get_dynamic_section (Filedata *);
2636
2637static void
2638locate_dynamic_section (Filedata *filedata)
2639{
2640 unsigned long dynamic_addr = 0;
2641 bfd_size_type dynamic_size = 0;
2642
2643 if (filedata->file_header.e_phnum != 0
2644 && get_program_headers (filedata))
2645 {
2646 Elf_Internal_Phdr *segment;
2647 unsigned int i;
2648
2649 for (i = 0, segment = filedata->program_headers;
2650 i < filedata->file_header.e_phnum;
2651 i++, segment++)
2652 {
2653 if (segment->p_type == PT_DYNAMIC)
2654 {
2655 dynamic_addr = segment->p_offset;
2656 dynamic_size = segment->p_filesz;
2657
2658 if (filedata->section_headers != NULL)
2659 {
2660 Elf_Internal_Shdr *sec;
2661
2662 sec = find_section (filedata, ".dynamic");
2663 if (sec != NULL)
2664 {
2665 if (sec->sh_size == 0
2666 || sec->sh_type == SHT_NOBITS)
2667 {
2668 dynamic_addr = 0;
2669 dynamic_size = 0;
2670 }
2671 else
2672 {
2673 dynamic_addr = sec->sh_offset;
2674 dynamic_size = sec->sh_size;
2675 }
2676 }
2677 }
2678
2679 if (dynamic_addr > filedata->file_size
2680 || (dynamic_size > filedata->file_size - dynamic_addr))
2681 {
2682 dynamic_addr = 0;
2683 dynamic_size = 0;
2684 }
2685 break;
2686 }
2687 }
2688 }
2689 filedata->dynamic_addr = dynamic_addr;
2690 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2691}
2692
2693static bool
2694is_pie (Filedata *filedata)
2695{
2696 Elf_Internal_Dyn *entry;
2697
2698 if (filedata->dynamic_size == 0)
2699 locate_dynamic_section (filedata);
2700 if (filedata->dynamic_size <= 1)
2701 return false;
2702
2703 if (!get_dynamic_section (filedata))
2704 return false;
2705
2706 for (entry = filedata->dynamic_section;
2707 entry < filedata->dynamic_section + filedata->dynamic_nent;
2708 entry++)
2709 {
2710 if (entry->d_tag == DT_FLAGS_1)
2711 {
2712 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2713 return true;
2714 break;
2715 }
2716 }
2717 return false;
2718}
2719
252b5132 2720static char *
93df3340 2721get_file_type (Filedata *filedata)
252b5132 2722{
93df3340 2723 unsigned e_type = filedata->file_header.e_type;
89246a0e 2724 static char buff[64];
252b5132
RH
2725
2726 switch (e_type)
2727 {
32ec8896
NC
2728 case ET_NONE: return _("NONE (None)");
2729 case ET_REL: return _("REL (Relocatable file)");
2730 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2731 case ET_DYN:
2732 if (is_pie (filedata))
2733 return _("DYN (Position-Independent Executable file)");
2734 else
2735 return _("DYN (Shared object file)");
32ec8896 2736 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2737
2738 default:
2739 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2740 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2741 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2742 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2743 else
e9e44622 2744 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2745 return buff;
2746 }
2747}
2748
2749static char *
d3ba0551 2750get_machine_name (unsigned e_machine)
252b5132 2751{
b34976b6 2752 static char buff[64]; /* XXX */
252b5132
RH
2753
2754 switch (e_machine)
2755 {
55e22ca8
NC
2756 /* Please keep this switch table sorted by increasing EM_ value. */
2757 /* 0 */
c45021f2
NC
2758 case EM_NONE: return _("None");
2759 case EM_M32: return "WE32100";
2760 case EM_SPARC: return "Sparc";
2761 case EM_386: return "Intel 80386";
2762 case EM_68K: return "MC68000";
2763 case EM_88K: return "MC88000";
22abe556 2764 case EM_IAMCU: return "Intel MCU";
fb70ec17 2765 case EM_860: return "Intel 80860";
c45021f2
NC
2766 case EM_MIPS: return "MIPS R3000";
2767 case EM_S370: return "IBM System/370";
55e22ca8 2768 /* 10 */
7036c0e1 2769 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2770 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2771 case EM_PARISC: return "HPPA";
55e22ca8 2772 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2773 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2774 case EM_960: return "Intel 80960";
c45021f2 2775 case EM_PPC: return "PowerPC";
55e22ca8 2776 /* 20 */
285d1771 2777 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2778 case EM_S390_OLD:
2779 case EM_S390: return "IBM S/390";
2780 case EM_SPU: return "SPU";
2781 /* 30 */
2782 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2783 case EM_FR20: return "Fujitsu FR20";
2784 case EM_RH32: return "TRW RH32";
b34976b6 2785 case EM_MCORE: return "MCORE";
55e22ca8 2786 /* 40 */
7036c0e1
AJ
2787 case EM_ARM: return "ARM";
2788 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2789 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2790 case EM_SPARCV9: return "Sparc v9";
2791 case EM_TRICORE: return "Siemens Tricore";
584da044 2792 case EM_ARC: return "ARC";
c2dcd04e
NC
2793 case EM_H8_300: return "Renesas H8/300";
2794 case EM_H8_300H: return "Renesas H8/300H";
2795 case EM_H8S: return "Renesas H8S";
2796 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2797 /* 50 */
30800947 2798 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2799 case EM_MIPS_X: return "Stanford MIPS-X";
2800 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2801 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2802 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2803 case EM_PCP: return "Siemens PCP";
2804 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2805 case EM_NDR1: return "Denso NDR1 microprocesspr";
2806 case EM_STARCORE: return "Motorola Star*Core processor";
2807 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2808 /* 60 */
7036c0e1
AJ
2809 case EM_ST100: return "STMicroelectronics ST100 processor";
2810 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2811 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2812 case EM_PDSP: return "Sony DSP processor";
2813 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2814 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2815 case EM_FX66: return "Siemens FX66 microcontroller";
2816 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2817 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2818 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2819 /* 70 */
7036c0e1
AJ
2820 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2821 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2822 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2823 case EM_SVX: return "Silicon Graphics SVx";
2824 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2825 case EM_VAX: return "Digital VAX";
1b61cf92 2826 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2827 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2828 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2829 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2830 /* 80 */
b34976b6 2831 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2832 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2833 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2834 case EM_AVR_OLD:
2835 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2836 case EM_CYGNUS_FR30:
2837 case EM_FR30: return "Fujitsu FR30";
2838 case EM_CYGNUS_D10V:
2839 case EM_D10V: return "d10v";
2840 case EM_CYGNUS_D30V:
2841 case EM_D30V: return "d30v";
2842 case EM_CYGNUS_V850:
2843 case EM_V850: return "Renesas V850";
2844 case EM_CYGNUS_M32R:
2845 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2846 case EM_CYGNUS_MN10300:
2847 case EM_MN10300: return "mn10300";
2848 /* 90 */
2849 case EM_CYGNUS_MN10200:
2850 case EM_MN10200: return "mn10200";
2851 case EM_PJ: return "picoJava";
73589c9d 2852 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2853 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2854 case EM_XTENSA_OLD:
2855 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2856 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2857 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2858 case EM_NS32K: return "National Semiconductor 32000 series";
2859 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2860 case EM_SNP1K: return "Trebia SNP 1000 processor";
2861 /* 100 */
9abca702 2862 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2863 case EM_IP2K_OLD:
2864 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2865 case EM_MAX: return "MAX Processor";
2866 case EM_CR: return "National Semiconductor CompactRISC";
2867 case EM_F2MC16: return "Fujitsu F2MC16";
2868 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2869 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2870 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2871 case EM_SEP: return "Sharp embedded microprocessor";
2872 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2873 /* 110 */
11636f9e
JM
2874 case EM_UNICORE: return "Unicore";
2875 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2876 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2877 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2878 case EM_CRX: return "National Semiconductor CRX microprocessor";
2879 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2880 case EM_C166:
d70c5fc7 2881 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2882 case EM_M16C: return "Renesas M16C series microprocessors";
2883 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2884 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2885 /* 120 */
2886 case EM_M32C: return "Renesas M32c";
2887 /* 130 */
11636f9e
JM
2888 case EM_TSK3000: return "Altium TSK3000 core";
2889 case EM_RS08: return "Freescale RS08 embedded processor";
2890 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2891 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2892 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2893 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2894 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2895 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2896 /* 140 */
11636f9e
JM
2897 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2898 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2899 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2900 case EM_TI_PRU: return "TI PRU I/O processor";
2901 /* 160 */
11636f9e
JM
2902 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2903 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2904 case EM_R32C: return "Renesas R32C series microprocessors";
2905 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2906 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2907 case EM_8051: return "Intel 8051 and variants";
2908 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2909 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2910 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2911 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2912 /* 170 */
11636f9e
JM
2913 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2914 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2915 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2916 case EM_RX: return "Renesas RX";
a3c62988 2917 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2918 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2919 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2920 case EM_CR16:
2921 case EM_MICROBLAZE:
2922 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2923 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2924 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2925 /* 180 */
2926 case EM_L1OM: return "Intel L1OM";
2927 case EM_K1OM: return "Intel K1OM";
2928 case EM_INTEL182: return "Intel (reserved)";
2929 case EM_AARCH64: return "AArch64";
2930 case EM_ARM184: return "ARM (reserved)";
2931 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2932 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2933 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2934 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2935 /* 190 */
11636f9e 2936 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2937 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2938 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2939 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2940 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2941 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2942 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2943 case EM_RL78: return "Renesas RL78";
6d913794 2944 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2945 case EM_78K0R: return "Renesas 78K0R";
2946 /* 200 */
6d913794 2947 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2948 case EM_BA1: return "Beyond BA1 CPU architecture";
2949 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2950 case EM_XCORE: return "XMOS xCORE processor family";
2951 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2952 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2953 /* 210 */
6d913794
NC
2954 case EM_KM32: return "KM211 KM32 32-bit processor";
2955 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2956 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2957 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2958 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2959 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2960 case EM_COGE: return "Cognitive Smart Memory Processor";
2961 case EM_COOL: return "Bluechip Systems CoolEngine";
2962 case EM_NORC: return "Nanoradio Optimized RISC";
2963 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2964 /* 220 */
15f205b1 2965 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2966 case EM_VISIUM: return "CDS VISIUMcore processor";
2967 case EM_FT32: return "FTDI Chip FT32";
2968 case EM_MOXIE: return "Moxie";
2969 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2970 /* 230 (all reserved) */
2971 /* 240 */
55e22ca8
NC
2972 case EM_RISCV: return "RISC-V";
2973 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2974 case EM_CEVA: return "CEVA Processor Architecture Family";
2975 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2976 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2977 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2978 case EM_IMG1: return "Imagination Technologies";
2979 /* 250 */
fe944acf 2980 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2981 case EM_VE: return "NEC Vector Engine";
2982 case EM_CSKY: return "C-SKY";
2983 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2984 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2985 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2986 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2987 case EM_65816: return "WDC 65816/65C816";
01a8c731 2988 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2989 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2990
2991 /* Large numbers... */
2992 case EM_MT: return "Morpho Techologies MT processor";
2993 case EM_ALPHA: return "Alpha";
2994 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2995 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2996 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2997 case EM_IQ2000: return "Vitesse IQ2000";
2998 case EM_M32C_OLD:
2999 case EM_NIOS32: return "Altera Nios";
3000 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3001 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3002 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3003 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3004
252b5132 3005 default:
35d9dd2f 3006 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3007 return buff;
3008 }
3009}
3010
a9522a21
AB
3011static void
3012decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3013{
3014 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3015 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3016 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3017 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3018 architectures.
3019
3020 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3021 but also sets a specific architecture type in the e_flags field.
3022
3023 However, when decoding the flags we don't worry if we see an
3024 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3025 ARCEM architecture type. */
3026
3027 switch (e_flags & EF_ARC_MACH_MSK)
3028 {
3029 /* We only expect these to occur for EM_ARC_COMPACT2. */
3030 case EF_ARC_CPU_ARCV2EM:
3031 strcat (buf, ", ARC EM");
3032 break;
3033 case EF_ARC_CPU_ARCV2HS:
3034 strcat (buf, ", ARC HS");
3035 break;
3036
3037 /* We only expect these to occur for EM_ARC_COMPACT. */
3038 case E_ARC_MACH_ARC600:
3039 strcat (buf, ", ARC600");
3040 break;
3041 case E_ARC_MACH_ARC601:
3042 strcat (buf, ", ARC601");
3043 break;
3044 case E_ARC_MACH_ARC700:
3045 strcat (buf, ", ARC700");
3046 break;
3047
3048 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3049 new ELF with new architecture being read by an old version of
3050 readelf, or (c) An ELF built with non-GNU compiler that does not
3051 set the architecture in the e_flags. */
3052 default:
3053 if (e_machine == EM_ARC_COMPACT)
3054 strcat (buf, ", Unknown ARCompact");
3055 else
3056 strcat (buf, ", Unknown ARC");
3057 break;
3058 }
3059
3060 switch (e_flags & EF_ARC_OSABI_MSK)
3061 {
3062 case E_ARC_OSABI_ORIG:
3063 strcat (buf, ", (ABI:legacy)");
3064 break;
3065 case E_ARC_OSABI_V2:
3066 strcat (buf, ", (ABI:v2)");
3067 break;
3068 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3069 case E_ARC_OSABI_V3:
3070 strcat (buf, ", v3 no-legacy-syscalls ABI");
3071 break;
53a346d8
CZ
3072 case E_ARC_OSABI_V4:
3073 strcat (buf, ", v4 ABI");
3074 break;
a9522a21
AB
3075 default:
3076 strcat (buf, ", unrecognised ARC OSABI flag");
3077 break;
3078 }
3079}
3080
f3485b74 3081static void
d3ba0551 3082decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3083{
3084 unsigned eabi;
015dc7e1 3085 bool unknown = false;
f3485b74
NC
3086
3087 eabi = EF_ARM_EABI_VERSION (e_flags);
3088 e_flags &= ~ EF_ARM_EABIMASK;
3089
3090 /* Handle "generic" ARM flags. */
3091 if (e_flags & EF_ARM_RELEXEC)
3092 {
3093 strcat (buf, ", relocatable executable");
3094 e_flags &= ~ EF_ARM_RELEXEC;
3095 }
76da6bbe 3096
18a20338
CL
3097 if (e_flags & EF_ARM_PIC)
3098 {
3099 strcat (buf, ", position independent");
3100 e_flags &= ~ EF_ARM_PIC;
3101 }
3102
f3485b74
NC
3103 /* Now handle EABI specific flags. */
3104 switch (eabi)
3105 {
3106 default:
2c71103e 3107 strcat (buf, ", <unrecognized EABI>");
f3485b74 3108 if (e_flags)
015dc7e1 3109 unknown = true;
f3485b74
NC
3110 break;
3111
3112 case EF_ARM_EABI_VER1:
a5bcd848 3113 strcat (buf, ", Version1 EABI");
f3485b74
NC
3114 while (e_flags)
3115 {
3116 unsigned flag;
76da6bbe 3117
f3485b74
NC
3118 /* Process flags one bit at a time. */
3119 flag = e_flags & - e_flags;
3120 e_flags &= ~ flag;
76da6bbe 3121
f3485b74
NC
3122 switch (flag)
3123 {
a5bcd848 3124 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3125 strcat (buf, ", sorted symbol tables");
3126 break;
76da6bbe 3127
f3485b74 3128 default:
015dc7e1 3129 unknown = true;
f3485b74
NC
3130 break;
3131 }
3132 }
3133 break;
76da6bbe 3134
a5bcd848
PB
3135 case EF_ARM_EABI_VER2:
3136 strcat (buf, ", Version2 EABI");
3137 while (e_flags)
3138 {
3139 unsigned flag;
3140
3141 /* Process flags one bit at a time. */
3142 flag = e_flags & - e_flags;
3143 e_flags &= ~ flag;
3144
3145 switch (flag)
3146 {
3147 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3148 strcat (buf, ", sorted symbol tables");
3149 break;
3150
3151 case EF_ARM_DYNSYMSUSESEGIDX:
3152 strcat (buf, ", dynamic symbols use segment index");
3153 break;
3154
3155 case EF_ARM_MAPSYMSFIRST:
3156 strcat (buf, ", mapping symbols precede others");
3157 break;
3158
3159 default:
015dc7e1 3160 unknown = true;
a5bcd848
PB
3161 break;
3162 }
3163 }
3164 break;
3165
d507cf36
PB
3166 case EF_ARM_EABI_VER3:
3167 strcat (buf, ", Version3 EABI");
8cb51566
PB
3168 break;
3169
3170 case EF_ARM_EABI_VER4:
3171 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3172 while (e_flags)
3173 {
3174 unsigned flag;
3175
3176 /* Process flags one bit at a time. */
3177 flag = e_flags & - e_flags;
3178 e_flags &= ~ flag;
3179
3180 switch (flag)
3181 {
3182 case EF_ARM_BE8:
3183 strcat (buf, ", BE8");
3184 break;
3185
3186 case EF_ARM_LE8:
3187 strcat (buf, ", LE8");
3188 break;
3189
3190 default:
015dc7e1 3191 unknown = true;
3bfcb652
NC
3192 break;
3193 }
3bfcb652
NC
3194 }
3195 break;
3a4a14e9
PB
3196
3197 case EF_ARM_EABI_VER5:
3198 strcat (buf, ", Version5 EABI");
d507cf36
PB
3199 while (e_flags)
3200 {
3201 unsigned flag;
3202
3203 /* Process flags one bit at a time. */
3204 flag = e_flags & - e_flags;
3205 e_flags &= ~ flag;
3206
3207 switch (flag)
3208 {
3209 case EF_ARM_BE8:
3210 strcat (buf, ", BE8");
3211 break;
3212
3213 case EF_ARM_LE8:
3214 strcat (buf, ", LE8");
3215 break;
3216
3bfcb652
NC
3217 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3218 strcat (buf, ", soft-float ABI");
3219 break;
3220
3221 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3222 strcat (buf, ", hard-float ABI");
3223 break;
3224
d507cf36 3225 default:
015dc7e1 3226 unknown = true;
d507cf36
PB
3227 break;
3228 }
3229 }
3230 break;
3231
f3485b74 3232 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3233 strcat (buf, ", GNU EABI");
f3485b74
NC
3234 while (e_flags)
3235 {
3236 unsigned flag;
76da6bbe 3237
f3485b74
NC
3238 /* Process flags one bit at a time. */
3239 flag = e_flags & - e_flags;
3240 e_flags &= ~ flag;
76da6bbe 3241
f3485b74
NC
3242 switch (flag)
3243 {
a5bcd848 3244 case EF_ARM_INTERWORK:
f3485b74
NC
3245 strcat (buf, ", interworking enabled");
3246 break;
76da6bbe 3247
a5bcd848 3248 case EF_ARM_APCS_26:
f3485b74
NC
3249 strcat (buf, ", uses APCS/26");
3250 break;
76da6bbe 3251
a5bcd848 3252 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3253 strcat (buf, ", uses APCS/float");
3254 break;
76da6bbe 3255
a5bcd848 3256 case EF_ARM_PIC:
f3485b74
NC
3257 strcat (buf, ", position independent");
3258 break;
76da6bbe 3259
a5bcd848 3260 case EF_ARM_ALIGN8:
f3485b74
NC
3261 strcat (buf, ", 8 bit structure alignment");
3262 break;
76da6bbe 3263
a5bcd848 3264 case EF_ARM_NEW_ABI:
f3485b74
NC
3265 strcat (buf, ", uses new ABI");
3266 break;
76da6bbe 3267
a5bcd848 3268 case EF_ARM_OLD_ABI:
f3485b74
NC
3269 strcat (buf, ", uses old ABI");
3270 break;
76da6bbe 3271
a5bcd848 3272 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3273 strcat (buf, ", software FP");
3274 break;
76da6bbe 3275
90e01f86
ILT
3276 case EF_ARM_VFP_FLOAT:
3277 strcat (buf, ", VFP");
3278 break;
3279
fde78edd
NC
3280 case EF_ARM_MAVERICK_FLOAT:
3281 strcat (buf, ", Maverick FP");
3282 break;
3283
f3485b74 3284 default:
015dc7e1 3285 unknown = true;
f3485b74
NC
3286 break;
3287 }
3288 }
3289 }
f3485b74
NC
3290
3291 if (unknown)
2b692964 3292 strcat (buf,_(", <unknown>"));
f3485b74
NC
3293}
3294
343433df
AB
3295static void
3296decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3297{
3298 --size; /* Leave space for null terminator. */
3299
3300 switch (e_flags & EF_AVR_MACH)
3301 {
3302 case E_AVR_MACH_AVR1:
3303 strncat (buf, ", avr:1", size);
3304 break;
3305 case E_AVR_MACH_AVR2:
3306 strncat (buf, ", avr:2", size);
3307 break;
3308 case E_AVR_MACH_AVR25:
3309 strncat (buf, ", avr:25", size);
3310 break;
3311 case E_AVR_MACH_AVR3:
3312 strncat (buf, ", avr:3", size);
3313 break;
3314 case E_AVR_MACH_AVR31:
3315 strncat (buf, ", avr:31", size);
3316 break;
3317 case E_AVR_MACH_AVR35:
3318 strncat (buf, ", avr:35", size);
3319 break;
3320 case E_AVR_MACH_AVR4:
3321 strncat (buf, ", avr:4", size);
3322 break;
3323 case E_AVR_MACH_AVR5:
3324 strncat (buf, ", avr:5", size);
3325 break;
3326 case E_AVR_MACH_AVR51:
3327 strncat (buf, ", avr:51", size);
3328 break;
3329 case E_AVR_MACH_AVR6:
3330 strncat (buf, ", avr:6", size);
3331 break;
3332 case E_AVR_MACH_AVRTINY:
3333 strncat (buf, ", avr:100", size);
3334 break;
3335 case E_AVR_MACH_XMEGA1:
3336 strncat (buf, ", avr:101", size);
3337 break;
3338 case E_AVR_MACH_XMEGA2:
3339 strncat (buf, ", avr:102", size);
3340 break;
3341 case E_AVR_MACH_XMEGA3:
3342 strncat (buf, ", avr:103", size);
3343 break;
3344 case E_AVR_MACH_XMEGA4:
3345 strncat (buf, ", avr:104", size);
3346 break;
3347 case E_AVR_MACH_XMEGA5:
3348 strncat (buf, ", avr:105", size);
3349 break;
3350 case E_AVR_MACH_XMEGA6:
3351 strncat (buf, ", avr:106", size);
3352 break;
3353 case E_AVR_MACH_XMEGA7:
3354 strncat (buf, ", avr:107", size);
3355 break;
3356 default:
3357 strncat (buf, ", avr:<unknown>", size);
3358 break;
3359 }
3360
3361 size -= strlen (buf);
3362 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3363 strncat (buf, ", link-relax", size);
3364}
3365
35c08157
KLC
3366static void
3367decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3368{
3369 unsigned abi;
3370 unsigned arch;
3371 unsigned config;
3372 unsigned version;
015dc7e1 3373 bool has_fpu = false;
32ec8896 3374 unsigned int r = 0;
35c08157
KLC
3375
3376 static const char *ABI_STRINGS[] =
3377 {
3378 "ABI v0", /* use r5 as return register; only used in N1213HC */
3379 "ABI v1", /* use r0 as return register */
3380 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3381 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3382 "AABI",
3383 "ABI2 FP+"
35c08157
KLC
3384 };
3385 static const char *VER_STRINGS[] =
3386 {
3387 "Andes ELF V1.3 or older",
3388 "Andes ELF V1.3.1",
3389 "Andes ELF V1.4"
3390 };
3391 static const char *ARCH_STRINGS[] =
3392 {
3393 "",
3394 "Andes Star v1.0",
3395 "Andes Star v2.0",
3396 "Andes Star v3.0",
3397 "Andes Star v3.0m"
3398 };
3399
3400 abi = EF_NDS_ABI & e_flags;
3401 arch = EF_NDS_ARCH & e_flags;
3402 config = EF_NDS_INST & e_flags;
3403 version = EF_NDS32_ELF_VERSION & e_flags;
3404
3405 memset (buf, 0, size);
3406
3407 switch (abi)
3408 {
3409 case E_NDS_ABI_V0:
3410 case E_NDS_ABI_V1:
3411 case E_NDS_ABI_V2:
3412 case E_NDS_ABI_V2FP:
3413 case E_NDS_ABI_AABI:
40c7a7cb 3414 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3415 /* In case there are holes in the array. */
3416 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3417 break;
3418
3419 default:
3420 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3421 break;
3422 }
3423
3424 switch (version)
3425 {
3426 case E_NDS32_ELF_VER_1_2:
3427 case E_NDS32_ELF_VER_1_3:
3428 case E_NDS32_ELF_VER_1_4:
3429 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3430 break;
3431
3432 default:
3433 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3434 break;
3435 }
3436
3437 if (E_NDS_ABI_V0 == abi)
3438 {
3439 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3440 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3441 if (arch == E_NDS_ARCH_STAR_V1_0)
3442 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3443 return;
3444 }
3445
3446 switch (arch)
3447 {
3448 case E_NDS_ARCH_STAR_V1_0:
3449 case E_NDS_ARCH_STAR_V2_0:
3450 case E_NDS_ARCH_STAR_V3_0:
3451 case E_NDS_ARCH_STAR_V3_M:
3452 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3453 break;
3454
3455 default:
3456 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3457 /* ARCH version determines how the e_flags are interpreted.
3458 If it is unknown, we cannot proceed. */
3459 return;
3460 }
3461
3462 /* Newer ABI; Now handle architecture specific flags. */
3463 if (arch == E_NDS_ARCH_STAR_V1_0)
3464 {
3465 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3466 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3467
3468 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3469 r += snprintf (buf + r, size -r, ", MAC");
3470
3471 if (config & E_NDS32_HAS_DIV_INST)
3472 r += snprintf (buf + r, size -r, ", DIV");
3473
3474 if (config & E_NDS32_HAS_16BIT_INST)
3475 r += snprintf (buf + r, size -r, ", 16b");
3476 }
3477 else
3478 {
3479 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3480 {
3481 if (version <= E_NDS32_ELF_VER_1_3)
3482 r += snprintf (buf + r, size -r, ", [B8]");
3483 else
3484 r += snprintf (buf + r, size -r, ", EX9");
3485 }
3486
3487 if (config & E_NDS32_HAS_MAC_DX_INST)
3488 r += snprintf (buf + r, size -r, ", MAC_DX");
3489
3490 if (config & E_NDS32_HAS_DIV_DX_INST)
3491 r += snprintf (buf + r, size -r, ", DIV_DX");
3492
3493 if (config & E_NDS32_HAS_16BIT_INST)
3494 {
3495 if (version <= E_NDS32_ELF_VER_1_3)
3496 r += snprintf (buf + r, size -r, ", 16b");
3497 else
3498 r += snprintf (buf + r, size -r, ", IFC");
3499 }
3500 }
3501
3502 if (config & E_NDS32_HAS_EXT_INST)
3503 r += snprintf (buf + r, size -r, ", PERF1");
3504
3505 if (config & E_NDS32_HAS_EXT2_INST)
3506 r += snprintf (buf + r, size -r, ", PERF2");
3507
3508 if (config & E_NDS32_HAS_FPU_INST)
3509 {
015dc7e1 3510 has_fpu = true;
35c08157
KLC
3511 r += snprintf (buf + r, size -r, ", FPU_SP");
3512 }
3513
3514 if (config & E_NDS32_HAS_FPU_DP_INST)
3515 {
015dc7e1 3516 has_fpu = true;
35c08157
KLC
3517 r += snprintf (buf + r, size -r, ", FPU_DP");
3518 }
3519
3520 if (config & E_NDS32_HAS_FPU_MAC_INST)
3521 {
015dc7e1 3522 has_fpu = true;
35c08157
KLC
3523 r += snprintf (buf + r, size -r, ", FPU_MAC");
3524 }
3525
3526 if (has_fpu)
3527 {
3528 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3529 {
3530 case E_NDS32_FPU_REG_8SP_4DP:
3531 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3532 break;
3533 case E_NDS32_FPU_REG_16SP_8DP:
3534 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3535 break;
3536 case E_NDS32_FPU_REG_32SP_16DP:
3537 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3538 break;
3539 case E_NDS32_FPU_REG_32SP_32DP:
3540 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3541 break;
3542 }
3543 }
3544
3545 if (config & E_NDS32_HAS_AUDIO_INST)
3546 r += snprintf (buf + r, size -r, ", AUDIO");
3547
3548 if (config & E_NDS32_HAS_STRING_INST)
3549 r += snprintf (buf + r, size -r, ", STR");
3550
3551 if (config & E_NDS32_HAS_REDUCED_REGS)
3552 r += snprintf (buf + r, size -r, ", 16REG");
3553
3554 if (config & E_NDS32_HAS_VIDEO_INST)
3555 {
3556 if (version <= E_NDS32_ELF_VER_1_3)
3557 r += snprintf (buf + r, size -r, ", VIDEO");
3558 else
3559 r += snprintf (buf + r, size -r, ", SATURATION");
3560 }
3561
3562 if (config & E_NDS32_HAS_ENCRIPT_INST)
3563 r += snprintf (buf + r, size -r, ", ENCRP");
3564
3565 if (config & E_NDS32_HAS_L2C_INST)
3566 r += snprintf (buf + r, size -r, ", L2C");
3567}
3568
c077c580
SM
3569static void
3570decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3571 char *buf)
3572{
3573 unsigned char *e_ident = filedata->file_header.e_ident;
3574 unsigned char osabi = e_ident[EI_OSABI];
3575 unsigned char abiversion = e_ident[EI_ABIVERSION];
3576 unsigned int mach;
3577
3578 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3579 it has been deprecated for a while.
3580
3581 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3582 of writing, they use the same flags as HSA v3, so the code below uses that
3583 assumption. */
3584 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3585 return;
3586
3587 mach = e_flags & EF_AMDGPU_MACH;
3588 switch (mach)
3589 {
3590#define AMDGPU_CASE(code, string) \
3591 case code: strcat (buf, ", " string); break;
3592 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3593 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3594 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3595 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3596 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3597 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3598 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3599 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3600 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3601 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3602 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3603 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3604 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3605 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3606 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3607 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3608 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3609 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3610 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3611 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3612 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3613 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3614 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3615 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3616 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3617 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3618 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3619 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3620 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3621 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3622 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3623 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3624 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3625 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3626 default:
3627 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3628 break;
3629#undef AMDGPU_CASE
3630 }
3631
3632 buf += strlen (buf);
3633 e_flags &= ~EF_AMDGPU_MACH;
3634
3635 if ((osabi == ELFOSABI_AMDGPU_HSA
3636 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3637 || osabi != ELFOSABI_AMDGPU_HSA)
3638 {
3639 /* For HSA v3 and other OS ABIs. */
3640 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3641 {
3642 strcat (buf, ", xnack on");
3643 buf += strlen (buf);
3644 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3645 }
3646
3647 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3648 {
3649 strcat (buf, ", sramecc on");
3650 buf += strlen (buf);
3651 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3652 }
3653 }
3654 else
3655 {
3656 /* For HSA v4+. */
3657 int xnack, sramecc;
3658
3659 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3660 switch (xnack)
3661 {
3662 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3663 break;
3664
3665 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3666 strcat (buf, ", xnack any");
3667 break;
3668
3669 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3670 strcat (buf, ", xnack off");
3671 break;
3672
3673 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3674 strcat (buf, ", xnack on");
3675 break;
3676
3677 default:
3678 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3679 break;
3680 }
3681
3682 buf += strlen (buf);
3683 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3684
3685 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3686 switch (sramecc)
3687 {
3688 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3689 break;
3690
3691 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3692 strcat (buf, ", sramecc any");
3693 break;
3694
3695 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3696 strcat (buf, ", sramecc off");
3697 break;
3698
3699 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3700 strcat (buf, ", sramecc on");
3701 break;
3702
3703 default:
3704 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3705 break;
3706 }
3707
3708 buf += strlen (buf);
3709 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3710 }
3711
3712 if (e_flags != 0)
3713 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3714}
3715
252b5132 3716static char *
dda8d76d 3717get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3718{
b34976b6 3719 static char buf[1024];
252b5132
RH
3720
3721 buf[0] = '\0';
76da6bbe 3722
252b5132
RH
3723 if (e_flags)
3724 {
3725 switch (e_machine)
3726 {
3727 default:
3728 break;
3729
886a2506 3730 case EM_ARC_COMPACT2:
886a2506 3731 case EM_ARC_COMPACT:
a9522a21
AB
3732 decode_ARC_machine_flags (e_flags, e_machine, buf);
3733 break;
886a2506 3734
f3485b74
NC
3735 case EM_ARM:
3736 decode_ARM_machine_flags (e_flags, buf);
3737 break;
76da6bbe 3738
343433df
AB
3739 case EM_AVR:
3740 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3741 break;
3742
781303ce
MF
3743 case EM_BLACKFIN:
3744 if (e_flags & EF_BFIN_PIC)
3745 strcat (buf, ", PIC");
3746
3747 if (e_flags & EF_BFIN_FDPIC)
3748 strcat (buf, ", FDPIC");
3749
3750 if (e_flags & EF_BFIN_CODE_IN_L1)
3751 strcat (buf, ", code in L1");
3752
3753 if (e_flags & EF_BFIN_DATA_IN_L1)
3754 strcat (buf, ", data in L1");
3755
3756 break;
3757
ec2dfb42
AO
3758 case EM_CYGNUS_FRV:
3759 switch (e_flags & EF_FRV_CPU_MASK)
3760 {
3761 case EF_FRV_CPU_GENERIC:
3762 break;
3763
3764 default:
3765 strcat (buf, ", fr???");
3766 break;
57346661 3767
ec2dfb42
AO
3768 case EF_FRV_CPU_FR300:
3769 strcat (buf, ", fr300");
3770 break;
3771
3772 case EF_FRV_CPU_FR400:
3773 strcat (buf, ", fr400");
3774 break;
3775 case EF_FRV_CPU_FR405:
3776 strcat (buf, ", fr405");
3777 break;
3778
3779 case EF_FRV_CPU_FR450:
3780 strcat (buf, ", fr450");
3781 break;
3782
3783 case EF_FRV_CPU_FR500:
3784 strcat (buf, ", fr500");
3785 break;
3786 case EF_FRV_CPU_FR550:
3787 strcat (buf, ", fr550");
3788 break;
3789
3790 case EF_FRV_CPU_SIMPLE:
3791 strcat (buf, ", simple");
3792 break;
3793 case EF_FRV_CPU_TOMCAT:
3794 strcat (buf, ", tomcat");
3795 break;
3796 }
1c877e87 3797 break;
ec2dfb42 3798
53c7db4b 3799 case EM_68K:
425c6cb0 3800 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3801 strcat (buf, ", m68000");
425c6cb0 3802 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3803 strcat (buf, ", cpu32");
3804 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3805 strcat (buf, ", fido_a");
425c6cb0 3806 else
266abb8f 3807 {
2cf0635d
NC
3808 char const * isa = _("unknown");
3809 char const * mac = _("unknown mac");
3810 char const * additional = NULL;
0112cd26 3811
c694fd50 3812 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3813 {
c694fd50 3814 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3815 isa = "A";
3816 additional = ", nodiv";
3817 break;
c694fd50 3818 case EF_M68K_CF_ISA_A:
266abb8f
NS
3819 isa = "A";
3820 break;
c694fd50 3821 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3822 isa = "A+";
3823 break;
c694fd50 3824 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3825 isa = "B";
3826 additional = ", nousp";
3827 break;
c694fd50 3828 case EF_M68K_CF_ISA_B:
266abb8f
NS
3829 isa = "B";
3830 break;
f608cd77
NS
3831 case EF_M68K_CF_ISA_C:
3832 isa = "C";
3833 break;
3834 case EF_M68K_CF_ISA_C_NODIV:
3835 isa = "C";
3836 additional = ", nodiv";
3837 break;
266abb8f
NS
3838 }
3839 strcat (buf, ", cf, isa ");
3840 strcat (buf, isa);
0b2e31dc
NS
3841 if (additional)
3842 strcat (buf, additional);
c694fd50 3843 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3844 strcat (buf, ", float");
c694fd50 3845 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3846 {
3847 case 0:
3848 mac = NULL;
3849 break;
c694fd50 3850 case EF_M68K_CF_MAC:
266abb8f
NS
3851 mac = "mac";
3852 break;
c694fd50 3853 case EF_M68K_CF_EMAC:
266abb8f
NS
3854 mac = "emac";
3855 break;
f608cd77
NS
3856 case EF_M68K_CF_EMAC_B:
3857 mac = "emac_b";
3858 break;
266abb8f
NS
3859 }
3860 if (mac)
3861 {
3862 strcat (buf, ", ");
3863 strcat (buf, mac);
3864 }
266abb8f 3865 }
53c7db4b 3866 break;
33c63f9d 3867
c077c580
SM
3868 case EM_AMDGPU:
3869 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3870 break;
3871
153a2776
NC
3872 case EM_CYGNUS_MEP:
3873 switch (e_flags & EF_MEP_CPU_MASK)
3874 {
3875 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3876 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3877 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3878 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3879 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3880 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3881 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3882 }
3883
3884 switch (e_flags & EF_MEP_COP_MASK)
3885 {
3886 case EF_MEP_COP_NONE: break;
3887 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3888 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3889 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3890 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3891 default: strcat (buf, _("<unknown MeP copro type>")); break;
3892 }
3893
3894 if (e_flags & EF_MEP_LIBRARY)
3895 strcat (buf, ", Built for Library");
3896
3897 if (e_flags & EF_MEP_INDEX_MASK)
3898 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3899 e_flags & EF_MEP_INDEX_MASK);
3900
3901 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3902 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3903 e_flags & ~ EF_MEP_ALL_FLAGS);
3904 break;
3905
252b5132
RH
3906 case EM_PPC:
3907 if (e_flags & EF_PPC_EMB)
3908 strcat (buf, ", emb");
3909
3910 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3911 strcat (buf, _(", relocatable"));
252b5132
RH
3912
3913 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3914 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3915 break;
3916
ee67d69a
AM
3917 case EM_PPC64:
3918 if (e_flags & EF_PPC64_ABI)
3919 {
3920 char abi[] = ", abiv0";
3921
3922 abi[6] += e_flags & EF_PPC64_ABI;
3923 strcat (buf, abi);
3924 }
3925 break;
3926
708e2187
NC
3927 case EM_V800:
3928 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3929 strcat (buf, ", RH850 ABI");
0b4362b0 3930
708e2187
NC
3931 if (e_flags & EF_V800_850E3)
3932 strcat (buf, ", V3 architecture");
3933
3934 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3935 strcat (buf, ", FPU not used");
3936
3937 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3938 strcat (buf, ", regmode: COMMON");
3939
3940 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3941 strcat (buf, ", r4 not used");
3942
3943 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3944 strcat (buf, ", r30 not used");
3945
3946 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3947 strcat (buf, ", r5 not used");
3948
3949 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3950 strcat (buf, ", r2 not used");
3951
3952 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3953 {
3954 switch (e_flags & - e_flags)
3955 {
3956 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3957 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3958 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3959 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3960 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3961 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3962 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3963 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3964 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3965 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3966 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3967 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3968 default: break;
3969 }
3970 }
3971 break;
3972
2b0337b0 3973 case EM_V850:
252b5132
RH
3974 case EM_CYGNUS_V850:
3975 switch (e_flags & EF_V850_ARCH)
3976 {
78c8d46c
NC
3977 case E_V850E3V5_ARCH:
3978 strcat (buf, ", v850e3v5");
3979 break;
1cd986c5
NC
3980 case E_V850E2V3_ARCH:
3981 strcat (buf, ", v850e2v3");
3982 break;
3983 case E_V850E2_ARCH:
3984 strcat (buf, ", v850e2");
3985 break;
3986 case E_V850E1_ARCH:
3987 strcat (buf, ", v850e1");
8ad30312 3988 break;
252b5132
RH
3989 case E_V850E_ARCH:
3990 strcat (buf, ", v850e");
3991 break;
252b5132
RH
3992 case E_V850_ARCH:
3993 strcat (buf, ", v850");
3994 break;
3995 default:
2b692964 3996 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3997 break;
3998 }
3999 break;
4000
2b0337b0 4001 case EM_M32R:
252b5132
RH
4002 case EM_CYGNUS_M32R:
4003 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4004 strcat (buf, ", m32r");
252b5132
RH
4005 break;
4006
4007 case EM_MIPS:
4fe85591 4008 case EM_MIPS_RS3_LE:
252b5132
RH
4009 if (e_flags & EF_MIPS_NOREORDER)
4010 strcat (buf, ", noreorder");
4011
4012 if (e_flags & EF_MIPS_PIC)
4013 strcat (buf, ", pic");
4014
4015 if (e_flags & EF_MIPS_CPIC)
4016 strcat (buf, ", cpic");
4017
d1bdd336
TS
4018 if (e_flags & EF_MIPS_UCODE)
4019 strcat (buf, ", ugen_reserved");
4020
252b5132
RH
4021 if (e_flags & EF_MIPS_ABI2)
4022 strcat (buf, ", abi2");
4023
43521d43
TS
4024 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4025 strcat (buf, ", odk first");
4026
a5d22d2a
TS
4027 if (e_flags & EF_MIPS_32BITMODE)
4028 strcat (buf, ", 32bitmode");
4029
ba92f887
MR
4030 if (e_flags & EF_MIPS_NAN2008)
4031 strcat (buf, ", nan2008");
4032
fef1b0b3
SE
4033 if (e_flags & EF_MIPS_FP64)
4034 strcat (buf, ", fp64");
4035
156c2f8b
NC
4036 switch ((e_flags & EF_MIPS_MACH))
4037 {
4038 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
4039 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
4040 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 4041 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
4042 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
4043 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
4044 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
4045 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 4046 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 4047 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 4048 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4049 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4050 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4051 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4052 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4053 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4054 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4055 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4056 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4057 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4058 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4059 case 0:
4060 /* We simply ignore the field in this case to avoid confusion:
4061 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4062 extension. */
4063 break;
2b692964 4064 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4065 }
43521d43
TS
4066
4067 switch ((e_flags & EF_MIPS_ABI))
4068 {
4069 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4070 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4071 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4072 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4073 case 0:
4074 /* We simply ignore the field in this case to avoid confusion:
4075 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4076 This means it is likely to be an o32 file, but not for
4077 sure. */
4078 break;
2b692964 4079 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4080 }
4081
4082 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4083 strcat (buf, ", mdmx");
4084
4085 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4086 strcat (buf, ", mips16");
4087
df58fc94
RS
4088 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4089 strcat (buf, ", micromips");
4090
43521d43
TS
4091 switch ((e_flags & EF_MIPS_ARCH))
4092 {
4093 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4094 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4095 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4096 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4097 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4098 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4099 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4100 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4101 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4102 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4103 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4104 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4105 }
252b5132 4106 break;
351b4b40 4107
35c08157
KLC
4108 case EM_NDS32:
4109 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4110 break;
4111
fe944acf
FT
4112 case EM_NFP:
4113 switch (EF_NFP_MACH (e_flags))
4114 {
4115 case E_NFP_MACH_3200:
4116 strcat (buf, ", NFP-32xx");
4117 break;
4118 case E_NFP_MACH_6000:
4119 strcat (buf, ", NFP-6xxx");
4120 break;
4121 }
4122 break;
4123
e23eba97
NC
4124 case EM_RISCV:
4125 if (e_flags & EF_RISCV_RVC)
4126 strcat (buf, ", RVC");
2922d21d 4127
7f999549
JW
4128 if (e_flags & EF_RISCV_RVE)
4129 strcat (buf, ", RVE");
4130
2922d21d
AW
4131 switch (e_flags & EF_RISCV_FLOAT_ABI)
4132 {
4133 case EF_RISCV_FLOAT_ABI_SOFT:
4134 strcat (buf, ", soft-float ABI");
4135 break;
4136
4137 case EF_RISCV_FLOAT_ABI_SINGLE:
4138 strcat (buf, ", single-float ABI");
4139 break;
4140
4141 case EF_RISCV_FLOAT_ABI_DOUBLE:
4142 strcat (buf, ", double-float ABI");
4143 break;
4144
4145 case EF_RISCV_FLOAT_ABI_QUAD:
4146 strcat (buf, ", quad-float ABI");
4147 break;
4148 }
e23eba97
NC
4149 break;
4150
ccde1100
AO
4151 case EM_SH:
4152 switch ((e_flags & EF_SH_MACH_MASK))
4153 {
4154 case EF_SH1: strcat (buf, ", sh1"); break;
4155 case EF_SH2: strcat (buf, ", sh2"); break;
4156 case EF_SH3: strcat (buf, ", sh3"); break;
4157 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4158 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4159 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4160 case EF_SH3E: strcat (buf, ", sh3e"); break;
4161 case EF_SH4: strcat (buf, ", sh4"); break;
4162 case EF_SH5: strcat (buf, ", sh5"); break;
4163 case EF_SH2E: strcat (buf, ", sh2e"); break;
4164 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4165 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4166 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4167 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4168 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4169 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4170 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4171 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4172 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4173 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4174 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4175 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4176 }
4177
cec6a5b8
MR
4178 if (e_flags & EF_SH_PIC)
4179 strcat (buf, ", pic");
4180
4181 if (e_flags & EF_SH_FDPIC)
4182 strcat (buf, ", fdpic");
ccde1100 4183 break;
948f632f 4184
73589c9d
CS
4185 case EM_OR1K:
4186 if (e_flags & EF_OR1K_NODELAY)
4187 strcat (buf, ", no delay");
4188 break;
57346661 4189
351b4b40
RH
4190 case EM_SPARCV9:
4191 if (e_flags & EF_SPARC_32PLUS)
4192 strcat (buf, ", v8+");
4193
4194 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4195 strcat (buf, ", ultrasparcI");
4196
4197 if (e_flags & EF_SPARC_SUN_US3)
4198 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4199
4200 if (e_flags & EF_SPARC_HAL_R1)
4201 strcat (buf, ", halr1");
4202
4203 if (e_flags & EF_SPARC_LEDATA)
4204 strcat (buf, ", ledata");
4205
4206 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4207 strcat (buf, ", tso");
4208
4209 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4210 strcat (buf, ", pso");
4211
4212 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4213 strcat (buf, ", rmo");
4214 break;
7d466069 4215
103f02d3
UD
4216 case EM_PARISC:
4217 switch (e_flags & EF_PARISC_ARCH)
4218 {
4219 case EFA_PARISC_1_0:
4220 strcpy (buf, ", PA-RISC 1.0");
4221 break;
4222 case EFA_PARISC_1_1:
4223 strcpy (buf, ", PA-RISC 1.1");
4224 break;
4225 case EFA_PARISC_2_0:
4226 strcpy (buf, ", PA-RISC 2.0");
4227 break;
4228 default:
4229 break;
4230 }
4231 if (e_flags & EF_PARISC_TRAPNIL)
4232 strcat (buf, ", trapnil");
4233 if (e_flags & EF_PARISC_EXT)
4234 strcat (buf, ", ext");
4235 if (e_flags & EF_PARISC_LSB)
4236 strcat (buf, ", lsb");
4237 if (e_flags & EF_PARISC_WIDE)
4238 strcat (buf, ", wide");
4239 if (e_flags & EF_PARISC_NO_KABP)
4240 strcat (buf, ", no kabp");
4241 if (e_flags & EF_PARISC_LAZYSWAP)
4242 strcat (buf, ", lazyswap");
30800947 4243 break;
76da6bbe 4244
7d466069 4245 case EM_PJ:
2b0337b0 4246 case EM_PJ_OLD:
7d466069
ILT
4247 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4248 strcat (buf, ", new calling convention");
4249
4250 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4251 strcat (buf, ", gnu calling convention");
4252 break;
4d6ed7c8
NC
4253
4254 case EM_IA_64:
4255 if ((e_flags & EF_IA_64_ABI64))
4256 strcat (buf, ", 64-bit");
4257 else
4258 strcat (buf, ", 32-bit");
4259 if ((e_flags & EF_IA_64_REDUCEDFP))
4260 strcat (buf, ", reduced fp model");
4261 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4262 strcat (buf, ", no function descriptors, constant gp");
4263 else if ((e_flags & EF_IA_64_CONS_GP))
4264 strcat (buf, ", constant gp");
4265 if ((e_flags & EF_IA_64_ABSOLUTE))
4266 strcat (buf, ", absolute");
dda8d76d 4267 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4268 {
4269 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4270 strcat (buf, ", vms_linkages");
4271 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4272 {
4273 case EF_IA_64_VMS_COMCOD_SUCCESS:
4274 break;
4275 case EF_IA_64_VMS_COMCOD_WARNING:
4276 strcat (buf, ", warning");
4277 break;
4278 case EF_IA_64_VMS_COMCOD_ERROR:
4279 strcat (buf, ", error");
4280 break;
4281 case EF_IA_64_VMS_COMCOD_ABORT:
4282 strcat (buf, ", abort");
4283 break;
4284 default:
bee0ee85
NC
4285 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4286 e_flags & EF_IA_64_VMS_COMCOD);
4287 strcat (buf, ", <unknown>");
28f997cf
TG
4288 }
4289 }
4d6ed7c8 4290 break;
179d3252
JT
4291
4292 case EM_VAX:
4293 if ((e_flags & EF_VAX_NONPIC))
4294 strcat (buf, ", non-PIC");
4295 if ((e_flags & EF_VAX_DFLOAT))
4296 strcat (buf, ", D-Float");
4297 if ((e_flags & EF_VAX_GFLOAT))
4298 strcat (buf, ", G-Float");
4299 break;
c7927a3c 4300
619ed720
EB
4301 case EM_VISIUM:
4302 if (e_flags & EF_VISIUM_ARCH_MCM)
4303 strcat (buf, ", mcm");
4304 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4305 strcat (buf, ", mcm24");
4306 if (e_flags & EF_VISIUM_ARCH_GR6)
4307 strcat (buf, ", gr6");
4308 break;
4309
4046d87a 4310 case EM_RL78:
1740ba0c
NC
4311 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4312 {
4313 case E_FLAG_RL78_ANY_CPU: break;
4314 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4315 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4316 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4317 }
856ea05c
KP
4318 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4319 strcat (buf, ", 64-bit doubles");
4046d87a 4320 break;
0b4362b0 4321
c7927a3c
NC
4322 case EM_RX:
4323 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4324 strcat (buf, ", 64-bit doubles");
4325 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4326 strcat (buf, ", dsp");
d4cb0ea0 4327 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4328 strcat (buf, ", pid");
708e2187
NC
4329 if (e_flags & E_FLAG_RX_ABI)
4330 strcat (buf, ", RX ABI");
3525236c
NC
4331 if (e_flags & E_FLAG_RX_SINSNS_SET)
4332 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4333 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4334 if (e_flags & E_FLAG_RX_V2)
4335 strcat (buf, ", V2");
f87673e0
YS
4336 if (e_flags & E_FLAG_RX_V3)
4337 strcat (buf, ", V3");
d4cb0ea0 4338 break;
55786da2
AK
4339
4340 case EM_S390:
4341 if (e_flags & EF_S390_HIGH_GPRS)
4342 strcat (buf, ", highgprs");
d4cb0ea0 4343 break;
40b36596
JM
4344
4345 case EM_TI_C6000:
4346 if ((e_flags & EF_C6000_REL))
4347 strcat (buf, ", relocatable module");
d4cb0ea0 4348 break;
13761a11
NC
4349
4350 case EM_MSP430:
4351 strcat (buf, _(": architecture variant: "));
4352 switch (e_flags & EF_MSP430_MACH)
4353 {
4354 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4355 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4356 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4357 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4358 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4359 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4360 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4361 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4362 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4363 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4364 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4365 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4366 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4367 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4368 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4369 default:
4370 strcat (buf, _(": unknown")); break;
4371 }
4372
4373 if (e_flags & ~ EF_MSP430_MACH)
4374 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4375 break;
4376
4377 case EM_Z80:
4378 switch (e_flags & EF_Z80_MACH_MSK)
4379 {
4380 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4381 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4382 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4383 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4384 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4385 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4386 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4387 default:
4388 strcat (buf, _(", unknown")); break;
4389 }
4390 break;
e9a0721f 4391 case EM_LOONGARCH:
4392 if (EF_LOONGARCH_IS_LP64 (e_flags))
4393 strcat (buf, ", LP64");
4394 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4395 strcat (buf, ", ILP32");
4396
4397 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4398 strcat (buf, ", SOFT-FLOAT");
4399 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4400 strcat (buf, ", SINGLE-FLOAT");
4401 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4402 strcat (buf, ", DOUBLE-FLOAT");
4403
4404 break;
252b5132
RH
4405 }
4406 }
4407
4408 return buf;
4409}
4410
252b5132 4411static const char *
dda8d76d 4412get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4413{
4414 static char buff[32];
4415
4416 switch (osabi)
4417 {
4418 case ELFOSABI_NONE: return "UNIX - System V";
4419 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4420 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4421 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4422 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4423 case ELFOSABI_AIX: return "UNIX - AIX";
4424 case ELFOSABI_IRIX: return "UNIX - IRIX";
4425 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4426 case ELFOSABI_TRU64: return "UNIX - TRU64";
4427 case ELFOSABI_MODESTO: return "Novell - Modesto";
4428 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4429 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4430 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4431 case ELFOSABI_AROS: return "AROS";
11636f9e 4432 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4433 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4434 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4435 default:
40b36596 4436 if (osabi >= 64)
dda8d76d 4437 switch (filedata->file_header.e_machine)
40b36596 4438 {
37870be8
SM
4439 case EM_AMDGPU:
4440 switch (osabi)
4441 {
4442 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4443 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4444 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4445 default:
4446 break;
4447 }
4448 break;
4449
40b36596
JM
4450 case EM_ARM:
4451 switch (osabi)
4452 {
4453 case ELFOSABI_ARM: return "ARM";
18a20338 4454 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4455 default:
4456 break;
4457 }
4458 break;
4459
4460 case EM_MSP430:
4461 case EM_MSP430_OLD:
619ed720 4462 case EM_VISIUM:
40b36596
JM
4463 switch (osabi)
4464 {
4465 case ELFOSABI_STANDALONE: return _("Standalone App");
4466 default:
4467 break;
4468 }
4469 break;
4470
4471 case EM_TI_C6000:
4472 switch (osabi)
4473 {
4474 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4475 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4476 default:
4477 break;
4478 }
4479 break;
4480
4481 default:
4482 break;
4483 }
e9e44622 4484 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4485 return buff;
4486 }
4487}
4488
a06ea964
NC
4489static const char *
4490get_aarch64_segment_type (unsigned long type)
4491{
4492 switch (type)
4493 {
32ec8896
NC
4494 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4495 default: return NULL;
a06ea964 4496 }
a06ea964
NC
4497}
4498
b294bdf8
MM
4499static const char *
4500get_arm_segment_type (unsigned long type)
4501{
4502 switch (type)
4503 {
32ec8896
NC
4504 case PT_ARM_EXIDX: return "EXIDX";
4505 default: return NULL;
b294bdf8 4506 }
b294bdf8
MM
4507}
4508
b4cbbe8f
AK
4509static const char *
4510get_s390_segment_type (unsigned long type)
4511{
4512 switch (type)
4513 {
4514 case PT_S390_PGSTE: return "S390_PGSTE";
4515 default: return NULL;
4516 }
4517}
4518
d3ba0551
AM
4519static const char *
4520get_mips_segment_type (unsigned long type)
252b5132
RH
4521{
4522 switch (type)
4523 {
32ec8896
NC
4524 case PT_MIPS_REGINFO: return "REGINFO";
4525 case PT_MIPS_RTPROC: return "RTPROC";
4526 case PT_MIPS_OPTIONS: return "OPTIONS";
4527 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4528 default: return NULL;
252b5132 4529 }
252b5132
RH
4530}
4531
103f02d3 4532static const char *
d3ba0551 4533get_parisc_segment_type (unsigned long type)
103f02d3
UD
4534{
4535 switch (type)
4536 {
103f02d3
UD
4537 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4538 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4539 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4540 default: return NULL;
103f02d3 4541 }
103f02d3
UD
4542}
4543
4d6ed7c8 4544static const char *
d3ba0551 4545get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4546{
4547 switch (type)
4548 {
4549 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4550 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4551 default: return NULL;
4d6ed7c8 4552 }
4d6ed7c8
NC
4553}
4554
40b36596
JM
4555static const char *
4556get_tic6x_segment_type (unsigned long type)
4557{
4558 switch (type)
4559 {
32ec8896
NC
4560 case PT_C6000_PHATTR: return "C6000_PHATTR";
4561 default: return NULL;
40b36596 4562 }
40b36596
JM
4563}
4564
fbc95f1e
KC
4565static const char *
4566get_riscv_segment_type (unsigned long type)
4567{
4568 switch (type)
4569 {
4570 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4571 default: return NULL;
4572 }
4573}
4574
df3a023b
AM
4575static const char *
4576get_hpux_segment_type (unsigned long type, unsigned e_machine)
4577{
4578 if (e_machine == EM_PARISC)
4579 switch (type)
4580 {
4581 case PT_HP_TLS: return "HP_TLS";
4582 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4583 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4584 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4585 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4586 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4587 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4588 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4589 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4590 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4591 case PT_HP_PARALLEL: return "HP_PARALLEL";
4592 case PT_HP_FASTBIND: return "HP_FASTBIND";
4593 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4594 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4595 case PT_HP_STACK: return "HP_STACK";
4596 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4597 default: return NULL;
4598 }
4599
4600 if (e_machine == EM_IA_64)
4601 switch (type)
4602 {
4603 case PT_HP_TLS: return "HP_TLS";
4604 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4605 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4606 case PT_IA_64_HP_STACK: return "HP_STACK";
4607 default: return NULL;
4608 }
4609
4610 return NULL;
4611}
4612
5522f910
NC
4613static const char *
4614get_solaris_segment_type (unsigned long type)
4615{
4616 switch (type)
4617 {
4618 case 0x6464e550: return "PT_SUNW_UNWIND";
4619 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4620 case 0x6ffffff7: return "PT_LOSUNW";
4621 case 0x6ffffffa: return "PT_SUNWBSS";
4622 case 0x6ffffffb: return "PT_SUNWSTACK";
4623 case 0x6ffffffc: return "PT_SUNWDTRACE";
4624 case 0x6ffffffd: return "PT_SUNWCAP";
4625 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4626 default: return NULL;
5522f910
NC
4627 }
4628}
4629
252b5132 4630static const char *
dda8d76d 4631get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4632{
b34976b6 4633 static char buff[32];
252b5132
RH
4634
4635 switch (p_type)
4636 {
b34976b6
AM
4637 case PT_NULL: return "NULL";
4638 case PT_LOAD: return "LOAD";
252b5132 4639 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4640 case PT_INTERP: return "INTERP";
4641 case PT_NOTE: return "NOTE";
4642 case PT_SHLIB: return "SHLIB";
4643 case PT_PHDR: return "PHDR";
13ae64f3 4644 case PT_TLS: return "TLS";
32ec8896 4645 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4646 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4647 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4648 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4649
3eba3ef3
NC
4650 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4651 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4652 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4653
252b5132 4654 default:
df3a023b 4655 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4656 {
2cf0635d 4657 const char * result;
103f02d3 4658
dda8d76d 4659 switch (filedata->file_header.e_machine)
252b5132 4660 {
a06ea964
NC
4661 case EM_AARCH64:
4662 result = get_aarch64_segment_type (p_type);
4663 break;
b294bdf8
MM
4664 case EM_ARM:
4665 result = get_arm_segment_type (p_type);
4666 break;
252b5132 4667 case EM_MIPS:
4fe85591 4668 case EM_MIPS_RS3_LE:
252b5132
RH
4669 result = get_mips_segment_type (p_type);
4670 break;
103f02d3
UD
4671 case EM_PARISC:
4672 result = get_parisc_segment_type (p_type);
4673 break;
4d6ed7c8
NC
4674 case EM_IA_64:
4675 result = get_ia64_segment_type (p_type);
4676 break;
40b36596
JM
4677 case EM_TI_C6000:
4678 result = get_tic6x_segment_type (p_type);
4679 break;
b4cbbe8f
AK
4680 case EM_S390:
4681 case EM_S390_OLD:
4682 result = get_s390_segment_type (p_type);
4683 break;
fbc95f1e
KC
4684 case EM_RISCV:
4685 result = get_riscv_segment_type (p_type);
4686 break;
252b5132
RH
4687 default:
4688 result = NULL;
4689 break;
4690 }
103f02d3 4691
252b5132
RH
4692 if (result != NULL)
4693 return result;
103f02d3 4694
1a9ccd70 4695 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4696 }
4697 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4698 {
df3a023b 4699 const char * result = NULL;
103f02d3 4700
df3a023b 4701 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4702 {
df3a023b
AM
4703 case ELFOSABI_GNU:
4704 case ELFOSABI_FREEBSD:
4705 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4706 {
4707 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4708 result = buff;
4709 }
103f02d3 4710 break;
df3a023b
AM
4711 case ELFOSABI_HPUX:
4712 result = get_hpux_segment_type (p_type,
4713 filedata->file_header.e_machine);
4714 break;
4715 case ELFOSABI_SOLARIS:
4716 result = get_solaris_segment_type (p_type);
00428cca 4717 break;
103f02d3 4718 default:
103f02d3
UD
4719 break;
4720 }
103f02d3
UD
4721 if (result != NULL)
4722 return result;
4723
1a9ccd70 4724 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4725 }
252b5132 4726 else
e9e44622 4727 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4728
4729 return buff;
4730 }
4731}
4732
53a346d8
CZ
4733static const char *
4734get_arc_section_type_name (unsigned int sh_type)
4735{
4736 switch (sh_type)
4737 {
4738 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4739 default:
4740 break;
4741 }
4742 return NULL;
4743}
4744
252b5132 4745static const char *
d3ba0551 4746get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4747{
4748 switch (sh_type)
4749 {
b34976b6
AM
4750 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4751 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4752 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4753 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4754 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4755 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4756 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4757 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4758 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4759 case SHT_MIPS_RELD: return "MIPS_RELD";
4760 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4761 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4762 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4763 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4764 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4765 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4766 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4767 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4768 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4769 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4770 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4771 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4772 case SHT_MIPS_LINE: return "MIPS_LINE";
4773 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4774 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4775 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4776 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4777 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4778 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4779 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4780 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4781 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4782 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4783 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4784 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4785 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4786 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4787 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4788 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4789 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4790 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4791 default:
4792 break;
4793 }
4794 return NULL;
4795}
4796
103f02d3 4797static const char *
d3ba0551 4798get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4799{
4800 switch (sh_type)
4801 {
4802 case SHT_PARISC_EXT: return "PARISC_EXT";
4803 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4804 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4805 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4806 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4807 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4808 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4809 default: return NULL;
103f02d3 4810 }
103f02d3
UD
4811}
4812
4d6ed7c8 4813static const char *
dda8d76d 4814get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4815{
18bd398b 4816 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4817 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4818 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4819
4d6ed7c8
NC
4820 switch (sh_type)
4821 {
148b93f2
NC
4822 case SHT_IA_64_EXT: return "IA_64_EXT";
4823 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4824 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4825 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4826 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4827 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4828 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4829 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4830 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4831 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4832 default:
4833 break;
4834 }
4835 return NULL;
4836}
4837
d2b2c203
DJ
4838static const char *
4839get_x86_64_section_type_name (unsigned int sh_type)
4840{
4841 switch (sh_type)
4842 {
4843 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4844 default: return NULL;
d2b2c203 4845 }
d2b2c203
DJ
4846}
4847
a06ea964
NC
4848static const char *
4849get_aarch64_section_type_name (unsigned int sh_type)
4850{
4851 switch (sh_type)
4852 {
32ec8896
NC
4853 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4854 default: return NULL;
a06ea964 4855 }
a06ea964
NC
4856}
4857
40a18ebd
NC
4858static const char *
4859get_arm_section_type_name (unsigned int sh_type)
4860{
4861 switch (sh_type)
4862 {
7f6fed87
NC
4863 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4864 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4865 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4866 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4867 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4868 default: return NULL;
40a18ebd 4869 }
40a18ebd
NC
4870}
4871
40b36596
JM
4872static const char *
4873get_tic6x_section_type_name (unsigned int sh_type)
4874{
4875 switch (sh_type)
4876 {
32ec8896
NC
4877 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4878 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4879 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4880 case SHT_TI_ICODE: return "TI_ICODE";
4881 case SHT_TI_XREF: return "TI_XREF";
4882 case SHT_TI_HANDLER: return "TI_HANDLER";
4883 case SHT_TI_INITINFO: return "TI_INITINFO";
4884 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4885 default: return NULL;
40b36596 4886 }
40b36596
JM
4887}
4888
13761a11 4889static const char *
b0191216 4890get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4891{
4892 switch (sh_type)
4893 {
32ec8896
NC
4894 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4895 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4896 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4897 default: return NULL;
13761a11
NC
4898 }
4899}
4900
fe944acf
FT
4901static const char *
4902get_nfp_section_type_name (unsigned int sh_type)
4903{
4904 switch (sh_type)
4905 {
4906 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4907 case SHT_NFP_INITREG: return "NFP_INITREG";
4908 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4909 default: return NULL;
4910 }
4911}
4912
685080f2
NC
4913static const char *
4914get_v850_section_type_name (unsigned int sh_type)
4915{
4916 switch (sh_type)
4917 {
32ec8896
NC
4918 case SHT_V850_SCOMMON: return "V850 Small Common";
4919 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4920 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4921 case SHT_RENESAS_IOP: return "RENESAS IOP";
4922 case SHT_RENESAS_INFO: return "RENESAS INFO";
4923 default: return NULL;
685080f2
NC
4924 }
4925}
4926
2dc8dd17
JW
4927static const char *
4928get_riscv_section_type_name (unsigned int sh_type)
4929{
4930 switch (sh_type)
4931 {
4932 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4933 default: return NULL;
4934 }
4935}
4936
0861f561
CQ
4937static const char *
4938get_csky_section_type_name (unsigned int sh_type)
4939{
4940 switch (sh_type)
4941 {
4942 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4943 default: return NULL;
4944 }
4945}
4946
252b5132 4947static const char *
dda8d76d 4948get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4949{
b34976b6 4950 static char buff[32];
9fb71ee4 4951 const char * result;
252b5132
RH
4952
4953 switch (sh_type)
4954 {
4955 case SHT_NULL: return "NULL";
4956 case SHT_PROGBITS: return "PROGBITS";
4957 case SHT_SYMTAB: return "SYMTAB";
4958 case SHT_STRTAB: return "STRTAB";
4959 case SHT_RELA: return "RELA";
dd207c13 4960 case SHT_RELR: return "RELR";
252b5132
RH
4961 case SHT_HASH: return "HASH";
4962 case SHT_DYNAMIC: return "DYNAMIC";
4963 case SHT_NOTE: return "NOTE";
4964 case SHT_NOBITS: return "NOBITS";
4965 case SHT_REL: return "REL";
4966 case SHT_SHLIB: return "SHLIB";
4967 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4968 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4969 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4970 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4971 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4972 case SHT_GROUP: return "GROUP";
67ce483b 4973 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4974 case SHT_GNU_verdef: return "VERDEF";
4975 case SHT_GNU_verneed: return "VERNEED";
4976 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4977 case 0x6ffffff0: return "VERSYM";
4978 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4979 case 0x7ffffffd: return "AUXILIARY";
4980 case 0x7fffffff: return "FILTER";
047b2264 4981 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4982
4983 default:
4984 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4985 {
dda8d76d 4986 switch (filedata->file_header.e_machine)
252b5132 4987 {
53a346d8
CZ
4988 case EM_ARC:
4989 case EM_ARC_COMPACT:
4990 case EM_ARC_COMPACT2:
4991 result = get_arc_section_type_name (sh_type);
4992 break;
252b5132 4993 case EM_MIPS:
4fe85591 4994 case EM_MIPS_RS3_LE:
252b5132
RH
4995 result = get_mips_section_type_name (sh_type);
4996 break;
103f02d3
UD
4997 case EM_PARISC:
4998 result = get_parisc_section_type_name (sh_type);
4999 break;
4d6ed7c8 5000 case EM_IA_64:
dda8d76d 5001 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5002 break;
d2b2c203 5003 case EM_X86_64:
8a9036a4 5004 case EM_L1OM:
7a9068fe 5005 case EM_K1OM:
d2b2c203
DJ
5006 result = get_x86_64_section_type_name (sh_type);
5007 break;
a06ea964
NC
5008 case EM_AARCH64:
5009 result = get_aarch64_section_type_name (sh_type);
5010 break;
40a18ebd
NC
5011 case EM_ARM:
5012 result = get_arm_section_type_name (sh_type);
5013 break;
40b36596
JM
5014 case EM_TI_C6000:
5015 result = get_tic6x_section_type_name (sh_type);
5016 break;
13761a11 5017 case EM_MSP430:
b0191216 5018 result = get_msp430_section_type_name (sh_type);
13761a11 5019 break;
fe944acf
FT
5020 case EM_NFP:
5021 result = get_nfp_section_type_name (sh_type);
5022 break;
685080f2
NC
5023 case EM_V800:
5024 case EM_V850:
5025 case EM_CYGNUS_V850:
5026 result = get_v850_section_type_name (sh_type);
5027 break;
2dc8dd17
JW
5028 case EM_RISCV:
5029 result = get_riscv_section_type_name (sh_type);
5030 break;
0861f561
CQ
5031 case EM_CSKY:
5032 result = get_csky_section_type_name (sh_type);
5033 break;
252b5132
RH
5034 default:
5035 result = NULL;
5036 break;
5037 }
5038
5039 if (result != NULL)
5040 return result;
5041
9fb71ee4 5042 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5043 }
5044 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5045 {
dda8d76d 5046 switch (filedata->file_header.e_machine)
148b93f2
NC
5047 {
5048 case EM_IA_64:
dda8d76d 5049 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5050 break;
5051 default:
dda8d76d 5052 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5053 result = get_solaris_section_type (sh_type);
5054 else
1b4b80bf
NC
5055 {
5056 switch (sh_type)
5057 {
5058 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5059 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5060 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5061 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5062 default:
5063 result = NULL;
5064 break;
5065 }
5066 }
148b93f2
NC
5067 break;
5068 }
5069
5070 if (result != NULL)
5071 return result;
5072
9fb71ee4 5073 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5074 }
252b5132 5075 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5076 {
dda8d76d 5077 switch (filedata->file_header.e_machine)
685080f2
NC
5078 {
5079 case EM_V800:
5080 case EM_V850:
5081 case EM_CYGNUS_V850:
9fb71ee4 5082 result = get_v850_section_type_name (sh_type);
a9fb83be 5083 break;
685080f2 5084 default:
9fb71ee4 5085 result = NULL;
685080f2
NC
5086 break;
5087 }
5088
9fb71ee4
NC
5089 if (result != NULL)
5090 return result;
5091
5092 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5093 }
252b5132 5094 else
a7dbfd1c
NC
5095 /* This message is probably going to be displayed in a 15
5096 character wide field, so put the hex value first. */
5097 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5098
252b5132
RH
5099 return buff;
5100 }
5101}
5102
79bc120c
NC
5103enum long_option_values
5104{
5105 OPTION_DEBUG_DUMP = 512,
5106 OPTION_DYN_SYMS,
0f03783c 5107 OPTION_LTO_SYMS,
79bc120c
NC
5108 OPTION_DWARF_DEPTH,
5109 OPTION_DWARF_START,
5110 OPTION_DWARF_CHECK,
5111 OPTION_CTF_DUMP,
5112 OPTION_CTF_PARENT,
5113 OPTION_CTF_SYMBOLS,
5114 OPTION_CTF_STRINGS,
5115 OPTION_WITH_SYMBOL_VERSIONS,
5116 OPTION_RECURSE_LIMIT,
5117 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5118 OPTION_NO_DEMANGLING,
5119 OPTION_SYM_BASE
79bc120c 5120};
2979dc34 5121
85b1c36d 5122static struct option options[] =
252b5132 5123{
79bc120c
NC
5124 /* Note - This table is alpha-sorted on the 'val'
5125 field in order to make adding new options easier. */
5126 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5127 {"all", no_argument, 0, 'a'},
79bc120c
NC
5128 {"demangle", optional_argument, 0, 'C'},
5129 {"archive-index", no_argument, 0, 'c'},
5130 {"use-dynamic", no_argument, 0, 'D'},
5131 {"dynamic", no_argument, 0, 'd'},
b34976b6 5132 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5133 {"section-groups", no_argument, 0, 'g'},
5134 {"help", no_argument, 0, 'H'},
5135 {"file-header", no_argument, 0, 'h'},
b34976b6 5136 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5137 {"lint", no_argument, 0, 'L'},
5138 {"enable-checks", no_argument, 0, 'L'},
5139 {"program-headers", no_argument, 0, 'l'},
b34976b6 5140 {"segments", no_argument, 0, 'l'},
595cf52e 5141 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5142 {"notes", no_argument, 0, 'n'},
ca0e11aa 5143 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5144 {"string-dump", required_argument, 0, 'p'},
5145 {"relocated-dump", required_argument, 0, 'R'},
5146 {"relocs", no_argument, 0, 'r'},
5147 {"section-headers", no_argument, 0, 'S'},
5148 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5149 {"symbols", no_argument, 0, 's'},
5150 {"syms", no_argument, 0, 's'},
79bc120c
NC
5151 {"silent-truncation",no_argument, 0, 'T'},
5152 {"section-details", no_argument, 0, 't'},
b3aa80b4 5153 {"unicode", required_argument, NULL, 'U'},
09c11c86 5154 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5155 {"version-info", no_argument, 0, 'V'},
5156 {"version", no_argument, 0, 'v'},
5157 {"wide", no_argument, 0, 'W'},
b34976b6 5158 {"hex-dump", required_argument, 0, 'x'},
0e602686 5159 {"decompress", no_argument, 0, 'z'},
252b5132 5160
79bc120c
NC
5161 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5162 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5163 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5164 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5165 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5166 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5167 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5168 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5169 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5170 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5171#ifdef ENABLE_LIBCTF
d344b407 5172 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5173 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5174 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5175 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5176#endif
047c3dbf 5177 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5178
b34976b6 5179 {0, no_argument, 0, 0}
252b5132
RH
5180};
5181
5182static void
2cf0635d 5183usage (FILE * stream)
252b5132 5184{
92f01d61
JM
5185 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5186 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5187 fprintf (stream, _(" Options are:\n"));
5188 fprintf (stream, _("\
5189 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5190 fprintf (stream, _("\
5191 -h --file-header Display the ELF file header\n"));
5192 fprintf (stream, _("\
5193 -l --program-headers Display the program headers\n"));
5194 fprintf (stream, _("\
5195 --segments An alias for --program-headers\n"));
5196 fprintf (stream, _("\
5197 -S --section-headers Display the sections' header\n"));
5198 fprintf (stream, _("\
5199 --sections An alias for --section-headers\n"));
5200 fprintf (stream, _("\
5201 -g --section-groups Display the section groups\n"));
5202 fprintf (stream, _("\
5203 -t --section-details Display the section details\n"));
5204 fprintf (stream, _("\
5205 -e --headers Equivalent to: -h -l -S\n"));
5206 fprintf (stream, _("\
5207 -s --syms Display the symbol table\n"));
5208 fprintf (stream, _("\
5209 --symbols An alias for --syms\n"));
5210 fprintf (stream, _("\
5211 --dyn-syms Display the dynamic symbol table\n"));
5212 fprintf (stream, _("\
5213 --lto-syms Display LTO symbol tables\n"));
5214 fprintf (stream, _("\
047c3dbf
NL
5215 --sym-base=[0|8|10|16] \n\
5216 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5217 mixed (the default), octal, decimal, hexadecimal.\n"));
5218 fprintf (stream, _("\
0d646226
AM
5219 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5220 display_demangler_styles (stream, _("\
5221 STYLE can be "));
d6249f5f
AM
5222 fprintf (stream, _("\
5223 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5224 fprintf (stream, _("\
5225 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5226 fprintf (stream, _("\
5227 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5228 fprintf (stream, _("\
5229 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5230 Display unicode characters as determined by the current locale\n\
5231 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5232 escape sequences, or treat them as invalid and display as\n\
5233 \"{hex sequences}\"\n"));
d6249f5f
AM
5234 fprintf (stream, _("\
5235 -n --notes Display the core notes (if present)\n"));
5236 fprintf (stream, _("\
5237 -r --relocs Display the relocations (if present)\n"));
5238 fprintf (stream, _("\
5239 -u --unwind Display the unwind info (if present)\n"));
5240 fprintf (stream, _("\
5241 -d --dynamic Display the dynamic section (if present)\n"));
5242 fprintf (stream, _("\
5243 -V --version-info Display the version sections (if present)\n"));
5244 fprintf (stream, _("\
5245 -A --arch-specific Display architecture specific information (if any)\n"));
5246 fprintf (stream, _("\
5247 -c --archive-index Display the symbol/file index in an archive\n"));
5248 fprintf (stream, _("\
5249 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5250 fprintf (stream, _("\
5251 -L --lint|--enable-checks\n\
5252 Display warning messages for possible problems\n"));
5253 fprintf (stream, _("\
09c11c86 5254 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5255 Dump the contents of section <number|name> as bytes\n"));
5256 fprintf (stream, _("\
09c11c86 5257 -p --string-dump=<number|name>\n\
d6249f5f
AM
5258 Dump the contents of section <number|name> as strings\n"));
5259 fprintf (stream, _("\
cf13d699 5260 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5261 Dump the relocated contents of section <number|name>\n"));
5262 fprintf (stream, _("\
5263 -z --decompress Decompress section before dumping it\n"));
5264 fprintf (stream, _("\
5265 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5266 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5267 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5268 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5269 U/=trace_info]\n\
5270 Display the contents of DWARF debug sections\n"));
5271 fprintf (stream, _("\
5272 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5273 debuginfo files\n"));
5274 fprintf (stream, _("\
5275 -P --process-links Display the contents of non-debug sections in separate\n\
5276 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5277#if DEFAULT_FOR_FOLLOW_LINKS
5278 fprintf (stream, _("\
d6249f5f
AM
5279 -wK --debug-dump=follow-links\n\
5280 Follow links to separate debug info files (default)\n"));
5281 fprintf (stream, _("\
5282 -wN --debug-dump=no-follow-links\n\
5283 Do not follow links to separate debug info files\n"));
c46b7066
NC
5284#else
5285 fprintf (stream, _("\
d6249f5f
AM
5286 -wK --debug-dump=follow-links\n\
5287 Follow links to separate debug info files\n"));
5288 fprintf (stream, _("\
5289 -wN --debug-dump=no-follow-links\n\
5290 Do not follow links to separate debug info files\n\
5291 (default)\n"));
bed566bb
NC
5292#endif
5293#if HAVE_LIBDEBUGINFOD
5294 fprintf (stream, _("\
5295 -wD --debug-dump=use-debuginfod\n\
5296 When following links, also query debuginfod servers (default)\n"));
5297 fprintf (stream, _("\
5298 -wE --debug-dump=do-not-use-debuginfod\n\
5299 When following links, do not query debuginfod servers\n"));
c46b7066 5300#endif
fd2f0033 5301 fprintf (stream, _("\
d6249f5f
AM
5302 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5303 fprintf (stream, _("\
5304 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5305#ifdef ENABLE_LIBCTF
7d9813f1 5306 fprintf (stream, _("\
d6249f5f
AM
5307 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5308 fprintf (stream, _("\
80b56fad 5309 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5310 fprintf (stream, _("\
7d9813f1 5311 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5312 Use section <number|name> as the CTF external symtab\n"));
5313 fprintf (stream, _("\
7d9813f1 5314 --ctf-strings=<number|name>\n\
d6249f5f 5315 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5316#endif
7d9813f1 5317
252b5132 5318#ifdef SUPPORT_DISASSEMBLY
92f01d61 5319 fprintf (stream, _("\
09c11c86
NC
5320 -i --instruction-dump=<number|name>\n\
5321 Disassemble the contents of section <number|name>\n"));
252b5132 5322#endif
92f01d61 5323 fprintf (stream, _("\
d6249f5f
AM
5324 -I --histogram Display histogram of bucket list lengths\n"));
5325 fprintf (stream, _("\
5326 -W --wide Allow output width to exceed 80 characters\n"));
5327 fprintf (stream, _("\
5328 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5329 fprintf (stream, _("\
5330 @<file> Read options from <file>\n"));
5331 fprintf (stream, _("\
5332 -H --help Display this information\n"));
5333 fprintf (stream, _("\
8b53311e 5334 -v --version Display the version number of readelf\n"));
1118d252 5335
92f01d61
JM
5336 if (REPORT_BUGS_TO[0] && stream == stdout)
5337 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5338
92f01d61 5339 exit (stream == stdout ? 0 : 1);
252b5132
RH
5340}
5341
18bd398b
NC
5342/* Record the fact that the user wants the contents of section number
5343 SECTION to be displayed using the method(s) encoded as flags bits
5344 in TYPE. Note, TYPE can be zero if we are creating the array for
5345 the first time. */
5346
252b5132 5347static void
6431e409
AM
5348request_dump_bynumber (struct dump_data *dumpdata,
5349 unsigned int section, dump_type type)
252b5132 5350{
6431e409 5351 if (section >= dumpdata->num_dump_sects)
252b5132 5352 {
2cf0635d 5353 dump_type * new_dump_sects;
252b5132 5354
3f5e193b 5355 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5356 sizeof (* new_dump_sects));
252b5132
RH
5357
5358 if (new_dump_sects == NULL)
591a748a 5359 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5360 else
5361 {
6431e409 5362 if (dumpdata->dump_sects)
21b65bac
NC
5363 {
5364 /* Copy current flag settings. */
6431e409
AM
5365 memcpy (new_dump_sects, dumpdata->dump_sects,
5366 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5367
6431e409 5368 free (dumpdata->dump_sects);
21b65bac 5369 }
252b5132 5370
6431e409
AM
5371 dumpdata->dump_sects = new_dump_sects;
5372 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5373 }
5374 }
5375
6431e409
AM
5376 if (dumpdata->dump_sects)
5377 dumpdata->dump_sects[section] |= type;
252b5132
RH
5378}
5379
aef1f6d0
DJ
5380/* Request a dump by section name. */
5381
5382static void
2cf0635d 5383request_dump_byname (const char * section, dump_type type)
aef1f6d0 5384{
2cf0635d 5385 struct dump_list_entry * new_request;
aef1f6d0 5386
3f5e193b
NC
5387 new_request = (struct dump_list_entry *)
5388 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5389 if (!new_request)
591a748a 5390 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5391
5392 new_request->name = strdup (section);
5393 if (!new_request->name)
591a748a 5394 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5395
5396 new_request->type = type;
5397
5398 new_request->next = dump_sects_byname;
5399 dump_sects_byname = new_request;
5400}
5401
cf13d699 5402static inline void
6431e409 5403request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5404{
5405 int section;
5406 char * cp;
5407
015dc7e1 5408 do_dump = true;
cf13d699
NC
5409 section = strtoul (optarg, & cp, 0);
5410
5411 if (! *cp && section >= 0)
6431e409 5412 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5413 else
5414 request_dump_byname (optarg, type);
5415}
5416
252b5132 5417static void
6431e409 5418parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5419{
5420 int c;
5421
5422 if (argc < 2)
92f01d61 5423 usage (stderr);
252b5132
RH
5424
5425 while ((c = getopt_long
b3aa80b4 5426 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5427 {
252b5132
RH
5428 switch (c)
5429 {
5430 case 0:
5431 /* Long options. */
5432 break;
5433 case 'H':
92f01d61 5434 usage (stdout);
252b5132
RH
5435 break;
5436
5437 case 'a':
015dc7e1
AM
5438 do_syms = true;
5439 do_reloc = true;
5440 do_unwind = true;
5441 do_dynamic = true;
5442 do_header = true;
5443 do_sections = true;
5444 do_section_groups = true;
5445 do_segments = true;
5446 do_version = true;
5447 do_histogram = true;
5448 do_arch = true;
5449 do_notes = true;
252b5132 5450 break;
79bc120c 5451
f5842774 5452 case 'g':
015dc7e1 5453 do_section_groups = true;
f5842774 5454 break;
5477e8a0 5455 case 't':
595cf52e 5456 case 'N':
015dc7e1
AM
5457 do_sections = true;
5458 do_section_details = true;
595cf52e 5459 break;
252b5132 5460 case 'e':
015dc7e1
AM
5461 do_header = true;
5462 do_sections = true;
5463 do_segments = true;
252b5132 5464 break;
a952a375 5465 case 'A':
015dc7e1 5466 do_arch = true;
a952a375 5467 break;
252b5132 5468 case 'D':
015dc7e1 5469 do_using_dynamic = true;
252b5132
RH
5470 break;
5471 case 'r':
015dc7e1 5472 do_reloc = true;
252b5132 5473 break;
4d6ed7c8 5474 case 'u':
015dc7e1 5475 do_unwind = true;
4d6ed7c8 5476 break;
252b5132 5477 case 'h':
015dc7e1 5478 do_header = true;
252b5132
RH
5479 break;
5480 case 'l':
015dc7e1 5481 do_segments = true;
252b5132
RH
5482 break;
5483 case 's':
015dc7e1 5484 do_syms = true;
252b5132
RH
5485 break;
5486 case 'S':
015dc7e1 5487 do_sections = true;
252b5132
RH
5488 break;
5489 case 'd':
015dc7e1 5490 do_dynamic = true;
252b5132 5491 break;
a952a375 5492 case 'I':
015dc7e1 5493 do_histogram = true;
a952a375 5494 break;
779fe533 5495 case 'n':
015dc7e1 5496 do_notes = true;
779fe533 5497 break;
4145f1d5 5498 case 'c':
015dc7e1 5499 do_archive_index = true;
4145f1d5 5500 break;
1b513401 5501 case 'L':
015dc7e1 5502 do_checks = true;
1b513401 5503 break;
ca0e11aa 5504 case 'P':
015dc7e1
AM
5505 process_links = true;
5506 do_follow_links = true;
e1dbfc17 5507 dump_any_debugging = true;
ca0e11aa 5508 break;
252b5132 5509 case 'x':
6431e409 5510 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5511 break;
09c11c86 5512 case 'p':
6431e409 5513 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5514 break;
5515 case 'R':
6431e409 5516 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5517 break;
0e602686 5518 case 'z':
015dc7e1 5519 decompress_dumps = true;
0e602686 5520 break;
252b5132 5521 case 'w':
015dc7e1 5522 do_dump = true;
e1dbfc17 5523 dump_any_debugging = true;
0f03783c 5524 if (optarg == NULL)
613ff48b 5525 {
015dc7e1 5526 do_debugging = true;
613ff48b
CC
5527 dwarf_select_sections_all ();
5528 }
252b5132
RH
5529 else
5530 {
015dc7e1 5531 do_debugging = false;
4cb93e3b 5532 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5533 }
5534 break;
2979dc34 5535 case OPTION_DEBUG_DUMP:
015dc7e1 5536 do_dump = true;
e1dbfc17 5537 dump_any_debugging = true;
0f03783c 5538 if (optarg == NULL)
d6249f5f
AM
5539 {
5540 do_debugging = true;
5541 dwarf_select_sections_all ();
5542 }
2979dc34
JJ
5543 else
5544 {
015dc7e1 5545 do_debugging = false;
4cb93e3b 5546 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5547 }
5548 break;
fd2f0033
TT
5549 case OPTION_DWARF_DEPTH:
5550 {
5551 char *cp;
5552
5553 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5554 }
5555 break;
5556 case OPTION_DWARF_START:
5557 {
5558 char *cp;
5559
5560 dwarf_start_die = strtoul (optarg, & cp, 0);
5561 }
5562 break;
4723351a 5563 case OPTION_DWARF_CHECK:
015dc7e1 5564 dwarf_check = true;
4723351a 5565 break;
7d9813f1 5566 case OPTION_CTF_DUMP:
015dc7e1 5567 do_ctf = true;
6431e409 5568 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5569 break;
5570 case OPTION_CTF_SYMBOLS:
df16e041 5571 free (dump_ctf_symtab_name);
7d9813f1
NA
5572 dump_ctf_symtab_name = strdup (optarg);
5573 break;
5574 case OPTION_CTF_STRINGS:
df16e041 5575 free (dump_ctf_strtab_name);
7d9813f1
NA
5576 dump_ctf_strtab_name = strdup (optarg);
5577 break;
5578 case OPTION_CTF_PARENT:
df16e041 5579 free (dump_ctf_parent_name);
7d9813f1
NA
5580 dump_ctf_parent_name = strdup (optarg);
5581 break;
2c610e4b 5582 case OPTION_DYN_SYMS:
015dc7e1 5583 do_dyn_syms = true;
2c610e4b 5584 break;
0f03783c 5585 case OPTION_LTO_SYMS:
015dc7e1 5586 do_lto_syms = true;
0f03783c 5587 break;
252b5132
RH
5588#ifdef SUPPORT_DISASSEMBLY
5589 case 'i':
6431e409 5590 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5591 break;
252b5132
RH
5592#endif
5593 case 'v':
5594 print_version (program_name);
5595 break;
5596 case 'V':
015dc7e1 5597 do_version = true;
252b5132 5598 break;
d974e256 5599 case 'W':
015dc7e1 5600 do_wide = true;
d974e256 5601 break;
0942c7ab 5602 case 'T':
015dc7e1 5603 do_not_show_symbol_truncation = true;
0942c7ab 5604 break;
79bc120c 5605 case 'C':
015dc7e1 5606 do_demangle = true;
79bc120c
NC
5607 if (optarg != NULL)
5608 {
5609 enum demangling_styles style;
5610
5611 style = cplus_demangle_name_to_style (optarg);
5612 if (style == unknown_demangling)
5613 error (_("unknown demangling style `%s'"), optarg);
5614
5615 cplus_demangle_set_style (style);
5616 }
5617 break;
5618 case OPTION_NO_DEMANGLING:
015dc7e1 5619 do_demangle = false;
79bc120c
NC
5620 break;
5621 case OPTION_RECURSE_LIMIT:
5622 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5623 break;
5624 case OPTION_NO_RECURSE_LIMIT:
5625 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5626 break;
5627 case OPTION_WITH_SYMBOL_VERSIONS:
5628 /* Ignored for backward compatibility. */
5629 break;
b9e920ec 5630
b3aa80b4
NC
5631 case 'U':
5632 if (optarg == NULL)
5633 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5634 else if (streq (optarg, "default") || streq (optarg, "d"))
5635 unicode_display = unicode_default;
5636 else if (streq (optarg, "locale") || streq (optarg, "l"))
5637 unicode_display = unicode_locale;
5638 else if (streq (optarg, "escape") || streq (optarg, "e"))
5639 unicode_display = unicode_escape;
5640 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5641 unicode_display = unicode_invalid;
5642 else if (streq (optarg, "hex") || streq (optarg, "x"))
5643 unicode_display = unicode_hex;
5644 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5645 unicode_display = unicode_highlight;
5646 else
5647 error (_("invalid argument to -U/--unicode: %s"), optarg);
5648 break;
5649
047c3dbf
NL
5650 case OPTION_SYM_BASE:
5651 sym_base = 0;
5652 if (optarg != NULL)
5653 {
5654 sym_base = strtoul (optarg, NULL, 0);
5655 switch (sym_base)
5656 {
5657 case 0:
5658 case 8:
5659 case 10:
5660 case 16:
5661 break;
5662
5663 default:
5664 sym_base = 0;
5665 break;
5666 }
5667 }
5668 break;
5669
252b5132 5670 default:
252b5132
RH
5671 /* xgettext:c-format */
5672 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5673 /* Fall through. */
252b5132 5674 case '?':
92f01d61 5675 usage (stderr);
252b5132
RH
5676 }
5677 }
5678
4d6ed7c8 5679 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5680 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5681 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5682 && !do_section_groups && !do_archive_index
0f03783c 5683 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5684 {
5685 if (do_checks)
5686 {
015dc7e1
AM
5687 check_all = true;
5688 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5689 do_segments = do_header = do_dump = do_version = true;
5690 do_histogram = do_debugging = do_arch = do_notes = true;
5691 do_section_groups = do_archive_index = do_dyn_syms = true;
5692 do_lto_syms = true;
1b513401
NC
5693 }
5694 else
5695 usage (stderr);
5696 }
252b5132
RH
5697}
5698
5699static const char *
d3ba0551 5700get_elf_class (unsigned int elf_class)
252b5132 5701{
b34976b6 5702 static char buff[32];
103f02d3 5703
252b5132
RH
5704 switch (elf_class)
5705 {
5706 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5707 case ELFCLASS32: return "ELF32";
5708 case ELFCLASS64: return "ELF64";
ab5e7794 5709 default:
e9e44622 5710 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5711 return buff;
252b5132
RH
5712 }
5713}
5714
5715static const char *
d3ba0551 5716get_data_encoding (unsigned int encoding)
252b5132 5717{
b34976b6 5718 static char buff[32];
103f02d3 5719
252b5132
RH
5720 switch (encoding)
5721 {
5722 case ELFDATANONE: return _("none");
33c63f9d
CM
5723 case ELFDATA2LSB: return _("2's complement, little endian");
5724 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5725 default:
e9e44622 5726 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5727 return buff;
252b5132
RH
5728 }
5729}
5730
dda8d76d 5731/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5732
015dc7e1 5733static bool
dda8d76d 5734process_file_header (Filedata * filedata)
252b5132 5735{
dda8d76d
NC
5736 Elf_Internal_Ehdr * header = & filedata->file_header;
5737
5738 if ( header->e_ident[EI_MAG0] != ELFMAG0
5739 || header->e_ident[EI_MAG1] != ELFMAG1
5740 || header->e_ident[EI_MAG2] != ELFMAG2
5741 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5742 {
5743 error
5744 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5745 return false;
252b5132
RH
5746 }
5747
ca0e11aa
NC
5748 if (! filedata->is_separate)
5749 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5750
252b5132
RH
5751 if (do_header)
5752 {
32ec8896 5753 unsigned i;
252b5132 5754
ca0e11aa
NC
5755 if (filedata->is_separate)
5756 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5757 else
5758 printf (_("ELF Header:\n"));
252b5132 5759 printf (_(" Magic: "));
b34976b6 5760 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5761 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5762 printf ("\n");
5763 printf (_(" Class: %s\n"),
dda8d76d 5764 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5765 printf (_(" Data: %s\n"),
dda8d76d 5766 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5767 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5768 header->e_ident[EI_VERSION],
5769 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5770 ? _(" (current)")
dda8d76d 5771 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5772 ? _(" <unknown>")
789be9f7 5773 : "")));
252b5132 5774 printf (_(" OS/ABI: %s\n"),
dda8d76d 5775 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5776 printf (_(" ABI Version: %d\n"),
dda8d76d 5777 header->e_ident[EI_ABIVERSION]);
252b5132 5778 printf (_(" Type: %s\n"),
93df3340 5779 get_file_type (filedata));
252b5132 5780 printf (_(" Machine: %s\n"),
dda8d76d 5781 get_machine_name (header->e_machine));
252b5132 5782 printf (_(" Version: 0x%lx\n"),
e8a64888 5783 header->e_version);
76da6bbe 5784
f7a99963 5785 printf (_(" Entry point address: "));
e8a64888 5786 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5787 printf (_("\n Start of program headers: "));
e8a64888 5788 print_vma (header->e_phoff, DEC);
f7a99963 5789 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5790 print_vma (header->e_shoff, DEC);
f7a99963 5791 printf (_(" (bytes into file)\n"));
76da6bbe 5792
252b5132 5793 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5794 header->e_flags,
dda8d76d 5795 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5796 printf (_(" Size of this header: %u (bytes)\n"),
5797 header->e_ehsize);
5798 printf (_(" Size of program headers: %u (bytes)\n"),
5799 header->e_phentsize);
5800 printf (_(" Number of program headers: %u"),
5801 header->e_phnum);
dda8d76d
NC
5802 if (filedata->section_headers != NULL
5803 && header->e_phnum == PN_XNUM
5804 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5805 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5806 putc ('\n', stdout);
e8a64888
AM
5807 printf (_(" Size of section headers: %u (bytes)\n"),
5808 header->e_shentsize);
5809 printf (_(" Number of section headers: %u"),
5810 header->e_shnum);
dda8d76d 5811 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5812 {
5813 header->e_shnum = filedata->section_headers[0].sh_size;
5814 printf (" (%u)", header->e_shnum);
5815 }
560f3c1c 5816 putc ('\n', stdout);
e8a64888
AM
5817 printf (_(" Section header string table index: %u"),
5818 header->e_shstrndx);
dda8d76d
NC
5819 if (filedata->section_headers != NULL
5820 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5821 {
5822 header->e_shstrndx = filedata->section_headers[0].sh_link;
5823 printf (" (%u)", header->e_shstrndx);
5824 }
5825 if (header->e_shstrndx != SHN_UNDEF
5826 && header->e_shstrndx >= header->e_shnum)
5827 {
5828 header->e_shstrndx = SHN_UNDEF;
5829 printf (_(" <corrupt: out of range>"));
5830 }
560f3c1c
AM
5831 putc ('\n', stdout);
5832 }
5833
dda8d76d 5834 if (filedata->section_headers != NULL)
560f3c1c 5835 {
dda8d76d
NC
5836 if (header->e_phnum == PN_XNUM
5837 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5838 {
5839 /* Throw away any cached read of PN_XNUM headers. */
5840 free (filedata->program_headers);
5841 filedata->program_headers = NULL;
5842 header->e_phnum = filedata->section_headers[0].sh_info;
5843 }
dda8d76d
NC
5844 if (header->e_shnum == SHN_UNDEF)
5845 header->e_shnum = filedata->section_headers[0].sh_size;
5846 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5847 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5848 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5849 header->e_shstrndx = SHN_UNDEF;
252b5132 5850 }
103f02d3 5851
015dc7e1 5852 return true;
9ea033b2
NC
5853}
5854
dda8d76d
NC
5855/* Read in the program headers from FILEDATA and store them in PHEADERS.
5856 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5857
015dc7e1 5858static bool
dda8d76d 5859get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5860{
2cf0635d
NC
5861 Elf32_External_Phdr * phdrs;
5862 Elf32_External_Phdr * external;
5863 Elf_Internal_Phdr * internal;
b34976b6 5864 unsigned int i;
dda8d76d
NC
5865 unsigned int size = filedata->file_header.e_phentsize;
5866 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5867
5868 /* PR binutils/17531: Cope with unexpected section header sizes. */
5869 if (size == 0 || num == 0)
015dc7e1 5870 return false;
e0a31db1
NC
5871 if (size < sizeof * phdrs)
5872 {
5873 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5874 return false;
e0a31db1
NC
5875 }
5876 if (size > sizeof * phdrs)
5877 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5878
dda8d76d 5879 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5880 size, num, _("program headers"));
5881 if (phdrs == NULL)
015dc7e1 5882 return false;
9ea033b2 5883
91d6fa6a 5884 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5885 i < filedata->file_header.e_phnum;
b34976b6 5886 i++, internal++, external++)
252b5132 5887 {
9ea033b2
NC
5888 internal->p_type = BYTE_GET (external->p_type);
5889 internal->p_offset = BYTE_GET (external->p_offset);
5890 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5891 internal->p_paddr = BYTE_GET (external->p_paddr);
5892 internal->p_filesz = BYTE_GET (external->p_filesz);
5893 internal->p_memsz = BYTE_GET (external->p_memsz);
5894 internal->p_flags = BYTE_GET (external->p_flags);
5895 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5896 }
5897
9ea033b2 5898 free (phdrs);
015dc7e1 5899 return true;
252b5132
RH
5900}
5901
dda8d76d
NC
5902/* Read in the program headers from FILEDATA and store them in PHEADERS.
5903 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5904
015dc7e1 5905static bool
dda8d76d 5906get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5907{
2cf0635d
NC
5908 Elf64_External_Phdr * phdrs;
5909 Elf64_External_Phdr * external;
5910 Elf_Internal_Phdr * internal;
b34976b6 5911 unsigned int i;
dda8d76d
NC
5912 unsigned int size = filedata->file_header.e_phentsize;
5913 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5914
5915 /* PR binutils/17531: Cope with unexpected section header sizes. */
5916 if (size == 0 || num == 0)
015dc7e1 5917 return false;
e0a31db1
NC
5918 if (size < sizeof * phdrs)
5919 {
5920 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5921 return false;
e0a31db1
NC
5922 }
5923 if (size > sizeof * phdrs)
5924 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5925
dda8d76d 5926 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5927 size, num, _("program headers"));
a6e9f9df 5928 if (!phdrs)
015dc7e1 5929 return false;
9ea033b2 5930
91d6fa6a 5931 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5932 i < filedata->file_header.e_phnum;
b34976b6 5933 i++, internal++, external++)
9ea033b2
NC
5934 {
5935 internal->p_type = BYTE_GET (external->p_type);
5936 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5937 internal->p_offset = BYTE_GET (external->p_offset);
5938 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5939 internal->p_paddr = BYTE_GET (external->p_paddr);
5940 internal->p_filesz = BYTE_GET (external->p_filesz);
5941 internal->p_memsz = BYTE_GET (external->p_memsz);
5942 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5943 }
5944
5945 free (phdrs);
015dc7e1 5946 return true;
9ea033b2 5947}
252b5132 5948
32ec8896 5949/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5950
015dc7e1 5951static bool
dda8d76d 5952get_program_headers (Filedata * filedata)
d93f0186 5953{
2cf0635d 5954 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5955
5956 /* Check cache of prior read. */
dda8d76d 5957 if (filedata->program_headers != NULL)
015dc7e1 5958 return true;
d93f0186 5959
82156ab7
NC
5960 /* Be kind to memory checkers by looking for
5961 e_phnum values which we know must be invalid. */
dda8d76d 5962 if (filedata->file_header.e_phnum
82156ab7 5963 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5964 >= filedata->file_size)
82156ab7
NC
5965 {
5966 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5967 filedata->file_header.e_phnum);
015dc7e1 5968 return false;
82156ab7 5969 }
d93f0186 5970
dda8d76d 5971 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5972 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5973 if (phdrs == NULL)
5974 {
8b73c356 5975 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5976 filedata->file_header.e_phnum);
015dc7e1 5977 return false;
d93f0186
NC
5978 }
5979
5980 if (is_32bit_elf
dda8d76d
NC
5981 ? get_32bit_program_headers (filedata, phdrs)
5982 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5983 {
dda8d76d 5984 filedata->program_headers = phdrs;
015dc7e1 5985 return true;
d93f0186
NC
5986 }
5987
5988 free (phdrs);
015dc7e1 5989 return false;
d93f0186
NC
5990}
5991
93df3340 5992/* Print program header info and locate dynamic section. */
2f62977e 5993
93df3340 5994static void
dda8d76d 5995process_program_headers (Filedata * filedata)
252b5132 5996{
2cf0635d 5997 Elf_Internal_Phdr * segment;
b34976b6 5998 unsigned int i;
1a9ccd70 5999 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6000
dda8d76d 6001 if (filedata->file_header.e_phnum == 0)
252b5132 6002 {
82f2dbf7 6003 /* PR binutils/12467. */
dda8d76d 6004 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6005 warn (_("possibly corrupt ELF header - it has a non-zero program"
6006 " header offset, but no program headers\n"));
82f2dbf7 6007 else if (do_segments)
ca0e11aa
NC
6008 {
6009 if (filedata->is_separate)
6010 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6011 filedata->file_name);
6012 else
6013 printf (_("\nThere are no program headers in this file.\n"));
6014 }
93df3340 6015 goto no_headers;
252b5132
RH
6016 }
6017
6018 if (do_segments && !do_header)
6019 {
ca0e11aa
NC
6020 if (filedata->is_separate)
6021 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6022 filedata->file_name, get_file_type (filedata));
ca0e11aa 6023 else
93df3340 6024 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 6025 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
6026 printf (ngettext ("There is %d program header, starting at offset %s\n",
6027 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
6028 filedata->file_header.e_phnum),
6029 filedata->file_header.e_phnum,
6030 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
6031 }
6032
dda8d76d 6033 if (! get_program_headers (filedata))
93df3340 6034 goto no_headers;
103f02d3 6035
252b5132
RH
6036 if (do_segments)
6037 {
dda8d76d 6038 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6039 printf (_("\nProgram Headers:\n"));
6040 else
6041 printf (_("\nProgram Headers:\n"));
76da6bbe 6042
f7a99963
NC
6043 if (is_32bit_elf)
6044 printf
6045 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6046 else if (do_wide)
6047 printf
6048 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6049 else
6050 {
6051 printf
6052 (_(" Type Offset VirtAddr PhysAddr\n"));
6053 printf
6054 (_(" FileSiz MemSiz Flags Align\n"));
6055 }
252b5132
RH
6056 }
6057
93df3340
AM
6058 unsigned long dynamic_addr = 0;
6059 bfd_size_type dynamic_size = 0;
dda8d76d
NC
6060 for (i = 0, segment = filedata->program_headers;
6061 i < filedata->file_header.e_phnum;
b34976b6 6062 i++, segment++)
252b5132
RH
6063 {
6064 if (do_segments)
6065 {
dda8d76d 6066 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6067
6068 if (is_32bit_elf)
6069 {
6070 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6071 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6072 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6073 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6074 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6075 printf ("%c%c%c ",
6076 (segment->p_flags & PF_R ? 'R' : ' '),
6077 (segment->p_flags & PF_W ? 'W' : ' '),
6078 (segment->p_flags & PF_X ? 'E' : ' '));
6079 printf ("%#lx", (unsigned long) segment->p_align);
6080 }
d974e256
JJ
6081 else if (do_wide)
6082 {
6083 if ((unsigned long) segment->p_offset == segment->p_offset)
6084 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6085 else
6086 {
6087 print_vma (segment->p_offset, FULL_HEX);
6088 putchar (' ');
6089 }
6090
6091 print_vma (segment->p_vaddr, FULL_HEX);
6092 putchar (' ');
6093 print_vma (segment->p_paddr, FULL_HEX);
6094 putchar (' ');
6095
6096 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6097 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6098 else
6099 {
6100 print_vma (segment->p_filesz, FULL_HEX);
6101 putchar (' ');
6102 }
6103
6104 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6105 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6106 else
6107 {
f48e6c45 6108 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6109 }
6110
6111 printf (" %c%c%c ",
6112 (segment->p_flags & PF_R ? 'R' : ' '),
6113 (segment->p_flags & PF_W ? 'W' : ' '),
6114 (segment->p_flags & PF_X ? 'E' : ' '));
6115
6116 if ((unsigned long) segment->p_align == segment->p_align)
6117 printf ("%#lx", (unsigned long) segment->p_align);
6118 else
6119 {
6120 print_vma (segment->p_align, PREFIX_HEX);
6121 }
6122 }
f7a99963
NC
6123 else
6124 {
6125 print_vma (segment->p_offset, FULL_HEX);
6126 putchar (' ');
6127 print_vma (segment->p_vaddr, FULL_HEX);
6128 putchar (' ');
6129 print_vma (segment->p_paddr, FULL_HEX);
6130 printf ("\n ");
6131 print_vma (segment->p_filesz, FULL_HEX);
6132 putchar (' ');
6133 print_vma (segment->p_memsz, FULL_HEX);
6134 printf (" %c%c%c ",
6135 (segment->p_flags & PF_R ? 'R' : ' '),
6136 (segment->p_flags & PF_W ? 'W' : ' '),
6137 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6138 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6139 }
252b5132 6140
1a9ccd70
NC
6141 putc ('\n', stdout);
6142 }
f54498b4 6143
252b5132
RH
6144 switch (segment->p_type)
6145 {
1a9ccd70 6146 case PT_LOAD:
502d895c
NC
6147#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6148 required by the ELF standard, several programs, including the Linux
6149 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6150 if (previous_load
6151 && previous_load->p_vaddr > segment->p_vaddr)
6152 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6153#endif
1a9ccd70
NC
6154 if (segment->p_memsz < segment->p_filesz)
6155 error (_("the segment's file size is larger than its memory size\n"));
6156 previous_load = segment;
6157 break;
6158
6159 case PT_PHDR:
6160 /* PR 20815 - Verify that the program header is loaded into memory. */
6161 if (i > 0 && previous_load != NULL)
6162 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6163 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6164 {
6165 unsigned int j;
6166
dda8d76d 6167 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6168 {
6169 Elf_Internal_Phdr *load = filedata->program_headers + j;
6170 if (load->p_type == PT_LOAD
6171 && load->p_offset <= segment->p_offset
6172 && (load->p_offset + load->p_filesz
6173 >= segment->p_offset + segment->p_filesz)
6174 && load->p_vaddr <= segment->p_vaddr
6175 && (load->p_vaddr + load->p_filesz
6176 >= segment->p_vaddr + segment->p_filesz))
6177 break;
6178 }
dda8d76d 6179 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6180 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6181 }
6182 break;
6183
252b5132 6184 case PT_DYNAMIC:
93df3340 6185 if (dynamic_addr)
252b5132
RH
6186 error (_("more than one dynamic segment\n"));
6187
20737c13
AM
6188 /* By default, assume that the .dynamic section is the first
6189 section in the DYNAMIC segment. */
93df3340
AM
6190 dynamic_addr = segment->p_offset;
6191 dynamic_size = segment->p_filesz;
20737c13 6192
b2d38a17
NC
6193 /* Try to locate the .dynamic section. If there is
6194 a section header table, we can easily locate it. */
dda8d76d 6195 if (filedata->section_headers != NULL)
b2d38a17 6196 {
2cf0635d 6197 Elf_Internal_Shdr * sec;
b2d38a17 6198
dda8d76d 6199 sec = find_section (filedata, ".dynamic");
89fac5e3 6200 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6201 {
93df3340
AM
6202 /* A corresponding .dynamic section is expected, but on
6203 IA-64/OpenVMS it is OK for it to be missing. */
6204 if (!is_ia64_vms (filedata))
6205 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6206 break;
6207 }
6208
42bb2e33 6209 if (sec->sh_type == SHT_NOBITS)
20737c13 6210 {
93df3340
AM
6211 dynamic_addr = 0;
6212 dynamic_size = 0;
20737c13
AM
6213 break;
6214 }
42bb2e33 6215
93df3340
AM
6216 dynamic_addr = sec->sh_offset;
6217 dynamic_size = sec->sh_size;
b2d38a17 6218
8ac10c5b
L
6219 /* The PT_DYNAMIC segment, which is used by the run-time
6220 loader, should exactly match the .dynamic section. */
6221 if (do_checks
93df3340
AM
6222 && (dynamic_addr != segment->p_offset
6223 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6224 warn (_("\
6225the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6226 }
39e224f6
MW
6227
6228 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6229 segment. Check this after matching against the section headers
6230 so we don't warn on debuginfo file (which have NOBITS .dynamic
6231 sections). */
93df3340
AM
6232 if (dynamic_addr > filedata->file_size
6233 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6234 {
6235 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6236 dynamic_addr = 0;
6237 dynamic_size = 0;
39e224f6 6238 }
252b5132
RH
6239 break;
6240
6241 case PT_INTERP:
13acb58d
AM
6242 if (segment->p_offset >= filedata->file_size
6243 || segment->p_filesz > filedata->file_size - segment->p_offset
6244 || segment->p_filesz - 1 >= (size_t) -2
6245 || fseek (filedata->handle,
6246 filedata->archive_file_offset + (long) segment->p_offset,
6247 SEEK_SET))
252b5132
RH
6248 error (_("Unable to find program interpreter name\n"));
6249 else
6250 {
13acb58d
AM
6251 size_t len = segment->p_filesz;
6252 free (filedata->program_interpreter);
6253 filedata->program_interpreter = xmalloc (len + 1);
6254 len = fread (filedata->program_interpreter, 1, len,
6255 filedata->handle);
6256 filedata->program_interpreter[len] = 0;
252b5132
RH
6257
6258 if (do_segments)
f54498b4 6259 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6260 filedata->program_interpreter);
252b5132
RH
6261 }
6262 break;
6263 }
252b5132
RH
6264 }
6265
dda8d76d
NC
6266 if (do_segments
6267 && filedata->section_headers != NULL
6268 && filedata->string_table != NULL)
252b5132
RH
6269 {
6270 printf (_("\n Section to Segment mapping:\n"));
6271 printf (_(" Segment Sections...\n"));
6272
dda8d76d 6273 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6274 {
9ad5cbcf 6275 unsigned int j;
2cf0635d 6276 Elf_Internal_Shdr * section;
252b5132 6277
dda8d76d
NC
6278 segment = filedata->program_headers + i;
6279 section = filedata->section_headers + 1;
252b5132
RH
6280
6281 printf (" %2.2d ", i);
6282
dda8d76d 6283 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6284 {
f4638467
AM
6285 if (!ELF_TBSS_SPECIAL (section, segment)
6286 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6287 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6288 }
6289
6290 putc ('\n',stdout);
6291 }
6292 }
6293
93df3340
AM
6294 filedata->dynamic_addr = dynamic_addr;
6295 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6296 return;
6297
6298 no_headers:
6299 filedata->dynamic_addr = 0;
6300 filedata->dynamic_size = 1;
252b5132
RH
6301}
6302
6303
d93f0186
NC
6304/* Find the file offset corresponding to VMA by using the program headers. */
6305
6306static long
dda8d76d 6307offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6308{
2cf0635d 6309 Elf_Internal_Phdr * seg;
d93f0186 6310
dda8d76d 6311 if (! get_program_headers (filedata))
d93f0186
NC
6312 {
6313 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6314 return (long) vma;
6315 }
6316
dda8d76d
NC
6317 for (seg = filedata->program_headers;
6318 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6319 ++seg)
6320 {
6321 if (seg->p_type != PT_LOAD)
6322 continue;
6323
6324 if (vma >= (seg->p_vaddr & -seg->p_align)
6325 && vma + size <= seg->p_vaddr + seg->p_filesz)
6326 return vma - seg->p_vaddr + seg->p_offset;
6327 }
6328
6329 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6330 (unsigned long) vma);
d93f0186
NC
6331 return (long) vma;
6332}
6333
6334
dda8d76d
NC
6335/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6336 If PROBE is true, this is just a probe and we do not generate any error
6337 messages if the load fails. */
049b0c3a 6338
015dc7e1
AM
6339static bool
6340get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6341{
2cf0635d
NC
6342 Elf32_External_Shdr * shdrs;
6343 Elf_Internal_Shdr * internal;
dda8d76d
NC
6344 unsigned int i;
6345 unsigned int size = filedata->file_header.e_shentsize;
6346 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6347
6348 /* PR binutils/17531: Cope with unexpected section header sizes. */
6349 if (size == 0 || num == 0)
015dc7e1 6350 return false;
049b0c3a
NC
6351 if (size < sizeof * shdrs)
6352 {
6353 if (! probe)
6354 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6355 return false;
049b0c3a
NC
6356 }
6357 if (!probe && size > sizeof * shdrs)
6358 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6359
dda8d76d 6360 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6361 size, num,
6362 probe ? NULL : _("section headers"));
6363 if (shdrs == NULL)
015dc7e1 6364 return false;
252b5132 6365
dda8d76d
NC
6366 filedata->section_headers = (Elf_Internal_Shdr *)
6367 cmalloc (num, sizeof (Elf_Internal_Shdr));
6368 if (filedata->section_headers == NULL)
252b5132 6369 {
049b0c3a 6370 if (!probe)
8b73c356 6371 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6372 free (shdrs);
015dc7e1 6373 return false;
252b5132
RH
6374 }
6375
dda8d76d 6376 for (i = 0, internal = filedata->section_headers;
560f3c1c 6377 i < num;
b34976b6 6378 i++, internal++)
252b5132
RH
6379 {
6380 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6381 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6382 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6383 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6384 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6385 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6386 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6387 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6388 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6389 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6390 if (!probe && internal->sh_link > num)
6391 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6392 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6393 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6394 }
6395
6396 free (shdrs);
015dc7e1 6397 return true;
252b5132
RH
6398}
6399
dda8d76d
NC
6400/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6401
015dc7e1
AM
6402static bool
6403get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6404{
dda8d76d
NC
6405 Elf64_External_Shdr * shdrs;
6406 Elf_Internal_Shdr * internal;
6407 unsigned int i;
6408 unsigned int size = filedata->file_header.e_shentsize;
6409 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6410
6411 /* PR binutils/17531: Cope with unexpected section header sizes. */
6412 if (size == 0 || num == 0)
015dc7e1 6413 return false;
dda8d76d 6414
049b0c3a
NC
6415 if (size < sizeof * shdrs)
6416 {
6417 if (! probe)
6418 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6419 return false;
049b0c3a 6420 }
dda8d76d 6421
049b0c3a
NC
6422 if (! probe && size > sizeof * shdrs)
6423 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6424
dda8d76d
NC
6425 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6426 filedata->file_header.e_shoff,
049b0c3a
NC
6427 size, num,
6428 probe ? NULL : _("section headers"));
6429 if (shdrs == NULL)
015dc7e1 6430 return false;
9ea033b2 6431
dda8d76d
NC
6432 filedata->section_headers = (Elf_Internal_Shdr *)
6433 cmalloc (num, sizeof (Elf_Internal_Shdr));
6434 if (filedata->section_headers == NULL)
9ea033b2 6435 {
049b0c3a 6436 if (! probe)
8b73c356 6437 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6438 free (shdrs);
015dc7e1 6439 return false;
9ea033b2
NC
6440 }
6441
dda8d76d 6442 for (i = 0, internal = filedata->section_headers;
560f3c1c 6443 i < num;
b34976b6 6444 i++, internal++)
9ea033b2
NC
6445 {
6446 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6447 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6448 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6449 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6450 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6451 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6452 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6453 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6454 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6455 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6456 if (!probe && internal->sh_link > num)
6457 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6458 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6459 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6460 }
6461
6462 free (shdrs);
015dc7e1 6463 return true;
9ea033b2
NC
6464}
6465
4de91c10
AM
6466static bool
6467get_section_headers (Filedata *filedata, bool probe)
6468{
6469 if (filedata->section_headers != NULL)
6470 return true;
6471
4de91c10
AM
6472 if (is_32bit_elf)
6473 return get_32bit_section_headers (filedata, probe);
6474 else
6475 return get_64bit_section_headers (filedata, probe);
6476}
6477
252b5132 6478static Elf_Internal_Sym *
dda8d76d
NC
6479get_32bit_elf_symbols (Filedata * filedata,
6480 Elf_Internal_Shdr * section,
6481 unsigned long * num_syms_return)
252b5132 6482{
ba5cdace 6483 unsigned long number = 0;
dd24e3da 6484 Elf32_External_Sym * esyms = NULL;
ba5cdace 6485 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6486 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6487 Elf_Internal_Sym * psym;
b34976b6 6488 unsigned int j;
e3d39609 6489 elf_section_list * entry;
252b5132 6490
c9c1d674
EG
6491 if (section->sh_size == 0)
6492 {
6493 if (num_syms_return != NULL)
6494 * num_syms_return = 0;
6495 return NULL;
6496 }
6497
dd24e3da 6498 /* Run some sanity checks first. */
c9c1d674 6499 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6500 {
c9c1d674 6501 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6502 printable_section_name (filedata, section),
6503 (unsigned long) section->sh_entsize);
ba5cdace 6504 goto exit_point;
dd24e3da
NC
6505 }
6506
dda8d76d 6507 if (section->sh_size > filedata->file_size)
f54498b4
NC
6508 {
6509 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6510 printable_section_name (filedata, section),
6511 (unsigned long) section->sh_size);
f54498b4
NC
6512 goto exit_point;
6513 }
6514
dd24e3da
NC
6515 number = section->sh_size / section->sh_entsize;
6516
6517 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6518 {
c9c1d674 6519 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6520 (unsigned long) section->sh_size,
dda8d76d 6521 printable_section_name (filedata, section),
8066deb1 6522 (unsigned long) section->sh_entsize);
ba5cdace 6523 goto exit_point;
dd24e3da
NC
6524 }
6525
dda8d76d 6526 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6527 section->sh_size, _("symbols"));
dd24e3da 6528 if (esyms == NULL)
ba5cdace 6529 goto exit_point;
252b5132 6530
e3d39609 6531 shndx = NULL;
978c4450 6532 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6533 {
6534 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6535 continue;
6536
6537 if (shndx != NULL)
6538 {
6539 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6540 free (shndx);
6541 }
6542
6543 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6544 entry->hdr->sh_offset,
6545 1, entry->hdr->sh_size,
6546 _("symbol table section indices"));
6547 if (shndx == NULL)
6548 goto exit_point;
6549
6550 /* PR17531: file: heap-buffer-overflow */
6551 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6552 {
6553 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6554 printable_section_name (filedata, entry->hdr),
6555 (unsigned long) entry->hdr->sh_size,
6556 (unsigned long) section->sh_size);
6557 goto exit_point;
c9c1d674 6558 }
e3d39609 6559 }
9ad5cbcf 6560
3f5e193b 6561 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6562
6563 if (isyms == NULL)
6564 {
8b73c356
NC
6565 error (_("Out of memory reading %lu symbols\n"),
6566 (unsigned long) number);
dd24e3da 6567 goto exit_point;
252b5132
RH
6568 }
6569
dd24e3da 6570 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6571 {
6572 psym->st_name = BYTE_GET (esyms[j].st_name);
6573 psym->st_value = BYTE_GET (esyms[j].st_value);
6574 psym->st_size = BYTE_GET (esyms[j].st_size);
6575 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6576 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6577 psym->st_shndx
6578 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6579 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6580 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6581 psym->st_info = BYTE_GET (esyms[j].st_info);
6582 psym->st_other = BYTE_GET (esyms[j].st_other);
6583 }
6584
dd24e3da 6585 exit_point:
e3d39609
NC
6586 free (shndx);
6587 free (esyms);
252b5132 6588
ba5cdace
NC
6589 if (num_syms_return != NULL)
6590 * num_syms_return = isyms == NULL ? 0 : number;
6591
252b5132
RH
6592 return isyms;
6593}
6594
9ea033b2 6595static Elf_Internal_Sym *
dda8d76d
NC
6596get_64bit_elf_symbols (Filedata * filedata,
6597 Elf_Internal_Shdr * section,
6598 unsigned long * num_syms_return)
9ea033b2 6599{
ba5cdace
NC
6600 unsigned long number = 0;
6601 Elf64_External_Sym * esyms = NULL;
6602 Elf_External_Sym_Shndx * shndx = NULL;
6603 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6604 Elf_Internal_Sym * psym;
b34976b6 6605 unsigned int j;
e3d39609 6606 elf_section_list * entry;
9ea033b2 6607
c9c1d674
EG
6608 if (section->sh_size == 0)
6609 {
6610 if (num_syms_return != NULL)
6611 * num_syms_return = 0;
6612 return NULL;
6613 }
6614
dd24e3da 6615 /* Run some sanity checks first. */
c9c1d674 6616 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6617 {
c9c1d674 6618 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6619 printable_section_name (filedata, section),
8066deb1 6620 (unsigned long) section->sh_entsize);
ba5cdace 6621 goto exit_point;
dd24e3da
NC
6622 }
6623
dda8d76d 6624 if (section->sh_size > filedata->file_size)
f54498b4
NC
6625 {
6626 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6627 printable_section_name (filedata, section),
8066deb1 6628 (unsigned long) section->sh_size);
f54498b4
NC
6629 goto exit_point;
6630 }
6631
dd24e3da
NC
6632 number = section->sh_size / section->sh_entsize;
6633
6634 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6635 {
c9c1d674 6636 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6637 (unsigned long) section->sh_size,
dda8d76d 6638 printable_section_name (filedata, section),
8066deb1 6639 (unsigned long) section->sh_entsize);
ba5cdace 6640 goto exit_point;
dd24e3da
NC
6641 }
6642
dda8d76d 6643 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6644 section->sh_size, _("symbols"));
a6e9f9df 6645 if (!esyms)
ba5cdace 6646 goto exit_point;
9ea033b2 6647
e3d39609 6648 shndx = NULL;
978c4450 6649 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6650 {
6651 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6652 continue;
6653
6654 if (shndx != NULL)
6655 {
6656 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6657 free (shndx);
c9c1d674 6658 }
e3d39609
NC
6659
6660 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6661 entry->hdr->sh_offset,
6662 1, entry->hdr->sh_size,
6663 _("symbol table section indices"));
6664 if (shndx == NULL)
6665 goto exit_point;
6666
6667 /* PR17531: file: heap-buffer-overflow */
6668 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6669 {
6670 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6671 printable_section_name (filedata, entry->hdr),
6672 (unsigned long) entry->hdr->sh_size,
6673 (unsigned long) section->sh_size);
6674 goto exit_point;
6675 }
6676 }
9ad5cbcf 6677
3f5e193b 6678 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6679
6680 if (isyms == NULL)
6681 {
8b73c356
NC
6682 error (_("Out of memory reading %lu symbols\n"),
6683 (unsigned long) number);
ba5cdace 6684 goto exit_point;
9ea033b2
NC
6685 }
6686
ba5cdace 6687 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6688 {
6689 psym->st_name = BYTE_GET (esyms[j].st_name);
6690 psym->st_info = BYTE_GET (esyms[j].st_info);
6691 psym->st_other = BYTE_GET (esyms[j].st_other);
6692 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6693
4fbb74a6 6694 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6695 psym->st_shndx
6696 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6697 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6698 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6699
66543521
AM
6700 psym->st_value = BYTE_GET (esyms[j].st_value);
6701 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6702 }
6703
ba5cdace 6704 exit_point:
e3d39609
NC
6705 free (shndx);
6706 free (esyms);
ba5cdace
NC
6707
6708 if (num_syms_return != NULL)
6709 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6710
6711 return isyms;
6712}
6713
4de91c10
AM
6714static Elf_Internal_Sym *
6715get_elf_symbols (Filedata *filedata,
6716 Elf_Internal_Shdr *section,
6717 unsigned long *num_syms_return)
6718{
6719 if (is_32bit_elf)
6720 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6721 else
6722 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6723}
6724
d1133906 6725static const char *
dda8d76d 6726get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6727{
5477e8a0 6728 static char buff[1024];
2cf0635d 6729 char * p = buff;
32ec8896
NC
6730 unsigned int field_size = is_32bit_elf ? 8 : 16;
6731 signed int sindex;
6732 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6733 bfd_vma os_flags = 0;
6734 bfd_vma proc_flags = 0;
6735 bfd_vma unknown_flags = 0;
148b93f2 6736 static const struct
5477e8a0 6737 {
2cf0635d 6738 const char * str;
32ec8896 6739 unsigned int len;
5477e8a0
L
6740 }
6741 flags [] =
6742 {
cfcac11d
NC
6743 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6744 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6745 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6746 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6747 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6748 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6749 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6750 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6751 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6752 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6753 /* IA-64 specific. */
6754 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6755 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6756 /* IA-64 OpenVMS specific. */
6757 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6758 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6759 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6760 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6761 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6762 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6763 /* Generic. */
cfcac11d 6764 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6765 /* SPARC specific. */
77115a4a 6766 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6767 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6768 /* ARM specific. */
6769 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6770 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6771 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6772 /* GNU specific. */
6773 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6774 /* VLE specific. */
6775 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6776 /* GNU specific. */
6777 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6778 };
6779
6780 if (do_section_details)
6781 {
8d5ff12c
L
6782 sprintf (buff, "[%*.*lx]: ",
6783 field_size, field_size, (unsigned long) sh_flags);
6784 p += field_size + 4;
5477e8a0 6785 }
76da6bbe 6786
d1133906
NC
6787 while (sh_flags)
6788 {
6789 bfd_vma flag;
6790
6791 flag = sh_flags & - sh_flags;
6792 sh_flags &= ~ flag;
76da6bbe 6793
5477e8a0 6794 if (do_section_details)
d1133906 6795 {
5477e8a0
L
6796 switch (flag)
6797 {
91d6fa6a
NC
6798 case SHF_WRITE: sindex = 0; break;
6799 case SHF_ALLOC: sindex = 1; break;
6800 case SHF_EXECINSTR: sindex = 2; break;
6801 case SHF_MERGE: sindex = 3; break;
6802 case SHF_STRINGS: sindex = 4; break;
6803 case SHF_INFO_LINK: sindex = 5; break;
6804 case SHF_LINK_ORDER: sindex = 6; break;
6805 case SHF_OS_NONCONFORMING: sindex = 7; break;
6806 case SHF_GROUP: sindex = 8; break;
6807 case SHF_TLS: sindex = 9; break;
18ae9cc1 6808 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6809 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6810
5477e8a0 6811 default:
91d6fa6a 6812 sindex = -1;
dda8d76d 6813 switch (filedata->file_header.e_machine)
148b93f2 6814 {
cfcac11d 6815 case EM_IA_64:
148b93f2 6816 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6817 sindex = 10;
148b93f2 6818 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6819 sindex = 11;
148b93f2 6820#ifdef BFD64
dda8d76d 6821 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6822 switch (flag)
6823 {
91d6fa6a
NC
6824 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6825 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6826 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6827 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6828 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6829 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6830 default: break;
6831 }
6832#endif
cfcac11d
NC
6833 break;
6834
caa83f8b 6835 case EM_386:
22abe556 6836 case EM_IAMCU:
caa83f8b 6837 case EM_X86_64:
7f502d6c 6838 case EM_L1OM:
7a9068fe 6839 case EM_K1OM:
cfcac11d
NC
6840 case EM_OLD_SPARCV9:
6841 case EM_SPARC32PLUS:
6842 case EM_SPARCV9:
6843 case EM_SPARC:
18ae9cc1 6844 if (flag == SHF_ORDERED)
91d6fa6a 6845 sindex = 19;
cfcac11d 6846 break;
ac4c9b04
MG
6847
6848 case EM_ARM:
6849 switch (flag)
6850 {
6851 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6852 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6853 case SHF_COMDEF: sindex = 23; break;
6854 default: break;
6855 }
6856 break;
83eef883
AFB
6857 case EM_PPC:
6858 if (flag == SHF_PPC_VLE)
6859 sindex = 25;
6860 break;
99fabbc9
JL
6861 default:
6862 break;
6863 }
ac4c9b04 6864
99fabbc9
JL
6865 switch (filedata->file_header.e_ident[EI_OSABI])
6866 {
6867 case ELFOSABI_GNU:
6868 case ELFOSABI_FREEBSD:
6869 if (flag == SHF_GNU_RETAIN)
6870 sindex = 26;
6871 /* Fall through */
6872 case ELFOSABI_NONE:
6873 if (flag == SHF_GNU_MBIND)
6874 /* We should not recognize SHF_GNU_MBIND for
6875 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6876 not set the EI_OSABI header byte. */
6877 sindex = 24;
6878 break;
cfcac11d
NC
6879 default:
6880 break;
148b93f2 6881 }
99fabbc9 6882 break;
5477e8a0
L
6883 }
6884
91d6fa6a 6885 if (sindex != -1)
5477e8a0 6886 {
8d5ff12c
L
6887 if (p != buff + field_size + 4)
6888 {
6889 if (size < (10 + 2))
bee0ee85
NC
6890 {
6891 warn (_("Internal error: not enough buffer room for section flag info"));
6892 return _("<unknown>");
6893 }
8d5ff12c
L
6894 size -= 2;
6895 *p++ = ',';
6896 *p++ = ' ';
6897 }
6898
91d6fa6a
NC
6899 size -= flags [sindex].len;
6900 p = stpcpy (p, flags [sindex].str);
5477e8a0 6901 }
3b22753a 6902 else if (flag & SHF_MASKOS)
8d5ff12c 6903 os_flags |= flag;
d1133906 6904 else if (flag & SHF_MASKPROC)
8d5ff12c 6905 proc_flags |= flag;
d1133906 6906 else
8d5ff12c 6907 unknown_flags |= flag;
5477e8a0
L
6908 }
6909 else
6910 {
6911 switch (flag)
6912 {
6913 case SHF_WRITE: *p = 'W'; break;
6914 case SHF_ALLOC: *p = 'A'; break;
6915 case SHF_EXECINSTR: *p = 'X'; break;
6916 case SHF_MERGE: *p = 'M'; break;
6917 case SHF_STRINGS: *p = 'S'; break;
6918 case SHF_INFO_LINK: *p = 'I'; break;
6919 case SHF_LINK_ORDER: *p = 'L'; break;
6920 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6921 case SHF_GROUP: *p = 'G'; break;
6922 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6923 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6924 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6925
6926 default:
dda8d76d
NC
6927 if ((filedata->file_header.e_machine == EM_X86_64
6928 || filedata->file_header.e_machine == EM_L1OM
6929 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6930 && flag == SHF_X86_64_LARGE)
6931 *p = 'l';
dda8d76d 6932 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6933 && flag == SHF_ARM_PURECODE)
99fabbc9 6934 *p = 'y';
dda8d76d 6935 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6936 && flag == SHF_PPC_VLE)
99fabbc9 6937 *p = 'v';
5477e8a0
L
6938 else if (flag & SHF_MASKOS)
6939 {
99fabbc9
JL
6940 switch (filedata->file_header.e_ident[EI_OSABI])
6941 {
6942 case ELFOSABI_GNU:
6943 case ELFOSABI_FREEBSD:
6944 if (flag == SHF_GNU_RETAIN)
6945 {
6946 *p = 'R';
6947 break;
6948 }
6949 /* Fall through */
6950 case ELFOSABI_NONE:
6951 if (flag == SHF_GNU_MBIND)
6952 {
6953 /* We should not recognize SHF_GNU_MBIND for
6954 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6955 not set the EI_OSABI header byte. */
6956 *p = 'D';
6957 break;
6958 }
6959 /* Fall through */
6960 default:
6961 *p = 'o';
6962 sh_flags &= ~SHF_MASKOS;
6963 break;
6964 }
5477e8a0
L
6965 }
6966 else if (flag & SHF_MASKPROC)
6967 {
6968 *p = 'p';
6969 sh_flags &= ~ SHF_MASKPROC;
6970 }
6971 else
6972 *p = 'x';
6973 break;
6974 }
6975 p++;
d1133906
NC
6976 }
6977 }
76da6bbe 6978
8d5ff12c
L
6979 if (do_section_details)
6980 {
6981 if (os_flags)
6982 {
6983 size -= 5 + field_size;
6984 if (p != buff + field_size + 4)
6985 {
6986 if (size < (2 + 1))
bee0ee85
NC
6987 {
6988 warn (_("Internal error: not enough buffer room for section flag info"));
6989 return _("<unknown>");
6990 }
8d5ff12c
L
6991 size -= 2;
6992 *p++ = ',';
6993 *p++ = ' ';
6994 }
6995 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6996 (unsigned long) os_flags);
6997 p += 5 + field_size;
6998 }
6999 if (proc_flags)
7000 {
7001 size -= 7 + field_size;
7002 if (p != buff + field_size + 4)
7003 {
7004 if (size < (2 + 1))
bee0ee85
NC
7005 {
7006 warn (_("Internal error: not enough buffer room for section flag info"));
7007 return _("<unknown>");
7008 }
8d5ff12c
L
7009 size -= 2;
7010 *p++ = ',';
7011 *p++ = ' ';
7012 }
7013 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7014 (unsigned long) proc_flags);
7015 p += 7 + field_size;
7016 }
7017 if (unknown_flags)
7018 {
7019 size -= 10 + field_size;
7020 if (p != buff + field_size + 4)
7021 {
7022 if (size < (2 + 1))
bee0ee85
NC
7023 {
7024 warn (_("Internal error: not enough buffer room for section flag info"));
7025 return _("<unknown>");
7026 }
8d5ff12c
L
7027 size -= 2;
7028 *p++ = ',';
7029 *p++ = ' ';
7030 }
2b692964 7031 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7032 (unsigned long) unknown_flags);
7033 p += 10 + field_size;
7034 }
7035 }
7036
e9e44622 7037 *p = '\0';
d1133906
NC
7038 return buff;
7039}
7040
5844b465 7041static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 7042get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
7043{
7044 if (is_32bit_elf)
7045 {
7046 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7047
ebdf1ebf
NC
7048 if (size < sizeof (* echdr))
7049 {
7050 error (_("Compressed section is too small even for a compression header\n"));
7051 return 0;
7052 }
7053
77115a4a
L
7054 chdr->ch_type = BYTE_GET (echdr->ch_type);
7055 chdr->ch_size = BYTE_GET (echdr->ch_size);
7056 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7057 return sizeof (*echdr);
7058 }
7059 else
7060 {
7061 Elf64_External_Chdr *echdr = (Elf64_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}
7075
015dc7e1 7076static bool
dda8d76d 7077process_section_headers (Filedata * filedata)
252b5132 7078{
2cf0635d 7079 Elf_Internal_Shdr * section;
b34976b6 7080 unsigned int i;
252b5132 7081
dda8d76d 7082 if (filedata->file_header.e_shnum == 0)
252b5132 7083 {
82f2dbf7 7084 /* PR binutils/12467. */
dda8d76d 7085 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7086 {
7087 warn (_("possibly corrupt ELF file header - it has a non-zero"
7088 " section header offset, but no section headers\n"));
015dc7e1 7089 return false;
32ec8896 7090 }
82f2dbf7 7091 else if (do_sections)
252b5132
RH
7092 printf (_("\nThere are no sections in this file.\n"));
7093
015dc7e1 7094 return true;
252b5132
RH
7095 }
7096
7097 if (do_sections && !do_header)
ca0e11aa
NC
7098 {
7099 if (filedata->is_separate && process_links)
7100 printf (_("In linked file '%s': "), filedata->file_name);
7101 if (! filedata->is_separate || process_links)
7102 printf (ngettext ("There is %d section header, "
7103 "starting at offset 0x%lx:\n",
7104 "There are %d section headers, "
7105 "starting at offset 0x%lx:\n",
7106 filedata->file_header.e_shnum),
7107 filedata->file_header.e_shnum,
7108 (unsigned long) filedata->file_header.e_shoff);
7109 }
252b5132 7110
4de91c10
AM
7111 if (!get_section_headers (filedata, false))
7112 return false;
252b5132
RH
7113
7114 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7115 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7116 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7117 {
dda8d76d 7118 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7119
c256ffe7
JJ
7120 if (section->sh_size != 0)
7121 {
dda8d76d
NC
7122 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7123 1, section->sh_size,
7124 _("string table"));
0de14b54 7125
dda8d76d 7126 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7127 }
252b5132
RH
7128 }
7129
7130 /* Scan the sections for the dynamic symbol table
e3c8793a 7131 and dynamic string table and debug sections. */
89fac5e3 7132 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7133 switch (filedata->file_header.e_machine)
89fac5e3
RS
7134 {
7135 case EM_MIPS:
7136 case EM_MIPS_RS3_LE:
7137 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7138 FDE addresses. However, the ABI also has a semi-official ILP32
7139 variant for which the normal FDE address size rules apply.
7140
7141 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7142 section, where XX is the size of longs in bits. Unfortunately,
7143 earlier compilers provided no way of distinguishing ILP32 objects
7144 from LP64 objects, so if there's any doubt, we should assume that
7145 the official LP64 form is being used. */
dda8d76d
NC
7146 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7147 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7148 eh_addr_size = 8;
7149 break;
0f56a26a
DD
7150
7151 case EM_H8_300:
7152 case EM_H8_300H:
dda8d76d 7153 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7154 {
7155 case E_H8_MACH_H8300:
7156 case E_H8_MACH_H8300HN:
7157 case E_H8_MACH_H8300SN:
7158 case E_H8_MACH_H8300SXN:
7159 eh_addr_size = 2;
7160 break;
7161 case E_H8_MACH_H8300H:
7162 case E_H8_MACH_H8300S:
7163 case E_H8_MACH_H8300SX:
7164 eh_addr_size = 4;
7165 break;
7166 }
f4236fe4
DD
7167 break;
7168
ff7eeb89 7169 case EM_M32C_OLD:
f4236fe4 7170 case EM_M32C:
dda8d76d 7171 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7172 {
7173 case EF_M32C_CPU_M16C:
7174 eh_addr_size = 2;
7175 break;
7176 }
7177 break;
89fac5e3
RS
7178 }
7179
76ca31c0
NC
7180#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7181 do \
7182 { \
7183 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7184 if (section->sh_entsize != expected_entsize) \
9dd3a467 7185 { \
76ca31c0
NC
7186 char buf[40]; \
7187 sprintf_vma (buf, section->sh_entsize); \
7188 /* Note: coded this way so that there is a single string for \
7189 translation. */ \
7190 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7191 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7192 (unsigned) expected_entsize); \
9dd3a467 7193 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7194 } \
7195 } \
08d8fa11 7196 while (0)
9dd3a467
NC
7197
7198#define CHECK_ENTSIZE(section, i, type) \
1b513401 7199 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7200 sizeof (Elf64_External_##type))
7201
dda8d76d
NC
7202 for (i = 0, section = filedata->section_headers;
7203 i < filedata->file_header.e_shnum;
b34976b6 7204 i++, section++)
252b5132 7205 {
84714f86 7206 const char *name = section_name_print (filedata, section);
252b5132 7207
1b513401
NC
7208 /* Run some sanity checks on the headers and
7209 possibly fill in some file data as well. */
7210 switch (section->sh_type)
252b5132 7211 {
1b513401 7212 case SHT_DYNSYM:
978c4450 7213 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7214 {
7215 error (_("File contains multiple dynamic symbol tables\n"));
7216 continue;
7217 }
7218
08d8fa11 7219 CHECK_ENTSIZE (section, i, Sym);
978c4450 7220 filedata->dynamic_symbols
4de91c10 7221 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7222 filedata->dynamic_symtab_section = section;
1b513401
NC
7223 break;
7224
7225 case SHT_STRTAB:
7226 if (streq (name, ".dynstr"))
252b5132 7227 {
1b513401
NC
7228 if (filedata->dynamic_strings != NULL)
7229 {
7230 error (_("File contains multiple dynamic string tables\n"));
7231 continue;
7232 }
7233
7234 filedata->dynamic_strings
7235 = (char *) get_data (NULL, filedata, section->sh_offset,
7236 1, section->sh_size, _("dynamic strings"));
7237 filedata->dynamic_strings_length
7238 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7239 filedata->dynamic_strtab_section = section;
252b5132 7240 }
1b513401
NC
7241 break;
7242
7243 case SHT_SYMTAB_SHNDX:
7244 {
7245 elf_section_list * entry = xmalloc (sizeof * entry);
7246
7247 entry->hdr = section;
7248 entry->next = filedata->symtab_shndx_list;
7249 filedata->symtab_shndx_list = entry;
7250 }
7251 break;
7252
7253 case SHT_SYMTAB:
7254 CHECK_ENTSIZE (section, i, Sym);
7255 break;
7256
7257 case SHT_GROUP:
7258 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7259 break;
252b5132 7260
1b513401
NC
7261 case SHT_REL:
7262 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7263 if (do_checks && section->sh_size == 0)
1b513401
NC
7264 warn (_("Section '%s': zero-sized relocation section\n"), name);
7265 break;
7266
7267 case SHT_RELA:
7268 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7269 if (do_checks && section->sh_size == 0)
1b513401
NC
7270 warn (_("Section '%s': zero-sized relocation section\n"), name);
7271 break;
7272
682351b9
AM
7273 case SHT_RELR:
7274 CHECK_ENTSIZE (section, i, Relr);
7275 break;
7276
1b513401
NC
7277 case SHT_NOTE:
7278 case SHT_PROGBITS:
546cb2d8
NC
7279 /* Having a zero sized section is not illegal according to the
7280 ELF standard, but it might be an indication that something
7281 is wrong. So issue a warning if we are running in lint mode. */
7282 if (do_checks && section->sh_size == 0)
1b513401
NC
7283 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7284 break;
7285
7286 default:
7287 break;
7288 }
7289
7290 if ((do_debugging || do_debug_info || do_debug_abbrevs
7291 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7292 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7293 || do_debug_str || do_debug_str_offsets || do_debug_loc
7294 || do_debug_ranges
1b513401 7295 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7296 && (startswith (name, ".debug_")
7297 || startswith (name, ".zdebug_")))
252b5132 7298 {
1b315056
CS
7299 if (name[1] == 'z')
7300 name += sizeof (".zdebug_") - 1;
7301 else
7302 name += sizeof (".debug_") - 1;
252b5132
RH
7303
7304 if (do_debugging
24d127aa
ML
7305 || (do_debug_info && startswith (name, "info"))
7306 || (do_debug_info && startswith (name, "types"))
7307 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7308 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7309 || (do_debug_lines && startswith (name, "line."))
7310 || (do_debug_pubnames && startswith (name, "pubnames"))
7311 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7312 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7313 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7314 || (do_debug_aranges && startswith (name, "aranges"))
7315 || (do_debug_ranges && startswith (name, "ranges"))
7316 || (do_debug_ranges && startswith (name, "rnglists"))
7317 || (do_debug_frames && startswith (name, "frame"))
7318 || (do_debug_macinfo && startswith (name, "macinfo"))
7319 || (do_debug_macinfo && startswith (name, "macro"))
7320 || (do_debug_str && startswith (name, "str"))
7321 || (do_debug_links && startswith (name, "sup"))
7322 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7323 || (do_debug_loc && startswith (name, "loc"))
7324 || (do_debug_loc && startswith (name, "loclists"))
7325 || (do_debug_addr && startswith (name, "addr"))
7326 || (do_debug_cu_index && startswith (name, "cu_index"))
7327 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7328 )
6431e409 7329 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7330 }
a262ae96 7331 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7332 else if ((do_debugging || do_debug_info)
24d127aa 7333 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7334 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7335 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7336 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7337 else if (do_gdb_index && (streq (name, ".gdb_index")
7338 || streq (name, ".debug_names")))
6431e409 7339 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7340 /* Trace sections for Itanium VMS. */
7341 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7342 || do_trace_aranges)
24d127aa 7343 && startswith (name, ".trace_"))
6f875884
TG
7344 {
7345 name += sizeof (".trace_") - 1;
7346
7347 if (do_debugging
7348 || (do_trace_info && streq (name, "info"))
7349 || (do_trace_abbrevs && streq (name, "abbrev"))
7350 || (do_trace_aranges && streq (name, "aranges"))
7351 )
6431e409 7352 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7353 }
dda8d76d 7354 else if ((do_debugging || do_debug_links)
24d127aa
ML
7355 && (startswith (name, ".gnu_debuglink")
7356 || startswith (name, ".gnu_debugaltlink")))
6431e409 7357 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7358 }
7359
7360 if (! do_sections)
015dc7e1 7361 return true;
252b5132 7362
ca0e11aa 7363 if (filedata->is_separate && ! process_links)
015dc7e1 7364 return true;
ca0e11aa
NC
7365
7366 if (filedata->is_separate)
7367 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7368 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7369 printf (_("\nSection Headers:\n"));
7370 else
7371 printf (_("\nSection Header:\n"));
76da6bbe 7372
f7a99963 7373 if (is_32bit_elf)
595cf52e 7374 {
5477e8a0 7375 if (do_section_details)
595cf52e
L
7376 {
7377 printf (_(" [Nr] Name\n"));
5477e8a0 7378 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7379 }
7380 else
7381 printf
7382 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7383 }
d974e256 7384 else if (do_wide)
595cf52e 7385 {
5477e8a0 7386 if (do_section_details)
595cf52e
L
7387 {
7388 printf (_(" [Nr] Name\n"));
5477e8a0 7389 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7390 }
7391 else
7392 printf
7393 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7394 }
f7a99963
NC
7395 else
7396 {
5477e8a0 7397 if (do_section_details)
595cf52e
L
7398 {
7399 printf (_(" [Nr] Name\n"));
5477e8a0
L
7400 printf (_(" Type Address Offset Link\n"));
7401 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7402 }
7403 else
7404 {
7405 printf (_(" [Nr] Name Type Address Offset\n"));
7406 printf (_(" Size EntSize Flags Link Info Align\n"));
7407 }
f7a99963 7408 }
252b5132 7409
5477e8a0
L
7410 if (do_section_details)
7411 printf (_(" Flags\n"));
7412
dda8d76d
NC
7413 for (i = 0, section = filedata->section_headers;
7414 i < filedata->file_header.e_shnum;
b34976b6 7415 i++, section++)
252b5132 7416 {
dd905818
NC
7417 /* Run some sanity checks on the section header. */
7418
7419 /* Check the sh_link field. */
7420 switch (section->sh_type)
7421 {
285e3f99
AM
7422 case SHT_REL:
7423 case SHT_RELA:
7424 if (section->sh_link == 0
7425 && (filedata->file_header.e_type == ET_EXEC
7426 || filedata->file_header.e_type == ET_DYN))
7427 /* A dynamic relocation section where all entries use a
7428 zero symbol index need not specify a symtab section. */
7429 break;
7430 /* Fall through. */
dd905818
NC
7431 case SHT_SYMTAB_SHNDX:
7432 case SHT_GROUP:
7433 case SHT_HASH:
7434 case SHT_GNU_HASH:
7435 case SHT_GNU_versym:
285e3f99 7436 if (section->sh_link == 0
dda8d76d
NC
7437 || section->sh_link >= filedata->file_header.e_shnum
7438 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7439 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7440 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7441 i, section->sh_link);
7442 break;
7443
7444 case SHT_DYNAMIC:
7445 case SHT_SYMTAB:
7446 case SHT_DYNSYM:
7447 case SHT_GNU_verneed:
7448 case SHT_GNU_verdef:
7449 case SHT_GNU_LIBLIST:
285e3f99 7450 if (section->sh_link == 0
dda8d76d
NC
7451 || section->sh_link >= filedata->file_header.e_shnum
7452 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7453 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7454 i, section->sh_link);
7455 break;
7456
7457 case SHT_INIT_ARRAY:
7458 case SHT_FINI_ARRAY:
7459 case SHT_PREINIT_ARRAY:
7460 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7461 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7462 i, section->sh_link);
7463 break;
7464
7465 default:
7466 /* FIXME: Add support for target specific section types. */
7467#if 0 /* Currently we do not check other section types as there are too
7468 many special cases. Stab sections for example have a type
7469 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7470 section. */
7471 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7472 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7473 i, section->sh_link);
7474#endif
7475 break;
7476 }
7477
7478 /* Check the sh_info field. */
7479 switch (section->sh_type)
7480 {
7481 case SHT_REL:
7482 case SHT_RELA:
285e3f99
AM
7483 if (section->sh_info == 0
7484 && (filedata->file_header.e_type == ET_EXEC
7485 || filedata->file_header.e_type == ET_DYN))
7486 /* Dynamic relocations apply to segments, so they do not
7487 need to specify the section they relocate. */
7488 break;
7489 if (section->sh_info == 0
dda8d76d
NC
7490 || section->sh_info >= filedata->file_header.e_shnum
7491 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7492 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7493 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7494 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7495 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7496 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7497 /* FIXME: Are other section types valid ? */
dda8d76d 7498 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7499 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7500 i, section->sh_info);
dd905818
NC
7501 break;
7502
7503 case SHT_DYNAMIC:
7504 case SHT_HASH:
7505 case SHT_SYMTAB_SHNDX:
7506 case SHT_INIT_ARRAY:
7507 case SHT_FINI_ARRAY:
7508 case SHT_PREINIT_ARRAY:
7509 if (section->sh_info != 0)
7510 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7511 i, section->sh_info);
7512 break;
7513
7514 case SHT_GROUP:
7515 case SHT_SYMTAB:
7516 case SHT_DYNSYM:
7517 /* A symbol index - we assume that it is valid. */
7518 break;
7519
7520 default:
7521 /* FIXME: Add support for target specific section types. */
7522 if (section->sh_type == SHT_NOBITS)
7523 /* NOBITS section headers with non-zero sh_info fields can be
7524 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7525 information. The stripped sections have their headers
7526 preserved but their types set to SHT_NOBITS. So do not check
7527 this type of section. */
dd905818
NC
7528 ;
7529 else if (section->sh_flags & SHF_INFO_LINK)
7530 {
dda8d76d 7531 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7532 warn (_("[%2u]: Expected link to another section in info field"), i);
7533 }
a91e1603
L
7534 else if (section->sh_type < SHT_LOOS
7535 && (section->sh_flags & SHF_GNU_MBIND) == 0
7536 && section->sh_info != 0)
dd905818
NC
7537 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7538 i, section->sh_info);
7539 break;
7540 }
7541
3e6b6445 7542 /* Check the sh_size field. */
dda8d76d 7543 if (section->sh_size > filedata->file_size
3e6b6445
NC
7544 && section->sh_type != SHT_NOBITS
7545 && section->sh_type != SHT_NULL
7546 && section->sh_type < SHT_LOOS)
7547 warn (_("Size of section %u is larger than the entire file!\n"), i);
7548
7bfd842d 7549 printf (" [%2u] ", i);
5477e8a0 7550 if (do_section_details)
dda8d76d 7551 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7552 else
84714f86 7553 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7554
ea52a088 7555 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7556 get_section_type_name (filedata, section->sh_type));
0b4362b0 7557
f7a99963
NC
7558 if (is_32bit_elf)
7559 {
cfcac11d
NC
7560 const char * link_too_big = NULL;
7561
f7a99963 7562 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7563
f7a99963
NC
7564 printf ( " %6.6lx %6.6lx %2.2lx",
7565 (unsigned long) section->sh_offset,
7566 (unsigned long) section->sh_size,
7567 (unsigned long) section->sh_entsize);
d1133906 7568
5477e8a0
L
7569 if (do_section_details)
7570 fputs (" ", stdout);
7571 else
dda8d76d 7572 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7573
dda8d76d 7574 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7575 {
7576 link_too_big = "";
7577 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7578 an error but it can have special values in Solaris binaries. */
dda8d76d 7579 switch (filedata->file_header.e_machine)
cfcac11d 7580 {
caa83f8b 7581 case EM_386:
22abe556 7582 case EM_IAMCU:
caa83f8b 7583 case EM_X86_64:
7f502d6c 7584 case EM_L1OM:
7a9068fe 7585 case EM_K1OM:
cfcac11d
NC
7586 case EM_OLD_SPARCV9:
7587 case EM_SPARC32PLUS:
7588 case EM_SPARCV9:
7589 case EM_SPARC:
7590 if (section->sh_link == (SHN_BEFORE & 0xffff))
7591 link_too_big = "BEFORE";
7592 else if (section->sh_link == (SHN_AFTER & 0xffff))
7593 link_too_big = "AFTER";
7594 break;
7595 default:
7596 break;
7597 }
7598 }
7599
7600 if (do_section_details)
7601 {
7602 if (link_too_big != NULL && * link_too_big)
7603 printf ("<%s> ", link_too_big);
7604 else
7605 printf ("%2u ", section->sh_link);
7606 printf ("%3u %2lu\n", section->sh_info,
7607 (unsigned long) section->sh_addralign);
7608 }
7609 else
7610 printf ("%2u %3u %2lu\n",
7611 section->sh_link,
7612 section->sh_info,
7613 (unsigned long) section->sh_addralign);
7614
7615 if (link_too_big && ! * link_too_big)
7616 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7617 i, section->sh_link);
f7a99963 7618 }
d974e256
JJ
7619 else if (do_wide)
7620 {
7621 print_vma (section->sh_addr, LONG_HEX);
7622
7623 if ((long) section->sh_offset == section->sh_offset)
7624 printf (" %6.6lx", (unsigned long) section->sh_offset);
7625 else
7626 {
7627 putchar (' ');
7628 print_vma (section->sh_offset, LONG_HEX);
7629 }
7630
7631 if ((unsigned long) section->sh_size == section->sh_size)
7632 printf (" %6.6lx", (unsigned long) section->sh_size);
7633 else
7634 {
7635 putchar (' ');
7636 print_vma (section->sh_size, LONG_HEX);
7637 }
7638
7639 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7640 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7641 else
7642 {
7643 putchar (' ');
7644 print_vma (section->sh_entsize, LONG_HEX);
7645 }
7646
5477e8a0
L
7647 if (do_section_details)
7648 fputs (" ", stdout);
7649 else
dda8d76d 7650 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7651
72de5009 7652 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7653
7654 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7655 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7656 else
7657 {
7658 print_vma (section->sh_addralign, DEC);
7659 putchar ('\n');
7660 }
7661 }
5477e8a0 7662 else if (do_section_details)
595cf52e 7663 {
55cc53e9 7664 putchar (' ');
595cf52e
L
7665 print_vma (section->sh_addr, LONG_HEX);
7666 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7667 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7668 else
7669 {
7670 printf (" ");
7671 print_vma (section->sh_offset, LONG_HEX);
7672 }
72de5009 7673 printf (" %u\n ", section->sh_link);
595cf52e 7674 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7675 putchar (' ');
595cf52e
L
7676 print_vma (section->sh_entsize, LONG_HEX);
7677
72de5009
AM
7678 printf (" %-16u %lu\n",
7679 section->sh_info,
595cf52e
L
7680 (unsigned long) section->sh_addralign);
7681 }
f7a99963
NC
7682 else
7683 {
7684 putchar (' ');
7685 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7686 if ((long) section->sh_offset == section->sh_offset)
7687 printf (" %8.8lx", (unsigned long) section->sh_offset);
7688 else
7689 {
7690 printf (" ");
7691 print_vma (section->sh_offset, LONG_HEX);
7692 }
f7a99963
NC
7693 printf ("\n ");
7694 print_vma (section->sh_size, LONG_HEX);
7695 printf (" ");
7696 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7697
dda8d76d 7698 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7699
72de5009
AM
7700 printf (" %2u %3u %lu\n",
7701 section->sh_link,
7702 section->sh_info,
f7a99963
NC
7703 (unsigned long) section->sh_addralign);
7704 }
5477e8a0
L
7705
7706 if (do_section_details)
77115a4a 7707 {
dda8d76d 7708 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7709 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7710 {
7711 /* Minimum section size is 12 bytes for 32-bit compression
7712 header + 12 bytes for compressed data header. */
7713 unsigned char buf[24];
d8024a91 7714
77115a4a 7715 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7716 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7717 sizeof (buf), _("compression header")))
7718 {
7719 Elf_Internal_Chdr chdr;
d8024a91 7720
5844b465
NC
7721 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7722 printf (_(" [<corrupt>]\n"));
77115a4a 7723 else
5844b465
NC
7724 {
7725 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7726 printf (" ZLIB, ");
7727 else
7728 printf (_(" [<unknown>: 0x%x], "),
7729 chdr.ch_type);
7730 print_vma (chdr.ch_size, LONG_HEX);
7731 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7732 }
77115a4a
L
7733 }
7734 }
7735 }
252b5132
RH
7736 }
7737
5477e8a0 7738 if (!do_section_details)
3dbcc61d 7739 {
9fb71ee4
NC
7740 /* The ordering of the letters shown here matches the ordering of the
7741 corresponding SHF_xxx values, and hence the order in which these
7742 letters will be displayed to the user. */
7743 printf (_("Key to Flags:\n\
7744 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7745 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7746 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7747 switch (filedata->file_header.e_ident[EI_OSABI])
7748 {
7749 case ELFOSABI_GNU:
7750 case ELFOSABI_FREEBSD:
7751 printf (_("R (retain), "));
7752 /* Fall through */
7753 case ELFOSABI_NONE:
7754 printf (_("D (mbind), "));
7755 break;
7756 default:
7757 break;
7758 }
dda8d76d
NC
7759 if (filedata->file_header.e_machine == EM_X86_64
7760 || filedata->file_header.e_machine == EM_L1OM
7761 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7762 printf (_("l (large), "));
dda8d76d 7763 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7764 printf (_("y (purecode), "));
dda8d76d 7765 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7766 printf (_("v (VLE), "));
9fb71ee4 7767 printf ("p (processor specific)\n");
0b4362b0 7768 }
d1133906 7769
015dc7e1 7770 return true;
252b5132
RH
7771}
7772
015dc7e1 7773static bool
28d13567
AM
7774get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7775 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7776 char **strtab, unsigned long *strtablen)
7777{
7778 *strtab = NULL;
7779 *strtablen = 0;
4de91c10 7780 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7781
7782 if (*symtab == NULL)
015dc7e1 7783 return false;
28d13567
AM
7784
7785 if (symsec->sh_link != 0)
7786 {
7787 Elf_Internal_Shdr *strsec;
7788
7789 if (symsec->sh_link >= filedata->file_header.e_shnum)
7790 {
7791 error (_("Bad sh_link in symbol table section\n"));
7792 free (*symtab);
7793 *symtab = NULL;
7794 *nsyms = 0;
015dc7e1 7795 return false;
28d13567
AM
7796 }
7797
7798 strsec = filedata->section_headers + symsec->sh_link;
7799
7800 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7801 1, strsec->sh_size, _("string table"));
7802 if (*strtab == NULL)
7803 {
7804 free (*symtab);
7805 *symtab = NULL;
7806 *nsyms = 0;
015dc7e1 7807 return false;
28d13567
AM
7808 }
7809 *strtablen = strsec->sh_size;
7810 }
015dc7e1 7811 return true;
28d13567
AM
7812}
7813
f5842774
L
7814static const char *
7815get_group_flags (unsigned int flags)
7816{
1449284b 7817 static char buff[128];
220453ec 7818
6d913794
NC
7819 if (flags == 0)
7820 return "";
7821 else if (flags == GRP_COMDAT)
7822 return "COMDAT ";
f5842774 7823
89246a0e
AM
7824 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7825 flags,
7826 flags & GRP_MASKOS ? _("<OS specific>") : "",
7827 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7828 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7829 ? _("<unknown>") : ""));
6d913794 7830
f5842774
L
7831 return buff;
7832}
7833
015dc7e1 7834static bool
dda8d76d 7835process_section_groups (Filedata * filedata)
f5842774 7836{
2cf0635d 7837 Elf_Internal_Shdr * section;
f5842774 7838 unsigned int i;
2cf0635d
NC
7839 struct group * group;
7840 Elf_Internal_Shdr * symtab_sec;
7841 Elf_Internal_Shdr * strtab_sec;
7842 Elf_Internal_Sym * symtab;
ba5cdace 7843 unsigned long num_syms;
2cf0635d 7844 char * strtab;
c256ffe7 7845 size_t strtab_size;
d1f5c6e3
L
7846
7847 /* Don't process section groups unless needed. */
7848 if (!do_unwind && !do_section_groups)
015dc7e1 7849 return true;
f5842774 7850
dda8d76d 7851 if (filedata->file_header.e_shnum == 0)
f5842774
L
7852 {
7853 if (do_section_groups)
ca0e11aa
NC
7854 {
7855 if (filedata->is_separate)
7856 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7857 filedata->file_name);
7858 else
7859 printf (_("\nThere are no section groups in this file.\n"));
7860 }
015dc7e1 7861 return true;
f5842774
L
7862 }
7863
dda8d76d 7864 if (filedata->section_headers == NULL)
f5842774
L
7865 {
7866 error (_("Section headers are not available!\n"));
fa1908fd 7867 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7868 return false;
f5842774
L
7869 }
7870
978c4450
AM
7871 filedata->section_headers_groups
7872 = (struct group **) calloc (filedata->file_header.e_shnum,
7873 sizeof (struct group *));
e4b17d5c 7874
978c4450 7875 if (filedata->section_headers_groups == NULL)
e4b17d5c 7876 {
8b73c356 7877 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7878 filedata->file_header.e_shnum);
015dc7e1 7879 return false;
e4b17d5c
L
7880 }
7881
f5842774 7882 /* Scan the sections for the group section. */
978c4450 7883 filedata->group_count = 0;
dda8d76d
NC
7884 for (i = 0, section = filedata->section_headers;
7885 i < filedata->file_header.e_shnum;
f5842774 7886 i++, section++)
e4b17d5c 7887 if (section->sh_type == SHT_GROUP)
978c4450 7888 filedata->group_count++;
e4b17d5c 7889
978c4450 7890 if (filedata->group_count == 0)
d1f5c6e3
L
7891 {
7892 if (do_section_groups)
ca0e11aa
NC
7893 {
7894 if (filedata->is_separate)
7895 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7896 filedata->file_name);
7897 else
7898 printf (_("\nThere are no section groups in this file.\n"));
7899 }
d1f5c6e3 7900
015dc7e1 7901 return true;
d1f5c6e3
L
7902 }
7903
978c4450
AM
7904 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7905 sizeof (struct group));
e4b17d5c 7906
978c4450 7907 if (filedata->section_groups == NULL)
e4b17d5c 7908 {
8b73c356 7909 error (_("Out of memory reading %lu groups\n"),
978c4450 7910 (unsigned long) filedata->group_count);
015dc7e1 7911 return false;
e4b17d5c
L
7912 }
7913
d1f5c6e3
L
7914 symtab_sec = NULL;
7915 strtab_sec = NULL;
7916 symtab = NULL;
ba5cdace 7917 num_syms = 0;
d1f5c6e3 7918 strtab = NULL;
c256ffe7 7919 strtab_size = 0;
ca0e11aa
NC
7920
7921 if (filedata->is_separate)
7922 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7923
978c4450 7924 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7925 i < filedata->file_header.e_shnum;
e4b17d5c 7926 i++, section++)
f5842774
L
7927 {
7928 if (section->sh_type == SHT_GROUP)
7929 {
dda8d76d 7930 const char * name = printable_section_name (filedata, section);
74e1a04b 7931 const char * group_name;
2cf0635d
NC
7932 unsigned char * start;
7933 unsigned char * indices;
f5842774 7934 unsigned int entry, j, size;
2cf0635d
NC
7935 Elf_Internal_Shdr * sec;
7936 Elf_Internal_Sym * sym;
f5842774
L
7937
7938 /* Get the symbol table. */
dda8d76d
NC
7939 if (section->sh_link >= filedata->file_header.e_shnum
7940 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7941 != SHT_SYMTAB))
f5842774
L
7942 {
7943 error (_("Bad sh_link in group section `%s'\n"), name);
7944 continue;
7945 }
d1f5c6e3
L
7946
7947 if (symtab_sec != sec)
7948 {
7949 symtab_sec = sec;
9db70fc3 7950 free (symtab);
4de91c10 7951 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7952 }
f5842774 7953
dd24e3da
NC
7954 if (symtab == NULL)
7955 {
7956 error (_("Corrupt header in group section `%s'\n"), name);
7957 continue;
7958 }
7959
ba5cdace
NC
7960 if (section->sh_info >= num_syms)
7961 {
7962 error (_("Bad sh_info in group section `%s'\n"), name);
7963 continue;
7964 }
7965
f5842774
L
7966 sym = symtab + section->sh_info;
7967
7968 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7969 {
4fbb74a6 7970 if (sym->st_shndx == 0
dda8d76d 7971 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7972 {
7973 error (_("Bad sh_info in group section `%s'\n"), name);
7974 continue;
7975 }
ba2685cc 7976
84714f86
AM
7977 group_name = section_name_print (filedata,
7978 filedata->section_headers
b9e920ec 7979 + sym->st_shndx);
c256ffe7 7980 strtab_sec = NULL;
9db70fc3 7981 free (strtab);
f5842774 7982 strtab = NULL;
c256ffe7 7983 strtab_size = 0;
f5842774
L
7984 }
7985 else
7986 {
7987 /* Get the string table. */
dda8d76d 7988 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7989 {
7990 strtab_sec = NULL;
9db70fc3 7991 free (strtab);
c256ffe7
JJ
7992 strtab = NULL;
7993 strtab_size = 0;
7994 }
7995 else if (strtab_sec
dda8d76d 7996 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7997 {
7998 strtab_sec = sec;
9db70fc3 7999 free (strtab);
071436c6 8000
dda8d76d 8001 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8002 1, strtab_sec->sh_size,
8003 _("string table"));
c256ffe7 8004 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8005 }
c256ffe7 8006 group_name = sym->st_name < strtab_size
2b692964 8007 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8008 }
8009
c9c1d674
EG
8010 /* PR 17531: file: loop. */
8011 if (section->sh_entsize > section->sh_size)
8012 {
8013 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8014 printable_section_name (filedata, section),
8066deb1
AM
8015 (unsigned long) section->sh_entsize,
8016 (unsigned long) section->sh_size);
61dd8e19 8017 continue;
c9c1d674
EG
8018 }
8019
dda8d76d 8020 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8021 1, section->sh_size,
8022 _("section data"));
59245841
NC
8023 if (start == NULL)
8024 continue;
f5842774
L
8025
8026 indices = start;
8027 size = (section->sh_size / section->sh_entsize) - 1;
8028 entry = byte_get (indices, 4);
8029 indices += 4;
e4b17d5c
L
8030
8031 if (do_section_groups)
8032 {
2b692964 8033 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8034 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8035
e4b17d5c
L
8036 printf (_(" [Index] Name\n"));
8037 }
8038
8039 group->group_index = i;
8040
f5842774
L
8041 for (j = 0; j < size; j++)
8042 {
2cf0635d 8043 struct group_list * g;
e4b17d5c 8044
f5842774
L
8045 entry = byte_get (indices, 4);
8046 indices += 4;
8047
dda8d76d 8048 if (entry >= filedata->file_header.e_shnum)
391cb864 8049 {
57028622
NC
8050 static unsigned num_group_errors = 0;
8051
8052 if (num_group_errors ++ < 10)
8053 {
8054 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8055 entry, i, filedata->file_header.e_shnum - 1);
57028622 8056 if (num_group_errors == 10)
67ce483b 8057 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8058 }
391cb864
L
8059 continue;
8060 }
391cb864 8061
978c4450 8062 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8063 {
d1f5c6e3
L
8064 if (entry)
8065 {
57028622
NC
8066 static unsigned num_errs = 0;
8067
8068 if (num_errs ++ < 10)
8069 {
8070 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8071 entry, i,
978c4450 8072 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8073 if (num_errs == 10)
8074 warn (_("Further error messages about already contained group sections suppressed\n"));
8075 }
d1f5c6e3
L
8076 continue;
8077 }
8078 else
8079 {
8080 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8081 section group. We just warn it the first time
d1f5c6e3 8082 and ignore it afterwards. */
015dc7e1 8083 static bool warned = false;
d1f5c6e3
L
8084 if (!warned)
8085 {
8086 error (_("section 0 in group section [%5u]\n"),
978c4450 8087 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8088 warned = true;
d1f5c6e3
L
8089 }
8090 }
e4b17d5c
L
8091 }
8092
978c4450 8093 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8094
8095 if (do_section_groups)
8096 {
dda8d76d
NC
8097 sec = filedata->section_headers + entry;
8098 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8099 }
8100
3f5e193b 8101 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8102 g->section_index = entry;
8103 g->next = group->root;
8104 group->root = g;
f5842774
L
8105 }
8106
9db70fc3 8107 free (start);
e4b17d5c
L
8108
8109 group++;
f5842774
L
8110 }
8111 }
8112
9db70fc3
AM
8113 free (symtab);
8114 free (strtab);
015dc7e1 8115 return true;
f5842774
L
8116}
8117
28f997cf
TG
8118/* Data used to display dynamic fixups. */
8119
8120struct ia64_vms_dynfixup
8121{
8122 bfd_vma needed_ident; /* Library ident number. */
8123 bfd_vma needed; /* Index in the dstrtab of the library name. */
8124 bfd_vma fixup_needed; /* Index of the library. */
8125 bfd_vma fixup_rela_cnt; /* Number of fixups. */
8126 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
8127};
8128
8129/* Data used to display dynamic relocations. */
8130
8131struct ia64_vms_dynimgrela
8132{
8133 bfd_vma img_rela_cnt; /* Number of relocations. */
8134 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
8135};
8136
8137/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8138 library). */
8139
015dc7e1 8140static bool
dda8d76d
NC
8141dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8142 struct ia64_vms_dynfixup * fixup,
8143 const char * strtab,
8144 unsigned int strtab_sz)
28f997cf 8145{
32ec8896 8146 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8147 long i;
32ec8896 8148 const char * lib_name;
28f997cf 8149
978c4450
AM
8150 imfs = get_data (NULL, filedata,
8151 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8152 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8153 _("dynamic section image fixups"));
8154 if (!imfs)
015dc7e1 8155 return false;
28f997cf
TG
8156
8157 if (fixup->needed < strtab_sz)
8158 lib_name = strtab + fixup->needed;
8159 else
8160 {
32ec8896 8161 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8162 (unsigned long) fixup->needed);
28f997cf
TG
8163 lib_name = "???";
8164 }
736990c4 8165
28f997cf
TG
8166 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8167 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8168 printf
8169 (_("Seg Offset Type SymVec DataType\n"));
8170
8171 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8172 {
8173 unsigned int type;
8174 const char *rtype;
8175
8176 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8177 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8178 type = BYTE_GET (imfs [i].type);
8179 rtype = elf_ia64_reloc_type (type);
8180 if (rtype == NULL)
8181 printf (" 0x%08x ", type);
8182 else
8183 printf (" %-32s ", rtype);
8184 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8185 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8186 }
8187
8188 free (imfs);
015dc7e1 8189 return true;
28f997cf
TG
8190}
8191
8192/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8193
015dc7e1 8194static bool
dda8d76d 8195dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8196{
8197 Elf64_External_VMS_IMAGE_RELA *imrs;
8198 long i;
8199
978c4450
AM
8200 imrs = get_data (NULL, filedata,
8201 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8202 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8203 _("dynamic section image relocations"));
28f997cf 8204 if (!imrs)
015dc7e1 8205 return false;
28f997cf
TG
8206
8207 printf (_("\nImage relocs\n"));
8208 printf
8209 (_("Seg Offset Type Addend Seg Sym Off\n"));
8210
8211 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8212 {
8213 unsigned int type;
8214 const char *rtype;
8215
8216 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8217 printf ("%08" BFD_VMA_FMT "x ",
8218 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8219 type = BYTE_GET (imrs [i].type);
8220 rtype = elf_ia64_reloc_type (type);
8221 if (rtype == NULL)
8222 printf ("0x%08x ", type);
8223 else
8224 printf ("%-31s ", rtype);
8225 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8226 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8227 printf ("%08" BFD_VMA_FMT "x\n",
8228 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8229 }
8230
8231 free (imrs);
015dc7e1 8232 return true;
28f997cf
TG
8233}
8234
8235/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8236
015dc7e1 8237static bool
dda8d76d 8238process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8239{
8240 struct ia64_vms_dynfixup fixup;
8241 struct ia64_vms_dynimgrela imgrela;
8242 Elf_Internal_Dyn *entry;
28f997cf
TG
8243 bfd_vma strtab_off = 0;
8244 bfd_vma strtab_sz = 0;
8245 char *strtab = NULL;
015dc7e1 8246 bool res = true;
28f997cf
TG
8247
8248 memset (&fixup, 0, sizeof (fixup));
8249 memset (&imgrela, 0, sizeof (imgrela));
8250
8251 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8252 for (entry = filedata->dynamic_section;
8253 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8254 entry++)
8255 {
8256 switch (entry->d_tag)
8257 {
8258 case DT_IA_64_VMS_STRTAB_OFFSET:
8259 strtab_off = entry->d_un.d_val;
8260 break;
8261 case DT_STRSZ:
8262 strtab_sz = entry->d_un.d_val;
8263 if (strtab == NULL)
978c4450
AM
8264 strtab = get_data (NULL, filedata,
8265 filedata->dynamic_addr + strtab_off,
28f997cf 8266 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8267 if (strtab == NULL)
8268 strtab_sz = 0;
28f997cf
TG
8269 break;
8270
8271 case DT_IA_64_VMS_NEEDED_IDENT:
8272 fixup.needed_ident = entry->d_un.d_val;
8273 break;
8274 case DT_NEEDED:
8275 fixup.needed = entry->d_un.d_val;
8276 break;
8277 case DT_IA_64_VMS_FIXUP_NEEDED:
8278 fixup.fixup_needed = entry->d_un.d_val;
8279 break;
8280 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8281 fixup.fixup_rela_cnt = entry->d_un.d_val;
8282 break;
8283 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8284 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8285 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8286 res = false;
28f997cf 8287 break;
28f997cf
TG
8288 case DT_IA_64_VMS_IMG_RELA_CNT:
8289 imgrela.img_rela_cnt = entry->d_un.d_val;
8290 break;
8291 case DT_IA_64_VMS_IMG_RELA_OFF:
8292 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8293 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8294 res = false;
28f997cf
TG
8295 break;
8296
8297 default:
8298 break;
8299 }
8300 }
8301
9db70fc3 8302 free (strtab);
28f997cf
TG
8303
8304 return res;
8305}
8306
85b1c36d 8307static struct
566b0d53 8308{
2cf0635d 8309 const char * name;
566b0d53
L
8310 int reloc;
8311 int size;
a7fd1186 8312 relocation_type rel_type;
32ec8896
NC
8313}
8314 dynamic_relocations [] =
566b0d53 8315{
a7fd1186
FS
8316 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8317 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8318 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8319 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8320};
8321
252b5132 8322/* Process the reloc section. */
18bd398b 8323
015dc7e1 8324static bool
dda8d76d 8325process_relocs (Filedata * filedata)
252b5132 8326{
b34976b6
AM
8327 unsigned long rel_size;
8328 unsigned long rel_offset;
252b5132 8329
252b5132 8330 if (!do_reloc)
015dc7e1 8331 return true;
252b5132
RH
8332
8333 if (do_using_dynamic)
8334 {
a7fd1186 8335 relocation_type rel_type;
2cf0635d 8336 const char * name;
015dc7e1 8337 bool has_dynamic_reloc;
566b0d53 8338 unsigned int i;
0de14b54 8339
015dc7e1 8340 has_dynamic_reloc = false;
252b5132 8341
566b0d53 8342 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8343 {
a7fd1186 8344 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8345 name = dynamic_relocations [i].name;
978c4450
AM
8346 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8347 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8348
32ec8896 8349 if (rel_size)
015dc7e1 8350 has_dynamic_reloc = true;
566b0d53 8351
a7fd1186 8352 if (rel_type == reltype_unknown)
aa903cfb 8353 {
566b0d53 8354 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8355 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8356 {
8357 case DT_REL:
a7fd1186 8358 rel_type = reltype_rel;
566b0d53
L
8359 break;
8360 case DT_RELA:
a7fd1186 8361 rel_type = reltype_rela;
566b0d53
L
8362 break;
8363 }
aa903cfb 8364 }
252b5132 8365
566b0d53
L
8366 if (rel_size)
8367 {
ca0e11aa
NC
8368 if (filedata->is_separate)
8369 printf
8370 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8371 filedata->file_name, name, rel_offset, rel_size);
8372 else
8373 printf
8374 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8375 name, rel_offset, rel_size);
252b5132 8376
dda8d76d
NC
8377 dump_relocations (filedata,
8378 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8379 rel_size,
978c4450
AM
8380 filedata->dynamic_symbols,
8381 filedata->num_dynamic_syms,
8382 filedata->dynamic_strings,
8383 filedata->dynamic_strings_length,
a7fd1186 8384 rel_type, true /* is_dynamic */);
566b0d53 8385 }
252b5132 8386 }
566b0d53 8387
dda8d76d
NC
8388 if (is_ia64_vms (filedata))
8389 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8390 has_dynamic_reloc = true;
28f997cf 8391
566b0d53 8392 if (! has_dynamic_reloc)
ca0e11aa
NC
8393 {
8394 if (filedata->is_separate)
8395 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8396 filedata->file_name);
8397 else
8398 printf (_("\nThere are no dynamic relocations in this file.\n"));
8399 }
252b5132
RH
8400 }
8401 else
8402 {
2cf0635d 8403 Elf_Internal_Shdr * section;
b34976b6 8404 unsigned long i;
015dc7e1 8405 bool found = false;
252b5132 8406
dda8d76d
NC
8407 for (i = 0, section = filedata->section_headers;
8408 i < filedata->file_header.e_shnum;
b34976b6 8409 i++, section++)
252b5132
RH
8410 {
8411 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8412 && section->sh_type != SHT_REL
8413 && section->sh_type != SHT_RELR)
252b5132
RH
8414 continue;
8415
8416 rel_offset = section->sh_offset;
8417 rel_size = section->sh_size;
8418
8419 if (rel_size)
8420 {
a7fd1186 8421 relocation_type rel_type;
d3a49aa8 8422 unsigned long num_rela;
103f02d3 8423
ca0e11aa
NC
8424 if (filedata->is_separate)
8425 printf (_("\nIn linked file '%s' relocation section "),
8426 filedata->file_name);
8427 else
8428 printf (_("\nRelocation section "));
252b5132 8429
dda8d76d 8430 if (filedata->string_table == NULL)
19936277 8431 printf ("%d", section->sh_name);
252b5132 8432 else
dda8d76d 8433 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8434
d3a49aa8
AM
8435 num_rela = rel_size / section->sh_entsize;
8436 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8437 " at offset 0x%lx contains %lu entries:\n",
8438 num_rela),
8439 rel_offset, num_rela);
252b5132 8440
a7fd1186
FS
8441 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8442 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8443
4fbb74a6 8444 if (section->sh_link != 0
dda8d76d 8445 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8446 {
2cf0635d
NC
8447 Elf_Internal_Shdr * symsec;
8448 Elf_Internal_Sym * symtab;
d79b3d50 8449 unsigned long nsyms;
c256ffe7 8450 unsigned long strtablen = 0;
2cf0635d 8451 char * strtab = NULL;
57346661 8452
dda8d76d 8453 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8454 if (symsec->sh_type != SHT_SYMTAB
8455 && symsec->sh_type != SHT_DYNSYM)
8456 continue;
8457
28d13567
AM
8458 if (!get_symtab (filedata, symsec,
8459 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8460 continue;
252b5132 8461
dda8d76d 8462 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8463 symtab, nsyms, strtab, strtablen,
a7fd1186 8464 rel_type,
bb4d2ac2 8465 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8466 free (strtab);
d79b3d50
NC
8467 free (symtab);
8468 }
8469 else
dda8d76d 8470 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8471 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8472
015dc7e1 8473 found = true;
252b5132
RH
8474 }
8475 }
8476
8477 if (! found)
45ac8f4f
NC
8478 {
8479 /* Users sometimes forget the -D option, so try to be helpful. */
8480 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8481 {
978c4450 8482 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8483 {
ca0e11aa
NC
8484 if (filedata->is_separate)
8485 printf (_("\nThere are no static relocations in linked file '%s'."),
8486 filedata->file_name);
8487 else
8488 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8489 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8490
8491 break;
8492 }
8493 }
8494 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8495 {
8496 if (filedata->is_separate)
8497 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8498 filedata->file_name);
8499 else
8500 printf (_("\nThere are no relocations in this file.\n"));
8501 }
45ac8f4f 8502 }
252b5132
RH
8503 }
8504
015dc7e1 8505 return true;
252b5132
RH
8506}
8507
4d6ed7c8
NC
8508/* An absolute address consists of a section and an offset. If the
8509 section is NULL, the offset itself is the address, otherwise, the
8510 address equals to LOAD_ADDRESS(section) + offset. */
8511
8512struct absaddr
948f632f
DA
8513{
8514 unsigned short section;
8515 bfd_vma offset;
8516};
4d6ed7c8 8517
948f632f
DA
8518/* Find the nearest symbol at or below ADDR. Returns the symbol
8519 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8520
4d6ed7c8 8521static void
dda8d76d
NC
8522find_symbol_for_address (Filedata * filedata,
8523 Elf_Internal_Sym * symtab,
8524 unsigned long nsyms,
8525 const char * strtab,
8526 unsigned long strtab_size,
8527 struct absaddr addr,
8528 const char ** symname,
8529 bfd_vma * offset)
4d6ed7c8 8530{
d3ba0551 8531 bfd_vma dist = 0x100000;
2cf0635d 8532 Elf_Internal_Sym * sym;
948f632f
DA
8533 Elf_Internal_Sym * beg;
8534 Elf_Internal_Sym * end;
2cf0635d 8535 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8536
0b6ae522 8537 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8538 beg = symtab;
8539 end = symtab + nsyms;
0b6ae522 8540
948f632f 8541 while (beg < end)
4d6ed7c8 8542 {
948f632f
DA
8543 bfd_vma value;
8544
8545 sym = beg + (end - beg) / 2;
0b6ae522 8546
948f632f 8547 value = sym->st_value;
0b6ae522
DJ
8548 REMOVE_ARCH_BITS (value);
8549
948f632f 8550 if (sym->st_name != 0
4d6ed7c8 8551 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8552 && addr.offset >= value
8553 && addr.offset - value < dist)
4d6ed7c8
NC
8554 {
8555 best = sym;
0b6ae522 8556 dist = addr.offset - value;
4d6ed7c8
NC
8557 if (!dist)
8558 break;
8559 }
948f632f
DA
8560
8561 if (addr.offset < value)
8562 end = sym;
8563 else
8564 beg = sym + 1;
4d6ed7c8 8565 }
1b31d05e 8566
4d6ed7c8
NC
8567 if (best)
8568 {
57346661 8569 *symname = (best->st_name >= strtab_size
2b692964 8570 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8571 *offset = dist;
8572 return;
8573 }
1b31d05e 8574
4d6ed7c8
NC
8575 *symname = NULL;
8576 *offset = addr.offset;
8577}
8578
32ec8896 8579static /* signed */ int
948f632f
DA
8580symcmp (const void *p, const void *q)
8581{
8582 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8583 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8584
8585 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8586}
8587
8588/* Process the unwind section. */
8589
8590#include "unwind-ia64.h"
8591
8592struct ia64_unw_table_entry
8593{
8594 struct absaddr start;
8595 struct absaddr end;
8596 struct absaddr info;
8597};
8598
8599struct ia64_unw_aux_info
8600{
32ec8896
NC
8601 struct ia64_unw_table_entry * table; /* Unwind table. */
8602 unsigned long table_len; /* Length of unwind table. */
8603 unsigned char * info; /* Unwind info. */
8604 unsigned long info_size; /* Size of unwind info. */
8605 bfd_vma info_addr; /* Starting address of unwind info. */
8606 bfd_vma seg_base; /* Starting address of segment. */
8607 Elf_Internal_Sym * symtab; /* The symbol table. */
8608 unsigned long nsyms; /* Number of symbols. */
8609 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8610 unsigned long nfuns; /* Number of entries in funtab. */
8611 char * strtab; /* The string table. */
8612 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8613};
8614
015dc7e1 8615static bool
dda8d76d 8616dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8617{
2cf0635d 8618 struct ia64_unw_table_entry * tp;
948f632f 8619 unsigned long j, nfuns;
4d6ed7c8 8620 int in_body;
015dc7e1 8621 bool res = true;
7036c0e1 8622
948f632f
DA
8623 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8624 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8625 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8626 aux->funtab[nfuns++] = aux->symtab[j];
8627 aux->nfuns = nfuns;
8628 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8629
4d6ed7c8
NC
8630 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8631 {
8632 bfd_vma stamp;
8633 bfd_vma offset;
2cf0635d
NC
8634 const unsigned char * dp;
8635 const unsigned char * head;
53774b7e 8636 const unsigned char * end;
2cf0635d 8637 const char * procname;
4d6ed7c8 8638
dda8d76d 8639 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8640 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8641
8642 fputs ("\n<", stdout);
8643
8644 if (procname)
8645 {
8646 fputs (procname, stdout);
8647
8648 if (offset)
8649 printf ("+%lx", (unsigned long) offset);
8650 }
8651
8652 fputs (">: [", stdout);
8653 print_vma (tp->start.offset, PREFIX_HEX);
8654 fputc ('-', stdout);
8655 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8656 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8657 (unsigned long) (tp->info.offset - aux->seg_base));
8658
53774b7e
NC
8659 /* PR 17531: file: 86232b32. */
8660 if (aux->info == NULL)
8661 continue;
8662
97c0a079
AM
8663 offset = tp->info.offset;
8664 if (tp->info.section)
8665 {
8666 if (tp->info.section >= filedata->file_header.e_shnum)
8667 {
8668 warn (_("Invalid section %u in table entry %ld\n"),
8669 tp->info.section, (long) (tp - aux->table));
015dc7e1 8670 res = false;
97c0a079
AM
8671 continue;
8672 }
8673 offset += filedata->section_headers[tp->info.section].sh_addr;
8674 }
8675 offset -= aux->info_addr;
53774b7e 8676 /* PR 17531: file: 0997b4d1. */
90679903
AM
8677 if (offset >= aux->info_size
8678 || aux->info_size - offset < 8)
53774b7e
NC
8679 {
8680 warn (_("Invalid offset %lx in table entry %ld\n"),
8681 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8682 res = false;
53774b7e
NC
8683 continue;
8684 }
8685
97c0a079 8686 head = aux->info + offset;
a4a00738 8687 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8688
86f55779 8689 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8690 (unsigned) UNW_VER (stamp),
8691 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8692 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8693 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8694 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8695
8696 if (UNW_VER (stamp) != 1)
8697 {
2b692964 8698 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8699 continue;
8700 }
8701
8702 in_body = 0;
53774b7e
NC
8703 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8704 /* PR 17531: file: 16ceda89. */
8705 if (end > aux->info + aux->info_size)
8706 end = aux->info + aux->info_size;
8707 for (dp = head + 8; dp < end;)
b4477bc8 8708 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8709 }
948f632f
DA
8710
8711 free (aux->funtab);
32ec8896
NC
8712
8713 return res;
4d6ed7c8
NC
8714}
8715
015dc7e1 8716static bool
dda8d76d
NC
8717slurp_ia64_unwind_table (Filedata * filedata,
8718 struct ia64_unw_aux_info * aux,
8719 Elf_Internal_Shdr * sec)
4d6ed7c8 8720{
89fac5e3 8721 unsigned long size, nrelas, i;
2cf0635d
NC
8722 Elf_Internal_Phdr * seg;
8723 struct ia64_unw_table_entry * tep;
8724 Elf_Internal_Shdr * relsec;
8725 Elf_Internal_Rela * rela;
8726 Elf_Internal_Rela * rp;
8727 unsigned char * table;
8728 unsigned char * tp;
8729 Elf_Internal_Sym * sym;
8730 const char * relname;
4d6ed7c8 8731
53774b7e
NC
8732 aux->table_len = 0;
8733
4d6ed7c8
NC
8734 /* First, find the starting address of the segment that includes
8735 this section: */
8736
dda8d76d 8737 if (filedata->file_header.e_phnum)
4d6ed7c8 8738 {
dda8d76d 8739 if (! get_program_headers (filedata))
015dc7e1 8740 return false;
4d6ed7c8 8741
dda8d76d
NC
8742 for (seg = filedata->program_headers;
8743 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8744 ++seg)
4d6ed7c8
NC
8745 {
8746 if (seg->p_type != PT_LOAD)
8747 continue;
8748
8749 if (sec->sh_addr >= seg->p_vaddr
8750 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8751 {
8752 aux->seg_base = seg->p_vaddr;
8753 break;
8754 }
8755 }
4d6ed7c8
NC
8756 }
8757
8758 /* Second, build the unwind table from the contents of the unwind section: */
8759 size = sec->sh_size;
dda8d76d 8760 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8761 _("unwind table"));
a6e9f9df 8762 if (!table)
015dc7e1 8763 return false;
4d6ed7c8 8764
53774b7e 8765 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8766 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8767 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8768 tep = aux->table;
53774b7e
NC
8769
8770 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8771 {
8772 tep->start.section = SHN_UNDEF;
8773 tep->end.section = SHN_UNDEF;
8774 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8775 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8776 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8777 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8778 tep->start.offset += aux->seg_base;
8779 tep->end.offset += aux->seg_base;
8780 tep->info.offset += aux->seg_base;
8781 }
8782 free (table);
8783
41e92641 8784 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8785 for (relsec = filedata->section_headers;
8786 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8787 ++relsec)
8788 {
8789 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8790 || relsec->sh_info >= filedata->file_header.e_shnum
8791 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8792 continue;
8793
dda8d76d 8794 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8795 & rela, & nrelas))
53774b7e
NC
8796 {
8797 free (aux->table);
8798 aux->table = NULL;
8799 aux->table_len = 0;
015dc7e1 8800 return false;
53774b7e 8801 }
4d6ed7c8
NC
8802
8803 for (rp = rela; rp < rela + nrelas; ++rp)
8804 {
4770fb94 8805 unsigned int sym_ndx;
726bd37d
AM
8806 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8807 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8808
82b1b41b
NC
8809 /* PR 17531: file: 9fa67536. */
8810 if (relname == NULL)
8811 {
726bd37d 8812 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8813 continue;
8814 }
948f632f 8815
24d127aa 8816 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8817 {
82b1b41b 8818 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8819 continue;
8820 }
8821
89fac5e3 8822 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8823
53774b7e
NC
8824 /* PR 17531: file: 5bc8d9bf. */
8825 if (i >= aux->table_len)
8826 {
8827 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8828 continue;
8829 }
8830
4770fb94
AM
8831 sym_ndx = get_reloc_symindex (rp->r_info);
8832 if (sym_ndx >= aux->nsyms)
8833 {
8834 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8835 sym_ndx);
8836 continue;
8837 }
8838 sym = aux->symtab + sym_ndx;
8839
53774b7e 8840 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8841 {
8842 case 0:
8843 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8844 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8845 break;
8846 case 1:
8847 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8848 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8849 break;
8850 case 2:
8851 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8852 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8853 break;
8854 default:
8855 break;
8856 }
8857 }
8858
8859 free (rela);
8860 }
8861
015dc7e1 8862 return true;
4d6ed7c8
NC
8863}
8864
015dc7e1 8865static bool
dda8d76d 8866ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8867{
2cf0635d
NC
8868 Elf_Internal_Shdr * sec;
8869 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8870 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8871 struct ia64_unw_aux_info aux;
015dc7e1 8872 bool res = true;
f1467e33 8873
4d6ed7c8
NC
8874 memset (& aux, 0, sizeof (aux));
8875
dda8d76d 8876 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8877 {
28d13567 8878 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8879 {
28d13567 8880 if (aux.symtab)
4082ef84 8881 {
28d13567
AM
8882 error (_("Multiple symbol tables encountered\n"));
8883 free (aux.symtab);
8884 aux.symtab = NULL;
4082ef84 8885 free (aux.strtab);
28d13567 8886 aux.strtab = NULL;
4082ef84 8887 }
28d13567
AM
8888 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8889 &aux.strtab, &aux.strtab_size))
015dc7e1 8890 return false;
4d6ed7c8
NC
8891 }
8892 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8893 unwcount++;
8894 }
8895
8896 if (!unwcount)
8897 printf (_("\nThere are no unwind sections in this file.\n"));
8898
8899 while (unwcount-- > 0)
8900 {
84714f86 8901 const char *suffix;
579f31ac
JJ
8902 size_t len, len2;
8903
dda8d76d
NC
8904 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8905 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8906 if (sec->sh_type == SHT_IA_64_UNWIND)
8907 {
8908 unwsec = sec;
8909 break;
8910 }
4082ef84
NC
8911 /* We have already counted the number of SHT_IA64_UNWIND
8912 sections so the loop above should never fail. */
8913 assert (unwsec != NULL);
579f31ac
JJ
8914
8915 unwstart = i + 1;
8916 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8917
e4b17d5c
L
8918 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8919 {
8920 /* We need to find which section group it is in. */
4082ef84 8921 struct group_list * g;
e4b17d5c 8922
978c4450
AM
8923 if (filedata->section_headers_groups == NULL
8924 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8925 i = filedata->file_header.e_shnum;
4082ef84 8926 else
e4b17d5c 8927 {
978c4450 8928 g = filedata->section_headers_groups[i]->root;
18bd398b 8929
4082ef84
NC
8930 for (; g != NULL; g = g->next)
8931 {
dda8d76d 8932 sec = filedata->section_headers + g->section_index;
e4b17d5c 8933
84714f86
AM
8934 if (section_name_valid (filedata, sec)
8935 && streq (section_name (filedata, sec),
8936 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8937 break;
8938 }
8939
8940 if (g == NULL)
dda8d76d 8941 i = filedata->file_header.e_shnum;
4082ef84 8942 }
e4b17d5c 8943 }
84714f86
AM
8944 else if (section_name_valid (filedata, unwsec)
8945 && startswith (section_name (filedata, unwsec),
e9b095a5 8946 ELF_STRING_ia64_unwind_once))
579f31ac 8947 {
18bd398b 8948 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8949 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8950 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8951 for (i = 0, sec = filedata->section_headers;
8952 i < filedata->file_header.e_shnum;
579f31ac 8953 ++i, ++sec)
84714f86
AM
8954 if (section_name_valid (filedata, sec)
8955 && startswith (section_name (filedata, sec),
e9b095a5 8956 ELF_STRING_ia64_unwind_info_once)
84714f86 8957 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8958 break;
8959 }
8960 else
8961 {
8962 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8963 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8964 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8965 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8966 suffix = "";
84714f86
AM
8967 if (section_name_valid (filedata, unwsec)
8968 && startswith (section_name (filedata, unwsec),
8969 ELF_STRING_ia64_unwind))
8970 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8971 for (i = 0, sec = filedata->section_headers;
8972 i < filedata->file_header.e_shnum;
579f31ac 8973 ++i, ++sec)
84714f86
AM
8974 if (section_name_valid (filedata, sec)
8975 && startswith (section_name (filedata, sec),
8976 ELF_STRING_ia64_unwind_info)
8977 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8978 break;
8979 }
8980
dda8d76d 8981 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8982 {
8983 printf (_("\nCould not find unwind info section for "));
8984
dda8d76d 8985 if (filedata->string_table == NULL)
579f31ac
JJ
8986 printf ("%d", unwsec->sh_name);
8987 else
dda8d76d 8988 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8989 }
8990 else
4d6ed7c8 8991 {
4d6ed7c8 8992 aux.info_addr = sec->sh_addr;
dda8d76d 8993 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8994 sec->sh_size,
8995 _("unwind info"));
59245841 8996 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8997
579f31ac 8998 printf (_("\nUnwind section "));
4d6ed7c8 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));
4d6ed7c8 9004
579f31ac 9005 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9006 (unsigned long) unwsec->sh_offset,
89fac5e3 9007 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9008
dda8d76d 9009 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9010 && aux.table_len > 0)
dda8d76d 9011 dump_ia64_unwind (filedata, & aux);
579f31ac 9012
9db70fc3
AM
9013 free ((char *) aux.table);
9014 free ((char *) aux.info);
579f31ac
JJ
9015 aux.table = NULL;
9016 aux.info = NULL;
9017 }
4d6ed7c8 9018 }
4d6ed7c8 9019
9db70fc3
AM
9020 free (aux.symtab);
9021 free ((char *) aux.strtab);
32ec8896
NC
9022
9023 return res;
4d6ed7c8
NC
9024}
9025
3f5e193b 9026struct hppa_unw_table_entry
32ec8896
NC
9027{
9028 struct absaddr start;
9029 struct absaddr end;
9030 unsigned int Cannot_unwind:1; /* 0 */
9031 unsigned int Millicode:1; /* 1 */
9032 unsigned int Millicode_save_sr0:1; /* 2 */
9033 unsigned int Region_description:2; /* 3..4 */
9034 unsigned int reserved1:1; /* 5 */
9035 unsigned int Entry_SR:1; /* 6 */
9036 unsigned int Entry_FR:4; /* Number saved 7..10 */
9037 unsigned int Entry_GR:5; /* Number saved 11..15 */
9038 unsigned int Args_stored:1; /* 16 */
9039 unsigned int Variable_Frame:1; /* 17 */
9040 unsigned int Separate_Package_Body:1; /* 18 */
9041 unsigned int Frame_Extension_Millicode:1; /* 19 */
9042 unsigned int Stack_Overflow_Check:1; /* 20 */
9043 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9044 unsigned int Ada_Region:1; /* 22 */
9045 unsigned int cxx_info:1; /* 23 */
9046 unsigned int cxx_try_catch:1; /* 24 */
9047 unsigned int sched_entry_seq:1; /* 25 */
9048 unsigned int reserved2:1; /* 26 */
9049 unsigned int Save_SP:1; /* 27 */
9050 unsigned int Save_RP:1; /* 28 */
9051 unsigned int Save_MRP_in_frame:1; /* 29 */
9052 unsigned int extn_ptr_defined:1; /* 30 */
9053 unsigned int Cleanup_defined:1; /* 31 */
9054
9055 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9056 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9057 unsigned int Large_frame:1; /* 2 */
9058 unsigned int Pseudo_SP_Set:1; /* 3 */
9059 unsigned int reserved4:1; /* 4 */
9060 unsigned int Total_frame_size:27; /* 5..31 */
9061};
3f5e193b 9062
57346661 9063struct hppa_unw_aux_info
948f632f 9064{
32ec8896
NC
9065 struct hppa_unw_table_entry * table; /* Unwind table. */
9066 unsigned long table_len; /* Length of unwind table. */
9067 bfd_vma seg_base; /* Starting address of segment. */
9068 Elf_Internal_Sym * symtab; /* The symbol table. */
9069 unsigned long nsyms; /* Number of symbols. */
9070 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9071 unsigned long nfuns; /* Number of entries in funtab. */
9072 char * strtab; /* The string table. */
9073 unsigned long strtab_size; /* Size of string table. */
948f632f 9074};
57346661 9075
015dc7e1 9076static bool
dda8d76d 9077dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9078{
2cf0635d 9079 struct hppa_unw_table_entry * tp;
948f632f 9080 unsigned long j, nfuns;
015dc7e1 9081 bool res = true;
948f632f
DA
9082
9083 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9084 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9085 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9086 aux->funtab[nfuns++] = aux->symtab[j];
9087 aux->nfuns = nfuns;
9088 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9089
57346661
AM
9090 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9091 {
9092 bfd_vma offset;
2cf0635d 9093 const char * procname;
57346661 9094
dda8d76d 9095 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9096 aux->strtab_size, tp->start, &procname,
9097 &offset);
9098
9099 fputs ("\n<", stdout);
9100
9101 if (procname)
9102 {
9103 fputs (procname, stdout);
9104
9105 if (offset)
9106 printf ("+%lx", (unsigned long) offset);
9107 }
9108
9109 fputs (">: [", stdout);
9110 print_vma (tp->start.offset, PREFIX_HEX);
9111 fputc ('-', stdout);
9112 print_vma (tp->end.offset, PREFIX_HEX);
9113 printf ("]\n\t");
9114
18bd398b
NC
9115#define PF(_m) if (tp->_m) printf (#_m " ");
9116#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9117 PF(Cannot_unwind);
9118 PF(Millicode);
9119 PF(Millicode_save_sr0);
18bd398b 9120 /* PV(Region_description); */
57346661
AM
9121 PF(Entry_SR);
9122 PV(Entry_FR);
9123 PV(Entry_GR);
9124 PF(Args_stored);
9125 PF(Variable_Frame);
9126 PF(Separate_Package_Body);
9127 PF(Frame_Extension_Millicode);
9128 PF(Stack_Overflow_Check);
9129 PF(Two_Instruction_SP_Increment);
9130 PF(Ada_Region);
9131 PF(cxx_info);
9132 PF(cxx_try_catch);
9133 PF(sched_entry_seq);
9134 PF(Save_SP);
9135 PF(Save_RP);
9136 PF(Save_MRP_in_frame);
9137 PF(extn_ptr_defined);
9138 PF(Cleanup_defined);
9139 PF(MPE_XL_interrupt_marker);
9140 PF(HP_UX_interrupt_marker);
9141 PF(Large_frame);
9142 PF(Pseudo_SP_Set);
9143 PV(Total_frame_size);
9144#undef PF
9145#undef PV
9146 }
9147
18bd398b 9148 printf ("\n");
948f632f
DA
9149
9150 free (aux->funtab);
32ec8896
NC
9151
9152 return res;
57346661
AM
9153}
9154
015dc7e1 9155static bool
dda8d76d
NC
9156slurp_hppa_unwind_table (Filedata * filedata,
9157 struct hppa_unw_aux_info * aux,
9158 Elf_Internal_Shdr * sec)
57346661 9159{
1c0751b2 9160 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9161 Elf_Internal_Phdr * seg;
9162 struct hppa_unw_table_entry * tep;
9163 Elf_Internal_Shdr * relsec;
9164 Elf_Internal_Rela * rela;
9165 Elf_Internal_Rela * rp;
9166 unsigned char * table;
9167 unsigned char * tp;
9168 Elf_Internal_Sym * sym;
9169 const char * relname;
57346661 9170
57346661
AM
9171 /* First, find the starting address of the segment that includes
9172 this section. */
dda8d76d 9173 if (filedata->file_header.e_phnum)
57346661 9174 {
dda8d76d 9175 if (! get_program_headers (filedata))
015dc7e1 9176 return false;
57346661 9177
dda8d76d
NC
9178 for (seg = filedata->program_headers;
9179 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9180 ++seg)
9181 {
9182 if (seg->p_type != PT_LOAD)
9183 continue;
9184
9185 if (sec->sh_addr >= seg->p_vaddr
9186 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9187 {
9188 aux->seg_base = seg->p_vaddr;
9189 break;
9190 }
9191 }
9192 }
9193
9194 /* Second, build the unwind table from the contents of the unwind
9195 section. */
9196 size = sec->sh_size;
dda8d76d 9197 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9198 _("unwind table"));
57346661 9199 if (!table)
015dc7e1 9200 return false;
57346661 9201
1c0751b2
DA
9202 unw_ent_size = 16;
9203 nentries = size / unw_ent_size;
9204 size = unw_ent_size * nentries;
57346661 9205
e3fdc001 9206 aux->table_len = nentries;
3f5e193b
NC
9207 tep = aux->table = (struct hppa_unw_table_entry *)
9208 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9209
1c0751b2 9210 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9211 {
9212 unsigned int tmp1, tmp2;
9213
9214 tep->start.section = SHN_UNDEF;
9215 tep->end.section = SHN_UNDEF;
9216
1c0751b2
DA
9217 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9218 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9219 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9220 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9221
9222 tep->start.offset += aux->seg_base;
9223 tep->end.offset += aux->seg_base;
57346661
AM
9224
9225 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9226 tep->Millicode = (tmp1 >> 30) & 0x1;
9227 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9228 tep->Region_description = (tmp1 >> 27) & 0x3;
9229 tep->reserved1 = (tmp1 >> 26) & 0x1;
9230 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9231 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9232 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9233 tep->Args_stored = (tmp1 >> 15) & 0x1;
9234 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9235 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9236 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9237 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9238 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9239 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9240 tep->cxx_info = (tmp1 >> 8) & 0x1;
9241 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9242 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9243 tep->reserved2 = (tmp1 >> 5) & 0x1;
9244 tep->Save_SP = (tmp1 >> 4) & 0x1;
9245 tep->Save_RP = (tmp1 >> 3) & 0x1;
9246 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9247 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9248 tep->Cleanup_defined = tmp1 & 0x1;
9249
9250 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9251 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9252 tep->Large_frame = (tmp2 >> 29) & 0x1;
9253 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9254 tep->reserved4 = (tmp2 >> 27) & 0x1;
9255 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9256 }
9257 free (table);
9258
9259 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9260 for (relsec = filedata->section_headers;
9261 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9262 ++relsec)
9263 {
9264 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9265 || relsec->sh_info >= filedata->file_header.e_shnum
9266 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9267 continue;
9268
dda8d76d 9269 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9270 & rela, & nrelas))
015dc7e1 9271 return false;
57346661
AM
9272
9273 for (rp = rela; rp < rela + nrelas; ++rp)
9274 {
4770fb94 9275 unsigned int sym_ndx;
726bd37d
AM
9276 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9277 relname = elf_hppa_reloc_type (r_type);
57346661 9278
726bd37d
AM
9279 if (relname == NULL)
9280 {
9281 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9282 continue;
9283 }
9284
57346661 9285 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9286 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9287 {
726bd37d 9288 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9289 continue;
9290 }
9291
9292 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9293 if (i >= aux->table_len)
9294 {
9295 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9296 continue;
9297 }
57346661 9298
4770fb94
AM
9299 sym_ndx = get_reloc_symindex (rp->r_info);
9300 if (sym_ndx >= aux->nsyms)
9301 {
9302 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9303 sym_ndx);
9304 continue;
9305 }
9306 sym = aux->symtab + sym_ndx;
9307
43f6cd05 9308 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9309 {
9310 case 0:
9311 aux->table[i].start.section = sym->st_shndx;
1e456d54 9312 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9313 break;
9314 case 1:
9315 aux->table[i].end.section = sym->st_shndx;
1e456d54 9316 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9317 break;
9318 default:
9319 break;
9320 }
9321 }
9322
9323 free (rela);
9324 }
9325
015dc7e1 9326 return true;
57346661
AM
9327}
9328
015dc7e1 9329static bool
dda8d76d 9330hppa_process_unwind (Filedata * filedata)
57346661 9331{
57346661 9332 struct hppa_unw_aux_info aux;
2cf0635d 9333 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9334 Elf_Internal_Shdr * sec;
18bd398b 9335 unsigned long i;
015dc7e1 9336 bool res = true;
57346661 9337
dda8d76d 9338 if (filedata->string_table == NULL)
015dc7e1 9339 return false;
1b31d05e
NC
9340
9341 memset (& aux, 0, sizeof (aux));
57346661 9342
dda8d76d 9343 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9344 {
28d13567 9345 if (sec->sh_type == SHT_SYMTAB)
57346661 9346 {
28d13567 9347 if (aux.symtab)
4082ef84 9348 {
28d13567
AM
9349 error (_("Multiple symbol tables encountered\n"));
9350 free (aux.symtab);
9351 aux.symtab = NULL;
4082ef84 9352 free (aux.strtab);
28d13567 9353 aux.strtab = NULL;
4082ef84 9354 }
28d13567
AM
9355 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9356 &aux.strtab, &aux.strtab_size))
015dc7e1 9357 return false;
57346661 9358 }
84714f86
AM
9359 else if (section_name_valid (filedata, sec)
9360 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9361 unwsec = sec;
9362 }
9363
9364 if (!unwsec)
9365 printf (_("\nThere are no unwind sections in this file.\n"));
9366
dda8d76d 9367 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9368 {
84714f86
AM
9369 if (section_name_valid (filedata, sec)
9370 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9371 {
43f6cd05 9372 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9373
d3a49aa8
AM
9374 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9375 "contains %lu entry:\n",
9376 "\nUnwind section '%s' at offset 0x%lx "
9377 "contains %lu entries:\n",
9378 num_unwind),
dda8d76d 9379 printable_section_name (filedata, sec),
57346661 9380 (unsigned long) sec->sh_offset,
d3a49aa8 9381 num_unwind);
57346661 9382
dda8d76d 9383 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9384 res = false;
66b09c7e
S
9385
9386 if (res && aux.table_len > 0)
32ec8896 9387 {
dda8d76d 9388 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9389 res = false;
32ec8896 9390 }
57346661 9391
9db70fc3 9392 free ((char *) aux.table);
57346661
AM
9393 aux.table = NULL;
9394 }
9395 }
9396
9db70fc3
AM
9397 free (aux.symtab);
9398 free ((char *) aux.strtab);
32ec8896
NC
9399
9400 return res;
57346661
AM
9401}
9402
0b6ae522
DJ
9403struct arm_section
9404{
a734115a
NC
9405 unsigned char * data; /* The unwind data. */
9406 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9407 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9408 unsigned long nrelas; /* The number of relocations. */
9409 unsigned int rel_type; /* REL or RELA ? */
9410 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9411};
9412
9413struct arm_unw_aux_info
9414{
dda8d76d 9415 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9416 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9417 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9418 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9419 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9420 char * strtab; /* The file's string table. */
9421 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9422};
9423
9424static const char *
dda8d76d
NC
9425arm_print_vma_and_name (Filedata * filedata,
9426 struct arm_unw_aux_info * aux,
9427 bfd_vma fn,
9428 struct absaddr addr)
0b6ae522
DJ
9429{
9430 const char *procname;
9431 bfd_vma sym_offset;
9432
9433 if (addr.section == SHN_UNDEF)
9434 addr.offset = fn;
9435
dda8d76d 9436 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9437 aux->strtab_size, addr, &procname,
9438 &sym_offset);
9439
9440 print_vma (fn, PREFIX_HEX);
9441
9442 if (procname)
9443 {
9444 fputs (" <", stdout);
9445 fputs (procname, stdout);
9446
9447 if (sym_offset)
9448 printf ("+0x%lx", (unsigned long) sym_offset);
9449 fputc ('>', stdout);
9450 }
9451
9452 return procname;
9453}
9454
9455static void
9456arm_free_section (struct arm_section *arm_sec)
9457{
9db70fc3
AM
9458 free (arm_sec->data);
9459 free (arm_sec->rela);
0b6ae522
DJ
9460}
9461
a734115a
NC
9462/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9463 cached section and install SEC instead.
9464 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9465 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9466 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9467 relocation's offset in ADDR.
1b31d05e
NC
9468 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9469 into the string table of the symbol associated with the reloc. If no
9470 reloc was applied store -1 there.
9471 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9472
015dc7e1 9473static bool
dda8d76d
NC
9474get_unwind_section_word (Filedata * filedata,
9475 struct arm_unw_aux_info * aux,
1b31d05e
NC
9476 struct arm_section * arm_sec,
9477 Elf_Internal_Shdr * sec,
9478 bfd_vma word_offset,
9479 unsigned int * wordp,
9480 struct absaddr * addr,
9481 bfd_vma * sym_name)
0b6ae522
DJ
9482{
9483 Elf_Internal_Rela *rp;
9484 Elf_Internal_Sym *sym;
9485 const char * relname;
9486 unsigned int word;
015dc7e1 9487 bool wrapped;
0b6ae522 9488
e0a31db1 9489 if (sec == NULL || arm_sec == NULL)
015dc7e1 9490 return false;
e0a31db1 9491
0b6ae522
DJ
9492 addr->section = SHN_UNDEF;
9493 addr->offset = 0;
9494
1b31d05e
NC
9495 if (sym_name != NULL)
9496 *sym_name = (bfd_vma) -1;
9497
a734115a 9498 /* If necessary, update the section cache. */
0b6ae522
DJ
9499 if (sec != arm_sec->sec)
9500 {
9501 Elf_Internal_Shdr *relsec;
9502
9503 arm_free_section (arm_sec);
9504
9505 arm_sec->sec = sec;
dda8d76d 9506 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9507 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9508 arm_sec->rela = NULL;
9509 arm_sec->nrelas = 0;
9510
dda8d76d
NC
9511 for (relsec = filedata->section_headers;
9512 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9513 ++relsec)
9514 {
dda8d76d
NC
9515 if (relsec->sh_info >= filedata->file_header.e_shnum
9516 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9517 /* PR 15745: Check the section type as well. */
9518 || (relsec->sh_type != SHT_REL
9519 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9520 continue;
9521
a734115a 9522 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9523 if (relsec->sh_type == SHT_REL)
9524 {
dda8d76d 9525 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9526 relsec->sh_size,
9527 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9528 return false;
0b6ae522 9529 }
1ae40aa4 9530 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9531 {
dda8d76d 9532 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9533 relsec->sh_size,
9534 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9535 return false;
0b6ae522 9536 }
1ae40aa4 9537 break;
0b6ae522
DJ
9538 }
9539
9540 arm_sec->next_rela = arm_sec->rela;
9541 }
9542
a734115a 9543 /* If there is no unwind data we can do nothing. */
0b6ae522 9544 if (arm_sec->data == NULL)
015dc7e1 9545 return false;
0b6ae522 9546
e0a31db1 9547 /* If the offset is invalid then fail. */
f32ba729
NC
9548 if (/* PR 21343 *//* PR 18879 */
9549 sec->sh_size < 4
9550 || word_offset > (sec->sh_size - 4)
1a915552 9551 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9552 return false;
e0a31db1 9553
a734115a 9554 /* Get the word at the required offset. */
0b6ae522
DJ
9555 word = byte_get (arm_sec->data + word_offset, 4);
9556
0eff7165
NC
9557 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9558 if (arm_sec->rela == NULL)
9559 {
9560 * wordp = word;
015dc7e1 9561 return true;
0eff7165
NC
9562 }
9563
a734115a 9564 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9565 wrapped = false;
0b6ae522
DJ
9566 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9567 {
9568 bfd_vma prelval, offset;
9569
9570 if (rp->r_offset > word_offset && !wrapped)
9571 {
9572 rp = arm_sec->rela;
015dc7e1 9573 wrapped = true;
0b6ae522
DJ
9574 }
9575 if (rp->r_offset > word_offset)
9576 break;
9577
9578 if (rp->r_offset & 3)
9579 {
9580 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9581 (unsigned long) rp->r_offset);
9582 continue;
9583 }
9584
9585 if (rp->r_offset < word_offset)
9586 continue;
9587
74e1a04b
NC
9588 /* PR 17531: file: 027-161405-0.004 */
9589 if (aux->symtab == NULL)
9590 continue;
9591
0b6ae522
DJ
9592 if (arm_sec->rel_type == SHT_REL)
9593 {
9594 offset = word & 0x7fffffff;
9595 if (offset & 0x40000000)
9596 offset |= ~ (bfd_vma) 0x7fffffff;
9597 }
a734115a 9598 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9599 offset = rp->r_addend;
a734115a 9600 else
74e1a04b
NC
9601 {
9602 error (_("Unknown section relocation type %d encountered\n"),
9603 arm_sec->rel_type);
9604 break;
9605 }
0b6ae522 9606
071436c6
NC
9607 /* PR 17531 file: 027-1241568-0.004. */
9608 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9609 {
9610 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9611 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9612 break;
9613 }
9614
9615 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9616 offset += sym->st_value;
9617 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9618
a734115a 9619 /* Check that we are processing the expected reloc type. */
dda8d76d 9620 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9621 {
9622 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9623 if (relname == NULL)
9624 {
9625 warn (_("Skipping unknown ARM relocation type: %d\n"),
9626 (int) ELF32_R_TYPE (rp->r_info));
9627 continue;
9628 }
a734115a
NC
9629
9630 if (streq (relname, "R_ARM_NONE"))
9631 continue;
0b4362b0 9632
a734115a
NC
9633 if (! streq (relname, "R_ARM_PREL31"))
9634 {
071436c6 9635 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9636 continue;
9637 }
9638 }
dda8d76d 9639 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9640 {
9641 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9642 if (relname == NULL)
9643 {
9644 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9645 (int) ELF32_R_TYPE (rp->r_info));
9646 continue;
9647 }
0b4362b0 9648
a734115a
NC
9649 if (streq (relname, "R_C6000_NONE"))
9650 continue;
9651
9652 if (! streq (relname, "R_C6000_PREL31"))
9653 {
071436c6 9654 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9655 continue;
9656 }
9657
9658 prelval >>= 1;
9659 }
9660 else
74e1a04b
NC
9661 {
9662 /* This function currently only supports ARM and TI unwinders. */
9663 warn (_("Only TI and ARM unwinders are currently supported\n"));
9664 break;
9665 }
fa197c1c 9666
0b6ae522
DJ
9667 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9668 addr->section = sym->st_shndx;
9669 addr->offset = offset;
74e1a04b 9670
1b31d05e
NC
9671 if (sym_name)
9672 * sym_name = sym->st_name;
0b6ae522
DJ
9673 break;
9674 }
9675
9676 *wordp = word;
9677 arm_sec->next_rela = rp;
9678
015dc7e1 9679 return true;
0b6ae522
DJ
9680}
9681
a734115a
NC
9682static const char *tic6x_unwind_regnames[16] =
9683{
0b4362b0
RM
9684 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9685 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9686 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9687};
fa197c1c 9688
0b6ae522 9689static void
fa197c1c 9690decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9691{
fa197c1c
PB
9692 int i;
9693
9694 for (i = 12; mask; mask >>= 1, i--)
9695 {
9696 if (mask & 1)
9697 {
9698 fputs (tic6x_unwind_regnames[i], stdout);
9699 if (mask > 1)
9700 fputs (", ", stdout);
9701 }
9702 }
9703}
0b6ae522
DJ
9704
9705#define ADVANCE \
9706 if (remaining == 0 && more_words) \
9707 { \
9708 data_offset += 4; \
dda8d76d 9709 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9710 data_offset, & word, & addr, NULL)) \
015dc7e1 9711 return false; \
0b6ae522
DJ
9712 remaining = 4; \
9713 more_words--; \
9714 } \
9715
9716#define GET_OP(OP) \
9717 ADVANCE; \
9718 if (remaining) \
9719 { \
9720 remaining--; \
9721 (OP) = word >> 24; \
9722 word <<= 8; \
9723 } \
9724 else \
9725 { \
2b692964 9726 printf (_("[Truncated opcode]\n")); \
015dc7e1 9727 return false; \
0b6ae522 9728 } \
cc5914eb 9729 printf ("0x%02x ", OP)
0b6ae522 9730
015dc7e1 9731static bool
dda8d76d
NC
9732decode_arm_unwind_bytecode (Filedata * filedata,
9733 struct arm_unw_aux_info * aux,
948f632f
DA
9734 unsigned int word,
9735 unsigned int remaining,
9736 unsigned int more_words,
9737 bfd_vma data_offset,
9738 Elf_Internal_Shdr * data_sec,
9739 struct arm_section * data_arm_sec)
fa197c1c
PB
9740{
9741 struct absaddr addr;
015dc7e1 9742 bool res = true;
0b6ae522
DJ
9743
9744 /* Decode the unwinding instructions. */
9745 while (1)
9746 {
9747 unsigned int op, op2;
9748
9749 ADVANCE;
9750 if (remaining == 0)
9751 break;
9752 remaining--;
9753 op = word >> 24;
9754 word <<= 8;
9755
cc5914eb 9756 printf (" 0x%02x ", op);
0b6ae522
DJ
9757
9758 if ((op & 0xc0) == 0x00)
9759 {
9760 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9761
cc5914eb 9762 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9763 }
9764 else if ((op & 0xc0) == 0x40)
9765 {
9766 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9767
cc5914eb 9768 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9769 }
9770 else if ((op & 0xf0) == 0x80)
9771 {
9772 GET_OP (op2);
9773 if (op == 0x80 && op2 == 0)
9774 printf (_("Refuse to unwind"));
9775 else
9776 {
9777 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9778 bool first = true;
0b6ae522 9779 int i;
2b692964 9780
0b6ae522
DJ
9781 printf ("pop {");
9782 for (i = 0; i < 12; i++)
9783 if (mask & (1 << i))
9784 {
9785 if (first)
015dc7e1 9786 first = false;
0b6ae522
DJ
9787 else
9788 printf (", ");
9789 printf ("r%d", 4 + i);
9790 }
9791 printf ("}");
9792 }
9793 }
9794 else if ((op & 0xf0) == 0x90)
9795 {
9796 if (op == 0x9d || op == 0x9f)
9797 printf (_(" [Reserved]"));
9798 else
cc5914eb 9799 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9800 }
9801 else if ((op & 0xf0) == 0xa0)
9802 {
9803 int end = 4 + (op & 0x07);
015dc7e1 9804 bool first = true;
0b6ae522 9805 int i;
61865e30 9806
0b6ae522
DJ
9807 printf (" pop {");
9808 for (i = 4; i <= end; i++)
9809 {
9810 if (first)
015dc7e1 9811 first = false;
0b6ae522
DJ
9812 else
9813 printf (", ");
9814 printf ("r%d", i);
9815 }
9816 if (op & 0x08)
9817 {
1b31d05e 9818 if (!first)
0b6ae522
DJ
9819 printf (", ");
9820 printf ("r14");
9821 }
9822 printf ("}");
9823 }
9824 else if (op == 0xb0)
9825 printf (_(" finish"));
9826 else if (op == 0xb1)
9827 {
9828 GET_OP (op2);
9829 if (op2 == 0 || (op2 & 0xf0) != 0)
9830 printf (_("[Spare]"));
9831 else
9832 {
9833 unsigned int mask = op2 & 0x0f;
015dc7e1 9834 bool first = true;
0b6ae522 9835 int i;
61865e30 9836
0b6ae522
DJ
9837 printf ("pop {");
9838 for (i = 0; i < 12; i++)
9839 if (mask & (1 << i))
9840 {
9841 if (first)
015dc7e1 9842 first = false;
0b6ae522
DJ
9843 else
9844 printf (", ");
9845 printf ("r%d", i);
9846 }
9847 printf ("}");
9848 }
9849 }
9850 else if (op == 0xb2)
9851 {
b115cf96 9852 unsigned char buf[9];
0b6ae522
DJ
9853 unsigned int i, len;
9854 unsigned long offset;
61865e30 9855
b115cf96 9856 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9857 {
9858 GET_OP (buf[i]);
9859 if ((buf[i] & 0x80) == 0)
9860 break;
9861 }
4082ef84 9862 if (i == sizeof (buf))
32ec8896 9863 {
27a45f42 9864 error (_("corrupt change to vsp\n"));
015dc7e1 9865 res = false;
32ec8896 9866 }
4082ef84
NC
9867 else
9868 {
015dc7e1 9869 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9870 assert (len == i + 1);
9871 offset = offset * 4 + 0x204;
9872 printf ("vsp = vsp + %ld", offset);
9873 }
0b6ae522 9874 }
61865e30 9875 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9876 {
61865e30
NC
9877 unsigned int first, last;
9878
9879 GET_OP (op2);
9880 first = op2 >> 4;
9881 last = op2 & 0x0f;
9882 if (op == 0xc8)
9883 first = first + 16;
9884 printf ("pop {D%d", first);
9885 if (last)
9886 printf ("-D%d", first + last);
9887 printf ("}");
9888 }
09854a88
TB
9889 else if (op == 0xb4)
9890 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9891 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9892 {
9893 unsigned int count = op & 0x07;
9894
9895 printf ("pop {D8");
9896 if (count)
9897 printf ("-D%d", 8 + count);
9898 printf ("}");
9899 }
9900 else if (op >= 0xc0 && op <= 0xc5)
9901 {
9902 unsigned int count = op & 0x07;
9903
9904 printf (" pop {wR10");
9905 if (count)
9906 printf ("-wR%d", 10 + count);
9907 printf ("}");
9908 }
9909 else if (op == 0xc6)
9910 {
9911 unsigned int first, last;
9912
9913 GET_OP (op2);
9914 first = op2 >> 4;
9915 last = op2 & 0x0f;
9916 printf ("pop {wR%d", first);
9917 if (last)
9918 printf ("-wR%d", first + last);
9919 printf ("}");
9920 }
9921 else if (op == 0xc7)
9922 {
9923 GET_OP (op2);
9924 if (op2 == 0 || (op2 & 0xf0) != 0)
9925 printf (_("[Spare]"));
0b6ae522
DJ
9926 else
9927 {
61865e30 9928 unsigned int mask = op2 & 0x0f;
015dc7e1 9929 bool first = true;
61865e30
NC
9930 int i;
9931
9932 printf ("pop {");
9933 for (i = 0; i < 4; i++)
9934 if (mask & (1 << i))
9935 {
9936 if (first)
015dc7e1 9937 first = false;
61865e30
NC
9938 else
9939 printf (", ");
9940 printf ("wCGR%d", i);
9941 }
9942 printf ("}");
0b6ae522
DJ
9943 }
9944 }
61865e30 9945 else
32ec8896
NC
9946 {
9947 printf (_(" [unsupported opcode]"));
015dc7e1 9948 res = false;
32ec8896
NC
9949 }
9950
0b6ae522
DJ
9951 printf ("\n");
9952 }
32ec8896
NC
9953
9954 return res;
fa197c1c
PB
9955}
9956
015dc7e1 9957static bool
dda8d76d
NC
9958decode_tic6x_unwind_bytecode (Filedata * filedata,
9959 struct arm_unw_aux_info * aux,
948f632f
DA
9960 unsigned int word,
9961 unsigned int remaining,
9962 unsigned int more_words,
9963 bfd_vma data_offset,
9964 Elf_Internal_Shdr * data_sec,
9965 struct arm_section * data_arm_sec)
fa197c1c
PB
9966{
9967 struct absaddr addr;
9968
9969 /* Decode the unwinding instructions. */
9970 while (1)
9971 {
9972 unsigned int op, op2;
9973
9974 ADVANCE;
9975 if (remaining == 0)
9976 break;
9977 remaining--;
9978 op = word >> 24;
9979 word <<= 8;
9980
9cf03b7e 9981 printf (" 0x%02x ", op);
fa197c1c
PB
9982
9983 if ((op & 0xc0) == 0x00)
9984 {
9985 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9986 printf (" sp = sp + %d", offset);
fa197c1c
PB
9987 }
9988 else if ((op & 0xc0) == 0x80)
9989 {
9990 GET_OP (op2);
9991 if (op == 0x80 && op2 == 0)
9992 printf (_("Refuse to unwind"));
9993 else
9994 {
9995 unsigned int mask = ((op & 0x1f) << 8) | op2;
9996 if (op & 0x20)
9997 printf ("pop compact {");
9998 else
9999 printf ("pop {");
10000
10001 decode_tic6x_unwind_regmask (mask);
10002 printf("}");
10003 }
10004 }
10005 else if ((op & 0xf0) == 0xc0)
10006 {
10007 unsigned int reg;
10008 unsigned int nregs;
10009 unsigned int i;
10010 const char *name;
a734115a
NC
10011 struct
10012 {
32ec8896
NC
10013 unsigned int offset;
10014 unsigned int reg;
fa197c1c
PB
10015 } regpos[16];
10016
10017 /* Scan entire instruction first so that GET_OP output is not
10018 interleaved with disassembly. */
10019 nregs = 0;
10020 for (i = 0; nregs < (op & 0xf); i++)
10021 {
10022 GET_OP (op2);
10023 reg = op2 >> 4;
10024 if (reg != 0xf)
10025 {
10026 regpos[nregs].offset = i * 2;
10027 regpos[nregs].reg = reg;
10028 nregs++;
10029 }
10030
10031 reg = op2 & 0xf;
10032 if (reg != 0xf)
10033 {
10034 regpos[nregs].offset = i * 2 + 1;
10035 regpos[nregs].reg = reg;
10036 nregs++;
10037 }
10038 }
10039
10040 printf (_("pop frame {"));
18344509 10041 if (nregs == 0)
fa197c1c 10042 {
18344509
NC
10043 printf (_("*corrupt* - no registers specified"));
10044 }
10045 else
10046 {
10047 reg = nregs - 1;
10048 for (i = i * 2; i > 0; i--)
fa197c1c 10049 {
18344509
NC
10050 if (regpos[reg].offset == i - 1)
10051 {
10052 name = tic6x_unwind_regnames[regpos[reg].reg];
10053 if (reg > 0)
10054 reg--;
10055 }
10056 else
10057 name = _("[pad]");
fa197c1c 10058
18344509
NC
10059 fputs (name, stdout);
10060 if (i > 1)
10061 printf (", ");
10062 }
fa197c1c
PB
10063 }
10064
10065 printf ("}");
10066 }
10067 else if (op == 0xd0)
10068 printf (" MOV FP, SP");
10069 else if (op == 0xd1)
10070 printf (" __c6xabi_pop_rts");
10071 else if (op == 0xd2)
10072 {
10073 unsigned char buf[9];
10074 unsigned int i, len;
10075 unsigned long offset;
a734115a 10076
fa197c1c
PB
10077 for (i = 0; i < sizeof (buf); i++)
10078 {
10079 GET_OP (buf[i]);
10080 if ((buf[i] & 0x80) == 0)
10081 break;
10082 }
0eff7165
NC
10083 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10084 if (i == sizeof (buf))
10085 {
0eff7165 10086 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10087 return false;
0eff7165 10088 }
948f632f 10089
015dc7e1 10090 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10091 assert (len == i + 1);
10092 offset = offset * 8 + 0x408;
10093 printf (_("sp = sp + %ld"), offset);
10094 }
10095 else if ((op & 0xf0) == 0xe0)
10096 {
10097 if ((op & 0x0f) == 7)
10098 printf (" RETURN");
10099 else
10100 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10101 }
10102 else
10103 {
10104 printf (_(" [unsupported opcode]"));
10105 }
10106 putchar ('\n');
10107 }
32ec8896 10108
015dc7e1 10109 return true;
fa197c1c
PB
10110}
10111
10112static bfd_vma
dda8d76d 10113arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
10114{
10115 bfd_vma offset;
10116
10117 offset = word & 0x7fffffff;
10118 if (offset & 0x40000000)
10119 offset |= ~ (bfd_vma) 0x7fffffff;
10120
dda8d76d 10121 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10122 offset <<= 1;
10123
10124 return offset + where;
10125}
10126
015dc7e1 10127static bool
dda8d76d
NC
10128decode_arm_unwind (Filedata * filedata,
10129 struct arm_unw_aux_info * aux,
1b31d05e
NC
10130 unsigned int word,
10131 unsigned int remaining,
10132 bfd_vma data_offset,
10133 Elf_Internal_Shdr * data_sec,
10134 struct arm_section * data_arm_sec)
fa197c1c
PB
10135{
10136 int per_index;
10137 unsigned int more_words = 0;
37e14bc3 10138 struct absaddr addr;
1b31d05e 10139 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 10140 bool res = true;
fa197c1c
PB
10141
10142 if (remaining == 0)
10143 {
1b31d05e
NC
10144 /* Fetch the first word.
10145 Note - when decoding an object file the address extracted
10146 here will always be 0. So we also pass in the sym_name
10147 parameter so that we can find the symbol associated with
10148 the personality routine. */
dda8d76d 10149 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10150 & word, & addr, & sym_name))
015dc7e1 10151 return false;
1b31d05e 10152
fa197c1c
PB
10153 remaining = 4;
10154 }
c93dbb25
CZ
10155 else
10156 {
10157 addr.section = SHN_UNDEF;
10158 addr.offset = 0;
10159 }
fa197c1c
PB
10160
10161 if ((word & 0x80000000) == 0)
10162 {
10163 /* Expand prel31 for personality routine. */
10164 bfd_vma fn;
10165 const char *procname;
10166
dda8d76d 10167 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10168 printf (_(" Personality routine: "));
1b31d05e
NC
10169 if (fn == 0
10170 && addr.section == SHN_UNDEF && addr.offset == 0
10171 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10172 {
10173 procname = aux->strtab + sym_name;
10174 print_vma (fn, PREFIX_HEX);
10175 if (procname)
10176 {
10177 fputs (" <", stdout);
10178 fputs (procname, stdout);
10179 fputc ('>', stdout);
10180 }
10181 }
10182 else
dda8d76d 10183 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10184 fputc ('\n', stdout);
10185
10186 /* The GCC personality routines use the standard compact
10187 encoding, starting with one byte giving the number of
10188 words. */
10189 if (procname != NULL
24d127aa
ML
10190 && (startswith (procname, "__gcc_personality_v0")
10191 || startswith (procname, "__gxx_personality_v0")
10192 || startswith (procname, "__gcj_personality_v0")
10193 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10194 {
10195 remaining = 0;
10196 more_words = 1;
10197 ADVANCE;
10198 if (!remaining)
10199 {
10200 printf (_(" [Truncated data]\n"));
015dc7e1 10201 return false;
fa197c1c
PB
10202 }
10203 more_words = word >> 24;
10204 word <<= 8;
10205 remaining--;
10206 per_index = -1;
10207 }
10208 else
015dc7e1 10209 return true;
fa197c1c
PB
10210 }
10211 else
10212 {
1b31d05e 10213 /* ARM EHABI Section 6.3:
0b4362b0 10214
1b31d05e 10215 An exception-handling table entry for the compact model looks like:
0b4362b0 10216
1b31d05e
NC
10217 31 30-28 27-24 23-0
10218 -- ----- ----- ----
10219 1 0 index Data for personalityRoutine[index] */
10220
dda8d76d 10221 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10222 && (word & 0x70000000))
32ec8896
NC
10223 {
10224 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10225 res = false;
32ec8896 10226 }
1b31d05e 10227
fa197c1c 10228 per_index = (word >> 24) & 0x7f;
1b31d05e 10229 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10230 if (per_index == 0)
10231 {
10232 more_words = 0;
10233 word <<= 8;
10234 remaining--;
10235 }
10236 else if (per_index < 3)
10237 {
10238 more_words = (word >> 16) & 0xff;
10239 word <<= 16;
10240 remaining -= 2;
10241 }
10242 }
10243
dda8d76d 10244 switch (filedata->file_header.e_machine)
fa197c1c
PB
10245 {
10246 case EM_ARM:
10247 if (per_index < 3)
10248 {
dda8d76d 10249 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10250 data_offset, data_sec, data_arm_sec))
015dc7e1 10251 res = false;
fa197c1c
PB
10252 }
10253 else
1b31d05e
NC
10254 {
10255 warn (_("Unknown ARM compact model index encountered\n"));
10256 printf (_(" [reserved]\n"));
015dc7e1 10257 res = false;
1b31d05e 10258 }
fa197c1c
PB
10259 break;
10260
10261 case EM_TI_C6000:
10262 if (per_index < 3)
10263 {
dda8d76d 10264 if (! decode_tic6x_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 if (per_index < 5)
10269 {
10270 if (((word >> 17) & 0x7f) == 0x7f)
10271 printf (_(" Restore stack from frame pointer\n"));
10272 else
10273 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10274 printf (_(" Registers restored: "));
10275 if (per_index == 4)
10276 printf (" (compact) ");
10277 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10278 putchar ('\n');
10279 printf (_(" Return register: %s\n"),
10280 tic6x_unwind_regnames[word & 0xf]);
10281 }
10282 else
1b31d05e 10283 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10284 break;
10285
10286 default:
74e1a04b 10287 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10288 filedata->file_header.e_machine);
015dc7e1 10289 res = false;
fa197c1c 10290 }
0b6ae522
DJ
10291
10292 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10293
10294 return res;
0b6ae522
DJ
10295}
10296
015dc7e1 10297static bool
dda8d76d
NC
10298dump_arm_unwind (Filedata * filedata,
10299 struct arm_unw_aux_info * aux,
10300 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10301{
10302 struct arm_section exidx_arm_sec, extab_arm_sec;
10303 unsigned int i, exidx_len;
948f632f 10304 unsigned long j, nfuns;
015dc7e1 10305 bool res = true;
0b6ae522
DJ
10306
10307 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10308 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10309 exidx_len = exidx_sec->sh_size / 8;
10310
948f632f
DA
10311 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10312 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10313 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10314 aux->funtab[nfuns++] = aux->symtab[j];
10315 aux->nfuns = nfuns;
10316 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10317
0b6ae522
DJ
10318 for (i = 0; i < exidx_len; i++)
10319 {
10320 unsigned int exidx_fn, exidx_entry;
10321 struct absaddr fn_addr, entry_addr;
10322 bfd_vma fn;
10323
10324 fputc ('\n', stdout);
10325
dda8d76d 10326 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10327 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10328 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10329 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10330 {
948f632f 10331 free (aux->funtab);
1b31d05e
NC
10332 arm_free_section (& exidx_arm_sec);
10333 arm_free_section (& extab_arm_sec);
015dc7e1 10334 return false;
0b6ae522
DJ
10335 }
10336
83c257ca
NC
10337 /* ARM EHABI, Section 5:
10338 An index table entry consists of 2 words.
10339 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10340 if (exidx_fn & 0x80000000)
32ec8896
NC
10341 {
10342 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10343 res = false;
32ec8896 10344 }
83c257ca 10345
dda8d76d 10346 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10347
dda8d76d 10348 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10349 fputs (": ", stdout);
10350
10351 if (exidx_entry == 1)
10352 {
10353 print_vma (exidx_entry, PREFIX_HEX);
10354 fputs (" [cantunwind]\n", stdout);
10355 }
10356 else if (exidx_entry & 0x80000000)
10357 {
10358 print_vma (exidx_entry, PREFIX_HEX);
10359 fputc ('\n', stdout);
dda8d76d 10360 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10361 }
10362 else
10363 {
8f73510c 10364 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10365 Elf_Internal_Shdr *table_sec;
10366
10367 fputs ("@", stdout);
dda8d76d 10368 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10369 print_vma (table, PREFIX_HEX);
10370 printf ("\n");
10371
10372 /* Locate the matching .ARM.extab. */
10373 if (entry_addr.section != SHN_UNDEF
dda8d76d 10374 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10375 {
dda8d76d 10376 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10377 table_offset = entry_addr.offset;
1a915552
NC
10378 /* PR 18879 */
10379 if (table_offset > table_sec->sh_size
10380 || ((bfd_signed_vma) table_offset) < 0)
10381 {
10382 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10383 (unsigned long) table_offset,
dda8d76d 10384 printable_section_name (filedata, table_sec));
015dc7e1 10385 res = false;
1a915552
NC
10386 continue;
10387 }
0b6ae522
DJ
10388 }
10389 else
10390 {
dda8d76d 10391 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10392 if (table_sec != NULL)
10393 table_offset = table - table_sec->sh_addr;
10394 }
32ec8896 10395
0b6ae522
DJ
10396 if (table_sec == NULL)
10397 {
10398 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10399 (unsigned long) table);
015dc7e1 10400 res = false;
0b6ae522
DJ
10401 continue;
10402 }
32ec8896 10403
dda8d76d 10404 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10405 &extab_arm_sec))
015dc7e1 10406 res = false;
0b6ae522
DJ
10407 }
10408 }
10409
10410 printf ("\n");
10411
948f632f 10412 free (aux->funtab);
0b6ae522
DJ
10413 arm_free_section (&exidx_arm_sec);
10414 arm_free_section (&extab_arm_sec);
32ec8896
NC
10415
10416 return res;
0b6ae522
DJ
10417}
10418
fa197c1c 10419/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10420
015dc7e1 10421static bool
dda8d76d 10422arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10423{
10424 struct arm_unw_aux_info aux;
10425 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10426 Elf_Internal_Shdr *sec;
10427 unsigned long i;
fa197c1c 10428 unsigned int sec_type;
015dc7e1 10429 bool res = true;
0b6ae522 10430
dda8d76d 10431 switch (filedata->file_header.e_machine)
fa197c1c
PB
10432 {
10433 case EM_ARM:
10434 sec_type = SHT_ARM_EXIDX;
10435 break;
10436
10437 case EM_TI_C6000:
10438 sec_type = SHT_C6000_UNWIND;
10439 break;
10440
0b4362b0 10441 default:
74e1a04b 10442 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10443 filedata->file_header.e_machine);
015dc7e1 10444 return false;
fa197c1c
PB
10445 }
10446
dda8d76d 10447 if (filedata->string_table == NULL)
015dc7e1 10448 return false;
1b31d05e
NC
10449
10450 memset (& aux, 0, sizeof (aux));
dda8d76d 10451 aux.filedata = filedata;
0b6ae522 10452
dda8d76d 10453 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10454 {
28d13567 10455 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10456 {
28d13567 10457 if (aux.symtab)
74e1a04b 10458 {
28d13567
AM
10459 error (_("Multiple symbol tables encountered\n"));
10460 free (aux.symtab);
10461 aux.symtab = NULL;
74e1a04b 10462 free (aux.strtab);
28d13567 10463 aux.strtab = NULL;
74e1a04b 10464 }
28d13567
AM
10465 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10466 &aux.strtab, &aux.strtab_size))
015dc7e1 10467 return false;
0b6ae522 10468 }
fa197c1c 10469 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10470 unwsec = sec;
10471 }
10472
1b31d05e 10473 if (unwsec == NULL)
0b6ae522 10474 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10475 else
dda8d76d 10476 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10477 {
10478 if (sec->sh_type == sec_type)
10479 {
d3a49aa8
AM
10480 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10481 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10482 "contains %lu entry:\n",
10483 "\nUnwind section '%s' at offset 0x%lx "
10484 "contains %lu entries:\n",
10485 num_unwind),
dda8d76d 10486 printable_section_name (filedata, sec),
1b31d05e 10487 (unsigned long) sec->sh_offset,
d3a49aa8 10488 num_unwind);
0b6ae522 10489
dda8d76d 10490 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10491 res = false;
1b31d05e
NC
10492 }
10493 }
0b6ae522 10494
9db70fc3
AM
10495 free (aux.symtab);
10496 free ((char *) aux.strtab);
32ec8896
NC
10497
10498 return res;
0b6ae522
DJ
10499}
10500
3ecc00ec
NC
10501static bool
10502no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10503{
10504 printf (_("No processor specific unwind information to decode\n"));
10505 return true;
10506}
10507
015dc7e1 10508static bool
dda8d76d 10509process_unwind (Filedata * filedata)
57346661 10510{
2cf0635d
NC
10511 struct unwind_handler
10512 {
32ec8896 10513 unsigned int machtype;
015dc7e1 10514 bool (* handler)(Filedata *);
2cf0635d
NC
10515 } handlers[] =
10516 {
0b6ae522 10517 { EM_ARM, arm_process_unwind },
57346661
AM
10518 { EM_IA_64, ia64_process_unwind },
10519 { EM_PARISC, hppa_process_unwind },
fa197c1c 10520 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10521 { EM_386, no_processor_specific_unwind },
10522 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10523 { 0, NULL }
57346661
AM
10524 };
10525 int i;
10526
10527 if (!do_unwind)
015dc7e1 10528 return true;
57346661
AM
10529
10530 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10531 if (filedata->file_header.e_machine == handlers[i].machtype)
10532 return handlers[i].handler (filedata);
57346661 10533
1b31d05e 10534 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10535 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10536 return true;
57346661
AM
10537}
10538
37c18eed
SD
10539static void
10540dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10541{
10542 switch (entry->d_tag)
10543 {
10544 case DT_AARCH64_BTI_PLT:
1dbade74 10545 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10546 break;
10547 default:
10548 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10549 break;
10550 }
10551 putchar ('\n');
10552}
10553
252b5132 10554static void
978c4450 10555dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10556{
10557 switch (entry->d_tag)
10558 {
10559 case DT_MIPS_FLAGS:
10560 if (entry->d_un.d_val == 0)
4b68bca3 10561 printf (_("NONE"));
252b5132
RH
10562 else
10563 {
10564 static const char * opts[] =
10565 {
10566 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10567 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10568 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10569 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10570 "RLD_ORDER_SAFE"
10571 };
10572 unsigned int cnt;
015dc7e1 10573 bool first = true;
2b692964 10574
60bca95a 10575 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10576 if (entry->d_un.d_val & (1 << cnt))
10577 {
10578 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10579 first = false;
252b5132 10580 }
252b5132
RH
10581 }
10582 break;
103f02d3 10583
252b5132 10584 case DT_MIPS_IVERSION:
84714f86 10585 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10586 printf (_("Interface Version: %s"),
84714f86 10587 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10588 else
76ca31c0
NC
10589 {
10590 char buf[40];
10591 sprintf_vma (buf, entry->d_un.d_ptr);
10592 /* Note: coded this way so that there is a single string for translation. */
10593 printf (_("<corrupt: %s>"), buf);
10594 }
252b5132 10595 break;
103f02d3 10596
252b5132
RH
10597 case DT_MIPS_TIME_STAMP:
10598 {
d5b07ef4 10599 char timebuf[128];
2cf0635d 10600 struct tm * tmp;
91d6fa6a 10601 time_t atime = entry->d_un.d_val;
82b1b41b 10602
91d6fa6a 10603 tmp = gmtime (&atime);
82b1b41b
NC
10604 /* PR 17531: file: 6accc532. */
10605 if (tmp == NULL)
10606 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10607 else
10608 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10609 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10610 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10611 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10612 }
10613 break;
103f02d3 10614
252b5132
RH
10615 case DT_MIPS_RLD_VERSION:
10616 case DT_MIPS_LOCAL_GOTNO:
10617 case DT_MIPS_CONFLICTNO:
10618 case DT_MIPS_LIBLISTNO:
10619 case DT_MIPS_SYMTABNO:
10620 case DT_MIPS_UNREFEXTNO:
10621 case DT_MIPS_HIPAGENO:
10622 case DT_MIPS_DELTA_CLASS_NO:
10623 case DT_MIPS_DELTA_INSTANCE_NO:
10624 case DT_MIPS_DELTA_RELOC_NO:
10625 case DT_MIPS_DELTA_SYM_NO:
10626 case DT_MIPS_DELTA_CLASSSYM_NO:
10627 case DT_MIPS_COMPACT_SIZE:
c69075ac 10628 print_vma (entry->d_un.d_val, DEC);
252b5132 10629 break;
103f02d3 10630
f16a9783 10631 case DT_MIPS_XHASH:
978c4450
AM
10632 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10633 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10634 /* Falls through. */
10635
103f02d3 10636 default:
4b68bca3 10637 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10638 }
4b68bca3 10639 putchar ('\n');
103f02d3
UD
10640}
10641
103f02d3 10642static void
2cf0635d 10643dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10644{
10645 switch (entry->d_tag)
10646 {
10647 case DT_HP_DLD_FLAGS:
10648 {
10649 static struct
10650 {
10651 long int bit;
2cf0635d 10652 const char * str;
5e220199
NC
10653 }
10654 flags[] =
10655 {
10656 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10657 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10658 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10659 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10660 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10661 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10662 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10663 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10664 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10665 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10666 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10667 { DT_HP_GST, "HP_GST" },
10668 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10669 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10670 { DT_HP_NODELETE, "HP_NODELETE" },
10671 { DT_HP_GROUP, "HP_GROUP" },
10672 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10673 };
015dc7e1 10674 bool first = true;
5e220199 10675 size_t cnt;
f7a99963 10676 bfd_vma val = entry->d_un.d_val;
103f02d3 10677
60bca95a 10678 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10679 if (val & flags[cnt].bit)
30800947
NC
10680 {
10681 if (! first)
10682 putchar (' ');
10683 fputs (flags[cnt].str, stdout);
015dc7e1 10684 first = false;
30800947
NC
10685 val ^= flags[cnt].bit;
10686 }
76da6bbe 10687
103f02d3 10688 if (val != 0 || first)
f7a99963
NC
10689 {
10690 if (! first)
10691 putchar (' ');
10692 print_vma (val, HEX);
10693 }
103f02d3
UD
10694 }
10695 break;
76da6bbe 10696
252b5132 10697 default:
f7a99963
NC
10698 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10699 break;
252b5132 10700 }
35b1837e 10701 putchar ('\n');
252b5132
RH
10702}
10703
28f997cf
TG
10704#ifdef BFD64
10705
10706/* VMS vs Unix time offset and factor. */
10707
10708#define VMS_EPOCH_OFFSET 35067168000000000LL
10709#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10710#ifndef INT64_MIN
10711#define INT64_MIN (-9223372036854775807LL - 1)
10712#endif
28f997cf
TG
10713
10714/* Display a VMS time in a human readable format. */
10715
10716static void
10717print_vms_time (bfd_int64_t vmstime)
10718{
dccc31de 10719 struct tm *tm = NULL;
28f997cf
TG
10720 time_t unxtime;
10721
dccc31de
AM
10722 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10723 {
10724 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10725 unxtime = vmstime;
10726 if (unxtime == vmstime)
10727 tm = gmtime (&unxtime);
10728 }
10729 if (tm != NULL)
10730 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10731 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10732 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10733}
10734#endif /* BFD64 */
10735
ecc51f48 10736static void
2cf0635d 10737dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10738{
10739 switch (entry->d_tag)
10740 {
0de14b54 10741 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10742 /* First 3 slots reserved. */
ecc51f48
NC
10743 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10744 printf (" -- ");
10745 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10746 break;
10747
28f997cf
TG
10748 case DT_IA_64_VMS_LINKTIME:
10749#ifdef BFD64
10750 print_vms_time (entry->d_un.d_val);
10751#endif
10752 break;
10753
10754 case DT_IA_64_VMS_LNKFLAGS:
10755 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10756 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10757 printf (" CALL_DEBUG");
10758 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10759 printf (" NOP0BUFS");
10760 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10761 printf (" P0IMAGE");
10762 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10763 printf (" MKTHREADS");
10764 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10765 printf (" UPCALLS");
10766 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10767 printf (" IMGSTA");
10768 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10769 printf (" INITIALIZE");
10770 if (entry->d_un.d_val & VMS_LF_MAIN)
10771 printf (" MAIN");
10772 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10773 printf (" EXE_INIT");
10774 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10775 printf (" TBK_IN_IMG");
10776 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10777 printf (" DBG_IN_IMG");
10778 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10779 printf (" TBK_IN_DSF");
10780 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10781 printf (" DBG_IN_DSF");
10782 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10783 printf (" SIGNATURES");
10784 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10785 printf (" REL_SEG_OFF");
10786 break;
10787
bdf4d63a
JJ
10788 default:
10789 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10790 break;
ecc51f48 10791 }
bdf4d63a 10792 putchar ('\n');
ecc51f48
NC
10793}
10794
015dc7e1 10795static bool
dda8d76d 10796get_32bit_dynamic_section (Filedata * filedata)
252b5132 10797{
2cf0635d
NC
10798 Elf32_External_Dyn * edyn;
10799 Elf32_External_Dyn * ext;
10800 Elf_Internal_Dyn * entry;
103f02d3 10801
978c4450
AM
10802 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10803 filedata->dynamic_addr, 1,
10804 filedata->dynamic_size,
10805 _("dynamic section"));
a6e9f9df 10806 if (!edyn)
015dc7e1 10807 return false;
103f02d3 10808
071436c6
NC
10809 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10810 might not have the luxury of section headers. Look for the DT_NULL
10811 terminator to determine the number of entries. */
978c4450
AM
10812 for (ext = edyn, filedata->dynamic_nent = 0;
10813 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10814 ext++)
10815 {
978c4450 10816 filedata->dynamic_nent++;
ba2685cc
AM
10817 if (BYTE_GET (ext->d_tag) == DT_NULL)
10818 break;
10819 }
252b5132 10820
978c4450
AM
10821 filedata->dynamic_section
10822 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10823 if (filedata->dynamic_section == NULL)
252b5132 10824 {
8b73c356 10825 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10826 (unsigned long) filedata->dynamic_nent);
9ea033b2 10827 free (edyn);
015dc7e1 10828 return false;
9ea033b2 10829 }
252b5132 10830
978c4450
AM
10831 for (ext = edyn, entry = filedata->dynamic_section;
10832 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10833 ext++, entry++)
9ea033b2 10834 {
fb514b26
AM
10835 entry->d_tag = BYTE_GET (ext->d_tag);
10836 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10837 }
10838
9ea033b2
NC
10839 free (edyn);
10840
015dc7e1 10841 return true;
9ea033b2
NC
10842}
10843
015dc7e1 10844static bool
dda8d76d 10845get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10846{
2cf0635d
NC
10847 Elf64_External_Dyn * edyn;
10848 Elf64_External_Dyn * ext;
10849 Elf_Internal_Dyn * entry;
103f02d3 10850
071436c6 10851 /* Read in the data. */
978c4450
AM
10852 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10853 filedata->dynamic_addr, 1,
10854 filedata->dynamic_size,
10855 _("dynamic section"));
a6e9f9df 10856 if (!edyn)
015dc7e1 10857 return false;
103f02d3 10858
071436c6
NC
10859 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10860 might not have the luxury of section headers. Look for the DT_NULL
10861 terminator to determine the number of entries. */
978c4450 10862 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10863 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10864 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10865 ext++)
10866 {
978c4450 10867 filedata->dynamic_nent++;
66543521 10868 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10869 break;
10870 }
252b5132 10871
978c4450
AM
10872 filedata->dynamic_section
10873 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10874 if (filedata->dynamic_section == NULL)
252b5132 10875 {
8b73c356 10876 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10877 (unsigned long) filedata->dynamic_nent);
252b5132 10878 free (edyn);
015dc7e1 10879 return false;
252b5132
RH
10880 }
10881
071436c6 10882 /* Convert from external to internal formats. */
978c4450
AM
10883 for (ext = edyn, entry = filedata->dynamic_section;
10884 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10885 ext++, entry++)
252b5132 10886 {
66543521
AM
10887 entry->d_tag = BYTE_GET (ext->d_tag);
10888 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10889 }
10890
10891 free (edyn);
10892
015dc7e1 10893 return true;
9ea033b2
NC
10894}
10895
4de91c10
AM
10896static bool
10897get_dynamic_section (Filedata *filedata)
10898{
10899 if (filedata->dynamic_section)
10900 return true;
10901
10902 if (is_32bit_elf)
10903 return get_32bit_dynamic_section (filedata);
10904 else
10905 return get_64bit_dynamic_section (filedata);
10906}
10907
e9e44622
JJ
10908static void
10909print_dynamic_flags (bfd_vma flags)
d1133906 10910{
015dc7e1 10911 bool first = true;
13ae64f3 10912
d1133906
NC
10913 while (flags)
10914 {
10915 bfd_vma flag;
10916
10917 flag = flags & - flags;
10918 flags &= ~ flag;
10919
e9e44622 10920 if (first)
015dc7e1 10921 first = false;
e9e44622
JJ
10922 else
10923 putc (' ', stdout);
13ae64f3 10924
d1133906
NC
10925 switch (flag)
10926 {
e9e44622
JJ
10927 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10928 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10929 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10930 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10931 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10932 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10933 }
10934 }
e9e44622 10935 puts ("");
d1133906
NC
10936}
10937
10ca4b04
L
10938static bfd_vma *
10939get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10940{
10941 unsigned char * e_data;
10942 bfd_vma * i_data;
10943
10944 /* If the size_t type is smaller than the bfd_size_type, eg because
10945 you are building a 32-bit tool on a 64-bit host, then make sure
10946 that when (number) is cast to (size_t) no information is lost. */
10947 if (sizeof (size_t) < sizeof (bfd_size_type)
10948 && (bfd_size_type) ((size_t) number) != number)
10949 {
10950 error (_("Size truncation prevents reading %s elements of size %u\n"),
10951 bfd_vmatoa ("u", number), ent_size);
10952 return NULL;
10953 }
10954
10955 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10956 attempting to allocate memory when the read is bound to fail. */
10957 if (ent_size * number > filedata->file_size)
10958 {
10959 error (_("Invalid number of dynamic entries: %s\n"),
10960 bfd_vmatoa ("u", number));
10961 return NULL;
10962 }
10963
10964 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10965 if (e_data == NULL)
10966 {
10967 error (_("Out of memory reading %s dynamic entries\n"),
10968 bfd_vmatoa ("u", number));
10969 return NULL;
10970 }
10971
10972 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10973 {
10974 error (_("Unable to read in %s bytes of dynamic data\n"),
10975 bfd_vmatoa ("u", number * ent_size));
10976 free (e_data);
10977 return NULL;
10978 }
10979
10980 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10981 if (i_data == NULL)
10982 {
10983 error (_("Out of memory allocating space for %s dynamic entries\n"),
10984 bfd_vmatoa ("u", number));
10985 free (e_data);
10986 return NULL;
10987 }
10988
10989 while (number--)
10990 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10991
10992 free (e_data);
10993
10994 return i_data;
10995}
10996
10997static unsigned long
10998get_num_dynamic_syms (Filedata * filedata)
10999{
11000 unsigned long num_of_syms = 0;
11001
11002 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11003 return num_of_syms;
11004
978c4450 11005 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11006 {
11007 unsigned char nb[8];
11008 unsigned char nc[8];
11009 unsigned int hash_ent_size = 4;
11010
11011 if ((filedata->file_header.e_machine == EM_ALPHA
11012 || filedata->file_header.e_machine == EM_S390
11013 || filedata->file_header.e_machine == EM_S390_OLD)
11014 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11015 hash_ent_size = 8;
11016
11017 if (fseek (filedata->handle,
978c4450
AM
11018 (filedata->archive_file_offset
11019 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11020 sizeof nb + sizeof nc)),
11021 SEEK_SET))
11022 {
11023 error (_("Unable to seek to start of dynamic information\n"));
11024 goto no_hash;
11025 }
11026
11027 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11028 {
11029 error (_("Failed to read in number of buckets\n"));
11030 goto no_hash;
11031 }
11032
11033 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11034 {
11035 error (_("Failed to read in number of chains\n"));
11036 goto no_hash;
11037 }
11038
978c4450
AM
11039 filedata->nbuckets = byte_get (nb, hash_ent_size);
11040 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11041
2482f306
AM
11042 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11043 {
11044 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11045 hash_ent_size);
11046 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11047 hash_ent_size);
001890e1 11048
2482f306
AM
11049 if (filedata->buckets != NULL && filedata->chains != NULL)
11050 num_of_syms = filedata->nchains;
11051 }
ceb9bf11 11052 no_hash:
10ca4b04
L
11053 if (num_of_syms == 0)
11054 {
9db70fc3
AM
11055 free (filedata->buckets);
11056 filedata->buckets = NULL;
11057 free (filedata->chains);
11058 filedata->chains = NULL;
978c4450 11059 filedata->nbuckets = 0;
10ca4b04
L
11060 }
11061 }
11062
978c4450 11063 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11064 {
11065 unsigned char nb[16];
11066 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11067 bfd_vma buckets_vma;
11068 unsigned long hn;
10ca4b04
L
11069
11070 if (fseek (filedata->handle,
978c4450
AM
11071 (filedata->archive_file_offset
11072 + offset_from_vma (filedata,
11073 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11074 sizeof nb)),
11075 SEEK_SET))
11076 {
11077 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11078 goto no_gnu_hash;
11079 }
11080
11081 if (fread (nb, 16, 1, filedata->handle) != 1)
11082 {
11083 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11084 goto no_gnu_hash;
11085 }
11086
978c4450
AM
11087 filedata->ngnubuckets = byte_get (nb, 4);
11088 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11089 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11090 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11091 if (is_32bit_elf)
11092 buckets_vma += bitmaskwords * 4;
11093 else
11094 buckets_vma += bitmaskwords * 8;
11095
11096 if (fseek (filedata->handle,
978c4450 11097 (filedata->archive_file_offset
10ca4b04
L
11098 + offset_from_vma (filedata, buckets_vma, 4)),
11099 SEEK_SET))
11100 {
11101 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11102 goto no_gnu_hash;
11103 }
11104
978c4450
AM
11105 filedata->gnubuckets
11106 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11107
978c4450 11108 if (filedata->gnubuckets == NULL)
90837ea7 11109 goto no_gnu_hash;
10ca4b04 11110
978c4450
AM
11111 for (i = 0; i < filedata->ngnubuckets; i++)
11112 if (filedata->gnubuckets[i] != 0)
10ca4b04 11113 {
978c4450 11114 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11115 goto no_gnu_hash;
10ca4b04 11116
978c4450
AM
11117 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11118 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11119 }
11120
11121 if (maxchain == 0xffffffff)
90837ea7 11122 goto no_gnu_hash;
10ca4b04 11123
978c4450 11124 maxchain -= filedata->gnusymidx;
10ca4b04
L
11125
11126 if (fseek (filedata->handle,
978c4450
AM
11127 (filedata->archive_file_offset
11128 + offset_from_vma (filedata,
11129 buckets_vma + 4 * (filedata->ngnubuckets
11130 + maxchain),
11131 4)),
10ca4b04
L
11132 SEEK_SET))
11133 {
11134 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11135 goto no_gnu_hash;
11136 }
11137
11138 do
11139 {
11140 if (fread (nb, 4, 1, filedata->handle) != 1)
11141 {
11142 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11143 goto no_gnu_hash;
11144 }
11145
11146 if (maxchain + 1 == 0)
90837ea7 11147 goto no_gnu_hash;
10ca4b04
L
11148
11149 ++maxchain;
11150 }
11151 while ((byte_get (nb, 4) & 1) == 0);
11152
11153 if (fseek (filedata->handle,
978c4450
AM
11154 (filedata->archive_file_offset
11155 + offset_from_vma (filedata, (buckets_vma
11156 + 4 * filedata->ngnubuckets),
11157 4)),
10ca4b04
L
11158 SEEK_SET))
11159 {
11160 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11161 goto no_gnu_hash;
11162 }
11163
978c4450
AM
11164 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11165 filedata->ngnuchains = maxchain;
10ca4b04 11166
978c4450 11167 if (filedata->gnuchains == NULL)
90837ea7 11168 goto no_gnu_hash;
10ca4b04 11169
978c4450 11170 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11171 {
11172 if (fseek (filedata->handle,
978c4450 11173 (filedata->archive_file_offset
10ca4b04 11174 + offset_from_vma (filedata, (buckets_vma
978c4450 11175 + 4 * (filedata->ngnubuckets
10ca4b04
L
11176 + maxchain)), 4)),
11177 SEEK_SET))
11178 {
11179 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11180 goto no_gnu_hash;
11181 }
11182
978c4450 11183 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11184 if (filedata->mipsxlat == NULL)
11185 goto no_gnu_hash;
10ca4b04
L
11186 }
11187
978c4450
AM
11188 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11189 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11190 {
978c4450
AM
11191 bfd_vma si = filedata->gnubuckets[hn];
11192 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11193
11194 do
11195 {
978c4450 11196 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11197 {
c31ab5a0
AM
11198 if (off < filedata->ngnuchains
11199 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11200 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11201 }
11202 else
11203 {
11204 if (si >= num_of_syms)
11205 num_of_syms = si + 1;
11206 }
11207 si++;
11208 }
978c4450
AM
11209 while (off < filedata->ngnuchains
11210 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11211 }
11212
90837ea7 11213 if (num_of_syms == 0)
10ca4b04 11214 {
90837ea7 11215 no_gnu_hash:
9db70fc3
AM
11216 free (filedata->mipsxlat);
11217 filedata->mipsxlat = NULL;
11218 free (filedata->gnuchains);
11219 filedata->gnuchains = NULL;
11220 free (filedata->gnubuckets);
11221 filedata->gnubuckets = NULL;
978c4450
AM
11222 filedata->ngnubuckets = 0;
11223 filedata->ngnuchains = 0;
10ca4b04
L
11224 }
11225 }
11226
11227 return num_of_syms;
11228}
11229
b2d38a17
NC
11230/* Parse and display the contents of the dynamic section. */
11231
015dc7e1 11232static bool
dda8d76d 11233process_dynamic_section (Filedata * filedata)
9ea033b2 11234{
2cf0635d 11235 Elf_Internal_Dyn * entry;
9ea033b2 11236
93df3340 11237 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11238 {
11239 if (do_dynamic)
ca0e11aa
NC
11240 {
11241 if (filedata->is_separate)
11242 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11243 filedata->file_name);
11244 else
11245 printf (_("\nThere is no dynamic section in this file.\n"));
11246 }
9ea033b2 11247
015dc7e1 11248 return true;
9ea033b2
NC
11249 }
11250
4de91c10
AM
11251 if (!get_dynamic_section (filedata))
11252 return false;
9ea033b2 11253
252b5132 11254 /* Find the appropriate symbol table. */
978c4450 11255 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11256 {
2482f306
AM
11257 unsigned long num_of_syms;
11258
978c4450
AM
11259 for (entry = filedata->dynamic_section;
11260 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11261 ++entry)
10ca4b04 11262 if (entry->d_tag == DT_SYMTAB)
978c4450 11263 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11264 else if (entry->d_tag == DT_SYMENT)
978c4450 11265 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11266 else if (entry->d_tag == DT_HASH)
978c4450 11267 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11268 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11269 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11270 else if ((filedata->file_header.e_machine == EM_MIPS
11271 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11272 && entry->d_tag == DT_MIPS_XHASH)
11273 {
978c4450
AM
11274 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11275 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11276 }
252b5132 11277
2482f306
AM
11278 num_of_syms = get_num_dynamic_syms (filedata);
11279
11280 if (num_of_syms != 0
11281 && filedata->dynamic_symbols == NULL
11282 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11283 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11284 {
11285 Elf_Internal_Phdr *seg;
2482f306 11286 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11287
2482f306
AM
11288 if (! get_program_headers (filedata))
11289 {
11290 error (_("Cannot interpret virtual addresses "
11291 "without program headers.\n"));
015dc7e1 11292 return false;
2482f306 11293 }
252b5132 11294
2482f306
AM
11295 for (seg = filedata->program_headers;
11296 seg < filedata->program_headers + filedata->file_header.e_phnum;
11297 ++seg)
11298 {
11299 if (seg->p_type != PT_LOAD)
11300 continue;
252b5132 11301
2482f306
AM
11302 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11303 {
11304 /* See PR 21379 for a reproducer. */
11305 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11306 return false;
2482f306 11307 }
252b5132 11308
2482f306
AM
11309 if (vma >= (seg->p_vaddr & -seg->p_align)
11310 && vma < seg->p_vaddr + seg->p_filesz)
11311 {
11312 /* Since we do not know how big the symbol table is,
11313 we default to reading in up to the end of PT_LOAD
11314 segment and processing that. This is overkill, I
11315 know, but it should work. */
11316 Elf_Internal_Shdr section;
11317 section.sh_offset = (vma - seg->p_vaddr
11318 + seg->p_offset);
11319 section.sh_size = (num_of_syms
11320 * filedata->dynamic_info[DT_SYMENT]);
11321 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11322
11323 if (do_checks
11324 && filedata->dynamic_symtab_section != NULL
11325 && ((filedata->dynamic_symtab_section->sh_offset
11326 != section.sh_offset)
11327 || (filedata->dynamic_symtab_section->sh_size
11328 != section.sh_size)
11329 || (filedata->dynamic_symtab_section->sh_entsize
11330 != section.sh_entsize)))
11331 warn (_("\
11332the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11333
2482f306
AM
11334 section.sh_name = filedata->string_table_length;
11335 filedata->dynamic_symbols
4de91c10 11336 = get_elf_symbols (filedata, &section,
2482f306
AM
11337 &filedata->num_dynamic_syms);
11338 if (filedata->dynamic_symbols == NULL
11339 || filedata->num_dynamic_syms != num_of_syms)
11340 {
11341 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11342 return false;
2482f306
AM
11343 }
11344 break;
11345 }
11346 }
11347 }
11348 }
252b5132
RH
11349
11350 /* Similarly find a string table. */
978c4450
AM
11351 if (filedata->dynamic_strings == NULL)
11352 for (entry = filedata->dynamic_section;
11353 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11354 ++entry)
11355 {
11356 if (entry->d_tag == DT_STRTAB)
978c4450 11357 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11358
10ca4b04 11359 if (entry->d_tag == DT_STRSZ)
978c4450 11360 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11361
978c4450
AM
11362 if (filedata->dynamic_info[DT_STRTAB]
11363 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11364 {
11365 unsigned long offset;
978c4450 11366 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11367
11368 offset = offset_from_vma (filedata,
978c4450 11369 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11370 str_tab_len);
8ac10c5b
L
11371 if (do_checks
11372 && filedata->dynamic_strtab_section
11373 && ((filedata->dynamic_strtab_section->sh_offset
11374 != (file_ptr) offset)
11375 || (filedata->dynamic_strtab_section->sh_size
11376 != str_tab_len)))
11377 warn (_("\
11378the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11379
978c4450
AM
11380 filedata->dynamic_strings
11381 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11382 _("dynamic string table"));
11383 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11384 {
11385 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11386 break;
11387 }
e3d39609 11388
978c4450 11389 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11390 break;
11391 }
11392 }
252b5132
RH
11393
11394 /* And find the syminfo section if available. */
978c4450 11395 if (filedata->dynamic_syminfo == NULL)
252b5132 11396 {
3e8bba36 11397 unsigned long syminsz = 0;
252b5132 11398
978c4450
AM
11399 for (entry = filedata->dynamic_section;
11400 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11401 ++entry)
252b5132
RH
11402 {
11403 if (entry->d_tag == DT_SYMINENT)
11404 {
11405 /* Note: these braces are necessary to avoid a syntax
11406 error from the SunOS4 C compiler. */
049b0c3a
NC
11407 /* PR binutils/17531: A corrupt file can trigger this test.
11408 So do not use an assert, instead generate an error message. */
11409 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11410 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11411 (int) entry->d_un.d_val);
252b5132
RH
11412 }
11413 else if (entry->d_tag == DT_SYMINSZ)
11414 syminsz = entry->d_un.d_val;
11415 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11416 filedata->dynamic_syminfo_offset
11417 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11418 }
11419
978c4450 11420 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11421 {
2cf0635d
NC
11422 Elf_External_Syminfo * extsyminfo;
11423 Elf_External_Syminfo * extsym;
11424 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11425
11426 /* There is a syminfo section. Read the data. */
3f5e193b 11427 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11428 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11429 1, syminsz, _("symbol information"));
a6e9f9df 11430 if (!extsyminfo)
015dc7e1 11431 return false;
252b5132 11432
978c4450 11433 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11434 {
11435 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11436 free (filedata->dynamic_syminfo);
e3d39609 11437 }
978c4450
AM
11438 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11439 if (filedata->dynamic_syminfo == NULL)
252b5132 11440 {
2482f306
AM
11441 error (_("Out of memory allocating %lu bytes "
11442 "for dynamic symbol info\n"),
8b73c356 11443 (unsigned long) syminsz);
015dc7e1 11444 return false;
252b5132
RH
11445 }
11446
2482f306
AM
11447 filedata->dynamic_syminfo_nent
11448 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11449 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11450 syminfo < (filedata->dynamic_syminfo
11451 + filedata->dynamic_syminfo_nent);
86dba8ee 11452 ++syminfo, ++extsym)
252b5132 11453 {
86dba8ee
AM
11454 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11455 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11456 }
11457
11458 free (extsyminfo);
11459 }
11460 }
11461
978c4450 11462 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11463 {
f253158f
NC
11464 if (filedata->is_separate)
11465 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11466 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11467 (unsigned long) filedata->dynamic_nent),
11468 filedata->file_name,
11469 filedata->dynamic_addr,
11470 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11471 else
11472 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11473 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11474 (unsigned long) filedata->dynamic_nent),
11475 filedata->dynamic_addr,
11476 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11477 }
252b5132
RH
11478 if (do_dynamic)
11479 printf (_(" Tag Type Name/Value\n"));
11480
978c4450
AM
11481 for (entry = filedata->dynamic_section;
11482 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11483 entry++)
252b5132
RH
11484 {
11485 if (do_dynamic)
f7a99963 11486 {
2cf0635d 11487 const char * dtype;
e699b9ff 11488
f7a99963
NC
11489 putchar (' ');
11490 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11491 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11492 printf (" (%s)%*s", dtype,
32ec8896 11493 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11494 }
252b5132
RH
11495
11496 switch (entry->d_tag)
11497 {
d1133906
NC
11498 case DT_FLAGS:
11499 if (do_dynamic)
e9e44622 11500 print_dynamic_flags (entry->d_un.d_val);
d1133906 11501 break;
76da6bbe 11502
252b5132
RH
11503 case DT_AUXILIARY:
11504 case DT_FILTER:
019148e4
L
11505 case DT_CONFIG:
11506 case DT_DEPAUDIT:
11507 case DT_AUDIT:
252b5132
RH
11508 if (do_dynamic)
11509 {
019148e4 11510 switch (entry->d_tag)
b34976b6 11511 {
019148e4
L
11512 case DT_AUXILIARY:
11513 printf (_("Auxiliary library"));
11514 break;
11515
11516 case DT_FILTER:
11517 printf (_("Filter library"));
11518 break;
11519
b34976b6 11520 case DT_CONFIG:
019148e4
L
11521 printf (_("Configuration file"));
11522 break;
11523
11524 case DT_DEPAUDIT:
11525 printf (_("Dependency audit library"));
11526 break;
11527
11528 case DT_AUDIT:
11529 printf (_("Audit library"));
11530 break;
11531 }
252b5132 11532
84714f86 11533 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11534 printf (": [%s]\n",
84714f86 11535 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11536 else
f7a99963
NC
11537 {
11538 printf (": ");
11539 print_vma (entry->d_un.d_val, PREFIX_HEX);
11540 putchar ('\n');
11541 }
252b5132
RH
11542 }
11543 break;
11544
dcefbbbd 11545 case DT_FEATURE:
252b5132
RH
11546 if (do_dynamic)
11547 {
11548 printf (_("Flags:"));
86f55779 11549
252b5132
RH
11550 if (entry->d_un.d_val == 0)
11551 printf (_(" None\n"));
11552 else
11553 {
11554 unsigned long int val = entry->d_un.d_val;
86f55779 11555
252b5132
RH
11556 if (val & DTF_1_PARINIT)
11557 {
11558 printf (" PARINIT");
11559 val ^= DTF_1_PARINIT;
11560 }
dcefbbbd
L
11561 if (val & DTF_1_CONFEXP)
11562 {
11563 printf (" CONFEXP");
11564 val ^= DTF_1_CONFEXP;
11565 }
252b5132
RH
11566 if (val != 0)
11567 printf (" %lx", val);
11568 puts ("");
11569 }
11570 }
11571 break;
11572
11573 case DT_POSFLAG_1:
11574 if (do_dynamic)
11575 {
11576 printf (_("Flags:"));
86f55779 11577
252b5132
RH
11578 if (entry->d_un.d_val == 0)
11579 printf (_(" None\n"));
11580 else
11581 {
11582 unsigned long int val = entry->d_un.d_val;
86f55779 11583
252b5132
RH
11584 if (val & DF_P1_LAZYLOAD)
11585 {
11586 printf (" LAZYLOAD");
11587 val ^= DF_P1_LAZYLOAD;
11588 }
11589 if (val & DF_P1_GROUPPERM)
11590 {
11591 printf (" GROUPPERM");
11592 val ^= DF_P1_GROUPPERM;
11593 }
11594 if (val != 0)
11595 printf (" %lx", val);
11596 puts ("");
11597 }
11598 }
11599 break;
11600
11601 case DT_FLAGS_1:
11602 if (do_dynamic)
11603 {
11604 printf (_("Flags:"));
11605 if (entry->d_un.d_val == 0)
11606 printf (_(" None\n"));
11607 else
11608 {
11609 unsigned long int val = entry->d_un.d_val;
86f55779 11610
252b5132
RH
11611 if (val & DF_1_NOW)
11612 {
11613 printf (" NOW");
11614 val ^= DF_1_NOW;
11615 }
11616 if (val & DF_1_GLOBAL)
11617 {
11618 printf (" GLOBAL");
11619 val ^= DF_1_GLOBAL;
11620 }
11621 if (val & DF_1_GROUP)
11622 {
11623 printf (" GROUP");
11624 val ^= DF_1_GROUP;
11625 }
11626 if (val & DF_1_NODELETE)
11627 {
11628 printf (" NODELETE");
11629 val ^= DF_1_NODELETE;
11630 }
11631 if (val & DF_1_LOADFLTR)
11632 {
11633 printf (" LOADFLTR");
11634 val ^= DF_1_LOADFLTR;
11635 }
11636 if (val & DF_1_INITFIRST)
11637 {
11638 printf (" INITFIRST");
11639 val ^= DF_1_INITFIRST;
11640 }
11641 if (val & DF_1_NOOPEN)
11642 {
11643 printf (" NOOPEN");
11644 val ^= DF_1_NOOPEN;
11645 }
11646 if (val & DF_1_ORIGIN)
11647 {
11648 printf (" ORIGIN");
11649 val ^= DF_1_ORIGIN;
11650 }
11651 if (val & DF_1_DIRECT)
11652 {
11653 printf (" DIRECT");
11654 val ^= DF_1_DIRECT;
11655 }
11656 if (val & DF_1_TRANS)
11657 {
11658 printf (" TRANS");
11659 val ^= DF_1_TRANS;
11660 }
11661 if (val & DF_1_INTERPOSE)
11662 {
11663 printf (" INTERPOSE");
11664 val ^= DF_1_INTERPOSE;
11665 }
f7db6139 11666 if (val & DF_1_NODEFLIB)
dcefbbbd 11667 {
f7db6139
L
11668 printf (" NODEFLIB");
11669 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11670 }
11671 if (val & DF_1_NODUMP)
11672 {
11673 printf (" NODUMP");
11674 val ^= DF_1_NODUMP;
11675 }
34b60028 11676 if (val & DF_1_CONFALT)
dcefbbbd 11677 {
34b60028
L
11678 printf (" CONFALT");
11679 val ^= DF_1_CONFALT;
11680 }
11681 if (val & DF_1_ENDFILTEE)
11682 {
11683 printf (" ENDFILTEE");
11684 val ^= DF_1_ENDFILTEE;
11685 }
11686 if (val & DF_1_DISPRELDNE)
11687 {
11688 printf (" DISPRELDNE");
11689 val ^= DF_1_DISPRELDNE;
11690 }
11691 if (val & DF_1_DISPRELPND)
11692 {
11693 printf (" DISPRELPND");
11694 val ^= DF_1_DISPRELPND;
11695 }
11696 if (val & DF_1_NODIRECT)
11697 {
11698 printf (" NODIRECT");
11699 val ^= DF_1_NODIRECT;
11700 }
11701 if (val & DF_1_IGNMULDEF)
11702 {
11703 printf (" IGNMULDEF");
11704 val ^= DF_1_IGNMULDEF;
11705 }
11706 if (val & DF_1_NOKSYMS)
11707 {
11708 printf (" NOKSYMS");
11709 val ^= DF_1_NOKSYMS;
11710 }
11711 if (val & DF_1_NOHDR)
11712 {
11713 printf (" NOHDR");
11714 val ^= DF_1_NOHDR;
11715 }
11716 if (val & DF_1_EDITED)
11717 {
11718 printf (" EDITED");
11719 val ^= DF_1_EDITED;
11720 }
11721 if (val & DF_1_NORELOC)
11722 {
11723 printf (" NORELOC");
11724 val ^= DF_1_NORELOC;
11725 }
11726 if (val & DF_1_SYMINTPOSE)
11727 {
11728 printf (" SYMINTPOSE");
11729 val ^= DF_1_SYMINTPOSE;
11730 }
11731 if (val & DF_1_GLOBAUDIT)
11732 {
11733 printf (" GLOBAUDIT");
11734 val ^= DF_1_GLOBAUDIT;
11735 }
11736 if (val & DF_1_SINGLETON)
11737 {
11738 printf (" SINGLETON");
11739 val ^= DF_1_SINGLETON;
dcefbbbd 11740 }
5c383f02
RO
11741 if (val & DF_1_STUB)
11742 {
11743 printf (" STUB");
11744 val ^= DF_1_STUB;
11745 }
11746 if (val & DF_1_PIE)
11747 {
11748 printf (" PIE");
11749 val ^= DF_1_PIE;
11750 }
b1202ffa
L
11751 if (val & DF_1_KMOD)
11752 {
11753 printf (" KMOD");
11754 val ^= DF_1_KMOD;
11755 }
11756 if (val & DF_1_WEAKFILTER)
11757 {
11758 printf (" WEAKFILTER");
11759 val ^= DF_1_WEAKFILTER;
11760 }
11761 if (val & DF_1_NOCOMMON)
11762 {
11763 printf (" NOCOMMON");
11764 val ^= DF_1_NOCOMMON;
11765 }
252b5132
RH
11766 if (val != 0)
11767 printf (" %lx", val);
11768 puts ("");
11769 }
11770 }
11771 break;
11772
11773 case DT_PLTREL:
978c4450 11774 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11775 if (do_dynamic)
dda8d76d 11776 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11777 break;
11778
11779 case DT_NULL :
11780 case DT_NEEDED :
11781 case DT_PLTGOT :
11782 case DT_HASH :
11783 case DT_STRTAB :
11784 case DT_SYMTAB :
11785 case DT_RELA :
11786 case DT_INIT :
11787 case DT_FINI :
11788 case DT_SONAME :
11789 case DT_RPATH :
11790 case DT_SYMBOLIC:
11791 case DT_REL :
a7fd1186 11792 case DT_RELR :
252b5132
RH
11793 case DT_DEBUG :
11794 case DT_TEXTREL :
11795 case DT_JMPREL :
019148e4 11796 case DT_RUNPATH :
978c4450 11797 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11798
11799 if (do_dynamic)
11800 {
84714f86 11801 const char *name;
252b5132 11802
84714f86
AM
11803 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11804 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11805 else
d79b3d50 11806 name = NULL;
252b5132
RH
11807
11808 if (name)
11809 {
11810 switch (entry->d_tag)
11811 {
11812 case DT_NEEDED:
11813 printf (_("Shared library: [%s]"), name);
11814
13acb58d
AM
11815 if (filedata->program_interpreter
11816 && streq (name, filedata->program_interpreter))
f7a99963 11817 printf (_(" program interpreter"));
252b5132
RH
11818 break;
11819
11820 case DT_SONAME:
f7a99963 11821 printf (_("Library soname: [%s]"), name);
252b5132
RH
11822 break;
11823
11824 case DT_RPATH:
f7a99963 11825 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11826 break;
11827
019148e4
L
11828 case DT_RUNPATH:
11829 printf (_("Library runpath: [%s]"), name);
11830 break;
11831
252b5132 11832 default:
f7a99963
NC
11833 print_vma (entry->d_un.d_val, PREFIX_HEX);
11834 break;
252b5132
RH
11835 }
11836 }
11837 else
f7a99963
NC
11838 print_vma (entry->d_un.d_val, PREFIX_HEX);
11839
11840 putchar ('\n');
252b5132
RH
11841 }
11842 break;
11843
11844 case DT_PLTRELSZ:
11845 case DT_RELASZ :
11846 case DT_STRSZ :
11847 case DT_RELSZ :
11848 case DT_RELAENT :
a7fd1186
FS
11849 case DT_RELRENT :
11850 case DT_RELRSZ :
252b5132
RH
11851 case DT_SYMENT :
11852 case DT_RELENT :
978c4450 11853 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11854 /* Fall through. */
252b5132
RH
11855 case DT_PLTPADSZ:
11856 case DT_MOVEENT :
11857 case DT_MOVESZ :
04d8355a 11858 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11859 case DT_INIT_ARRAYSZ:
11860 case DT_FINI_ARRAYSZ:
047b2264
JJ
11861 case DT_GNU_CONFLICTSZ:
11862 case DT_GNU_LIBLISTSZ:
252b5132 11863 if (do_dynamic)
f7a99963
NC
11864 {
11865 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11866 printf (_(" (bytes)\n"));
f7a99963 11867 }
252b5132
RH
11868 break;
11869
11870 case DT_VERDEFNUM:
11871 case DT_VERNEEDNUM:
11872 case DT_RELACOUNT:
11873 case DT_RELCOUNT:
11874 if (do_dynamic)
f7a99963
NC
11875 {
11876 print_vma (entry->d_un.d_val, UNSIGNED);
11877 putchar ('\n');
11878 }
252b5132
RH
11879 break;
11880
11881 case DT_SYMINSZ:
11882 case DT_SYMINENT:
11883 case DT_SYMINFO:
11884 case DT_USED:
11885 case DT_INIT_ARRAY:
11886 case DT_FINI_ARRAY:
11887 if (do_dynamic)
11888 {
d79b3d50 11889 if (entry->d_tag == DT_USED
84714f86 11890 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11891 {
84714f86
AM
11892 const char *name
11893 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11894
b34976b6 11895 if (*name)
252b5132
RH
11896 {
11897 printf (_("Not needed object: [%s]\n"), name);
11898 break;
11899 }
11900 }
103f02d3 11901
f7a99963
NC
11902 print_vma (entry->d_un.d_val, PREFIX_HEX);
11903 putchar ('\n');
252b5132
RH
11904 }
11905 break;
11906
11907 case DT_BIND_NOW:
11908 /* The value of this entry is ignored. */
35b1837e
AM
11909 if (do_dynamic)
11910 putchar ('\n');
252b5132 11911 break;
103f02d3 11912
047b2264
JJ
11913 case DT_GNU_PRELINKED:
11914 if (do_dynamic)
11915 {
2cf0635d 11916 struct tm * tmp;
91d6fa6a 11917 time_t atime = entry->d_un.d_val;
047b2264 11918
91d6fa6a 11919 tmp = gmtime (&atime);
071436c6
NC
11920 /* PR 17533 file: 041-1244816-0.004. */
11921 if (tmp == NULL)
5a2cbcf4
L
11922 printf (_("<corrupt time val: %lx"),
11923 (unsigned long) atime);
071436c6
NC
11924 else
11925 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11926 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11927 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11928
11929 }
11930 break;
11931
fdc90cb4 11932 case DT_GNU_HASH:
978c4450 11933 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11934 if (do_dynamic)
11935 {
11936 print_vma (entry->d_un.d_val, PREFIX_HEX);
11937 putchar ('\n');
11938 }
11939 break;
11940
a5da3dee
VDM
11941 case DT_GNU_FLAGS_1:
11942 if (do_dynamic)
11943 {
11944 printf (_("Flags:"));
11945 if (entry->d_un.d_val == 0)
11946 printf (_(" None\n"));
11947 else
11948 {
11949 unsigned long int val = entry->d_un.d_val;
11950
11951 if (val & DF_GNU_1_UNIQUE)
11952 {
11953 printf (" UNIQUE");
11954 val ^= DF_GNU_1_UNIQUE;
11955 }
11956 if (val != 0)
11957 printf (" %lx", val);
11958 puts ("");
11959 }
11960 }
11961 break;
11962
252b5132
RH
11963 default:
11964 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11965 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11966 = entry->d_un.d_val;
252b5132
RH
11967
11968 if (do_dynamic)
11969 {
dda8d76d 11970 switch (filedata->file_header.e_machine)
252b5132 11971 {
37c18eed
SD
11972 case EM_AARCH64:
11973 dynamic_section_aarch64_val (entry);
11974 break;
252b5132 11975 case EM_MIPS:
4fe85591 11976 case EM_MIPS_RS3_LE:
978c4450 11977 dynamic_section_mips_val (filedata, entry);
252b5132 11978 break;
103f02d3 11979 case EM_PARISC:
b2d38a17 11980 dynamic_section_parisc_val (entry);
103f02d3 11981 break;
ecc51f48 11982 case EM_IA_64:
b2d38a17 11983 dynamic_section_ia64_val (entry);
ecc51f48 11984 break;
252b5132 11985 default:
f7a99963
NC
11986 print_vma (entry->d_un.d_val, PREFIX_HEX);
11987 putchar ('\n');
252b5132
RH
11988 }
11989 }
11990 break;
11991 }
11992 }
11993
015dc7e1 11994 return true;
252b5132
RH
11995}
11996
11997static char *
d3ba0551 11998get_ver_flags (unsigned int flags)
252b5132 11999{
6d4f21f6 12000 static char buff[128];
252b5132
RH
12001
12002 buff[0] = 0;
12003
12004 if (flags == 0)
12005 return _("none");
12006
12007 if (flags & VER_FLG_BASE)
7bb1ad17 12008 strcat (buff, "BASE");
252b5132
RH
12009
12010 if (flags & VER_FLG_WEAK)
12011 {
12012 if (flags & VER_FLG_BASE)
7bb1ad17 12013 strcat (buff, " | ");
252b5132 12014
7bb1ad17 12015 strcat (buff, "WEAK");
252b5132
RH
12016 }
12017
44ec90b9
RO
12018 if (flags & VER_FLG_INFO)
12019 {
12020 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12021 strcat (buff, " | ");
44ec90b9 12022
7bb1ad17 12023 strcat (buff, "INFO");
44ec90b9
RO
12024 }
12025
12026 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12027 {
12028 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12029 strcat (buff, " | ");
12030
12031 strcat (buff, _("<unknown>"));
12032 }
252b5132
RH
12033
12034 return buff;
12035}
12036
12037/* Display the contents of the version sections. */
98fb390a 12038
015dc7e1 12039static bool
dda8d76d 12040process_version_sections (Filedata * filedata)
252b5132 12041{
2cf0635d 12042 Elf_Internal_Shdr * section;
b34976b6 12043 unsigned i;
015dc7e1 12044 bool found = false;
252b5132
RH
12045
12046 if (! do_version)
015dc7e1 12047 return true;
252b5132 12048
dda8d76d
NC
12049 for (i = 0, section = filedata->section_headers;
12050 i < filedata->file_header.e_shnum;
b34976b6 12051 i++, section++)
252b5132
RH
12052 {
12053 switch (section->sh_type)
12054 {
12055 case SHT_GNU_verdef:
12056 {
2cf0635d 12057 Elf_External_Verdef * edefs;
452bf675
AM
12058 unsigned long idx;
12059 unsigned long cnt;
2cf0635d 12060 char * endbuf;
252b5132 12061
015dc7e1 12062 found = true;
252b5132 12063
ca0e11aa
NC
12064 if (filedata->is_separate)
12065 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12066 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12067 section->sh_info),
12068 filedata->file_name,
12069 printable_section_name (filedata, section),
12070 section->sh_info);
12071 else
12072 printf (ngettext ("\nVersion definition section '%s' "
12073 "contains %u entry:\n",
12074 "\nVersion definition section '%s' "
12075 "contains %u entries:\n",
12076 section->sh_info),
12077 printable_section_name (filedata, section),
12078 section->sh_info);
047c3dbf 12079
ae9ac79e 12080 printf (_(" Addr: 0x"));
252b5132 12081 printf_vma (section->sh_addr);
233f82cf 12082 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12083 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12084 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12085
3f5e193b 12086 edefs = (Elf_External_Verdef *)
dda8d76d 12087 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12088 _("version definition section"));
a6e9f9df
AM
12089 if (!edefs)
12090 break;
59245841 12091 endbuf = (char *) edefs + section->sh_size;
252b5132 12092
1445030f 12093 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12094 {
2cf0635d
NC
12095 char * vstart;
12096 Elf_External_Verdef * edef;
b34976b6 12097 Elf_Internal_Verdef ent;
2cf0635d 12098 Elf_External_Verdaux * eaux;
b34976b6 12099 Elf_Internal_Verdaux aux;
452bf675 12100 unsigned long isum;
b34976b6 12101 int j;
103f02d3 12102
252b5132 12103 vstart = ((char *) edefs) + idx;
54806181
AM
12104 if (vstart + sizeof (*edef) > endbuf)
12105 break;
252b5132
RH
12106
12107 edef = (Elf_External_Verdef *) vstart;
12108
12109 ent.vd_version = BYTE_GET (edef->vd_version);
12110 ent.vd_flags = BYTE_GET (edef->vd_flags);
12111 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12112 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12113 ent.vd_hash = BYTE_GET (edef->vd_hash);
12114 ent.vd_aux = BYTE_GET (edef->vd_aux);
12115 ent.vd_next = BYTE_GET (edef->vd_next);
12116
452bf675 12117 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12118 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12119
12120 printf (_(" Index: %d Cnt: %d "),
12121 ent.vd_ndx, ent.vd_cnt);
12122
452bf675 12123 /* Check for overflow. */
1445030f 12124 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12125 break;
12126
252b5132
RH
12127 vstart += ent.vd_aux;
12128
1445030f
AM
12129 if (vstart + sizeof (*eaux) > endbuf)
12130 break;
252b5132
RH
12131 eaux = (Elf_External_Verdaux *) vstart;
12132
12133 aux.vda_name = BYTE_GET (eaux->vda_name);
12134 aux.vda_next = BYTE_GET (eaux->vda_next);
12135
84714f86 12136 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12137 printf (_("Name: %s\n"),
84714f86 12138 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12139 else
12140 printf (_("Name index: %ld\n"), aux.vda_name);
12141
12142 isum = idx + ent.vd_aux;
12143
b34976b6 12144 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12145 {
1445030f
AM
12146 if (aux.vda_next < sizeof (*eaux)
12147 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12148 {
12149 warn (_("Invalid vda_next field of %lx\n"),
12150 aux.vda_next);
12151 j = ent.vd_cnt;
12152 break;
12153 }
dd24e3da 12154 /* Check for overflow. */
7e26601c 12155 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12156 break;
12157
252b5132
RH
12158 isum += aux.vda_next;
12159 vstart += aux.vda_next;
12160
54806181
AM
12161 if (vstart + sizeof (*eaux) > endbuf)
12162 break;
1445030f 12163 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12164
12165 aux.vda_name = BYTE_GET (eaux->vda_name);
12166 aux.vda_next = BYTE_GET (eaux->vda_next);
12167
84714f86 12168 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12169 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12170 isum, j,
84714f86 12171 get_dynamic_name (filedata, aux.vda_name));
252b5132 12172 else
452bf675 12173 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12174 isum, j, aux.vda_name);
12175 }
dd24e3da 12176
54806181
AM
12177 if (j < ent.vd_cnt)
12178 printf (_(" Version def aux past end of section\n"));
252b5132 12179
c9f02c3e
MR
12180 /* PR 17531:
12181 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12182 if (ent.vd_next < sizeof (*edef)
12183 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12184 {
12185 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12186 cnt = section->sh_info;
12187 break;
12188 }
452bf675 12189 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12190 break;
12191
252b5132
RH
12192 idx += ent.vd_next;
12193 }
dd24e3da 12194
54806181
AM
12195 if (cnt < section->sh_info)
12196 printf (_(" Version definition past end of section\n"));
252b5132
RH
12197
12198 free (edefs);
12199 }
12200 break;
103f02d3 12201
252b5132
RH
12202 case SHT_GNU_verneed:
12203 {
2cf0635d 12204 Elf_External_Verneed * eneed;
452bf675
AM
12205 unsigned long idx;
12206 unsigned long cnt;
2cf0635d 12207 char * endbuf;
252b5132 12208
015dc7e1 12209 found = true;
252b5132 12210
ca0e11aa
NC
12211 if (filedata->is_separate)
12212 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12213 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12214 section->sh_info),
12215 filedata->file_name,
12216 printable_section_name (filedata, section),
12217 section->sh_info);
12218 else
12219 printf (ngettext ("\nVersion needs section '%s' "
12220 "contains %u entry:\n",
12221 "\nVersion needs section '%s' "
12222 "contains %u entries:\n",
12223 section->sh_info),
12224 printable_section_name (filedata, section),
12225 section->sh_info);
047c3dbf 12226
252b5132
RH
12227 printf (_(" Addr: 0x"));
12228 printf_vma (section->sh_addr);
72de5009 12229 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12230 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12231 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12232
dda8d76d 12233 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12234 section->sh_offset, 1,
12235 section->sh_size,
9cf03b7e 12236 _("Version Needs section"));
a6e9f9df
AM
12237 if (!eneed)
12238 break;
59245841 12239 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12240
12241 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12242 {
2cf0635d 12243 Elf_External_Verneed * entry;
b34976b6 12244 Elf_Internal_Verneed ent;
452bf675 12245 unsigned long isum;
b34976b6 12246 int j;
2cf0635d 12247 char * vstart;
252b5132
RH
12248
12249 vstart = ((char *) eneed) + idx;
54806181
AM
12250 if (vstart + sizeof (*entry) > endbuf)
12251 break;
252b5132
RH
12252
12253 entry = (Elf_External_Verneed *) vstart;
12254
12255 ent.vn_version = BYTE_GET (entry->vn_version);
12256 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12257 ent.vn_file = BYTE_GET (entry->vn_file);
12258 ent.vn_aux = BYTE_GET (entry->vn_aux);
12259 ent.vn_next = BYTE_GET (entry->vn_next);
12260
452bf675 12261 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12262
84714f86 12263 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12264 printf (_(" File: %s"),
84714f86 12265 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12266 else
12267 printf (_(" File: %lx"), ent.vn_file);
12268
12269 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12270
dd24e3da 12271 /* Check for overflow. */
7e26601c 12272 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12273 break;
252b5132
RH
12274 vstart += ent.vn_aux;
12275
12276 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12277 {
2cf0635d 12278 Elf_External_Vernaux * eaux;
b34976b6 12279 Elf_Internal_Vernaux aux;
252b5132 12280
54806181
AM
12281 if (vstart + sizeof (*eaux) > endbuf)
12282 break;
252b5132
RH
12283 eaux = (Elf_External_Vernaux *) vstart;
12284
12285 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12286 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12287 aux.vna_other = BYTE_GET (eaux->vna_other);
12288 aux.vna_name = BYTE_GET (eaux->vna_name);
12289 aux.vna_next = BYTE_GET (eaux->vna_next);
12290
84714f86 12291 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12292 printf (_(" %#06lx: Name: %s"),
84714f86 12293 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12294 else
452bf675 12295 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12296 isum, aux.vna_name);
12297
12298 printf (_(" Flags: %s Version: %d\n"),
12299 get_ver_flags (aux.vna_flags), aux.vna_other);
12300
1445030f
AM
12301 if (aux.vna_next < sizeof (*eaux)
12302 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12303 {
12304 warn (_("Invalid vna_next field of %lx\n"),
12305 aux.vna_next);
12306 j = ent.vn_cnt;
12307 break;
12308 }
1445030f
AM
12309 /* Check for overflow. */
12310 if (aux.vna_next > (size_t) (endbuf - vstart))
12311 break;
252b5132
RH
12312 isum += aux.vna_next;
12313 vstart += aux.vna_next;
12314 }
9cf03b7e 12315
54806181 12316 if (j < ent.vn_cnt)
f9a6a8f0 12317 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12318
1445030f
AM
12319 if (ent.vn_next < sizeof (*entry)
12320 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12321 {
452bf675 12322 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12323 cnt = section->sh_info;
12324 break;
12325 }
1445030f
AM
12326 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12327 break;
252b5132
RH
12328 idx += ent.vn_next;
12329 }
9cf03b7e 12330
54806181 12331 if (cnt < section->sh_info)
9cf03b7e 12332 warn (_("Missing Version Needs information\n"));
103f02d3 12333
252b5132
RH
12334 free (eneed);
12335 }
12336 break;
12337
12338 case SHT_GNU_versym:
12339 {
2cf0635d 12340 Elf_Internal_Shdr * link_section;
8b73c356
NC
12341 size_t total;
12342 unsigned int cnt;
2cf0635d
NC
12343 unsigned char * edata;
12344 unsigned short * data;
12345 char * strtab;
12346 Elf_Internal_Sym * symbols;
12347 Elf_Internal_Shdr * string_sec;
ba5cdace 12348 unsigned long num_syms;
d3ba0551 12349 long off;
252b5132 12350
dda8d76d 12351 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12352 break;
12353
dda8d76d 12354 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12355 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12356
dda8d76d 12357 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12358 break;
12359
015dc7e1 12360 found = true;
252b5132 12361
4de91c10 12362 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12363 if (symbols == NULL)
12364 break;
252b5132 12365
dda8d76d 12366 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12367
dda8d76d 12368 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12369 string_sec->sh_size,
12370 _("version string table"));
a6e9f9df 12371 if (!strtab)
0429c154
MS
12372 {
12373 free (symbols);
12374 break;
12375 }
252b5132 12376
ca0e11aa
NC
12377 if (filedata->is_separate)
12378 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12379 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12380 total),
12381 filedata->file_name,
12382 printable_section_name (filedata, section),
12383 (unsigned long) total);
12384 else
12385 printf (ngettext ("\nVersion symbols section '%s' "
12386 "contains %lu entry:\n",
12387 "\nVersion symbols section '%s' "
12388 "contains %lu entries:\n",
12389 total),
12390 printable_section_name (filedata, section),
12391 (unsigned long) total);
252b5132 12392
ae9ac79e 12393 printf (_(" Addr: 0x"));
252b5132 12394 printf_vma (section->sh_addr);
72de5009 12395 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12396 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12397 printable_section_name (filedata, link_section));
252b5132 12398
dda8d76d 12399 off = offset_from_vma (filedata,
978c4450 12400 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12401 total * sizeof (short));
95099889
AM
12402 edata = (unsigned char *) get_data (NULL, filedata, off,
12403 sizeof (short), total,
12404 _("version symbol data"));
a6e9f9df
AM
12405 if (!edata)
12406 {
12407 free (strtab);
0429c154 12408 free (symbols);
a6e9f9df
AM
12409 break;
12410 }
252b5132 12411
3f5e193b 12412 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12413
12414 for (cnt = total; cnt --;)
b34976b6
AM
12415 data[cnt] = byte_get (edata + cnt * sizeof (short),
12416 sizeof (short));
252b5132
RH
12417
12418 free (edata);
12419
12420 for (cnt = 0; cnt < total; cnt += 4)
12421 {
12422 int j, nn;
ab273396
AM
12423 char *name;
12424 char *invalid = _("*invalid*");
252b5132
RH
12425
12426 printf (" %03x:", cnt);
12427
12428 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12429 switch (data[cnt + j])
252b5132
RH
12430 {
12431 case 0:
12432 fputs (_(" 0 (*local*) "), stdout);
12433 break;
12434
12435 case 1:
12436 fputs (_(" 1 (*global*) "), stdout);
12437 break;
12438
12439 default:
c244d050
NC
12440 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12441 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12442
dd24e3da 12443 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12444 array, break to avoid an out-of-bounds read. */
12445 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12446 {
12447 warn (_("invalid index into symbol array\n"));
12448 break;
12449 }
12450
ab273396 12451 name = NULL;
978c4450 12452 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12453 {
b34976b6
AM
12454 Elf_Internal_Verneed ivn;
12455 unsigned long offset;
252b5132 12456
d93f0186 12457 offset = offset_from_vma
978c4450
AM
12458 (filedata,
12459 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12460 sizeof (Elf_External_Verneed));
252b5132 12461
b34976b6 12462 do
252b5132 12463 {
b34976b6
AM
12464 Elf_Internal_Vernaux ivna;
12465 Elf_External_Verneed evn;
12466 Elf_External_Vernaux evna;
12467 unsigned long a_off;
252b5132 12468
dda8d76d 12469 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12470 _("version need")) == NULL)
12471 break;
0b4362b0 12472
252b5132
RH
12473 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12474 ivn.vn_next = BYTE_GET (evn.vn_next);
12475
12476 a_off = offset + ivn.vn_aux;
12477
12478 do
12479 {
dda8d76d 12480 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12481 1, _("version need aux (2)")) == NULL)
12482 {
12483 ivna.vna_next = 0;
12484 ivna.vna_other = 0;
12485 }
12486 else
12487 {
12488 ivna.vna_next = BYTE_GET (evna.vna_next);
12489 ivna.vna_other = BYTE_GET (evna.vna_other);
12490 }
252b5132
RH
12491
12492 a_off += ivna.vna_next;
12493 }
b34976b6 12494 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12495 && ivna.vna_next != 0);
12496
b34976b6 12497 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12498 {
12499 ivna.vna_name = BYTE_GET (evna.vna_name);
12500
54806181 12501 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12502 name = invalid;
54806181
AM
12503 else
12504 name = strtab + ivna.vna_name;
252b5132
RH
12505 break;
12506 }
12507
12508 offset += ivn.vn_next;
12509 }
12510 while (ivn.vn_next);
12511 }
00d93f34 12512
ab273396 12513 if (data[cnt + j] != 0x8001
978c4450 12514 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12515 {
b34976b6
AM
12516 Elf_Internal_Verdef ivd;
12517 Elf_External_Verdef evd;
12518 unsigned long offset;
252b5132 12519
d93f0186 12520 offset = offset_from_vma
978c4450
AM
12521 (filedata,
12522 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12523 sizeof evd);
252b5132
RH
12524
12525 do
12526 {
dda8d76d 12527 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12528 _("version def")) == NULL)
12529 {
12530 ivd.vd_next = 0;
948f632f 12531 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12532 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12533 break;
59245841
NC
12534 }
12535 else
12536 {
12537 ivd.vd_next = BYTE_GET (evd.vd_next);
12538 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12539 }
252b5132
RH
12540
12541 offset += ivd.vd_next;
12542 }
c244d050 12543 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12544 && ivd.vd_next != 0);
12545
c244d050 12546 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12547 {
b34976b6
AM
12548 Elf_External_Verdaux evda;
12549 Elf_Internal_Verdaux ivda;
252b5132
RH
12550
12551 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12552
dda8d76d 12553 if (get_data (&evda, filedata,
59245841
NC
12554 offset - ivd.vd_next + ivd.vd_aux,
12555 sizeof (evda), 1,
12556 _("version def aux")) == NULL)
12557 break;
252b5132
RH
12558
12559 ivda.vda_name = BYTE_GET (evda.vda_name);
12560
54806181 12561 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12562 name = invalid;
12563 else if (name != NULL && name != invalid)
12564 name = _("*both*");
54806181
AM
12565 else
12566 name = strtab + ivda.vda_name;
252b5132
RH
12567 }
12568 }
ab273396
AM
12569 if (name != NULL)
12570 nn += printf ("(%s%-*s",
12571 name,
12572 12 - (int) strlen (name),
12573 ")");
252b5132
RH
12574
12575 if (nn < 18)
12576 printf ("%*c", 18 - nn, ' ');
12577 }
12578
12579 putchar ('\n');
12580 }
12581
12582 free (data);
12583 free (strtab);
12584 free (symbols);
12585 }
12586 break;
103f02d3 12587
252b5132
RH
12588 default:
12589 break;
12590 }
12591 }
12592
12593 if (! found)
ca0e11aa
NC
12594 {
12595 if (filedata->is_separate)
12596 printf (_("\nNo version information found in linked file '%s'.\n"),
12597 filedata->file_name);
12598 else
12599 printf (_("\nNo version information found in this file.\n"));
12600 }
252b5132 12601
015dc7e1 12602 return true;
252b5132
RH
12603}
12604
d1133906 12605static const char *
dda8d76d 12606get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12607{
89246a0e 12608 static char buff[64];
252b5132
RH
12609
12610 switch (binding)
12611 {
b34976b6
AM
12612 case STB_LOCAL: return "LOCAL";
12613 case STB_GLOBAL: return "GLOBAL";
12614 case STB_WEAK: return "WEAK";
252b5132
RH
12615 default:
12616 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12617 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12618 binding);
252b5132 12619 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12620 {
12621 if (binding == STB_GNU_UNIQUE
df3a023b 12622 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12623 return "UNIQUE";
12624 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12625 }
252b5132 12626 else
e9e44622 12627 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12628 return buff;
12629 }
12630}
12631
d1133906 12632static const char *
dda8d76d 12633get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12634{
89246a0e 12635 static char buff[64];
252b5132
RH
12636
12637 switch (type)
12638 {
b34976b6
AM
12639 case STT_NOTYPE: return "NOTYPE";
12640 case STT_OBJECT: return "OBJECT";
12641 case STT_FUNC: return "FUNC";
12642 case STT_SECTION: return "SECTION";
12643 case STT_FILE: return "FILE";
12644 case STT_COMMON: return "COMMON";
12645 case STT_TLS: return "TLS";
15ab5209
DB
12646 case STT_RELC: return "RELC";
12647 case STT_SRELC: return "SRELC";
252b5132
RH
12648 default:
12649 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12650 {
dda8d76d 12651 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12652 return "THUMB_FUNC";
103f02d3 12653
dda8d76d 12654 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12655 return "REGISTER";
12656
dda8d76d 12657 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12658 return "PARISC_MILLI";
12659
e9e44622 12660 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12661 }
252b5132 12662 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12663 {
dda8d76d 12664 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12665 {
12666 if (type == STT_HP_OPAQUE)
12667 return "HP_OPAQUE";
12668 if (type == STT_HP_STUB)
12669 return "HP_STUB";
12670 }
12671
d8045f23 12672 if (type == STT_GNU_IFUNC
dda8d76d 12673 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12674 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12675 return "IFUNC";
12676
e9e44622 12677 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12678 }
252b5132 12679 else
e9e44622 12680 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12681 return buff;
12682 }
12683}
12684
d1133906 12685static const char *
d3ba0551 12686get_symbol_visibility (unsigned int visibility)
d1133906
NC
12687{
12688 switch (visibility)
12689 {
b34976b6
AM
12690 case STV_DEFAULT: return "DEFAULT";
12691 case STV_INTERNAL: return "INTERNAL";
12692 case STV_HIDDEN: return "HIDDEN";
d1133906 12693 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12694 default:
27a45f42 12695 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12696 return _("<unknown>");
d1133906
NC
12697 }
12698}
12699
2057d69d
CZ
12700static const char *
12701get_alpha_symbol_other (unsigned int other)
9abca702 12702{
2057d69d
CZ
12703 switch (other)
12704 {
12705 case STO_ALPHA_NOPV: return "NOPV";
12706 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12707 default:
27a45f42 12708 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12709 return _("<unknown>");
9abca702 12710 }
2057d69d
CZ
12711}
12712
fd85a6a1
NC
12713static const char *
12714get_solaris_symbol_visibility (unsigned int visibility)
12715{
12716 switch (visibility)
12717 {
12718 case 4: return "EXPORTED";
12719 case 5: return "SINGLETON";
12720 case 6: return "ELIMINATE";
12721 default: return get_symbol_visibility (visibility);
12722 }
12723}
12724
2301ed1c
SN
12725static const char *
12726get_aarch64_symbol_other (unsigned int other)
12727{
12728 static char buf[32];
12729
12730 if (other & STO_AARCH64_VARIANT_PCS)
12731 {
12732 other &= ~STO_AARCH64_VARIANT_PCS;
12733 if (other == 0)
12734 return "VARIANT_PCS";
12735 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12736 return buf;
12737 }
12738 return NULL;
12739}
12740
5e2b0d47
NC
12741static const char *
12742get_mips_symbol_other (unsigned int other)
12743{
12744 switch (other)
12745 {
32ec8896
NC
12746 case STO_OPTIONAL: return "OPTIONAL";
12747 case STO_MIPS_PLT: return "MIPS PLT";
12748 case STO_MIPS_PIC: return "MIPS PIC";
12749 case STO_MICROMIPS: return "MICROMIPS";
12750 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12751 case STO_MIPS16: return "MIPS16";
12752 default: return NULL;
5e2b0d47
NC
12753 }
12754}
12755
28f997cf 12756static const char *
dda8d76d 12757get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12758{
dda8d76d 12759 if (is_ia64_vms (filedata))
28f997cf
TG
12760 {
12761 static char res[32];
12762
12763 res[0] = 0;
12764
12765 /* Function types is for images and .STB files only. */
dda8d76d 12766 switch (filedata->file_header.e_type)
28f997cf
TG
12767 {
12768 case ET_DYN:
12769 case ET_EXEC:
12770 switch (VMS_ST_FUNC_TYPE (other))
12771 {
12772 case VMS_SFT_CODE_ADDR:
12773 strcat (res, " CA");
12774 break;
12775 case VMS_SFT_SYMV_IDX:
12776 strcat (res, " VEC");
12777 break;
12778 case VMS_SFT_FD:
12779 strcat (res, " FD");
12780 break;
12781 case VMS_SFT_RESERVE:
12782 strcat (res, " RSV");
12783 break;
12784 default:
bee0ee85
NC
12785 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12786 VMS_ST_FUNC_TYPE (other));
12787 strcat (res, " <unknown>");
12788 break;
28f997cf
TG
12789 }
12790 break;
12791 default:
12792 break;
12793 }
12794 switch (VMS_ST_LINKAGE (other))
12795 {
12796 case VMS_STL_IGNORE:
12797 strcat (res, " IGN");
12798 break;
12799 case VMS_STL_RESERVE:
12800 strcat (res, " RSV");
12801 break;
12802 case VMS_STL_STD:
12803 strcat (res, " STD");
12804 break;
12805 case VMS_STL_LNK:
12806 strcat (res, " LNK");
12807 break;
12808 default:
bee0ee85
NC
12809 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12810 VMS_ST_LINKAGE (other));
12811 strcat (res, " <unknown>");
12812 break;
28f997cf
TG
12813 }
12814
12815 if (res[0] != 0)
12816 return res + 1;
12817 else
12818 return res;
12819 }
12820 return NULL;
12821}
12822
6911b7dc
AM
12823static const char *
12824get_ppc64_symbol_other (unsigned int other)
12825{
14732552
AM
12826 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12827 return NULL;
12828
12829 other >>= STO_PPC64_LOCAL_BIT;
12830 if (other <= 6)
6911b7dc 12831 {
89246a0e 12832 static char buf[64];
14732552
AM
12833 if (other >= 2)
12834 other = ppc64_decode_local_entry (other);
12835 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12836 return buf;
12837 }
12838 return NULL;
12839}
12840
8155b853
NC
12841static const char *
12842get_riscv_symbol_other (unsigned int other)
12843{
12844 static char buf[32];
12845 buf[0] = 0;
12846
12847 if (other & STO_RISCV_VARIANT_CC)
12848 {
12849 strcat (buf, _(" VARIANT_CC"));
12850 other &= ~STO_RISCV_VARIANT_CC;
12851 }
12852
12853 if (other != 0)
12854 snprintf (buf, sizeof buf, " %x", other);
12855
12856
12857 if (buf[0] != 0)
12858 return buf + 1;
12859 else
12860 return buf;
12861}
12862
5e2b0d47 12863static const char *
dda8d76d 12864get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12865{
12866 const char * result = NULL;
89246a0e 12867 static char buff [64];
5e2b0d47
NC
12868
12869 if (other == 0)
12870 return "";
12871
dda8d76d 12872 switch (filedata->file_header.e_machine)
5e2b0d47 12873 {
2057d69d
CZ
12874 case EM_ALPHA:
12875 result = get_alpha_symbol_other (other);
12876 break;
2301ed1c
SN
12877 case EM_AARCH64:
12878 result = get_aarch64_symbol_other (other);
12879 break;
5e2b0d47
NC
12880 case EM_MIPS:
12881 result = get_mips_symbol_other (other);
28f997cf
TG
12882 break;
12883 case EM_IA_64:
dda8d76d 12884 result = get_ia64_symbol_other (filedata, other);
28f997cf 12885 break;
6911b7dc
AM
12886 case EM_PPC64:
12887 result = get_ppc64_symbol_other (other);
12888 break;
8155b853
NC
12889 case EM_RISCV:
12890 result = get_riscv_symbol_other (other);
12891 break;
5e2b0d47 12892 default:
fd85a6a1 12893 result = NULL;
5e2b0d47
NC
12894 break;
12895 }
12896
12897 if (result)
12898 return result;
12899
12900 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12901 return buff;
12902}
12903
d1133906 12904static const char *
dda8d76d 12905get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12906{
b34976b6 12907 static char buff[32];
5cf1065c 12908
252b5132
RH
12909 switch (type)
12910 {
b34976b6
AM
12911 case SHN_UNDEF: return "UND";
12912 case SHN_ABS: return "ABS";
12913 case SHN_COMMON: return "COM";
252b5132 12914 default:
9ce701e2 12915 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12916 && filedata->file_header.e_machine == EM_IA_64
12917 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12918 return "ANSI_COM";
12919 else if ((filedata->file_header.e_machine == EM_X86_64
12920 || filedata->file_header.e_machine == EM_L1OM
12921 || filedata->file_header.e_machine == EM_K1OM)
12922 && type == SHN_X86_64_LCOMMON)
12923 return "LARGE_COM";
12924 else if ((type == SHN_MIPS_SCOMMON
12925 && filedata->file_header.e_machine == EM_MIPS)
12926 || (type == SHN_TIC6X_SCOMMON
12927 && filedata->file_header.e_machine == EM_TI_C6000))
12928 return "SCOM";
12929 else if (type == SHN_MIPS_SUNDEFINED
12930 && filedata->file_header.e_machine == EM_MIPS)
12931 return "SUND";
12932 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12933 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12934 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12935 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12936 else if (type >= SHN_LORESERVE)
12937 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12938 else if (filedata->file_header.e_shnum != 0
12939 && type >= filedata->file_header.e_shnum)
12940 sprintf (buff, _("bad section index[%3d]"), type);
12941 else
12942 sprintf (buff, "%3d", type);
12943 break;
fd85a6a1
NC
12944 }
12945
10ca4b04 12946 return buff;
6bd1a22c
L
12947}
12948
bb4d2ac2 12949static const char *
dda8d76d 12950get_symbol_version_string (Filedata * filedata,
015dc7e1 12951 bool is_dynsym,
1449284b
NC
12952 const char * strtab,
12953 unsigned long int strtab_size,
12954 unsigned int si,
12955 Elf_Internal_Sym * psym,
12956 enum versioned_symbol_info * sym_info,
12957 unsigned short * vna_other)
bb4d2ac2 12958{
ab273396
AM
12959 unsigned char data[2];
12960 unsigned short vers_data;
12961 unsigned long offset;
7a815dd5 12962 unsigned short max_vd_ndx;
bb4d2ac2 12963
ab273396 12964 if (!is_dynsym
978c4450 12965 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12966 return NULL;
bb4d2ac2 12967
978c4450
AM
12968 offset = offset_from_vma (filedata,
12969 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12970 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12971
dda8d76d 12972 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12973 sizeof (data), 1, _("version data")) == NULL)
12974 return NULL;
12975
12976 vers_data = byte_get (data, 2);
bb4d2ac2 12977
1f6f5dba 12978 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12979 return NULL;
bb4d2ac2 12980
0b8b7609 12981 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12982 max_vd_ndx = 0;
12983
ab273396
AM
12984 /* Usually we'd only see verdef for defined symbols, and verneed for
12985 undefined symbols. However, symbols defined by the linker in
12986 .dynbss for variables copied from a shared library in order to
12987 avoid text relocations are defined yet have verneed. We could
12988 use a heuristic to detect the special case, for example, check
12989 for verneed first on symbols defined in SHT_NOBITS sections, but
12990 it is simpler and more reliable to just look for both verdef and
12991 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12992
ab273396
AM
12993 if (psym->st_shndx != SHN_UNDEF
12994 && vers_data != 0x8001
978c4450 12995 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12996 {
12997 Elf_Internal_Verdef ivd;
12998 Elf_Internal_Verdaux ivda;
12999 Elf_External_Verdaux evda;
13000 unsigned long off;
bb4d2ac2 13001
dda8d76d 13002 off = offset_from_vma (filedata,
978c4450 13003 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13004 sizeof (Elf_External_Verdef));
13005
13006 do
bb4d2ac2 13007 {
ab273396
AM
13008 Elf_External_Verdef evd;
13009
dda8d76d 13010 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13011 _("version def")) == NULL)
13012 {
13013 ivd.vd_ndx = 0;
13014 ivd.vd_aux = 0;
13015 ivd.vd_next = 0;
1f6f5dba 13016 ivd.vd_flags = 0;
ab273396
AM
13017 }
13018 else
bb4d2ac2 13019 {
ab273396
AM
13020 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13021 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13022 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13023 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13024 }
bb4d2ac2 13025
7a815dd5
L
13026 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13027 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13028
ab273396
AM
13029 off += ivd.vd_next;
13030 }
13031 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13032
ab273396
AM
13033 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13034 {
9abca702 13035 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13036 return NULL;
13037
ab273396
AM
13038 off -= ivd.vd_next;
13039 off += ivd.vd_aux;
bb4d2ac2 13040
dda8d76d 13041 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13042 _("version def aux")) != NULL)
13043 {
13044 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13045
ab273396 13046 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13047 return (ivda.vda_name < strtab_size
13048 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13049 }
13050 }
13051 }
bb4d2ac2 13052
978c4450 13053 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13054 {
13055 Elf_External_Verneed evn;
13056 Elf_Internal_Verneed ivn;
13057 Elf_Internal_Vernaux ivna;
bb4d2ac2 13058
dda8d76d 13059 offset = offset_from_vma (filedata,
978c4450 13060 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13061 sizeof evn);
13062 do
13063 {
13064 unsigned long vna_off;
bb4d2ac2 13065
dda8d76d 13066 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13067 _("version need")) == NULL)
13068 {
13069 ivna.vna_next = 0;
13070 ivna.vna_other = 0;
13071 ivna.vna_name = 0;
13072 break;
13073 }
bb4d2ac2 13074
ab273396
AM
13075 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13076 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13077
ab273396 13078 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13079
ab273396
AM
13080 do
13081 {
13082 Elf_External_Vernaux evna;
bb4d2ac2 13083
dda8d76d 13084 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13085 _("version need aux (3)")) == NULL)
bb4d2ac2 13086 {
ab273396
AM
13087 ivna.vna_next = 0;
13088 ivna.vna_other = 0;
13089 ivna.vna_name = 0;
bb4d2ac2 13090 }
bb4d2ac2 13091 else
bb4d2ac2 13092 {
ab273396
AM
13093 ivna.vna_other = BYTE_GET (evna.vna_other);
13094 ivna.vna_next = BYTE_GET (evna.vna_next);
13095 ivna.vna_name = BYTE_GET (evna.vna_name);
13096 }
bb4d2ac2 13097
ab273396
AM
13098 vna_off += ivna.vna_next;
13099 }
13100 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13101
ab273396
AM
13102 if (ivna.vna_other == vers_data)
13103 break;
bb4d2ac2 13104
ab273396
AM
13105 offset += ivn.vn_next;
13106 }
13107 while (ivn.vn_next != 0);
bb4d2ac2 13108
ab273396
AM
13109 if (ivna.vna_other == vers_data)
13110 {
13111 *sym_info = symbol_undefined;
13112 *vna_other = ivna.vna_other;
13113 return (ivna.vna_name < strtab_size
13114 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13115 }
7a815dd5
L
13116 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13117 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13118 return _("<corrupt>");
bb4d2ac2 13119 }
ab273396 13120 return NULL;
bb4d2ac2
L
13121}
13122
047c3dbf
NL
13123/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13124
13125static unsigned int
13126print_dynamic_symbol_size (bfd_vma vma, int base)
13127{
13128 switch (base)
13129 {
13130 case 8:
13131 return print_vma (vma, OCTAL_5);
13132
13133 case 10:
13134 return print_vma (vma, UNSIGNED_5);
13135
13136 case 16:
13137 return print_vma (vma, PREFIX_HEX_5);
13138
13139 case 0:
13140 default:
13141 return print_vma (vma, DEC_5);
13142 }
13143}
13144
10ca4b04
L
13145static void
13146print_dynamic_symbol (Filedata *filedata, unsigned long si,
13147 Elf_Internal_Sym *symtab,
13148 Elf_Internal_Shdr *section,
13149 char *strtab, size_t strtab_size)
252b5132 13150{
10ca4b04
L
13151 const char *version_string;
13152 enum versioned_symbol_info sym_info;
13153 unsigned short vna_other;
23356397
NC
13154 bool is_valid;
13155 const char * sstr;
10ca4b04 13156 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13157
10ca4b04
L
13158 printf ("%6ld: ", si);
13159 print_vma (psym->st_value, LONG_HEX);
13160 putchar (' ');
047c3dbf 13161 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13162 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13163 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13164 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13165 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13166 else
252b5132 13167 {
10ca4b04 13168 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13169
10ca4b04
L
13170 printf (" %-7s", get_symbol_visibility (vis));
13171 /* Check to see if any other bits in the st_other field are set.
13172 Note - displaying this information disrupts the layout of the
13173 table being generated, but for the moment this case is very rare. */
13174 if (psym->st_other ^ vis)
13175 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13176 }
10ca4b04 13177 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13178
23356397
NC
13179 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13180 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13181 && filedata->section_headers != NULL
23356397
NC
13182 && psym->st_name == 0)
13183 {
84714f86
AM
13184 is_valid
13185 = section_name_valid (filedata,
13186 filedata->section_headers + psym->st_shndx);
23356397 13187 sstr = is_valid ?
84714f86
AM
13188 section_name_print (filedata,
13189 filedata->section_headers + psym->st_shndx)
23356397
NC
13190 : _("<corrupt>");
13191 }
13192 else
13193 {
84714f86 13194 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13195 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13196 }
10ca4b04
L
13197
13198 version_string
13199 = get_symbol_version_string (filedata,
13200 (section == NULL
13201 || section->sh_type == SHT_DYNSYM),
13202 strtab, strtab_size, si,
13203 psym, &sym_info, &vna_other);
b9e920ec 13204
0942c7ab
NC
13205 int len_avail = 21;
13206 if (! do_wide && version_string != NULL)
13207 {
ddb43bab 13208 char buffer[16];
0942c7ab 13209
ddb43bab 13210 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13211
13212 if (sym_info == symbol_undefined)
13213 len_avail -= sprintf (buffer," (%d)", vna_other);
13214 else if (sym_info != symbol_hidden)
13215 len_avail -= 1;
13216 }
13217
13218 print_symbol (len_avail, sstr);
b9e920ec 13219
10ca4b04
L
13220 if (version_string)
13221 {
13222 if (sym_info == symbol_undefined)
13223 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13224 else
10ca4b04
L
13225 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13226 version_string);
13227 }
6bd1a22c 13228
10ca4b04 13229 putchar ('\n');
6bd1a22c 13230
10ca4b04
L
13231 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13232 && section != NULL
13233 && si >= section->sh_info
13234 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13235 && filedata->file_header.e_machine != EM_MIPS
13236 /* Solaris binaries have been found to violate this requirement as
13237 well. Not sure if this is a bug or an ABI requirement. */
13238 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13239 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13240 si, printable_section_name (filedata, section), section->sh_info);
13241}
f16a9783 13242
0f03783c
NC
13243static const char *
13244get_lto_kind (unsigned int kind)
13245{
13246 switch (kind)
13247 {
13248 case 0: return "DEF";
13249 case 1: return "WEAKDEF";
13250 case 2: return "UNDEF";
13251 case 3: return "WEAKUNDEF";
13252 case 4: return "COMMON";
13253 default:
13254 break;
13255 }
13256
13257 static char buffer[30];
13258 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13259 sprintf (buffer, "<unknown: %u>", kind);
13260 return buffer;
13261}
13262
13263static const char *
13264get_lto_visibility (unsigned int visibility)
13265{
13266 switch (visibility)
13267 {
13268 case 0: return "DEFAULT";
13269 case 1: return "PROTECTED";
13270 case 2: return "INTERNAL";
13271 case 3: return "HIDDEN";
13272 default:
13273 break;
13274 }
13275
13276 static char buffer[30];
13277 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13278 sprintf (buffer, "<unknown: %u>", visibility);
13279 return buffer;
13280}
13281
13282static const char *
13283get_lto_sym_type (unsigned int sym_type)
13284{
13285 switch (sym_type)
13286 {
13287 case 0: return "UNKNOWN";
13288 case 1: return "FUNCTION";
13289 case 2: return "VARIABLE";
13290 default:
13291 break;
13292 }
13293
13294 static char buffer[30];
13295 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13296 sprintf (buffer, "<unknown: %u>", sym_type);
13297 return buffer;
13298}
13299
13300/* Display an LTO format symbol table.
13301 FIXME: The format of LTO symbol tables is not formalized.
13302 So this code could need changing in the future. */
13303
015dc7e1 13304static bool
0f03783c
NC
13305display_lto_symtab (Filedata * filedata,
13306 Elf_Internal_Shdr * section)
13307{
13308 if (section->sh_size == 0)
13309 {
ca0e11aa
NC
13310 if (filedata->is_separate)
13311 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13312 printable_section_name (filedata, section),
13313 filedata->file_name);
13314 else
13315 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13316 printable_section_name (filedata, section));
047c3dbf 13317
015dc7e1 13318 return true;
0f03783c
NC
13319 }
13320
13321 if (section->sh_size > filedata->file_size)
13322 {
13323 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13324 printable_section_name (filedata, section),
13325 (unsigned long) section->sh_size);
015dc7e1 13326 return false;
0f03783c
NC
13327 }
13328
13329 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13330 section->sh_size, 1, _("LTO symbols"));
13331 if (alloced_data == NULL)
015dc7e1 13332 return false;
0f03783c
NC
13333
13334 /* Look for extended data for the symbol table. */
13335 Elf_Internal_Shdr * ext;
13336 void * ext_data_orig = NULL;
13337 char * ext_data = NULL;
13338 char * ext_data_end = NULL;
13339 char * ext_name = NULL;
13340
13341 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13342 (section_name (filedata, section)
13343 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13344 && ext_name != NULL /* Paranoia. */
13345 && (ext = find_section (filedata, ext_name)) != NULL)
13346 {
13347 if (ext->sh_size < 3)
13348 error (_("LTO Symbol extension table '%s' is empty!\n"),
13349 printable_section_name (filedata, ext));
13350 else
13351 {
13352 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13353 ext->sh_size, 1,
13354 _("LTO ext symbol data"));
13355 if (ext_data != NULL)
13356 {
13357 ext_data_end = ext_data + ext->sh_size;
13358 if (* ext_data++ != 1)
13359 error (_("Unexpected version number in symbol extension table\n"));
13360 }
13361 }
13362 }
b9e920ec 13363
0f03783c
NC
13364 const unsigned char * data = (const unsigned char *) alloced_data;
13365 const unsigned char * end = data + section->sh_size;
13366
ca0e11aa
NC
13367 if (filedata->is_separate)
13368 printf (_("\nIn linked file '%s': "), filedata->file_name);
13369 else
13370 printf ("\n");
13371
0f03783c
NC
13372 if (ext_data_orig != NULL)
13373 {
13374 if (do_wide)
ca0e11aa 13375 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13376 printable_section_name (filedata, section),
13377 printable_section_name (filedata, ext));
13378 else
13379 {
ca0e11aa 13380 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13381 printable_section_name (filedata, section));
13382 printf (_(" and extension table '%s' contain:\n"),
13383 printable_section_name (filedata, ext));
13384 }
13385 }
13386 else
ca0e11aa 13387 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13388 printable_section_name (filedata, section));
b9e920ec 13389
0f03783c 13390 /* FIXME: Add a wide version. */
b9e920ec 13391 if (ext_data_orig != NULL)
0f03783c
NC
13392 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13393 else
13394 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13395
13396 /* FIXME: We do not handle style prefixes. */
13397
13398 while (data < end)
13399 {
13400 const unsigned char * sym_name = data;
13401 data += strnlen ((const char *) sym_name, end - data) + 1;
13402 if (data >= end)
13403 goto fail;
13404
13405 const unsigned char * comdat_key = data;
13406 data += strnlen ((const char *) comdat_key, end - data) + 1;
13407 if (data >= end)
13408 goto fail;
13409
13410 if (data + 2 + 8 + 4 > end)
13411 goto fail;
13412
13413 unsigned int kind = *data++;
13414 unsigned int visibility = *data++;
13415
13416 elf_vma size = byte_get (data, 8);
13417 data += 8;
13418
13419 elf_vma slot = byte_get (data, 4);
13420 data += 4;
13421
13422 if (ext_data != NULL)
13423 {
13424 if (ext_data < (ext_data_end - 1))
13425 {
13426 unsigned int sym_type = * ext_data ++;
13427 unsigned int sec_kind = * ext_data ++;
13428
13429 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13430 * comdat_key == 0 ? "-" : (char *) comdat_key,
13431 get_lto_kind (kind),
13432 get_lto_visibility (visibility),
13433 (long) size,
13434 (long) slot,
13435 get_lto_sym_type (sym_type),
13436 (long) sec_kind);
13437 print_symbol (6, (const char *) sym_name);
13438 }
13439 else
13440 {
13441 error (_("Ran out of LTO symbol extension data\n"));
13442 ext_data = NULL;
13443 /* FIXME: return FAIL result ? */
13444 }
13445 }
13446 else
13447 {
13448 printf (" %10s %10s %11s %08lx %08lx _",
13449 * comdat_key == 0 ? "-" : (char *) comdat_key,
13450 get_lto_kind (kind),
13451 get_lto_visibility (visibility),
13452 (long) size,
13453 (long) slot);
13454 print_symbol (21, (const char *) sym_name);
13455 }
13456 putchar ('\n');
13457 }
13458
13459 if (ext_data != NULL && ext_data < ext_data_end)
13460 {
13461 error (_("Data remains in the LTO symbol extension table\n"));
13462 goto fail;
13463 }
13464
13465 free (alloced_data);
13466 free (ext_data_orig);
13467 free (ext_name);
015dc7e1 13468 return true;
b9e920ec 13469
0f03783c
NC
13470 fail:
13471 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13472 free (alloced_data);
13473 free (ext_data_orig);
13474 free (ext_name);
015dc7e1 13475 return false;
0f03783c
NC
13476}
13477
13478/* Display LTO symbol tables. */
13479
015dc7e1 13480static bool
0f03783c
NC
13481process_lto_symbol_tables (Filedata * filedata)
13482{
13483 Elf_Internal_Shdr * section;
13484 unsigned int i;
015dc7e1 13485 bool res = true;
0f03783c
NC
13486
13487 if (!do_lto_syms)
015dc7e1 13488 return true;
0f03783c
NC
13489
13490 if (filedata->section_headers == NULL)
015dc7e1 13491 return true;
0f03783c
NC
13492
13493 for (i = 0, section = filedata->section_headers;
13494 i < filedata->file_header.e_shnum;
13495 i++, section++)
84714f86
AM
13496 if (section_name_valid (filedata, section)
13497 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13498 res &= display_lto_symtab (filedata, section);
13499
b9e920ec 13500 return res;
0f03783c
NC
13501}
13502
10ca4b04 13503/* Dump the symbol table. */
0f03783c 13504
015dc7e1 13505static bool
10ca4b04
L
13506process_symbol_table (Filedata * filedata)
13507{
13508 Elf_Internal_Shdr * section;
f16a9783 13509
10ca4b04 13510 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13511 return true;
6bd1a22c 13512
978c4450 13513 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13514 && do_syms
13515 && do_using_dynamic
978c4450
AM
13516 && filedata->dynamic_strings != NULL
13517 && filedata->dynamic_symbols != NULL)
6bd1a22c 13518 {
10ca4b04 13519 unsigned long si;
6bd1a22c 13520
ca0e11aa
NC
13521 if (filedata->is_separate)
13522 {
13523 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13524 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13525 filedata->num_dynamic_syms),
13526 filedata->file_name,
13527 filedata->num_dynamic_syms);
13528 }
13529 else
13530 {
13531 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13532 "\nSymbol table for image contains %lu entries:\n",
13533 filedata->num_dynamic_syms),
13534 filedata->num_dynamic_syms);
13535 }
10ca4b04
L
13536 if (is_32bit_elf)
13537 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13538 else
13539 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13540
978c4450
AM
13541 for (si = 0; si < filedata->num_dynamic_syms; si++)
13542 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13543 filedata->dynamic_strings,
13544 filedata->dynamic_strings_length);
252b5132 13545 }
8b73c356 13546 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13547 && filedata->section_headers != NULL)
252b5132 13548 {
b34976b6 13549 unsigned int i;
252b5132 13550
dda8d76d
NC
13551 for (i = 0, section = filedata->section_headers;
13552 i < filedata->file_header.e_shnum;
252b5132
RH
13553 i++, section++)
13554 {
2cf0635d 13555 char * strtab = NULL;
c256ffe7 13556 unsigned long int strtab_size = 0;
2cf0635d 13557 Elf_Internal_Sym * symtab;
ef3df110 13558 unsigned long si, num_syms;
252b5132 13559
2c610e4b
L
13560 if ((section->sh_type != SHT_SYMTAB
13561 && section->sh_type != SHT_DYNSYM)
13562 || (!do_syms
13563 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13564 continue;
13565
dd24e3da
NC
13566 if (section->sh_entsize == 0)
13567 {
13568 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13569 printable_section_name (filedata, section));
dd24e3da
NC
13570 continue;
13571 }
13572
d3a49aa8 13573 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13574
13575 if (filedata->is_separate)
13576 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13577 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13578 num_syms),
13579 filedata->file_name,
13580 printable_section_name (filedata, section),
13581 num_syms);
13582 else
13583 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13584 "\nSymbol table '%s' contains %lu entries:\n",
13585 num_syms),
13586 printable_section_name (filedata, section),
13587 num_syms);
dd24e3da 13588
f7a99963 13589 if (is_32bit_elf)
ca47b30c 13590 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13591 else
ca47b30c 13592 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13593
4de91c10 13594 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13595 if (symtab == NULL)
13596 continue;
13597
dda8d76d 13598 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13599 {
dda8d76d
NC
13600 strtab = filedata->string_table;
13601 strtab_size = filedata->string_table_length;
c256ffe7 13602 }
dda8d76d 13603 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13604 {
2cf0635d 13605 Elf_Internal_Shdr * string_sec;
252b5132 13606
dda8d76d 13607 string_sec = filedata->section_headers + section->sh_link;
252b5132 13608
dda8d76d 13609 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13610 1, string_sec->sh_size,
13611 _("string table"));
c256ffe7 13612 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13613 }
13614
10ca4b04
L
13615 for (si = 0; si < num_syms; si++)
13616 print_dynamic_symbol (filedata, si, symtab, section,
13617 strtab, strtab_size);
252b5132
RH
13618
13619 free (symtab);
dda8d76d 13620 if (strtab != filedata->string_table)
252b5132
RH
13621 free (strtab);
13622 }
13623 }
13624 else if (do_syms)
13625 printf
13626 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13627
978c4450 13628 if (do_histogram && filedata->buckets != NULL)
252b5132 13629 {
2cf0635d
NC
13630 unsigned long * lengths;
13631 unsigned long * counts;
66543521
AM
13632 unsigned long hn;
13633 bfd_vma si;
13634 unsigned long maxlength = 0;
13635 unsigned long nzero_counts = 0;
13636 unsigned long nsyms = 0;
6bd6a03d 13637 char *visited;
252b5132 13638
d3a49aa8
AM
13639 printf (ngettext ("\nHistogram for bucket list length "
13640 "(total of %lu bucket):\n",
13641 "\nHistogram for bucket list length "
13642 "(total of %lu buckets):\n",
978c4450
AM
13643 (unsigned long) filedata->nbuckets),
13644 (unsigned long) filedata->nbuckets);
252b5132 13645
978c4450
AM
13646 lengths = (unsigned long *) calloc (filedata->nbuckets,
13647 sizeof (*lengths));
252b5132
RH
13648 if (lengths == NULL)
13649 {
8b73c356 13650 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13651 goto err_out;
252b5132 13652 }
978c4450
AM
13653 visited = xcmalloc (filedata->nchains, 1);
13654 memset (visited, 0, filedata->nchains);
8b73c356
NC
13655
13656 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13657 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13658 {
978c4450 13659 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13660 {
b34976b6 13661 ++nsyms;
252b5132 13662 if (maxlength < ++lengths[hn])
b34976b6 13663 ++maxlength;
978c4450 13664 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13665 {
13666 error (_("histogram chain is corrupt\n"));
13667 break;
13668 }
13669 visited[si] = 1;
252b5132
RH
13670 }
13671 }
6bd6a03d 13672 free (visited);
252b5132 13673
3f5e193b 13674 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13675 if (counts == NULL)
13676 {
b2e951ec 13677 free (lengths);
8b73c356 13678 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13679 goto err_out;
252b5132
RH
13680 }
13681
978c4450 13682 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13683 ++counts[lengths[hn]];
252b5132 13684
978c4450 13685 if (filedata->nbuckets > 0)
252b5132 13686 {
66543521
AM
13687 unsigned long i;
13688 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13689 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13690 for (i = 1; i <= maxlength; ++i)
103f02d3 13691 {
66543521
AM
13692 nzero_counts += counts[i] * i;
13693 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13694 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13695 (nzero_counts * 100.0) / nsyms);
13696 }
252b5132
RH
13697 }
13698
13699 free (counts);
13700 free (lengths);
13701 }
13702
978c4450
AM
13703 free (filedata->buckets);
13704 filedata->buckets = NULL;
13705 filedata->nbuckets = 0;
13706 free (filedata->chains);
13707 filedata->chains = NULL;
252b5132 13708
978c4450 13709 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13710 {
2cf0635d
NC
13711 unsigned long * lengths;
13712 unsigned long * counts;
fdc90cb4
JJ
13713 unsigned long hn;
13714 unsigned long maxlength = 0;
13715 unsigned long nzero_counts = 0;
13716 unsigned long nsyms = 0;
fdc90cb4 13717
f16a9783 13718 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13719 "(total of %lu bucket):\n",
f16a9783 13720 "\nHistogram for `%s' bucket list length "
d3a49aa8 13721 "(total of %lu buckets):\n",
978c4450
AM
13722 (unsigned long) filedata->ngnubuckets),
13723 GNU_HASH_SECTION_NAME (filedata),
13724 (unsigned long) filedata->ngnubuckets);
8b73c356 13725
978c4450
AM
13726 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13727 sizeof (*lengths));
fdc90cb4
JJ
13728 if (lengths == NULL)
13729 {
8b73c356 13730 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13731 goto err_out;
fdc90cb4
JJ
13732 }
13733
fdc90cb4
JJ
13734 printf (_(" Length Number %% of total Coverage\n"));
13735
978c4450
AM
13736 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13737 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13738 {
13739 bfd_vma off, length = 1;
13740
978c4450 13741 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13742 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13743 off < filedata->ngnuchains
13744 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13745 ++off)
fdc90cb4
JJ
13746 ++length;
13747 lengths[hn] = length;
13748 if (length > maxlength)
13749 maxlength = length;
13750 nsyms += length;
13751 }
13752
3f5e193b 13753 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13754 if (counts == NULL)
13755 {
b2e951ec 13756 free (lengths);
8b73c356 13757 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13758 goto err_out;
fdc90cb4
JJ
13759 }
13760
978c4450 13761 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13762 ++counts[lengths[hn]];
13763
978c4450 13764 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13765 {
13766 unsigned long j;
13767 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13768 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13769 for (j = 1; j <= maxlength; ++j)
13770 {
13771 nzero_counts += counts[j] * j;
13772 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13773 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13774 (nzero_counts * 100.0) / nsyms);
13775 }
13776 }
13777
13778 free (counts);
13779 free (lengths);
fdc90cb4 13780 }
978c4450
AM
13781 free (filedata->gnubuckets);
13782 filedata->gnubuckets = NULL;
13783 filedata->ngnubuckets = 0;
13784 free (filedata->gnuchains);
13785 filedata->gnuchains = NULL;
13786 filedata->ngnuchains = 0;
13787 free (filedata->mipsxlat);
13788 filedata->mipsxlat = NULL;
015dc7e1 13789 return true;
fd486f32
AM
13790
13791 err_out:
978c4450
AM
13792 free (filedata->gnubuckets);
13793 filedata->gnubuckets = NULL;
13794 filedata->ngnubuckets = 0;
13795 free (filedata->gnuchains);
13796 filedata->gnuchains = NULL;
13797 filedata->ngnuchains = 0;
13798 free (filedata->mipsxlat);
13799 filedata->mipsxlat = NULL;
13800 free (filedata->buckets);
13801 filedata->buckets = NULL;
13802 filedata->nbuckets = 0;
13803 free (filedata->chains);
13804 filedata->chains = NULL;
015dc7e1 13805 return false;
252b5132
RH
13806}
13807
015dc7e1 13808static bool
ca0e11aa 13809process_syminfo (Filedata * filedata)
252b5132 13810{
b4c96d0d 13811 unsigned int i;
252b5132 13812
978c4450 13813 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13814 || !do_dynamic)
13815 /* No syminfo, this is ok. */
015dc7e1 13816 return true;
252b5132
RH
13817
13818 /* There better should be a dynamic symbol section. */
978c4450 13819 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13820 return false;
252b5132 13821
ca0e11aa
NC
13822 if (filedata->is_separate)
13823 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13824 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13825 filedata->dynamic_syminfo_nent),
13826 filedata->file_name,
13827 filedata->dynamic_syminfo_offset,
13828 filedata->dynamic_syminfo_nent);
13829 else
d3a49aa8
AM
13830 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13831 "contains %d entry:\n",
13832 "\nDynamic info segment at offset 0x%lx "
13833 "contains %d entries:\n",
978c4450 13834 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13835 filedata->dynamic_syminfo_offset,
13836 filedata->dynamic_syminfo_nent);
252b5132
RH
13837
13838 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13839 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13840 {
978c4450 13841 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13842
31104126 13843 printf ("%4d: ", i);
978c4450 13844 if (i >= filedata->num_dynamic_syms)
4082ef84 13845 printf (_("<corrupt index>"));
84714f86
AM
13846 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13847 print_symbol (30, get_dynamic_name (filedata,
978c4450 13848 filedata->dynamic_symbols[i].st_name));
d79b3d50 13849 else
978c4450 13850 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13851 putchar (' ');
252b5132 13852
978c4450 13853 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13854 {
13855 case SYMINFO_BT_SELF:
13856 fputs ("SELF ", stdout);
13857 break;
13858 case SYMINFO_BT_PARENT:
13859 fputs ("PARENT ", stdout);
13860 break;
13861 default:
978c4450
AM
13862 if (filedata->dynamic_syminfo[i].si_boundto > 0
13863 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13864 && valid_dynamic_name (filedata,
978c4450 13865 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13866 {
84714f86 13867 print_symbol (10, get_dynamic_name (filedata,
978c4450 13868 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13869 putchar (' ' );
13870 }
252b5132 13871 else
978c4450 13872 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13873 break;
13874 }
13875
13876 if (flags & SYMINFO_FLG_DIRECT)
13877 printf (" DIRECT");
13878 if (flags & SYMINFO_FLG_PASSTHRU)
13879 printf (" PASSTHRU");
13880 if (flags & SYMINFO_FLG_COPY)
13881 printf (" COPY");
13882 if (flags & SYMINFO_FLG_LAZYLOAD)
13883 printf (" LAZYLOAD");
13884
13885 puts ("");
13886 }
13887
015dc7e1 13888 return true;
252b5132
RH
13889}
13890
75802ccb
CE
13891/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13892 is contained by the region START .. END. The types of ADDR, START
13893 and END should all be the same. Note both ADDR + NELEM and END
13894 point to just beyond the end of the regions that are being tested. */
13895#define IN_RANGE(START,END,ADDR,NELEM) \
13896 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13897
cf13d699
NC
13898/* Check to see if the given reloc needs to be handled in a target specific
13899 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13900 FALSE.
13901
13902 If called with reloc == NULL, then this is a signal that reloc processing
13903 for the current section has finished, and any saved state should be
13904 discarded. */
09c11c86 13905
015dc7e1 13906static bool
dda8d76d
NC
13907target_specific_reloc_handling (Filedata * filedata,
13908 Elf_Internal_Rela * reloc,
13909 unsigned char * start,
13910 unsigned char * end,
13911 Elf_Internal_Sym * symtab,
13912 unsigned long num_syms)
252b5132 13913{
f84ce13b
NC
13914 unsigned int reloc_type = 0;
13915 unsigned long sym_index = 0;
13916
13917 if (reloc)
13918 {
dda8d76d 13919 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13920 sym_index = get_reloc_symindex (reloc->r_info);
13921 }
252b5132 13922
dda8d76d 13923 switch (filedata->file_header.e_machine)
252b5132 13924 {
13761a11
NC
13925 case EM_MSP430:
13926 case EM_MSP430_OLD:
13927 {
13928 static Elf_Internal_Sym * saved_sym = NULL;
13929
f84ce13b
NC
13930 if (reloc == NULL)
13931 {
13932 saved_sym = NULL;
015dc7e1 13933 return true;
f84ce13b
NC
13934 }
13935
13761a11
NC
13936 switch (reloc_type)
13937 {
13938 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13939 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13940 if (uses_msp430x_relocs (filedata))
13761a11 13941 break;
1a0670f3 13942 /* Fall through. */
13761a11 13943 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13944 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13945 /* PR 21139. */
13946 if (sym_index >= num_syms)
13947 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13948 sym_index);
13949 else
13950 saved_sym = symtab + sym_index;
015dc7e1 13951 return true;
13761a11
NC
13952
13953 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13954 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13955 goto handle_sym_diff;
0b4362b0 13956
13761a11
NC
13957 case 5: /* R_MSP430_16_BYTE */
13958 case 9: /* R_MSP430_8 */
7d81bc93 13959 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13960 if (uses_msp430x_relocs (filedata))
13761a11
NC
13961 break;
13962 goto handle_sym_diff;
13963
13964 case 2: /* R_MSP430_ABS16 */
13965 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13966 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13967 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13968 break;
13969 goto handle_sym_diff;
0b4362b0 13970
13761a11
NC
13971 handle_sym_diff:
13972 if (saved_sym != NULL)
13973 {
13974 bfd_vma value;
5a805384 13975 unsigned int reloc_size = 0;
7d81bc93
JL
13976 int leb_ret = 0;
13977 switch (reloc_type)
13978 {
13979 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13980 reloc_size = 4;
13981 break;
13982 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13983 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13984 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13985 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13986 &reloc_size, &leb_ret);
7d81bc93
JL
13987 break;
13988 default:
13989 reloc_size = 2;
13990 break;
13991 }
13761a11 13992
5a805384 13993 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13994 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13995 "ULEB128 value\n"),
13996 (long) reloc->r_offset);
13997 else if (sym_index >= num_syms)
f84ce13b
NC
13998 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13999 sym_index);
03f7786e 14000 else
f84ce13b
NC
14001 {
14002 value = reloc->r_addend + (symtab[sym_index].st_value
14003 - saved_sym->st_value);
14004
b32e566b 14005 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14006 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14007 else
14008 /* PR 21137 */
14009 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14010 (long) reloc->r_offset);
f84ce13b 14011 }
13761a11
NC
14012
14013 saved_sym = NULL;
015dc7e1 14014 return true;
13761a11
NC
14015 }
14016 break;
14017
14018 default:
14019 if (saved_sym != NULL)
071436c6 14020 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14021 break;
14022 }
14023 break;
14024 }
14025
cf13d699
NC
14026 case EM_MN10300:
14027 case EM_CYGNUS_MN10300:
14028 {
14029 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14030
f84ce13b
NC
14031 if (reloc == NULL)
14032 {
14033 saved_sym = NULL;
015dc7e1 14034 return true;
f84ce13b
NC
14035 }
14036
cf13d699
NC
14037 switch (reloc_type)
14038 {
14039 case 34: /* R_MN10300_ALIGN */
015dc7e1 14040 return true;
cf13d699 14041 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14042 if (sym_index >= num_syms)
14043 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14044 sym_index);
14045 else
14046 saved_sym = symtab + sym_index;
015dc7e1 14047 return true;
f84ce13b 14048
cf13d699
NC
14049 case 1: /* R_MN10300_32 */
14050 case 2: /* R_MN10300_16 */
14051 if (saved_sym != NULL)
14052 {
03f7786e 14053 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 14054 bfd_vma value;
252b5132 14055
f84ce13b
NC
14056 if (sym_index >= num_syms)
14057 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14058 sym_index);
03f7786e 14059 else
f84ce13b
NC
14060 {
14061 value = reloc->r_addend + (symtab[sym_index].st_value
14062 - saved_sym->st_value);
14063
b32e566b 14064 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14065 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14066 else
14067 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14068 (long) reloc->r_offset);
f84ce13b 14069 }
252b5132 14070
cf13d699 14071 saved_sym = NULL;
015dc7e1 14072 return true;
cf13d699
NC
14073 }
14074 break;
14075 default:
14076 if (saved_sym != NULL)
071436c6 14077 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14078 break;
14079 }
14080 break;
14081 }
6ff71e76
NC
14082
14083 case EM_RL78:
14084 {
14085 static bfd_vma saved_sym1 = 0;
14086 static bfd_vma saved_sym2 = 0;
14087 static bfd_vma value;
14088
f84ce13b
NC
14089 if (reloc == NULL)
14090 {
14091 saved_sym1 = saved_sym2 = 0;
015dc7e1 14092 return true;
f84ce13b
NC
14093 }
14094
6ff71e76
NC
14095 switch (reloc_type)
14096 {
14097 case 0x80: /* R_RL78_SYM. */
14098 saved_sym1 = saved_sym2;
f84ce13b
NC
14099 if (sym_index >= num_syms)
14100 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14101 sym_index);
14102 else
14103 {
14104 saved_sym2 = symtab[sym_index].st_value;
14105 saved_sym2 += reloc->r_addend;
14106 }
015dc7e1 14107 return true;
6ff71e76
NC
14108
14109 case 0x83: /* R_RL78_OPsub. */
14110 value = saved_sym1 - saved_sym2;
14111 saved_sym2 = saved_sym1 = 0;
015dc7e1 14112 return true;
6ff71e76
NC
14113 break;
14114
14115 case 0x41: /* R_RL78_ABS32. */
b32e566b 14116 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14117 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14118 else
14119 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14120 (long) reloc->r_offset);
6ff71e76 14121 value = 0;
015dc7e1 14122 return true;
6ff71e76
NC
14123
14124 case 0x43: /* R_RL78_ABS16. */
b32e566b 14125 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14126 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14127 else
14128 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14129 (long) reloc->r_offset);
6ff71e76 14130 value = 0;
015dc7e1 14131 return true;
6ff71e76
NC
14132
14133 default:
14134 break;
14135 }
14136 break;
14137 }
252b5132
RH
14138 }
14139
015dc7e1 14140 return false;
252b5132
RH
14141}
14142
aca88567
NC
14143/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14144 DWARF debug sections. This is a target specific test. Note - we do not
14145 go through the whole including-target-headers-multiple-times route, (as
14146 we have already done with <elf/h8.h>) because this would become very
14147 messy and even then this function would have to contain target specific
14148 information (the names of the relocs instead of their numeric values).
14149 FIXME: This is not the correct way to solve this problem. The proper way
14150 is to have target specific reloc sizing and typing functions created by
14151 the reloc-macros.h header, in the same way that it already creates the
14152 reloc naming functions. */
14153
015dc7e1 14154static bool
dda8d76d 14155is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14156{
d347c9df 14157 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14158 switch (filedata->file_header.e_machine)
aca88567 14159 {
41e92641 14160 case EM_386:
22abe556 14161 case EM_IAMCU:
41e92641 14162 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14163 case EM_68K:
14164 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14165 case EM_860:
14166 return reloc_type == 1; /* R_860_32. */
14167 case EM_960:
14168 return reloc_type == 2; /* R_960_32. */
a06ea964 14169 case EM_AARCH64:
9282b95a
JW
14170 return (reloc_type == 258
14171 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14172 case EM_BPF:
14173 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14174 case EM_ADAPTEVA_EPIPHANY:
14175 return reloc_type == 3;
aca88567 14176 case EM_ALPHA:
137b6b5f 14177 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14178 case EM_ARC:
14179 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14180 case EM_ARC_COMPACT:
14181 case EM_ARC_COMPACT2:
14182 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14183 case EM_ARM:
14184 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14185 case EM_AVR_OLD:
aca88567
NC
14186 case EM_AVR:
14187 return reloc_type == 1;
14188 case EM_BLACKFIN:
14189 return reloc_type == 0x12; /* R_byte4_data. */
14190 case EM_CRIS:
14191 return reloc_type == 3; /* R_CRIS_32. */
14192 case EM_CR16:
14193 return reloc_type == 3; /* R_CR16_NUM32. */
14194 case EM_CRX:
14195 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14196 case EM_CSKY:
14197 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14198 case EM_CYGNUS_FRV:
14199 return reloc_type == 1;
41e92641
NC
14200 case EM_CYGNUS_D10V:
14201 case EM_D10V:
14202 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14203 case EM_CYGNUS_D30V:
14204 case EM_D30V:
14205 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14206 case EM_DLX:
14207 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14208 case EM_CYGNUS_FR30:
14209 case EM_FR30:
14210 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14211 case EM_FT32:
14212 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14213 case EM_H8S:
14214 case EM_H8_300:
14215 case EM_H8_300H:
14216 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14217 case EM_IA_64:
262cdac7
AM
14218 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14219 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14220 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14221 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14222 case EM_IP2K_OLD:
14223 case EM_IP2K:
14224 return reloc_type == 2; /* R_IP2K_32. */
14225 case EM_IQ2000:
14226 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14227 case EM_LATTICEMICO32:
14228 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14229 case EM_LOONGARCH:
14230 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14231 case EM_M32C_OLD:
aca88567
NC
14232 case EM_M32C:
14233 return reloc_type == 3; /* R_M32C_32. */
14234 case EM_M32R:
14235 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14236 case EM_68HC11:
14237 case EM_68HC12:
14238 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14239 case EM_S12Z:
2849d19f
JD
14240 return reloc_type == 7 || /* R_S12Z_EXT32 */
14241 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14242 case EM_MCORE:
14243 return reloc_type == 1; /* R_MCORE_ADDR32. */
14244 case EM_CYGNUS_MEP:
14245 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14246 case EM_METAG:
14247 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14248 case EM_MICROBLAZE:
14249 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14250 case EM_MIPS:
14251 return reloc_type == 2; /* R_MIPS_32. */
14252 case EM_MMIX:
14253 return reloc_type == 4; /* R_MMIX_32. */
14254 case EM_CYGNUS_MN10200:
14255 case EM_MN10200:
14256 return reloc_type == 1; /* R_MN10200_32. */
14257 case EM_CYGNUS_MN10300:
14258 case EM_MN10300:
14259 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14260 case EM_MOXIE:
14261 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14262 case EM_MSP430_OLD:
14263 case EM_MSP430:
13761a11 14264 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14265 case EM_MT:
14266 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14267 case EM_NDS32:
14268 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14269 case EM_ALTERA_NIOS2:
36591ba1 14270 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14271 case EM_NIOS32:
14272 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14273 case EM_OR1K:
14274 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14275 case EM_PARISC:
9abca702 14276 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14277 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14278 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14279 case EM_PJ:
14280 case EM_PJ_OLD:
14281 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14282 case EM_PPC64:
14283 return reloc_type == 1; /* R_PPC64_ADDR32. */
14284 case EM_PPC:
14285 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14286 case EM_TI_PRU:
14287 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14288 case EM_RISCV:
14289 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14290 case EM_RL78:
14291 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14292 case EM_RX:
14293 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14294 case EM_S370:
14295 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14296 case EM_S390_OLD:
14297 case EM_S390:
14298 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14299 case EM_SCORE:
14300 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14301 case EM_SH:
14302 return reloc_type == 1; /* R_SH_DIR32. */
14303 case EM_SPARC32PLUS:
14304 case EM_SPARCV9:
14305 case EM_SPARC:
14306 return reloc_type == 3 /* R_SPARC_32. */
14307 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14308 case EM_SPU:
14309 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14310 case EM_TI_C6000:
14311 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14312 case EM_TILEGX:
14313 return reloc_type == 2; /* R_TILEGX_32. */
14314 case EM_TILEPRO:
14315 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14316 case EM_CYGNUS_V850:
14317 case EM_V850:
14318 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14319 case EM_V800:
14320 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14321 case EM_VAX:
14322 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14323 case EM_VISIUM:
14324 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14325 case EM_WEBASSEMBLY:
14326 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14327 case EM_X86_64:
8a9036a4 14328 case EM_L1OM:
7a9068fe 14329 case EM_K1OM:
aca88567 14330 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14331 case EM_XC16X:
14332 case EM_C166:
14333 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14334 case EM_XGATE:
14335 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14336 case EM_XSTORMY16:
14337 return reloc_type == 1; /* R_XSTROMY16_32. */
14338 case EM_XTENSA_OLD:
14339 case EM_XTENSA:
14340 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14341 case EM_Z80:
14342 return reloc_type == 6; /* R_Z80_32. */
aca88567 14343 default:
bee0ee85
NC
14344 {
14345 static unsigned int prev_warn = 0;
14346
14347 /* Avoid repeating the same warning multiple times. */
dda8d76d 14348 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14349 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14350 filedata->file_header.e_machine);
14351 prev_warn = filedata->file_header.e_machine;
015dc7e1 14352 return false;
bee0ee85 14353 }
aca88567
NC
14354 }
14355}
14356
14357/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14358 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14359
015dc7e1 14360static bool
dda8d76d 14361is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14362{
dda8d76d 14363 switch (filedata->file_header.e_machine)
d347c9df 14364 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14365 {
41e92641 14366 case EM_386:
22abe556 14367 case EM_IAMCU:
3e0873ac 14368 return reloc_type == 2; /* R_386_PC32. */
aca88567 14369 case EM_68K:
3e0873ac 14370 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14371 case EM_AARCH64:
14372 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14373 case EM_ADAPTEVA_EPIPHANY:
14374 return reloc_type == 6;
aca88567
NC
14375 case EM_ALPHA:
14376 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14377 case EM_ARC_COMPACT:
14378 case EM_ARC_COMPACT2:
14379 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14380 case EM_ARM:
3e0873ac 14381 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14382 case EM_AVR_OLD:
14383 case EM_AVR:
14384 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14385 case EM_MICROBLAZE:
14386 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14387 case EM_OR1K:
14388 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14389 case EM_PARISC:
85acf597 14390 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14391 case EM_PPC:
14392 return reloc_type == 26; /* R_PPC_REL32. */
14393 case EM_PPC64:
3e0873ac 14394 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14395 case EM_RISCV:
14396 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14397 case EM_S390_OLD:
14398 case EM_S390:
3e0873ac 14399 return reloc_type == 5; /* R_390_PC32. */
aca88567 14400 case EM_SH:
3e0873ac 14401 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14402 case EM_SPARC32PLUS:
14403 case EM_SPARCV9:
14404 case EM_SPARC:
3e0873ac 14405 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14406 case EM_SPU:
14407 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14408 case EM_TILEGX:
14409 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14410 case EM_TILEPRO:
14411 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14412 case EM_VISIUM:
14413 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14414 case EM_X86_64:
8a9036a4 14415 case EM_L1OM:
7a9068fe 14416 case EM_K1OM:
3e0873ac 14417 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14418 case EM_VAX:
14419 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14420 case EM_XTENSA_OLD:
14421 case EM_XTENSA:
14422 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14423 default:
14424 /* Do not abort or issue an error message here. Not all targets use
14425 pc-relative 32-bit relocs in their DWARF debug information and we
14426 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14427 more helpful warning message will be generated by apply_relocations
14428 anyway, so just return. */
015dc7e1 14429 return false;
aca88567
NC
14430 }
14431}
14432
14433/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14434 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14435
015dc7e1 14436static bool
dda8d76d 14437is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14438{
dda8d76d 14439 switch (filedata->file_header.e_machine)
aca88567 14440 {
a06ea964
NC
14441 case EM_AARCH64:
14442 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14443 case EM_ALPHA:
14444 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14445 case EM_IA_64:
262cdac7
AM
14446 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14447 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14448 case EM_LOONGARCH:
14449 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14450 case EM_PARISC:
14451 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14452 case EM_PPC64:
14453 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14454 case EM_RISCV:
14455 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14456 case EM_SPARC32PLUS:
14457 case EM_SPARCV9:
14458 case EM_SPARC:
714da62f
NC
14459 return reloc_type == 32 /* R_SPARC_64. */
14460 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14461 case EM_X86_64:
8a9036a4 14462 case EM_L1OM:
7a9068fe 14463 case EM_K1OM:
aca88567 14464 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14465 case EM_S390_OLD:
14466 case EM_S390:
aa137e4d
NC
14467 return reloc_type == 22; /* R_S390_64. */
14468 case EM_TILEGX:
14469 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14470 case EM_MIPS:
aa137e4d 14471 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14472 default:
015dc7e1 14473 return false;
aca88567
NC
14474 }
14475}
14476
85acf597
RH
14477/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14478 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14479
015dc7e1 14480static bool
dda8d76d 14481is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14482{
dda8d76d 14483 switch (filedata->file_header.e_machine)
85acf597 14484 {
a06ea964
NC
14485 case EM_AARCH64:
14486 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14487 case EM_ALPHA:
aa137e4d 14488 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14489 case EM_IA_64:
262cdac7
AM
14490 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14491 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14492 case EM_PARISC:
aa137e4d 14493 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14494 case EM_PPC64:
aa137e4d 14495 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14496 case EM_SPARC32PLUS:
14497 case EM_SPARCV9:
14498 case EM_SPARC:
aa137e4d 14499 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14500 case EM_X86_64:
8a9036a4 14501 case EM_L1OM:
7a9068fe 14502 case EM_K1OM:
aa137e4d 14503 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14504 case EM_S390_OLD:
14505 case EM_S390:
aa137e4d
NC
14506 return reloc_type == 23; /* R_S390_PC64. */
14507 case EM_TILEGX:
14508 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14509 default:
015dc7e1 14510 return false;
85acf597
RH
14511 }
14512}
14513
4dc3c23d
AM
14514/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14515 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14516
015dc7e1 14517static bool
dda8d76d 14518is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14519{
dda8d76d 14520 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14521 {
14522 case EM_CYGNUS_MN10200:
14523 case EM_MN10200:
14524 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14525 case EM_FT32:
14526 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14527 case EM_Z80:
14528 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14529 default:
015dc7e1 14530 return false;
4dc3c23d
AM
14531 }
14532}
14533
aca88567
NC
14534/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14535 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14536
015dc7e1 14537static bool
dda8d76d 14538is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14539{
d347c9df 14540 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14541 switch (filedata->file_header.e_machine)
4b78141a 14542 {
886a2506
NC
14543 case EM_ARC:
14544 case EM_ARC_COMPACT:
14545 case EM_ARC_COMPACT2:
14546 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14547 case EM_ADAPTEVA_EPIPHANY:
14548 return reloc_type == 5;
aca88567
NC
14549 case EM_AVR_OLD:
14550 case EM_AVR:
14551 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14552 case EM_CYGNUS_D10V:
14553 case EM_D10V:
14554 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14555 case EM_FT32:
14556 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14557 case EM_H8S:
14558 case EM_H8_300:
14559 case EM_H8_300H:
aca88567
NC
14560 return reloc_type == R_H8_DIR16;
14561 case EM_IP2K_OLD:
14562 case EM_IP2K:
14563 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14564 case EM_M32C_OLD:
f4236fe4
DD
14565 case EM_M32C:
14566 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14567 case EM_CYGNUS_MN10200:
14568 case EM_MN10200:
14569 return reloc_type == 2; /* R_MN10200_16. */
14570 case EM_CYGNUS_MN10300:
14571 case EM_MN10300:
14572 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14573 case EM_MSP430:
dda8d76d 14574 if (uses_msp430x_relocs (filedata))
13761a11 14575 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14576 /* Fall through. */
78c8d46c 14577 case EM_MSP430_OLD:
aca88567 14578 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14579 case EM_NDS32:
14580 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14581 case EM_ALTERA_NIOS2:
36591ba1 14582 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14583 case EM_NIOS32:
14584 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14585 case EM_OR1K:
14586 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14587 case EM_RISCV:
14588 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14589 case EM_TI_PRU:
14590 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14591 case EM_TI_C6000:
14592 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14593 case EM_VISIUM:
14594 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14595 case EM_XC16X:
14596 case EM_C166:
14597 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14598 case EM_XGATE:
14599 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14600 case EM_Z80:
14601 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14602 default:
015dc7e1 14603 return false;
4b78141a
NC
14604 }
14605}
14606
39e07931
AS
14607/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14608 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14609
015dc7e1 14610static bool
39e07931
AS
14611is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14612{
14613 switch (filedata->file_header.e_machine)
14614 {
14615 case EM_RISCV:
14616 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14617 case EM_Z80:
14618 return reloc_type == 1; /* R_Z80_8. */
39e07931 14619 default:
015dc7e1 14620 return false;
39e07931
AS
14621 }
14622}
14623
14624/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14625 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14626
015dc7e1 14627static bool
39e07931
AS
14628is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14629{
14630 switch (filedata->file_header.e_machine)
14631 {
14632 case EM_RISCV:
14633 return reloc_type == 53; /* R_RISCV_SET6. */
14634 default:
015dc7e1 14635 return false;
39e07931
AS
14636 }
14637}
14638
03336641
JW
14639/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14640 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14641
015dc7e1 14642static bool
03336641
JW
14643is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14644{
14645 /* Please keep this table alpha-sorted for ease of visual lookup. */
14646 switch (filedata->file_header.e_machine)
14647 {
14648 case EM_RISCV:
14649 return reloc_type == 35; /* R_RISCV_ADD32. */
14650 default:
015dc7e1 14651 return false;
03336641
JW
14652 }
14653}
14654
14655/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14656 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14657
015dc7e1 14658static bool
03336641
JW
14659is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14660{
14661 /* Please keep this table alpha-sorted for ease of visual lookup. */
14662 switch (filedata->file_header.e_machine)
14663 {
14664 case EM_RISCV:
14665 return reloc_type == 39; /* R_RISCV_SUB32. */
14666 default:
015dc7e1 14667 return false;
03336641
JW
14668 }
14669}
14670
14671/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14672 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14673
015dc7e1 14674static bool
03336641
JW
14675is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14676{
14677 /* Please keep this table alpha-sorted for ease of visual lookup. */
14678 switch (filedata->file_header.e_machine)
14679 {
14680 case EM_RISCV:
14681 return reloc_type == 36; /* R_RISCV_ADD64. */
14682 default:
015dc7e1 14683 return false;
03336641
JW
14684 }
14685}
14686
14687/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14688 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14689
015dc7e1 14690static bool
03336641
JW
14691is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14692{
14693 /* Please keep this table alpha-sorted for ease of visual lookup. */
14694 switch (filedata->file_header.e_machine)
14695 {
14696 case EM_RISCV:
14697 return reloc_type == 40; /* R_RISCV_SUB64. */
14698 default:
015dc7e1 14699 return false;
03336641
JW
14700 }
14701}
14702
14703/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14704 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14705
015dc7e1 14706static bool
03336641
JW
14707is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14708{
14709 /* Please keep this table alpha-sorted for ease of visual lookup. */
14710 switch (filedata->file_header.e_machine)
14711 {
14712 case EM_RISCV:
14713 return reloc_type == 34; /* R_RISCV_ADD16. */
14714 default:
015dc7e1 14715 return false;
03336641
JW
14716 }
14717}
14718
14719/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14720 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14721
015dc7e1 14722static bool
03336641
JW
14723is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14724{
14725 /* Please keep this table alpha-sorted for ease of visual lookup. */
14726 switch (filedata->file_header.e_machine)
14727 {
14728 case EM_RISCV:
14729 return reloc_type == 38; /* R_RISCV_SUB16. */
14730 default:
015dc7e1 14731 return false;
03336641
JW
14732 }
14733}
14734
14735/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14736 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14737
015dc7e1 14738static bool
03336641
JW
14739is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14740{
14741 /* Please keep this table alpha-sorted for ease of visual lookup. */
14742 switch (filedata->file_header.e_machine)
14743 {
14744 case EM_RISCV:
14745 return reloc_type == 33; /* R_RISCV_ADD8. */
14746 default:
015dc7e1 14747 return false;
03336641
JW
14748 }
14749}
14750
14751/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14752 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14753
015dc7e1 14754static bool
03336641
JW
14755is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14756{
14757 /* Please keep this table alpha-sorted for ease of visual lookup. */
14758 switch (filedata->file_header.e_machine)
14759 {
14760 case EM_RISCV:
14761 return reloc_type == 37; /* R_RISCV_SUB8. */
14762 default:
015dc7e1 14763 return false;
03336641
JW
14764 }
14765}
14766
39e07931
AS
14767/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14768 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14769
015dc7e1 14770static bool
39e07931
AS
14771is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14772{
14773 switch (filedata->file_header.e_machine)
14774 {
14775 case EM_RISCV:
14776 return reloc_type == 52; /* R_RISCV_SUB6. */
14777 default:
015dc7e1 14778 return false;
39e07931
AS
14779 }
14780}
14781
2a7b2e88
JK
14782/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14783 relocation entries (possibly formerly used for SHT_GROUP sections). */
14784
015dc7e1 14785static bool
dda8d76d 14786is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14787{
dda8d76d 14788 switch (filedata->file_header.e_machine)
2a7b2e88 14789 {
cb8f3167 14790 case EM_386: /* R_386_NONE. */
d347c9df 14791 case EM_68K: /* R_68K_NONE. */
cfb8c092 14792 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14793 case EM_ALPHA: /* R_ALPHA_NONE. */
14794 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14795 case EM_ARC: /* R_ARC_NONE. */
886a2506 14796 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14797 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14798 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14799 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14800 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14801 case EM_FT32: /* R_FT32_NONE. */
14802 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14803 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14804 case EM_L1OM: /* R_X86_64_NONE. */
14805 case EM_M32R: /* R_M32R_NONE. */
14806 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14807 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14808 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14809 case EM_NIOS32: /* R_NIOS_NONE. */
14810 case EM_OR1K: /* R_OR1K_NONE. */
14811 case EM_PARISC: /* R_PARISC_NONE. */
14812 case EM_PPC64: /* R_PPC64_NONE. */
14813 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14814 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14815 case EM_S390: /* R_390_NONE. */
14816 case EM_S390_OLD:
14817 case EM_SH: /* R_SH_NONE. */
14818 case EM_SPARC32PLUS:
14819 case EM_SPARC: /* R_SPARC_NONE. */
14820 case EM_SPARCV9:
aa137e4d
NC
14821 case EM_TILEGX: /* R_TILEGX_NONE. */
14822 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14823 case EM_TI_C6000:/* R_C6000_NONE. */
14824 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14825 case EM_XC16X:
6655dba2 14826 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14827 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14828 return reloc_type == 0;
d347c9df 14829
a06ea964
NC
14830 case EM_AARCH64:
14831 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14832 case EM_AVR_OLD:
14833 case EM_AVR:
14834 return (reloc_type == 0 /* R_AVR_NONE. */
14835 || reloc_type == 30 /* R_AVR_DIFF8. */
14836 || reloc_type == 31 /* R_AVR_DIFF16. */
14837 || reloc_type == 32 /* R_AVR_DIFF32. */);
14838 case EM_METAG:
14839 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14840 case EM_NDS32:
14841 return (reloc_type == 0 /* R_XTENSA_NONE. */
14842 || reloc_type == 204 /* R_NDS32_DIFF8. */
14843 || reloc_type == 205 /* R_NDS32_DIFF16. */
14844 || reloc_type == 206 /* R_NDS32_DIFF32. */
14845 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14846 case EM_TI_PRU:
14847 return (reloc_type == 0 /* R_PRU_NONE. */
14848 || reloc_type == 65 /* R_PRU_DIFF8. */
14849 || reloc_type == 66 /* R_PRU_DIFF16. */
14850 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14851 case EM_XTENSA_OLD:
14852 case EM_XTENSA:
4dc3c23d
AM
14853 return (reloc_type == 0 /* R_XTENSA_NONE. */
14854 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14855 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14856 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14857 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14858 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14859 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14860 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14861 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14862 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14863 }
015dc7e1 14864 return false;
2a7b2e88
JK
14865}
14866
d1c4b12b
NC
14867/* Returns TRUE if there is a relocation against
14868 section NAME at OFFSET bytes. */
14869
015dc7e1 14870bool
d1c4b12b
NC
14871reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14872{
14873 Elf_Internal_Rela * relocs;
14874 Elf_Internal_Rela * rp;
14875
14876 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14877 return false;
d1c4b12b
NC
14878
14879 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14880
14881 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14882 if (rp->r_offset == offset)
015dc7e1 14883 return true;
d1c4b12b 14884
015dc7e1 14885 return false;
d1c4b12b
NC
14886}
14887
cf13d699 14888/* Apply relocations to a section.
32ec8896
NC
14889 Returns TRUE upon success, FALSE otherwise.
14890 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14891 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14892 will be set to the number of relocs loaded.
14893
cf13d699 14894 Note: So far support has been added only for those relocations
32ec8896
NC
14895 which can be found in debug sections. FIXME: Add support for
14896 more relocations ? */
1b315056 14897
015dc7e1 14898static bool
dda8d76d 14899apply_relocations (Filedata * filedata,
d1c4b12b
NC
14900 const Elf_Internal_Shdr * section,
14901 unsigned char * start,
14902 bfd_size_type size,
1449284b 14903 void ** relocs_return,
d1c4b12b 14904 unsigned long * num_relocs_return)
1b315056 14905{
cf13d699 14906 Elf_Internal_Shdr * relsec;
0d2a7a93 14907 unsigned char * end = start + size;
cb8f3167 14908
d1c4b12b
NC
14909 if (relocs_return != NULL)
14910 {
14911 * (Elf_Internal_Rela **) relocs_return = NULL;
14912 * num_relocs_return = 0;
14913 }
14914
dda8d76d 14915 if (filedata->file_header.e_type != ET_REL)
32ec8896 14916 /* No relocs to apply. */
015dc7e1 14917 return true;
1b315056 14918
cf13d699 14919 /* Find the reloc section associated with the section. */
dda8d76d
NC
14920 for (relsec = filedata->section_headers;
14921 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14922 ++relsec)
252b5132 14923 {
015dc7e1 14924 bool is_rela;
41e92641 14925 unsigned long num_relocs;
2cf0635d
NC
14926 Elf_Internal_Rela * relocs;
14927 Elf_Internal_Rela * rp;
14928 Elf_Internal_Shdr * symsec;
14929 Elf_Internal_Sym * symtab;
ba5cdace 14930 unsigned long num_syms;
2cf0635d 14931 Elf_Internal_Sym * sym;
252b5132 14932
41e92641 14933 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14934 || relsec->sh_info >= filedata->file_header.e_shnum
14935 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14936 || relsec->sh_size == 0
dda8d76d 14937 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14938 continue;
428409d5 14939
a788aedd
AM
14940 symsec = filedata->section_headers + relsec->sh_link;
14941 if (symsec->sh_type != SHT_SYMTAB
14942 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14943 return false;
a788aedd 14944
41e92641
NC
14945 is_rela = relsec->sh_type == SHT_RELA;
14946
14947 if (is_rela)
14948 {
dda8d76d 14949 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14950 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14951 return false;
41e92641
NC
14952 }
14953 else
14954 {
dda8d76d 14955 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14956 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14957 return false;
41e92641
NC
14958 }
14959
14960 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14961 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14962 is_rela = false;
428409d5 14963
4de91c10 14964 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14965
41e92641 14966 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14967 {
015dc7e1
AM
14968 bfd_vma addend;
14969 unsigned int reloc_type;
14970 unsigned int reloc_size;
14971 bool reloc_inplace = false;
14972 bool reloc_subtract = false;
14973 unsigned char *rloc;
14974 unsigned long sym_index;
4b78141a 14975
dda8d76d 14976 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14977
dda8d76d 14978 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14979 continue;
dda8d76d 14980 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14981 continue;
dda8d76d
NC
14982 else if (is_32bit_abs_reloc (filedata, reloc_type)
14983 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14984 reloc_size = 4;
dda8d76d
NC
14985 else if (is_64bit_abs_reloc (filedata, reloc_type)
14986 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14987 reloc_size = 8;
dda8d76d 14988 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14989 reloc_size = 3;
dda8d76d 14990 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14991 reloc_size = 2;
39e07931
AS
14992 else if (is_8bit_abs_reloc (filedata, reloc_type)
14993 || is_6bit_abs_reloc (filedata, reloc_type))
14994 reloc_size = 1;
03336641
JW
14995 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14996 reloc_type))
14997 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14998 {
14999 reloc_size = 4;
015dc7e1 15000 reloc_inplace = true;
03336641
JW
15001 }
15002 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15003 reloc_type))
15004 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15005 {
15006 reloc_size = 8;
015dc7e1 15007 reloc_inplace = true;
03336641
JW
15008 }
15009 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15010 reloc_type))
15011 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15012 {
15013 reloc_size = 2;
015dc7e1 15014 reloc_inplace = true;
03336641
JW
15015 }
15016 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15017 reloc_type))
15018 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15019 {
15020 reloc_size = 1;
015dc7e1 15021 reloc_inplace = true;
03336641 15022 }
39e07931
AS
15023 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15024 reloc_type)))
15025 {
15026 reloc_size = 1;
015dc7e1 15027 reloc_inplace = true;
39e07931 15028 }
aca88567 15029 else
4b78141a 15030 {
bee0ee85 15031 static unsigned int prev_reloc = 0;
dda8d76d 15032
bee0ee85
NC
15033 if (reloc_type != prev_reloc)
15034 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15035 reloc_type, printable_section_name (filedata, section));
bee0ee85 15036 prev_reloc = reloc_type;
4b78141a
NC
15037 continue;
15038 }
103f02d3 15039
91d6fa6a 15040 rloc = start + rp->r_offset;
75802ccb 15041 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15042 {
15043 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15044 (unsigned long) rp->r_offset,
dda8d76d 15045 printable_section_name (filedata, section));
700dd8b7
L
15046 continue;
15047 }
103f02d3 15048
ba5cdace
NC
15049 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15050 if (sym_index >= num_syms)
15051 {
15052 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15053 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15054 continue;
15055 }
15056 sym = symtab + sym_index;
41e92641
NC
15057
15058 /* If the reloc has a symbol associated with it,
55f25fc3
L
15059 make sure that it is of an appropriate type.
15060
15061 Relocations against symbols without type can happen.
15062 Gcc -feliminate-dwarf2-dups may generate symbols
15063 without type for debug info.
15064
15065 Icc generates relocations against function symbols
15066 instead of local labels.
15067
15068 Relocations against object symbols can happen, eg when
15069 referencing a global array. For an example of this see
15070 the _clz.o binary in libgcc.a. */
aca88567 15071 if (sym != symtab
b8871f35 15072 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15073 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15074 {
d3a49aa8 15075 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15076 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15077 printable_section_name (filedata, relsec),
d3a49aa8 15078 (long int)(rp - relocs));
aca88567 15079 continue;
5b18a4bc 15080 }
252b5132 15081
4dc3c23d
AM
15082 addend = 0;
15083 if (is_rela)
15084 addend += rp->r_addend;
c47320c3
AM
15085 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15086 partial_inplace. */
4dc3c23d 15087 if (!is_rela
dda8d76d 15088 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15089 && reloc_type == 1)
dda8d76d
NC
15090 || ((filedata->file_header.e_machine == EM_PJ
15091 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15092 && reloc_type == 1)
dda8d76d
NC
15093 || ((filedata->file_header.e_machine == EM_D30V
15094 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15095 && reloc_type == 12)
15096 || reloc_inplace)
39e07931
AS
15097 {
15098 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15099 addend += byte_get (rloc, reloc_size) & 0x3f;
15100 else
15101 addend += byte_get (rloc, reloc_size);
15102 }
cb8f3167 15103
dda8d76d
NC
15104 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15105 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15106 {
15107 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15108 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15109 addend -= 8;
91d6fa6a 15110 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15111 reloc_size);
15112 }
39e07931
AS
15113 else if (is_6bit_abs_reloc (filedata, reloc_type)
15114 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15115 {
15116 if (reloc_subtract)
15117 addend -= sym->st_value;
15118 else
15119 addend += sym->st_value;
15120 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15121 byte_put (rloc, addend, reloc_size);
15122 }
03336641
JW
15123 else if (reloc_subtract)
15124 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15125 else
91d6fa6a 15126 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15127 }
252b5132 15128
5b18a4bc 15129 free (symtab);
f84ce13b
NC
15130 /* Let the target specific reloc processing code know that
15131 we have finished with these relocs. */
dda8d76d 15132 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15133
15134 if (relocs_return)
15135 {
15136 * (Elf_Internal_Rela **) relocs_return = relocs;
15137 * num_relocs_return = num_relocs;
15138 }
15139 else
15140 free (relocs);
15141
5b18a4bc
NC
15142 break;
15143 }
32ec8896 15144
015dc7e1 15145 return true;
5b18a4bc 15146}
103f02d3 15147
cf13d699 15148#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15149static bool
dda8d76d 15150disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15151{
dda8d76d 15152 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15153
74e1a04b 15154 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15155
015dc7e1 15156 return true;
cf13d699
NC
15157}
15158#endif
15159
15160/* Reads in the contents of SECTION from FILE, returning a pointer
15161 to a malloc'ed buffer or NULL if something went wrong. */
15162
15163static char *
dda8d76d 15164get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15165{
dda8d76d 15166 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15167
15168 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15169 {
c6b78c96 15170 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15171 printable_section_name (filedata, section));
cf13d699
NC
15172 return NULL;
15173 }
15174
dda8d76d 15175 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15176 _("section contents"));
cf13d699
NC
15177}
15178
0e602686
NC
15179/* Uncompresses a section that was compressed using zlib, in place. */
15180
015dc7e1 15181static bool
dda8d76d
NC
15182uncompress_section_contents (unsigned char ** buffer,
15183 dwarf_size_type uncompressed_size,
15184 dwarf_size_type * size)
0e602686
NC
15185{
15186 dwarf_size_type compressed_size = *size;
15187 unsigned char * compressed_buffer = *buffer;
15188 unsigned char * uncompressed_buffer;
15189 z_stream strm;
15190 int rc;
15191
15192 /* It is possible the section consists of several compressed
15193 buffers concatenated together, so we uncompress in a loop. */
15194 /* PR 18313: The state field in the z_stream structure is supposed
15195 to be invisible to the user (ie us), but some compilers will
15196 still complain about it being used without initialisation. So
15197 we first zero the entire z_stream structure and then set the fields
15198 that we need. */
15199 memset (& strm, 0, sizeof strm);
15200 strm.avail_in = compressed_size;
15201 strm.next_in = (Bytef *) compressed_buffer;
15202 strm.avail_out = uncompressed_size;
15203 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15204
15205 rc = inflateInit (& strm);
15206 while (strm.avail_in > 0)
15207 {
15208 if (rc != Z_OK)
3624a6c1 15209 break;
0e602686
NC
15210 strm.next_out = ((Bytef *) uncompressed_buffer
15211 + (uncompressed_size - strm.avail_out));
15212 rc = inflate (&strm, Z_FINISH);
15213 if (rc != Z_STREAM_END)
3624a6c1 15214 break;
0e602686
NC
15215 rc = inflateReset (& strm);
15216 }
ad92f33d
AM
15217 if (inflateEnd (& strm) != Z_OK
15218 || rc != Z_OK
0e602686
NC
15219 || strm.avail_out != 0)
15220 goto fail;
15221
15222 *buffer = uncompressed_buffer;
15223 *size = uncompressed_size;
015dc7e1 15224 return true;
0e602686
NC
15225
15226 fail:
15227 free (uncompressed_buffer);
15228 /* Indicate decompression failure. */
15229 *buffer = NULL;
015dc7e1 15230 return false;
0e602686 15231}
dd24e3da 15232
015dc7e1 15233static bool
dda8d76d 15234dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15235{
015dc7e1
AM
15236 Elf_Internal_Shdr *relsec;
15237 bfd_size_type num_bytes;
15238 unsigned char *data;
15239 unsigned char *end;
15240 unsigned char *real_start;
15241 unsigned char *start;
15242 bool some_strings_shown;
cf13d699 15243
dda8d76d 15244 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15245 if (start == NULL)
c6b78c96 15246 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15247 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15248
0e602686 15249 num_bytes = section->sh_size;
cf13d699 15250
835f2fae
NC
15251 if (filedata->is_separate)
15252 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15253 printable_section_name (filedata, section),
15254 filedata->file_name);
15255 else
15256 printf (_("\nString dump of section '%s':\n"),
15257 printable_section_name (filedata, section));
cf13d699 15258
0e602686
NC
15259 if (decompress_dumps)
15260 {
15261 dwarf_size_type new_size = num_bytes;
15262 dwarf_size_type uncompressed_size = 0;
15263
15264 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15265 {
15266 Elf_Internal_Chdr chdr;
15267 unsigned int compression_header_size
ebdf1ebf
NC
15268 = get_compression_header (& chdr, (unsigned char *) start,
15269 num_bytes);
5844b465
NC
15270 if (compression_header_size == 0)
15271 /* An error message will have already been generated
15272 by get_compression_header. */
15273 goto error_out;
0e602686 15274
813dabb9 15275 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15276 {
813dabb9 15277 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15278 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15279 goto error_out;
813dabb9 15280 }
813dabb9
L
15281 uncompressed_size = chdr.ch_size;
15282 start += compression_header_size;
15283 new_size -= compression_header_size;
0e602686
NC
15284 }
15285 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15286 {
15287 /* Read the zlib header. In this case, it should be "ZLIB"
15288 followed by the uncompressed section size, 8 bytes in
15289 big-endian order. */
15290 uncompressed_size = start[4]; uncompressed_size <<= 8;
15291 uncompressed_size += start[5]; uncompressed_size <<= 8;
15292 uncompressed_size += start[6]; uncompressed_size <<= 8;
15293 uncompressed_size += start[7]; uncompressed_size <<= 8;
15294 uncompressed_size += start[8]; uncompressed_size <<= 8;
15295 uncompressed_size += start[9]; uncompressed_size <<= 8;
15296 uncompressed_size += start[10]; uncompressed_size <<= 8;
15297 uncompressed_size += start[11];
15298 start += 12;
15299 new_size -= 12;
15300 }
15301
1835f746
NC
15302 if (uncompressed_size)
15303 {
15304 if (uncompress_section_contents (& start,
15305 uncompressed_size, & new_size))
15306 num_bytes = new_size;
15307 else
15308 {
15309 error (_("Unable to decompress section %s\n"),
dda8d76d 15310 printable_section_name (filedata, section));
f761cb13 15311 goto error_out;
1835f746
NC
15312 }
15313 }
bc303e5d
NC
15314 else
15315 start = real_start;
0e602686 15316 }
fd8008d8 15317
cf13d699
NC
15318 /* If the section being dumped has relocations against it the user might
15319 be expecting these relocations to have been applied. Check for this
15320 case and issue a warning message in order to avoid confusion.
15321 FIXME: Maybe we ought to have an option that dumps a section with
15322 relocs applied ? */
dda8d76d
NC
15323 for (relsec = filedata->section_headers;
15324 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15325 ++relsec)
15326 {
15327 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15328 || relsec->sh_info >= filedata->file_header.e_shnum
15329 || filedata->section_headers + relsec->sh_info != section
cf13d699 15330 || relsec->sh_size == 0
dda8d76d 15331 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15332 continue;
15333
15334 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15335 break;
15336 }
15337
cf13d699
NC
15338 data = start;
15339 end = start + num_bytes;
015dc7e1 15340 some_strings_shown = false;
cf13d699 15341
ba3265d0
NC
15342#ifdef HAVE_MBSTATE_T
15343 mbstate_t state;
15344 /* Initialise the multibyte conversion state. */
15345 memset (& state, 0, sizeof (state));
15346#endif
15347
015dc7e1 15348 bool continuing = false;
ba3265d0 15349
cf13d699
NC
15350 while (data < end)
15351 {
15352 while (!ISPRINT (* data))
15353 if (++ data >= end)
15354 break;
15355
15356 if (data < end)
15357 {
071436c6
NC
15358 size_t maxlen = end - data;
15359
ba3265d0
NC
15360 if (continuing)
15361 {
15362 printf (" ");
015dc7e1 15363 continuing = false;
ba3265d0
NC
15364 }
15365 else
15366 {
d1ce973e 15367 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15368 }
15369
4082ef84
NC
15370 if (maxlen > 0)
15371 {
f3da8a96 15372 char c = 0;
ba3265d0
NC
15373
15374 while (maxlen)
15375 {
15376 c = *data++;
15377
15378 if (c == 0)
15379 break;
15380
15381 /* PR 25543: Treat new-lines as string-ending characters. */
15382 if (c == '\n')
15383 {
15384 printf ("\\n\n");
15385 if (*data != 0)
015dc7e1 15386 continuing = true;
ba3265d0
NC
15387 break;
15388 }
15389
15390 /* Do not print control characters directly as they can affect terminal
15391 settings. Such characters usually appear in the names generated
15392 by the assembler for local labels. */
15393 if (ISCNTRL (c))
15394 {
15395 printf ("^%c", c + 0x40);
15396 }
15397 else if (ISPRINT (c))
15398 {
15399 putchar (c);
15400 }
15401 else
15402 {
15403 size_t n;
15404#ifdef HAVE_MBSTATE_T
15405 wchar_t w;
15406#endif
15407 /* Let printf do the hard work of displaying multibyte characters. */
15408 printf ("%.1s", data - 1);
15409#ifdef HAVE_MBSTATE_T
15410 /* Try to find out how many bytes made up the character that was
15411 just printed. Advance the symbol pointer past the bytes that
15412 were displayed. */
15413 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15414#else
15415 n = 1;
15416#endif
15417 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15418 data += (n - 1);
15419 }
15420 }
15421
15422 if (c != '\n')
15423 putchar ('\n');
4082ef84
NC
15424 }
15425 else
15426 {
15427 printf (_("<corrupt>\n"));
15428 data = end;
15429 }
015dc7e1 15430 some_strings_shown = true;
cf13d699
NC
15431 }
15432 }
15433
15434 if (! some_strings_shown)
15435 printf (_(" No strings found in this section."));
15436
0e602686 15437 free (real_start);
cf13d699
NC
15438
15439 putchar ('\n');
015dc7e1 15440 return true;
f761cb13
AM
15441
15442error_out:
15443 free (real_start);
015dc7e1 15444 return false;
cf13d699
NC
15445}
15446
015dc7e1
AM
15447static bool
15448dump_section_as_bytes (Elf_Internal_Shdr *section,
15449 Filedata *filedata,
15450 bool relocate)
cf13d699
NC
15451{
15452 Elf_Internal_Shdr * relsec;
0e602686
NC
15453 bfd_size_type bytes;
15454 bfd_size_type section_size;
15455 bfd_vma addr;
15456 unsigned char * data;
15457 unsigned char * real_start;
15458 unsigned char * start;
15459
dda8d76d 15460 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15461 if (start == NULL)
c6b78c96 15462 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15463 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15464
0e602686 15465 section_size = section->sh_size;
cf13d699 15466
835f2fae
NC
15467 if (filedata->is_separate)
15468 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15469 printable_section_name (filedata, section),
15470 filedata->file_name);
15471 else
15472 printf (_("\nHex dump of section '%s':\n"),
15473 printable_section_name (filedata, section));
cf13d699 15474
0e602686
NC
15475 if (decompress_dumps)
15476 {
15477 dwarf_size_type new_size = section_size;
15478 dwarf_size_type uncompressed_size = 0;
15479
15480 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15481 {
15482 Elf_Internal_Chdr chdr;
15483 unsigned int compression_header_size
ebdf1ebf 15484 = get_compression_header (& chdr, start, section_size);
0e602686 15485
5844b465
NC
15486 if (compression_header_size == 0)
15487 /* An error message will have already been generated
15488 by get_compression_header. */
15489 goto error_out;
15490
813dabb9 15491 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15492 {
813dabb9 15493 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15494 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15495 goto error_out;
0e602686 15496 }
813dabb9
L
15497 uncompressed_size = chdr.ch_size;
15498 start += compression_header_size;
15499 new_size -= compression_header_size;
0e602686
NC
15500 }
15501 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15502 {
15503 /* Read the zlib header. In this case, it should be "ZLIB"
15504 followed by the uncompressed section size, 8 bytes in
15505 big-endian order. */
15506 uncompressed_size = start[4]; uncompressed_size <<= 8;
15507 uncompressed_size += start[5]; uncompressed_size <<= 8;
15508 uncompressed_size += start[6]; uncompressed_size <<= 8;
15509 uncompressed_size += start[7]; uncompressed_size <<= 8;
15510 uncompressed_size += start[8]; uncompressed_size <<= 8;
15511 uncompressed_size += start[9]; uncompressed_size <<= 8;
15512 uncompressed_size += start[10]; uncompressed_size <<= 8;
15513 uncompressed_size += start[11];
15514 start += 12;
15515 new_size -= 12;
15516 }
15517
f055032e
NC
15518 if (uncompressed_size)
15519 {
15520 if (uncompress_section_contents (& start, uncompressed_size,
15521 & new_size))
bc303e5d
NC
15522 {
15523 section_size = new_size;
15524 }
f055032e
NC
15525 else
15526 {
15527 error (_("Unable to decompress section %s\n"),
dda8d76d 15528 printable_section_name (filedata, section));
bc303e5d 15529 /* FIXME: Print the section anyway ? */
f761cb13 15530 goto error_out;
f055032e
NC
15531 }
15532 }
bc303e5d
NC
15533 else
15534 start = real_start;
0e602686 15535 }
14ae95f2 15536
cf13d699
NC
15537 if (relocate)
15538 {
dda8d76d 15539 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15540 goto error_out;
cf13d699
NC
15541 }
15542 else
15543 {
15544 /* If the section being dumped has relocations against it the user might
15545 be expecting these relocations to have been applied. Check for this
15546 case and issue a warning message in order to avoid confusion.
15547 FIXME: Maybe we ought to have an option that dumps a section with
15548 relocs applied ? */
dda8d76d
NC
15549 for (relsec = filedata->section_headers;
15550 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15551 ++relsec)
15552 {
15553 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15554 || relsec->sh_info >= filedata->file_header.e_shnum
15555 || filedata->section_headers + relsec->sh_info != section
cf13d699 15556 || relsec->sh_size == 0
dda8d76d 15557 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15558 continue;
15559
15560 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15561 break;
15562 }
15563 }
15564
15565 addr = section->sh_addr;
0e602686 15566 bytes = section_size;
cf13d699
NC
15567 data = start;
15568
15569 while (bytes)
15570 {
15571 int j;
15572 int k;
15573 int lbytes;
15574
15575 lbytes = (bytes > 16 ? 16 : bytes);
15576
15577 printf (" 0x%8.8lx ", (unsigned long) addr);
15578
15579 for (j = 0; j < 16; j++)
15580 {
15581 if (j < lbytes)
15582 printf ("%2.2x", data[j]);
15583 else
15584 printf (" ");
15585
15586 if ((j & 3) == 3)
15587 printf (" ");
15588 }
15589
15590 for (j = 0; j < lbytes; j++)
15591 {
15592 k = data[j];
15593 if (k >= ' ' && k < 0x7f)
15594 printf ("%c", k);
15595 else
15596 printf (".");
15597 }
15598
15599 putchar ('\n');
15600
15601 data += lbytes;
15602 addr += lbytes;
15603 bytes -= lbytes;
15604 }
15605
0e602686 15606 free (real_start);
cf13d699
NC
15607
15608 putchar ('\n');
015dc7e1 15609 return true;
f761cb13
AM
15610
15611 error_out:
15612 free (real_start);
015dc7e1 15613 return false;
cf13d699
NC
15614}
15615
094e34f2 15616#ifdef ENABLE_LIBCTF
7d9813f1
NA
15617static ctf_sect_t *
15618shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15619{
84714f86 15620 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15621 buf->cts_size = shdr->sh_size;
15622 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15623
15624 return buf;
15625}
15626
15627/* Formatting callback function passed to ctf_dump. Returns either the pointer
15628 it is passed, or a pointer to newly-allocated storage, in which case
15629 dump_ctf() will free it when it no longer needs it. */
15630
2f6ecaed
NA
15631static char *
15632dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15633 char *s, void *arg)
7d9813f1 15634{
3e50a591 15635 const char *blanks = arg;
7d9813f1
NA
15636 char *new_s;
15637
3e50a591 15638 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15639 return s;
15640 return new_s;
15641}
15642
926c9e76
NA
15643/* Dump CTF errors/warnings. */
15644static void
139633c3 15645dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15646{
15647 ctf_next_t *it = NULL;
15648 char *errtext;
15649 int is_warning;
15650 int err;
15651
15652 /* Dump accumulated errors and warnings. */
15653 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15654 {
5e9b84f7 15655 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15656 errtext);
15657 free (errtext);
15658 }
15659 if (err != ECTF_NEXT_END)
15660 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15661}
15662
2f6ecaed
NA
15663/* Dump one CTF archive member. */
15664
80b56fad
NA
15665static void
15666dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15667 size_t member)
2f6ecaed 15668{
2f6ecaed
NA
15669 const char *things[] = {"Header", "Labels", "Data objects",
15670 "Function objects", "Variables", "Types", "Strings",
15671 ""};
15672 const char **thing;
15673 size_t i;
15674
80b56fad
NA
15675 /* Don't print out the name of the default-named archive member if it appears
15676 first in the list. The name .ctf appears everywhere, even for things that
15677 aren't really archives, so printing it out is liable to be confusing; also,
15678 the common case by far is for only one archive member to exist, and hiding
15679 it in that case seems worthwhile. */
2f6ecaed 15680
80b56fad
NA
15681 if (strcmp (name, ".ctf") != 0 || member != 0)
15682 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15683
80b56fad
NA
15684 if (ctf_parent_name (ctf) != NULL)
15685 ctf_import (ctf, parent);
2f6ecaed
NA
15686
15687 for (i = 0, thing = things; *thing[0]; thing++, i++)
15688 {
15689 ctf_dump_state_t *s = NULL;
15690 char *item;
15691
15692 printf ("\n %s:\n", *thing);
15693 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15694 (void *) " ")) != NULL)
15695 {
15696 printf ("%s\n", item);
15697 free (item);
15698 }
15699
15700 if (ctf_errno (ctf))
15701 {
15702 error (_("Iteration failed: %s, %s\n"), *thing,
15703 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15704 break;
2f6ecaed
NA
15705 }
15706 }
8b37e7b6 15707
926c9e76 15708 dump_ctf_errs (ctf);
2f6ecaed
NA
15709}
15710
015dc7e1 15711static bool
7d9813f1
NA
15712dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15713{
7d9813f1
NA
15714 Elf_Internal_Shdr * symtab_sec = NULL;
15715 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15716 void * data = NULL;
15717 void * symdata = NULL;
15718 void * strdata = NULL;
80b56fad 15719 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15720 ctf_sect_t * symsectp = NULL;
15721 ctf_sect_t * strsectp = NULL;
2f6ecaed 15722 ctf_archive_t * ctfa = NULL;
139633c3 15723 ctf_dict_t * parent = NULL;
80b56fad 15724 ctf_dict_t * fp;
7d9813f1 15725
80b56fad
NA
15726 ctf_next_t *i = NULL;
15727 const char *name;
15728 size_t member = 0;
7d9813f1 15729 int err;
015dc7e1 15730 bool ret = false;
7d9813f1
NA
15731
15732 shdr_to_ctf_sect (&ctfsect, section, filedata);
15733 data = get_section_contents (section, filedata);
15734 ctfsect.cts_data = data;
15735
616febde 15736 if (!dump_ctf_symtab_name)
3d16b64e 15737 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15738
15739 if (!dump_ctf_strtab_name)
3d16b64e 15740 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15741
15742 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15743 {
15744 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15745 {
15746 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15747 goto fail;
15748 }
15749 if ((symdata = (void *) get_data (NULL, filedata,
15750 symtab_sec->sh_offset, 1,
15751 symtab_sec->sh_size,
15752 _("symbols"))) == NULL)
15753 goto fail;
15754 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15755 symsect.cts_data = symdata;
15756 }
835f2fae 15757
df16e041 15758 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15759 {
15760 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15761 {
15762 error (_("No string table section named %s\n"),
15763 dump_ctf_strtab_name);
15764 goto fail;
15765 }
15766 if ((strdata = (void *) get_data (NULL, filedata,
15767 strtab_sec->sh_offset, 1,
15768 strtab_sec->sh_size,
15769 _("strings"))) == NULL)
15770 goto fail;
15771 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15772 strsect.cts_data = strdata;
15773 }
835f2fae 15774
2f6ecaed
NA
15775 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15776 libctf papers over the difference, so we can pretend it is always an
80b56fad 15777 archive. */
7d9813f1 15778
2f6ecaed 15779 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15780 {
926c9e76 15781 dump_ctf_errs (NULL);
7d9813f1
NA
15782 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15783 goto fail;
15784 }
15785
96c61be5
NA
15786 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15787 != ELFDATA2MSB);
15788
80b56fad
NA
15789 /* Preload the parent dict, since it will need to be imported into every
15790 child in turn. */
15791 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15792 {
926c9e76 15793 dump_ctf_errs (NULL);
2f6ecaed
NA
15794 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15795 goto fail;
7d9813f1
NA
15796 }
15797
015dc7e1 15798 ret = true;
7d9813f1 15799
835f2fae
NC
15800 if (filedata->is_separate)
15801 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15802 printable_section_name (filedata, section),
15803 filedata->file_name);
15804 else
15805 printf (_("\nDump of CTF section '%s':\n"),
15806 printable_section_name (filedata, section));
7d9813f1 15807
80b56fad
NA
15808 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15809 dump_ctf_archive_member (fp, name, parent, member++);
15810 if (err != ECTF_NEXT_END)
15811 {
15812 dump_ctf_errs (NULL);
15813 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15814 ret = false;
15815 }
7d9813f1
NA
15816
15817 fail:
139633c3 15818 ctf_dict_close (parent);
2f6ecaed 15819 ctf_close (ctfa);
7d9813f1
NA
15820 free (data);
15821 free (symdata);
15822 free (strdata);
15823 return ret;
15824}
094e34f2 15825#endif
7d9813f1 15826
015dc7e1 15827static bool
dda8d76d
NC
15828load_specific_debug_section (enum dwarf_section_display_enum debug,
15829 const Elf_Internal_Shdr * sec,
15830 void * data)
1007acb3 15831{
2cf0635d 15832 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15833 char buf [64];
dda8d76d 15834 Filedata * filedata = (Filedata *) data;
9abca702 15835
19e6b90e 15836 if (section->start != NULL)
dda8d76d
NC
15837 {
15838 /* If it is already loaded, do nothing. */
15839 if (streq (section->filename, filedata->file_name))
015dc7e1 15840 return true;
dda8d76d
NC
15841 free (section->start);
15842 }
1007acb3 15843
19e6b90e
L
15844 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15845 section->address = sec->sh_addr;
dda8d76d
NC
15846 section->filename = filedata->file_name;
15847 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15848 sec->sh_offset, 1,
15849 sec->sh_size, buf);
59245841
NC
15850 if (section->start == NULL)
15851 section->size = 0;
15852 else
15853 {
77115a4a
L
15854 unsigned char *start = section->start;
15855 dwarf_size_type size = sec->sh_size;
dab394de 15856 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15857
15858 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15859 {
15860 Elf_Internal_Chdr chdr;
d8024a91
NC
15861 unsigned int compression_header_size;
15862
f53be977
L
15863 if (size < (is_32bit_elf
15864 ? sizeof (Elf32_External_Chdr)
15865 : sizeof (Elf64_External_Chdr)))
d8024a91 15866 {
55be8fd0 15867 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15868 section->name);
015dc7e1 15869 return false;
d8024a91
NC
15870 }
15871
ebdf1ebf 15872 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15873 if (compression_header_size == 0)
15874 /* An error message will have already been generated
15875 by get_compression_header. */
015dc7e1 15876 return false;
d8024a91 15877
813dabb9
L
15878 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15879 {
15880 warn (_("section '%s' has unsupported compress type: %d\n"),
15881 section->name, chdr.ch_type);
015dc7e1 15882 return false;
813dabb9 15883 }
dab394de 15884 uncompressed_size = chdr.ch_size;
77115a4a
L
15885 start += compression_header_size;
15886 size -= compression_header_size;
15887 }
dab394de
L
15888 else if (size > 12 && streq ((char *) start, "ZLIB"))
15889 {
15890 /* Read the zlib header. In this case, it should be "ZLIB"
15891 followed by the uncompressed section size, 8 bytes in
15892 big-endian order. */
15893 uncompressed_size = start[4]; uncompressed_size <<= 8;
15894 uncompressed_size += start[5]; uncompressed_size <<= 8;
15895 uncompressed_size += start[6]; uncompressed_size <<= 8;
15896 uncompressed_size += start[7]; uncompressed_size <<= 8;
15897 uncompressed_size += start[8]; uncompressed_size <<= 8;
15898 uncompressed_size += start[9]; uncompressed_size <<= 8;
15899 uncompressed_size += start[10]; uncompressed_size <<= 8;
15900 uncompressed_size += start[11];
15901 start += 12;
15902 size -= 12;
15903 }
15904
1835f746 15905 if (uncompressed_size)
77115a4a 15906 {
1835f746
NC
15907 if (uncompress_section_contents (&start, uncompressed_size,
15908 &size))
15909 {
15910 /* Free the compressed buffer, update the section buffer
15911 and the section size if uncompress is successful. */
15912 free (section->start);
15913 section->start = start;
15914 }
15915 else
15916 {
15917 error (_("Unable to decompress section %s\n"),
dda8d76d 15918 printable_section_name (filedata, sec));
015dc7e1 15919 return false;
1835f746 15920 }
77115a4a 15921 }
bc303e5d 15922
77115a4a 15923 section->size = size;
59245841 15924 }
4a114e3e 15925
1b315056 15926 if (section->start == NULL)
015dc7e1 15927 return false;
1b315056 15928
19e6b90e 15929 if (debug_displays [debug].relocate)
32ec8896 15930 {
dda8d76d 15931 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15932 & section->reloc_info, & section->num_relocs))
015dc7e1 15933 return false;
32ec8896 15934 }
d1c4b12b
NC
15935 else
15936 {
15937 section->reloc_info = NULL;
15938 section->num_relocs = 0;
15939 }
1007acb3 15940
015dc7e1 15941 return true;
1007acb3
L
15942}
15943
301a9420
AM
15944#if HAVE_LIBDEBUGINFOD
15945/* Return a hex string representation of the build-id. */
15946unsigned char *
15947get_build_id (void * data)
15948{
ca0e11aa 15949 Filedata * filedata = (Filedata *) data;
301a9420
AM
15950 Elf_Internal_Shdr * shdr;
15951 unsigned long i;
15952
55be8fd0
NC
15953 /* Iterate through notes to find note.gnu.build-id.
15954 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15955 for (i = 0, shdr = filedata->section_headers;
15956 i < filedata->file_header.e_shnum && shdr != NULL;
15957 i++, shdr++)
15958 {
15959 if (shdr->sh_type != SHT_NOTE)
15960 continue;
15961
15962 char * next;
15963 char * end;
15964 size_t data_remaining;
15965 size_t min_notesz;
15966 Elf_External_Note * enote;
15967 Elf_Internal_Note inote;
15968
15969 bfd_vma offset = shdr->sh_offset;
15970 bfd_vma align = shdr->sh_addralign;
15971 bfd_vma length = shdr->sh_size;
15972
15973 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15974 if (enote == NULL)
15975 continue;
15976
15977 if (align < 4)
15978 align = 4;
15979 else if (align != 4 && align != 8)
f761cb13
AM
15980 {
15981 free (enote);
15982 continue;
15983 }
301a9420
AM
15984
15985 end = (char *) enote + length;
15986 data_remaining = end - (char *) enote;
15987
15988 if (!is_ia64_vms (filedata))
15989 {
15990 min_notesz = offsetof (Elf_External_Note, name);
15991 if (data_remaining < min_notesz)
15992 {
55be8fd0
NC
15993 warn (_("\
15994malformed note encountered in section %s whilst scanning for build-id note\n"),
15995 printable_section_name (filedata, shdr));
f761cb13 15996 free (enote);
55be8fd0 15997 continue;
301a9420
AM
15998 }
15999 data_remaining -= min_notesz;
16000
16001 inote.type = BYTE_GET (enote->type);
16002 inote.namesz = BYTE_GET (enote->namesz);
16003 inote.namedata = enote->name;
16004 inote.descsz = BYTE_GET (enote->descsz);
16005 inote.descdata = ((char *) enote
16006 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16007 inote.descpos = offset + (inote.descdata - (char *) enote);
16008 next = ((char *) enote
16009 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16010 }
16011 else
16012 {
16013 Elf64_External_VMS_Note *vms_enote;
16014
16015 /* PR binutils/15191
16016 Make sure that there is enough data to read. */
16017 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16018 if (data_remaining < min_notesz)
16019 {
55be8fd0
NC
16020 warn (_("\
16021malformed note encountered in section %s whilst scanning for build-id note\n"),
16022 printable_section_name (filedata, shdr));
f761cb13 16023 free (enote);
55be8fd0 16024 continue;
301a9420
AM
16025 }
16026 data_remaining -= min_notesz;
16027
16028 vms_enote = (Elf64_External_VMS_Note *) enote;
16029 inote.type = BYTE_GET (vms_enote->type);
16030 inote.namesz = BYTE_GET (vms_enote->namesz);
16031 inote.namedata = vms_enote->name;
16032 inote.descsz = BYTE_GET (vms_enote->descsz);
16033 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16034 inote.descpos = offset + (inote.descdata - (char *) enote);
16035 next = inote.descdata + align_power (inote.descsz, 3);
16036 }
16037
16038 /* Skip malformed notes. */
16039 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16040 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16041 || (size_t) (next - inote.descdata) < inote.descsz
16042 || ((size_t) (next - inote.descdata)
16043 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16044 {
55be8fd0
NC
16045 warn (_("\
16046malformed note encountered in section %s whilst scanning for build-id note\n"),
16047 printable_section_name (filedata, shdr));
f761cb13 16048 free (enote);
301a9420
AM
16049 continue;
16050 }
16051
16052 /* Check if this is the build-id note. If so then convert the build-id
16053 bytes to a hex string. */
16054 if (inote.namesz > 0
24d127aa 16055 && startswith (inote.namedata, "GNU")
301a9420
AM
16056 && inote.type == NT_GNU_BUILD_ID)
16057 {
16058 unsigned long j;
16059 char * build_id;
16060
16061 build_id = malloc (inote.descsz * 2 + 1);
16062 if (build_id == NULL)
f761cb13
AM
16063 {
16064 free (enote);
16065 return NULL;
16066 }
301a9420
AM
16067
16068 for (j = 0; j < inote.descsz; ++j)
16069 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16070 build_id[inote.descsz * 2] = '\0';
f761cb13 16071 free (enote);
301a9420 16072
55be8fd0 16073 return (unsigned char *) build_id;
301a9420 16074 }
f761cb13 16075 free (enote);
301a9420
AM
16076 }
16077
16078 return NULL;
16079}
16080#endif /* HAVE_LIBDEBUGINFOD */
16081
657d0d47
CC
16082/* If this is not NULL, load_debug_section will only look for sections
16083 within the list of sections given here. */
32ec8896 16084static unsigned int * section_subset = NULL;
657d0d47 16085
015dc7e1 16086bool
dda8d76d 16087load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16088{
2cf0635d
NC
16089 struct dwarf_section * section = &debug_displays [debug].section;
16090 Elf_Internal_Shdr * sec;
dda8d76d
NC
16091 Filedata * filedata = (Filedata *) data;
16092
e1dbfc17
L
16093 if (!dump_any_debugging)
16094 return false;
16095
f425ec66
NC
16096 /* Without section headers we cannot find any sections. */
16097 if (filedata->section_headers == NULL)
015dc7e1 16098 return false;
f425ec66 16099
9c1ce108
AM
16100 if (filedata->string_table == NULL
16101 && filedata->file_header.e_shstrndx != SHN_UNDEF
16102 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16103 {
16104 Elf_Internal_Shdr * strs;
16105
16106 /* Read in the string table, so that we have section names to scan. */
16107 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16108
4dff97b2 16109 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16110 {
9c1ce108
AM
16111 filedata->string_table
16112 = (char *) get_data (NULL, filedata, strs->sh_offset,
16113 1, strs->sh_size, _("string table"));
dda8d76d 16114
9c1ce108
AM
16115 filedata->string_table_length
16116 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16117 }
16118 }
d966045b
DJ
16119
16120 /* Locate the debug section. */
dda8d76d 16121 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16122 if (sec != NULL)
16123 section->name = section->uncompressed_name;
16124 else
16125 {
dda8d76d 16126 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16127 if (sec != NULL)
16128 section->name = section->compressed_name;
16129 }
16130 if (sec == NULL)
015dc7e1 16131 return false;
d966045b 16132
657d0d47
CC
16133 /* If we're loading from a subset of sections, and we've loaded
16134 a section matching this name before, it's likely that it's a
16135 different one. */
16136 if (section_subset != NULL)
16137 free_debug_section (debug);
16138
dda8d76d 16139 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16140}
16141
19e6b90e
L
16142void
16143free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16144{
2cf0635d 16145 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16146
19e6b90e
L
16147 if (section->start == NULL)
16148 return;
1007acb3 16149
19e6b90e
L
16150 free ((char *) section->start);
16151 section->start = NULL;
16152 section->address = 0;
16153 section->size = 0;
a788aedd 16154
9db70fc3
AM
16155 free (section->reloc_info);
16156 section->reloc_info = NULL;
16157 section->num_relocs = 0;
1007acb3
L
16158}
16159
015dc7e1 16160static bool
dda8d76d 16161display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16162{
84714f86
AM
16163 const char *name = (section_name_valid (filedata, section)
16164 ? section_name (filedata, section) : "");
16165 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16166 bfd_size_type length;
015dc7e1 16167 bool result = true;
3f5e193b 16168 int i;
1007acb3 16169
19e6b90e
L
16170 length = section->sh_size;
16171 if (length == 0)
1007acb3 16172 {
74e1a04b 16173 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16174 return true;
1007acb3 16175 }
5dff79d8
NC
16176 if (section->sh_type == SHT_NOBITS)
16177 {
16178 /* There is no point in dumping the contents of a debugging section
16179 which has the NOBITS type - the bits in the file will be random.
16180 This can happen when a file containing a .eh_frame section is
16181 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16182 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16183 print_name);
015dc7e1 16184 return false;
5dff79d8 16185 }
1007acb3 16186
24d127aa 16187 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16188 name = ".debug_info";
1007acb3 16189
19e6b90e
L
16190 /* See if we know how to display the contents of this section. */
16191 for (i = 0; i < max; i++)
d85bf2ba
NC
16192 {
16193 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16194 struct dwarf_section_display * display = debug_displays + i;
16195 struct dwarf_section * sec = & display->section;
d966045b 16196
d85bf2ba 16197 if (streq (sec->uncompressed_name, name)
24d127aa 16198 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16199 || streq (sec->compressed_name, name))
16200 {
015dc7e1 16201 bool secondary = (section != find_section (filedata, name));
1007acb3 16202
d85bf2ba
NC
16203 if (secondary)
16204 free_debug_section (id);
dda8d76d 16205
24d127aa 16206 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16207 sec->name = name;
16208 else if (streq (sec->uncompressed_name, name))
16209 sec->name = sec->uncompressed_name;
16210 else
16211 sec->name = sec->compressed_name;
657d0d47 16212
d85bf2ba
NC
16213 if (load_specific_debug_section (id, section, filedata))
16214 {
16215 /* If this debug section is part of a CU/TU set in a .dwp file,
16216 restrict load_debug_section to the sections in that set. */
16217 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16218
d85bf2ba 16219 result &= display->display (sec, filedata);
657d0d47 16220
d85bf2ba 16221 section_subset = NULL;
1007acb3 16222
44266f36 16223 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16224 free_debug_section (id);
16225 }
16226 break;
16227 }
16228 }
1007acb3 16229
19e6b90e 16230 if (i == max)
1007acb3 16231 {
74e1a04b 16232 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16233 result = false;
1007acb3
L
16234 }
16235
19e6b90e 16236 return result;
5b18a4bc 16237}
103f02d3 16238
aef1f6d0
DJ
16239/* Set DUMP_SECTS for all sections where dumps were requested
16240 based on section name. */
16241
16242static void
dda8d76d 16243initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16244{
2cf0635d 16245 struct dump_list_entry * cur;
aef1f6d0
DJ
16246
16247 for (cur = dump_sects_byname; cur; cur = cur->next)
16248 {
16249 unsigned int i;
015dc7e1 16250 bool any = false;
aef1f6d0 16251
dda8d76d 16252 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16253 if (section_name_valid (filedata, filedata->section_headers + i)
16254 && streq (section_name (filedata, filedata->section_headers + i),
16255 cur->name))
aef1f6d0 16256 {
6431e409 16257 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16258 any = true;
aef1f6d0
DJ
16259 }
16260
835f2fae
NC
16261 if (!any && !filedata->is_separate)
16262 warn (_("Section '%s' was not dumped because it does not exist\n"),
16263 cur->name);
aef1f6d0
DJ
16264 }
16265}
16266
015dc7e1 16267static bool
dda8d76d 16268process_section_contents (Filedata * filedata)
5b18a4bc 16269{
2cf0635d 16270 Elf_Internal_Shdr * section;
19e6b90e 16271 unsigned int i;
015dc7e1 16272 bool res = true;
103f02d3 16273
19e6b90e 16274 if (! do_dump)
015dc7e1 16275 return true;
103f02d3 16276
dda8d76d 16277 initialise_dumps_byname (filedata);
aef1f6d0 16278
dda8d76d 16279 for (i = 0, section = filedata->section_headers;
6431e409 16280 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16281 i++, section++)
16282 {
6431e409 16283 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16284
d6bfbc39
NC
16285 if (filedata->is_separate && ! process_links)
16286 dump &= DEBUG_DUMP;
047c3dbf 16287
19e6b90e 16288#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16289 if (dump & DISASS_DUMP)
16290 {
16291 if (! disassemble_section (section, filedata))
015dc7e1 16292 res = false;
dda8d76d 16293 }
19e6b90e 16294#endif
dda8d76d 16295 if (dump & HEX_DUMP)
32ec8896 16296 {
015dc7e1
AM
16297 if (! dump_section_as_bytes (section, filedata, false))
16298 res = false;
32ec8896 16299 }
103f02d3 16300
dda8d76d 16301 if (dump & RELOC_DUMP)
32ec8896 16302 {
015dc7e1
AM
16303 if (! dump_section_as_bytes (section, filedata, true))
16304 res = false;
32ec8896 16305 }
09c11c86 16306
dda8d76d 16307 if (dump & STRING_DUMP)
32ec8896 16308 {
dda8d76d 16309 if (! dump_section_as_strings (section, filedata))
015dc7e1 16310 res = false;
32ec8896 16311 }
cf13d699 16312
dda8d76d 16313 if (dump & DEBUG_DUMP)
32ec8896 16314 {
dda8d76d 16315 if (! display_debug_section (i, section, filedata))
015dc7e1 16316 res = false;
32ec8896 16317 }
7d9813f1 16318
094e34f2 16319#ifdef ENABLE_LIBCTF
7d9813f1
NA
16320 if (dump & CTF_DUMP)
16321 {
16322 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16323 res = false;
7d9813f1 16324 }
094e34f2 16325#endif
5b18a4bc 16326 }
103f02d3 16327
835f2fae 16328 if (! filedata->is_separate)
0ee3043f 16329 {
835f2fae
NC
16330 /* Check to see if the user requested a
16331 dump of a section that does not exist. */
16332 for (; i < filedata->dump.num_dump_sects; i++)
16333 if (filedata->dump.dump_sects[i])
16334 {
ca0e11aa 16335 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16336 res = false;
835f2fae 16337 }
0ee3043f 16338 }
32ec8896
NC
16339
16340 return res;
5b18a4bc 16341}
103f02d3 16342
5b18a4bc 16343static void
19e6b90e 16344process_mips_fpe_exception (int mask)
5b18a4bc 16345{
19e6b90e
L
16346 if (mask)
16347 {
015dc7e1 16348 bool first = true;
32ec8896 16349
19e6b90e 16350 if (mask & OEX_FPU_INEX)
015dc7e1 16351 fputs ("INEX", stdout), first = false;
19e6b90e 16352 if (mask & OEX_FPU_UFLO)
015dc7e1 16353 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16354 if (mask & OEX_FPU_OFLO)
015dc7e1 16355 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16356 if (mask & OEX_FPU_DIV0)
015dc7e1 16357 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16358 if (mask & OEX_FPU_INVAL)
16359 printf ("%sINVAL", first ? "" : "|");
16360 }
5b18a4bc 16361 else
19e6b90e 16362 fputs ("0", stdout);
5b18a4bc 16363}
103f02d3 16364
f6f0e17b
NC
16365/* Display's the value of TAG at location P. If TAG is
16366 greater than 0 it is assumed to be an unknown tag, and
16367 a message is printed to this effect. Otherwise it is
16368 assumed that a message has already been printed.
16369
16370 If the bottom bit of TAG is set it assumed to have a
16371 string value, otherwise it is assumed to have an integer
16372 value.
16373
16374 Returns an updated P pointing to the first unread byte
16375 beyond the end of TAG's value.
16376
16377 Reads at or beyond END will not be made. */
16378
16379static unsigned char *
60abdbed 16380display_tag_value (signed int tag,
f6f0e17b
NC
16381 unsigned char * p,
16382 const unsigned char * const end)
16383{
16384 unsigned long val;
16385
16386 if (tag > 0)
16387 printf (" Tag_unknown_%d: ", tag);
16388
16389 if (p >= end)
16390 {
4082ef84 16391 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16392 }
16393 else if (tag & 1)
16394 {
071436c6
NC
16395 /* PR 17531 file: 027-19978-0.004. */
16396 size_t maxlen = (end - p) - 1;
16397
16398 putchar ('"');
4082ef84
NC
16399 if (maxlen > 0)
16400 {
16401 print_symbol ((int) maxlen, (const char *) p);
16402 p += strnlen ((char *) p, maxlen) + 1;
16403 }
16404 else
16405 {
16406 printf (_("<corrupt string tag>"));
16407 p = (unsigned char *) end;
16408 }
071436c6 16409 printf ("\"\n");
f6f0e17b
NC
16410 }
16411 else
16412 {
cd30bcef 16413 READ_ULEB (val, p, end);
f6f0e17b
NC
16414 printf ("%ld (0x%lx)\n", val, val);
16415 }
16416
4082ef84 16417 assert (p <= end);
f6f0e17b
NC
16418 return p;
16419}
16420
53a346d8
CZ
16421/* ARC ABI attributes section. */
16422
16423static unsigned char *
16424display_arc_attribute (unsigned char * p,
16425 const unsigned char * const end)
16426{
16427 unsigned int tag;
53a346d8
CZ
16428 unsigned int val;
16429
cd30bcef 16430 READ_ULEB (tag, p, end);
53a346d8
CZ
16431
16432 switch (tag)
16433 {
16434 case Tag_ARC_PCS_config:
cd30bcef 16435 READ_ULEB (val, p, end);
53a346d8
CZ
16436 printf (" Tag_ARC_PCS_config: ");
16437 switch (val)
16438 {
16439 case 0:
16440 printf (_("Absent/Non standard\n"));
16441 break;
16442 case 1:
16443 printf (_("Bare metal/mwdt\n"));
16444 break;
16445 case 2:
16446 printf (_("Bare metal/newlib\n"));
16447 break;
16448 case 3:
16449 printf (_("Linux/uclibc\n"));
16450 break;
16451 case 4:
16452 printf (_("Linux/glibc\n"));
16453 break;
16454 default:
16455 printf (_("Unknown\n"));
16456 break;
16457 }
16458 break;
16459
16460 case Tag_ARC_CPU_base:
cd30bcef 16461 READ_ULEB (val, p, end);
53a346d8
CZ
16462 printf (" Tag_ARC_CPU_base: ");
16463 switch (val)
16464 {
16465 default:
16466 case TAG_CPU_NONE:
16467 printf (_("Absent\n"));
16468 break;
16469 case TAG_CPU_ARC6xx:
16470 printf ("ARC6xx\n");
16471 break;
16472 case TAG_CPU_ARC7xx:
16473 printf ("ARC7xx\n");
16474 break;
16475 case TAG_CPU_ARCEM:
16476 printf ("ARCEM\n");
16477 break;
16478 case TAG_CPU_ARCHS:
16479 printf ("ARCHS\n");
16480 break;
16481 }
16482 break;
16483
16484 case Tag_ARC_CPU_variation:
cd30bcef 16485 READ_ULEB (val, p, end);
53a346d8
CZ
16486 printf (" Tag_ARC_CPU_variation: ");
16487 switch (val)
16488 {
16489 default:
16490 if (val > 0 && val < 16)
53a346d8 16491 printf ("Core%d\n", val);
d8cbc93b
JL
16492 else
16493 printf ("Unknown\n");
16494 break;
16495
53a346d8
CZ
16496 case 0:
16497 printf (_("Absent\n"));
16498 break;
16499 }
16500 break;
16501
16502 case Tag_ARC_CPU_name:
16503 printf (" Tag_ARC_CPU_name: ");
16504 p = display_tag_value (-1, p, end);
16505 break;
16506
16507 case Tag_ARC_ABI_rf16:
cd30bcef 16508 READ_ULEB (val, p, end);
53a346d8
CZ
16509 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16510 break;
16511
16512 case Tag_ARC_ABI_osver:
cd30bcef 16513 READ_ULEB (val, p, end);
53a346d8
CZ
16514 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16515 break;
16516
16517 case Tag_ARC_ABI_pic:
16518 case Tag_ARC_ABI_sda:
cd30bcef 16519 READ_ULEB (val, p, end);
53a346d8
CZ
16520 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16521 : " Tag_ARC_ABI_pic: ");
16522 switch (val)
16523 {
16524 case 0:
16525 printf (_("Absent\n"));
16526 break;
16527 case 1:
16528 printf ("MWDT\n");
16529 break;
16530 case 2:
16531 printf ("GNU\n");
16532 break;
16533 default:
16534 printf (_("Unknown\n"));
16535 break;
16536 }
16537 break;
16538
16539 case Tag_ARC_ABI_tls:
cd30bcef 16540 READ_ULEB (val, p, end);
53a346d8
CZ
16541 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16542 break;
16543
16544 case Tag_ARC_ABI_enumsize:
cd30bcef 16545 READ_ULEB (val, p, end);
53a346d8
CZ
16546 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16547 _("smallest"));
16548 break;
16549
16550 case Tag_ARC_ABI_exceptions:
cd30bcef 16551 READ_ULEB (val, p, end);
53a346d8
CZ
16552 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16553 : _("default"));
16554 break;
16555
16556 case Tag_ARC_ABI_double_size:
cd30bcef 16557 READ_ULEB (val, p, end);
53a346d8
CZ
16558 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16559 break;
16560
16561 case Tag_ARC_ISA_config:
16562 printf (" Tag_ARC_ISA_config: ");
16563 p = display_tag_value (-1, p, end);
16564 break;
16565
16566 case Tag_ARC_ISA_apex:
16567 printf (" Tag_ARC_ISA_apex: ");
16568 p = display_tag_value (-1, p, end);
16569 break;
16570
16571 case Tag_ARC_ISA_mpy_option:
cd30bcef 16572 READ_ULEB (val, p, end);
53a346d8
CZ
16573 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16574 break;
16575
db1e1b45 16576 case Tag_ARC_ATR_version:
cd30bcef 16577 READ_ULEB (val, p, end);
db1e1b45 16578 printf (" Tag_ARC_ATR_version: %d\n", val);
16579 break;
16580
53a346d8
CZ
16581 default:
16582 return display_tag_value (tag & 1, p, end);
16583 }
16584
16585 return p;
16586}
16587
11c1ff18
PB
16588/* ARM EABI attributes section. */
16589typedef struct
16590{
70e99720 16591 unsigned int tag;
2cf0635d 16592 const char * name;
11c1ff18 16593 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16594 unsigned int type;
288f0ba2 16595 const char *const *table;
11c1ff18
PB
16596} arm_attr_public_tag;
16597
288f0ba2 16598static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16599 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16600 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16601 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16602 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16603static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16604static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16605 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16606static const char *const arm_attr_tag_FP_arch[] =
bca38921 16607 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16608 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16609static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16610static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16611 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16612 "NEON for ARMv8.1"};
288f0ba2 16613static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16614 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16615 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16616static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16617 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16618static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16619 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16620static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16621 {"Absolute", "PC-relative", "None"};
288f0ba2 16622static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16623 {"None", "direct", "GOT-indirect"};
288f0ba2 16624static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16625 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16626static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16627static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16628 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16629static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16630static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16631static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16632 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16633static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16634 {"Unused", "small", "int", "forced to int"};
288f0ba2 16635static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16636 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16637static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16638 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16639static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16640 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16641static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16642 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16643 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16644static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16645 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16646 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16647static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16648static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16649 {"Not Allowed", "Allowed"};
288f0ba2 16650static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16651 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16652static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16653 {"Follow architecture", "Allowed"};
288f0ba2 16654static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16655 {"Not Allowed", "Allowed"};
288f0ba2 16656static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16657 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16658 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16659static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16660static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16661 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16662 "TrustZone and Virtualization Extensions"};
288f0ba2 16663static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16664 {"Not Allowed", "Allowed"};
11c1ff18 16665
288f0ba2 16666static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16667 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16668
99db83d0
AC
16669static const char * arm_attr_tag_PAC_extension[] =
16670 {"No PAC/AUT instructions",
16671 "PAC/AUT instructions permitted in the NOP space",
16672 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16673
4b535030
AC
16674static const char * arm_attr_tag_BTI_extension[] =
16675 {"BTI instructions not permitted",
16676 "BTI instructions permitted in the NOP space",
16677 "BTI instructions permitted in the NOP and in the non-NOP space"};
16678
b81ee92f
AC
16679static const char * arm_attr_tag_BTI_use[] =
16680 {"Compiled without branch target enforcement",
16681 "Compiled with branch target enforcement"};
16682
c9fed665
AC
16683static const char * arm_attr_tag_PACRET_use[] =
16684 {"Compiled without return address signing and authentication",
16685 "Compiled with return address signing and authentication"};
16686
11c1ff18
PB
16687#define LOOKUP(id, name) \
16688 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16689static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16690{
16691 {4, "CPU_raw_name", 1, NULL},
16692 {5, "CPU_name", 1, NULL},
16693 LOOKUP(6, CPU_arch),
16694 {7, "CPU_arch_profile", 0, NULL},
16695 LOOKUP(8, ARM_ISA_use),
16696 LOOKUP(9, THUMB_ISA_use),
75375b3e 16697 LOOKUP(10, FP_arch),
11c1ff18 16698 LOOKUP(11, WMMX_arch),
f5f53991
AS
16699 LOOKUP(12, Advanced_SIMD_arch),
16700 LOOKUP(13, PCS_config),
11c1ff18
PB
16701 LOOKUP(14, ABI_PCS_R9_use),
16702 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16703 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16704 LOOKUP(17, ABI_PCS_GOT_use),
16705 LOOKUP(18, ABI_PCS_wchar_t),
16706 LOOKUP(19, ABI_FP_rounding),
16707 LOOKUP(20, ABI_FP_denormal),
16708 LOOKUP(21, ABI_FP_exceptions),
16709 LOOKUP(22, ABI_FP_user_exceptions),
16710 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16711 {24, "ABI_align_needed", 0, NULL},
16712 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16713 LOOKUP(26, ABI_enum_size),
16714 LOOKUP(27, ABI_HardFP_use),
16715 LOOKUP(28, ABI_VFP_args),
16716 LOOKUP(29, ABI_WMMX_args),
16717 LOOKUP(30, ABI_optimization_goals),
16718 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16719 {32, "compatibility", 0, NULL},
f5f53991 16720 LOOKUP(34, CPU_unaligned_access),
75375b3e 16721 LOOKUP(36, FP_HP_extension),
8e79c3df 16722 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16723 LOOKUP(42, MPextension_use),
16724 LOOKUP(44, DIV_use),
15afaa63 16725 LOOKUP(46, DSP_extension),
a7ad558c 16726 LOOKUP(48, MVE_arch),
99db83d0 16727 LOOKUP(50, PAC_extension),
4b535030 16728 LOOKUP(52, BTI_extension),
b81ee92f 16729 LOOKUP(74, BTI_use),
c9fed665 16730 LOOKUP(76, PACRET_use),
f5f53991
AS
16731 {64, "nodefaults", 0, NULL},
16732 {65, "also_compatible_with", 0, NULL},
16733 LOOKUP(66, T2EE_use),
16734 {67, "conformance", 1, NULL},
16735 LOOKUP(68, Virtualization_use),
cd21e546 16736 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16737};
16738#undef LOOKUP
16739
11c1ff18 16740static unsigned char *
f6f0e17b
NC
16741display_arm_attribute (unsigned char * p,
16742 const unsigned char * const end)
11c1ff18 16743{
70e99720 16744 unsigned int tag;
70e99720 16745 unsigned int val;
2cf0635d 16746 arm_attr_public_tag * attr;
11c1ff18 16747 unsigned i;
70e99720 16748 unsigned int type;
11c1ff18 16749
cd30bcef 16750 READ_ULEB (tag, p, end);
11c1ff18 16751 attr = NULL;
2cf0635d 16752 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16753 {
16754 if (arm_attr_public_tags[i].tag == tag)
16755 {
16756 attr = &arm_attr_public_tags[i];
16757 break;
16758 }
16759 }
16760
16761 if (attr)
16762 {
16763 printf (" Tag_%s: ", attr->name);
16764 switch (attr->type)
16765 {
16766 case 0:
16767 switch (tag)
16768 {
16769 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16770 READ_ULEB (val, p, end);
11c1ff18
PB
16771 switch (val)
16772 {
2b692964
NC
16773 case 0: printf (_("None\n")); break;
16774 case 'A': printf (_("Application\n")); break;
16775 case 'R': printf (_("Realtime\n")); break;
16776 case 'M': printf (_("Microcontroller\n")); break;
16777 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16778 default: printf ("??? (%d)\n", val); break;
16779 }
16780 break;
16781
75375b3e 16782 case 24: /* Tag_align_needed. */
cd30bcef 16783 READ_ULEB (val, p, end);
75375b3e
MGD
16784 switch (val)
16785 {
2b692964
NC
16786 case 0: printf (_("None\n")); break;
16787 case 1: printf (_("8-byte\n")); break;
16788 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16789 case 3: printf ("??? 3\n"); break;
16790 default:
16791 if (val <= 12)
dd24e3da 16792 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16793 1 << val);
16794 else
16795 printf ("??? (%d)\n", val);
16796 break;
16797 }
16798 break;
16799
16800 case 25: /* Tag_align_preserved. */
cd30bcef 16801 READ_ULEB (val, p, end);
75375b3e
MGD
16802 switch (val)
16803 {
2b692964
NC
16804 case 0: printf (_("None\n")); break;
16805 case 1: printf (_("8-byte, except leaf SP\n")); break;
16806 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16807 case 3: printf ("??? 3\n"); break;
16808 default:
16809 if (val <= 12)
dd24e3da 16810 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16811 1 << val);
16812 else
16813 printf ("??? (%d)\n", val);
16814 break;
16815 }
16816 break;
16817
11c1ff18 16818 case 32: /* Tag_compatibility. */
071436c6 16819 {
cd30bcef 16820 READ_ULEB (val, p, end);
071436c6 16821 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16822 if (p < end - 1)
16823 {
16824 size_t maxlen = (end - p) - 1;
16825
16826 print_symbol ((int) maxlen, (const char *) p);
16827 p += strnlen ((char *) p, maxlen) + 1;
16828 }
16829 else
16830 {
16831 printf (_("<corrupt>"));
16832 p = (unsigned char *) end;
16833 }
071436c6 16834 putchar ('\n');
071436c6 16835 }
11c1ff18
PB
16836 break;
16837
f5f53991 16838 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16839 /* PR 17531: file: 001-505008-0.01. */
16840 if (p < end)
16841 p++;
2b692964 16842 printf (_("True\n"));
f5f53991
AS
16843 break;
16844
16845 case 65: /* Tag_also_compatible_with. */
cd30bcef 16846 READ_ULEB (val, p, end);
f5f53991
AS
16847 if (val == 6 /* Tag_CPU_arch. */)
16848 {
cd30bcef 16849 READ_ULEB (val, p, end);
071436c6 16850 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16851 printf ("??? (%d)\n", val);
16852 else
16853 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16854 }
16855 else
16856 printf ("???\n");
071436c6
NC
16857 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16858 ;
f5f53991
AS
16859 break;
16860
11c1ff18 16861 default:
bee0ee85
NC
16862 printf (_("<unknown: %d>\n"), tag);
16863 break;
11c1ff18
PB
16864 }
16865 return p;
16866
16867 case 1:
f6f0e17b 16868 return display_tag_value (-1, p, end);
11c1ff18 16869 case 2:
f6f0e17b 16870 return display_tag_value (0, p, end);
11c1ff18
PB
16871
16872 default:
16873 assert (attr->type & 0x80);
cd30bcef 16874 READ_ULEB (val, p, end);
11c1ff18
PB
16875 type = attr->type & 0x7f;
16876 if (val >= type)
16877 printf ("??? (%d)\n", val);
16878 else
16879 printf ("%s\n", attr->table[val]);
16880 return p;
16881 }
16882 }
11c1ff18 16883
f6f0e17b 16884 return display_tag_value (tag, p, end);
11c1ff18
PB
16885}
16886
104d59d1 16887static unsigned char *
60bca95a 16888display_gnu_attribute (unsigned char * p,
60abdbed 16889 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16890 const unsigned char * const end)
104d59d1 16891{
cd30bcef 16892 unsigned int tag;
60abdbed 16893 unsigned int val;
104d59d1 16894
cd30bcef 16895 READ_ULEB (tag, p, end);
104d59d1
JM
16896
16897 /* Tag_compatibility is the only generic GNU attribute defined at
16898 present. */
16899 if (tag == 32)
16900 {
cd30bcef 16901 READ_ULEB (val, p, end);
071436c6
NC
16902
16903 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16904 if (p == end)
16905 {
071436c6 16906 printf (_("<corrupt>\n"));
f6f0e17b
NC
16907 warn (_("corrupt vendor attribute\n"));
16908 }
16909 else
16910 {
4082ef84
NC
16911 if (p < end - 1)
16912 {
16913 size_t maxlen = (end - p) - 1;
071436c6 16914
4082ef84
NC
16915 print_symbol ((int) maxlen, (const char *) p);
16916 p += strnlen ((char *) p, maxlen) + 1;
16917 }
16918 else
16919 {
16920 printf (_("<corrupt>"));
16921 p = (unsigned char *) end;
16922 }
071436c6 16923 putchar ('\n');
f6f0e17b 16924 }
104d59d1
JM
16925 return p;
16926 }
16927
16928 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16929 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16930
f6f0e17b 16931 return display_tag_value (tag, p, end);
104d59d1
JM
16932}
16933
85f7484a
PB
16934static unsigned char *
16935display_m68k_gnu_attribute (unsigned char * p,
16936 unsigned int tag,
16937 const unsigned char * const end)
16938{
16939 unsigned int val;
16940
16941 if (tag == Tag_GNU_M68K_ABI_FP)
16942 {
16943 printf (" Tag_GNU_M68K_ABI_FP: ");
16944 if (p == end)
16945 {
16946 printf (_("<corrupt>\n"));
16947 return p;
16948 }
16949 READ_ULEB (val, p, end);
16950
16951 if (val > 3)
16952 printf ("(%#x), ", val);
16953
16954 switch (val & 3)
16955 {
16956 case 0:
16957 printf (_("unspecified hard/soft float\n"));
16958 break;
16959 case 1:
16960 printf (_("hard float\n"));
16961 break;
16962 case 2:
16963 printf (_("soft float\n"));
16964 break;
16965 }
16966 return p;
16967 }
16968
16969 return display_tag_value (tag & 1, p, end);
16970}
16971
34c8bcba 16972static unsigned char *
f6f0e17b 16973display_power_gnu_attribute (unsigned char * p,
60abdbed 16974 unsigned int tag,
f6f0e17b 16975 const unsigned char * const end)
34c8bcba 16976{
005d79fd 16977 unsigned int val;
34c8bcba
JM
16978
16979 if (tag == Tag_GNU_Power_ABI_FP)
16980 {
34c8bcba 16981 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16982 if (p == end)
005d79fd
AM
16983 {
16984 printf (_("<corrupt>\n"));
16985 return p;
16986 }
cd30bcef 16987 READ_ULEB (val, p, end);
60bca95a 16988
005d79fd
AM
16989 if (val > 15)
16990 printf ("(%#x), ", val);
16991
16992 switch (val & 3)
34c8bcba
JM
16993 {
16994 case 0:
005d79fd 16995 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16996 break;
16997 case 1:
005d79fd 16998 printf (_("hard float, "));
34c8bcba
JM
16999 break;
17000 case 2:
005d79fd 17001 printf (_("soft float, "));
34c8bcba 17002 break;
3c7b9897 17003 case 3:
005d79fd 17004 printf (_("single-precision hard float, "));
3c7b9897 17005 break;
005d79fd
AM
17006 }
17007
17008 switch (val & 0xC)
17009 {
17010 case 0:
17011 printf (_("unspecified long double\n"));
17012 break;
17013 case 4:
17014 printf (_("128-bit IBM long double\n"));
17015 break;
17016 case 8:
17017 printf (_("64-bit long double\n"));
17018 break;
17019 case 12:
17020 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17021 break;
17022 }
17023 return p;
005d79fd 17024 }
34c8bcba 17025
c6e65352
DJ
17026 if (tag == Tag_GNU_Power_ABI_Vector)
17027 {
c6e65352 17028 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17029 if (p == end)
005d79fd
AM
17030 {
17031 printf (_("<corrupt>\n"));
17032 return p;
17033 }
cd30bcef 17034 READ_ULEB (val, p, end);
005d79fd
AM
17035
17036 if (val > 3)
17037 printf ("(%#x), ", val);
17038
17039 switch (val & 3)
c6e65352
DJ
17040 {
17041 case 0:
005d79fd 17042 printf (_("unspecified\n"));
c6e65352
DJ
17043 break;
17044 case 1:
005d79fd 17045 printf (_("generic\n"));
c6e65352
DJ
17046 break;
17047 case 2:
17048 printf ("AltiVec\n");
17049 break;
17050 case 3:
17051 printf ("SPE\n");
17052 break;
c6e65352
DJ
17053 }
17054 return p;
005d79fd 17055 }
c6e65352 17056
f82e0623
NF
17057 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17058 {
005d79fd 17059 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17060 if (p == end)
f6f0e17b 17061 {
005d79fd 17062 printf (_("<corrupt>\n"));
f6f0e17b
NC
17063 return p;
17064 }
cd30bcef 17065 READ_ULEB (val, p, end);
0b4362b0 17066
005d79fd
AM
17067 if (val > 2)
17068 printf ("(%#x), ", val);
17069
17070 switch (val & 3)
17071 {
17072 case 0:
17073 printf (_("unspecified\n"));
17074 break;
17075 case 1:
17076 printf ("r3/r4\n");
17077 break;
17078 case 2:
17079 printf (_("memory\n"));
17080 break;
17081 case 3:
17082 printf ("???\n");
17083 break;
17084 }
f82e0623
NF
17085 return p;
17086 }
17087
f6f0e17b 17088 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17089}
17090
643f7afb
AK
17091static unsigned char *
17092display_s390_gnu_attribute (unsigned char * p,
60abdbed 17093 unsigned int tag,
643f7afb
AK
17094 const unsigned char * const end)
17095{
cd30bcef 17096 unsigned int val;
643f7afb
AK
17097
17098 if (tag == Tag_GNU_S390_ABI_Vector)
17099 {
643f7afb 17100 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17101 READ_ULEB (val, p, end);
643f7afb
AK
17102
17103 switch (val)
17104 {
17105 case 0:
17106 printf (_("any\n"));
17107 break;
17108 case 1:
17109 printf (_("software\n"));
17110 break;
17111 case 2:
17112 printf (_("hardware\n"));
17113 break;
17114 default:
17115 printf ("??? (%d)\n", val);
17116 break;
17117 }
17118 return p;
17119 }
17120
17121 return display_tag_value (tag & 1, p, end);
17122}
17123
9e8c70f9 17124static void
60abdbed 17125display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17126{
17127 if (mask)
17128 {
015dc7e1 17129 bool first = true;
071436c6 17130
9e8c70f9 17131 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17132 fputs ("mul32", stdout), first = false;
9e8c70f9 17133 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17134 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17135 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17136 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17137 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17138 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17139 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17140 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17141 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17142 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17143 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17144 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17145 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17146 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17147 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17148 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17149 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17150 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17151 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17152 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17153 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17154 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17155 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17156 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17157 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17158 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17159 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17160 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17161 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17162 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17163 }
17164 else
071436c6
NC
17165 fputc ('0', stdout);
17166 fputc ('\n', stdout);
9e8c70f9
DM
17167}
17168
3d68f91c 17169static void
60abdbed 17170display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17171{
17172 if (mask)
17173 {
015dc7e1 17174 bool first = true;
071436c6 17175
3d68f91c 17176 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17177 fputs ("fjathplus", stdout), first = false;
3d68f91c 17178 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17179 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17180 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17181 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17182 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17183 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17184 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17185 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17186 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17187 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17188 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17189 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17190 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17191 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17192 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17193 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17194 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17195 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17196 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17197 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17198 }
17199 else
071436c6
NC
17200 fputc ('0', stdout);
17201 fputc ('\n', stdout);
3d68f91c
JM
17202}
17203
9e8c70f9 17204static unsigned char *
f6f0e17b 17205display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17206 unsigned int tag,
f6f0e17b 17207 const unsigned char * const end)
9e8c70f9 17208{
cd30bcef 17209 unsigned int val;
3d68f91c 17210
9e8c70f9
DM
17211 if (tag == Tag_GNU_Sparc_HWCAPS)
17212 {
cd30bcef 17213 READ_ULEB (val, p, end);
9e8c70f9 17214 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17215 display_sparc_hwcaps (val);
17216 return p;
3d68f91c
JM
17217 }
17218 if (tag == Tag_GNU_Sparc_HWCAPS2)
17219 {
cd30bcef 17220 READ_ULEB (val, p, end);
3d68f91c
JM
17221 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17222 display_sparc_hwcaps2 (val);
17223 return p;
17224 }
9e8c70f9 17225
f6f0e17b 17226 return display_tag_value (tag, p, end);
9e8c70f9
DM
17227}
17228
351cdf24 17229static void
32ec8896 17230print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17231{
17232 switch (val)
17233 {
17234 case Val_GNU_MIPS_ABI_FP_ANY:
17235 printf (_("Hard or soft float\n"));
17236 break;
17237 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17238 printf (_("Hard float (double precision)\n"));
17239 break;
17240 case Val_GNU_MIPS_ABI_FP_SINGLE:
17241 printf (_("Hard float (single precision)\n"));
17242 break;
17243 case Val_GNU_MIPS_ABI_FP_SOFT:
17244 printf (_("Soft float\n"));
17245 break;
17246 case Val_GNU_MIPS_ABI_FP_OLD_64:
17247 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17248 break;
17249 case Val_GNU_MIPS_ABI_FP_XX:
17250 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17251 break;
17252 case Val_GNU_MIPS_ABI_FP_64:
17253 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17254 break;
17255 case Val_GNU_MIPS_ABI_FP_64A:
17256 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17257 break;
3350cc01
CM
17258 case Val_GNU_MIPS_ABI_FP_NAN2008:
17259 printf (_("NaN 2008 compatibility\n"));
17260 break;
351cdf24
MF
17261 default:
17262 printf ("??? (%d)\n", val);
17263 break;
17264 }
17265}
17266
2cf19d5c 17267static unsigned char *
f6f0e17b 17268display_mips_gnu_attribute (unsigned char * p,
60abdbed 17269 unsigned int tag,
f6f0e17b 17270 const unsigned char * const end)
2cf19d5c 17271{
2cf19d5c
JM
17272 if (tag == Tag_GNU_MIPS_ABI_FP)
17273 {
32ec8896 17274 unsigned int val;
f6f0e17b 17275
2cf19d5c 17276 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17277 READ_ULEB (val, p, end);
351cdf24 17278 print_mips_fp_abi_value (val);
2cf19d5c
JM
17279 return p;
17280 }
17281
a9f58168
CF
17282 if (tag == Tag_GNU_MIPS_ABI_MSA)
17283 {
32ec8896 17284 unsigned int val;
a9f58168 17285
a9f58168 17286 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17287 READ_ULEB (val, p, end);
a9f58168
CF
17288
17289 switch (val)
17290 {
17291 case Val_GNU_MIPS_ABI_MSA_ANY:
17292 printf (_("Any MSA or not\n"));
17293 break;
17294 case Val_GNU_MIPS_ABI_MSA_128:
17295 printf (_("128-bit MSA\n"));
17296 break;
17297 default:
17298 printf ("??? (%d)\n", val);
17299 break;
17300 }
17301 return p;
17302 }
17303
f6f0e17b 17304 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17305}
17306
59e6276b 17307static unsigned char *
f6f0e17b
NC
17308display_tic6x_attribute (unsigned char * p,
17309 const unsigned char * const end)
59e6276b 17310{
60abdbed 17311 unsigned int tag;
cd30bcef 17312 unsigned int val;
59e6276b 17313
cd30bcef 17314 READ_ULEB (tag, p, end);
59e6276b
JM
17315
17316 switch (tag)
17317 {
75fa6dc1 17318 case Tag_ISA:
75fa6dc1 17319 printf (" Tag_ISA: ");
cd30bcef 17320 READ_ULEB (val, p, end);
59e6276b
JM
17321
17322 switch (val)
17323 {
75fa6dc1 17324 case C6XABI_Tag_ISA_none:
59e6276b
JM
17325 printf (_("None\n"));
17326 break;
75fa6dc1 17327 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17328 printf ("C62x\n");
17329 break;
75fa6dc1 17330 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17331 printf ("C67x\n");
17332 break;
75fa6dc1 17333 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17334 printf ("C67x+\n");
17335 break;
75fa6dc1 17336 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17337 printf ("C64x\n");
17338 break;
75fa6dc1 17339 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17340 printf ("C64x+\n");
17341 break;
75fa6dc1 17342 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17343 printf ("C674x\n");
17344 break;
17345 default:
17346 printf ("??? (%d)\n", val);
17347 break;
17348 }
17349 return p;
17350
87779176 17351 case Tag_ABI_wchar_t:
87779176 17352 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17353 READ_ULEB (val, p, end);
87779176
JM
17354 switch (val)
17355 {
17356 case 0:
17357 printf (_("Not used\n"));
17358 break;
17359 case 1:
17360 printf (_("2 bytes\n"));
17361 break;
17362 case 2:
17363 printf (_("4 bytes\n"));
17364 break;
17365 default:
17366 printf ("??? (%d)\n", val);
17367 break;
17368 }
17369 return p;
17370
17371 case Tag_ABI_stack_align_needed:
87779176 17372 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17373 READ_ULEB (val, p, end);
87779176
JM
17374 switch (val)
17375 {
17376 case 0:
17377 printf (_("8-byte\n"));
17378 break;
17379 case 1:
17380 printf (_("16-byte\n"));
17381 break;
17382 default:
17383 printf ("??? (%d)\n", val);
17384 break;
17385 }
17386 return p;
17387
17388 case Tag_ABI_stack_align_preserved:
cd30bcef 17389 READ_ULEB (val, p, end);
87779176
JM
17390 printf (" Tag_ABI_stack_align_preserved: ");
17391 switch (val)
17392 {
17393 case 0:
17394 printf (_("8-byte\n"));
17395 break;
17396 case 1:
17397 printf (_("16-byte\n"));
17398 break;
17399 default:
17400 printf ("??? (%d)\n", val);
17401 break;
17402 }
17403 return p;
17404
b5593623 17405 case Tag_ABI_DSBT:
cd30bcef 17406 READ_ULEB (val, p, end);
b5593623
JM
17407 printf (" Tag_ABI_DSBT: ");
17408 switch (val)
17409 {
17410 case 0:
17411 printf (_("DSBT addressing not used\n"));
17412 break;
17413 case 1:
17414 printf (_("DSBT addressing used\n"));
17415 break;
17416 default:
17417 printf ("??? (%d)\n", val);
17418 break;
17419 }
17420 return p;
17421
87779176 17422 case Tag_ABI_PID:
cd30bcef 17423 READ_ULEB (val, p, end);
87779176
JM
17424 printf (" Tag_ABI_PID: ");
17425 switch (val)
17426 {
17427 case 0:
17428 printf (_("Data addressing position-dependent\n"));
17429 break;
17430 case 1:
17431 printf (_("Data addressing position-independent, GOT near DP\n"));
17432 break;
17433 case 2:
17434 printf (_("Data addressing position-independent, GOT far from DP\n"));
17435 break;
17436 default:
17437 printf ("??? (%d)\n", val);
17438 break;
17439 }
17440 return p;
17441
17442 case Tag_ABI_PIC:
cd30bcef 17443 READ_ULEB (val, p, end);
87779176
JM
17444 printf (" Tag_ABI_PIC: ");
17445 switch (val)
17446 {
17447 case 0:
17448 printf (_("Code addressing position-dependent\n"));
17449 break;
17450 case 1:
17451 printf (_("Code addressing position-independent\n"));
17452 break;
17453 default:
17454 printf ("??? (%d)\n", val);
17455 break;
17456 }
17457 return p;
17458
17459 case Tag_ABI_array_object_alignment:
cd30bcef 17460 READ_ULEB (val, p, end);
87779176
JM
17461 printf (" Tag_ABI_array_object_alignment: ");
17462 switch (val)
17463 {
17464 case 0:
17465 printf (_("8-byte\n"));
17466 break;
17467 case 1:
17468 printf (_("4-byte\n"));
17469 break;
17470 case 2:
17471 printf (_("16-byte\n"));
17472 break;
17473 default:
17474 printf ("??? (%d)\n", val);
17475 break;
17476 }
17477 return p;
17478
17479 case Tag_ABI_array_object_align_expected:
cd30bcef 17480 READ_ULEB (val, p, end);
87779176
JM
17481 printf (" Tag_ABI_array_object_align_expected: ");
17482 switch (val)
17483 {
17484 case 0:
17485 printf (_("8-byte\n"));
17486 break;
17487 case 1:
17488 printf (_("4-byte\n"));
17489 break;
17490 case 2:
17491 printf (_("16-byte\n"));
17492 break;
17493 default:
17494 printf ("??? (%d)\n", val);
17495 break;
17496 }
17497 return p;
17498
3cbd1c06 17499 case Tag_ABI_compatibility:
071436c6 17500 {
cd30bcef 17501 READ_ULEB (val, p, end);
071436c6 17502 printf (" Tag_ABI_compatibility: ");
071436c6 17503 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17504 if (p < end - 1)
17505 {
17506 size_t maxlen = (end - p) - 1;
17507
17508 print_symbol ((int) maxlen, (const char *) p);
17509 p += strnlen ((char *) p, maxlen) + 1;
17510 }
17511 else
17512 {
17513 printf (_("<corrupt>"));
17514 p = (unsigned char *) end;
17515 }
071436c6 17516 putchar ('\n');
071436c6
NC
17517 return p;
17518 }
87779176
JM
17519
17520 case Tag_ABI_conformance:
071436c6 17521 {
4082ef84
NC
17522 printf (" Tag_ABI_conformance: \"");
17523 if (p < end - 1)
17524 {
17525 size_t maxlen = (end - p) - 1;
071436c6 17526
4082ef84
NC
17527 print_symbol ((int) maxlen, (const char *) p);
17528 p += strnlen ((char *) p, maxlen) + 1;
17529 }
17530 else
17531 {
17532 printf (_("<corrupt>"));
17533 p = (unsigned char *) end;
17534 }
071436c6 17535 printf ("\"\n");
071436c6
NC
17536 return p;
17537 }
59e6276b
JM
17538 }
17539
f6f0e17b
NC
17540 return display_tag_value (tag, p, end);
17541}
59e6276b 17542
f6f0e17b 17543static void
60abdbed 17544display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17545{
17546 unsigned long addr = 0;
17547 size_t bytes = end - p;
17548
feceaa59 17549 assert (end >= p);
f6f0e17b 17550 while (bytes)
87779176 17551 {
f6f0e17b
NC
17552 int j;
17553 int k;
17554 int lbytes = (bytes > 16 ? 16 : bytes);
17555
17556 printf (" 0x%8.8lx ", addr);
17557
17558 for (j = 0; j < 16; j++)
17559 {
17560 if (j < lbytes)
17561 printf ("%2.2x", p[j]);
17562 else
17563 printf (" ");
17564
17565 if ((j & 3) == 3)
17566 printf (" ");
17567 }
17568
17569 for (j = 0; j < lbytes; j++)
17570 {
17571 k = p[j];
17572 if (k >= ' ' && k < 0x7f)
17573 printf ("%c", k);
17574 else
17575 printf (".");
17576 }
17577
17578 putchar ('\n');
17579
17580 p += lbytes;
17581 bytes -= lbytes;
17582 addr += lbytes;
87779176 17583 }
59e6276b 17584
f6f0e17b 17585 putchar ('\n');
59e6276b
JM
17586}
17587
13761a11 17588static unsigned char *
b0191216 17589display_msp430_attribute (unsigned char * p,
13761a11
NC
17590 const unsigned char * const end)
17591{
60abdbed
NC
17592 unsigned int val;
17593 unsigned int tag;
13761a11 17594
cd30bcef 17595 READ_ULEB (tag, p, end);
0b4362b0 17596
13761a11
NC
17597 switch (tag)
17598 {
17599 case OFBA_MSPABI_Tag_ISA:
13761a11 17600 printf (" Tag_ISA: ");
cd30bcef 17601 READ_ULEB (val, p, end);
13761a11
NC
17602 switch (val)
17603 {
17604 case 0: printf (_("None\n")); break;
17605 case 1: printf (_("MSP430\n")); break;
17606 case 2: printf (_("MSP430X\n")); break;
17607 default: printf ("??? (%d)\n", val); break;
17608 }
17609 break;
17610
17611 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17612 printf (" Tag_Code_Model: ");
cd30bcef 17613 READ_ULEB (val, p, end);
13761a11
NC
17614 switch (val)
17615 {
17616 case 0: printf (_("None\n")); break;
17617 case 1: printf (_("Small\n")); break;
17618 case 2: printf (_("Large\n")); break;
17619 default: printf ("??? (%d)\n", val); break;
17620 }
17621 break;
17622
17623 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17624 printf (" Tag_Data_Model: ");
cd30bcef 17625 READ_ULEB (val, p, end);
13761a11
NC
17626 switch (val)
17627 {
17628 case 0: printf (_("None\n")); break;
17629 case 1: printf (_("Small\n")); break;
17630 case 2: printf (_("Large\n")); break;
17631 case 3: printf (_("Restricted Large\n")); break;
17632 default: printf ("??? (%d)\n", val); break;
17633 }
17634 break;
17635
17636 default:
17637 printf (_(" <unknown tag %d>: "), tag);
17638
17639 if (tag & 1)
17640 {
071436c6 17641 putchar ('"');
4082ef84
NC
17642 if (p < end - 1)
17643 {
17644 size_t maxlen = (end - p) - 1;
17645
17646 print_symbol ((int) maxlen, (const char *) p);
17647 p += strnlen ((char *) p, maxlen) + 1;
17648 }
17649 else
17650 {
17651 printf (_("<corrupt>"));
17652 p = (unsigned char *) end;
17653 }
071436c6 17654 printf ("\"\n");
13761a11
NC
17655 }
17656 else
17657 {
cd30bcef 17658 READ_ULEB (val, p, end);
13761a11
NC
17659 printf ("%d (0x%x)\n", val, val);
17660 }
17661 break;
17662 }
17663
4082ef84 17664 assert (p <= end);
13761a11
NC
17665 return p;
17666}
17667
c0ea7c52
JL
17668static unsigned char *
17669display_msp430_gnu_attribute (unsigned char * p,
17670 unsigned int tag,
17671 const unsigned char * const end)
17672{
17673 if (tag == Tag_GNU_MSP430_Data_Region)
17674 {
cd30bcef 17675 unsigned int val;
c0ea7c52 17676
c0ea7c52 17677 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17678 READ_ULEB (val, p, end);
c0ea7c52
JL
17679
17680 switch (val)
17681 {
17682 case Val_GNU_MSP430_Data_Region_Any:
17683 printf (_("Any Region\n"));
17684 break;
17685 case Val_GNU_MSP430_Data_Region_Lower:
17686 printf (_("Lower Region Only\n"));
17687 break;
17688 default:
cd30bcef 17689 printf ("??? (%u)\n", val);
c0ea7c52
JL
17690 }
17691 return p;
17692 }
17693 return display_tag_value (tag & 1, p, end);
17694}
17695
2dc8dd17
JW
17696struct riscv_attr_tag_t {
17697 const char *name;
cd30bcef 17698 unsigned int tag;
2dc8dd17
JW
17699};
17700
17701static struct riscv_attr_tag_t riscv_attr_tag[] =
17702{
17703#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17704 T(arch),
17705 T(priv_spec),
17706 T(priv_spec_minor),
17707 T(priv_spec_revision),
17708 T(unaligned_access),
17709 T(stack_align),
17710#undef T
17711};
17712
17713static unsigned char *
17714display_riscv_attribute (unsigned char *p,
17715 const unsigned char * const end)
17716{
cd30bcef
AM
17717 unsigned int val;
17718 unsigned int tag;
2dc8dd17
JW
17719 struct riscv_attr_tag_t *attr = NULL;
17720 unsigned i;
17721
cd30bcef 17722 READ_ULEB (tag, p, end);
2dc8dd17
JW
17723
17724 /* Find the name of attribute. */
17725 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17726 {
17727 if (riscv_attr_tag[i].tag == tag)
17728 {
17729 attr = &riscv_attr_tag[i];
17730 break;
17731 }
17732 }
17733
17734 if (attr)
17735 printf (" %s: ", attr->name);
17736 else
17737 return display_tag_value (tag, p, end);
17738
17739 switch (tag)
17740 {
17741 case Tag_RISCV_priv_spec:
17742 case Tag_RISCV_priv_spec_minor:
17743 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17744 READ_ULEB (val, p, end);
17745 printf (_("%u\n"), val);
2dc8dd17
JW
17746 break;
17747 case Tag_RISCV_unaligned_access:
cd30bcef 17748 READ_ULEB (val, p, end);
2dc8dd17
JW
17749 switch (val)
17750 {
17751 case 0:
17752 printf (_("No unaligned access\n"));
17753 break;
17754 case 1:
17755 printf (_("Unaligned access\n"));
17756 break;
17757 }
17758 break;
17759 case Tag_RISCV_stack_align:
cd30bcef
AM
17760 READ_ULEB (val, p, end);
17761 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17762 break;
17763 case Tag_RISCV_arch:
17764 p = display_tag_value (-1, p, end);
17765 break;
17766 default:
17767 return display_tag_value (tag, p, end);
17768 }
17769
17770 return p;
17771}
17772
0861f561
CQ
17773static unsigned char *
17774display_csky_attribute (unsigned char * p,
17775 const unsigned char * const end)
17776{
17777 unsigned int tag;
17778 unsigned int val;
17779 READ_ULEB (tag, p, end);
17780
17781 if (tag >= Tag_CSKY_MAX)
17782 {
17783 return display_tag_value (-1, p, end);
17784 }
17785
17786 switch (tag)
17787 {
17788 case Tag_CSKY_ARCH_NAME:
17789 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17790 return display_tag_value (-1, p, end);
17791 case Tag_CSKY_CPU_NAME:
17792 printf (" Tag_CSKY_CPU_NAME:\t\t");
17793 return display_tag_value (-1, p, end);
17794
17795 case Tag_CSKY_ISA_FLAGS:
17796 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17797 return display_tag_value (0, p, end);
17798 case Tag_CSKY_ISA_EXT_FLAGS:
17799 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17800 return display_tag_value (0, p, end);
17801
17802 case Tag_CSKY_DSP_VERSION:
17803 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17804 READ_ULEB (val, p, end);
17805 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17806 printf ("DSP Extension\n");
17807 else if (val == VAL_CSKY_DSP_VERSION_2)
17808 printf ("DSP 2.0\n");
17809 break;
17810
17811 case Tag_CSKY_VDSP_VERSION:
17812 printf (" Tag_CSKY_VDSP_VERSION:\t");
17813 READ_ULEB (val, p, end);
17814 printf ("VDSP Version %d\n", val);
17815 break;
17816
17817 case Tag_CSKY_FPU_VERSION:
17818 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17819 READ_ULEB (val, p, end);
17820 if (val == VAL_CSKY_FPU_VERSION_1)
17821 printf ("ABIV1 FPU Version 1\n");
17822 else if (val == VAL_CSKY_FPU_VERSION_2)
17823 printf ("FPU Version 2\n");
17824 break;
17825
17826 case Tag_CSKY_FPU_ABI:
17827 printf (" Tag_CSKY_FPU_ABI:\t\t");
17828 READ_ULEB (val, p, end);
17829 if (val == VAL_CSKY_FPU_ABI_HARD)
17830 printf ("Hard\n");
17831 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17832 printf ("SoftFP\n");
17833 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17834 printf ("Soft\n");
17835 break;
17836 case Tag_CSKY_FPU_ROUNDING:
17837 READ_ULEB (val, p, end);
f253158f
NC
17838 if (val == 1)
17839 {
17840 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17841 printf ("Needed\n");
17842 }
0861f561
CQ
17843 break;
17844 case Tag_CSKY_FPU_DENORMAL:
17845 READ_ULEB (val, p, end);
f253158f
NC
17846 if (val == 1)
17847 {
17848 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17849 printf ("Needed\n");
17850 }
0861f561
CQ
17851 break;
17852 case Tag_CSKY_FPU_Exception:
17853 READ_ULEB (val, p, end);
f253158f
NC
17854 if (val == 1)
17855 {
17856 printf (" Tag_CSKY_FPU_Exception:\t");
17857 printf ("Needed\n");
17858 }
0861f561
CQ
17859 break;
17860 case Tag_CSKY_FPU_NUMBER_MODULE:
17861 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17862 return display_tag_value (-1, p, end);
17863 case Tag_CSKY_FPU_HARDFP:
17864 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17865 READ_ULEB (val, p, end);
17866 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17867 printf (" Half");
17868 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17869 printf (" Single");
17870 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17871 printf (" Double");
17872 printf ("\n");
17873 break;
17874 default:
17875 return display_tag_value (tag, p, end);
17876 }
17877 return p;
17878}
17879
015dc7e1 17880static bool
dda8d76d 17881process_attributes (Filedata * filedata,
60bca95a 17882 const char * public_name,
104d59d1 17883 unsigned int proc_type,
f6f0e17b 17884 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17885 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17886{
2cf0635d 17887 Elf_Internal_Shdr * sect;
11c1ff18 17888 unsigned i;
015dc7e1 17889 bool res = true;
11c1ff18
PB
17890
17891 /* Find the section header so that we get the size. */
dda8d76d
NC
17892 for (i = 0, sect = filedata->section_headers;
17893 i < filedata->file_header.e_shnum;
11c1ff18
PB
17894 i++, sect++)
17895 {
071436c6
NC
17896 unsigned char * contents;
17897 unsigned char * p;
17898
104d59d1 17899 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17900 continue;
17901
dda8d76d 17902 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17903 sect->sh_size, _("attributes"));
60bca95a 17904 if (contents == NULL)
32ec8896 17905 {
015dc7e1 17906 res = false;
32ec8896
NC
17907 continue;
17908 }
60bca95a 17909
11c1ff18 17910 p = contents;
60abdbed
NC
17911 /* The first character is the version of the attributes.
17912 Currently only version 1, (aka 'A') is recognised here. */
17913 if (*p != 'A')
32ec8896
NC
17914 {
17915 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17916 res = false;
32ec8896 17917 }
60abdbed 17918 else
11c1ff18 17919 {
071436c6
NC
17920 bfd_vma section_len;
17921
17922 section_len = sect->sh_size - 1;
11c1ff18 17923 p++;
60bca95a 17924
071436c6 17925 while (section_len > 0)
11c1ff18 17926 {
071436c6 17927 bfd_vma attr_len;
e9847026 17928 unsigned int namelen;
015dc7e1
AM
17929 bool public_section;
17930 bool gnu_section;
11c1ff18 17931
071436c6 17932 if (section_len <= 4)
e0a31db1
NC
17933 {
17934 error (_("Tag section ends prematurely\n"));
015dc7e1 17935 res = false;
e0a31db1
NC
17936 break;
17937 }
071436c6 17938 attr_len = byte_get (p, 4);
11c1ff18 17939 p += 4;
60bca95a 17940
071436c6 17941 if (attr_len > section_len)
11c1ff18 17942 {
071436c6
NC
17943 error (_("Bad attribute length (%u > %u)\n"),
17944 (unsigned) attr_len, (unsigned) section_len);
17945 attr_len = section_len;
015dc7e1 17946 res = false;
11c1ff18 17947 }
74e1a04b 17948 /* PR 17531: file: 001-101425-0.004 */
071436c6 17949 else if (attr_len < 5)
74e1a04b 17950 {
071436c6 17951 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17952 res = false;
74e1a04b
NC
17953 break;
17954 }
e9847026 17955
071436c6
NC
17956 section_len -= attr_len;
17957 attr_len -= 4;
17958
17959 namelen = strnlen ((char *) p, attr_len) + 1;
17960 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17961 {
17962 error (_("Corrupt attribute section name\n"));
015dc7e1 17963 res = false;
e9847026
NC
17964 break;
17965 }
17966
071436c6
NC
17967 printf (_("Attribute Section: "));
17968 print_symbol (INT_MAX, (const char *) p);
17969 putchar ('\n');
60bca95a
NC
17970
17971 if (public_name && streq ((char *) p, public_name))
015dc7e1 17972 public_section = true;
11c1ff18 17973 else
015dc7e1 17974 public_section = false;
60bca95a
NC
17975
17976 if (streq ((char *) p, "gnu"))
015dc7e1 17977 gnu_section = true;
104d59d1 17978 else
015dc7e1 17979 gnu_section = false;
60bca95a 17980
11c1ff18 17981 p += namelen;
071436c6 17982 attr_len -= namelen;
e0a31db1 17983
071436c6 17984 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17985 {
e0a31db1 17986 int tag;
cd30bcef 17987 unsigned int val;
11c1ff18 17988 bfd_vma size;
071436c6 17989 unsigned char * end;
60bca95a 17990
e0a31db1 17991 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17992 if (attr_len < 6)
e0a31db1
NC
17993 {
17994 error (_("Unused bytes at end of section\n"));
015dc7e1 17995 res = false;
e0a31db1
NC
17996 section_len = 0;
17997 break;
17998 }
17999
18000 tag = *(p++);
11c1ff18 18001 size = byte_get (p, 4);
071436c6 18002 if (size > attr_len)
11c1ff18 18003 {
e9847026 18004 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18005 (unsigned) size, (unsigned) attr_len);
015dc7e1 18006 res = false;
071436c6 18007 size = attr_len;
11c1ff18 18008 }
e0a31db1
NC
18009 /* PR binutils/17531: Safe handling of corrupt files. */
18010 if (size < 6)
18011 {
18012 error (_("Bad subsection length (%u < 6)\n"),
18013 (unsigned) size);
015dc7e1 18014 res = false;
e0a31db1
NC
18015 section_len = 0;
18016 break;
18017 }
60bca95a 18018
071436c6 18019 attr_len -= size;
11c1ff18 18020 end = p + size - 1;
071436c6 18021 assert (end <= contents + sect->sh_size);
11c1ff18 18022 p += 4;
60bca95a 18023
11c1ff18
PB
18024 switch (tag)
18025 {
18026 case 1:
2b692964 18027 printf (_("File Attributes\n"));
11c1ff18
PB
18028 break;
18029 case 2:
2b692964 18030 printf (_("Section Attributes:"));
11c1ff18
PB
18031 goto do_numlist;
18032 case 3:
2b692964 18033 printf (_("Symbol Attributes:"));
1a0670f3 18034 /* Fall through. */
11c1ff18
PB
18035 do_numlist:
18036 for (;;)
18037 {
cd30bcef 18038 READ_ULEB (val, p, end);
11c1ff18
PB
18039 if (val == 0)
18040 break;
18041 printf (" %d", val);
18042 }
18043 printf ("\n");
18044 break;
18045 default:
2b692964 18046 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18047 public_section = false;
11c1ff18
PB
18048 break;
18049 }
60bca95a 18050
071436c6 18051 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18052 {
18053 while (p < end)
f6f0e17b 18054 p = display_pub_attribute (p, end);
60abdbed 18055 assert (p == end);
104d59d1 18056 }
071436c6 18057 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18058 {
18059 while (p < end)
18060 p = display_gnu_attribute (p,
f6f0e17b
NC
18061 display_proc_gnu_attribute,
18062 end);
60abdbed 18063 assert (p == end);
11c1ff18 18064 }
071436c6 18065 else if (p < end)
11c1ff18 18066 {
071436c6 18067 printf (_(" Unknown attribute:\n"));
f6f0e17b 18068 display_raw_attribute (p, end);
11c1ff18
PB
18069 p = end;
18070 }
071436c6
NC
18071 else
18072 attr_len = 0;
11c1ff18
PB
18073 }
18074 }
18075 }
d70c5fc7 18076
60bca95a 18077 free (contents);
11c1ff18 18078 }
32ec8896
NC
18079
18080 return res;
11c1ff18
PB
18081}
18082
ccb4c951
RS
18083/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18084 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18085 and return the VMA of the next entry, or -1 if there was a problem.
18086 Does not read from DATA_END or beyond. */
ccb4c951
RS
18087
18088static bfd_vma
82b1b41b
NC
18089print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
18090 unsigned char * data_end)
ccb4c951
RS
18091{
18092 printf (" ");
18093 print_vma (addr, LONG_HEX);
18094 printf (" ");
18095 if (addr < pltgot + 0xfff0)
18096 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18097 else
18098 printf ("%10s", "");
18099 printf (" ");
18100 if (data == NULL)
2b692964 18101 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18102 else
18103 {
18104 bfd_vma entry;
82b1b41b 18105 unsigned char * from = data + addr - pltgot;
ccb4c951 18106
82b1b41b
NC
18107 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18108 {
18109 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18110 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18111 return (bfd_vma) -1;
18112 }
18113 else
18114 {
18115 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18116 print_vma (entry, LONG_HEX);
18117 }
ccb4c951
RS
18118 }
18119 return addr + (is_32bit_elf ? 4 : 8);
18120}
18121
861fb55a
DJ
18122/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18123 PLTGOT. Print the Address and Initial fields of an entry at VMA
18124 ADDR and return the VMA of the next entry. */
18125
18126static bfd_vma
2cf0635d 18127print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
18128{
18129 printf (" ");
18130 print_vma (addr, LONG_HEX);
18131 printf (" ");
18132 if (data == NULL)
2b692964 18133 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18134 else
18135 {
18136 bfd_vma entry;
18137
18138 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18139 print_vma (entry, LONG_HEX);
18140 }
18141 return addr + (is_32bit_elf ? 4 : 8);
18142}
18143
351cdf24
MF
18144static void
18145print_mips_ases (unsigned int mask)
18146{
18147 if (mask & AFL_ASE_DSP)
18148 fputs ("\n\tDSP ASE", stdout);
18149 if (mask & AFL_ASE_DSPR2)
18150 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18151 if (mask & AFL_ASE_DSPR3)
18152 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18153 if (mask & AFL_ASE_EVA)
18154 fputs ("\n\tEnhanced VA Scheme", stdout);
18155 if (mask & AFL_ASE_MCU)
18156 fputs ("\n\tMCU (MicroController) ASE", stdout);
18157 if (mask & AFL_ASE_MDMX)
18158 fputs ("\n\tMDMX ASE", stdout);
18159 if (mask & AFL_ASE_MIPS3D)
18160 fputs ("\n\tMIPS-3D ASE", stdout);
18161 if (mask & AFL_ASE_MT)
18162 fputs ("\n\tMT ASE", stdout);
18163 if (mask & AFL_ASE_SMARTMIPS)
18164 fputs ("\n\tSmartMIPS ASE", stdout);
18165 if (mask & AFL_ASE_VIRT)
18166 fputs ("\n\tVZ ASE", stdout);
18167 if (mask & AFL_ASE_MSA)
18168 fputs ("\n\tMSA ASE", stdout);
18169 if (mask & AFL_ASE_MIPS16)
18170 fputs ("\n\tMIPS16 ASE", stdout);
18171 if (mask & AFL_ASE_MICROMIPS)
18172 fputs ("\n\tMICROMIPS ASE", stdout);
18173 if (mask & AFL_ASE_XPA)
18174 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18175 if (mask & AFL_ASE_MIPS16E2)
18176 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18177 if (mask & AFL_ASE_CRC)
18178 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18179 if (mask & AFL_ASE_GINV)
18180 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18181 if (mask & AFL_ASE_LOONGSON_MMI)
18182 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18183 if (mask & AFL_ASE_LOONGSON_CAM)
18184 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18185 if (mask & AFL_ASE_LOONGSON_EXT)
18186 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18187 if (mask & AFL_ASE_LOONGSON_EXT2)
18188 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18189 if (mask == 0)
18190 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18191 else if ((mask & ~AFL_ASE_MASK) != 0)
18192 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18193}
18194
18195static void
18196print_mips_isa_ext (unsigned int isa_ext)
18197{
18198 switch (isa_ext)
18199 {
18200 case 0:
18201 fputs (_("None"), stdout);
18202 break;
18203 case AFL_EXT_XLR:
18204 fputs ("RMI XLR", stdout);
18205 break;
2c629856
N
18206 case AFL_EXT_OCTEON3:
18207 fputs ("Cavium Networks Octeon3", stdout);
18208 break;
351cdf24
MF
18209 case AFL_EXT_OCTEON2:
18210 fputs ("Cavium Networks Octeon2", stdout);
18211 break;
18212 case AFL_EXT_OCTEONP:
18213 fputs ("Cavium Networks OcteonP", stdout);
18214 break;
351cdf24
MF
18215 case AFL_EXT_OCTEON:
18216 fputs ("Cavium Networks Octeon", stdout);
18217 break;
18218 case AFL_EXT_5900:
18219 fputs ("Toshiba R5900", stdout);
18220 break;
18221 case AFL_EXT_4650:
18222 fputs ("MIPS R4650", stdout);
18223 break;
18224 case AFL_EXT_4010:
18225 fputs ("LSI R4010", stdout);
18226 break;
18227 case AFL_EXT_4100:
18228 fputs ("NEC VR4100", stdout);
18229 break;
18230 case AFL_EXT_3900:
18231 fputs ("Toshiba R3900", stdout);
18232 break;
18233 case AFL_EXT_10000:
18234 fputs ("MIPS R10000", stdout);
18235 break;
18236 case AFL_EXT_SB1:
18237 fputs ("Broadcom SB-1", stdout);
18238 break;
18239 case AFL_EXT_4111:
18240 fputs ("NEC VR4111/VR4181", stdout);
18241 break;
18242 case AFL_EXT_4120:
18243 fputs ("NEC VR4120", stdout);
18244 break;
18245 case AFL_EXT_5400:
18246 fputs ("NEC VR5400", stdout);
18247 break;
18248 case AFL_EXT_5500:
18249 fputs ("NEC VR5500", stdout);
18250 break;
18251 case AFL_EXT_LOONGSON_2E:
18252 fputs ("ST Microelectronics Loongson 2E", stdout);
18253 break;
18254 case AFL_EXT_LOONGSON_2F:
18255 fputs ("ST Microelectronics Loongson 2F", stdout);
18256 break;
38bf472a
MR
18257 case AFL_EXT_INTERAPTIV_MR2:
18258 fputs ("Imagination interAptiv MR2", stdout);
18259 break;
351cdf24 18260 default:
00ac7aa0 18261 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18262 }
18263}
18264
32ec8896 18265static signed int
351cdf24
MF
18266get_mips_reg_size (int reg_size)
18267{
18268 return (reg_size == AFL_REG_NONE) ? 0
18269 : (reg_size == AFL_REG_32) ? 32
18270 : (reg_size == AFL_REG_64) ? 64
18271 : (reg_size == AFL_REG_128) ? 128
18272 : -1;
18273}
18274
015dc7e1 18275static bool
dda8d76d 18276process_mips_specific (Filedata * filedata)
5b18a4bc 18277{
2cf0635d 18278 Elf_Internal_Dyn * entry;
351cdf24 18279 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18280 size_t liblist_offset = 0;
18281 size_t liblistno = 0;
18282 size_t conflictsno = 0;
18283 size_t options_offset = 0;
18284 size_t conflicts_offset = 0;
861fb55a
DJ
18285 size_t pltrelsz = 0;
18286 size_t pltrel = 0;
ccb4c951 18287 bfd_vma pltgot = 0;
861fb55a
DJ
18288 bfd_vma mips_pltgot = 0;
18289 bfd_vma jmprel = 0;
ccb4c951
RS
18290 bfd_vma local_gotno = 0;
18291 bfd_vma gotsym = 0;
18292 bfd_vma symtabno = 0;
015dc7e1 18293 bool res = true;
103f02d3 18294
dda8d76d 18295 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18296 display_mips_gnu_attribute))
015dc7e1 18297 res = false;
2cf19d5c 18298
dda8d76d 18299 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18300
18301 if (sect != NULL)
18302 {
18303 Elf_External_ABIFlags_v0 *abiflags_ext;
18304 Elf_Internal_ABIFlags_v0 abiflags_in;
18305
18306 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18307 {
18308 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18309 res = false;
32ec8896 18310 }
351cdf24
MF
18311 else
18312 {
dda8d76d 18313 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18314 sect->sh_size, _("MIPS ABI Flags section"));
18315 if (abiflags_ext)
18316 {
18317 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18318 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18319 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18320 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18321 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18322 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18323 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18324 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18325 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18326 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18327 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18328
18329 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18330 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18331 if (abiflags_in.isa_rev > 1)
18332 printf ("r%d", abiflags_in.isa_rev);
18333 printf ("\nGPR size: %d",
18334 get_mips_reg_size (abiflags_in.gpr_size));
18335 printf ("\nCPR1 size: %d",
18336 get_mips_reg_size (abiflags_in.cpr1_size));
18337 printf ("\nCPR2 size: %d",
18338 get_mips_reg_size (abiflags_in.cpr2_size));
18339 fputs ("\nFP ABI: ", stdout);
18340 print_mips_fp_abi_value (abiflags_in.fp_abi);
18341 fputs ("ISA Extension: ", stdout);
18342 print_mips_isa_ext (abiflags_in.isa_ext);
18343 fputs ("\nASEs:", stdout);
18344 print_mips_ases (abiflags_in.ases);
18345 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18346 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18347 fputc ('\n', stdout);
18348 free (abiflags_ext);
18349 }
18350 }
18351 }
18352
19e6b90e 18353 /* We have a lot of special sections. Thanks SGI! */
978c4450 18354 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18355 {
18356 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18357 sect = find_section (filedata, ".got");
bbdd9a68
MR
18358 if (sect != NULL)
18359 {
18360 unsigned char *data_end;
18361 unsigned char *data;
18362 bfd_vma ent, end;
18363 int addr_size;
18364
18365 pltgot = sect->sh_addr;
18366
18367 ent = pltgot;
18368 addr_size = (is_32bit_elf ? 4 : 8);
18369 end = pltgot + sect->sh_size;
18370
dda8d76d 18371 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18372 end - pltgot, 1,
18373 _("Global Offset Table data"));
18374 /* PR 12855: Null data is handled gracefully throughout. */
18375 data_end = data + (end - pltgot);
18376
18377 printf (_("\nStatic GOT:\n"));
18378 printf (_(" Canonical gp value: "));
18379 print_vma (ent + 0x7ff0, LONG_HEX);
18380 printf ("\n\n");
18381
18382 /* In a dynamic binary GOT[0] is reserved for the dynamic
18383 loader to store the lazy resolver pointer, however in
18384 a static binary it may well have been omitted and GOT
18385 reduced to a table of addresses.
18386 PR 21344: Check for the entry being fully available
18387 before fetching it. */
18388 if (data
18389 && data + ent - pltgot + addr_size <= data_end
18390 && byte_get (data + ent - pltgot, addr_size) == 0)
18391 {
18392 printf (_(" Reserved entries:\n"));
18393 printf (_(" %*s %10s %*s\n"),
18394 addr_size * 2, _("Address"), _("Access"),
18395 addr_size * 2, _("Value"));
18396 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18397 printf ("\n");
18398 if (ent == (bfd_vma) -1)
18399 goto sgot_print_fail;
18400
18401 /* Check for the MSB of GOT[1] being set, identifying a
18402 GNU object. This entry will be used by some runtime
18403 loaders, to store the module pointer. Otherwise this
18404 is an ordinary local entry.
18405 PR 21344: Check for the entry being fully available
18406 before fetching it. */
18407 if (data
18408 && data + ent - pltgot + addr_size <= data_end
18409 && (byte_get (data + ent - pltgot, addr_size)
18410 >> (addr_size * 8 - 1)) != 0)
18411 {
18412 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18413 printf ("\n");
18414 if (ent == (bfd_vma) -1)
18415 goto sgot_print_fail;
18416 }
18417 printf ("\n");
18418 }
18419
f17e9d8a 18420 if (data != NULL && ent < end)
bbdd9a68
MR
18421 {
18422 printf (_(" Local entries:\n"));
18423 printf (" %*s %10s %*s\n",
18424 addr_size * 2, _("Address"), _("Access"),
18425 addr_size * 2, _("Value"));
18426 while (ent < end)
18427 {
18428 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18429 printf ("\n");
18430 if (ent == (bfd_vma) -1)
18431 goto sgot_print_fail;
18432 }
18433 printf ("\n");
18434 }
18435
18436 sgot_print_fail:
9db70fc3 18437 free (data);
bbdd9a68
MR
18438 }
18439 return res;
18440 }
252b5132 18441
978c4450 18442 for (entry = filedata->dynamic_section;
071436c6 18443 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18444 (entry < filedata->dynamic_section + filedata->dynamic_nent
18445 && entry->d_tag != DT_NULL);
071436c6 18446 ++entry)
252b5132
RH
18447 switch (entry->d_tag)
18448 {
18449 case DT_MIPS_LIBLIST:
d93f0186 18450 liblist_offset
dda8d76d 18451 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18452 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18453 break;
18454 case DT_MIPS_LIBLISTNO:
18455 liblistno = entry->d_un.d_val;
18456 break;
18457 case DT_MIPS_OPTIONS:
dda8d76d 18458 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18459 break;
18460 case DT_MIPS_CONFLICT:
d93f0186 18461 conflicts_offset
dda8d76d 18462 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18463 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18464 break;
18465 case DT_MIPS_CONFLICTNO:
18466 conflictsno = entry->d_un.d_val;
18467 break;
ccb4c951 18468 case DT_PLTGOT:
861fb55a
DJ
18469 pltgot = entry->d_un.d_ptr;
18470 break;
ccb4c951
RS
18471 case DT_MIPS_LOCAL_GOTNO:
18472 local_gotno = entry->d_un.d_val;
18473 break;
18474 case DT_MIPS_GOTSYM:
18475 gotsym = entry->d_un.d_val;
18476 break;
18477 case DT_MIPS_SYMTABNO:
18478 symtabno = entry->d_un.d_val;
18479 break;
861fb55a
DJ
18480 case DT_MIPS_PLTGOT:
18481 mips_pltgot = entry->d_un.d_ptr;
18482 break;
18483 case DT_PLTREL:
18484 pltrel = entry->d_un.d_val;
18485 break;
18486 case DT_PLTRELSZ:
18487 pltrelsz = entry->d_un.d_val;
18488 break;
18489 case DT_JMPREL:
18490 jmprel = entry->d_un.d_ptr;
18491 break;
252b5132
RH
18492 default:
18493 break;
18494 }
18495
18496 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18497 {
2cf0635d 18498 Elf32_External_Lib * elib;
252b5132
RH
18499 size_t cnt;
18500
dda8d76d 18501 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18502 sizeof (Elf32_External_Lib),
18503 liblistno,
18504 _("liblist section data"));
a6e9f9df 18505 if (elib)
252b5132 18506 {
d3a49aa8
AM
18507 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18508 "\nSection '.liblist' contains %lu entries:\n",
18509 (unsigned long) liblistno),
a6e9f9df 18510 (unsigned long) liblistno);
2b692964 18511 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18512 stdout);
18513
18514 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18515 {
a6e9f9df 18516 Elf32_Lib liblist;
91d6fa6a 18517 time_t atime;
d5b07ef4 18518 char timebuf[128];
2cf0635d 18519 struct tm * tmp;
a6e9f9df
AM
18520
18521 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18522 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18523 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18524 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18525 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18526
91d6fa6a 18527 tmp = gmtime (&atime);
e9e44622
JJ
18528 snprintf (timebuf, sizeof (timebuf),
18529 "%04u-%02u-%02uT%02u:%02u:%02u",
18530 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18531 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18532
31104126 18533 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18534 if (valid_dynamic_name (filedata, liblist.l_name))
18535 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18536 else
2b692964 18537 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18538 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18539 liblist.l_version);
a6e9f9df
AM
18540
18541 if (liblist.l_flags == 0)
2b692964 18542 puts (_(" NONE"));
a6e9f9df
AM
18543 else
18544 {
18545 static const struct
252b5132 18546 {
2cf0635d 18547 const char * name;
a6e9f9df 18548 int bit;
252b5132 18549 }
a6e9f9df
AM
18550 l_flags_vals[] =
18551 {
18552 { " EXACT_MATCH", LL_EXACT_MATCH },
18553 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18554 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18555 { " EXPORTS", LL_EXPORTS },
18556 { " DELAY_LOAD", LL_DELAY_LOAD },
18557 { " DELTA", LL_DELTA }
18558 };
18559 int flags = liblist.l_flags;
18560 size_t fcnt;
18561
60bca95a 18562 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18563 if ((flags & l_flags_vals[fcnt].bit) != 0)
18564 {
18565 fputs (l_flags_vals[fcnt].name, stdout);
18566 flags ^= l_flags_vals[fcnt].bit;
18567 }
18568 if (flags != 0)
18569 printf (" %#x", (unsigned int) flags);
252b5132 18570
a6e9f9df
AM
18571 puts ("");
18572 }
252b5132 18573 }
252b5132 18574
a6e9f9df
AM
18575 free (elib);
18576 }
32ec8896 18577 else
015dc7e1 18578 res = false;
252b5132
RH
18579 }
18580
18581 if (options_offset != 0)
18582 {
2cf0635d 18583 Elf_External_Options * eopt;
252b5132
RH
18584 size_t offset;
18585 int cnt;
18586
18587 /* Find the section header so that we get the size. */
dda8d76d 18588 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18589 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18590 if (sect == NULL)
18591 {
18592 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18593 return false;
071436c6 18594 }
7fc0c668
NC
18595 /* PR 24243 */
18596 if (sect->sh_size < sizeof (* eopt))
18597 {
18598 error (_("The MIPS options section is too small.\n"));
015dc7e1 18599 return false;
7fc0c668 18600 }
252b5132 18601
dda8d76d 18602 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18603 sect->sh_size, _("options"));
a6e9f9df 18604 if (eopt)
252b5132 18605 {
fd17d1e6 18606 Elf_Internal_Options option;
76da6bbe 18607
a6e9f9df 18608 offset = cnt = 0;
82b1b41b 18609 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18610 {
2cf0635d 18611 Elf_External_Options * eoption;
fd17d1e6 18612 unsigned int optsize;
252b5132 18613
a6e9f9df 18614 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18615
fd17d1e6 18616 optsize = BYTE_GET (eoption->size);
76da6bbe 18617
82b1b41b 18618 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18619 if (optsize < sizeof (* eopt)
18620 || optsize > sect->sh_size - offset)
82b1b41b 18621 {
645f43a8 18622 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18623 optsize);
645f43a8 18624 free (eopt);
015dc7e1 18625 return false;
82b1b41b 18626 }
fd17d1e6 18627 offset += optsize;
a6e9f9df
AM
18628 ++cnt;
18629 }
252b5132 18630
d3a49aa8
AM
18631 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18632 "\nSection '%s' contains %d entries:\n",
18633 cnt),
dda8d76d 18634 printable_section_name (filedata, sect), cnt);
76da6bbe 18635
82b1b41b 18636 offset = 0;
a6e9f9df 18637 while (cnt-- > 0)
252b5132 18638 {
a6e9f9df 18639 size_t len;
fd17d1e6
AM
18640 Elf_External_Options * eoption;
18641
18642 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18643
18644 option.kind = BYTE_GET (eoption->kind);
18645 option.size = BYTE_GET (eoption->size);
18646 option.section = BYTE_GET (eoption->section);
18647 option.info = BYTE_GET (eoption->info);
a6e9f9df 18648
fd17d1e6 18649 switch (option.kind)
252b5132 18650 {
a6e9f9df
AM
18651 case ODK_NULL:
18652 /* This shouldn't happen. */
d0c4e780 18653 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18654 option.section, option.info);
a6e9f9df 18655 break;
2e6be59c 18656
a6e9f9df
AM
18657 case ODK_REGINFO:
18658 printf (" REGINFO ");
dda8d76d 18659 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18660 {
2cf0635d 18661 Elf32_External_RegInfo * ereg;
b34976b6 18662 Elf32_RegInfo reginfo;
a6e9f9df 18663
2e6be59c 18664 /* 32bit form. */
fd17d1e6
AM
18665 if (option.size < (sizeof (Elf_External_Options)
18666 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18667 {
18668 printf (_("<corrupt>\n"));
18669 error (_("Truncated MIPS REGINFO option\n"));
18670 cnt = 0;
18671 break;
18672 }
18673
fd17d1e6 18674 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18675
a6e9f9df
AM
18676 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18677 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18678 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18679 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18680 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18681 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18682
d0c4e780
AM
18683 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18684 reginfo.ri_gprmask, reginfo.ri_gp_value);
18685 printf (" "
18686 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18687 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18688 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18689 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18690 }
18691 else
18692 {
18693 /* 64 bit form. */
2cf0635d 18694 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18695 Elf64_Internal_RegInfo reginfo;
18696
fd17d1e6
AM
18697 if (option.size < (sizeof (Elf_External_Options)
18698 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18699 {
18700 printf (_("<corrupt>\n"));
18701 error (_("Truncated MIPS REGINFO option\n"));
18702 cnt = 0;
18703 break;
18704 }
18705
fd17d1e6 18706 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18707 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18708 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18709 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18710 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18711 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18712 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18713
d0c4e780
AM
18714 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18715 reginfo.ri_gprmask, reginfo.ri_gp_value);
18716 printf (" "
18717 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18718 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18719 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18720 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18721 }
fd17d1e6 18722 offset += option.size;
a6e9f9df 18723 continue;
2e6be59c 18724
a6e9f9df
AM
18725 case ODK_EXCEPTIONS:
18726 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18727 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18728 fputs (") fpe_max(", stdout);
fd17d1e6 18729 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18730 fputs (")", stdout);
18731
fd17d1e6 18732 if (option.info & OEX_PAGE0)
a6e9f9df 18733 fputs (" PAGE0", stdout);
fd17d1e6 18734 if (option.info & OEX_SMM)
a6e9f9df 18735 fputs (" SMM", stdout);
fd17d1e6 18736 if (option.info & OEX_FPDBUG)
a6e9f9df 18737 fputs (" FPDBUG", stdout);
fd17d1e6 18738 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18739 fputs (" DISMISS", stdout);
18740 break;
2e6be59c 18741
a6e9f9df
AM
18742 case ODK_PAD:
18743 fputs (" PAD ", stdout);
fd17d1e6 18744 if (option.info & OPAD_PREFIX)
a6e9f9df 18745 fputs (" PREFIX", stdout);
fd17d1e6 18746 if (option.info & OPAD_POSTFIX)
a6e9f9df 18747 fputs (" POSTFIX", stdout);
fd17d1e6 18748 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18749 fputs (" SYMBOL", stdout);
18750 break;
2e6be59c 18751
a6e9f9df
AM
18752 case ODK_HWPATCH:
18753 fputs (" HWPATCH ", stdout);
fd17d1e6 18754 if (option.info & OHW_R4KEOP)
a6e9f9df 18755 fputs (" R4KEOP", stdout);
fd17d1e6 18756 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18757 fputs (" R8KPFETCH", stdout);
fd17d1e6 18758 if (option.info & OHW_R5KEOP)
a6e9f9df 18759 fputs (" R5KEOP", stdout);
fd17d1e6 18760 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18761 fputs (" R5KCVTL", stdout);
18762 break;
2e6be59c 18763
a6e9f9df
AM
18764 case ODK_FILL:
18765 fputs (" FILL ", stdout);
18766 /* XXX Print content of info word? */
18767 break;
2e6be59c 18768
a6e9f9df
AM
18769 case ODK_TAGS:
18770 fputs (" TAGS ", stdout);
18771 /* XXX Print content of info word? */
18772 break;
2e6be59c 18773
a6e9f9df
AM
18774 case ODK_HWAND:
18775 fputs (" HWAND ", stdout);
fd17d1e6 18776 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18777 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18778 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18779 fputs (" R4KEOP_CLEAN", stdout);
18780 break;
2e6be59c 18781
a6e9f9df
AM
18782 case ODK_HWOR:
18783 fputs (" HWOR ", stdout);
fd17d1e6 18784 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18785 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18786 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18787 fputs (" R4KEOP_CLEAN", stdout);
18788 break;
2e6be59c 18789
a6e9f9df 18790 case ODK_GP_GROUP:
d0c4e780 18791 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18792 option.info & OGP_GROUP,
18793 (option.info & OGP_SELF) >> 16);
a6e9f9df 18794 break;
2e6be59c 18795
a6e9f9df 18796 case ODK_IDENT:
d0c4e780 18797 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18798 option.info & OGP_GROUP,
18799 (option.info & OGP_SELF) >> 16);
a6e9f9df 18800 break;
2e6be59c 18801
a6e9f9df
AM
18802 default:
18803 /* This shouldn't happen. */
d0c4e780 18804 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18805 option.kind, option.section, option.info);
a6e9f9df 18806 break;
252b5132 18807 }
a6e9f9df 18808
2cf0635d 18809 len = sizeof (* eopt);
fd17d1e6 18810 while (len < option.size)
82b1b41b 18811 {
fd17d1e6 18812 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18813
82b1b41b
NC
18814 if (ISPRINT (datum))
18815 printf ("%c", datum);
18816 else
18817 printf ("\\%03o", datum);
18818 len ++;
18819 }
a6e9f9df 18820 fputs ("\n", stdout);
82b1b41b 18821
fd17d1e6 18822 offset += option.size;
252b5132 18823 }
a6e9f9df 18824 free (eopt);
252b5132 18825 }
32ec8896 18826 else
015dc7e1 18827 res = false;
252b5132
RH
18828 }
18829
18830 if (conflicts_offset != 0 && conflictsno != 0)
18831 {
2cf0635d 18832 Elf32_Conflict * iconf;
252b5132
RH
18833 size_t cnt;
18834
978c4450 18835 if (filedata->dynamic_symbols == NULL)
252b5132 18836 {
591a748a 18837 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18838 return false;
252b5132
RH
18839 }
18840
7296a62a
NC
18841 /* PR 21345 - print a slightly more helpful error message
18842 if we are sure that the cmalloc will fail. */
645f43a8 18843 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18844 {
18845 error (_("Overlarge number of conflicts detected: %lx\n"),
18846 (long) conflictsno);
015dc7e1 18847 return false;
7296a62a
NC
18848 }
18849
3f5e193b 18850 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18851 if (iconf == NULL)
18852 {
8b73c356 18853 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18854 return false;
252b5132
RH
18855 }
18856
9ea033b2 18857 if (is_32bit_elf)
252b5132 18858 {
2cf0635d 18859 Elf32_External_Conflict * econf32;
a6e9f9df 18860
3f5e193b 18861 econf32 = (Elf32_External_Conflict *)
95099889
AM
18862 get_data (NULL, filedata, conflicts_offset,
18863 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18864 if (!econf32)
5a814d6d
AM
18865 {
18866 free (iconf);
015dc7e1 18867 return false;
5a814d6d 18868 }
252b5132
RH
18869
18870 for (cnt = 0; cnt < conflictsno; ++cnt)
18871 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18872
18873 free (econf32);
252b5132
RH
18874 }
18875 else
18876 {
2cf0635d 18877 Elf64_External_Conflict * econf64;
a6e9f9df 18878
3f5e193b 18879 econf64 = (Elf64_External_Conflict *)
95099889
AM
18880 get_data (NULL, filedata, conflicts_offset,
18881 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18882 if (!econf64)
5a814d6d
AM
18883 {
18884 free (iconf);
015dc7e1 18885 return false;
5a814d6d 18886 }
252b5132
RH
18887
18888 for (cnt = 0; cnt < conflictsno; ++cnt)
18889 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18890
18891 free (econf64);
252b5132
RH
18892 }
18893
d3a49aa8
AM
18894 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18895 "\nSection '.conflict' contains %lu entries:\n",
18896 (unsigned long) conflictsno),
c7e7ca54 18897 (unsigned long) conflictsno);
252b5132
RH
18898 puts (_(" Num: Index Value Name"));
18899
18900 for (cnt = 0; cnt < conflictsno; ++cnt)
18901 {
b34976b6 18902 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18903
978c4450 18904 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18905 printf (_("<corrupt symbol index>"));
d79b3d50 18906 else
e0a31db1
NC
18907 {
18908 Elf_Internal_Sym * psym;
18909
978c4450 18910 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18911 print_vma (psym->st_value, FULL_HEX);
18912 putchar (' ');
84714f86
AM
18913 if (valid_dynamic_name (filedata, psym->st_name))
18914 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18915 else
18916 printf (_("<corrupt: %14ld>"), psym->st_name);
18917 }
31104126 18918 putchar ('\n');
252b5132
RH
18919 }
18920
252b5132
RH
18921 free (iconf);
18922 }
18923
ccb4c951
RS
18924 if (pltgot != 0 && local_gotno != 0)
18925 {
91d6fa6a 18926 bfd_vma ent, local_end, global_end;
bbeee7ea 18927 size_t i, offset;
2cf0635d 18928 unsigned char * data;
82b1b41b 18929 unsigned char * data_end;
bbeee7ea 18930 int addr_size;
ccb4c951 18931
91d6fa6a 18932 ent = pltgot;
ccb4c951
RS
18933 addr_size = (is_32bit_elf ? 4 : 8);
18934 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18935
74e1a04b
NC
18936 /* PR binutils/17533 file: 012-111227-0.004 */
18937 if (symtabno < gotsym)
18938 {
18939 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18940 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18941 return false;
74e1a04b 18942 }
82b1b41b 18943
74e1a04b 18944 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18945 /* PR 17531: file: 54c91a34. */
18946 if (global_end < local_end)
18947 {
18948 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18949 return false;
82b1b41b 18950 }
948f632f 18951
dda8d76d
NC
18952 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18953 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18954 global_end - pltgot, 1,
18955 _("Global Offset Table data"));
919383ac 18956 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18957 data_end = data + (global_end - pltgot);
59245841 18958
ccb4c951
RS
18959 printf (_("\nPrimary GOT:\n"));
18960 printf (_(" Canonical gp value: "));
18961 print_vma (pltgot + 0x7ff0, LONG_HEX);
18962 printf ("\n\n");
18963
18964 printf (_(" Reserved entries:\n"));
18965 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18966 addr_size * 2, _("Address"), _("Access"),
18967 addr_size * 2, _("Initial"));
82b1b41b 18968 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18969 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18970 if (ent == (bfd_vma) -1)
18971 goto got_print_fail;
75ec1fdb 18972
c4ab9505
MR
18973 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18974 This entry will be used by some runtime loaders, to store the
18975 module pointer. Otherwise this is an ordinary local entry.
18976 PR 21344: Check for the entry being fully available before
18977 fetching it. */
18978 if (data
18979 && data + ent - pltgot + addr_size <= data_end
18980 && (byte_get (data + ent - pltgot, addr_size)
18981 >> (addr_size * 8 - 1)) != 0)
18982 {
18983 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18984 printf (_(" Module pointer (GNU extension)\n"));
18985 if (ent == (bfd_vma) -1)
18986 goto got_print_fail;
ccb4c951
RS
18987 }
18988 printf ("\n");
18989
f17e9d8a 18990 if (data != NULL && ent < local_end)
ccb4c951
RS
18991 {
18992 printf (_(" Local entries:\n"));
cc5914eb 18993 printf (" %*s %10s %*s\n",
2b692964
NC
18994 addr_size * 2, _("Address"), _("Access"),
18995 addr_size * 2, _("Initial"));
91d6fa6a 18996 while (ent < local_end)
ccb4c951 18997 {
82b1b41b 18998 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18999 printf ("\n");
82b1b41b
NC
19000 if (ent == (bfd_vma) -1)
19001 goto got_print_fail;
ccb4c951
RS
19002 }
19003 printf ("\n");
19004 }
19005
f17e9d8a 19006 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19007 {
19008 int sym_width;
19009
19010 printf (_(" Global entries:\n"));
cc5914eb 19011 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19012 addr_size * 2, _("Address"),
19013 _("Access"),
2b692964 19014 addr_size * 2, _("Initial"),
9cf03b7e
NC
19015 addr_size * 2, _("Sym.Val."),
19016 _("Type"),
19017 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19018 _("Ndx"), _("Name"));
0b4362b0 19019
ccb4c951 19020 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19021
ccb4c951
RS
19022 for (i = gotsym; i < symtabno; i++)
19023 {
82b1b41b 19024 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19025 printf (" ");
e0a31db1 19026
978c4450 19027 if (filedata->dynamic_symbols == NULL)
e0a31db1 19028 printf (_("<no dynamic symbols>"));
978c4450 19029 else if (i < filedata->num_dynamic_syms)
e0a31db1 19030 {
978c4450 19031 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19032
19033 print_vma (psym->st_value, LONG_HEX);
19034 printf (" %-7s %3s ",
dda8d76d
NC
19035 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19036 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19037
84714f86 19038 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19039 print_symbol (sym_width,
84714f86 19040 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19041 else
19042 printf (_("<corrupt: %14ld>"), psym->st_name);
19043 }
ccb4c951 19044 else
7fc5ac57
JBG
19045 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19046 (unsigned long) i);
e0a31db1 19047
ccb4c951 19048 printf ("\n");
82b1b41b
NC
19049 if (ent == (bfd_vma) -1)
19050 break;
ccb4c951
RS
19051 }
19052 printf ("\n");
19053 }
19054
82b1b41b 19055 got_print_fail:
9db70fc3 19056 free (data);
ccb4c951
RS
19057 }
19058
861fb55a
DJ
19059 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19060 {
91d6fa6a 19061 bfd_vma ent, end;
861fb55a
DJ
19062 size_t offset, rel_offset;
19063 unsigned long count, i;
2cf0635d 19064 unsigned char * data;
861fb55a 19065 int addr_size, sym_width;
2cf0635d 19066 Elf_Internal_Rela * rels;
861fb55a 19067
dda8d76d 19068 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19069 if (pltrel == DT_RELA)
19070 {
dda8d76d 19071 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19072 return false;
861fb55a
DJ
19073 }
19074 else
19075 {
dda8d76d 19076 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19077 return false;
861fb55a
DJ
19078 }
19079
91d6fa6a 19080 ent = mips_pltgot;
861fb55a
DJ
19081 addr_size = (is_32bit_elf ? 4 : 8);
19082 end = mips_pltgot + (2 + count) * addr_size;
19083
dda8d76d
NC
19084 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19085 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19086 1, _("Procedure Linkage Table data"));
59245841 19087 if (data == NULL)
288f0ba2
AM
19088 {
19089 free (rels);
015dc7e1 19090 return false;
288f0ba2 19091 }
59245841 19092
9cf03b7e 19093 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19094 printf (_(" Reserved entries:\n"));
19095 printf (_(" %*s %*s Purpose\n"),
2b692964 19096 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19097 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19098 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19099 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19100 printf (_(" Module pointer\n"));
861fb55a
DJ
19101 printf ("\n");
19102
19103 printf (_(" Entries:\n"));
cc5914eb 19104 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19105 addr_size * 2, _("Address"),
19106 addr_size * 2, _("Initial"),
19107 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19108 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19109 for (i = 0; i < count; i++)
19110 {
df97ab2a 19111 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19112
91d6fa6a 19113 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19114 printf (" ");
e0a31db1 19115
978c4450 19116 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19117 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19118 else
e0a31db1 19119 {
978c4450 19120 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19121
19122 print_vma (psym->st_value, LONG_HEX);
19123 printf (" %-7s %3s ",
dda8d76d
NC
19124 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19125 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19126 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19127 print_symbol (sym_width,
84714f86 19128 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19129 else
19130 printf (_("<corrupt: %14ld>"), psym->st_name);
19131 }
861fb55a
DJ
19132 printf ("\n");
19133 }
19134 printf ("\n");
19135
9db70fc3 19136 free (data);
861fb55a
DJ
19137 free (rels);
19138 }
19139
32ec8896 19140 return res;
252b5132
RH
19141}
19142
015dc7e1 19143static bool
dda8d76d 19144process_nds32_specific (Filedata * filedata)
35c08157
KLC
19145{
19146 Elf_Internal_Shdr *sect = NULL;
19147
dda8d76d 19148 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19149 if (sect != NULL && sect->sh_size >= 4)
35c08157 19150 {
9c7b8e9b
AM
19151 unsigned char *buf;
19152 unsigned int flag;
35c08157
KLC
19153
19154 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19155 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19156 _("NDS32 elf flags section"));
35c08157 19157
9c7b8e9b 19158 if (buf == NULL)
015dc7e1 19159 return false;
32ec8896 19160
9c7b8e9b
AM
19161 flag = byte_get (buf, 4);
19162 free (buf);
19163 switch (flag & 0x3)
35c08157
KLC
19164 {
19165 case 0:
19166 printf ("(VEC_SIZE):\tNo entry.\n");
19167 break;
19168 case 1:
19169 printf ("(VEC_SIZE):\t4 bytes\n");
19170 break;
19171 case 2:
19172 printf ("(VEC_SIZE):\t16 bytes\n");
19173 break;
19174 case 3:
19175 printf ("(VEC_SIZE):\treserved\n");
19176 break;
19177 }
19178 }
19179
015dc7e1 19180 return true;
35c08157
KLC
19181}
19182
015dc7e1 19183static bool
dda8d76d 19184process_gnu_liblist (Filedata * filedata)
047b2264 19185{
2cf0635d
NC
19186 Elf_Internal_Shdr * section;
19187 Elf_Internal_Shdr * string_sec;
19188 Elf32_External_Lib * elib;
19189 char * strtab;
c256ffe7 19190 size_t strtab_size;
047b2264 19191 size_t cnt;
d3a49aa8 19192 unsigned long num_liblist;
047b2264 19193 unsigned i;
015dc7e1 19194 bool res = true;
047b2264
JJ
19195
19196 if (! do_arch)
015dc7e1 19197 return true;
047b2264 19198
dda8d76d
NC
19199 for (i = 0, section = filedata->section_headers;
19200 i < filedata->file_header.e_shnum;
b34976b6 19201 i++, section++)
047b2264
JJ
19202 {
19203 switch (section->sh_type)
19204 {
19205 case SHT_GNU_LIBLIST:
dda8d76d 19206 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19207 break;
19208
3f5e193b 19209 elib = (Elf32_External_Lib *)
dda8d76d 19210 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19211 _("liblist section data"));
047b2264
JJ
19212
19213 if (elib == NULL)
32ec8896 19214 {
015dc7e1 19215 res = false;
32ec8896
NC
19216 break;
19217 }
047b2264 19218
dda8d76d
NC
19219 string_sec = filedata->section_headers + section->sh_link;
19220 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19221 string_sec->sh_size,
19222 _("liblist string table"));
047b2264
JJ
19223 if (strtab == NULL
19224 || section->sh_entsize != sizeof (Elf32_External_Lib))
19225 {
19226 free (elib);
2842702f 19227 free (strtab);
015dc7e1 19228 res = false;
047b2264
JJ
19229 break;
19230 }
59245841 19231 strtab_size = string_sec->sh_size;
047b2264 19232
d3a49aa8
AM
19233 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19234 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19235 "\nLibrary list section '%s' contains %lu entries:\n",
19236 num_liblist),
dda8d76d 19237 printable_section_name (filedata, section),
d3a49aa8 19238 num_liblist);
047b2264 19239
2b692964 19240 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19241
19242 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19243 ++cnt)
19244 {
19245 Elf32_Lib liblist;
91d6fa6a 19246 time_t atime;
d5b07ef4 19247 char timebuf[128];
2cf0635d 19248 struct tm * tmp;
047b2264
JJ
19249
19250 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19251 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19252 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19253 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19254 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19255
91d6fa6a 19256 tmp = gmtime (&atime);
e9e44622
JJ
19257 snprintf (timebuf, sizeof (timebuf),
19258 "%04u-%02u-%02uT%02u:%02u:%02u",
19259 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19260 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19261
19262 printf ("%3lu: ", (unsigned long) cnt);
19263 if (do_wide)
c256ffe7 19264 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19265 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19266 else
c256ffe7 19267 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19268 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19269 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19270 liblist.l_version, liblist.l_flags);
19271 }
19272
19273 free (elib);
2842702f 19274 free (strtab);
047b2264
JJ
19275 }
19276 }
19277
32ec8896 19278 return res;
047b2264
JJ
19279}
19280
9437c45b 19281static const char *
dda8d76d 19282get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19283{
19284 static char buff[64];
103f02d3 19285
dda8d76d 19286 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19287 switch (e_type)
19288 {
57346661 19289 case NT_AUXV:
1ec5cd37 19290 return _("NT_AUXV (auxiliary vector)");
57346661 19291 case NT_PRSTATUS:
1ec5cd37 19292 return _("NT_PRSTATUS (prstatus structure)");
57346661 19293 case NT_FPREGSET:
1ec5cd37 19294 return _("NT_FPREGSET (floating point registers)");
57346661 19295 case NT_PRPSINFO:
1ec5cd37 19296 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19297 case NT_TASKSTRUCT:
1ec5cd37 19298 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19299 case NT_GDB_TDESC:
19300 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19301 case NT_PRXFPREG:
1ec5cd37 19302 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19303 case NT_PPC_VMX:
19304 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19305 case NT_PPC_VSX:
19306 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19307 case NT_PPC_TAR:
19308 return _("NT_PPC_TAR (ppc TAR register)");
19309 case NT_PPC_PPR:
19310 return _("NT_PPC_PPR (ppc PPR register)");
19311 case NT_PPC_DSCR:
19312 return _("NT_PPC_DSCR (ppc DSCR register)");
19313 case NT_PPC_EBB:
19314 return _("NT_PPC_EBB (ppc EBB registers)");
19315 case NT_PPC_PMU:
19316 return _("NT_PPC_PMU (ppc PMU registers)");
19317 case NT_PPC_TM_CGPR:
19318 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19319 case NT_PPC_TM_CFPR:
19320 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19321 case NT_PPC_TM_CVMX:
19322 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19323 case NT_PPC_TM_CVSX:
3fd21718 19324 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19325 case NT_PPC_TM_SPR:
19326 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19327 case NT_PPC_TM_CTAR:
19328 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19329 case NT_PPC_TM_CPPR:
19330 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19331 case NT_PPC_TM_CDSCR:
19332 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19333 case NT_386_TLS:
19334 return _("NT_386_TLS (x86 TLS information)");
19335 case NT_386_IOPERM:
19336 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19337 case NT_X86_XSTATE:
19338 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19339 case NT_X86_CET:
19340 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19341 case NT_S390_HIGH_GPRS:
19342 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19343 case NT_S390_TIMER:
19344 return _("NT_S390_TIMER (s390 timer register)");
19345 case NT_S390_TODCMP:
19346 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19347 case NT_S390_TODPREG:
19348 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19349 case NT_S390_CTRS:
19350 return _("NT_S390_CTRS (s390 control registers)");
19351 case NT_S390_PREFIX:
19352 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19353 case NT_S390_LAST_BREAK:
19354 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19355 case NT_S390_SYSTEM_CALL:
19356 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19357 case NT_S390_TDB:
19358 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19359 case NT_S390_VXRS_LOW:
19360 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19361 case NT_S390_VXRS_HIGH:
19362 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19363 case NT_S390_GS_CB:
19364 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19365 case NT_S390_GS_BC:
19366 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19367 case NT_ARM_VFP:
19368 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19369 case NT_ARM_TLS:
19370 return _("NT_ARM_TLS (AArch TLS registers)");
19371 case NT_ARM_HW_BREAK:
19372 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19373 case NT_ARM_HW_WATCH:
19374 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19375 case NT_ARM_SVE:
19376 return _("NT_ARM_SVE (AArch SVE registers)");
19377 case NT_ARM_PAC_MASK:
19378 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19379 case NT_ARM_PACA_KEYS:
19380 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19381 case NT_ARM_PACG_KEYS:
19382 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19383 case NT_ARM_TAGGED_ADDR_CTRL:
19384 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19385 case NT_ARM_PAC_ENABLED_KEYS:
19386 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19387 case NT_ARC_V2:
19388 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19389 case NT_RISCV_CSR:
19390 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19391 case NT_PSTATUS:
1ec5cd37 19392 return _("NT_PSTATUS (pstatus structure)");
57346661 19393 case NT_FPREGS:
1ec5cd37 19394 return _("NT_FPREGS (floating point registers)");
57346661 19395 case NT_PSINFO:
1ec5cd37 19396 return _("NT_PSINFO (psinfo structure)");
57346661 19397 case NT_LWPSTATUS:
1ec5cd37 19398 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19399 case NT_LWPSINFO:
1ec5cd37 19400 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19401 case NT_WIN32PSTATUS:
1ec5cd37 19402 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19403 case NT_SIGINFO:
19404 return _("NT_SIGINFO (siginfo_t data)");
19405 case NT_FILE:
19406 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19407 default:
19408 break;
19409 }
19410 else
19411 switch (e_type)
19412 {
19413 case NT_VERSION:
19414 return _("NT_VERSION (version)");
19415 case NT_ARCH:
19416 return _("NT_ARCH (architecture)");
9ef920e9 19417 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19418 return _("OPEN");
9ef920e9 19419 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19420 return _("func");
c8795e1f
NC
19421 case NT_GO_BUILDID:
19422 return _("GO BUILDID");
3ac925fc
LB
19423 case FDO_PACKAGING_METADATA:
19424 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19425 default:
19426 break;
19427 }
19428
e9e44622 19429 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19430 return buff;
779fe533
NC
19431}
19432
015dc7e1 19433static bool
9ece1fa9
TT
19434print_core_note (Elf_Internal_Note *pnote)
19435{
19436 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19437 bfd_vma count, page_size;
19438 unsigned char *descdata, *filenames, *descend;
19439
19440 if (pnote->type != NT_FILE)
04ac15ab
AS
19441 {
19442 if (do_wide)
19443 printf ("\n");
015dc7e1 19444 return true;
04ac15ab 19445 }
9ece1fa9
TT
19446
19447#ifndef BFD64
19448 if (!is_32bit_elf)
19449 {
19450 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19451 /* Still "successful". */
015dc7e1 19452 return true;
9ece1fa9
TT
19453 }
19454#endif
19455
19456 if (pnote->descsz < 2 * addr_size)
19457 {
32ec8896 19458 error (_(" Malformed note - too short for header\n"));
015dc7e1 19459 return false;
9ece1fa9
TT
19460 }
19461
19462 descdata = (unsigned char *) pnote->descdata;
19463 descend = descdata + pnote->descsz;
19464
19465 if (descdata[pnote->descsz - 1] != '\0')
19466 {
32ec8896 19467 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19468 return false;
9ece1fa9
TT
19469 }
19470
19471 count = byte_get (descdata, addr_size);
19472 descdata += addr_size;
19473
19474 page_size = byte_get (descdata, addr_size);
19475 descdata += addr_size;
19476
5396a86e
AM
19477 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19478 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19479 {
32ec8896 19480 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19481 return false;
9ece1fa9
TT
19482 }
19483
19484 printf (_(" Page size: "));
19485 print_vma (page_size, DEC);
19486 printf ("\n");
19487
19488 printf (_(" %*s%*s%*s\n"),
19489 (int) (2 + 2 * addr_size), _("Start"),
19490 (int) (4 + 2 * addr_size), _("End"),
19491 (int) (4 + 2 * addr_size), _("Page Offset"));
19492 filenames = descdata + count * 3 * addr_size;
595712bb 19493 while (count-- > 0)
9ece1fa9
TT
19494 {
19495 bfd_vma start, end, file_ofs;
19496
19497 if (filenames == descend)
19498 {
32ec8896 19499 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19500 return false;
9ece1fa9
TT
19501 }
19502
19503 start = byte_get (descdata, addr_size);
19504 descdata += addr_size;
19505 end = byte_get (descdata, addr_size);
19506 descdata += addr_size;
19507 file_ofs = byte_get (descdata, addr_size);
19508 descdata += addr_size;
19509
19510 printf (" ");
19511 print_vma (start, FULL_HEX);
19512 printf (" ");
19513 print_vma (end, FULL_HEX);
19514 printf (" ");
19515 print_vma (file_ofs, FULL_HEX);
19516 printf ("\n %s\n", filenames);
19517
19518 filenames += 1 + strlen ((char *) filenames);
19519 }
19520
015dc7e1 19521 return true;
9ece1fa9
TT
19522}
19523
1118d252
RM
19524static const char *
19525get_gnu_elf_note_type (unsigned e_type)
19526{
1449284b 19527 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19528 switch (e_type)
19529 {
19530 case NT_GNU_ABI_TAG:
19531 return _("NT_GNU_ABI_TAG (ABI version tag)");
19532 case NT_GNU_HWCAP:
19533 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19534 case NT_GNU_BUILD_ID:
19535 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19536 case NT_GNU_GOLD_VERSION:
19537 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19538 case NT_GNU_PROPERTY_TYPE_0:
19539 return _("NT_GNU_PROPERTY_TYPE_0");
19540 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19541 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19542 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19543 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19544 default:
1449284b
NC
19545 {
19546 static char buff[64];
1118d252 19547
1449284b
NC
19548 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19549 return buff;
19550 }
19551 }
1118d252
RM
19552}
19553
a9eafb08
L
19554static void
19555decode_x86_compat_isa (unsigned int bitmask)
19556{
19557 while (bitmask)
19558 {
19559 unsigned int bit = bitmask & (- bitmask);
19560
19561 bitmask &= ~ bit;
19562 switch (bit)
19563 {
19564 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19565 printf ("i486");
19566 break;
19567 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19568 printf ("586");
19569 break;
19570 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19571 printf ("686");
19572 break;
19573 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19574 printf ("SSE");
19575 break;
19576 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19577 printf ("SSE2");
19578 break;
19579 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19580 printf ("SSE3");
19581 break;
19582 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19583 printf ("SSSE3");
19584 break;
19585 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19586 printf ("SSE4_1");
19587 break;
19588 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19589 printf ("SSE4_2");
19590 break;
19591 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19592 printf ("AVX");
19593 break;
19594 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19595 printf ("AVX2");
19596 break;
19597 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19598 printf ("AVX512F");
19599 break;
19600 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19601 printf ("AVX512CD");
19602 break;
19603 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19604 printf ("AVX512ER");
19605 break;
19606 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19607 printf ("AVX512PF");
19608 break;
19609 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19610 printf ("AVX512VL");
19611 break;
19612 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19613 printf ("AVX512DQ");
19614 break;
19615 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19616 printf ("AVX512BW");
19617 break;
65b3d26e
L
19618 default:
19619 printf (_("<unknown: %x>"), bit);
19620 break;
a9eafb08
L
19621 }
19622 if (bitmask)
19623 printf (", ");
19624 }
19625}
19626
9ef920e9 19627static void
32930e4e 19628decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19629{
0a59decb 19630 if (!bitmask)
90c745dc
L
19631 {
19632 printf (_("<None>"));
19633 return;
19634 }
90c745dc 19635
9ef920e9
NC
19636 while (bitmask)
19637 {
1fc87489 19638 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19639
19640 bitmask &= ~ bit;
19641 switch (bit)
19642 {
32930e4e 19643 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19644 printf ("CMOV");
19645 break;
32930e4e 19646 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19647 printf ("SSE");
19648 break;
32930e4e 19649 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19650 printf ("SSE2");
19651 break;
32930e4e 19652 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19653 printf ("SSE3");
19654 break;
32930e4e 19655 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19656 printf ("SSSE3");
19657 break;
32930e4e 19658 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19659 printf ("SSE4_1");
19660 break;
32930e4e 19661 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19662 printf ("SSE4_2");
19663 break;
32930e4e 19664 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19665 printf ("AVX");
19666 break;
32930e4e 19667 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19668 printf ("AVX2");
19669 break;
32930e4e 19670 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19671 printf ("FMA");
19672 break;
32930e4e 19673 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19674 printf ("AVX512F");
19675 break;
32930e4e 19676 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19677 printf ("AVX512CD");
19678 break;
32930e4e 19679 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19680 printf ("AVX512ER");
19681 break;
32930e4e 19682 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19683 printf ("AVX512PF");
19684 break;
32930e4e 19685 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19686 printf ("AVX512VL");
19687 break;
32930e4e 19688 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19689 printf ("AVX512DQ");
19690 break;
32930e4e 19691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19692 printf ("AVX512BW");
19693 break;
32930e4e 19694 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19695 printf ("AVX512_4FMAPS");
19696 break;
32930e4e 19697 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19698 printf ("AVX512_4VNNIW");
19699 break;
32930e4e 19700 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19701 printf ("AVX512_BITALG");
19702 break;
32930e4e 19703 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19704 printf ("AVX512_IFMA");
19705 break;
32930e4e 19706 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19707 printf ("AVX512_VBMI");
19708 break;
32930e4e 19709 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19710 printf ("AVX512_VBMI2");
19711 break;
32930e4e 19712 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19713 printf ("AVX512_VNNI");
19714 break;
32930e4e 19715 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19716 printf ("AVX512_BF16");
19717 break;
65b3d26e
L
19718 default:
19719 printf (_("<unknown: %x>"), bit);
19720 break;
9ef920e9
NC
19721 }
19722 if (bitmask)
19723 printf (", ");
19724 }
19725}
19726
32930e4e
L
19727static void
19728decode_x86_isa (unsigned int bitmask)
19729{
32930e4e
L
19730 while (bitmask)
19731 {
19732 unsigned int bit = bitmask & (- bitmask);
19733
19734 bitmask &= ~ bit;
19735 switch (bit)
19736 {
b0ab0693
L
19737 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19738 printf ("x86-64-baseline");
19739 break;
32930e4e
L
19740 case GNU_PROPERTY_X86_ISA_1_V2:
19741 printf ("x86-64-v2");
19742 break;
19743 case GNU_PROPERTY_X86_ISA_1_V3:
19744 printf ("x86-64-v3");
19745 break;
19746 case GNU_PROPERTY_X86_ISA_1_V4:
19747 printf ("x86-64-v4");
19748 break;
19749 default:
19750 printf (_("<unknown: %x>"), bit);
19751 break;
19752 }
19753 if (bitmask)
19754 printf (", ");
19755 }
19756}
19757
ee2fdd6f 19758static void
a9eafb08 19759decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19760{
0a59decb 19761 if (!bitmask)
90c745dc
L
19762 {
19763 printf (_("<None>"));
19764 return;
19765 }
90c745dc 19766
ee2fdd6f
L
19767 while (bitmask)
19768 {
19769 unsigned int bit = bitmask & (- bitmask);
19770
19771 bitmask &= ~ bit;
19772 switch (bit)
19773 {
19774 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19775 printf ("IBT");
ee2fdd6f 19776 break;
48580982 19777 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19778 printf ("SHSTK");
48580982 19779 break;
279d901e
L
19780 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19781 printf ("LAM_U48");
19782 break;
19783 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19784 printf ("LAM_U57");
19785 break;
ee2fdd6f
L
19786 default:
19787 printf (_("<unknown: %x>"), bit);
19788 break;
19789 }
19790 if (bitmask)
19791 printf (", ");
19792 }
19793}
19794
a9eafb08
L
19795static void
19796decode_x86_feature_2 (unsigned int bitmask)
19797{
0a59decb 19798 if (!bitmask)
90c745dc
L
19799 {
19800 printf (_("<None>"));
19801 return;
19802 }
90c745dc 19803
a9eafb08
L
19804 while (bitmask)
19805 {
19806 unsigned int bit = bitmask & (- bitmask);
19807
19808 bitmask &= ~ bit;
19809 switch (bit)
19810 {
19811 case GNU_PROPERTY_X86_FEATURE_2_X86:
19812 printf ("x86");
19813 break;
19814 case GNU_PROPERTY_X86_FEATURE_2_X87:
19815 printf ("x87");
19816 break;
19817 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19818 printf ("MMX");
19819 break;
19820 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19821 printf ("XMM");
19822 break;
19823 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19824 printf ("YMM");
19825 break;
19826 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19827 printf ("ZMM");
19828 break;
a308b89d
L
19829 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19830 printf ("TMM");
19831 break;
32930e4e
L
19832 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19833 printf ("MASK");
19834 break;
a9eafb08
L
19835 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19836 printf ("FXSR");
19837 break;
19838 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19839 printf ("XSAVE");
19840 break;
19841 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19842 printf ("XSAVEOPT");
19843 break;
19844 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19845 printf ("XSAVEC");
19846 break;
65b3d26e
L
19847 default:
19848 printf (_("<unknown: %x>"), bit);
19849 break;
a9eafb08
L
19850 }
19851 if (bitmask)
19852 printf (", ");
19853 }
19854}
19855
cd702818
SD
19856static void
19857decode_aarch64_feature_1_and (unsigned int bitmask)
19858{
19859 while (bitmask)
19860 {
19861 unsigned int bit = bitmask & (- bitmask);
19862
19863 bitmask &= ~ bit;
19864 switch (bit)
19865 {
19866 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19867 printf ("BTI");
19868 break;
19869
19870 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19871 printf ("PAC");
19872 break;
19873
19874 default:
19875 printf (_("<unknown: %x>"), bit);
19876 break;
19877 }
19878 if (bitmask)
19879 printf (", ");
19880 }
19881}
19882
6320fd00
L
19883static void
19884decode_1_needed (unsigned int bitmask)
19885{
19886 while (bitmask)
19887 {
19888 unsigned int bit = bitmask & (- bitmask);
19889
19890 bitmask &= ~ bit;
19891 switch (bit)
19892 {
19893 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19894 printf ("indirect external access");
19895 break;
19896 default:
19897 printf (_("<unknown: %x>"), bit);
19898 break;
19899 }
19900 if (bitmask)
19901 printf (", ");
19902 }
19903}
19904
9ef920e9 19905static void
dda8d76d 19906print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19907{
19908 unsigned char * ptr = (unsigned char *) pnote->descdata;
19909 unsigned char * ptr_end = ptr + pnote->descsz;
19910 unsigned int size = is_32bit_elf ? 4 : 8;
19911
19912 printf (_(" Properties: "));
19913
1fc87489 19914 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19915 {
19916 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19917 return;
19918 }
19919
6ab2c4ed 19920 while (ptr < ptr_end)
9ef920e9 19921 {
1fc87489 19922 unsigned int j;
6ab2c4ed
MC
19923 unsigned int type;
19924 unsigned int datasz;
19925
19926 if ((size_t) (ptr_end - ptr) < 8)
19927 {
19928 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19929 break;
19930 }
19931
19932 type = byte_get (ptr, 4);
19933 datasz = byte_get (ptr + 4, 4);
9ef920e9 19934
1fc87489 19935 ptr += 8;
9ef920e9 19936
6ab2c4ed 19937 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19938 {
1fc87489
L
19939 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19940 type, datasz);
9ef920e9 19941 break;
1fc87489 19942 }
9ef920e9 19943
1fc87489
L
19944 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19945 {
dda8d76d
NC
19946 if (filedata->file_header.e_machine == EM_X86_64
19947 || filedata->file_header.e_machine == EM_IAMCU
19948 || filedata->file_header.e_machine == EM_386)
1fc87489 19949 {
aa7bca9b
L
19950 unsigned int bitmask;
19951
19952 if (datasz == 4)
0a59decb 19953 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19954 else
19955 bitmask = 0;
19956
1fc87489
L
19957 switch (type)
19958 {
19959 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19960 if (datasz != 4)
aa7bca9b
L
19961 printf (_("x86 ISA used: <corrupt length: %#x> "),
19962 datasz);
1fc87489 19963 else
aa7bca9b
L
19964 {
19965 printf ("x86 ISA used: ");
19966 decode_x86_isa (bitmask);
19967 }
1fc87489 19968 goto next;
9ef920e9 19969
1fc87489 19970 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19971 if (datasz != 4)
aa7bca9b
L
19972 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19973 datasz);
1fc87489 19974 else
aa7bca9b
L
19975 {
19976 printf ("x86 ISA needed: ");
19977 decode_x86_isa (bitmask);
19978 }
1fc87489 19979 goto next;
9ef920e9 19980
ee2fdd6f 19981 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19982 if (datasz != 4)
aa7bca9b
L
19983 printf (_("x86 feature: <corrupt length: %#x> "),
19984 datasz);
ee2fdd6f 19985 else
aa7bca9b
L
19986 {
19987 printf ("x86 feature: ");
a9eafb08
L
19988 decode_x86_feature_1 (bitmask);
19989 }
19990 goto next;
19991
19992 case GNU_PROPERTY_X86_FEATURE_2_USED:
19993 if (datasz != 4)
19994 printf (_("x86 feature used: <corrupt length: %#x> "),
19995 datasz);
19996 else
19997 {
19998 printf ("x86 feature used: ");
19999 decode_x86_feature_2 (bitmask);
20000 }
20001 goto next;
20002
20003 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20004 if (datasz != 4)
20005 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20006 else
20007 {
20008 printf ("x86 feature needed: ");
20009 decode_x86_feature_2 (bitmask);
20010 }
20011 goto next;
20012
20013 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20014 if (datasz != 4)
20015 printf (_("x86 ISA used: <corrupt length: %#x> "),
20016 datasz);
20017 else
20018 {
20019 printf ("x86 ISA used: ");
20020 decode_x86_compat_isa (bitmask);
20021 }
20022 goto next;
20023
20024 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20025 if (datasz != 4)
20026 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20027 datasz);
20028 else
20029 {
20030 printf ("x86 ISA needed: ");
20031 decode_x86_compat_isa (bitmask);
aa7bca9b 20032 }
ee2fdd6f
L
20033 goto next;
20034
32930e4e
L
20035 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20036 if (datasz != 4)
20037 printf (_("x86 ISA used: <corrupt length: %#x> "),
20038 datasz);
20039 else
20040 {
20041 printf ("x86 ISA used: ");
20042 decode_x86_compat_2_isa (bitmask);
20043 }
20044 goto next;
20045
20046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20047 if (datasz != 4)
20048 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20049 datasz);
20050 else
20051 {
20052 printf ("x86 ISA needed: ");
20053 decode_x86_compat_2_isa (bitmask);
20054 }
20055 goto next;
20056
1fc87489
L
20057 default:
20058 break;
20059 }
20060 }
cd702818
SD
20061 else if (filedata->file_header.e_machine == EM_AARCH64)
20062 {
20063 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20064 {
20065 printf ("AArch64 feature: ");
20066 if (datasz != 4)
20067 printf (_("<corrupt length: %#x> "), datasz);
20068 else
20069 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20070 goto next;
20071 }
20072 }
1fc87489
L
20073 }
20074 else
20075 {
20076 switch (type)
9ef920e9 20077 {
1fc87489
L
20078 case GNU_PROPERTY_STACK_SIZE:
20079 printf (_("stack size: "));
20080 if (datasz != size)
20081 printf (_("<corrupt length: %#x> "), datasz);
20082 else
20083 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20084 goto next;
20085
20086 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20087 printf ("no copy on protected ");
20088 if (datasz)
20089 printf (_("<corrupt length: %#x> "), datasz);
20090 goto next;
20091
20092 default:
5a767724
L
20093 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20094 && type <= GNU_PROPERTY_UINT32_AND_HI)
20095 || (type >= GNU_PROPERTY_UINT32_OR_LO
20096 && type <= GNU_PROPERTY_UINT32_OR_HI))
20097 {
6320fd00
L
20098 switch (type)
20099 {
20100 case GNU_PROPERTY_1_NEEDED:
20101 if (datasz != 4)
20102 printf (_("1_needed: <corrupt length: %#x> "),
20103 datasz);
20104 else
20105 {
20106 unsigned int bitmask = byte_get (ptr, 4);
20107 printf ("1_needed: ");
20108 decode_1_needed (bitmask);
20109 }
20110 goto next;
20111
20112 default:
20113 break;
20114 }
5a767724
L
20115 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20116 printf (_("UINT32_AND (%#x): "), type);
20117 else
20118 printf (_("UINT32_OR (%#x): "), type);
20119 if (datasz != 4)
20120 printf (_("<corrupt length: %#x> "), datasz);
20121 else
20122 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20123 goto next;
20124 }
9ef920e9
NC
20125 break;
20126 }
9ef920e9
NC
20127 }
20128
1fc87489
L
20129 if (type < GNU_PROPERTY_LOPROC)
20130 printf (_("<unknown type %#x data: "), type);
20131 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20132 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20133 else
20134 printf (_("<application-specific type %#x data: "), type);
20135 for (j = 0; j < datasz; ++j)
20136 printf ("%02x ", ptr[j] & 0xff);
20137 printf (">");
20138
dc1e8a47 20139 next:
9ef920e9 20140 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20141 if (ptr == ptr_end)
20142 break;
1fc87489 20143
6ab2c4ed
MC
20144 if (do_wide)
20145 printf (", ");
20146 else
20147 printf ("\n\t");
9ef920e9
NC
20148 }
20149
20150 printf ("\n");
20151}
20152
015dc7e1 20153static bool
dda8d76d 20154print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20155{
1449284b 20156 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20157 switch (pnote->type)
20158 {
20159 case NT_GNU_BUILD_ID:
20160 {
20161 unsigned long i;
20162
20163 printf (_(" Build ID: "));
20164 for (i = 0; i < pnote->descsz; ++i)
20165 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20166 printf ("\n");
664f90a3
TT
20167 }
20168 break;
20169
20170 case NT_GNU_ABI_TAG:
20171 {
20172 unsigned long os, major, minor, subminor;
20173 const char *osname;
20174
3102e897
NC
20175 /* PR 17531: file: 030-599401-0.004. */
20176 if (pnote->descsz < 16)
20177 {
20178 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20179 break;
20180 }
20181
664f90a3
TT
20182 os = byte_get ((unsigned char *) pnote->descdata, 4);
20183 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20184 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20185 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20186
20187 switch (os)
20188 {
20189 case GNU_ABI_TAG_LINUX:
20190 osname = "Linux";
20191 break;
20192 case GNU_ABI_TAG_HURD:
20193 osname = "Hurd";
20194 break;
20195 case GNU_ABI_TAG_SOLARIS:
20196 osname = "Solaris";
20197 break;
20198 case GNU_ABI_TAG_FREEBSD:
20199 osname = "FreeBSD";
20200 break;
20201 case GNU_ABI_TAG_NETBSD:
20202 osname = "NetBSD";
20203 break;
14ae95f2
RM
20204 case GNU_ABI_TAG_SYLLABLE:
20205 osname = "Syllable";
20206 break;
20207 case GNU_ABI_TAG_NACL:
20208 osname = "NaCl";
20209 break;
664f90a3
TT
20210 default:
20211 osname = "Unknown";
20212 break;
20213 }
20214
20215 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20216 major, minor, subminor);
20217 }
20218 break;
926c5385
CC
20219
20220 case NT_GNU_GOLD_VERSION:
20221 {
20222 unsigned long i;
20223
20224 printf (_(" Version: "));
20225 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20226 printf ("%c", pnote->descdata[i]);
20227 printf ("\n");
20228 }
20229 break;
1449284b
NC
20230
20231 case NT_GNU_HWCAP:
20232 {
20233 unsigned long num_entries, mask;
20234
20235 /* Hardware capabilities information. Word 0 is the number of entries.
20236 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20237 is a series of entries, where each entry is a single byte followed
20238 by a nul terminated string. The byte gives the bit number to test
20239 if enabled in the bitmask. */
20240 printf (_(" Hardware Capabilities: "));
20241 if (pnote->descsz < 8)
20242 {
32ec8896 20243 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20244 return false;
1449284b
NC
20245 }
20246 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20247 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20248 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20249 /* FIXME: Add code to display the entries... */
20250 }
20251 break;
20252
9ef920e9 20253 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20254 print_gnu_property_note (filedata, pnote);
9ef920e9 20255 break;
9abca702 20256
1449284b
NC
20257 default:
20258 /* Handle unrecognised types. An error message should have already been
20259 created by get_gnu_elf_note_type(), so all that we need to do is to
20260 display the data. */
20261 {
20262 unsigned long i;
20263
20264 printf (_(" Description data: "));
20265 for (i = 0; i < pnote->descsz; ++i)
20266 printf ("%02x ", pnote->descdata[i] & 0xff);
20267 printf ("\n");
20268 }
20269 break;
664f90a3
TT
20270 }
20271
015dc7e1 20272 return true;
664f90a3
TT
20273}
20274
685080f2
NC
20275static const char *
20276get_v850_elf_note_type (enum v850_notes n_type)
20277{
20278 static char buff[64];
20279
20280 switch (n_type)
20281 {
20282 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20283 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20284 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20285 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20286 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20287 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20288 default:
20289 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20290 return buff;
20291 }
20292}
20293
015dc7e1 20294static bool
685080f2
NC
20295print_v850_note (Elf_Internal_Note * pnote)
20296{
20297 unsigned int val;
20298
20299 if (pnote->descsz != 4)
015dc7e1 20300 return false;
32ec8896 20301
685080f2
NC
20302 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20303
20304 if (val == 0)
20305 {
20306 printf (_("not set\n"));
015dc7e1 20307 return true;
685080f2
NC
20308 }
20309
20310 switch (pnote->type)
20311 {
20312 case V850_NOTE_ALIGNMENT:
20313 switch (val)
20314 {
015dc7e1
AM
20315 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20316 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20317 }
20318 break;
14ae95f2 20319
685080f2
NC
20320 case V850_NOTE_DATA_SIZE:
20321 switch (val)
20322 {
015dc7e1
AM
20323 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20324 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20325 }
20326 break;
14ae95f2 20327
685080f2
NC
20328 case V850_NOTE_FPU_INFO:
20329 switch (val)
20330 {
015dc7e1
AM
20331 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20332 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20333 }
20334 break;
14ae95f2 20335
685080f2
NC
20336 case V850_NOTE_MMU_INFO:
20337 case V850_NOTE_CACHE_INFO:
20338 case V850_NOTE_SIMD_INFO:
20339 if (val == EF_RH850_SIMD)
20340 {
20341 printf (_("yes\n"));
015dc7e1 20342 return true;
685080f2
NC
20343 }
20344 break;
20345
20346 default:
20347 /* An 'unknown note type' message will already have been displayed. */
20348 break;
20349 }
20350
20351 printf (_("unknown value: %x\n"), val);
015dc7e1 20352 return false;
685080f2
NC
20353}
20354
015dc7e1 20355static bool
c6056a74
SF
20356process_netbsd_elf_note (Elf_Internal_Note * pnote)
20357{
20358 unsigned int version;
20359
20360 switch (pnote->type)
20361 {
20362 case NT_NETBSD_IDENT:
b966f55f
AM
20363 if (pnote->descsz < 1)
20364 break;
c6056a74
SF
20365 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20366 if ((version / 10000) % 100)
b966f55f 20367 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20368 version, version / 100000000, (version / 1000000) % 100,
20369 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20370 'A' + (version / 10000) % 26);
c6056a74
SF
20371 else
20372 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20373 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20374 (version / 100) % 100);
015dc7e1 20375 return true;
c6056a74
SF
20376
20377 case NT_NETBSD_MARCH:
9abca702 20378 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20379 pnote->descdata);
015dc7e1 20380 return true;
c6056a74 20381
9abca702 20382 case NT_NETBSD_PAX:
b966f55f
AM
20383 if (pnote->descsz < 1)
20384 break;
9abca702
CZ
20385 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20386 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20387 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20388 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20389 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20390 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20391 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20392 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20393 return true;
c6056a74 20394 }
b966f55f
AM
20395
20396 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20397 pnote->descsz, pnote->type);
015dc7e1 20398 return false;
c6056a74
SF
20399}
20400
f4ddf30f 20401static const char *
dda8d76d 20402get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20403{
f4ddf30f
JB
20404 switch (e_type)
20405 {
20406 case NT_FREEBSD_THRMISC:
20407 return _("NT_THRMISC (thrmisc structure)");
20408 case NT_FREEBSD_PROCSTAT_PROC:
20409 return _("NT_PROCSTAT_PROC (proc data)");
20410 case NT_FREEBSD_PROCSTAT_FILES:
20411 return _("NT_PROCSTAT_FILES (files data)");
20412 case NT_FREEBSD_PROCSTAT_VMMAP:
20413 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20414 case NT_FREEBSD_PROCSTAT_GROUPS:
20415 return _("NT_PROCSTAT_GROUPS (groups data)");
20416 case NT_FREEBSD_PROCSTAT_UMASK:
20417 return _("NT_PROCSTAT_UMASK (umask data)");
20418 case NT_FREEBSD_PROCSTAT_RLIMIT:
20419 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20420 case NT_FREEBSD_PROCSTAT_OSREL:
20421 return _("NT_PROCSTAT_OSREL (osreldate data)");
20422 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20423 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20424 case NT_FREEBSD_PROCSTAT_AUXV:
20425 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20426 case NT_FREEBSD_PTLWPINFO:
20427 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20428 }
dda8d76d 20429 return get_note_type (filedata, e_type);
f4ddf30f
JB
20430}
20431
9437c45b 20432static const char *
dda8d76d 20433get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20434{
20435 static char buff[64];
20436
540e6170
CZ
20437 switch (e_type)
20438 {
20439 case NT_NETBSDCORE_PROCINFO:
20440 /* NetBSD core "procinfo" structure. */
20441 return _("NetBSD procinfo structure");
9437c45b 20442
540e6170
CZ
20443 case NT_NETBSDCORE_AUXV:
20444 return _("NetBSD ELF auxiliary vector data");
9437c45b 20445
06d949ec
KR
20446 case NT_NETBSDCORE_LWPSTATUS:
20447 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20448
540e6170 20449 default:
06d949ec 20450 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20451 defined for NetBSD core files. If the note type is less
20452 than the start of the machine-dependent note types, we don't
20453 understand it. */
20454
20455 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20456 {
20457 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20458 return buff;
20459 }
20460 break;
9437c45b
JT
20461 }
20462
dda8d76d 20463 switch (filedata->file_header.e_machine)
9437c45b
JT
20464 {
20465 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20466 and PT_GETFPREGS == mach+2. */
20467
20468 case EM_OLD_ALPHA:
20469 case EM_ALPHA:
20470 case EM_SPARC:
20471 case EM_SPARC32PLUS:
20472 case EM_SPARCV9:
20473 switch (e_type)
20474 {
2b692964 20475 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20476 return _("PT_GETREGS (reg structure)");
2b692964 20477 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20478 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20479 default:
20480 break;
20481 }
20482 break;
20483
c0d38b0e
CZ
20484 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20485 There's also old PT___GETREGS40 == mach + 1 for old reg
20486 structure which lacks GBR. */
20487 case EM_SH:
20488 switch (e_type)
20489 {
20490 case NT_NETBSDCORE_FIRSTMACH + 1:
20491 return _("PT___GETREGS40 (old reg structure)");
20492 case NT_NETBSDCORE_FIRSTMACH + 3:
20493 return _("PT_GETREGS (reg structure)");
20494 case NT_NETBSDCORE_FIRSTMACH + 5:
20495 return _("PT_GETFPREGS (fpreg structure)");
20496 default:
20497 break;
20498 }
20499 break;
20500
9437c45b
JT
20501 /* On all other arch's, PT_GETREGS == mach+1 and
20502 PT_GETFPREGS == mach+3. */
20503 default:
20504 switch (e_type)
20505 {
2b692964 20506 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20507 return _("PT_GETREGS (reg structure)");
2b692964 20508 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20509 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20510 default:
20511 break;
20512 }
20513 }
20514
9cf03b7e 20515 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20516 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20517 return buff;
20518}
20519
98ca73af
FC
20520static const char *
20521get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20522{
20523 switch (e_type)
20524 {
20525 case NT_OPENBSD_PROCINFO:
20526 return _("OpenBSD procinfo structure");
20527 case NT_OPENBSD_AUXV:
20528 return _("OpenBSD ELF auxiliary vector data");
20529 case NT_OPENBSD_REGS:
20530 return _("OpenBSD regular registers");
20531 case NT_OPENBSD_FPREGS:
20532 return _("OpenBSD floating point registers");
20533 case NT_OPENBSD_WCOOKIE:
20534 return _("OpenBSD window cookie");
20535 }
20536
20537 return get_note_type (filedata, e_type);
20538}
20539
70616151
TT
20540static const char *
20541get_stapsdt_note_type (unsigned e_type)
20542{
20543 static char buff[64];
20544
20545 switch (e_type)
20546 {
20547 case NT_STAPSDT:
20548 return _("NT_STAPSDT (SystemTap probe descriptors)");
20549
20550 default:
20551 break;
20552 }
20553
20554 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20555 return buff;
20556}
20557
015dc7e1 20558static bool
c6a9fc58
TT
20559print_stapsdt_note (Elf_Internal_Note *pnote)
20560{
3ca60c57
NC
20561 size_t len, maxlen;
20562 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20563 char *data = pnote->descdata;
20564 char *data_end = pnote->descdata + pnote->descsz;
20565 bfd_vma pc, base_addr, semaphore;
20566 char *provider, *probe, *arg_fmt;
20567
3ca60c57
NC
20568 if (pnote->descsz < (addr_size * 3))
20569 goto stapdt_note_too_small;
20570
c6a9fc58
TT
20571 pc = byte_get ((unsigned char *) data, addr_size);
20572 data += addr_size;
3ca60c57 20573
c6a9fc58
TT
20574 base_addr = byte_get ((unsigned char *) data, addr_size);
20575 data += addr_size;
3ca60c57 20576
c6a9fc58
TT
20577 semaphore = byte_get ((unsigned char *) data, addr_size);
20578 data += addr_size;
20579
3ca60c57
NC
20580 if (data >= data_end)
20581 goto stapdt_note_too_small;
20582 maxlen = data_end - data;
20583 len = strnlen (data, maxlen);
20584 if (len < maxlen)
20585 {
20586 provider = data;
20587 data += len + 1;
20588 }
20589 else
20590 goto stapdt_note_too_small;
20591
20592 if (data >= data_end)
20593 goto stapdt_note_too_small;
20594 maxlen = data_end - data;
20595 len = strnlen (data, maxlen);
20596 if (len < maxlen)
20597 {
20598 probe = data;
20599 data += len + 1;
20600 }
20601 else
20602 goto stapdt_note_too_small;
9abca702 20603
3ca60c57
NC
20604 if (data >= data_end)
20605 goto stapdt_note_too_small;
20606 maxlen = data_end - data;
20607 len = strnlen (data, maxlen);
20608 if (len < maxlen)
20609 {
20610 arg_fmt = data;
20611 data += len + 1;
20612 }
20613 else
20614 goto stapdt_note_too_small;
c6a9fc58
TT
20615
20616 printf (_(" Provider: %s\n"), provider);
20617 printf (_(" Name: %s\n"), probe);
20618 printf (_(" Location: "));
20619 print_vma (pc, FULL_HEX);
20620 printf (_(", Base: "));
20621 print_vma (base_addr, FULL_HEX);
20622 printf (_(", Semaphore: "));
20623 print_vma (semaphore, FULL_HEX);
9cf03b7e 20624 printf ("\n");
c6a9fc58
TT
20625 printf (_(" Arguments: %s\n"), arg_fmt);
20626
20627 return data == data_end;
3ca60c57
NC
20628
20629 stapdt_note_too_small:
20630 printf (_(" <corrupt - note is too small>\n"));
20631 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20632 return false;
c6a9fc58
TT
20633}
20634
e5382207
LB
20635static bool
20636print_fdo_note (Elf_Internal_Note * pnote)
20637{
20638 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20639 {
20640 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20641 return true;
20642 }
20643 return false;
20644}
20645
00e98fc7
TG
20646static const char *
20647get_ia64_vms_note_type (unsigned e_type)
20648{
20649 static char buff[64];
20650
20651 switch (e_type)
20652 {
20653 case NT_VMS_MHD:
20654 return _("NT_VMS_MHD (module header)");
20655 case NT_VMS_LNM:
20656 return _("NT_VMS_LNM (language name)");
20657 case NT_VMS_SRC:
20658 return _("NT_VMS_SRC (source files)");
20659 case NT_VMS_TITLE:
9cf03b7e 20660 return "NT_VMS_TITLE";
00e98fc7
TG
20661 case NT_VMS_EIDC:
20662 return _("NT_VMS_EIDC (consistency check)");
20663 case NT_VMS_FPMODE:
20664 return _("NT_VMS_FPMODE (FP mode)");
20665 case NT_VMS_LINKTIME:
9cf03b7e 20666 return "NT_VMS_LINKTIME";
00e98fc7
TG
20667 case NT_VMS_IMGNAM:
20668 return _("NT_VMS_IMGNAM (image name)");
20669 case NT_VMS_IMGID:
20670 return _("NT_VMS_IMGID (image id)");
20671 case NT_VMS_LINKID:
20672 return _("NT_VMS_LINKID (link id)");
20673 case NT_VMS_IMGBID:
20674 return _("NT_VMS_IMGBID (build id)");
20675 case NT_VMS_GSTNAM:
20676 return _("NT_VMS_GSTNAM (sym table name)");
20677 case NT_VMS_ORIG_DYN:
9cf03b7e 20678 return "NT_VMS_ORIG_DYN";
00e98fc7 20679 case NT_VMS_PATCHTIME:
9cf03b7e 20680 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20681 default:
20682 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20683 return buff;
20684 }
20685}
20686
015dc7e1 20687static bool
00e98fc7
TG
20688print_ia64_vms_note (Elf_Internal_Note * pnote)
20689{
8d18bf79
NC
20690 int maxlen = pnote->descsz;
20691
20692 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20693 goto desc_size_fail;
20694
00e98fc7
TG
20695 switch (pnote->type)
20696 {
20697 case NT_VMS_MHD:
8d18bf79
NC
20698 if (maxlen <= 36)
20699 goto desc_size_fail;
20700
20701 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20702
20703 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20704 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20705 if (l + 34 < maxlen)
20706 {
20707 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20708 if (l + 35 < maxlen)
20709 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20710 else
20711 printf (_(" Module version : <missing>\n"));
20712 }
00e98fc7 20713 else
8d18bf79
NC
20714 {
20715 printf (_(" Module name : <missing>\n"));
20716 printf (_(" Module version : <missing>\n"));
20717 }
00e98fc7 20718 break;
8d18bf79 20719
00e98fc7 20720 case NT_VMS_LNM:
8d18bf79 20721 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20722 break;
8d18bf79 20723
00e98fc7
TG
20724#ifdef BFD64
20725 case NT_VMS_FPMODE:
9cf03b7e 20726 printf (_(" Floating Point mode: "));
8d18bf79
NC
20727 if (maxlen < 8)
20728 goto desc_size_fail;
20729 /* FIXME: Generate an error if descsz > 8 ? */
20730
4a5cb34f 20731 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20732 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20733 break;
8d18bf79 20734
00e98fc7
TG
20735 case NT_VMS_LINKTIME:
20736 printf (_(" Link time: "));
8d18bf79
NC
20737 if (maxlen < 8)
20738 goto desc_size_fail;
20739 /* FIXME: Generate an error if descsz > 8 ? */
20740
00e98fc7 20741 print_vms_time
8d18bf79 20742 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20743 printf ("\n");
20744 break;
8d18bf79 20745
00e98fc7
TG
20746 case NT_VMS_PATCHTIME:
20747 printf (_(" Patch time: "));
8d18bf79
NC
20748 if (maxlen < 8)
20749 goto desc_size_fail;
20750 /* FIXME: Generate an error if descsz > 8 ? */
20751
00e98fc7 20752 print_vms_time
8d18bf79 20753 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20754 printf ("\n");
20755 break;
8d18bf79 20756
00e98fc7 20757 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20758 if (maxlen < 34)
20759 goto desc_size_fail;
20760
00e98fc7
TG
20761 printf (_(" Major id: %u, minor id: %u\n"),
20762 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20763 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20764 printf (_(" Last modified : "));
00e98fc7
TG
20765 print_vms_time
20766 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20767 printf (_("\n Link flags : "));
4a5cb34f 20768 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20769 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20770 printf (_(" Header flags: 0x%08x\n"),
948f632f 20771 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20772 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20773 break;
20774#endif
8d18bf79 20775
00e98fc7 20776 case NT_VMS_IMGNAM:
8d18bf79 20777 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20778 break;
8d18bf79 20779
00e98fc7 20780 case NT_VMS_GSTNAM:
8d18bf79 20781 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20782 break;
8d18bf79 20783
00e98fc7 20784 case NT_VMS_IMGID:
8d18bf79 20785 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20786 break;
8d18bf79 20787
00e98fc7 20788 case NT_VMS_LINKID:
8d18bf79 20789 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20790 break;
8d18bf79 20791
00e98fc7 20792 default:
015dc7e1 20793 return false;
00e98fc7 20794 }
8d18bf79 20795
015dc7e1 20796 return true;
8d18bf79
NC
20797
20798 desc_size_fail:
20799 printf (_(" <corrupt - data size is too small>\n"));
20800 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20801 return false;
00e98fc7
TG
20802}
20803
fd486f32
AM
20804struct build_attr_cache {
20805 Filedata *filedata;
20806 char *strtab;
20807 unsigned long strtablen;
20808 Elf_Internal_Sym *symtab;
20809 unsigned long nsyms;
20810} ba_cache;
20811
6f156d7a
NC
20812/* Find the symbol associated with a build attribute that is attached
20813 to address OFFSET. If PNAME is non-NULL then store the name of
20814 the symbol (if found) in the provided pointer, Returns NULL if a
20815 symbol could not be found. */
c799a79d 20816
6f156d7a 20817static Elf_Internal_Sym *
015dc7e1
AM
20818get_symbol_for_build_attribute (Filedata *filedata,
20819 unsigned long offset,
20820 bool is_open_attr,
20821 const char **pname)
9ef920e9 20822{
fd486f32
AM
20823 Elf_Internal_Sym *saved_sym = NULL;
20824 Elf_Internal_Sym *sym;
9ef920e9 20825
dda8d76d 20826 if (filedata->section_headers != NULL
fd486f32 20827 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20828 {
c799a79d 20829 Elf_Internal_Shdr * symsec;
9ef920e9 20830
fd486f32
AM
20831 free (ba_cache.strtab);
20832 ba_cache.strtab = NULL;
20833 free (ba_cache.symtab);
20834 ba_cache.symtab = NULL;
20835
c799a79d 20836 /* Load the symbol and string sections. */
dda8d76d
NC
20837 for (symsec = filedata->section_headers;
20838 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20839 symsec ++)
9ef920e9 20840 {
28d13567
AM
20841 if (symsec->sh_type == SHT_SYMTAB
20842 && get_symtab (filedata, symsec,
20843 &ba_cache.symtab, &ba_cache.nsyms,
20844 &ba_cache.strtab, &ba_cache.strtablen))
20845 break;
9ef920e9 20846 }
fd486f32 20847 ba_cache.filedata = filedata;
9ef920e9
NC
20848 }
20849
fd486f32 20850 if (ba_cache.symtab == NULL)
6f156d7a 20851 return NULL;
9ef920e9 20852
c799a79d 20853 /* Find a symbol whose value matches offset. */
fd486f32 20854 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20855 if (sym->st_value == offset)
20856 {
fd486f32 20857 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20858 /* Huh ? This should not happen. */
20859 continue;
9ef920e9 20860
fd486f32 20861 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20862 continue;
9ef920e9 20863
9b9b1092 20864 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20865 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20866 if (ba_cache.strtab[sym->st_name] == '$'
20867 && ba_cache.strtab[sym->st_name + 1] != 0
20868 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20869 continue;
20870
c799a79d
NC
20871 if (is_open_attr)
20872 {
20873 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20874 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20875 FUNC symbols entirely. */
20876 switch (ELF_ST_TYPE (sym->st_info))
20877 {
c799a79d 20878 case STT_OBJECT:
6f156d7a 20879 case STT_FILE:
c799a79d 20880 saved_sym = sym;
6f156d7a
NC
20881 if (sym->st_size)
20882 {
20883 /* If the symbol has a size associated
20884 with it then we can stop searching. */
fd486f32 20885 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20886 }
c799a79d 20887 continue;
9ef920e9 20888
c799a79d
NC
20889 case STT_FUNC:
20890 /* Ignore function symbols. */
20891 continue;
20892
20893 default:
20894 break;
20895 }
20896
20897 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20898 {
c799a79d
NC
20899 case STB_GLOBAL:
20900 if (saved_sym == NULL
20901 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20902 saved_sym = sym;
20903 break;
c871dade 20904
c799a79d
NC
20905 case STB_LOCAL:
20906 if (saved_sym == NULL)
20907 saved_sym = sym;
20908 break;
20909
20910 default:
9ef920e9
NC
20911 break;
20912 }
20913 }
c799a79d
NC
20914 else
20915 {
20916 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20917 continue;
20918
20919 saved_sym = sym;
20920 break;
20921 }
20922 }
20923
6f156d7a 20924 if (saved_sym && pname)
fd486f32 20925 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20926
20927 return saved_sym;
c799a79d
NC
20928}
20929
d20e98ab
NC
20930/* Returns true iff addr1 and addr2 are in the same section. */
20931
015dc7e1 20932static bool
d20e98ab
NC
20933same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20934{
20935 Elf_Internal_Shdr * a1;
20936 Elf_Internal_Shdr * a2;
20937
20938 a1 = find_section_by_address (filedata, addr1);
20939 a2 = find_section_by_address (filedata, addr2);
9abca702 20940
d20e98ab
NC
20941 return a1 == a2 && a1 != NULL;
20942}
20943
015dc7e1 20944static bool
dda8d76d
NC
20945print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20946 Filedata * filedata)
c799a79d 20947{
015dc7e1
AM
20948 static unsigned long global_offset = 0;
20949 static unsigned long global_end = 0;
20950 static unsigned long func_offset = 0;
20951 static unsigned long func_end = 0;
c871dade 20952
015dc7e1
AM
20953 Elf_Internal_Sym *sym;
20954 const char *name;
20955 unsigned long start;
20956 unsigned long end;
20957 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20958
20959 switch (pnote->descsz)
c799a79d 20960 {
6f156d7a
NC
20961 case 0:
20962 /* A zero-length description means that the range of
20963 the previous note of the same type should be used. */
c799a79d 20964 if (is_open_attr)
c871dade 20965 {
6f156d7a
NC
20966 if (global_end > global_offset)
20967 printf (_(" Applies to region from %#lx to %#lx\n"),
20968 global_offset, global_end);
20969 else
20970 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20971 }
20972 else
20973 {
6f156d7a
NC
20974 if (func_end > func_offset)
20975 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20976 else
20977 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20978 }
015dc7e1 20979 return true;
9ef920e9 20980
6f156d7a
NC
20981 case 4:
20982 start = byte_get ((unsigned char *) pnote->descdata, 4);
20983 end = 0;
20984 break;
20985
20986 case 8:
c74147bb
NC
20987 start = byte_get ((unsigned char *) pnote->descdata, 4);
20988 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20989 break;
20990
20991 case 16:
20992 start = byte_get ((unsigned char *) pnote->descdata, 8);
20993 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20994 break;
9abca702 20995
6f156d7a 20996 default:
c799a79d
NC
20997 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20998 printf (_(" <invalid descsz>"));
015dc7e1 20999 return false;
c799a79d
NC
21000 }
21001
6f156d7a
NC
21002 name = NULL;
21003 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21004 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21005 in order to avoid them being confused with the start address of the
21006 first function in the file... */
21007 if (sym == NULL && is_open_attr)
21008 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21009 & name);
6f156d7a
NC
21010
21011 if (end == 0 && sym != NULL && sym->st_size > 0)
21012 end = start + sym->st_size;
c799a79d
NC
21013
21014 if (is_open_attr)
21015 {
d20e98ab
NC
21016 /* FIXME: Need to properly allow for section alignment.
21017 16 is just the alignment used on x86_64. */
21018 if (global_end > 0
21019 && start > BFD_ALIGN (global_end, 16)
21020 /* Build notes are not guaranteed to be organised in order of
21021 increasing address, but we should find the all of the notes
21022 for one section in the same place. */
21023 && same_section (filedata, start, global_end))
6f156d7a
NC
21024 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21025 global_end + 1, start - 1);
21026
21027 printf (_(" Applies to region from %#lx"), start);
21028 global_offset = start;
21029
21030 if (end)
21031 {
21032 printf (_(" to %#lx"), end);
21033 global_end = end;
21034 }
c799a79d
NC
21035 }
21036 else
21037 {
6f156d7a
NC
21038 printf (_(" Applies to region from %#lx"), start);
21039 func_offset = start;
21040
21041 if (end)
21042 {
21043 printf (_(" to %#lx"), end);
21044 func_end = end;
21045 }
c799a79d
NC
21046 }
21047
6f156d7a
NC
21048 if (sym && name)
21049 printf (_(" (%s)"), name);
21050
21051 printf ("\n");
015dc7e1 21052 return true;
9ef920e9
NC
21053}
21054
015dc7e1 21055static bool
9ef920e9
NC
21056print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21057{
1d15e434
NC
21058 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21059 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21060 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21061 char name_type;
21062 char name_attribute;
1d15e434 21063 const char * expected_types;
9ef920e9
NC
21064 const char * name = pnote->namedata;
21065 const char * text;
88305e1b 21066 signed int left;
9ef920e9
NC
21067
21068 if (name == NULL || pnote->namesz < 2)
21069 {
21070 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21071 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21072 return false;
9ef920e9
NC
21073 }
21074
6f156d7a
NC
21075 if (do_wide)
21076 left = 28;
21077 else
21078 left = 20;
88305e1b
NC
21079
21080 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21081 if (name[0] == 'G' && name[1] == 'A')
21082 {
6f156d7a
NC
21083 if (pnote->namesz < 4)
21084 {
21085 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21086 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21087 return false;
6f156d7a
NC
21088 }
21089
88305e1b
NC
21090 printf ("GA");
21091 name += 2;
21092 left -= 2;
21093 }
21094
9ef920e9
NC
21095 switch ((name_type = * name))
21096 {
21097 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21098 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21099 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21100 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21101 printf ("%c", * name);
88305e1b 21102 left --;
9ef920e9
NC
21103 break;
21104 default:
21105 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21106 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21107 return false;
9ef920e9
NC
21108 }
21109
9ef920e9
NC
21110 ++ name;
21111 text = NULL;
21112
21113 switch ((name_attribute = * name))
21114 {
21115 case GNU_BUILD_ATTRIBUTE_VERSION:
21116 text = _("<version>");
1d15e434 21117 expected_types = string_expected;
9ef920e9
NC
21118 ++ name;
21119 break;
21120 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21121 text = _("<stack prot>");
75d7d298 21122 expected_types = "!+*";
9ef920e9
NC
21123 ++ name;
21124 break;
21125 case GNU_BUILD_ATTRIBUTE_RELRO:
21126 text = _("<relro>");
1d15e434 21127 expected_types = bool_expected;
9ef920e9
NC
21128 ++ name;
21129 break;
21130 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21131 text = _("<stack size>");
1d15e434 21132 expected_types = number_expected;
9ef920e9
NC
21133 ++ name;
21134 break;
21135 case GNU_BUILD_ATTRIBUTE_TOOL:
21136 text = _("<tool>");
1d15e434 21137 expected_types = string_expected;
9ef920e9
NC
21138 ++ name;
21139 break;
21140 case GNU_BUILD_ATTRIBUTE_ABI:
21141 text = _("<ABI>");
21142 expected_types = "$*";
21143 ++ name;
21144 break;
21145 case GNU_BUILD_ATTRIBUTE_PIC:
21146 text = _("<PIC>");
1d15e434 21147 expected_types = number_expected;
9ef920e9
NC
21148 ++ name;
21149 break;
a8be5506
NC
21150 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21151 text = _("<short enum>");
1d15e434 21152 expected_types = bool_expected;
a8be5506
NC
21153 ++ name;
21154 break;
9ef920e9
NC
21155 default:
21156 if (ISPRINT (* name))
21157 {
21158 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21159
21160 if (len > left && ! do_wide)
21161 len = left;
75d7d298 21162 printf ("%.*s:", len, name);
9ef920e9 21163 left -= len;
0dd6ae21 21164 name += len;
9ef920e9
NC
21165 }
21166 else
21167 {
3e6b6445 21168 static char tmpbuf [128];
88305e1b 21169
3e6b6445
NC
21170 error (_("unrecognised byte in name field: %d\n"), * name);
21171 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21172 text = tmpbuf;
21173 name ++;
9ef920e9
NC
21174 }
21175 expected_types = "*$!+";
21176 break;
21177 }
21178
21179 if (text)
88305e1b 21180 left -= printf ("%s", text);
9ef920e9
NC
21181
21182 if (strchr (expected_types, name_type) == NULL)
75d7d298 21183 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21184
21185 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21186 {
21187 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21188 (unsigned long) pnote->namesz,
21189 (long) (name - pnote->namedata));
015dc7e1 21190 return false;
9ef920e9
NC
21191 }
21192
21193 if (left < 1 && ! do_wide)
015dc7e1 21194 return true;
9ef920e9
NC
21195
21196 switch (name_type)
21197 {
21198 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21199 {
b06b2c92 21200 unsigned int bytes;
ddef72cd
NC
21201 unsigned long long val = 0;
21202 unsigned int shift = 0;
21203 char * decoded = NULL;
21204
b06b2c92
NC
21205 bytes = pnote->namesz - (name - pnote->namedata);
21206 if (bytes > 0)
21207 /* The -1 is because the name field is always 0 terminated, and we
21208 want to be able to ensure that the shift in the while loop below
21209 will not overflow. */
21210 -- bytes;
21211
ddef72cd
NC
21212 if (bytes > sizeof (val))
21213 {
3e6b6445
NC
21214 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21215 bytes);
21216 bytes = sizeof (val);
ddef72cd 21217 }
3e6b6445
NC
21218 /* We do not bother to warn if bytes == 0 as this can
21219 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21220
21221 while (bytes --)
21222 {
54b8331d 21223 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21224
21225 val |= byte << shift;
9ef920e9
NC
21226 shift += 8;
21227 }
21228
75d7d298 21229 switch (name_attribute)
9ef920e9 21230 {
75d7d298 21231 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21232 switch (val)
21233 {
75d7d298
NC
21234 case 0: decoded = "static"; break;
21235 case 1: decoded = "pic"; break;
21236 case 2: decoded = "PIC"; break;
21237 case 3: decoded = "pie"; break;
21238 case 4: decoded = "PIE"; break;
21239 default: break;
9ef920e9 21240 }
75d7d298
NC
21241 break;
21242 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21243 switch (val)
9ef920e9 21244 {
75d7d298
NC
21245 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21246 case 0: decoded = "off"; break;
21247 case 1: decoded = "on"; break;
21248 case 2: decoded = "all"; break;
21249 case 3: decoded = "strong"; break;
21250 case 4: decoded = "explicit"; break;
21251 default: break;
9ef920e9 21252 }
75d7d298
NC
21253 break;
21254 default:
21255 break;
9ef920e9
NC
21256 }
21257
75d7d298 21258 if (decoded != NULL)
3e6b6445
NC
21259 {
21260 print_symbol (-left, decoded);
21261 left = 0;
21262 }
21263 else if (val == 0)
21264 {
21265 printf ("0x0");
21266 left -= 3;
21267 }
9ef920e9 21268 else
75d7d298
NC
21269 {
21270 if (do_wide)
ddef72cd 21271 left -= printf ("0x%llx", val);
75d7d298 21272 else
ddef72cd 21273 left -= printf ("0x%-.*llx", left, val);
75d7d298 21274 }
9ef920e9
NC
21275 }
21276 break;
21277 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21278 left -= print_symbol (- left, name);
21279 break;
21280 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21281 left -= print_symbol (- left, "true");
21282 break;
21283 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21284 left -= print_symbol (- left, "false");
21285 break;
21286 }
21287
21288 if (do_wide && left > 0)
21289 printf ("%-*s", left, " ");
9abca702 21290
015dc7e1 21291 return true;
9ef920e9
NC
21292}
21293
6d118b09
NC
21294/* Note that by the ELF standard, the name field is already null byte
21295 terminated, and namesz includes the terminating null byte.
21296 I.E. the value of namesz for the name "FSF" is 4.
21297
e3c8793a 21298 If the value of namesz is zero, there is no name present. */
9ef920e9 21299
015dc7e1 21300static bool
9ef920e9 21301process_note (Elf_Internal_Note * pnote,
dda8d76d 21302 Filedata * filedata)
779fe533 21303{
2cf0635d
NC
21304 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21305 const char * nt;
9437c45b
JT
21306
21307 if (pnote->namesz == 0)
1ec5cd37
NC
21308 /* If there is no note name, then use the default set of
21309 note type strings. */
dda8d76d 21310 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21311
24d127aa 21312 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21313 /* GNU-specific object file notes. */
21314 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21315
24d127aa 21316 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21317 /* FreeBSD-specific core file notes. */
dda8d76d 21318 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21319
24d127aa 21320 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21321 /* NetBSD-specific core file notes. */
dda8d76d 21322 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21323
24d127aa 21324 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21325 /* NetBSD-specific core file notes. */
21326 return process_netbsd_elf_note (pnote);
21327
24d127aa 21328 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21329 /* NetBSD-specific core file notes. */
21330 return process_netbsd_elf_note (pnote);
21331
98ca73af
FC
21332 else if (startswith (pnote->namedata, "OpenBSD"))
21333 /* OpenBSD-specific core file notes. */
21334 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21335
e9b095a5 21336 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21337 {
21338 /* SPU-specific core file notes. */
21339 nt = pnote->namedata + 4;
21340 name = "SPU";
21341 }
21342
24d127aa 21343 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21344 /* VMS/ia64-specific file notes. */
21345 nt = get_ia64_vms_note_type (pnote->type);
21346
24d127aa 21347 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21348 nt = get_stapsdt_note_type (pnote->type);
21349
9437c45b 21350 else
1ec5cd37
NC
21351 /* Don't recognize this note name; just use the default set of
21352 note type strings. */
dda8d76d 21353 nt = get_note_type (filedata, pnote->type);
9437c45b 21354
1449284b 21355 printf (" ");
9ef920e9 21356
24d127aa 21357 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21358 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21359 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21360 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21361 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21362 print_gnu_build_attribute_name (pnote);
21363 else
21364 print_symbol (-20, name);
21365
21366 if (do_wide)
21367 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21368 else
21369 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21370
24d127aa 21371 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21372 return print_ia64_vms_note (pnote);
24d127aa 21373 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21374 return print_gnu_note (filedata, pnote);
24d127aa 21375 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21376 return print_stapsdt_note (pnote);
24d127aa 21377 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21378 return print_core_note (pnote);
e5382207
LB
21379 else if (startswith (pnote->namedata, "FDO"))
21380 return print_fdo_note (pnote);
24d127aa 21381 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21382 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21383 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21384 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21385 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21386 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21387
9ef920e9 21388 if (pnote->descsz)
1449284b
NC
21389 {
21390 unsigned long i;
21391
21392 printf (_(" description data: "));
21393 for (i = 0; i < pnote->descsz; i++)
178d8719 21394 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21395 if (!do_wide)
21396 printf ("\n");
1449284b
NC
21397 }
21398
9ef920e9
NC
21399 if (do_wide)
21400 printf ("\n");
21401
015dc7e1 21402 return true;
1449284b 21403}
6d118b09 21404
015dc7e1 21405static bool
dda8d76d
NC
21406process_notes_at (Filedata * filedata,
21407 Elf_Internal_Shdr * section,
21408 bfd_vma offset,
82ed9683
L
21409 bfd_vma length,
21410 bfd_vma align)
779fe533 21411{
015dc7e1
AM
21412 Elf_External_Note *pnotes;
21413 Elf_External_Note *external;
21414 char *end;
21415 bool res = true;
103f02d3 21416
779fe533 21417 if (length <= 0)
015dc7e1 21418 return false;
103f02d3 21419
1449284b
NC
21420 if (section)
21421 {
dda8d76d 21422 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21423 if (pnotes)
32ec8896 21424 {
dda8d76d 21425 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21426 {
21427 free (pnotes);
015dc7e1 21428 return false;
f761cb13 21429 }
32ec8896 21430 }
1449284b
NC
21431 }
21432 else
82ed9683 21433 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21434 _("notes"));
4dff97b2 21435
dd24e3da 21436 if (pnotes == NULL)
015dc7e1 21437 return false;
779fe533 21438
103f02d3 21439 external = pnotes;
103f02d3 21440
ca0e11aa
NC
21441 if (filedata->is_separate)
21442 printf (_("In linked file '%s': "), filedata->file_name);
21443 else
21444 printf ("\n");
1449284b 21445 if (section)
ca0e11aa 21446 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21447 else
ca0e11aa 21448 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21449 (unsigned long) offset, (unsigned long) length);
21450
82ed9683
L
21451 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21452 specifies that notes should be aligned to 4 bytes in 32-bit
21453 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21454 we also support 4 byte alignment in 64-bit objects. If section
21455 alignment is less than 4, we treate alignment as 4 bytes. */
21456 if (align < 4)
21457 align = 4;
21458 else if (align != 4 && align != 8)
21459 {
21460 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21461 (long) align);
a788aedd 21462 free (pnotes);
015dc7e1 21463 return false;
82ed9683
L
21464 }
21465
dbe15e4e 21466 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21467
c8071705
NC
21468 end = (char *) pnotes + length;
21469 while ((char *) external < end)
779fe533 21470 {
b34976b6 21471 Elf_Internal_Note inote;
15b42fb0 21472 size_t min_notesz;
4dff97b2 21473 char * next;
2cf0635d 21474 char * temp = NULL;
c8071705 21475 size_t data_remaining = end - (char *) external;
6d118b09 21476
dda8d76d 21477 if (!is_ia64_vms (filedata))
15b42fb0 21478 {
9dd3a467
NC
21479 /* PR binutils/15191
21480 Make sure that there is enough data to read. */
15b42fb0
AM
21481 min_notesz = offsetof (Elf_External_Note, name);
21482 if (data_remaining < min_notesz)
9dd3a467 21483 {
d3a49aa8
AM
21484 warn (ngettext ("Corrupt note: only %ld byte remains, "
21485 "not enough for a full note\n",
21486 "Corrupt note: only %ld bytes remain, "
21487 "not enough for a full note\n",
21488 data_remaining),
21489 (long) data_remaining);
9dd3a467
NC
21490 break;
21491 }
5396a86e
AM
21492 data_remaining -= min_notesz;
21493
15b42fb0
AM
21494 inote.type = BYTE_GET (external->type);
21495 inote.namesz = BYTE_GET (external->namesz);
21496 inote.namedata = external->name;
21497 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21498 inote.descdata = ((char *) external
4dff97b2 21499 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21500 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21501 next = ((char *) external
4dff97b2 21502 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21503 }
00e98fc7 21504 else
15b42fb0
AM
21505 {
21506 Elf64_External_VMS_Note *vms_external;
00e98fc7 21507
9dd3a467
NC
21508 /* PR binutils/15191
21509 Make sure that there is enough data to read. */
15b42fb0
AM
21510 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21511 if (data_remaining < min_notesz)
9dd3a467 21512 {
d3a49aa8
AM
21513 warn (ngettext ("Corrupt note: only %ld byte remains, "
21514 "not enough for a full note\n",
21515 "Corrupt note: only %ld bytes remain, "
21516 "not enough for a full note\n",
21517 data_remaining),
21518 (long) data_remaining);
9dd3a467
NC
21519 break;
21520 }
5396a86e 21521 data_remaining -= min_notesz;
3e55a963 21522
15b42fb0
AM
21523 vms_external = (Elf64_External_VMS_Note *) external;
21524 inote.type = BYTE_GET (vms_external->type);
21525 inote.namesz = BYTE_GET (vms_external->namesz);
21526 inote.namedata = vms_external->name;
21527 inote.descsz = BYTE_GET (vms_external->descsz);
21528 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21529 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21530 next = inote.descdata + align_power (inote.descsz, 3);
21531 }
21532
5396a86e
AM
21533 /* PR 17531: file: 3443835e. */
21534 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21535 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21536 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21537 || (size_t) (next - inote.descdata) < inote.descsz
21538 || ((size_t) (next - inote.descdata)
21539 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21540 {
15b42fb0 21541 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21542 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21543 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21544 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21545 break;
21546 }
21547
15b42fb0 21548 external = (Elf_External_Note *) next;
dd24e3da 21549
6d118b09
NC
21550 /* Verify that name is null terminated. It appears that at least
21551 one version of Linux (RedHat 6.0) generates corefiles that don't
21552 comply with the ELF spec by failing to include the null byte in
21553 namesz. */
18344509 21554 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21555 {
5396a86e 21556 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21557 {
5396a86e
AM
21558 temp = (char *) malloc (inote.namesz + 1);
21559 if (temp == NULL)
21560 {
21561 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21562 res = false;
5396a86e
AM
21563 break;
21564 }
76da6bbe 21565
5396a86e
AM
21566 memcpy (temp, inote.namedata, inote.namesz);
21567 inote.namedata = temp;
21568 }
21569 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21570 }
21571
dda8d76d 21572 if (! process_note (& inote, filedata))
015dc7e1 21573 res = false;
103f02d3 21574
9db70fc3
AM
21575 free (temp);
21576 temp = NULL;
779fe533
NC
21577 }
21578
21579 free (pnotes);
103f02d3 21580
779fe533
NC
21581 return res;
21582}
21583
015dc7e1 21584static bool
dda8d76d 21585process_corefile_note_segments (Filedata * filedata)
779fe533 21586{
015dc7e1 21587 Elf_Internal_Phdr *segment;
b34976b6 21588 unsigned int i;
015dc7e1 21589 bool res = true;
103f02d3 21590
dda8d76d 21591 if (! get_program_headers (filedata))
015dc7e1 21592 return true;
103f02d3 21593
dda8d76d
NC
21594 for (i = 0, segment = filedata->program_headers;
21595 i < filedata->file_header.e_phnum;
b34976b6 21596 i++, segment++)
779fe533
NC
21597 {
21598 if (segment->p_type == PT_NOTE)
dda8d76d 21599 if (! process_notes_at (filedata, NULL,
32ec8896 21600 (bfd_vma) segment->p_offset,
82ed9683
L
21601 (bfd_vma) segment->p_filesz,
21602 (bfd_vma) segment->p_align))
015dc7e1 21603 res = false;
779fe533 21604 }
103f02d3 21605
779fe533
NC
21606 return res;
21607}
21608
015dc7e1 21609static bool
dda8d76d 21610process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21611{
21612 Elf_External_Note * pnotes;
21613 Elf_External_Note * external;
c8071705 21614 char * end;
015dc7e1 21615 bool res = true;
685080f2
NC
21616
21617 if (length <= 0)
015dc7e1 21618 return false;
685080f2 21619
dda8d76d 21620 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21621 _("v850 notes"));
21622 if (pnotes == NULL)
015dc7e1 21623 return false;
685080f2
NC
21624
21625 external = pnotes;
c8071705 21626 end = (char*) pnotes + length;
685080f2
NC
21627
21628 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21629 (unsigned long) offset, (unsigned long) length);
21630
c8071705 21631 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21632 {
21633 Elf_External_Note * next;
21634 Elf_Internal_Note inote;
21635
21636 inote.type = BYTE_GET (external->type);
21637 inote.namesz = BYTE_GET (external->namesz);
21638 inote.namedata = external->name;
21639 inote.descsz = BYTE_GET (external->descsz);
21640 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21641 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21642
c8071705
NC
21643 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21644 {
21645 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21646 inote.descdata = inote.namedata;
21647 inote.namesz = 0;
21648 }
21649
685080f2
NC
21650 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21651
c8071705 21652 if ( ((char *) next > end)
685080f2
NC
21653 || ((char *) next < (char *) pnotes))
21654 {
21655 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21656 (unsigned long) ((char *) external - (char *) pnotes));
21657 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21658 inote.type, inote.namesz, inote.descsz);
21659 break;
21660 }
21661
21662 external = next;
21663
21664 /* Prevent out-of-bounds indexing. */
c8071705 21665 if ( inote.namedata + inote.namesz > end
685080f2
NC
21666 || inote.namedata + inote.namesz < inote.namedata)
21667 {
21668 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21669 (unsigned long) ((char *) external - (char *) pnotes));
21670 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21671 inote.type, inote.namesz, inote.descsz);
21672 break;
21673 }
21674
21675 printf (" %s: ", get_v850_elf_note_type (inote.type));
21676
21677 if (! print_v850_note (& inote))
21678 {
015dc7e1 21679 res = false;
685080f2
NC
21680 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21681 inote.namesz, inote.descsz);
21682 }
21683 }
21684
21685 free (pnotes);
21686
21687 return res;
21688}
21689
015dc7e1 21690static bool
dda8d76d 21691process_note_sections (Filedata * filedata)
1ec5cd37 21692{
015dc7e1 21693 Elf_Internal_Shdr *section;
1ec5cd37 21694 unsigned long i;
32ec8896 21695 unsigned int n = 0;
015dc7e1 21696 bool res = true;
1ec5cd37 21697
dda8d76d
NC
21698 for (i = 0, section = filedata->section_headers;
21699 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21700 i++, section++)
685080f2
NC
21701 {
21702 if (section->sh_type == SHT_NOTE)
21703 {
dda8d76d 21704 if (! process_notes_at (filedata, section,
32ec8896 21705 (bfd_vma) section->sh_offset,
82ed9683
L
21706 (bfd_vma) section->sh_size,
21707 (bfd_vma) section->sh_addralign))
015dc7e1 21708 res = false;
685080f2
NC
21709 n++;
21710 }
21711
dda8d76d
NC
21712 if (( filedata->file_header.e_machine == EM_V800
21713 || filedata->file_header.e_machine == EM_V850
21714 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21715 && section->sh_type == SHT_RENESAS_INFO)
21716 {
dda8d76d 21717 if (! process_v850_notes (filedata,
32ec8896
NC
21718 (bfd_vma) section->sh_offset,
21719 (bfd_vma) section->sh_size))
015dc7e1 21720 res = false;
685080f2
NC
21721 n++;
21722 }
21723 }
df565f32
NC
21724
21725 if (n == 0)
21726 /* Try processing NOTE segments instead. */
dda8d76d 21727 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21728
21729 return res;
21730}
21731
015dc7e1 21732static bool
dda8d76d 21733process_notes (Filedata * filedata)
779fe533
NC
21734{
21735 /* If we have not been asked to display the notes then do nothing. */
21736 if (! do_notes)
015dc7e1 21737 return true;
103f02d3 21738
dda8d76d
NC
21739 if (filedata->file_header.e_type != ET_CORE)
21740 return process_note_sections (filedata);
103f02d3 21741
779fe533 21742 /* No program headers means no NOTE segment. */
dda8d76d
NC
21743 if (filedata->file_header.e_phnum > 0)
21744 return process_corefile_note_segments (filedata);
779fe533 21745
ca0e11aa
NC
21746 if (filedata->is_separate)
21747 printf (_("No notes found in linked file '%s'.\n"),
21748 filedata->file_name);
21749 else
21750 printf (_("No notes found file.\n"));
21751
015dc7e1 21752 return true;
779fe533
NC
21753}
21754
60abdbed
NC
21755static unsigned char *
21756display_public_gnu_attributes (unsigned char * start,
21757 const unsigned char * const end)
21758{
21759 printf (_(" Unknown GNU attribute: %s\n"), start);
21760
21761 start += strnlen ((char *) start, end - start);
21762 display_raw_attribute (start, end);
21763
21764 return (unsigned char *) end;
21765}
21766
21767static unsigned char *
21768display_generic_attribute (unsigned char * start,
21769 unsigned int tag,
21770 const unsigned char * const end)
21771{
21772 if (tag == 0)
21773 return (unsigned char *) end;
21774
21775 return display_tag_value (tag, start, end);
21776}
21777
015dc7e1 21778static bool
dda8d76d 21779process_arch_specific (Filedata * filedata)
252b5132 21780{
a952a375 21781 if (! do_arch)
015dc7e1 21782 return true;
a952a375 21783
dda8d76d 21784 switch (filedata->file_header.e_machine)
252b5132 21785 {
53a346d8
CZ
21786 case EM_ARC:
21787 case EM_ARC_COMPACT:
21788 case EM_ARC_COMPACT2:
dda8d76d 21789 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21790 display_arc_attribute,
21791 display_generic_attribute);
11c1ff18 21792 case EM_ARM:
dda8d76d 21793 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21794 display_arm_attribute,
21795 display_generic_attribute);
21796
252b5132 21797 case EM_MIPS:
4fe85591 21798 case EM_MIPS_RS3_LE:
dda8d76d 21799 return process_mips_specific (filedata);
60abdbed
NC
21800
21801 case EM_MSP430:
dda8d76d 21802 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21803 display_msp430_attribute,
c0ea7c52 21804 display_msp430_gnu_attribute);
60abdbed 21805
2dc8dd17
JW
21806 case EM_RISCV:
21807 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21808 display_riscv_attribute,
21809 display_generic_attribute);
21810
35c08157 21811 case EM_NDS32:
dda8d76d 21812 return process_nds32_specific (filedata);
60abdbed 21813
85f7484a
PB
21814 case EM_68K:
21815 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21816 display_m68k_gnu_attribute);
21817
34c8bcba 21818 case EM_PPC:
b82317dd 21819 case EM_PPC64:
dda8d76d 21820 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21821 display_power_gnu_attribute);
21822
643f7afb
AK
21823 case EM_S390:
21824 case EM_S390_OLD:
dda8d76d 21825 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21826 display_s390_gnu_attribute);
21827
9e8c70f9
DM
21828 case EM_SPARC:
21829 case EM_SPARC32PLUS:
21830 case EM_SPARCV9:
dda8d76d 21831 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21832 display_sparc_gnu_attribute);
21833
59e6276b 21834 case EM_TI_C6000:
dda8d76d 21835 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21836 display_tic6x_attribute,
21837 display_generic_attribute);
21838
0861f561
CQ
21839 case EM_CSKY:
21840 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21841 display_csky_attribute, NULL);
21842
252b5132 21843 default:
dda8d76d 21844 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21845 display_public_gnu_attributes,
21846 display_generic_attribute);
252b5132 21847 }
252b5132
RH
21848}
21849
015dc7e1 21850static bool
dda8d76d 21851get_file_header (Filedata * filedata)
252b5132 21852{
9ea033b2 21853 /* Read in the identity array. */
dda8d76d 21854 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21855 return false;
252b5132 21856
9ea033b2 21857 /* Determine how to read the rest of the header. */
dda8d76d 21858 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21859 {
1a0670f3
AM
21860 default:
21861 case ELFDATANONE:
adab8cdc
AO
21862 case ELFDATA2LSB:
21863 byte_get = byte_get_little_endian;
21864 byte_put = byte_put_little_endian;
21865 break;
21866 case ELFDATA2MSB:
21867 byte_get = byte_get_big_endian;
21868 byte_put = byte_put_big_endian;
21869 break;
9ea033b2
NC
21870 }
21871
21872 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21873 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21874
21875 /* Read in the rest of the header. */
21876 if (is_32bit_elf)
21877 {
21878 Elf32_External_Ehdr ehdr32;
252b5132 21879
dda8d76d 21880 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21881 return false;
103f02d3 21882
dda8d76d
NC
21883 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21884 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21885 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21886 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21887 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21888 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21889 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21890 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21891 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21892 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21893 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21894 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21895 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21896 }
252b5132 21897 else
9ea033b2
NC
21898 {
21899 Elf64_External_Ehdr ehdr64;
a952a375
NC
21900
21901 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21902 we will not be able to cope with the 64bit data found in
21903 64 ELF files. Detect this now and abort before we start
50c2245b 21904 overwriting things. */
a952a375
NC
21905 if (sizeof (bfd_vma) < 8)
21906 {
e3c8793a
NC
21907 error (_("This instance of readelf has been built without support for a\n\
2190864 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21909 return false;
a952a375 21910 }
103f02d3 21911
dda8d76d 21912 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21913 return false;
103f02d3 21914
dda8d76d
NC
21915 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21916 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21917 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21918 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21919 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21920 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21921 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21922 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21923 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21924 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21925 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21926 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21927 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21928 }
252b5132 21929
015dc7e1 21930 return true;
252b5132
RH
21931}
21932
13acb58d
AM
21933static void
21934free_filedata (Filedata *filedata)
21935{
21936 free (filedata->program_interpreter);
13acb58d 21937 free (filedata->program_headers);
13acb58d 21938 free (filedata->section_headers);
13acb58d 21939 free (filedata->string_table);
13acb58d 21940 free (filedata->dump.dump_sects);
13acb58d 21941 free (filedata->dynamic_strings);
13acb58d 21942 free (filedata->dynamic_symbols);
13acb58d 21943 free (filedata->dynamic_syminfo);
13acb58d 21944 free (filedata->dynamic_section);
13acb58d
AM
21945
21946 while (filedata->symtab_shndx_list != NULL)
21947 {
21948 elf_section_list *next = filedata->symtab_shndx_list->next;
21949 free (filedata->symtab_shndx_list);
21950 filedata->symtab_shndx_list = next;
21951 }
21952
21953 free (filedata->section_headers_groups);
13acb58d
AM
21954
21955 if (filedata->section_groups)
21956 {
21957 size_t i;
21958 struct group_list * g;
21959 struct group_list * next;
21960
21961 for (i = 0; i < filedata->group_count; i++)
21962 {
21963 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21964 {
21965 next = g->next;
21966 free (g);
21967 }
21968 }
21969
21970 free (filedata->section_groups);
13acb58d 21971 }
066f8fbe
AM
21972 memset (&filedata->section_headers, 0,
21973 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21974}
21975
dda8d76d
NC
21976static void
21977close_file (Filedata * filedata)
21978{
21979 if (filedata)
21980 {
21981 if (filedata->handle)
21982 fclose (filedata->handle);
21983 free (filedata);
21984 }
21985}
21986
21987void
21988close_debug_file (void * data)
21989{
13acb58d 21990 free_filedata ((Filedata *) data);
dda8d76d
NC
21991 close_file ((Filedata *) data);
21992}
21993
21994static Filedata *
015dc7e1 21995open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21996{
21997 struct stat statbuf;
21998 Filedata * filedata = NULL;
21999
22000 if (stat (pathname, & statbuf) < 0
22001 || ! S_ISREG (statbuf.st_mode))
22002 goto fail;
22003
22004 filedata = calloc (1, sizeof * filedata);
22005 if (filedata == NULL)
22006 goto fail;
22007
22008 filedata->handle = fopen (pathname, "rb");
22009 if (filedata->handle == NULL)
22010 goto fail;
22011
22012 filedata->file_size = (bfd_size_type) statbuf.st_size;
22013 filedata->file_name = pathname;
ca0e11aa 22014 filedata->is_separate = is_separate;
dda8d76d
NC
22015
22016 if (! get_file_header (filedata))
22017 goto fail;
22018
4de91c10
AM
22019 if (!get_section_headers (filedata, false))
22020 goto fail;
dda8d76d
NC
22021
22022 return filedata;
22023
22024 fail:
22025 if (filedata)
22026 {
22027 if (filedata->handle)
22028 fclose (filedata->handle);
22029 free (filedata);
22030 }
22031 return NULL;
22032}
22033
22034void *
22035open_debug_file (const char * pathname)
22036{
015dc7e1 22037 return open_file (pathname, true);
dda8d76d
NC
22038}
22039
835f2fae
NC
22040static void
22041initialise_dump_sects (Filedata * filedata)
22042{
22043 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22044 Note we do this even if cmdline_dump_sects is empty because we
22045 must make sure that the dump_sets array is zeroed out before each
22046 object file is processed. */
22047 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22048 memset (filedata->dump.dump_sects, 0,
22049 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22050
22051 if (cmdline.num_dump_sects > 0)
22052 {
22053 if (filedata->dump.num_dump_sects == 0)
22054 /* A sneaky way of allocating the dump_sects array. */
22055 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22056
22057 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22058 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22059 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22060 }
22061}
22062
fb52b2f4
NC
22063/* Process one ELF object file according to the command line options.
22064 This file may actually be stored in an archive. The file is
32ec8896
NC
22065 positioned at the start of the ELF object. Returns TRUE if no
22066 problems were encountered, FALSE otherwise. */
fb52b2f4 22067
015dc7e1 22068static bool
dda8d76d 22069process_object (Filedata * filedata)
252b5132 22070{
015dc7e1 22071 bool have_separate_files;
252b5132 22072 unsigned int i;
015dc7e1 22073 bool res;
252b5132 22074
dda8d76d 22075 if (! get_file_header (filedata))
252b5132 22076 {
dda8d76d 22077 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22078 return false;
252b5132
RH
22079 }
22080
22081 /* Initialise per file variables. */
978c4450
AM
22082 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22083 filedata->version_info[i] = 0;
252b5132 22084
978c4450
AM
22085 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22086 filedata->dynamic_info[i] = 0;
22087 filedata->dynamic_info_DT_GNU_HASH = 0;
22088 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22089
22090 /* Process the file. */
22091 if (show_name)
dda8d76d 22092 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22093
835f2fae 22094 initialise_dump_sects (filedata);
d70c5fc7 22095
4de91c10
AM
22096 /* There may be some extensions in the first section header. Don't
22097 bomb if we can't read it. */
22098 get_section_headers (filedata, true);
22099
dda8d76d 22100 if (! process_file_header (filedata))
4de91c10
AM
22101 {
22102 res = false;
22103 goto out;
22104 }
252b5132 22105
e331b18d
AM
22106 /* Throw away the single section header read above, so that we
22107 re-read the entire set. */
22108 free (filedata->section_headers);
22109 filedata->section_headers = NULL;
22110
dda8d76d 22111 if (! process_section_headers (filedata))
2f62977e 22112 {
32ec8896 22113 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22114 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22115
2f62977e 22116 if (! do_using_dynamic)
015dc7e1 22117 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22118 }
252b5132 22119
dda8d76d 22120 if (! process_section_groups (filedata))
32ec8896 22121 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22122 do_unwind = false;
d1f5c6e3 22123
93df3340
AM
22124 process_program_headers (filedata);
22125
22126 res = process_dynamic_section (filedata);
252b5132 22127
dda8d76d 22128 if (! process_relocs (filedata))
015dc7e1 22129 res = false;
252b5132 22130
dda8d76d 22131 if (! process_unwind (filedata))
015dc7e1 22132 res = false;
4d6ed7c8 22133
dda8d76d 22134 if (! process_symbol_table (filedata))
015dc7e1 22135 res = false;
252b5132 22136
0f03783c 22137 if (! process_lto_symbol_tables (filedata))
015dc7e1 22138 res = false;
b9e920ec 22139
dda8d76d 22140 if (! process_syminfo (filedata))
015dc7e1 22141 res = false;
252b5132 22142
dda8d76d 22143 if (! process_version_sections (filedata))
015dc7e1 22144 res = false;
252b5132 22145
82ed9683 22146 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 22147 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22148 else
015dc7e1 22149 have_separate_files = false;
dda8d76d
NC
22150
22151 if (! process_section_contents (filedata))
015dc7e1 22152 res = false;
f5842774 22153
24841daa 22154 if (have_separate_files)
dda8d76d 22155 {
24841daa
NC
22156 separate_info * d;
22157
22158 for (d = first_separate_info; d != NULL; d = d->next)
22159 {
835f2fae
NC
22160 initialise_dump_sects (d->handle);
22161
ca0e11aa 22162 if (process_links && ! process_file_header (d->handle))
015dc7e1 22163 res = false;
ca0e11aa 22164 else if (! process_section_headers (d->handle))
015dc7e1 22165 res = false;
d6bfbc39 22166 else if (! process_section_contents (d->handle))
015dc7e1 22167 res = false;
ca0e11aa
NC
22168 else if (process_links)
22169 {
ca0e11aa 22170 if (! process_section_groups (d->handle))
015dc7e1 22171 res = false;
93df3340 22172 process_program_headers (d->handle);
ca0e11aa 22173 if (! process_dynamic_section (d->handle))
015dc7e1 22174 res = false;
ca0e11aa 22175 if (! process_relocs (d->handle))
015dc7e1 22176 res = false;
ca0e11aa 22177 if (! process_unwind (d->handle))
015dc7e1 22178 res = false;
ca0e11aa 22179 if (! process_symbol_table (d->handle))
015dc7e1 22180 res = false;
ca0e11aa 22181 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22182 res = false;
ca0e11aa 22183 if (! process_syminfo (d->handle))
015dc7e1 22184 res = false;
ca0e11aa 22185 if (! process_version_sections (d->handle))
015dc7e1 22186 res = false;
ca0e11aa 22187 if (! process_notes (d->handle))
015dc7e1 22188 res = false;
ca0e11aa 22189 }
24841daa
NC
22190 }
22191
22192 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22193 }
22194
22195 if (! process_notes (filedata))
015dc7e1 22196 res = false;
103f02d3 22197
dda8d76d 22198 if (! process_gnu_liblist (filedata))
015dc7e1 22199 res = false;
047b2264 22200
dda8d76d 22201 if (! process_arch_specific (filedata))
015dc7e1 22202 res = false;
252b5132 22203
4de91c10 22204 out:
13acb58d 22205 free_filedata (filedata);
e4b17d5c 22206
19e6b90e 22207 free_debug_memory ();
18bd398b 22208
32ec8896 22209 return res;
252b5132
RH
22210}
22211
2cf0635d 22212/* Process an ELF archive.
32ec8896
NC
22213 On entry the file is positioned just after the ARMAG string.
22214 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22215
015dc7e1
AM
22216static bool
22217process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22218{
22219 struct archive_info arch;
22220 struct archive_info nested_arch;
22221 size_t got;
015dc7e1 22222 bool ret = true;
2cf0635d 22223
015dc7e1 22224 show_name = true;
2cf0635d
NC
22225
22226 /* The ARCH structure is used to hold information about this archive. */
22227 arch.file_name = NULL;
22228 arch.file = NULL;
22229 arch.index_array = NULL;
22230 arch.sym_table = NULL;
22231 arch.longnames = NULL;
22232
22233 /* The NESTED_ARCH structure is used as a single-item cache of information
22234 about a nested archive (when members of a thin archive reside within
22235 another regular archive file). */
22236 nested_arch.file_name = NULL;
22237 nested_arch.file = NULL;
22238 nested_arch.index_array = NULL;
22239 nested_arch.sym_table = NULL;
22240 nested_arch.longnames = NULL;
22241
dda8d76d 22242 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22243 filedata->file_size, is_thin_archive,
22244 do_archive_index) != 0)
2cf0635d 22245 {
015dc7e1 22246 ret = false;
2cf0635d 22247 goto out;
4145f1d5 22248 }
fb52b2f4 22249
4145f1d5
NC
22250 if (do_archive_index)
22251 {
2cf0635d 22252 if (arch.sym_table == NULL)
1cb7d8b1
AM
22253 error (_("%s: unable to dump the index as none was found\n"),
22254 filedata->file_name);
4145f1d5
NC
22255 else
22256 {
591f7597 22257 unsigned long i, l;
4145f1d5
NC
22258 unsigned long current_pos;
22259
1cb7d8b1
AM
22260 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22261 "in the symbol table)\n"),
22262 filedata->file_name, (unsigned long) arch.index_num,
22263 arch.sym_size);
dda8d76d
NC
22264
22265 current_pos = ftell (filedata->handle);
4145f1d5 22266
2cf0635d 22267 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22268 {
1cb7d8b1
AM
22269 if (i == 0
22270 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22271 {
22272 char * member_name
22273 = get_archive_member_name_at (&arch, arch.index_array[i],
22274 &nested_arch);
2cf0635d 22275
1cb7d8b1
AM
22276 if (member_name != NULL)
22277 {
22278 char * qualified_name
22279 = make_qualified_name (&arch, &nested_arch,
22280 member_name);
2cf0635d 22281
1cb7d8b1
AM
22282 if (qualified_name != NULL)
22283 {
22284 printf (_("Contents of binary %s at offset "),
22285 qualified_name);
c2a7d3f5
NC
22286 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22287 putchar ('\n');
1cb7d8b1
AM
22288 free (qualified_name);
22289 }
fd486f32 22290 free (member_name);
4145f1d5
NC
22291 }
22292 }
2cf0635d
NC
22293
22294 if (l >= arch.sym_size)
4145f1d5 22295 {
1cb7d8b1
AM
22296 error (_("%s: end of the symbol table reached "
22297 "before the end of the index\n"),
dda8d76d 22298 filedata->file_name);
015dc7e1 22299 ret = false;
cb8f3167 22300 break;
4145f1d5 22301 }
591f7597 22302 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22303 printf ("\t%.*s\n",
22304 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22305 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22306 }
22307
67ce483b 22308 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22309 l = (l + 7) & ~ 7;
22310 else
22311 l += l & 1;
22312
2cf0635d 22313 if (l < arch.sym_size)
32ec8896 22314 {
d3a49aa8
AM
22315 error (ngettext ("%s: %ld byte remains in the symbol table, "
22316 "but without corresponding entries in "
22317 "the index table\n",
22318 "%s: %ld bytes remain in the symbol table, "
22319 "but without corresponding entries in "
22320 "the index table\n",
22321 arch.sym_size - l),
dda8d76d 22322 filedata->file_name, arch.sym_size - l);
015dc7e1 22323 ret = false;
32ec8896 22324 }
4145f1d5 22325
dda8d76d 22326 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22327 {
1cb7d8b1
AM
22328 error (_("%s: failed to seek back to start of object files "
22329 "in the archive\n"),
dda8d76d 22330 filedata->file_name);
015dc7e1 22331 ret = false;
2cf0635d 22332 goto out;
4145f1d5 22333 }
fb52b2f4 22334 }
4145f1d5
NC
22335
22336 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22337 && !do_segments && !do_header && !do_dump && !do_version
22338 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22339 && !do_section_groups && !do_dyn_syms)
2cf0635d 22340 {
015dc7e1 22341 ret = true; /* Archive index only. */
2cf0635d
NC
22342 goto out;
22343 }
fb52b2f4
NC
22344 }
22345
fb52b2f4
NC
22346 while (1)
22347 {
2cf0635d
NC
22348 char * name;
22349 size_t namelen;
22350 char * qualified_name;
22351
22352 /* Read the next archive header. */
dda8d76d 22353 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22354 {
22355 error (_("%s: failed to seek to next archive header\n"),
22356 arch.file_name);
015dc7e1 22357 ret = false;
1cb7d8b1
AM
22358 break;
22359 }
dda8d76d 22360 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22361 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22362 {
22363 if (got == 0)
2cf0635d 22364 break;
28e817cc
NC
22365 /* PR 24049 - we cannot use filedata->file_name as this will
22366 have already been freed. */
22367 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22368
015dc7e1 22369 ret = false;
1cb7d8b1
AM
22370 break;
22371 }
2cf0635d 22372 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22373 {
22374 error (_("%s: did not find a valid archive header\n"),
22375 arch.file_name);
015dc7e1 22376 ret = false;
1cb7d8b1
AM
22377 break;
22378 }
2cf0635d
NC
22379
22380 arch.next_arhdr_offset += sizeof arch.arhdr;
22381
978c4450 22382 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22383
22384 name = get_archive_member_name (&arch, &nested_arch);
22385 if (name == NULL)
fb52b2f4 22386 {
28e817cc 22387 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22388 ret = false;
d989285c 22389 break;
fb52b2f4 22390 }
2cf0635d 22391 namelen = strlen (name);
fb52b2f4 22392
2cf0635d
NC
22393 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22394 if (qualified_name == NULL)
fb52b2f4 22395 {
28e817cc 22396 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22397 free (name);
015dc7e1 22398 ret = false;
d989285c 22399 break;
fb52b2f4
NC
22400 }
22401
2cf0635d 22402 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22403 {
22404 /* This is a proxy for an external member of a thin archive. */
22405 Filedata * member_filedata;
22406 char * member_file_name = adjust_relative_path
dda8d76d 22407 (filedata->file_name, name, namelen);
32ec8896 22408
fd486f32 22409 free (name);
1cb7d8b1
AM
22410 if (member_file_name == NULL)
22411 {
fd486f32 22412 free (qualified_name);
015dc7e1 22413 ret = false;
1cb7d8b1
AM
22414 break;
22415 }
2cf0635d 22416
015dc7e1 22417 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22418 if (member_filedata == NULL)
22419 {
22420 error (_("Input file '%s' is not readable.\n"), member_file_name);
22421 free (member_file_name);
fd486f32 22422 free (qualified_name);
015dc7e1 22423 ret = false;
1cb7d8b1
AM
22424 break;
22425 }
2cf0635d 22426
978c4450 22427 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22428 member_filedata->file_name = qualified_name;
2cf0635d 22429
75a2da57
AH
22430 /* The call to process_object() expects the file to be at the beginning. */
22431 rewind (member_filedata->handle);
22432
1cb7d8b1 22433 if (! process_object (member_filedata))
015dc7e1 22434 ret = false;
2cf0635d 22435
1cb7d8b1
AM
22436 close_file (member_filedata);
22437 free (member_file_name);
1cb7d8b1 22438 }
2cf0635d 22439 else if (is_thin_archive)
1cb7d8b1
AM
22440 {
22441 Filedata thin_filedata;
eb02c04d 22442
1cb7d8b1 22443 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22444
a043396b
NC
22445 /* PR 15140: Allow for corrupt thin archives. */
22446 if (nested_arch.file == NULL)
22447 {
22448 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22449 qualified_name, name);
fd486f32
AM
22450 free (qualified_name);
22451 free (name);
015dc7e1 22452 ret = false;
a043396b
NC
22453 break;
22454 }
fd486f32 22455 free (name);
a043396b 22456
1cb7d8b1 22457 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22458 filedata->archive_file_offset
22459 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22460
1cb7d8b1
AM
22461 /* The nested archive file will have been opened and setup by
22462 get_archive_member_name. */
978c4450
AM
22463 if (fseek (nested_arch.file, filedata->archive_file_offset,
22464 SEEK_SET) != 0)
1cb7d8b1
AM
22465 {
22466 error (_("%s: failed to seek to archive member.\n"),
22467 nested_arch.file_name);
fd486f32 22468 free (qualified_name);
015dc7e1 22469 ret = false;
1cb7d8b1
AM
22470 break;
22471 }
2cf0635d 22472
dda8d76d
NC
22473 thin_filedata.handle = nested_arch.file;
22474 thin_filedata.file_name = qualified_name;
9abca702 22475
1cb7d8b1 22476 if (! process_object (& thin_filedata))
015dc7e1 22477 ret = false;
1cb7d8b1 22478 }
2cf0635d 22479 else
1cb7d8b1 22480 {
fd486f32 22481 free (name);
978c4450 22482 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22483 filedata->file_name = qualified_name;
1cb7d8b1 22484 if (! process_object (filedata))
015dc7e1 22485 ret = false;
237877b8 22486 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22487 /* Stop looping with "negative" archive_file_size. */
978c4450 22488 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22489 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22490 }
fb52b2f4 22491
2cf0635d 22492 free (qualified_name);
fb52b2f4
NC
22493 }
22494
4145f1d5 22495 out:
2cf0635d
NC
22496 if (nested_arch.file != NULL)
22497 fclose (nested_arch.file);
22498 release_archive (&nested_arch);
22499 release_archive (&arch);
fb52b2f4 22500
d989285c 22501 return ret;
fb52b2f4
NC
22502}
22503
015dc7e1 22504static bool
2cf0635d 22505process_file (char * file_name)
fb52b2f4 22506{
dda8d76d 22507 Filedata * filedata = NULL;
fb52b2f4
NC
22508 struct stat statbuf;
22509 char armag[SARMAG];
015dc7e1 22510 bool ret = true;
fb52b2f4
NC
22511
22512 if (stat (file_name, &statbuf) < 0)
22513 {
f24ddbdd
NC
22514 if (errno == ENOENT)
22515 error (_("'%s': No such file\n"), file_name);
22516 else
22517 error (_("Could not locate '%s'. System error message: %s\n"),
22518 file_name, strerror (errno));
015dc7e1 22519 return false;
f24ddbdd
NC
22520 }
22521
22522 if (! S_ISREG (statbuf.st_mode))
22523 {
22524 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22525 return false;
fb52b2f4
NC
22526 }
22527
dda8d76d
NC
22528 filedata = calloc (1, sizeof * filedata);
22529 if (filedata == NULL)
22530 {
22531 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22532 return false;
dda8d76d
NC
22533 }
22534
22535 filedata->file_name = file_name;
22536 filedata->handle = fopen (file_name, "rb");
22537 if (filedata->handle == NULL)
fb52b2f4 22538 {
f24ddbdd 22539 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22540 free (filedata);
015dc7e1 22541 return false;
fb52b2f4
NC
22542 }
22543
dda8d76d 22544 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22545 {
4145f1d5 22546 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22547 fclose (filedata->handle);
22548 free (filedata);
015dc7e1 22549 return false;
fb52b2f4
NC
22550 }
22551
dda8d76d 22552 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22553 filedata->is_separate = false;
f54498b4 22554
fb52b2f4 22555 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22556 {
015dc7e1
AM
22557 if (! process_archive (filedata, false))
22558 ret = false;
32ec8896 22559 }
2cf0635d 22560 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22561 {
015dc7e1
AM
22562 if ( ! process_archive (filedata, true))
22563 ret = false;
32ec8896 22564 }
fb52b2f4
NC
22565 else
22566 {
1b513401 22567 if (do_archive_index && !check_all)
4145f1d5
NC
22568 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22569 file_name);
22570
dda8d76d 22571 rewind (filedata->handle);
978c4450 22572 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22573
dda8d76d 22574 if (! process_object (filedata))
015dc7e1 22575 ret = false;
fb52b2f4
NC
22576 }
22577
dda8d76d 22578 fclose (filedata->handle);
8fb879cd
AM
22579 free (filedata->section_headers);
22580 free (filedata->program_headers);
22581 free (filedata->string_table);
6431e409 22582 free (filedata->dump.dump_sects);
dda8d76d 22583 free (filedata);
32ec8896 22584
fd486f32 22585 free (ba_cache.strtab);
1bd6175a 22586 ba_cache.strtab = NULL;
fd486f32 22587 free (ba_cache.symtab);
1bd6175a 22588 ba_cache.symtab = NULL;
fd486f32
AM
22589 ba_cache.filedata = NULL;
22590
fb52b2f4
NC
22591 return ret;
22592}
22593
252b5132
RH
22594#ifdef SUPPORT_DISASSEMBLY
22595/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22596 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22597 symbols. */
252b5132
RH
22598
22599void
2cf0635d 22600print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22601{
22602 fprintf (outfile,"0x%8.8x", addr);
22603}
22604
e3c8793a 22605/* Needed by the i386 disassembler. */
dda8d76d 22606
252b5132
RH
22607void
22608db_task_printsym (unsigned int addr)
22609{
22610 print_address (addr, stderr);
22611}
22612#endif
22613
22614int
2cf0635d 22615main (int argc, char ** argv)
252b5132 22616{
ff78d6d6
L
22617 int err;
22618
87b9f255 22619#ifdef HAVE_LC_MESSAGES
252b5132 22620 setlocale (LC_MESSAGES, "");
3882b010 22621#endif
3882b010 22622 setlocale (LC_CTYPE, "");
252b5132
RH
22623 bindtextdomain (PACKAGE, LOCALEDIR);
22624 textdomain (PACKAGE);
22625
869b9d07
MM
22626 expandargv (&argc, &argv);
22627
dda8d76d 22628 parse_args (& cmdline, argc, argv);
59f14fc0 22629
18bd398b 22630 if (optind < (argc - 1))
1b513401
NC
22631 /* When displaying information for more than one file,
22632 prefix the information with the file name. */
015dc7e1 22633 show_name = true;
5656ba2c
L
22634 else if (optind >= argc)
22635 {
1b513401 22636 /* Ensure that the warning is always displayed. */
015dc7e1 22637 do_checks = true;
1b513401 22638
5656ba2c
L
22639 warn (_("Nothing to do.\n"));
22640 usage (stderr);
22641 }
18bd398b 22642
015dc7e1 22643 err = false;
252b5132 22644 while (optind < argc)
32ec8896 22645 if (! process_file (argv[optind++]))
015dc7e1 22646 err = true;
252b5132 22647
9db70fc3 22648 free (cmdline.dump_sects);
252b5132 22649
7d9813f1
NA
22650 free (dump_ctf_symtab_name);
22651 free (dump_ctf_strtab_name);
22652 free (dump_ctf_parent_name);
22653
32ec8896 22654 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22655}