]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gprofng: fix cppcheck warnings
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
a2c58332 2 Copyright (C) 1998-2022 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
2952f10c
SM
49#if defined HAVE_MSGPACK
50#include <msgpack.h>
51#endif
52
19936277 53/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 54 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 55#define BFD64
a952a375 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"
f6c1a2d5 162#include "elf/xgate.h"
93fbbb04 163#include "elf/xstormy16.h"
88da6820 164#include "elf/xtensa.h"
6655dba2 165#include "elf/z80.h"
e9a0721f 166#include "elf/loongarch.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
015dc7e1
AM
215static bool show_name = false;
216static bool do_dynamic = false;
217static bool do_syms = false;
218static bool do_dyn_syms = false;
219static bool do_lto_syms = false;
220static bool do_reloc = false;
221static bool do_sections = false;
222static bool do_section_groups = false;
223static bool do_section_details = false;
224static bool do_segments = false;
225static bool do_unwind = false;
226static bool do_using_dynamic = false;
227static bool do_header = false;
228static bool do_dump = false;
229static bool do_version = false;
230static bool do_histogram = false;
231static bool do_debugging = false;
232static bool do_ctf = false;
233static bool do_arch = false;
234static bool do_notes = false;
235static bool do_archive_index = false;
236static bool check_all = false;
237static bool is_32bit_elf = false;
238static bool decompress_dumps = false;
239static bool do_not_show_symbol_truncation = false;
240static bool do_demangle = false; /* Pretty print C++ symbol names. */
241static bool process_links = false;
e1dbfc17 242static bool dump_any_debugging = false;
79bc120c 243static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 244static int sym_base = 0;
252b5132 245
7d9813f1
NA
246static char *dump_ctf_parent_name;
247static char *dump_ctf_symtab_name;
248static char *dump_ctf_strtab_name;
249
e4b17d5c
L
250struct group_list
251{
dda8d76d
NC
252 struct group_list * next;
253 unsigned int section_index;
e4b17d5c
L
254};
255
256struct group
257{
dda8d76d
NC
258 struct group_list * root;
259 unsigned int group_index;
e4b17d5c
L
260};
261
978c4450
AM
262typedef struct filedata
263{
264 const char * file_name;
015dc7e1 265 bool is_separate;
978c4450 266 FILE * handle;
be7d229a 267 uint64_t file_size;
978c4450 268 Elf_Internal_Ehdr file_header;
066f8fbe
AM
269 unsigned long archive_file_offset;
270 unsigned long archive_file_size;
271 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
272 Elf_Internal_Shdr * section_headers;
273 Elf_Internal_Phdr * program_headers;
274 char * string_table;
275 unsigned long string_table_length;
978c4450 276 unsigned long dynamic_addr;
be7d229a 277 uint64_t dynamic_size;
978c4450
AM
278 size_t dynamic_nent;
279 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 280 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
281 char * dynamic_strings;
282 unsigned long dynamic_strings_length;
8ac10c5b 283 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
284 unsigned long num_dynamic_syms;
285 Elf_Internal_Sym * dynamic_symbols;
625d49fc 286 uint64_t version_info[16];
978c4450
AM
287 unsigned int dynamic_syminfo_nent;
288 Elf_Internal_Syminfo * dynamic_syminfo;
289 unsigned long dynamic_syminfo_offset;
be7d229a
AM
290 uint64_t nbuckets;
291 uint64_t nchains;
625d49fc
AM
292 uint64_t * buckets;
293 uint64_t * chains;
be7d229a
AM
294 uint64_t ngnubuckets;
295 uint64_t ngnuchains;
625d49fc
AM
296 uint64_t * gnubuckets;
297 uint64_t * gnuchains;
298 uint64_t * mipsxlat;
299 uint64_t gnusymidx;
13acb58d 300 char * program_interpreter;
625d49fc
AM
301 uint64_t dynamic_info[DT_ENCODING];
302 uint64_t dynamic_info_DT_GNU_HASH;
303 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
304 elf_section_list * symtab_shndx_list;
305 size_t group_count;
306 struct group * section_groups;
307 struct group ** section_headers_groups;
308 /* A dynamic array of flags indicating for which sections a dump of
309 some kind has been requested. It is reset on a per-object file
310 basis and then initialised from the cmdline_dump_sects array,
311 the results of interpreting the -w switch, and the
312 dump_sects_byname list. */
313 struct dump_data dump;
314} Filedata;
aef1f6d0 315
c256ffe7 316/* How to print a vma value. */
843dd992
NC
317typedef enum print_mode
318{
319 HEX,
047c3dbf 320 HEX_5,
843dd992
NC
321 DEC,
322 DEC_5,
323 UNSIGNED,
047c3dbf 324 UNSIGNED_5,
843dd992 325 PREFIX_HEX,
047c3dbf 326 PREFIX_HEX_5,
843dd992 327 FULL_HEX,
047c3dbf
NL
328 LONG_HEX,
329 OCTAL,
330 OCTAL_5
843dd992
NC
331}
332print_mode;
333
b3aa80b4
NC
334typedef enum unicode_display_type
335{
336 unicode_default = 0,
337 unicode_locale,
338 unicode_escape,
339 unicode_hex,
340 unicode_highlight,
341 unicode_invalid
342} unicode_display_type;
343
344static unicode_display_type unicode_display = unicode_default;
345
a7fd1186
FS
346typedef enum
347{
348 reltype_unknown,
349 reltype_rel,
350 reltype_rela,
351 reltype_relr
352} relocation_type;
353
bb4d2ac2
L
354/* Versioned symbol info. */
355enum versioned_symbol_info
356{
357 symbol_undefined,
358 symbol_hidden,
359 symbol_public
360};
361
32ec8896 362static const char * get_symbol_version_string
015dc7e1 363 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 364 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 365
9c19a809
NC
366#define UNKNOWN -1
367
84714f86
AM
368static inline const char *
369section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
370{
371 return filedata->string_table + hdr->sh_name;
372}
b9e920ec 373
84714f86
AM
374static inline bool
375section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
376{
377 return (hdr != NULL
378 && filedata->string_table != NULL
379 && hdr->sh_name < filedata->string_table_length);
380}
b9e920ec 381
84714f86
AM
382static inline const char *
383section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
384{
385 if (hdr == NULL)
386 return _("<none>");
387 if (filedata->string_table == NULL)
388 return _("<no-strings>");
389 if (hdr->sh_name >= filedata->string_table_length)
390 return _("<corrupt>");
391 return section_name (filedata, hdr);
392}
252b5132 393
ee42cf8c 394#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 395
84714f86
AM
396static inline bool
397valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
398{
399 return strtab != NULL && offset < strtab_size;
400}
401
402static inline bool
403valid_dynamic_name (const Filedata *filedata, uint64_t offset)
404{
405 return valid_symbol_name (filedata->dynamic_strings,
406 filedata->dynamic_strings_length, offset);
407}
408
d79b3d50
NC
409/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
410 already been called and verified that the string exists. */
84714f86
AM
411static inline const char *
412get_dynamic_name (const Filedata *filedata, size_t offset)
413{
414 return filedata->dynamic_strings + offset;
415}
18bd398b 416
61865e30
NC
417#define REMOVE_ARCH_BITS(ADDR) \
418 do \
419 { \
dda8d76d 420 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
421 (ADDR) &= ~1; \
422 } \
423 while (0)
f16a9783
MS
424
425/* Get the correct GNU hash section name. */
978c4450
AM
426#define GNU_HASH_SECTION_NAME(filedata) \
427 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 428\f
dda8d76d
NC
429/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
430 OFFSET + the offset of the current archive member, if we are examining an
431 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
432 allocate a buffer using malloc and fill that. In either case return the
433 pointer to the start of the retrieved data or NULL if something went wrong.
434 If something does go wrong and REASON is not NULL then emit an error
435 message using REASON as part of the context. */
59245841 436
c256ffe7 437static void *
be7d229a
AM
438get_data (void *var,
439 Filedata *filedata,
440 unsigned long offset,
441 uint64_t size,
442 uint64_t nmemb,
443 const char *reason)
a6e9f9df 444{
2cf0635d 445 void * mvar;
be7d229a 446 uint64_t amt = size * nmemb;
a6e9f9df 447
c256ffe7 448 if (size == 0 || nmemb == 0)
a6e9f9df
AM
449 return NULL;
450
be7d229a
AM
451 /* If size_t is smaller than uint64_t, eg because you are building
452 on a 32-bit host, then make sure that when the sizes are cast to
453 size_t no information is lost. */
7c1c1904
AM
454 if ((size_t) size != size
455 || (size_t) nmemb != nmemb
be7d229a
AM
456 || (size_t) amt != amt
457 || amt / size != nmemb
458 || (size_t) amt + 1 == 0)
57028622
NC
459 {
460 if (reason)
b8281767
AM
461 error (_("Size overflow prevents reading %" PRIu64
462 " elements of size %" PRIu64 " for %s\n"),
be7d229a 463 nmemb, size, reason);
57028622
NC
464 return NULL;
465 }
466
c22b42ce 467 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 468 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
469 if (filedata->archive_file_offset > filedata->file_size
470 || offset > filedata->file_size - filedata->archive_file_offset
471 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 472 {
049b0c3a 473 if (reason)
b8281767 474 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 475 amt, reason);
a6e9f9df
AM
476 return NULL;
477 }
478
978c4450
AM
479 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
480 SEEK_SET))
071436c6
NC
481 {
482 if (reason)
c9c1d674 483 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 484 filedata->archive_file_offset + offset, reason);
071436c6
NC
485 return NULL;
486 }
487
a6e9f9df
AM
488 mvar = var;
489 if (mvar == NULL)
490 {
7c1c1904
AM
491 /* + 1 so that we can '\0' terminate invalid string table sections. */
492 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
493
494 if (mvar == NULL)
495 {
049b0c3a 496 if (reason)
b8281767 497 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 498 amt, reason);
a6e9f9df
AM
499 return NULL;
500 }
c256ffe7 501
c9c1d674 502 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
503 }
504
dda8d76d 505 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 506 {
049b0c3a 507 if (reason)
b8281767 508 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 509 amt, reason);
a6e9f9df
AM
510 if (mvar != var)
511 free (mvar);
512 return NULL;
513 }
514
515 return mvar;
516}
517
32ec8896
NC
518/* Print a VMA value in the MODE specified.
519 Returns the number of characters displayed. */
cb8f3167 520
32ec8896 521static unsigned int
625d49fc 522print_vma (uint64_t vma, print_mode mode)
66543521 523{
32ec8896 524 unsigned int nc = 0;
66543521 525
14a91970 526 switch (mode)
66543521 527 {
14a91970
AM
528 case FULL_HEX:
529 nc = printf ("0x");
1a0670f3 530 /* Fall through. */
14a91970 531 case LONG_HEX:
f493c217 532 if (!is_32bit_elf)
625d49fc
AM
533 return nc + printf ("%16.16" PRIx64, vma);
534 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 535
14a91970
AM
536 case DEC_5:
537 if (vma <= 99999)
625d49fc 538 return printf ("%5" PRId64, vma);
1a0670f3 539 /* Fall through. */
14a91970
AM
540 case PREFIX_HEX:
541 nc = printf ("0x");
1a0670f3 542 /* Fall through. */
14a91970 543 case HEX:
625d49fc 544 return nc + printf ("%" PRIx64, vma);
b19aac67 545
047c3dbf
NL
546 case PREFIX_HEX_5:
547 nc = printf ("0x");
548 /* Fall through. */
549 case HEX_5:
625d49fc 550 return nc + printf ("%05" PRIx64, vma);
047c3dbf 551
14a91970 552 case DEC:
625d49fc 553 return printf ("%" PRId64, vma);
b19aac67 554
14a91970 555 case UNSIGNED:
625d49fc 556 return printf ("%" PRIu64, vma);
32ec8896 557
047c3dbf 558 case UNSIGNED_5:
625d49fc 559 return printf ("%5" PRIu64, vma);
047c3dbf
NL
560
561 case OCTAL:
625d49fc 562 return printf ("%" PRIo64, vma);
047c3dbf
NL
563
564 case OCTAL_5:
625d49fc 565 return printf ("%5" PRIo64, vma);
047c3dbf 566
32ec8896
NC
567 default:
568 /* FIXME: Report unrecognised mode ? */
569 return 0;
f7a99963 570 }
f7a99963
NC
571}
572
047c3dbf 573
7bfd842d 574/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 575 multibye characters (assuming the host environment supports them).
31104126 576
7bfd842d
NC
577 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
578
0942c7ab
NC
579 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
580 abs(WIDTH) - 5 characters followed by "[...]".
581
7bfd842d
NC
582 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
583 padding as necessary.
171191ba
NC
584
585 Returns the number of emitted characters. */
586
587static unsigned int
0942c7ab 588print_symbol (signed int width, const char * symbol)
31104126 589{
015dc7e1
AM
590 bool extra_padding = false;
591 bool do_dots = false;
32ec8896 592 signed int num_printed = 0;
3bfcb652 593#ifdef HAVE_MBSTATE_T
7bfd842d 594 mbstate_t state;
3bfcb652 595#endif
32ec8896 596 unsigned int width_remaining;
79bc120c 597 const void * alloced_symbol = NULL;
961c521f 598
7bfd842d 599 if (width < 0)
961c521f 600 {
88305e1b 601 /* Keep the width positive. This helps the code below. */
961c521f 602 width = - width;
015dc7e1 603 extra_padding = true;
0b4362b0 604 }
56d8f8a9
NC
605 else if (width == 0)
606 return 0;
961c521f 607
7bfd842d
NC
608 if (do_wide)
609 /* Set the remaining width to a very large value.
610 This simplifies the code below. */
611 width_remaining = INT_MAX;
612 else
0942c7ab
NC
613 {
614 width_remaining = width;
615 if (! do_not_show_symbol_truncation
616 && (int) strlen (symbol) > width)
617 {
618 width_remaining -= 5;
619 if ((int) width_remaining < 0)
620 width_remaining = 0;
015dc7e1 621 do_dots = true;
0942c7ab
NC
622 }
623 }
cb8f3167 624
3bfcb652 625#ifdef HAVE_MBSTATE_T
7bfd842d
NC
626 /* Initialise the multibyte conversion state. */
627 memset (& state, 0, sizeof (state));
3bfcb652 628#endif
961c521f 629
79bc120c
NC
630 if (do_demangle && *symbol)
631 {
632 const char * res = cplus_demangle (symbol, demangle_flags);
633
634 if (res != NULL)
635 alloced_symbol = symbol = res;
636 }
637
7bfd842d
NC
638 while (width_remaining)
639 {
640 size_t n;
7bfd842d 641 const char c = *symbol++;
961c521f 642
7bfd842d 643 if (c == 0)
961c521f
NC
644 break;
645
b3aa80b4
NC
646 if (ISPRINT (c))
647 {
648 putchar (c);
649 width_remaining --;
650 num_printed ++;
651 }
652 else if (ISCNTRL (c))
961c521f 653 {
b3aa80b4
NC
654 /* Do not print control characters directly as they can affect terminal
655 settings. Such characters usually appear in the names generated
656 by the assembler for local labels. */
657
7bfd842d 658 if (width_remaining < 2)
961c521f
NC
659 break;
660
7bfd842d
NC
661 printf ("^%c", c + 0x40);
662 width_remaining -= 2;
171191ba 663 num_printed += 2;
961c521f 664 }
b3aa80b4 665 else if (c == 0x7f)
7bfd842d 666 {
b3aa80b4
NC
667 if (width_remaining < 5)
668 break;
669 printf ("<DEL>");
670 width_remaining -= 5;
671 num_printed += 5;
672 }
673 else if (unicode_display != unicode_locale
674 && unicode_display != unicode_default)
675 {
676 /* Display unicode characters as something else. */
677 unsigned char bytes[4];
678 bool is_utf8;
795588ae 679 unsigned int nbytes;
b3aa80b4
NC
680
681 bytes[0] = c;
682
683 if (bytes[0] < 0xc0)
684 {
685 nbytes = 1;
686 is_utf8 = false;
687 }
688 else
689 {
690 bytes[1] = *symbol++;
691
692 if ((bytes[1] & 0xc0) != 0x80)
693 {
694 is_utf8 = false;
695 /* Do not consume this character. It may only
696 be the first byte in the sequence that was
697 corrupt. */
698 --symbol;
699 nbytes = 1;
700 }
701 else if ((bytes[0] & 0x20) == 0)
702 {
703 is_utf8 = true;
704 nbytes = 2;
705 }
706 else
707 {
708 bytes[2] = *symbol++;
709
710 if ((bytes[2] & 0xc0) != 0x80)
711 {
712 is_utf8 = false;
713 symbol -= 2;
714 nbytes = 1;
715 }
716 else if ((bytes[0] & 0x10) == 0)
717 {
718 is_utf8 = true;
719 nbytes = 3;
720 }
721 else
722 {
723 bytes[3] = *symbol++;
724
725 nbytes = 4;
726
727 if ((bytes[3] & 0xc0) != 0x80)
728 {
729 is_utf8 = false;
730 symbol -= 3;
731 nbytes = 1;
732 }
733 else
734 is_utf8 = true;
735 }
736 }
737 }
738
739 if (unicode_display == unicode_invalid)
740 is_utf8 = false;
741
742 if (unicode_display == unicode_hex || ! is_utf8)
743 {
795588ae 744 unsigned int i;
b3aa80b4
NC
745
746 if (width_remaining < (nbytes * 2) + 2)
747 break;
748
749 putchar (is_utf8 ? '<' : '{');
750 printf ("0x");
751 for (i = 0; i < nbytes; i++)
752 printf ("%02x", bytes[i]);
753 putchar (is_utf8 ? '>' : '}');
754 }
755 else
756 {
757 if (unicode_display == unicode_highlight && isatty (1))
758 printf ("\x1B[31;47m"); /* Red. */
759
760 switch (nbytes)
761 {
762 case 2:
763 if (width_remaining < 6)
764 break;
765 printf ("\\u%02x%02x",
766 (bytes[0] & 0x1c) >> 2,
767 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
768 break;
769 case 3:
770 if (width_remaining < 6)
771 break;
772 printf ("\\u%02x%02x",
773 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
774 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
775 break;
776 case 4:
777 if (width_remaining < 8)
778 break;
779 printf ("\\u%02x%02x%02x",
780 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
781 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
782 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
783
784 break;
785 default:
786 /* URG. */
787 break;
788 }
789
790 if (unicode_display == unicode_highlight && isatty (1))
791 printf ("\033[0m"); /* Default colour. */
792 }
793
794 if (bytes[nbytes - 1] == 0)
795 break;
7bfd842d 796 }
961c521f
NC
797 else
798 {
3bfcb652
NC
799#ifdef HAVE_MBSTATE_T
800 wchar_t w;
801#endif
7bfd842d
NC
802 /* Let printf do the hard work of displaying multibyte characters. */
803 printf ("%.1s", symbol - 1);
804 width_remaining --;
805 num_printed ++;
806
3bfcb652 807#ifdef HAVE_MBSTATE_T
7bfd842d
NC
808 /* Try to find out how many bytes made up the character that was
809 just printed. Advance the symbol pointer past the bytes that
810 were displayed. */
811 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
812#else
813 n = 1;
814#endif
7bfd842d
NC
815 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
816 symbol += (n - 1);
961c521f 817 }
961c521f 818 }
171191ba 819
0942c7ab
NC
820 if (do_dots)
821 num_printed += printf ("[...]");
822
7bfd842d 823 if (extra_padding && num_printed < width)
171191ba
NC
824 {
825 /* Fill in the remaining spaces. */
7bfd842d
NC
826 printf ("%-*s", width - num_printed, " ");
827 num_printed = width;
171191ba
NC
828 }
829
79bc120c 830 free ((void *) alloced_symbol);
171191ba 831 return num_printed;
31104126
NC
832}
833
1449284b 834/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
835 the given section's name. Like print_symbol, except that it does not try
836 to print multibyte characters, it just interprets them as hex values. */
837
838static const char *
dda8d76d 839printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 840{
ca0e11aa 841#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 842 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 843 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
844 char * buf = sec_name_buf;
845 char c;
846 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
847
848 while ((c = * name ++) != 0)
849 {
850 if (ISCNTRL (c))
851 {
852 if (remaining < 2)
853 break;
948f632f 854
74e1a04b
NC
855 * buf ++ = '^';
856 * buf ++ = c + 0x40;
857 remaining -= 2;
858 }
859 else if (ISPRINT (c))
860 {
861 * buf ++ = c;
862 remaining -= 1;
863 }
864 else
865 {
866 static char hex[17] = "0123456789ABCDEF";
867
868 if (remaining < 4)
869 break;
870 * buf ++ = '<';
871 * buf ++ = hex[(c & 0xf0) >> 4];
872 * buf ++ = hex[c & 0x0f];
873 * buf ++ = '>';
874 remaining -= 4;
875 }
876
877 if (remaining == 0)
878 break;
879 }
880
881 * buf = 0;
882 return sec_name_buf;
883}
884
885static const char *
dda8d76d 886printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 887{
dda8d76d 888 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
889 return _("<corrupt>");
890
dda8d76d 891 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
892}
893
89fac5e3
RS
894/* Return a pointer to section NAME, or NULL if no such section exists. */
895
896static Elf_Internal_Shdr *
dda8d76d 897find_section (Filedata * filedata, const char * name)
89fac5e3
RS
898{
899 unsigned int i;
900
68807c3c
NC
901 if (filedata->section_headers == NULL)
902 return NULL;
dda8d76d
NC
903
904 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
905 if (section_name_valid (filedata, filedata->section_headers + i)
906 && streq (section_name (filedata, filedata->section_headers + i),
907 name))
dda8d76d 908 return filedata->section_headers + i;
89fac5e3
RS
909
910 return NULL;
911}
912
0b6ae522
DJ
913/* Return a pointer to a section containing ADDR, or NULL if no such
914 section exists. */
915
916static Elf_Internal_Shdr *
625d49fc 917find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
918{
919 unsigned int i;
920
68807c3c
NC
921 if (filedata->section_headers == NULL)
922 return NULL;
923
dda8d76d 924 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 925 {
dda8d76d
NC
926 Elf_Internal_Shdr *sec = filedata->section_headers + i;
927
0b6ae522
DJ
928 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
929 return sec;
930 }
931
932 return NULL;
933}
934
071436c6 935static Elf_Internal_Shdr *
dda8d76d 936find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
937{
938 unsigned int i;
939
68807c3c
NC
940 if (filedata->section_headers == NULL)
941 return NULL;
942
dda8d76d 943 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 944 {
dda8d76d
NC
945 Elf_Internal_Shdr *sec = filedata->section_headers + i;
946
071436c6
NC
947 if (sec->sh_type == type)
948 return sec;
949 }
950
951 return NULL;
952}
953
657d0d47
CC
954/* Return a pointer to section NAME, or NULL if no such section exists,
955 restricted to the list of sections given in SET. */
956
957static Elf_Internal_Shdr *
dda8d76d 958find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
959{
960 unsigned int i;
961
68807c3c
NC
962 if (filedata->section_headers == NULL)
963 return NULL;
964
657d0d47
CC
965 if (set != NULL)
966 {
967 while ((i = *set++) > 0)
b814a36d
NC
968 {
969 /* See PR 21156 for a reproducer. */
dda8d76d 970 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
971 continue; /* FIXME: Should we issue an error message ? */
972
84714f86
AM
973 if (section_name_valid (filedata, filedata->section_headers + i)
974 && streq (section_name (filedata, filedata->section_headers + i),
975 name))
dda8d76d 976 return filedata->section_headers + i;
b814a36d 977 }
657d0d47
CC
978 }
979
dda8d76d 980 return find_section (filedata, name);
657d0d47
CC
981}
982
32ec8896 983/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
984 This OS has so many departures from the ELF standard that we test it at
985 many places. */
986
015dc7e1 987static inline bool
dda8d76d 988is_ia64_vms (Filedata * filedata)
28f997cf 989{
dda8d76d
NC
990 return filedata->file_header.e_machine == EM_IA_64
991 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
992}
993
bcedfee6 994/* Guess the relocation size commonly used by the specific machines. */
252b5132 995
015dc7e1 996static bool
2dc4cec1 997guess_is_rela (unsigned int e_machine)
252b5132 998{
9c19a809 999 switch (e_machine)
252b5132
RH
1000 {
1001 /* Targets that use REL relocations. */
252b5132 1002 case EM_386:
22abe556 1003 case EM_IAMCU:
f954747f 1004 case EM_960:
e9f53129 1005 case EM_ARM:
2b0337b0 1006 case EM_D10V:
252b5132 1007 case EM_CYGNUS_D10V:
e9f53129 1008 case EM_DLX:
252b5132 1009 case EM_MIPS:
4fe85591 1010 case EM_MIPS_RS3_LE:
e9f53129 1011 case EM_CYGNUS_M32R:
1c0d3aa6 1012 case EM_SCORE:
f6c1a2d5 1013 case EM_XGATE:
fe944acf 1014 case EM_NFP:
aca4efc7 1015 case EM_BPF:
015dc7e1 1016 return false;
103f02d3 1017
252b5132
RH
1018 /* Targets that use RELA relocations. */
1019 case EM_68K:
f954747f 1020 case EM_860:
a06ea964 1021 case EM_AARCH64:
cfb8c092 1022 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1023 case EM_ALPHA:
1024 case EM_ALTERA_NIOS2:
886a2506
NC
1025 case EM_ARC:
1026 case EM_ARC_COMPACT:
1027 case EM_ARC_COMPACT2:
e9f53129
AM
1028 case EM_AVR:
1029 case EM_AVR_OLD:
1030 case EM_BLACKFIN:
60bca95a 1031 case EM_CR16:
e9f53129
AM
1032 case EM_CRIS:
1033 case EM_CRX:
b8891f8d 1034 case EM_CSKY:
2b0337b0 1035 case EM_D30V:
252b5132 1036 case EM_CYGNUS_D30V:
2b0337b0 1037 case EM_FR30:
3f8107ab 1038 case EM_FT32:
252b5132 1039 case EM_CYGNUS_FR30:
5c70f934 1040 case EM_CYGNUS_FRV:
e9f53129
AM
1041 case EM_H8S:
1042 case EM_H8_300:
1043 case EM_H8_300H:
800eeca4 1044 case EM_IA_64:
1e4cf259
NC
1045 case EM_IP2K:
1046 case EM_IP2K_OLD:
3b36097d 1047 case EM_IQ2000:
84e94c90 1048 case EM_LATTICEMICO32:
ff7eeb89 1049 case EM_M32C_OLD:
49f58d10 1050 case EM_M32C:
e9f53129
AM
1051 case EM_M32R:
1052 case EM_MCORE:
15ab5209 1053 case EM_CYGNUS_MEP:
a3c62988 1054 case EM_METAG:
e9f53129
AM
1055 case EM_MMIX:
1056 case EM_MN10200:
1057 case EM_CYGNUS_MN10200:
1058 case EM_MN10300:
1059 case EM_CYGNUS_MN10300:
5506d11a 1060 case EM_MOXIE:
e9f53129
AM
1061 case EM_MSP430:
1062 case EM_MSP430_OLD:
d031aafb 1063 case EM_MT:
35c08157 1064 case EM_NDS32:
64fd6348 1065 case EM_NIOS32:
73589c9d 1066 case EM_OR1K:
e9f53129
AM
1067 case EM_PPC64:
1068 case EM_PPC:
2b100bb5 1069 case EM_TI_PRU:
e23eba97 1070 case EM_RISCV:
99c513f6 1071 case EM_RL78:
c7927a3c 1072 case EM_RX:
e9f53129
AM
1073 case EM_S390:
1074 case EM_S390_OLD:
1075 case EM_SH:
1076 case EM_SPARC:
1077 case EM_SPARC32PLUS:
1078 case EM_SPARCV9:
1079 case EM_SPU:
40b36596 1080 case EM_TI_C6000:
aa137e4d
NC
1081 case EM_TILEGX:
1082 case EM_TILEPRO:
708e2187 1083 case EM_V800:
e9f53129
AM
1084 case EM_V850:
1085 case EM_CYGNUS_V850:
1086 case EM_VAX:
619ed720 1087 case EM_VISIUM:
e9f53129 1088 case EM_X86_64:
8a9036a4 1089 case EM_L1OM:
7a9068fe 1090 case EM_K1OM:
e9f53129
AM
1091 case EM_XSTORMY16:
1092 case EM_XTENSA:
1093 case EM_XTENSA_OLD:
7ba29e2a
NC
1094 case EM_MICROBLAZE:
1095 case EM_MICROBLAZE_OLD:
f96bd6c2 1096 case EM_WEBASSEMBLY:
015dc7e1 1097 return true;
103f02d3 1098
e9f53129
AM
1099 case EM_68HC05:
1100 case EM_68HC08:
1101 case EM_68HC11:
1102 case EM_68HC16:
1103 case EM_FX66:
1104 case EM_ME16:
d1133906 1105 case EM_MMA:
d1133906
NC
1106 case EM_NCPU:
1107 case EM_NDR1:
e9f53129 1108 case EM_PCP:
d1133906 1109 case EM_ST100:
e9f53129 1110 case EM_ST19:
d1133906 1111 case EM_ST7:
e9f53129
AM
1112 case EM_ST9PLUS:
1113 case EM_STARCORE:
d1133906 1114 case EM_SVX:
e9f53129 1115 case EM_TINYJ:
9c19a809
NC
1116 default:
1117 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1118 return false;
9c19a809
NC
1119 }
1120}
252b5132 1121
dda8d76d 1122/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1123 Returns TRUE upon success, FALSE otherwise. If successful then a
1124 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1125 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1126 responsibility to free the allocated buffer. */
1127
015dc7e1 1128static bool
dda8d76d
NC
1129slurp_rela_relocs (Filedata * filedata,
1130 unsigned long rel_offset,
1131 unsigned long rel_size,
1132 Elf_Internal_Rela ** relasp,
1133 unsigned long * nrelasp)
9c19a809 1134{
2cf0635d 1135 Elf_Internal_Rela * relas;
8b73c356 1136 size_t nrelas;
4d6ed7c8 1137 unsigned int i;
252b5132 1138
4d6ed7c8
NC
1139 if (is_32bit_elf)
1140 {
2cf0635d 1141 Elf32_External_Rela * erelas;
103f02d3 1142
dda8d76d 1143 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1144 rel_size, _("32-bit relocation data"));
a6e9f9df 1145 if (!erelas)
015dc7e1 1146 return false;
252b5132 1147
4d6ed7c8 1148 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1149
3f5e193b
NC
1150 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1151 sizeof (Elf_Internal_Rela));
103f02d3 1152
4d6ed7c8
NC
1153 if (relas == NULL)
1154 {
c256ffe7 1155 free (erelas);
591a748a 1156 error (_("out of memory parsing relocs\n"));
015dc7e1 1157 return false;
4d6ed7c8 1158 }
103f02d3 1159
4d6ed7c8
NC
1160 for (i = 0; i < nrelas; i++)
1161 {
1162 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1163 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1164 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1165 }
103f02d3 1166
4d6ed7c8
NC
1167 free (erelas);
1168 }
1169 else
1170 {
2cf0635d 1171 Elf64_External_Rela * erelas;
103f02d3 1172
dda8d76d 1173 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1174 rel_size, _("64-bit relocation data"));
a6e9f9df 1175 if (!erelas)
015dc7e1 1176 return false;
4d6ed7c8
NC
1177
1178 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1179
3f5e193b
NC
1180 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1181 sizeof (Elf_Internal_Rela));
103f02d3 1182
4d6ed7c8
NC
1183 if (relas == NULL)
1184 {
c256ffe7 1185 free (erelas);
591a748a 1186 error (_("out of memory parsing relocs\n"));
015dc7e1 1187 return false;
9c19a809 1188 }
4d6ed7c8
NC
1189
1190 for (i = 0; i < nrelas; i++)
9c19a809 1191 {
66543521
AM
1192 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1193 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1194 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1195
dda8d76d
NC
1196 if (filedata->file_header.e_machine == EM_MIPS
1197 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1198 {
1199 /* In little-endian objects, r_info isn't really a
1200 64-bit little-endian value: it has a 32-bit
1201 little-endian symbol index followed by four
1202 individual byte fields. Reorder INFO
1203 accordingly. */
625d49fc 1204 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1205 inf = (((inf & 0xffffffff) << 32)
1206 | ((inf >> 56) & 0xff)
1207 | ((inf >> 40) & 0xff00)
1208 | ((inf >> 24) & 0xff0000)
1209 | ((inf >> 8) & 0xff000000));
1210 relas[i].r_info = inf;
861fb55a 1211 }
4d6ed7c8 1212 }
103f02d3 1213
4d6ed7c8
NC
1214 free (erelas);
1215 }
32ec8896 1216
4d6ed7c8
NC
1217 *relasp = relas;
1218 *nrelasp = nrelas;
015dc7e1 1219 return true;
4d6ed7c8 1220}
103f02d3 1221
dda8d76d 1222/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1223 Returns TRUE upon success, FALSE otherwise. If successful then a
1224 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1225 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1226 responsibility to free the allocated buffer. */
1227
015dc7e1 1228static bool
dda8d76d
NC
1229slurp_rel_relocs (Filedata * filedata,
1230 unsigned long rel_offset,
1231 unsigned long rel_size,
1232 Elf_Internal_Rela ** relsp,
1233 unsigned long * nrelsp)
4d6ed7c8 1234{
2cf0635d 1235 Elf_Internal_Rela * rels;
8b73c356 1236 size_t nrels;
4d6ed7c8 1237 unsigned int i;
103f02d3 1238
4d6ed7c8
NC
1239 if (is_32bit_elf)
1240 {
2cf0635d 1241 Elf32_External_Rel * erels;
103f02d3 1242
dda8d76d 1243 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1244 rel_size, _("32-bit relocation data"));
a6e9f9df 1245 if (!erels)
015dc7e1 1246 return false;
103f02d3 1247
4d6ed7c8 1248 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1249
3f5e193b 1250 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1251
4d6ed7c8
NC
1252 if (rels == NULL)
1253 {
c256ffe7 1254 free (erels);
591a748a 1255 error (_("out of memory parsing relocs\n"));
015dc7e1 1256 return false;
4d6ed7c8
NC
1257 }
1258
1259 for (i = 0; i < nrels; i++)
1260 {
1261 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1262 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1263 rels[i].r_addend = 0;
9ea033b2 1264 }
4d6ed7c8
NC
1265
1266 free (erels);
9c19a809
NC
1267 }
1268 else
1269 {
2cf0635d 1270 Elf64_External_Rel * erels;
9ea033b2 1271
dda8d76d 1272 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1273 rel_size, _("64-bit relocation data"));
a6e9f9df 1274 if (!erels)
015dc7e1 1275 return false;
103f02d3 1276
4d6ed7c8 1277 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1278
3f5e193b 1279 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1280
4d6ed7c8 1281 if (rels == NULL)
9c19a809 1282 {
c256ffe7 1283 free (erels);
591a748a 1284 error (_("out of memory parsing relocs\n"));
015dc7e1 1285 return false;
4d6ed7c8 1286 }
103f02d3 1287
4d6ed7c8
NC
1288 for (i = 0; i < nrels; i++)
1289 {
66543521
AM
1290 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1291 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1292 rels[i].r_addend = 0;
861fb55a 1293
dda8d76d
NC
1294 if (filedata->file_header.e_machine == EM_MIPS
1295 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1296 {
1297 /* In little-endian objects, r_info isn't really a
1298 64-bit little-endian value: it has a 32-bit
1299 little-endian symbol index followed by four
1300 individual byte fields. Reorder INFO
1301 accordingly. */
625d49fc 1302 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1303 inf = (((inf & 0xffffffff) << 32)
1304 | ((inf >> 56) & 0xff)
1305 | ((inf >> 40) & 0xff00)
1306 | ((inf >> 24) & 0xff0000)
1307 | ((inf >> 8) & 0xff000000));
1308 rels[i].r_info = inf;
861fb55a 1309 }
4d6ed7c8 1310 }
103f02d3 1311
4d6ed7c8
NC
1312 free (erels);
1313 }
32ec8896 1314
4d6ed7c8
NC
1315 *relsp = rels;
1316 *nrelsp = nrels;
015dc7e1 1317 return true;
4d6ed7c8 1318}
103f02d3 1319
a7fd1186
FS
1320static bool
1321slurp_relr_relocs (Filedata * filedata,
1322 unsigned long relr_offset,
1323 unsigned long relr_size,
625d49fc 1324 uint64_t ** relrsp,
a7fd1186
FS
1325 unsigned long * nrelrsp)
1326{
1327 void *relrs;
1328 size_t size = 0, nentries, i;
625d49fc 1329 uint64_t base = 0, addr, entry;
a7fd1186
FS
1330
1331 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1332 _("RELR relocation data"));
1333 if (!relrs)
1334 return false;
1335
1336 if (is_32bit_elf)
1337 nentries = relr_size / sizeof (Elf32_External_Relr);
1338 else
1339 nentries = relr_size / sizeof (Elf64_External_Relr);
1340 for (i = 0; i < nentries; i++)
1341 {
1342 if (is_32bit_elf)
1343 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1344 else
1345 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1346 if ((entry & 1) == 0)
1347 size++;
1348 else
1349 while ((entry >>= 1) != 0)
1350 if ((entry & 1) == 1)
1351 size++;
1352 }
1353
625d49fc 1354 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1355 if (*relrsp == NULL)
1356 {
1357 free (relrs);
1358 error (_("out of memory parsing relocs\n"));
1359 return false;
1360 }
1361
1362 size = 0;
1363 for (i = 0; i < nentries; i++)
1364 {
625d49fc 1365 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1366
1367 if (is_32bit_elf)
1368 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1369 else
1370 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1371 if ((entry & 1) == 0)
1372 {
1373 (*relrsp)[size++] = entry;
1374 base = entry + entry_bytes;
1375 }
1376 else
1377 {
1378 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1379 if ((entry & 1) != 0)
1380 (*relrsp)[size++] = addr;
1381 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1382 }
1383 }
1384
1385 *nrelrsp = size;
1386 free (relrs);
1387 return true;
1388}
1389
aca88567
NC
1390/* Returns the reloc type extracted from the reloc info field. */
1391
1392static unsigned int
625d49fc 1393get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1394{
1395 if (is_32bit_elf)
1396 return ELF32_R_TYPE (reloc_info);
1397
dda8d76d 1398 switch (filedata->file_header.e_machine)
aca88567
NC
1399 {
1400 case EM_MIPS:
1401 /* Note: We assume that reloc_info has already been adjusted for us. */
1402 return ELF64_MIPS_R_TYPE (reloc_info);
1403
1404 case EM_SPARCV9:
1405 return ELF64_R_TYPE_ID (reloc_info);
1406
1407 default:
1408 return ELF64_R_TYPE (reloc_info);
1409 }
1410}
1411
1412/* Return the symbol index extracted from the reloc info field. */
1413
625d49fc
AM
1414static uint64_t
1415get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1416{
1417 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1418}
1419
015dc7e1 1420static inline bool
dda8d76d 1421uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1422{
1423 return
dda8d76d 1424 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1425 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1426 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1427 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1428 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1429}
1430
d3ba0551
AM
1431/* Display the contents of the relocation data found at the specified
1432 offset. */
ee42cf8c 1433
015dc7e1 1434static bool
dda8d76d
NC
1435dump_relocations (Filedata * filedata,
1436 unsigned long rel_offset,
1437 unsigned long rel_size,
1438 Elf_Internal_Sym * symtab,
1439 unsigned long nsyms,
1440 char * strtab,
1441 unsigned long strtablen,
a7fd1186 1442 relocation_type rel_type,
015dc7e1 1443 bool is_dynsym)
4d6ed7c8 1444{
32ec8896 1445 unsigned long i;
2cf0635d 1446 Elf_Internal_Rela * rels;
015dc7e1 1447 bool res = true;
103f02d3 1448
a7fd1186
FS
1449 if (rel_type == reltype_unknown)
1450 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1451
a7fd1186 1452 if (rel_type == reltype_rela)
4d6ed7c8 1453 {
dda8d76d 1454 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1455 return false;
4d6ed7c8 1456 }
a7fd1186 1457 else if (rel_type == reltype_rel)
4d6ed7c8 1458 {
dda8d76d 1459 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1460 return false;
252b5132 1461 }
a7fd1186
FS
1462 else if (rel_type == reltype_relr)
1463 {
625d49fc 1464 uint64_t * relrs;
a7fd1186 1465 const char *format
b8281767 1466 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1467
1468 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1469 &rel_size))
1470 return false;
1471
b8281767
AM
1472 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size),
1473 rel_size);
a7fd1186 1474 for (i = 0; i < rel_size; i++)
625d49fc 1475 printf (format, relrs[i]);
a7fd1186
FS
1476 free (relrs);
1477 return true;
1478 }
252b5132 1479
410f7a12
L
1480 if (is_32bit_elf)
1481 {
a7fd1186 1482 if (rel_type == reltype_rela)
2c71103e
NC
1483 {
1484 if (do_wide)
1485 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1486 else
1487 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1488 }
410f7a12 1489 else
2c71103e
NC
1490 {
1491 if (do_wide)
1492 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1493 else
1494 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1495 }
410f7a12 1496 }
252b5132 1497 else
410f7a12 1498 {
a7fd1186 1499 if (rel_type == reltype_rela)
2c71103e
NC
1500 {
1501 if (do_wide)
8beeaeb7 1502 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1503 else
1504 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1505 }
410f7a12 1506 else
2c71103e
NC
1507 {
1508 if (do_wide)
8beeaeb7 1509 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1510 else
1511 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1512 }
410f7a12 1513 }
252b5132
RH
1514
1515 for (i = 0; i < rel_size; i++)
1516 {
2cf0635d 1517 const char * rtype;
625d49fc
AM
1518 uint64_t offset;
1519 uint64_t inf;
1520 uint64_t symtab_index;
1521 uint64_t type;
103f02d3 1522
b34976b6 1523 offset = rels[i].r_offset;
91d6fa6a 1524 inf = rels[i].r_info;
103f02d3 1525
dda8d76d 1526 type = get_reloc_type (filedata, inf);
91d6fa6a 1527 symtab_index = get_reloc_symindex (inf);
252b5132 1528
410f7a12
L
1529 if (is_32bit_elf)
1530 {
39dbeff8
AM
1531 printf ("%8.8lx %8.8lx ",
1532 (unsigned long) offset & 0xffffffff,
91d6fa6a 1533 (unsigned long) inf & 0xffffffff);
410f7a12
L
1534 }
1535 else
1536 {
39dbeff8 1537 printf (do_wide
b8281767
AM
1538 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1539 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1540 offset, inf);
410f7a12 1541 }
103f02d3 1542
dda8d76d 1543 switch (filedata->file_header.e_machine)
252b5132
RH
1544 {
1545 default:
1546 rtype = NULL;
1547 break;
1548
a06ea964
NC
1549 case EM_AARCH64:
1550 rtype = elf_aarch64_reloc_type (type);
1551 break;
1552
2b0337b0 1553 case EM_M32R:
252b5132 1554 case EM_CYGNUS_M32R:
9ea033b2 1555 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1556 break;
1557
1558 case EM_386:
22abe556 1559 case EM_IAMCU:
9ea033b2 1560 rtype = elf_i386_reloc_type (type);
252b5132
RH
1561 break;
1562
ba2685cc
AM
1563 case EM_68HC11:
1564 case EM_68HC12:
1565 rtype = elf_m68hc11_reloc_type (type);
1566 break;
75751cd9 1567
7b4ae824
JD
1568 case EM_S12Z:
1569 rtype = elf_s12z_reloc_type (type);
1570 break;
1571
252b5132 1572 case EM_68K:
9ea033b2 1573 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1574 break;
1575
f954747f
AM
1576 case EM_960:
1577 rtype = elf_i960_reloc_type (type);
1578 break;
1579
adde6300 1580 case EM_AVR:
2b0337b0 1581 case EM_AVR_OLD:
adde6300
AM
1582 rtype = elf_avr_reloc_type (type);
1583 break;
1584
9ea033b2
NC
1585 case EM_OLD_SPARCV9:
1586 case EM_SPARC32PLUS:
1587 case EM_SPARCV9:
252b5132 1588 case EM_SPARC:
9ea033b2 1589 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1590 break;
1591
e9f53129
AM
1592 case EM_SPU:
1593 rtype = elf_spu_reloc_type (type);
1594 break;
1595
708e2187
NC
1596 case EM_V800:
1597 rtype = v800_reloc_type (type);
1598 break;
2b0337b0 1599 case EM_V850:
252b5132 1600 case EM_CYGNUS_V850:
9ea033b2 1601 rtype = v850_reloc_type (type);
252b5132
RH
1602 break;
1603
2b0337b0 1604 case EM_D10V:
252b5132 1605 case EM_CYGNUS_D10V:
9ea033b2 1606 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1607 break;
1608
2b0337b0 1609 case EM_D30V:
252b5132 1610 case EM_CYGNUS_D30V:
9ea033b2 1611 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1612 break;
1613
d172d4ba
NC
1614 case EM_DLX:
1615 rtype = elf_dlx_reloc_type (type);
1616 break;
1617
252b5132 1618 case EM_SH:
9ea033b2 1619 rtype = elf_sh_reloc_type (type);
252b5132
RH
1620 break;
1621
2b0337b0 1622 case EM_MN10300:
252b5132 1623 case EM_CYGNUS_MN10300:
9ea033b2 1624 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1625 break;
1626
2b0337b0 1627 case EM_MN10200:
252b5132 1628 case EM_CYGNUS_MN10200:
9ea033b2 1629 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1630 break;
1631
2b0337b0 1632 case EM_FR30:
252b5132 1633 case EM_CYGNUS_FR30:
9ea033b2 1634 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1635 break;
1636
ba2685cc
AM
1637 case EM_CYGNUS_FRV:
1638 rtype = elf_frv_reloc_type (type);
1639 break;
5c70f934 1640
b8891f8d
AJ
1641 case EM_CSKY:
1642 rtype = elf_csky_reloc_type (type);
1643 break;
1644
3f8107ab
AM
1645 case EM_FT32:
1646 rtype = elf_ft32_reloc_type (type);
1647 break;
1648
252b5132 1649 case EM_MCORE:
9ea033b2 1650 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1651 break;
1652
3c3bdf30
NC
1653 case EM_MMIX:
1654 rtype = elf_mmix_reloc_type (type);
1655 break;
1656
5506d11a
AM
1657 case EM_MOXIE:
1658 rtype = elf_moxie_reloc_type (type);
1659 break;
1660
2469cfa2 1661 case EM_MSP430:
dda8d76d 1662 if (uses_msp430x_relocs (filedata))
13761a11
NC
1663 {
1664 rtype = elf_msp430x_reloc_type (type);
1665 break;
1666 }
1a0670f3 1667 /* Fall through. */
2469cfa2
NC
1668 case EM_MSP430_OLD:
1669 rtype = elf_msp430_reloc_type (type);
1670 break;
1671
35c08157
KLC
1672 case EM_NDS32:
1673 rtype = elf_nds32_reloc_type (type);
1674 break;
1675
252b5132 1676 case EM_PPC:
9ea033b2 1677 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1678 break;
1679
c833c019
AM
1680 case EM_PPC64:
1681 rtype = elf_ppc64_reloc_type (type);
1682 break;
1683
252b5132 1684 case EM_MIPS:
4fe85591 1685 case EM_MIPS_RS3_LE:
9ea033b2 1686 rtype = elf_mips_reloc_type (type);
252b5132
RH
1687 break;
1688
e23eba97
NC
1689 case EM_RISCV:
1690 rtype = elf_riscv_reloc_type (type);
1691 break;
1692
252b5132 1693 case EM_ALPHA:
9ea033b2 1694 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1695 break;
1696
1697 case EM_ARM:
9ea033b2 1698 rtype = elf_arm_reloc_type (type);
252b5132
RH
1699 break;
1700
584da044 1701 case EM_ARC:
886a2506
NC
1702 case EM_ARC_COMPACT:
1703 case EM_ARC_COMPACT2:
9ea033b2 1704 rtype = elf_arc_reloc_type (type);
252b5132
RH
1705 break;
1706
1707 case EM_PARISC:
69e617ca 1708 rtype = elf_hppa_reloc_type (type);
252b5132 1709 break;
7d466069 1710
b8720f9d
JL
1711 case EM_H8_300:
1712 case EM_H8_300H:
1713 case EM_H8S:
1714 rtype = elf_h8_reloc_type (type);
1715 break;
1716
73589c9d
CS
1717 case EM_OR1K:
1718 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1719 break;
1720
7d466069 1721 case EM_PJ:
2b0337b0 1722 case EM_PJ_OLD:
7d466069
ILT
1723 rtype = elf_pj_reloc_type (type);
1724 break;
800eeca4
JW
1725 case EM_IA_64:
1726 rtype = elf_ia64_reloc_type (type);
1727 break;
1b61cf92
HPN
1728
1729 case EM_CRIS:
1730 rtype = elf_cris_reloc_type (type);
1731 break;
535c37ff 1732
f954747f
AM
1733 case EM_860:
1734 rtype = elf_i860_reloc_type (type);
1735 break;
1736
bcedfee6 1737 case EM_X86_64:
8a9036a4 1738 case EM_L1OM:
7a9068fe 1739 case EM_K1OM:
bcedfee6
NC
1740 rtype = elf_x86_64_reloc_type (type);
1741 break;
a85d7ed0 1742
f954747f
AM
1743 case EM_S370:
1744 rtype = i370_reloc_type (type);
1745 break;
1746
53c7db4b
KH
1747 case EM_S390_OLD:
1748 case EM_S390:
1749 rtype = elf_s390_reloc_type (type);
1750 break;
93fbbb04 1751
1c0d3aa6
NC
1752 case EM_SCORE:
1753 rtype = elf_score_reloc_type (type);
1754 break;
1755
93fbbb04
GK
1756 case EM_XSTORMY16:
1757 rtype = elf_xstormy16_reloc_type (type);
1758 break;
179d3252 1759
1fe1f39c
NC
1760 case EM_CRX:
1761 rtype = elf_crx_reloc_type (type);
1762 break;
1763
179d3252
JT
1764 case EM_VAX:
1765 rtype = elf_vax_reloc_type (type);
1766 break;
1e4cf259 1767
619ed720
EB
1768 case EM_VISIUM:
1769 rtype = elf_visium_reloc_type (type);
1770 break;
1771
aca4efc7
JM
1772 case EM_BPF:
1773 rtype = elf_bpf_reloc_type (type);
1774 break;
1775
cfb8c092
NC
1776 case EM_ADAPTEVA_EPIPHANY:
1777 rtype = elf_epiphany_reloc_type (type);
1778 break;
1779
1e4cf259
NC
1780 case EM_IP2K:
1781 case EM_IP2K_OLD:
1782 rtype = elf_ip2k_reloc_type (type);
1783 break;
3b36097d
SC
1784
1785 case EM_IQ2000:
1786 rtype = elf_iq2000_reloc_type (type);
1787 break;
88da6820
NC
1788
1789 case EM_XTENSA_OLD:
1790 case EM_XTENSA:
1791 rtype = elf_xtensa_reloc_type (type);
1792 break;
a34e3ecb 1793
84e94c90
NC
1794 case EM_LATTICEMICO32:
1795 rtype = elf_lm32_reloc_type (type);
1796 break;
1797
ff7eeb89 1798 case EM_M32C_OLD:
49f58d10
JB
1799 case EM_M32C:
1800 rtype = elf_m32c_reloc_type (type);
1801 break;
1802
d031aafb
NS
1803 case EM_MT:
1804 rtype = elf_mt_reloc_type (type);
a34e3ecb 1805 break;
1d65ded4
CM
1806
1807 case EM_BLACKFIN:
1808 rtype = elf_bfin_reloc_type (type);
1809 break;
15ab5209
DB
1810
1811 case EM_CYGNUS_MEP:
1812 rtype = elf_mep_reloc_type (type);
1813 break;
60bca95a
NC
1814
1815 case EM_CR16:
1816 rtype = elf_cr16_reloc_type (type);
1817 break;
dd24e3da 1818
7ba29e2a
NC
1819 case EM_MICROBLAZE:
1820 case EM_MICROBLAZE_OLD:
1821 rtype = elf_microblaze_reloc_type (type);
1822 break;
c7927a3c 1823
99c513f6
DD
1824 case EM_RL78:
1825 rtype = elf_rl78_reloc_type (type);
1826 break;
1827
c7927a3c
NC
1828 case EM_RX:
1829 rtype = elf_rx_reloc_type (type);
1830 break;
c29aca4a 1831
a3c62988
NC
1832 case EM_METAG:
1833 rtype = elf_metag_reloc_type (type);
1834 break;
1835
40b36596
JM
1836 case EM_TI_C6000:
1837 rtype = elf_tic6x_reloc_type (type);
1838 break;
aa137e4d
NC
1839
1840 case EM_TILEGX:
1841 rtype = elf_tilegx_reloc_type (type);
1842 break;
1843
1844 case EM_TILEPRO:
1845 rtype = elf_tilepro_reloc_type (type);
1846 break;
f6c1a2d5 1847
f96bd6c2
PC
1848 case EM_WEBASSEMBLY:
1849 rtype = elf_wasm32_reloc_type (type);
1850 break;
1851
f6c1a2d5
NC
1852 case EM_XGATE:
1853 rtype = elf_xgate_reloc_type (type);
1854 break;
36591ba1
SL
1855
1856 case EM_ALTERA_NIOS2:
1857 rtype = elf_nios2_reloc_type (type);
1858 break;
2b100bb5
DD
1859
1860 case EM_TI_PRU:
1861 rtype = elf_pru_reloc_type (type);
1862 break;
fe944acf
FT
1863
1864 case EM_NFP:
1865 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1866 rtype = elf_nfp3200_reloc_type (type);
1867 else
1868 rtype = elf_nfp_reloc_type (type);
1869 break;
6655dba2
SB
1870
1871 case EM_Z80:
1872 rtype = elf_z80_reloc_type (type);
1873 break;
e9a0721f 1874
1875 case EM_LOONGARCH:
1876 rtype = elf_loongarch_reloc_type (type);
1877 break;
1878
0c857ef4
SM
1879 case EM_AMDGPU:
1880 rtype = elf_amdgpu_reloc_type (type);
1881 break;
252b5132
RH
1882 }
1883
1884 if (rtype == NULL)
39dbeff8 1885 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1886 else
5c144731 1887 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1888
dda8d76d 1889 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1890 && rtype != NULL
7ace3541 1891 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1892 && rel_type == reltype_rela)
7ace3541
RH
1893 {
1894 switch (rels[i].r_addend)
1895 {
1896 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1897 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1898 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1899 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1900 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1901 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1902 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1903 default: rtype = NULL;
1904 }
32ec8896 1905
7ace3541
RH
1906 if (rtype)
1907 printf (" (%s)", rtype);
1908 else
1909 {
1910 putchar (' ');
1911 printf (_("<unknown addend: %lx>"),
1912 (unsigned long) rels[i].r_addend);
015dc7e1 1913 res = false;
7ace3541
RH
1914 }
1915 }
1916 else if (symtab_index)
252b5132 1917 {
af3fc3bc 1918 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1919 {
27a45f42
AS
1920 error (_(" bad symbol index: %08lx in reloc\n"),
1921 (unsigned long) symtab_index);
015dc7e1 1922 res = false;
32ec8896 1923 }
af3fc3bc 1924 else
19936277 1925 {
2cf0635d 1926 Elf_Internal_Sym * psym;
bb4d2ac2
L
1927 const char * version_string;
1928 enum versioned_symbol_info sym_info;
1929 unsigned short vna_other;
19936277 1930
af3fc3bc 1931 psym = symtab + symtab_index;
103f02d3 1932
bb4d2ac2 1933 version_string
dda8d76d 1934 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1935 strtab, strtablen,
1936 symtab_index,
1937 psym,
1938 &sym_info,
1939 &vna_other);
1940
af3fc3bc 1941 printf (" ");
171191ba 1942
d8045f23
NC
1943 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1944 {
1945 const char * name;
1946 unsigned int len;
1947 unsigned int width = is_32bit_elf ? 8 : 14;
1948
1949 /* Relocations against GNU_IFUNC symbols do not use the value
1950 of the symbol as the address to relocate against. Instead
1951 they invoke the function named by the symbol and use its
1952 result as the address for relocation.
1953
1954 To indicate this to the user, do not display the value of
1955 the symbol in the "Symbols's Value" field. Instead show
1956 its name followed by () as a hint that the symbol is
1957 invoked. */
1958
1959 if (strtab == NULL
1960 || psym->st_name == 0
1961 || psym->st_name >= strtablen)
1962 name = "??";
1963 else
1964 name = strtab + psym->st_name;
1965
1966 len = print_symbol (width, name);
bb4d2ac2
L
1967 if (version_string)
1968 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1969 version_string);
d8045f23
NC
1970 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1971 }
1972 else
1973 {
1974 print_vma (psym->st_value, LONG_HEX);
171191ba 1975
d8045f23
NC
1976 printf (is_32bit_elf ? " " : " ");
1977 }
103f02d3 1978
af3fc3bc 1979 if (psym->st_name == 0)
f1ef08cb 1980 {
2cf0635d 1981 const char * sec_name = "<null>";
f1ef08cb
AM
1982 char name_buf[40];
1983
1984 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1985 {
b9af6379
AM
1986 if (psym->st_shndx < filedata->file_header.e_shnum
1987 && filedata->section_headers != NULL)
84714f86
AM
1988 sec_name = section_name_print (filedata,
1989 filedata->section_headers
b9e920ec 1990 + psym->st_shndx);
f1ef08cb
AM
1991 else if (psym->st_shndx == SHN_ABS)
1992 sec_name = "ABS";
1993 else if (psym->st_shndx == SHN_COMMON)
1994 sec_name = "COMMON";
dda8d76d 1995 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1996 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1997 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1998 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1999 sec_name = "SCOMMON";
dda8d76d 2000 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2001 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2002 sec_name = "SUNDEF";
dda8d76d
NC
2003 else if ((filedata->file_header.e_machine == EM_X86_64
2004 || filedata->file_header.e_machine == EM_L1OM
2005 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2006 && psym->st_shndx == SHN_X86_64_LCOMMON)
2007 sec_name = "LARGE_COMMON";
dda8d76d
NC
2008 else if (filedata->file_header.e_machine == EM_IA_64
2009 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2010 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2011 sec_name = "ANSI_COM";
dda8d76d 2012 else if (is_ia64_vms (filedata)
148b93f2
NC
2013 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2014 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2015 else
2016 {
2017 sprintf (name_buf, "<section 0x%x>",
2018 (unsigned int) psym->st_shndx);
2019 sec_name = name_buf;
2020 }
2021 }
2022 print_symbol (22, sec_name);
2023 }
af3fc3bc 2024 else if (strtab == NULL)
d79b3d50 2025 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2026 else if (psym->st_name >= strtablen)
32ec8896 2027 {
27a45f42
AS
2028 error (_("<corrupt string table index: %3ld>\n"),
2029 psym->st_name);
015dc7e1 2030 res = false;
32ec8896 2031 }
af3fc3bc 2032 else
bb4d2ac2
L
2033 {
2034 print_symbol (22, strtab + psym->st_name);
2035 if (version_string)
2036 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2037 version_string);
2038 }
103f02d3 2039
a7fd1186 2040 if (rel_type == reltype_rela)
171191ba 2041 {
625d49fc 2042 uint64_t off = rels[i].r_addend;
171191ba 2043
625d49fc
AM
2044 if ((int64_t) off < 0)
2045 printf (" - %" PRIx64, -off);
171191ba 2046 else
625d49fc 2047 printf (" + %" PRIx64, off);
171191ba 2048 }
19936277 2049 }
252b5132 2050 }
a7fd1186 2051 else if (rel_type == reltype_rela)
f7a99963 2052 {
625d49fc 2053 uint64_t off = rels[i].r_addend;
e04d7088
L
2054
2055 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2056 if ((int64_t) off < 0)
2057 printf ("-%" PRIx64, -off);
e04d7088 2058 else
625d49fc 2059 printf ("%" PRIx64, off);
f7a99963 2060 }
252b5132 2061
dda8d76d 2062 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2063 && rtype != NULL
2064 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2065 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2066
252b5132 2067 putchar ('\n');
2c71103e 2068
dda8d76d 2069 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2070 {
625d49fc
AM
2071 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2072 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2073 const char * rtype2 = elf_mips_reloc_type (type2);
2074 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2075
2c71103e
NC
2076 printf (" Type2: ");
2077
2078 if (rtype2 == NULL)
39dbeff8
AM
2079 printf (_("unrecognized: %-7lx"),
2080 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2081 else
2082 printf ("%-17.17s", rtype2);
2083
18bd398b 2084 printf ("\n Type3: ");
2c71103e
NC
2085
2086 if (rtype3 == NULL)
39dbeff8
AM
2087 printf (_("unrecognized: %-7lx"),
2088 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2089 else
2090 printf ("%-17.17s", rtype3);
2091
53c7db4b 2092 putchar ('\n');
2c71103e 2093 }
252b5132
RH
2094 }
2095
c8286bd1 2096 free (rels);
32ec8896
NC
2097
2098 return res;
252b5132
RH
2099}
2100
37c18eed
SD
2101static const char *
2102get_aarch64_dynamic_type (unsigned long type)
2103{
2104 switch (type)
2105 {
2106 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2107 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2108 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2109 default:
2110 return NULL;
2111 }
2112}
2113
252b5132 2114static const char *
d3ba0551 2115get_mips_dynamic_type (unsigned long type)
252b5132
RH
2116{
2117 switch (type)
2118 {
2119 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2120 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2121 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2122 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2123 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2124 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2125 case DT_MIPS_MSYM: return "MIPS_MSYM";
2126 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2127 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2128 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2129 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2130 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2131 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2132 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2133 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2134 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2135 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2136 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2137 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2138 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2139 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2140 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2141 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2142 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2143 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2144 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2145 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2146 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2147 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2148 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2149 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2150 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2151 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2152 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2153 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2154 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2155 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2156 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2157 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2158 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2159 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2160 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2161 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2162 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2163 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2164 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2165 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2166 default:
2167 return NULL;
2168 }
2169}
2170
9a097730 2171static const char *
d3ba0551 2172get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2173{
2174 switch (type)
2175 {
2176 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2177 default:
2178 return NULL;
2179 }
103f02d3
UD
2180}
2181
7490d522
AM
2182static const char *
2183get_ppc_dynamic_type (unsigned long type)
2184{
2185 switch (type)
2186 {
a7f2871e 2187 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2188 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2189 default:
2190 return NULL;
2191 }
2192}
2193
f1cb7e17 2194static const char *
d3ba0551 2195get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2196{
2197 switch (type)
2198 {
a7f2871e
AM
2199 case DT_PPC64_GLINK: return "PPC64_GLINK";
2200 case DT_PPC64_OPD: return "PPC64_OPD";
2201 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2202 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2203 default:
2204 return NULL;
2205 }
2206}
2207
103f02d3 2208static const char *
d3ba0551 2209get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2210{
2211 switch (type)
2212 {
2213 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2214 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2215 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2216 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2217 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2218 case DT_HP_PREINIT: return "HP_PREINIT";
2219 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2220 case DT_HP_NEEDED: return "HP_NEEDED";
2221 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2222 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2223 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2224 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2225 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2226 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2227 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2228 case DT_HP_FILTERED: return "HP_FILTERED";
2229 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2230 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2231 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2232 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2233 case DT_PLT: return "PLT";
2234 case DT_PLT_SIZE: return "PLT_SIZE";
2235 case DT_DLT: return "DLT";
2236 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2237 default:
2238 return NULL;
2239 }
2240}
9a097730 2241
ecc51f48 2242static const char *
d3ba0551 2243get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2244{
2245 switch (type)
2246 {
148b93f2
NC
2247 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2248 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2249 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2250 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2251 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2252 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2253 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2254 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2255 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2256 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2257 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2258 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2259 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2260 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2261 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2262 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2263 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2264 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2265 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2266 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2267 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2268 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2269 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2270 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2271 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2272 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2273 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2274 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2275 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2276 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2277 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2278 default:
2279 return NULL;
2280 }
2281}
2282
fd85a6a1
NC
2283static const char *
2284get_solaris_section_type (unsigned long type)
2285{
2286 switch (type)
2287 {
2288 case 0x6fffffee: return "SUNW_ancillary";
2289 case 0x6fffffef: return "SUNW_capchain";
2290 case 0x6ffffff0: return "SUNW_capinfo";
2291 case 0x6ffffff1: return "SUNW_symsort";
2292 case 0x6ffffff2: return "SUNW_tlssort";
2293 case 0x6ffffff3: return "SUNW_LDYNSYM";
2294 case 0x6ffffff4: return "SUNW_dof";
2295 case 0x6ffffff5: return "SUNW_cap";
2296 case 0x6ffffff6: return "SUNW_SIGNATURE";
2297 case 0x6ffffff7: return "SUNW_ANNOTATE";
2298 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2299 case 0x6ffffff9: return "SUNW_DEBUG";
2300 case 0x6ffffffa: return "SUNW_move";
2301 case 0x6ffffffb: return "SUNW_COMDAT";
2302 case 0x6ffffffc: return "SUNW_syminfo";
2303 case 0x6ffffffd: return "SUNW_verdef";
2304 case 0x6ffffffe: return "SUNW_verneed";
2305 case 0x6fffffff: return "SUNW_versym";
2306 case 0x70000000: return "SPARC_GOTDATA";
2307 default: return NULL;
2308 }
2309}
2310
fabcb361
RH
2311static const char *
2312get_alpha_dynamic_type (unsigned long type)
2313{
2314 switch (type)
2315 {
2316 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2317 default: return NULL;
fabcb361
RH
2318 }
2319}
2320
1c0d3aa6
NC
2321static const char *
2322get_score_dynamic_type (unsigned long type)
2323{
2324 switch (type)
2325 {
2326 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2327 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2328 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2329 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2330 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2331 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2332 default: return NULL;
1c0d3aa6
NC
2333 }
2334}
2335
40b36596
JM
2336static const char *
2337get_tic6x_dynamic_type (unsigned long type)
2338{
2339 switch (type)
2340 {
2341 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2342 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2343 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2344 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2345 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2346 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2347 default: return NULL;
40b36596
JM
2348 }
2349}
1c0d3aa6 2350
36591ba1
SL
2351static const char *
2352get_nios2_dynamic_type (unsigned long type)
2353{
2354 switch (type)
2355 {
2356 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2357 default: return NULL;
36591ba1
SL
2358 }
2359}
2360
fd85a6a1
NC
2361static const char *
2362get_solaris_dynamic_type (unsigned long type)
2363{
2364 switch (type)
2365 {
2366 case 0x6000000d: return "SUNW_AUXILIARY";
2367 case 0x6000000e: return "SUNW_RTLDINF";
2368 case 0x6000000f: return "SUNW_FILTER";
2369 case 0x60000010: return "SUNW_CAP";
2370 case 0x60000011: return "SUNW_SYMTAB";
2371 case 0x60000012: return "SUNW_SYMSZ";
2372 case 0x60000013: return "SUNW_SORTENT";
2373 case 0x60000014: return "SUNW_SYMSORT";
2374 case 0x60000015: return "SUNW_SYMSORTSZ";
2375 case 0x60000016: return "SUNW_TLSSORT";
2376 case 0x60000017: return "SUNW_TLSSORTSZ";
2377 case 0x60000018: return "SUNW_CAPINFO";
2378 case 0x60000019: return "SUNW_STRPAD";
2379 case 0x6000001a: return "SUNW_CAPCHAIN";
2380 case 0x6000001b: return "SUNW_LDMACH";
2381 case 0x6000001d: return "SUNW_CAPCHAINENT";
2382 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2383 case 0x60000021: return "SUNW_PARENT";
2384 case 0x60000023: return "SUNW_ASLR";
2385 case 0x60000025: return "SUNW_RELAX";
2386 case 0x60000029: return "SUNW_NXHEAP";
2387 case 0x6000002b: return "SUNW_NXSTACK";
2388
2389 case 0x70000001: return "SPARC_REGISTER";
2390 case 0x7ffffffd: return "AUXILIARY";
2391 case 0x7ffffffe: return "USED";
2392 case 0x7fffffff: return "FILTER";
2393
15f205b1 2394 default: return NULL;
fd85a6a1
NC
2395 }
2396}
2397
8155b853
NC
2398static const char *
2399get_riscv_dynamic_type (unsigned long type)
2400{
2401 switch (type)
2402 {
2403 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2404 default:
2405 return NULL;
2406 }
2407}
2408
252b5132 2409static const char *
dda8d76d 2410get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2411{
e9e44622 2412 static char buff[64];
252b5132
RH
2413
2414 switch (type)
2415 {
2416 case DT_NULL: return "NULL";
2417 case DT_NEEDED: return "NEEDED";
2418 case DT_PLTRELSZ: return "PLTRELSZ";
2419 case DT_PLTGOT: return "PLTGOT";
2420 case DT_HASH: return "HASH";
2421 case DT_STRTAB: return "STRTAB";
2422 case DT_SYMTAB: return "SYMTAB";
2423 case DT_RELA: return "RELA";
2424 case DT_RELASZ: return "RELASZ";
2425 case DT_RELAENT: return "RELAENT";
2426 case DT_STRSZ: return "STRSZ";
2427 case DT_SYMENT: return "SYMENT";
2428 case DT_INIT: return "INIT";
2429 case DT_FINI: return "FINI";
2430 case DT_SONAME: return "SONAME";
2431 case DT_RPATH: return "RPATH";
2432 case DT_SYMBOLIC: return "SYMBOLIC";
2433 case DT_REL: return "REL";
2434 case DT_RELSZ: return "RELSZ";
2435 case DT_RELENT: return "RELENT";
dd207c13
FS
2436 case DT_RELR: return "RELR";
2437 case DT_RELRSZ: return "RELRSZ";
2438 case DT_RELRENT: return "RELRENT";
252b5132
RH
2439 case DT_PLTREL: return "PLTREL";
2440 case DT_DEBUG: return "DEBUG";
2441 case DT_TEXTREL: return "TEXTREL";
2442 case DT_JMPREL: return "JMPREL";
2443 case DT_BIND_NOW: return "BIND_NOW";
2444 case DT_INIT_ARRAY: return "INIT_ARRAY";
2445 case DT_FINI_ARRAY: return "FINI_ARRAY";
2446 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2447 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2448 case DT_RUNPATH: return "RUNPATH";
2449 case DT_FLAGS: return "FLAGS";
2d0e6f43 2450
d1133906
NC
2451 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2452 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2453 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2454
05107a46 2455 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2456 case DT_PLTPADSZ: return "PLTPADSZ";
2457 case DT_MOVEENT: return "MOVEENT";
2458 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2459 case DT_FEATURE: return "FEATURE";
252b5132
RH
2460 case DT_POSFLAG_1: return "POSFLAG_1";
2461 case DT_SYMINSZ: return "SYMINSZ";
2462 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2463
252b5132 2464 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2465 case DT_CONFIG: return "CONFIG";
2466 case DT_DEPAUDIT: return "DEPAUDIT";
2467 case DT_AUDIT: return "AUDIT";
2468 case DT_PLTPAD: return "PLTPAD";
2469 case DT_MOVETAB: return "MOVETAB";
252b5132 2470 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2471
252b5132 2472 case DT_VERSYM: return "VERSYM";
103f02d3 2473
67a4f2b7
AO
2474 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2475 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2476 case DT_RELACOUNT: return "RELACOUNT";
2477 case DT_RELCOUNT: return "RELCOUNT";
2478 case DT_FLAGS_1: return "FLAGS_1";
2479 case DT_VERDEF: return "VERDEF";
2480 case DT_VERDEFNUM: return "VERDEFNUM";
2481 case DT_VERNEED: return "VERNEED";
2482 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2483
019148e4 2484 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2485 case DT_USED: return "USED";
2486 case DT_FILTER: return "FILTER";
103f02d3 2487
047b2264
JJ
2488 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2489 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2490 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2491 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2492 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2493 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2494 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2495
252b5132
RH
2496 default:
2497 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2498 {
2cf0635d 2499 const char * result;
103f02d3 2500
dda8d76d 2501 switch (filedata->file_header.e_machine)
252b5132 2502 {
37c18eed
SD
2503 case EM_AARCH64:
2504 result = get_aarch64_dynamic_type (type);
2505 break;
252b5132 2506 case EM_MIPS:
4fe85591 2507 case EM_MIPS_RS3_LE:
252b5132
RH
2508 result = get_mips_dynamic_type (type);
2509 break;
9a097730
RH
2510 case EM_SPARCV9:
2511 result = get_sparc64_dynamic_type (type);
2512 break;
7490d522
AM
2513 case EM_PPC:
2514 result = get_ppc_dynamic_type (type);
2515 break;
f1cb7e17
AM
2516 case EM_PPC64:
2517 result = get_ppc64_dynamic_type (type);
2518 break;
ecc51f48
NC
2519 case EM_IA_64:
2520 result = get_ia64_dynamic_type (type);
2521 break;
fabcb361
RH
2522 case EM_ALPHA:
2523 result = get_alpha_dynamic_type (type);
2524 break;
1c0d3aa6
NC
2525 case EM_SCORE:
2526 result = get_score_dynamic_type (type);
2527 break;
40b36596
JM
2528 case EM_TI_C6000:
2529 result = get_tic6x_dynamic_type (type);
2530 break;
36591ba1
SL
2531 case EM_ALTERA_NIOS2:
2532 result = get_nios2_dynamic_type (type);
2533 break;
8155b853
NC
2534 case EM_RISCV:
2535 result = get_riscv_dynamic_type (type);
2536 break;
252b5132 2537 default:
dda8d76d 2538 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2539 result = get_solaris_dynamic_type (type);
2540 else
2541 result = NULL;
252b5132
RH
2542 break;
2543 }
2544
2545 if (result != NULL)
2546 return result;
2547
e9e44622 2548 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2549 }
eec8f817 2550 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2551 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2552 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2553 {
2cf0635d 2554 const char * result;
103f02d3 2555
dda8d76d 2556 switch (filedata->file_header.e_machine)
103f02d3
UD
2557 {
2558 case EM_PARISC:
2559 result = get_parisc_dynamic_type (type);
2560 break;
148b93f2
NC
2561 case EM_IA_64:
2562 result = get_ia64_dynamic_type (type);
2563 break;
103f02d3 2564 default:
dda8d76d 2565 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2566 result = get_solaris_dynamic_type (type);
2567 else
2568 result = NULL;
103f02d3
UD
2569 break;
2570 }
2571
2572 if (result != NULL)
2573 return result;
2574
e9e44622
JJ
2575 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2576 type);
103f02d3 2577 }
252b5132 2578 else
e9e44622 2579 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2580
252b5132
RH
2581 return buff;
2582 }
2583}
2584
93df3340
AM
2585static bool get_program_headers (Filedata *);
2586static bool get_dynamic_section (Filedata *);
2587
2588static void
2589locate_dynamic_section (Filedata *filedata)
2590{
2591 unsigned long dynamic_addr = 0;
be7d229a 2592 uint64_t dynamic_size = 0;
93df3340
AM
2593
2594 if (filedata->file_header.e_phnum != 0
2595 && get_program_headers (filedata))
2596 {
2597 Elf_Internal_Phdr *segment;
2598 unsigned int i;
2599
2600 for (i = 0, segment = filedata->program_headers;
2601 i < filedata->file_header.e_phnum;
2602 i++, segment++)
2603 {
2604 if (segment->p_type == PT_DYNAMIC)
2605 {
2606 dynamic_addr = segment->p_offset;
2607 dynamic_size = segment->p_filesz;
2608
2609 if (filedata->section_headers != NULL)
2610 {
2611 Elf_Internal_Shdr *sec;
2612
2613 sec = find_section (filedata, ".dynamic");
2614 if (sec != NULL)
2615 {
2616 if (sec->sh_size == 0
2617 || sec->sh_type == SHT_NOBITS)
2618 {
2619 dynamic_addr = 0;
2620 dynamic_size = 0;
2621 }
2622 else
2623 {
2624 dynamic_addr = sec->sh_offset;
2625 dynamic_size = sec->sh_size;
2626 }
2627 }
2628 }
2629
2630 if (dynamic_addr > filedata->file_size
2631 || (dynamic_size > filedata->file_size - dynamic_addr))
2632 {
2633 dynamic_addr = 0;
2634 dynamic_size = 0;
2635 }
2636 break;
2637 }
2638 }
2639 }
2640 filedata->dynamic_addr = dynamic_addr;
2641 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2642}
2643
2644static bool
2645is_pie (Filedata *filedata)
2646{
2647 Elf_Internal_Dyn *entry;
2648
2649 if (filedata->dynamic_size == 0)
2650 locate_dynamic_section (filedata);
2651 if (filedata->dynamic_size <= 1)
2652 return false;
2653
2654 if (!get_dynamic_section (filedata))
2655 return false;
2656
2657 for (entry = filedata->dynamic_section;
2658 entry < filedata->dynamic_section + filedata->dynamic_nent;
2659 entry++)
2660 {
2661 if (entry->d_tag == DT_FLAGS_1)
2662 {
2663 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2664 return true;
2665 break;
2666 }
2667 }
2668 return false;
2669}
2670
252b5132 2671static char *
93df3340 2672get_file_type (Filedata *filedata)
252b5132 2673{
93df3340 2674 unsigned e_type = filedata->file_header.e_type;
89246a0e 2675 static char buff[64];
252b5132
RH
2676
2677 switch (e_type)
2678 {
32ec8896
NC
2679 case ET_NONE: return _("NONE (None)");
2680 case ET_REL: return _("REL (Relocatable file)");
2681 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2682 case ET_DYN:
2683 if (is_pie (filedata))
2684 return _("DYN (Position-Independent Executable file)");
2685 else
2686 return _("DYN (Shared object file)");
32ec8896 2687 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2688
2689 default:
2690 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2691 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2692 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2693 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2694 else
e9e44622 2695 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2696 return buff;
2697 }
2698}
2699
2700static char *
d3ba0551 2701get_machine_name (unsigned e_machine)
252b5132 2702{
b34976b6 2703 static char buff[64]; /* XXX */
252b5132
RH
2704
2705 switch (e_machine)
2706 {
55e22ca8
NC
2707 /* Please keep this switch table sorted by increasing EM_ value. */
2708 /* 0 */
c45021f2
NC
2709 case EM_NONE: return _("None");
2710 case EM_M32: return "WE32100";
2711 case EM_SPARC: return "Sparc";
2712 case EM_386: return "Intel 80386";
2713 case EM_68K: return "MC68000";
2714 case EM_88K: return "MC88000";
22abe556 2715 case EM_IAMCU: return "Intel MCU";
fb70ec17 2716 case EM_860: return "Intel 80860";
c45021f2
NC
2717 case EM_MIPS: return "MIPS R3000";
2718 case EM_S370: return "IBM System/370";
55e22ca8 2719 /* 10 */
7036c0e1 2720 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2721 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2722 case EM_PARISC: return "HPPA";
55e22ca8 2723 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2724 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2725 case EM_960: return "Intel 80960";
c45021f2 2726 case EM_PPC: return "PowerPC";
55e22ca8 2727 /* 20 */
285d1771 2728 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2729 case EM_S390_OLD:
2730 case EM_S390: return "IBM S/390";
2731 case EM_SPU: return "SPU";
2732 /* 30 */
2733 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2734 case EM_FR20: return "Fujitsu FR20";
2735 case EM_RH32: return "TRW RH32";
b34976b6 2736 case EM_MCORE: return "MCORE";
55e22ca8 2737 /* 40 */
7036c0e1
AJ
2738 case EM_ARM: return "ARM";
2739 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2740 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2741 case EM_SPARCV9: return "Sparc v9";
2742 case EM_TRICORE: return "Siemens Tricore";
584da044 2743 case EM_ARC: return "ARC";
c2dcd04e
NC
2744 case EM_H8_300: return "Renesas H8/300";
2745 case EM_H8_300H: return "Renesas H8/300H";
2746 case EM_H8S: return "Renesas H8S";
2747 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2748 /* 50 */
30800947 2749 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2750 case EM_MIPS_X: return "Stanford MIPS-X";
2751 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2752 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2753 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2754 case EM_PCP: return "Siemens PCP";
2755 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2756 case EM_NDR1: return "Denso NDR1 microprocesspr";
2757 case EM_STARCORE: return "Motorola Star*Core processor";
2758 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2759 /* 60 */
7036c0e1
AJ
2760 case EM_ST100: return "STMicroelectronics ST100 processor";
2761 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2762 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2763 case EM_PDSP: return "Sony DSP processor";
2764 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2765 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2766 case EM_FX66: return "Siemens FX66 microcontroller";
2767 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2768 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2769 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2770 /* 70 */
7036c0e1
AJ
2771 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2772 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2773 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2774 case EM_SVX: return "Silicon Graphics SVx";
2775 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2776 case EM_VAX: return "Digital VAX";
1b61cf92 2777 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2778 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2779 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2780 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2781 /* 80 */
b34976b6 2782 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2783 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2784 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2785 case EM_AVR_OLD:
2786 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2787 case EM_CYGNUS_FR30:
2788 case EM_FR30: return "Fujitsu FR30";
2789 case EM_CYGNUS_D10V:
2790 case EM_D10V: return "d10v";
2791 case EM_CYGNUS_D30V:
2792 case EM_D30V: return "d30v";
2793 case EM_CYGNUS_V850:
2794 case EM_V850: return "Renesas V850";
2795 case EM_CYGNUS_M32R:
2796 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2797 case EM_CYGNUS_MN10300:
2798 case EM_MN10300: return "mn10300";
2799 /* 90 */
2800 case EM_CYGNUS_MN10200:
2801 case EM_MN10200: return "mn10200";
2802 case EM_PJ: return "picoJava";
73589c9d 2803 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2804 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2805 case EM_XTENSA_OLD:
2806 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2807 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2808 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2809 case EM_NS32K: return "National Semiconductor 32000 series";
2810 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2811 case EM_SNP1K: return "Trebia SNP 1000 processor";
2812 /* 100 */
9abca702 2813 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2814 case EM_IP2K_OLD:
2815 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2816 case EM_MAX: return "MAX Processor";
2817 case EM_CR: return "National Semiconductor CompactRISC";
2818 case EM_F2MC16: return "Fujitsu F2MC16";
2819 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2820 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2821 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2822 case EM_SEP: return "Sharp embedded microprocessor";
2823 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2824 /* 110 */
11636f9e
JM
2825 case EM_UNICORE: return "Unicore";
2826 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2827 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2828 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2829 case EM_CRX: return "National Semiconductor CRX microprocessor";
2830 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2831 case EM_C166:
d70c5fc7 2832 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2833 case EM_M16C: return "Renesas M16C series microprocessors";
2834 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2835 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2836 /* 120 */
2837 case EM_M32C: return "Renesas M32c";
2838 /* 130 */
11636f9e
JM
2839 case EM_TSK3000: return "Altium TSK3000 core";
2840 case EM_RS08: return "Freescale RS08 embedded processor";
2841 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2842 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2843 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2844 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2845 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2846 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2847 /* 140 */
11636f9e
JM
2848 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2849 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2850 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2851 case EM_TI_PRU: return "TI PRU I/O processor";
2852 /* 160 */
11636f9e
JM
2853 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2854 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2855 case EM_R32C: return "Renesas R32C series microprocessors";
2856 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2857 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2858 case EM_8051: return "Intel 8051 and variants";
2859 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2860 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2861 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2862 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2863 /* 170 */
11636f9e
JM
2864 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2865 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2866 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2867 case EM_RX: return "Renesas RX";
a3c62988 2868 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2869 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2870 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2871 case EM_CR16:
2872 case EM_MICROBLAZE:
2873 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2874 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2875 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2876 /* 180 */
2877 case EM_L1OM: return "Intel L1OM";
2878 case EM_K1OM: return "Intel K1OM";
2879 case EM_INTEL182: return "Intel (reserved)";
2880 case EM_AARCH64: return "AArch64";
2881 case EM_ARM184: return "ARM (reserved)";
2882 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2883 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2884 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2885 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2886 /* 190 */
11636f9e 2887 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2888 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2889 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2890 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2891 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2892 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2893 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2894 case EM_RL78: return "Renesas RL78";
6d913794 2895 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2896 case EM_78K0R: return "Renesas 78K0R";
2897 /* 200 */
6d913794 2898 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2899 case EM_BA1: return "Beyond BA1 CPU architecture";
2900 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2901 case EM_XCORE: return "XMOS xCORE processor family";
2902 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2903 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2904 /* 210 */
6d913794
NC
2905 case EM_KM32: return "KM211 KM32 32-bit processor";
2906 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2907 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2908 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2909 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2910 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2911 case EM_COGE: return "Cognitive Smart Memory Processor";
2912 case EM_COOL: return "Bluechip Systems CoolEngine";
2913 case EM_NORC: return "Nanoradio Optimized RISC";
2914 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2915 /* 220 */
15f205b1 2916 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2917 case EM_VISIUM: return "CDS VISIUMcore processor";
2918 case EM_FT32: return "FTDI Chip FT32";
2919 case EM_MOXIE: return "Moxie";
2920 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2921 /* 230 (all reserved) */
2922 /* 240 */
55e22ca8
NC
2923 case EM_RISCV: return "RISC-V";
2924 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2925 case EM_CEVA: return "CEVA Processor Architecture Family";
2926 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2927 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2928 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2929 case EM_IMG1: return "Imagination Technologies";
2930 /* 250 */
fe944acf 2931 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2932 case EM_VE: return "NEC Vector Engine";
2933 case EM_CSKY: return "C-SKY";
2934 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2935 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2936 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2937 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2938 case EM_65816: return "WDC 65816/65C816";
01a8c731 2939 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2940 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2941
2942 /* Large numbers... */
2943 case EM_MT: return "Morpho Techologies MT processor";
2944 case EM_ALPHA: return "Alpha";
2945 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2946 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2947 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2948 case EM_IQ2000: return "Vitesse IQ2000";
2949 case EM_M32C_OLD:
2950 case EM_NIOS32: return "Altera Nios";
2951 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2952 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2953 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2954 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2955
252b5132 2956 default:
35d9dd2f 2957 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2958 return buff;
2959 }
2960}
2961
a9522a21
AB
2962static void
2963decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2964{
2965 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2966 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2967 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2968 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2969 architectures.
2970
2971 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2972 but also sets a specific architecture type in the e_flags field.
2973
2974 However, when decoding the flags we don't worry if we see an
2975 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2976 ARCEM architecture type. */
2977
2978 switch (e_flags & EF_ARC_MACH_MSK)
2979 {
2980 /* We only expect these to occur for EM_ARC_COMPACT2. */
2981 case EF_ARC_CPU_ARCV2EM:
2982 strcat (buf, ", ARC EM");
2983 break;
2984 case EF_ARC_CPU_ARCV2HS:
2985 strcat (buf, ", ARC HS");
2986 break;
2987
2988 /* We only expect these to occur for EM_ARC_COMPACT. */
2989 case E_ARC_MACH_ARC600:
2990 strcat (buf, ", ARC600");
2991 break;
2992 case E_ARC_MACH_ARC601:
2993 strcat (buf, ", ARC601");
2994 break;
2995 case E_ARC_MACH_ARC700:
2996 strcat (buf, ", ARC700");
2997 break;
2998
2999 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3000 new ELF with new architecture being read by an old version of
3001 readelf, or (c) An ELF built with non-GNU compiler that does not
3002 set the architecture in the e_flags. */
3003 default:
3004 if (e_machine == EM_ARC_COMPACT)
3005 strcat (buf, ", Unknown ARCompact");
3006 else
3007 strcat (buf, ", Unknown ARC");
3008 break;
3009 }
3010
3011 switch (e_flags & EF_ARC_OSABI_MSK)
3012 {
3013 case E_ARC_OSABI_ORIG:
3014 strcat (buf, ", (ABI:legacy)");
3015 break;
3016 case E_ARC_OSABI_V2:
3017 strcat (buf, ", (ABI:v2)");
3018 break;
3019 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3020 case E_ARC_OSABI_V3:
3021 strcat (buf, ", v3 no-legacy-syscalls ABI");
3022 break;
53a346d8
CZ
3023 case E_ARC_OSABI_V4:
3024 strcat (buf, ", v4 ABI");
3025 break;
a9522a21
AB
3026 default:
3027 strcat (buf, ", unrecognised ARC OSABI flag");
3028 break;
3029 }
3030}
3031
f3485b74 3032static void
d3ba0551 3033decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3034{
3035 unsigned eabi;
015dc7e1 3036 bool unknown = false;
f3485b74
NC
3037
3038 eabi = EF_ARM_EABI_VERSION (e_flags);
3039 e_flags &= ~ EF_ARM_EABIMASK;
3040
3041 /* Handle "generic" ARM flags. */
3042 if (e_flags & EF_ARM_RELEXEC)
3043 {
3044 strcat (buf, ", relocatable executable");
3045 e_flags &= ~ EF_ARM_RELEXEC;
3046 }
76da6bbe 3047
18a20338
CL
3048 if (e_flags & EF_ARM_PIC)
3049 {
3050 strcat (buf, ", position independent");
3051 e_flags &= ~ EF_ARM_PIC;
3052 }
3053
f3485b74
NC
3054 /* Now handle EABI specific flags. */
3055 switch (eabi)
3056 {
3057 default:
2c71103e 3058 strcat (buf, ", <unrecognized EABI>");
f3485b74 3059 if (e_flags)
015dc7e1 3060 unknown = true;
f3485b74
NC
3061 break;
3062
3063 case EF_ARM_EABI_VER1:
a5bcd848 3064 strcat (buf, ", Version1 EABI");
f3485b74
NC
3065 while (e_flags)
3066 {
3067 unsigned flag;
76da6bbe 3068
f3485b74
NC
3069 /* Process flags one bit at a time. */
3070 flag = e_flags & - e_flags;
3071 e_flags &= ~ flag;
76da6bbe 3072
f3485b74
NC
3073 switch (flag)
3074 {
a5bcd848 3075 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3076 strcat (buf, ", sorted symbol tables");
3077 break;
76da6bbe 3078
f3485b74 3079 default:
015dc7e1 3080 unknown = true;
f3485b74
NC
3081 break;
3082 }
3083 }
3084 break;
76da6bbe 3085
a5bcd848
PB
3086 case EF_ARM_EABI_VER2:
3087 strcat (buf, ", Version2 EABI");
3088 while (e_flags)
3089 {
3090 unsigned flag;
3091
3092 /* Process flags one bit at a time. */
3093 flag = e_flags & - e_flags;
3094 e_flags &= ~ flag;
3095
3096 switch (flag)
3097 {
3098 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3099 strcat (buf, ", sorted symbol tables");
3100 break;
3101
3102 case EF_ARM_DYNSYMSUSESEGIDX:
3103 strcat (buf, ", dynamic symbols use segment index");
3104 break;
3105
3106 case EF_ARM_MAPSYMSFIRST:
3107 strcat (buf, ", mapping symbols precede others");
3108 break;
3109
3110 default:
015dc7e1 3111 unknown = true;
a5bcd848
PB
3112 break;
3113 }
3114 }
3115 break;
3116
d507cf36
PB
3117 case EF_ARM_EABI_VER3:
3118 strcat (buf, ", Version3 EABI");
8cb51566
PB
3119 break;
3120
3121 case EF_ARM_EABI_VER4:
3122 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3123 while (e_flags)
3124 {
3125 unsigned flag;
3126
3127 /* Process flags one bit at a time. */
3128 flag = e_flags & - e_flags;
3129 e_flags &= ~ flag;
3130
3131 switch (flag)
3132 {
3133 case EF_ARM_BE8:
3134 strcat (buf, ", BE8");
3135 break;
3136
3137 case EF_ARM_LE8:
3138 strcat (buf, ", LE8");
3139 break;
3140
3141 default:
015dc7e1 3142 unknown = true;
3bfcb652
NC
3143 break;
3144 }
3bfcb652
NC
3145 }
3146 break;
3a4a14e9
PB
3147
3148 case EF_ARM_EABI_VER5:
3149 strcat (buf, ", Version5 EABI");
d507cf36
PB
3150 while (e_flags)
3151 {
3152 unsigned flag;
3153
3154 /* Process flags one bit at a time. */
3155 flag = e_flags & - e_flags;
3156 e_flags &= ~ flag;
3157
3158 switch (flag)
3159 {
3160 case EF_ARM_BE8:
3161 strcat (buf, ", BE8");
3162 break;
3163
3164 case EF_ARM_LE8:
3165 strcat (buf, ", LE8");
3166 break;
3167
3bfcb652
NC
3168 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3169 strcat (buf, ", soft-float ABI");
3170 break;
3171
3172 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3173 strcat (buf, ", hard-float ABI");
3174 break;
3175
d507cf36 3176 default:
015dc7e1 3177 unknown = true;
d507cf36
PB
3178 break;
3179 }
3180 }
3181 break;
3182
f3485b74 3183 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3184 strcat (buf, ", GNU EABI");
f3485b74
NC
3185 while (e_flags)
3186 {
3187 unsigned flag;
76da6bbe 3188
f3485b74
NC
3189 /* Process flags one bit at a time. */
3190 flag = e_flags & - e_flags;
3191 e_flags &= ~ flag;
76da6bbe 3192
f3485b74
NC
3193 switch (flag)
3194 {
a5bcd848 3195 case EF_ARM_INTERWORK:
f3485b74
NC
3196 strcat (buf, ", interworking enabled");
3197 break;
76da6bbe 3198
a5bcd848 3199 case EF_ARM_APCS_26:
f3485b74
NC
3200 strcat (buf, ", uses APCS/26");
3201 break;
76da6bbe 3202
a5bcd848 3203 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3204 strcat (buf, ", uses APCS/float");
3205 break;
76da6bbe 3206
a5bcd848 3207 case EF_ARM_PIC:
f3485b74
NC
3208 strcat (buf, ", position independent");
3209 break;
76da6bbe 3210
a5bcd848 3211 case EF_ARM_ALIGN8:
f3485b74
NC
3212 strcat (buf, ", 8 bit structure alignment");
3213 break;
76da6bbe 3214
a5bcd848 3215 case EF_ARM_NEW_ABI:
f3485b74
NC
3216 strcat (buf, ", uses new ABI");
3217 break;
76da6bbe 3218
a5bcd848 3219 case EF_ARM_OLD_ABI:
f3485b74
NC
3220 strcat (buf, ", uses old ABI");
3221 break;
76da6bbe 3222
a5bcd848 3223 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3224 strcat (buf, ", software FP");
3225 break;
76da6bbe 3226
90e01f86
ILT
3227 case EF_ARM_VFP_FLOAT:
3228 strcat (buf, ", VFP");
3229 break;
3230
fde78edd
NC
3231 case EF_ARM_MAVERICK_FLOAT:
3232 strcat (buf, ", Maverick FP");
3233 break;
3234
f3485b74 3235 default:
015dc7e1 3236 unknown = true;
f3485b74
NC
3237 break;
3238 }
3239 }
3240 }
f3485b74
NC
3241
3242 if (unknown)
2b692964 3243 strcat (buf,_(", <unknown>"));
f3485b74
NC
3244}
3245
343433df
AB
3246static void
3247decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3248{
3249 --size; /* Leave space for null terminator. */
3250
3251 switch (e_flags & EF_AVR_MACH)
3252 {
3253 case E_AVR_MACH_AVR1:
3254 strncat (buf, ", avr:1", size);
3255 break;
3256 case E_AVR_MACH_AVR2:
3257 strncat (buf, ", avr:2", size);
3258 break;
3259 case E_AVR_MACH_AVR25:
3260 strncat (buf, ", avr:25", size);
3261 break;
3262 case E_AVR_MACH_AVR3:
3263 strncat (buf, ", avr:3", size);
3264 break;
3265 case E_AVR_MACH_AVR31:
3266 strncat (buf, ", avr:31", size);
3267 break;
3268 case E_AVR_MACH_AVR35:
3269 strncat (buf, ", avr:35", size);
3270 break;
3271 case E_AVR_MACH_AVR4:
3272 strncat (buf, ", avr:4", size);
3273 break;
3274 case E_AVR_MACH_AVR5:
3275 strncat (buf, ", avr:5", size);
3276 break;
3277 case E_AVR_MACH_AVR51:
3278 strncat (buf, ", avr:51", size);
3279 break;
3280 case E_AVR_MACH_AVR6:
3281 strncat (buf, ", avr:6", size);
3282 break;
3283 case E_AVR_MACH_AVRTINY:
3284 strncat (buf, ", avr:100", size);
3285 break;
3286 case E_AVR_MACH_XMEGA1:
3287 strncat (buf, ", avr:101", size);
3288 break;
3289 case E_AVR_MACH_XMEGA2:
3290 strncat (buf, ", avr:102", size);
3291 break;
3292 case E_AVR_MACH_XMEGA3:
3293 strncat (buf, ", avr:103", size);
3294 break;
3295 case E_AVR_MACH_XMEGA4:
3296 strncat (buf, ", avr:104", size);
3297 break;
3298 case E_AVR_MACH_XMEGA5:
3299 strncat (buf, ", avr:105", size);
3300 break;
3301 case E_AVR_MACH_XMEGA6:
3302 strncat (buf, ", avr:106", size);
3303 break;
3304 case E_AVR_MACH_XMEGA7:
3305 strncat (buf, ", avr:107", size);
3306 break;
3307 default:
3308 strncat (buf, ", avr:<unknown>", size);
3309 break;
3310 }
3311
3312 size -= strlen (buf);
3313 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3314 strncat (buf, ", link-relax", size);
3315}
3316
35c08157
KLC
3317static void
3318decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3319{
3320 unsigned abi;
3321 unsigned arch;
3322 unsigned config;
3323 unsigned version;
015dc7e1 3324 bool has_fpu = false;
32ec8896 3325 unsigned int r = 0;
35c08157
KLC
3326
3327 static const char *ABI_STRINGS[] =
3328 {
3329 "ABI v0", /* use r5 as return register; only used in N1213HC */
3330 "ABI v1", /* use r0 as return register */
3331 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3332 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3333 "AABI",
3334 "ABI2 FP+"
35c08157
KLC
3335 };
3336 static const char *VER_STRINGS[] =
3337 {
3338 "Andes ELF V1.3 or older",
3339 "Andes ELF V1.3.1",
3340 "Andes ELF V1.4"
3341 };
3342 static const char *ARCH_STRINGS[] =
3343 {
3344 "",
3345 "Andes Star v1.0",
3346 "Andes Star v2.0",
3347 "Andes Star v3.0",
3348 "Andes Star v3.0m"
3349 };
3350
3351 abi = EF_NDS_ABI & e_flags;
3352 arch = EF_NDS_ARCH & e_flags;
3353 config = EF_NDS_INST & e_flags;
3354 version = EF_NDS32_ELF_VERSION & e_flags;
3355
3356 memset (buf, 0, size);
3357
3358 switch (abi)
3359 {
3360 case E_NDS_ABI_V0:
3361 case E_NDS_ABI_V1:
3362 case E_NDS_ABI_V2:
3363 case E_NDS_ABI_V2FP:
3364 case E_NDS_ABI_AABI:
40c7a7cb 3365 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3366 /* In case there are holes in the array. */
3367 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3368 break;
3369
3370 default:
3371 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3372 break;
3373 }
3374
3375 switch (version)
3376 {
3377 case E_NDS32_ELF_VER_1_2:
3378 case E_NDS32_ELF_VER_1_3:
3379 case E_NDS32_ELF_VER_1_4:
3380 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3381 break;
3382
3383 default:
3384 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3385 break;
3386 }
3387
3388 if (E_NDS_ABI_V0 == abi)
3389 {
3390 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3391 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3392 if (arch == E_NDS_ARCH_STAR_V1_0)
3393 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3394 return;
3395 }
3396
3397 switch (arch)
3398 {
3399 case E_NDS_ARCH_STAR_V1_0:
3400 case E_NDS_ARCH_STAR_V2_0:
3401 case E_NDS_ARCH_STAR_V3_0:
3402 case E_NDS_ARCH_STAR_V3_M:
3403 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3404 break;
3405
3406 default:
3407 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3408 /* ARCH version determines how the e_flags are interpreted.
3409 If it is unknown, we cannot proceed. */
3410 return;
3411 }
3412
3413 /* Newer ABI; Now handle architecture specific flags. */
3414 if (arch == E_NDS_ARCH_STAR_V1_0)
3415 {
3416 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3417 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3418
3419 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3420 r += snprintf (buf + r, size -r, ", MAC");
3421
3422 if (config & E_NDS32_HAS_DIV_INST)
3423 r += snprintf (buf + r, size -r, ", DIV");
3424
3425 if (config & E_NDS32_HAS_16BIT_INST)
3426 r += snprintf (buf + r, size -r, ", 16b");
3427 }
3428 else
3429 {
3430 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3431 {
3432 if (version <= E_NDS32_ELF_VER_1_3)
3433 r += snprintf (buf + r, size -r, ", [B8]");
3434 else
3435 r += snprintf (buf + r, size -r, ", EX9");
3436 }
3437
3438 if (config & E_NDS32_HAS_MAC_DX_INST)
3439 r += snprintf (buf + r, size -r, ", MAC_DX");
3440
3441 if (config & E_NDS32_HAS_DIV_DX_INST)
3442 r += snprintf (buf + r, size -r, ", DIV_DX");
3443
3444 if (config & E_NDS32_HAS_16BIT_INST)
3445 {
3446 if (version <= E_NDS32_ELF_VER_1_3)
3447 r += snprintf (buf + r, size -r, ", 16b");
3448 else
3449 r += snprintf (buf + r, size -r, ", IFC");
3450 }
3451 }
3452
3453 if (config & E_NDS32_HAS_EXT_INST)
3454 r += snprintf (buf + r, size -r, ", PERF1");
3455
3456 if (config & E_NDS32_HAS_EXT2_INST)
3457 r += snprintf (buf + r, size -r, ", PERF2");
3458
3459 if (config & E_NDS32_HAS_FPU_INST)
3460 {
015dc7e1 3461 has_fpu = true;
35c08157
KLC
3462 r += snprintf (buf + r, size -r, ", FPU_SP");
3463 }
3464
3465 if (config & E_NDS32_HAS_FPU_DP_INST)
3466 {
015dc7e1 3467 has_fpu = true;
35c08157
KLC
3468 r += snprintf (buf + r, size -r, ", FPU_DP");
3469 }
3470
3471 if (config & E_NDS32_HAS_FPU_MAC_INST)
3472 {
015dc7e1 3473 has_fpu = true;
35c08157
KLC
3474 r += snprintf (buf + r, size -r, ", FPU_MAC");
3475 }
3476
3477 if (has_fpu)
3478 {
3479 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3480 {
3481 case E_NDS32_FPU_REG_8SP_4DP:
3482 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3483 break;
3484 case E_NDS32_FPU_REG_16SP_8DP:
3485 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3486 break;
3487 case E_NDS32_FPU_REG_32SP_16DP:
3488 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3489 break;
3490 case E_NDS32_FPU_REG_32SP_32DP:
3491 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3492 break;
3493 }
3494 }
3495
3496 if (config & E_NDS32_HAS_AUDIO_INST)
3497 r += snprintf (buf + r, size -r, ", AUDIO");
3498
3499 if (config & E_NDS32_HAS_STRING_INST)
3500 r += snprintf (buf + r, size -r, ", STR");
3501
3502 if (config & E_NDS32_HAS_REDUCED_REGS)
3503 r += snprintf (buf + r, size -r, ", 16REG");
3504
3505 if (config & E_NDS32_HAS_VIDEO_INST)
3506 {
3507 if (version <= E_NDS32_ELF_VER_1_3)
3508 r += snprintf (buf + r, size -r, ", VIDEO");
3509 else
3510 r += snprintf (buf + r, size -r, ", SATURATION");
3511 }
3512
3513 if (config & E_NDS32_HAS_ENCRIPT_INST)
3514 r += snprintf (buf + r, size -r, ", ENCRP");
3515
3516 if (config & E_NDS32_HAS_L2C_INST)
3517 r += snprintf (buf + r, size -r, ", L2C");
3518}
3519
c077c580
SM
3520static void
3521decode_AMDGPU_machine_flags (Filedata *filedata, unsigned int e_flags,
3522 char *buf)
3523{
3524 unsigned char *e_ident = filedata->file_header.e_ident;
3525 unsigned char osabi = e_ident[EI_OSABI];
3526 unsigned char abiversion = e_ident[EI_ABIVERSION];
3527 unsigned int mach;
3528
3529 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
3530 it has been deprecated for a while.
3531
3532 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
3533 of writing, they use the same flags as HSA v3, so the code below uses that
3534 assumption. */
3535 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
3536 return;
3537
3538 mach = e_flags & EF_AMDGPU_MACH;
3539 switch (mach)
3540 {
3541#define AMDGPU_CASE(code, string) \
3542 case code: strcat (buf, ", " string); break;
3543 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
3544 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
3545 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
3546 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
3547 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
3548 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
3549 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
3550 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
3551 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
3552 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
3553 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
3554 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
3555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
3556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
3557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
3558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
3559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
3560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
3561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
3562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
3563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
3564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
3565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
3566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
3567 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
3568 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
3569 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
3570 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
3571 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
3572 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
3573 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
3574 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
3575 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
3576 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
3577 default:
3578 sprintf (buf, _(", <unknown AMDGPU GPU type: %#x>"), mach);
3579 break;
3580#undef AMDGPU_CASE
3581 }
3582
3583 buf += strlen (buf);
3584 e_flags &= ~EF_AMDGPU_MACH;
3585
3586 if ((osabi == ELFOSABI_AMDGPU_HSA
3587 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
3588 || osabi != ELFOSABI_AMDGPU_HSA)
3589 {
3590 /* For HSA v3 and other OS ABIs. */
3591 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
3592 {
3593 strcat (buf, ", xnack on");
3594 buf += strlen (buf);
3595 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
3596 }
3597
3598 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
3599 {
3600 strcat (buf, ", sramecc on");
3601 buf += strlen (buf);
3602 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
3603 }
3604 }
3605 else
3606 {
3607 /* For HSA v4+. */
3608 int xnack, sramecc;
3609
3610 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
3611 switch (xnack)
3612 {
3613 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
3614 break;
3615
3616 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
3617 strcat (buf, ", xnack any");
3618 break;
3619
3620 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
3621 strcat (buf, ", xnack off");
3622 break;
3623
3624 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
3625 strcat (buf, ", xnack on");
3626 break;
3627
3628 default:
3629 sprintf (buf, _(", <unknown xnack value: %#x>"), xnack);
3630 break;
3631 }
3632
3633 buf += strlen (buf);
3634 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
3635
3636 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
3637 switch (sramecc)
3638 {
3639 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
3640 break;
3641
3642 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
3643 strcat (buf, ", sramecc any");
3644 break;
3645
3646 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
3647 strcat (buf, ", sramecc off");
3648 break;
3649
3650 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
3651 strcat (buf, ", sramecc on");
3652 break;
3653
3654 default:
3655 sprintf (buf, _(", <unknown sramecc value: %#x>"), sramecc);
3656 break;
3657 }
3658
3659 buf += strlen (buf);
3660 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
3661 }
3662
3663 if (e_flags != 0)
3664 sprintf (buf, _(", unknown flags bits: %#x"), e_flags);
3665}
3666
252b5132 3667static char *
dda8d76d 3668get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3669{
b34976b6 3670 static char buf[1024];
252b5132
RH
3671
3672 buf[0] = '\0';
76da6bbe 3673
252b5132
RH
3674 if (e_flags)
3675 {
3676 switch (e_machine)
3677 {
3678 default:
3679 break;
3680
886a2506 3681 case EM_ARC_COMPACT2:
886a2506 3682 case EM_ARC_COMPACT:
a9522a21
AB
3683 decode_ARC_machine_flags (e_flags, e_machine, buf);
3684 break;
886a2506 3685
f3485b74
NC
3686 case EM_ARM:
3687 decode_ARM_machine_flags (e_flags, buf);
3688 break;
76da6bbe 3689
343433df
AB
3690 case EM_AVR:
3691 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3692 break;
3693
781303ce
MF
3694 case EM_BLACKFIN:
3695 if (e_flags & EF_BFIN_PIC)
3696 strcat (buf, ", PIC");
3697
3698 if (e_flags & EF_BFIN_FDPIC)
3699 strcat (buf, ", FDPIC");
3700
3701 if (e_flags & EF_BFIN_CODE_IN_L1)
3702 strcat (buf, ", code in L1");
3703
3704 if (e_flags & EF_BFIN_DATA_IN_L1)
3705 strcat (buf, ", data in L1");
3706
3707 break;
3708
ec2dfb42
AO
3709 case EM_CYGNUS_FRV:
3710 switch (e_flags & EF_FRV_CPU_MASK)
3711 {
3712 case EF_FRV_CPU_GENERIC:
3713 break;
3714
3715 default:
3716 strcat (buf, ", fr???");
3717 break;
57346661 3718
ec2dfb42
AO
3719 case EF_FRV_CPU_FR300:
3720 strcat (buf, ", fr300");
3721 break;
3722
3723 case EF_FRV_CPU_FR400:
3724 strcat (buf, ", fr400");
3725 break;
3726 case EF_FRV_CPU_FR405:
3727 strcat (buf, ", fr405");
3728 break;
3729
3730 case EF_FRV_CPU_FR450:
3731 strcat (buf, ", fr450");
3732 break;
3733
3734 case EF_FRV_CPU_FR500:
3735 strcat (buf, ", fr500");
3736 break;
3737 case EF_FRV_CPU_FR550:
3738 strcat (buf, ", fr550");
3739 break;
3740
3741 case EF_FRV_CPU_SIMPLE:
3742 strcat (buf, ", simple");
3743 break;
3744 case EF_FRV_CPU_TOMCAT:
3745 strcat (buf, ", tomcat");
3746 break;
3747 }
1c877e87 3748 break;
ec2dfb42 3749
53c7db4b 3750 case EM_68K:
425c6cb0 3751 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3752 strcat (buf, ", m68000");
425c6cb0 3753 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3754 strcat (buf, ", cpu32");
3755 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3756 strcat (buf, ", fido_a");
425c6cb0 3757 else
266abb8f 3758 {
2cf0635d
NC
3759 char const * isa = _("unknown");
3760 char const * mac = _("unknown mac");
3761 char const * additional = NULL;
0112cd26 3762
c694fd50 3763 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3764 {
c694fd50 3765 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3766 isa = "A";
3767 additional = ", nodiv";
3768 break;
c694fd50 3769 case EF_M68K_CF_ISA_A:
266abb8f
NS
3770 isa = "A";
3771 break;
c694fd50 3772 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3773 isa = "A+";
3774 break;
c694fd50 3775 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3776 isa = "B";
3777 additional = ", nousp";
3778 break;
c694fd50 3779 case EF_M68K_CF_ISA_B:
266abb8f
NS
3780 isa = "B";
3781 break;
f608cd77
NS
3782 case EF_M68K_CF_ISA_C:
3783 isa = "C";
3784 break;
3785 case EF_M68K_CF_ISA_C_NODIV:
3786 isa = "C";
3787 additional = ", nodiv";
3788 break;
266abb8f
NS
3789 }
3790 strcat (buf, ", cf, isa ");
3791 strcat (buf, isa);
0b2e31dc
NS
3792 if (additional)
3793 strcat (buf, additional);
c694fd50 3794 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3795 strcat (buf, ", float");
c694fd50 3796 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3797 {
3798 case 0:
3799 mac = NULL;
3800 break;
c694fd50 3801 case EF_M68K_CF_MAC:
266abb8f
NS
3802 mac = "mac";
3803 break;
c694fd50 3804 case EF_M68K_CF_EMAC:
266abb8f
NS
3805 mac = "emac";
3806 break;
f608cd77
NS
3807 case EF_M68K_CF_EMAC_B:
3808 mac = "emac_b";
3809 break;
266abb8f
NS
3810 }
3811 if (mac)
3812 {
3813 strcat (buf, ", ");
3814 strcat (buf, mac);
3815 }
266abb8f 3816 }
53c7db4b 3817 break;
33c63f9d 3818
c077c580
SM
3819 case EM_AMDGPU:
3820 decode_AMDGPU_machine_flags (filedata, e_flags, buf);
3821 break;
3822
153a2776
NC
3823 case EM_CYGNUS_MEP:
3824 switch (e_flags & EF_MEP_CPU_MASK)
3825 {
3826 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3827 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3828 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3829 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3830 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3831 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3832 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3833 }
3834
3835 switch (e_flags & EF_MEP_COP_MASK)
3836 {
3837 case EF_MEP_COP_NONE: break;
3838 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3839 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3840 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3841 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3842 default: strcat (buf, _("<unknown MeP copro type>")); break;
3843 }
3844
3845 if (e_flags & EF_MEP_LIBRARY)
3846 strcat (buf, ", Built for Library");
3847
3848 if (e_flags & EF_MEP_INDEX_MASK)
3849 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3850 e_flags & EF_MEP_INDEX_MASK);
3851
3852 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3853 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3854 e_flags & ~ EF_MEP_ALL_FLAGS);
3855 break;
3856
252b5132
RH
3857 case EM_PPC:
3858 if (e_flags & EF_PPC_EMB)
3859 strcat (buf, ", emb");
3860
3861 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3862 strcat (buf, _(", relocatable"));
252b5132
RH
3863
3864 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3865 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3866 break;
3867
ee67d69a
AM
3868 case EM_PPC64:
3869 if (e_flags & EF_PPC64_ABI)
3870 {
3871 char abi[] = ", abiv0";
3872
3873 abi[6] += e_flags & EF_PPC64_ABI;
3874 strcat (buf, abi);
3875 }
3876 break;
3877
708e2187
NC
3878 case EM_V800:
3879 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3880 strcat (buf, ", RH850 ABI");
0b4362b0 3881
708e2187
NC
3882 if (e_flags & EF_V800_850E3)
3883 strcat (buf, ", V3 architecture");
3884
3885 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3886 strcat (buf, ", FPU not used");
3887
3888 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3889 strcat (buf, ", regmode: COMMON");
3890
3891 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3892 strcat (buf, ", r4 not used");
3893
3894 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3895 strcat (buf, ", r30 not used");
3896
3897 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3898 strcat (buf, ", r5 not used");
3899
3900 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3901 strcat (buf, ", r2 not used");
3902
3903 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3904 {
3905 switch (e_flags & - e_flags)
3906 {
3907 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3908 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3909 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3910 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3911 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3912 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3913 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3914 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3915 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3916 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3917 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3918 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3919 default: break;
3920 }
3921 }
3922 break;
3923
2b0337b0 3924 case EM_V850:
252b5132
RH
3925 case EM_CYGNUS_V850:
3926 switch (e_flags & EF_V850_ARCH)
3927 {
78c8d46c
NC
3928 case E_V850E3V5_ARCH:
3929 strcat (buf, ", v850e3v5");
3930 break;
1cd986c5
NC
3931 case E_V850E2V3_ARCH:
3932 strcat (buf, ", v850e2v3");
3933 break;
3934 case E_V850E2_ARCH:
3935 strcat (buf, ", v850e2");
3936 break;
3937 case E_V850E1_ARCH:
3938 strcat (buf, ", v850e1");
8ad30312 3939 break;
252b5132
RH
3940 case E_V850E_ARCH:
3941 strcat (buf, ", v850e");
3942 break;
252b5132
RH
3943 case E_V850_ARCH:
3944 strcat (buf, ", v850");
3945 break;
3946 default:
2b692964 3947 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3948 break;
3949 }
3950 break;
3951
2b0337b0 3952 case EM_M32R:
252b5132
RH
3953 case EM_CYGNUS_M32R:
3954 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3955 strcat (buf, ", m32r");
252b5132
RH
3956 break;
3957
3958 case EM_MIPS:
4fe85591 3959 case EM_MIPS_RS3_LE:
252b5132
RH
3960 if (e_flags & EF_MIPS_NOREORDER)
3961 strcat (buf, ", noreorder");
3962
3963 if (e_flags & EF_MIPS_PIC)
3964 strcat (buf, ", pic");
3965
3966 if (e_flags & EF_MIPS_CPIC)
3967 strcat (buf, ", cpic");
3968
d1bdd336
TS
3969 if (e_flags & EF_MIPS_UCODE)
3970 strcat (buf, ", ugen_reserved");
3971
252b5132
RH
3972 if (e_flags & EF_MIPS_ABI2)
3973 strcat (buf, ", abi2");
3974
43521d43
TS
3975 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3976 strcat (buf, ", odk first");
3977
a5d22d2a
TS
3978 if (e_flags & EF_MIPS_32BITMODE)
3979 strcat (buf, ", 32bitmode");
3980
ba92f887
MR
3981 if (e_flags & EF_MIPS_NAN2008)
3982 strcat (buf, ", nan2008");
3983
fef1b0b3
SE
3984 if (e_flags & EF_MIPS_FP64)
3985 strcat (buf, ", fp64");
3986
156c2f8b
NC
3987 switch ((e_flags & EF_MIPS_MACH))
3988 {
3989 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3990 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3991 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3992 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3993 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3994 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3995 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3996 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3997 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3998 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3999 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
4000 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
4001 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 4002 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 4003 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 4004 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 4005 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 4006 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 4007 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 4008 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 4009 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
4010 case 0:
4011 /* We simply ignore the field in this case to avoid confusion:
4012 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4013 extension. */
4014 break;
2b692964 4015 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 4016 }
43521d43
TS
4017
4018 switch ((e_flags & EF_MIPS_ABI))
4019 {
4020 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
4021 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
4022 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
4023 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
4024 case 0:
4025 /* We simply ignore the field in this case to avoid confusion:
4026 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4027 This means it is likely to be an o32 file, but not for
4028 sure. */
4029 break;
2b692964 4030 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
4031 }
4032
4033 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4034 strcat (buf, ", mdmx");
4035
4036 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4037 strcat (buf, ", mips16");
4038
df58fc94
RS
4039 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4040 strcat (buf, ", micromips");
4041
43521d43
TS
4042 switch ((e_flags & EF_MIPS_ARCH))
4043 {
4044 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
4045 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
4046 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
4047 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
4048 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
4049 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 4050 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 4051 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 4052 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 4053 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 4054 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 4055 default: strcat (buf, _(", unknown ISA")); break;
43521d43 4056 }
252b5132 4057 break;
351b4b40 4058
35c08157
KLC
4059 case EM_NDS32:
4060 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4061 break;
4062
fe944acf
FT
4063 case EM_NFP:
4064 switch (EF_NFP_MACH (e_flags))
4065 {
4066 case E_NFP_MACH_3200:
4067 strcat (buf, ", NFP-32xx");
4068 break;
4069 case E_NFP_MACH_6000:
4070 strcat (buf, ", NFP-6xxx");
4071 break;
4072 }
4073 break;
4074
e23eba97
NC
4075 case EM_RISCV:
4076 if (e_flags & EF_RISCV_RVC)
4077 strcat (buf, ", RVC");
2922d21d 4078
7f999549
JW
4079 if (e_flags & EF_RISCV_RVE)
4080 strcat (buf, ", RVE");
4081
96462b01
S
4082 if (e_flags & EF_RISCV_TSO)
4083 strcat (buf, ", TSO");
4084
2922d21d
AW
4085 switch (e_flags & EF_RISCV_FLOAT_ABI)
4086 {
4087 case EF_RISCV_FLOAT_ABI_SOFT:
4088 strcat (buf, ", soft-float ABI");
4089 break;
4090
4091 case EF_RISCV_FLOAT_ABI_SINGLE:
4092 strcat (buf, ", single-float ABI");
4093 break;
4094
4095 case EF_RISCV_FLOAT_ABI_DOUBLE:
4096 strcat (buf, ", double-float ABI");
4097 break;
4098
4099 case EF_RISCV_FLOAT_ABI_QUAD:
4100 strcat (buf, ", quad-float ABI");
4101 break;
4102 }
e23eba97
NC
4103 break;
4104
ccde1100
AO
4105 case EM_SH:
4106 switch ((e_flags & EF_SH_MACH_MASK))
4107 {
4108 case EF_SH1: strcat (buf, ", sh1"); break;
4109 case EF_SH2: strcat (buf, ", sh2"); break;
4110 case EF_SH3: strcat (buf, ", sh3"); break;
4111 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4112 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4113 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4114 case EF_SH3E: strcat (buf, ", sh3e"); break;
4115 case EF_SH4: strcat (buf, ", sh4"); break;
4116 case EF_SH5: strcat (buf, ", sh5"); break;
4117 case EF_SH2E: strcat (buf, ", sh2e"); break;
4118 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4119 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4120 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4121 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4122 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4123 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4124 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4125 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4126 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4127 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4128 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4129 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4130 }
4131
cec6a5b8
MR
4132 if (e_flags & EF_SH_PIC)
4133 strcat (buf, ", pic");
4134
4135 if (e_flags & EF_SH_FDPIC)
4136 strcat (buf, ", fdpic");
ccde1100 4137 break;
948f632f 4138
73589c9d
CS
4139 case EM_OR1K:
4140 if (e_flags & EF_OR1K_NODELAY)
4141 strcat (buf, ", no delay");
4142 break;
57346661 4143
351b4b40
RH
4144 case EM_SPARCV9:
4145 if (e_flags & EF_SPARC_32PLUS)
4146 strcat (buf, ", v8+");
4147
4148 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4149 strcat (buf, ", ultrasparcI");
4150
4151 if (e_flags & EF_SPARC_SUN_US3)
4152 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4153
4154 if (e_flags & EF_SPARC_HAL_R1)
4155 strcat (buf, ", halr1");
4156
4157 if (e_flags & EF_SPARC_LEDATA)
4158 strcat (buf, ", ledata");
4159
4160 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4161 strcat (buf, ", tso");
4162
4163 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4164 strcat (buf, ", pso");
4165
4166 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4167 strcat (buf, ", rmo");
4168 break;
7d466069 4169
103f02d3
UD
4170 case EM_PARISC:
4171 switch (e_flags & EF_PARISC_ARCH)
4172 {
4173 case EFA_PARISC_1_0:
4174 strcpy (buf, ", PA-RISC 1.0");
4175 break;
4176 case EFA_PARISC_1_1:
4177 strcpy (buf, ", PA-RISC 1.1");
4178 break;
4179 case EFA_PARISC_2_0:
4180 strcpy (buf, ", PA-RISC 2.0");
4181 break;
4182 default:
4183 break;
4184 }
4185 if (e_flags & EF_PARISC_TRAPNIL)
4186 strcat (buf, ", trapnil");
4187 if (e_flags & EF_PARISC_EXT)
4188 strcat (buf, ", ext");
4189 if (e_flags & EF_PARISC_LSB)
4190 strcat (buf, ", lsb");
4191 if (e_flags & EF_PARISC_WIDE)
4192 strcat (buf, ", wide");
4193 if (e_flags & EF_PARISC_NO_KABP)
4194 strcat (buf, ", no kabp");
4195 if (e_flags & EF_PARISC_LAZYSWAP)
4196 strcat (buf, ", lazyswap");
30800947 4197 break;
76da6bbe 4198
7d466069 4199 case EM_PJ:
2b0337b0 4200 case EM_PJ_OLD:
7d466069
ILT
4201 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4202 strcat (buf, ", new calling convention");
4203
4204 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4205 strcat (buf, ", gnu calling convention");
4206 break;
4d6ed7c8
NC
4207
4208 case EM_IA_64:
4209 if ((e_flags & EF_IA_64_ABI64))
4210 strcat (buf, ", 64-bit");
4211 else
4212 strcat (buf, ", 32-bit");
4213 if ((e_flags & EF_IA_64_REDUCEDFP))
4214 strcat (buf, ", reduced fp model");
4215 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4216 strcat (buf, ", no function descriptors, constant gp");
4217 else if ((e_flags & EF_IA_64_CONS_GP))
4218 strcat (buf, ", constant gp");
4219 if ((e_flags & EF_IA_64_ABSOLUTE))
4220 strcat (buf, ", absolute");
dda8d76d 4221 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4222 {
4223 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4224 strcat (buf, ", vms_linkages");
4225 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4226 {
4227 case EF_IA_64_VMS_COMCOD_SUCCESS:
4228 break;
4229 case EF_IA_64_VMS_COMCOD_WARNING:
4230 strcat (buf, ", warning");
4231 break;
4232 case EF_IA_64_VMS_COMCOD_ERROR:
4233 strcat (buf, ", error");
4234 break;
4235 case EF_IA_64_VMS_COMCOD_ABORT:
4236 strcat (buf, ", abort");
4237 break;
4238 default:
bee0ee85
NC
4239 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4240 e_flags & EF_IA_64_VMS_COMCOD);
4241 strcat (buf, ", <unknown>");
28f997cf
TG
4242 }
4243 }
4d6ed7c8 4244 break;
179d3252
JT
4245
4246 case EM_VAX:
4247 if ((e_flags & EF_VAX_NONPIC))
4248 strcat (buf, ", non-PIC");
4249 if ((e_flags & EF_VAX_DFLOAT))
4250 strcat (buf, ", D-Float");
4251 if ((e_flags & EF_VAX_GFLOAT))
4252 strcat (buf, ", G-Float");
4253 break;
c7927a3c 4254
619ed720
EB
4255 case EM_VISIUM:
4256 if (e_flags & EF_VISIUM_ARCH_MCM)
4257 strcat (buf, ", mcm");
4258 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4259 strcat (buf, ", mcm24");
4260 if (e_flags & EF_VISIUM_ARCH_GR6)
4261 strcat (buf, ", gr6");
4262 break;
4263
4046d87a 4264 case EM_RL78:
1740ba0c
NC
4265 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4266 {
4267 case E_FLAG_RL78_ANY_CPU: break;
4268 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4269 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4270 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4271 }
856ea05c
KP
4272 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4273 strcat (buf, ", 64-bit doubles");
4046d87a 4274 break;
0b4362b0 4275
c7927a3c
NC
4276 case EM_RX:
4277 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4278 strcat (buf, ", 64-bit doubles");
4279 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4280 strcat (buf, ", dsp");
d4cb0ea0 4281 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4282 strcat (buf, ", pid");
708e2187
NC
4283 if (e_flags & E_FLAG_RX_ABI)
4284 strcat (buf, ", RX ABI");
3525236c
NC
4285 if (e_flags & E_FLAG_RX_SINSNS_SET)
4286 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4287 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4288 if (e_flags & E_FLAG_RX_V2)
4289 strcat (buf, ", V2");
f87673e0
YS
4290 if (e_flags & E_FLAG_RX_V3)
4291 strcat (buf, ", V3");
d4cb0ea0 4292 break;
55786da2
AK
4293
4294 case EM_S390:
4295 if (e_flags & EF_S390_HIGH_GPRS)
4296 strcat (buf, ", highgprs");
d4cb0ea0 4297 break;
40b36596
JM
4298
4299 case EM_TI_C6000:
4300 if ((e_flags & EF_C6000_REL))
4301 strcat (buf, ", relocatable module");
d4cb0ea0 4302 break;
13761a11
NC
4303
4304 case EM_MSP430:
4305 strcat (buf, _(": architecture variant: "));
4306 switch (e_flags & EF_MSP430_MACH)
4307 {
4308 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4309 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4310 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4311 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4312 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4313 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4314 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4315 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4316 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4317 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4318 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4319 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4320 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4321 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4322 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4323 default:
4324 strcat (buf, _(": unknown")); break;
4325 }
4326
4327 if (e_flags & ~ EF_MSP430_MACH)
4328 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4329 break;
4330
4331 case EM_Z80:
4332 switch (e_flags & EF_Z80_MACH_MSK)
4333 {
4334 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4335 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4336 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4337 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4338 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4339 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4340 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4341 default:
4342 strcat (buf, _(", unknown")); break;
4343 }
4344 break;
e9a0721f 4345 case EM_LOONGARCH:
4346 if (EF_LOONGARCH_IS_LP64 (e_flags))
4347 strcat (buf, ", LP64");
4348 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4349 strcat (buf, ", ILP32");
4350
4351 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4352 strcat (buf, ", SOFT-FLOAT");
4353 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4354 strcat (buf, ", SINGLE-FLOAT");
4355 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4356 strcat (buf, ", DOUBLE-FLOAT");
4357
4358 break;
252b5132
RH
4359 }
4360 }
4361
4362 return buf;
4363}
4364
252b5132 4365static const char *
dda8d76d 4366get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4367{
4368 static char buff[32];
4369
4370 switch (osabi)
4371 {
4372 case ELFOSABI_NONE: return "UNIX - System V";
4373 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4374 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4375 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4376 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4377 case ELFOSABI_AIX: return "UNIX - AIX";
4378 case ELFOSABI_IRIX: return "UNIX - IRIX";
4379 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4380 case ELFOSABI_TRU64: return "UNIX - TRU64";
4381 case ELFOSABI_MODESTO: return "Novell - Modesto";
4382 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4383 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4384 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4385 case ELFOSABI_AROS: return "AROS";
11636f9e 4386 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4387 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4388 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4389 default:
40b36596 4390 if (osabi >= 64)
dda8d76d 4391 switch (filedata->file_header.e_machine)
40b36596 4392 {
37870be8
SM
4393 case EM_AMDGPU:
4394 switch (osabi)
4395 {
4396 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4397 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4398 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4399 default:
4400 break;
4401 }
4402 break;
4403
40b36596
JM
4404 case EM_ARM:
4405 switch (osabi)
4406 {
4407 case ELFOSABI_ARM: return "ARM";
18a20338 4408 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4409 default:
4410 break;
4411 }
4412 break;
4413
4414 case EM_MSP430:
4415 case EM_MSP430_OLD:
619ed720 4416 case EM_VISIUM:
40b36596
JM
4417 switch (osabi)
4418 {
4419 case ELFOSABI_STANDALONE: return _("Standalone App");
4420 default:
4421 break;
4422 }
4423 break;
4424
4425 case EM_TI_C6000:
4426 switch (osabi)
4427 {
4428 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4429 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4430 default:
4431 break;
4432 }
4433 break;
4434
4435 default:
4436 break;
4437 }
e9e44622 4438 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4439 return buff;
4440 }
4441}
4442
a06ea964
NC
4443static const char *
4444get_aarch64_segment_type (unsigned long type)
4445{
4446 switch (type)
4447 {
32ec8896 4448 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4449 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4450 default: return NULL;
a06ea964 4451 }
a06ea964
NC
4452}
4453
b294bdf8
MM
4454static const char *
4455get_arm_segment_type (unsigned long type)
4456{
4457 switch (type)
4458 {
32ec8896
NC
4459 case PT_ARM_EXIDX: return "EXIDX";
4460 default: return NULL;
b294bdf8 4461 }
b294bdf8
MM
4462}
4463
b4cbbe8f
AK
4464static const char *
4465get_s390_segment_type (unsigned long type)
4466{
4467 switch (type)
4468 {
4469 case PT_S390_PGSTE: return "S390_PGSTE";
4470 default: return NULL;
4471 }
4472}
4473
d3ba0551
AM
4474static const char *
4475get_mips_segment_type (unsigned long type)
252b5132
RH
4476{
4477 switch (type)
4478 {
32ec8896
NC
4479 case PT_MIPS_REGINFO: return "REGINFO";
4480 case PT_MIPS_RTPROC: return "RTPROC";
4481 case PT_MIPS_OPTIONS: return "OPTIONS";
4482 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4483 default: return NULL;
252b5132 4484 }
252b5132
RH
4485}
4486
103f02d3 4487static const char *
d3ba0551 4488get_parisc_segment_type (unsigned long type)
103f02d3
UD
4489{
4490 switch (type)
4491 {
103f02d3
UD
4492 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4493 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4494 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4495 default: return NULL;
103f02d3 4496 }
103f02d3
UD
4497}
4498
4d6ed7c8 4499static const char *
d3ba0551 4500get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4501{
4502 switch (type)
4503 {
4504 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4505 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4506 default: return NULL;
4d6ed7c8 4507 }
4d6ed7c8
NC
4508}
4509
40b36596
JM
4510static const char *
4511get_tic6x_segment_type (unsigned long type)
4512{
4513 switch (type)
4514 {
32ec8896
NC
4515 case PT_C6000_PHATTR: return "C6000_PHATTR";
4516 default: return NULL;
40b36596 4517 }
40b36596
JM
4518}
4519
fbc95f1e
KC
4520static const char *
4521get_riscv_segment_type (unsigned long type)
4522{
4523 switch (type)
4524 {
4525 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4526 default: return NULL;
4527 }
4528}
4529
df3a023b
AM
4530static const char *
4531get_hpux_segment_type (unsigned long type, unsigned e_machine)
4532{
4533 if (e_machine == EM_PARISC)
4534 switch (type)
4535 {
4536 case PT_HP_TLS: return "HP_TLS";
4537 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4538 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4539 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4540 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4541 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4542 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4543 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4544 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4545 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4546 case PT_HP_PARALLEL: return "HP_PARALLEL";
4547 case PT_HP_FASTBIND: return "HP_FASTBIND";
4548 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4549 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4550 case PT_HP_STACK: return "HP_STACK";
4551 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4552 default: return NULL;
4553 }
4554
4555 if (e_machine == EM_IA_64)
4556 switch (type)
4557 {
4558 case PT_HP_TLS: return "HP_TLS";
4559 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4560 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4561 case PT_IA_64_HP_STACK: return "HP_STACK";
4562 default: return NULL;
4563 }
4564
4565 return NULL;
4566}
4567
5522f910
NC
4568static const char *
4569get_solaris_segment_type (unsigned long type)
4570{
4571 switch (type)
4572 {
4573 case 0x6464e550: return "PT_SUNW_UNWIND";
4574 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4575 case 0x6ffffff7: return "PT_LOSUNW";
4576 case 0x6ffffffa: return "PT_SUNWBSS";
4577 case 0x6ffffffb: return "PT_SUNWSTACK";
4578 case 0x6ffffffc: return "PT_SUNWDTRACE";
4579 case 0x6ffffffd: return "PT_SUNWCAP";
4580 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4581 default: return NULL;
5522f910
NC
4582 }
4583}
4584
252b5132 4585static const char *
dda8d76d 4586get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4587{
b34976b6 4588 static char buff[32];
252b5132
RH
4589
4590 switch (p_type)
4591 {
b34976b6
AM
4592 case PT_NULL: return "NULL";
4593 case PT_LOAD: return "LOAD";
252b5132 4594 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4595 case PT_INTERP: return "INTERP";
4596 case PT_NOTE: return "NOTE";
4597 case PT_SHLIB: return "SHLIB";
4598 case PT_PHDR: return "PHDR";
13ae64f3 4599 case PT_TLS: return "TLS";
32ec8896 4600 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4601 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4602 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4603 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4604
3eba3ef3
NC
4605 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4606 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4607 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4608
252b5132 4609 default:
df3a023b 4610 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4611 {
2cf0635d 4612 const char * result;
103f02d3 4613
dda8d76d 4614 switch (filedata->file_header.e_machine)
252b5132 4615 {
a06ea964
NC
4616 case EM_AARCH64:
4617 result = get_aarch64_segment_type (p_type);
4618 break;
b294bdf8
MM
4619 case EM_ARM:
4620 result = get_arm_segment_type (p_type);
4621 break;
252b5132 4622 case EM_MIPS:
4fe85591 4623 case EM_MIPS_RS3_LE:
252b5132
RH
4624 result = get_mips_segment_type (p_type);
4625 break;
103f02d3
UD
4626 case EM_PARISC:
4627 result = get_parisc_segment_type (p_type);
4628 break;
4d6ed7c8
NC
4629 case EM_IA_64:
4630 result = get_ia64_segment_type (p_type);
4631 break;
40b36596
JM
4632 case EM_TI_C6000:
4633 result = get_tic6x_segment_type (p_type);
4634 break;
b4cbbe8f
AK
4635 case EM_S390:
4636 case EM_S390_OLD:
4637 result = get_s390_segment_type (p_type);
4638 break;
fbc95f1e
KC
4639 case EM_RISCV:
4640 result = get_riscv_segment_type (p_type);
4641 break;
252b5132
RH
4642 default:
4643 result = NULL;
4644 break;
4645 }
103f02d3 4646
252b5132
RH
4647 if (result != NULL)
4648 return result;
103f02d3 4649
1a9ccd70 4650 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4651 }
4652 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4653 {
df3a023b 4654 const char * result = NULL;
103f02d3 4655
df3a023b 4656 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4657 {
df3a023b
AM
4658 case ELFOSABI_GNU:
4659 case ELFOSABI_FREEBSD:
4660 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4661 {
4662 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4663 result = buff;
4664 }
103f02d3 4665 break;
df3a023b
AM
4666 case ELFOSABI_HPUX:
4667 result = get_hpux_segment_type (p_type,
4668 filedata->file_header.e_machine);
4669 break;
4670 case ELFOSABI_SOLARIS:
4671 result = get_solaris_segment_type (p_type);
00428cca 4672 break;
103f02d3 4673 default:
103f02d3
UD
4674 break;
4675 }
103f02d3
UD
4676 if (result != NULL)
4677 return result;
4678
1a9ccd70 4679 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4680 }
252b5132 4681 else
e9e44622 4682 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4683
4684 return buff;
4685 }
4686}
4687
53a346d8
CZ
4688static const char *
4689get_arc_section_type_name (unsigned int sh_type)
4690{
4691 switch (sh_type)
4692 {
4693 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4694 default:
4695 break;
4696 }
4697 return NULL;
4698}
4699
252b5132 4700static const char *
d3ba0551 4701get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4702{
4703 switch (sh_type)
4704 {
b34976b6
AM
4705 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4706 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4707 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4708 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4709 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4710 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4711 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4712 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4713 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4714 case SHT_MIPS_RELD: return "MIPS_RELD";
4715 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4716 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4717 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4718 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4719 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4720 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4721 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4722 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4723 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4724 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4725 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4726 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4727 case SHT_MIPS_LINE: return "MIPS_LINE";
4728 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4729 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4730 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4731 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4732 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4733 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4734 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4735 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4736 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4737 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4738 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4739 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4740 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4741 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4742 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4743 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4744 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4745 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4746 default:
4747 break;
4748 }
4749 return NULL;
4750}
4751
103f02d3 4752static const char *
d3ba0551 4753get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4754{
4755 switch (sh_type)
4756 {
4757 case SHT_PARISC_EXT: return "PARISC_EXT";
4758 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4759 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4760 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4761 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4762 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4763 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4764 default: return NULL;
103f02d3 4765 }
103f02d3
UD
4766}
4767
4d6ed7c8 4768static const char *
dda8d76d 4769get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4770{
18bd398b 4771 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4772 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4773 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4774
4d6ed7c8
NC
4775 switch (sh_type)
4776 {
148b93f2
NC
4777 case SHT_IA_64_EXT: return "IA_64_EXT";
4778 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4779 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4780 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4781 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4782 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4783 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4784 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4785 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4786 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4787 default:
4788 break;
4789 }
4790 return NULL;
4791}
4792
d2b2c203
DJ
4793static const char *
4794get_x86_64_section_type_name (unsigned int sh_type)
4795{
4796 switch (sh_type)
4797 {
4798 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4799 default: return NULL;
d2b2c203 4800 }
d2b2c203
DJ
4801}
4802
a06ea964
NC
4803static const char *
4804get_aarch64_section_type_name (unsigned int sh_type)
4805{
4806 switch (sh_type)
4807 {
32ec8896
NC
4808 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4809 default: return NULL;
a06ea964 4810 }
a06ea964
NC
4811}
4812
40a18ebd
NC
4813static const char *
4814get_arm_section_type_name (unsigned int sh_type)
4815{
4816 switch (sh_type)
4817 {
7f6fed87
NC
4818 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4819 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4820 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4821 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4822 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4823 default: return NULL;
40a18ebd 4824 }
40a18ebd
NC
4825}
4826
40b36596
JM
4827static const char *
4828get_tic6x_section_type_name (unsigned int sh_type)
4829{
4830 switch (sh_type)
4831 {
32ec8896
NC
4832 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4833 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4834 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4835 case SHT_TI_ICODE: return "TI_ICODE";
4836 case SHT_TI_XREF: return "TI_XREF";
4837 case SHT_TI_HANDLER: return "TI_HANDLER";
4838 case SHT_TI_INITINFO: return "TI_INITINFO";
4839 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4840 default: return NULL;
40b36596 4841 }
40b36596
JM
4842}
4843
13761a11 4844static const char *
b0191216 4845get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4846{
4847 switch (sh_type)
4848 {
32ec8896
NC
4849 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4850 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4851 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4852 default: return NULL;
13761a11
NC
4853 }
4854}
4855
fe944acf
FT
4856static const char *
4857get_nfp_section_type_name (unsigned int sh_type)
4858{
4859 switch (sh_type)
4860 {
4861 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4862 case SHT_NFP_INITREG: return "NFP_INITREG";
4863 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4864 default: return NULL;
4865 }
4866}
4867
685080f2
NC
4868static const char *
4869get_v850_section_type_name (unsigned int sh_type)
4870{
4871 switch (sh_type)
4872 {
32ec8896
NC
4873 case SHT_V850_SCOMMON: return "V850 Small Common";
4874 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4875 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4876 case SHT_RENESAS_IOP: return "RENESAS IOP";
4877 case SHT_RENESAS_INFO: return "RENESAS INFO";
4878 default: return NULL;
685080f2
NC
4879 }
4880}
4881
2dc8dd17
JW
4882static const char *
4883get_riscv_section_type_name (unsigned int sh_type)
4884{
4885 switch (sh_type)
4886 {
4887 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4888 default: return NULL;
4889 }
4890}
4891
0861f561
CQ
4892static const char *
4893get_csky_section_type_name (unsigned int sh_type)
4894{
4895 switch (sh_type)
4896 {
4897 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4898 default: return NULL;
4899 }
4900}
4901
252b5132 4902static const char *
dda8d76d 4903get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4904{
b34976b6 4905 static char buff[32];
9fb71ee4 4906 const char * result;
252b5132
RH
4907
4908 switch (sh_type)
4909 {
4910 case SHT_NULL: return "NULL";
4911 case SHT_PROGBITS: return "PROGBITS";
4912 case SHT_SYMTAB: return "SYMTAB";
4913 case SHT_STRTAB: return "STRTAB";
4914 case SHT_RELA: return "RELA";
dd207c13 4915 case SHT_RELR: return "RELR";
252b5132
RH
4916 case SHT_HASH: return "HASH";
4917 case SHT_DYNAMIC: return "DYNAMIC";
4918 case SHT_NOTE: return "NOTE";
4919 case SHT_NOBITS: return "NOBITS";
4920 case SHT_REL: return "REL";
4921 case SHT_SHLIB: return "SHLIB";
4922 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4923 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4924 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4925 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4926 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4927 case SHT_GROUP: return "GROUP";
67ce483b 4928 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4929 case SHT_GNU_verdef: return "VERDEF";
4930 case SHT_GNU_verneed: return "VERNEED";
4931 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4932 case 0x6ffffff0: return "VERSYM";
4933 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4934 case 0x7ffffffd: return "AUXILIARY";
4935 case 0x7fffffff: return "FILTER";
047b2264 4936 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4937
4938 default:
4939 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4940 {
dda8d76d 4941 switch (filedata->file_header.e_machine)
252b5132 4942 {
53a346d8
CZ
4943 case EM_ARC:
4944 case EM_ARC_COMPACT:
4945 case EM_ARC_COMPACT2:
4946 result = get_arc_section_type_name (sh_type);
4947 break;
252b5132 4948 case EM_MIPS:
4fe85591 4949 case EM_MIPS_RS3_LE:
252b5132
RH
4950 result = get_mips_section_type_name (sh_type);
4951 break;
103f02d3
UD
4952 case EM_PARISC:
4953 result = get_parisc_section_type_name (sh_type);
4954 break;
4d6ed7c8 4955 case EM_IA_64:
dda8d76d 4956 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4957 break;
d2b2c203 4958 case EM_X86_64:
8a9036a4 4959 case EM_L1OM:
7a9068fe 4960 case EM_K1OM:
d2b2c203
DJ
4961 result = get_x86_64_section_type_name (sh_type);
4962 break;
a06ea964
NC
4963 case EM_AARCH64:
4964 result = get_aarch64_section_type_name (sh_type);
4965 break;
40a18ebd
NC
4966 case EM_ARM:
4967 result = get_arm_section_type_name (sh_type);
4968 break;
40b36596
JM
4969 case EM_TI_C6000:
4970 result = get_tic6x_section_type_name (sh_type);
4971 break;
13761a11 4972 case EM_MSP430:
b0191216 4973 result = get_msp430_section_type_name (sh_type);
13761a11 4974 break;
fe944acf
FT
4975 case EM_NFP:
4976 result = get_nfp_section_type_name (sh_type);
4977 break;
685080f2
NC
4978 case EM_V800:
4979 case EM_V850:
4980 case EM_CYGNUS_V850:
4981 result = get_v850_section_type_name (sh_type);
4982 break;
2dc8dd17
JW
4983 case EM_RISCV:
4984 result = get_riscv_section_type_name (sh_type);
4985 break;
0861f561
CQ
4986 case EM_CSKY:
4987 result = get_csky_section_type_name (sh_type);
4988 break;
252b5132
RH
4989 default:
4990 result = NULL;
4991 break;
4992 }
4993
4994 if (result != NULL)
4995 return result;
4996
9fb71ee4 4997 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4998 }
4999 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5000 {
dda8d76d 5001 switch (filedata->file_header.e_machine)
148b93f2
NC
5002 {
5003 case EM_IA_64:
dda8d76d 5004 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5005 break;
5006 default:
dda8d76d 5007 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5008 result = get_solaris_section_type (sh_type);
5009 else
1b4b80bf
NC
5010 {
5011 switch (sh_type)
5012 {
5013 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5014 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5015 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5016 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5017 default:
5018 result = NULL;
5019 break;
5020 }
5021 }
148b93f2
NC
5022 break;
5023 }
5024
5025 if (result != NULL)
5026 return result;
5027
9fb71ee4 5028 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5029 }
252b5132 5030 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5031 {
dda8d76d 5032 switch (filedata->file_header.e_machine)
685080f2
NC
5033 {
5034 case EM_V800:
5035 case EM_V850:
5036 case EM_CYGNUS_V850:
9fb71ee4 5037 result = get_v850_section_type_name (sh_type);
a9fb83be 5038 break;
685080f2 5039 default:
9fb71ee4 5040 result = NULL;
685080f2
NC
5041 break;
5042 }
5043
9fb71ee4
NC
5044 if (result != NULL)
5045 return result;
5046
5047 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5048 }
252b5132 5049 else
a7dbfd1c
NC
5050 /* This message is probably going to be displayed in a 15
5051 character wide field, so put the hex value first. */
5052 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5053
252b5132
RH
5054 return buff;
5055 }
5056}
5057
79bc120c
NC
5058enum long_option_values
5059{
5060 OPTION_DEBUG_DUMP = 512,
5061 OPTION_DYN_SYMS,
0f03783c 5062 OPTION_LTO_SYMS,
79bc120c
NC
5063 OPTION_DWARF_DEPTH,
5064 OPTION_DWARF_START,
5065 OPTION_DWARF_CHECK,
5066 OPTION_CTF_DUMP,
5067 OPTION_CTF_PARENT,
5068 OPTION_CTF_SYMBOLS,
5069 OPTION_CTF_STRINGS,
5070 OPTION_WITH_SYMBOL_VERSIONS,
5071 OPTION_RECURSE_LIMIT,
5072 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5073 OPTION_NO_DEMANGLING,
5074 OPTION_SYM_BASE
79bc120c 5075};
2979dc34 5076
85b1c36d 5077static struct option options[] =
252b5132 5078{
79bc120c
NC
5079 /* Note - This table is alpha-sorted on the 'val'
5080 field in order to make adding new options easier. */
5081 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5082 {"all", no_argument, 0, 'a'},
79bc120c
NC
5083 {"demangle", optional_argument, 0, 'C'},
5084 {"archive-index", no_argument, 0, 'c'},
5085 {"use-dynamic", no_argument, 0, 'D'},
5086 {"dynamic", no_argument, 0, 'd'},
b34976b6 5087 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5088 {"section-groups", no_argument, 0, 'g'},
5089 {"help", no_argument, 0, 'H'},
5090 {"file-header", no_argument, 0, 'h'},
b34976b6 5091 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5092 {"lint", no_argument, 0, 'L'},
5093 {"enable-checks", no_argument, 0, 'L'},
5094 {"program-headers", no_argument, 0, 'l'},
b34976b6 5095 {"segments", no_argument, 0, 'l'},
595cf52e 5096 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5097 {"notes", no_argument, 0, 'n'},
ca0e11aa 5098 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5099 {"string-dump", required_argument, 0, 'p'},
5100 {"relocated-dump", required_argument, 0, 'R'},
5101 {"relocs", no_argument, 0, 'r'},
5102 {"section-headers", no_argument, 0, 'S'},
5103 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5104 {"symbols", no_argument, 0, 's'},
5105 {"syms", no_argument, 0, 's'},
79bc120c
NC
5106 {"silent-truncation",no_argument, 0, 'T'},
5107 {"section-details", no_argument, 0, 't'},
b3aa80b4 5108 {"unicode", required_argument, NULL, 'U'},
09c11c86 5109 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5110 {"version-info", no_argument, 0, 'V'},
5111 {"version", no_argument, 0, 'v'},
5112 {"wide", no_argument, 0, 'W'},
b34976b6 5113 {"hex-dump", required_argument, 0, 'x'},
0e602686 5114 {"decompress", no_argument, 0, 'z'},
252b5132 5115
79bc120c
NC
5116 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5117 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5118 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5119 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5120 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5121 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5122 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5123 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5124 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5125 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5126#ifdef ENABLE_LIBCTF
d344b407 5127 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5128 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5129 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5130 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5131#endif
047c3dbf 5132 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5133
b34976b6 5134 {0, no_argument, 0, 0}
252b5132
RH
5135};
5136
5137static void
2cf0635d 5138usage (FILE * stream)
252b5132 5139{
92f01d61
JM
5140 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5141 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5142 fprintf (stream, _(" Options are:\n"));
5143 fprintf (stream, _("\
5144 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5145 fprintf (stream, _("\
5146 -h --file-header Display the ELF file header\n"));
5147 fprintf (stream, _("\
5148 -l --program-headers Display the program headers\n"));
5149 fprintf (stream, _("\
5150 --segments An alias for --program-headers\n"));
5151 fprintf (stream, _("\
5152 -S --section-headers Display the sections' header\n"));
5153 fprintf (stream, _("\
5154 --sections An alias for --section-headers\n"));
5155 fprintf (stream, _("\
5156 -g --section-groups Display the section groups\n"));
5157 fprintf (stream, _("\
5158 -t --section-details Display the section details\n"));
5159 fprintf (stream, _("\
5160 -e --headers Equivalent to: -h -l -S\n"));
5161 fprintf (stream, _("\
5162 -s --syms Display the symbol table\n"));
5163 fprintf (stream, _("\
5164 --symbols An alias for --syms\n"));
5165 fprintf (stream, _("\
5166 --dyn-syms Display the dynamic symbol table\n"));
5167 fprintf (stream, _("\
5168 --lto-syms Display LTO symbol tables\n"));
5169 fprintf (stream, _("\
047c3dbf
NL
5170 --sym-base=[0|8|10|16] \n\
5171 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5172 mixed (the default), octal, decimal, hexadecimal.\n"));
5173 fprintf (stream, _("\
0d646226
AM
5174 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5175 display_demangler_styles (stream, _("\
5176 STYLE can be "));
d6249f5f
AM
5177 fprintf (stream, _("\
5178 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5179 fprintf (stream, _("\
5180 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5181 fprintf (stream, _("\
5182 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5183 fprintf (stream, _("\
5184 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5185 Display unicode characters as determined by the current locale\n\
5186 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5187 escape sequences, or treat them as invalid and display as\n\
5188 \"{hex sequences}\"\n"));
d6249f5f
AM
5189 fprintf (stream, _("\
5190 -n --notes Display the core notes (if present)\n"));
5191 fprintf (stream, _("\
5192 -r --relocs Display the relocations (if present)\n"));
5193 fprintf (stream, _("\
5194 -u --unwind Display the unwind info (if present)\n"));
5195 fprintf (stream, _("\
5196 -d --dynamic Display the dynamic section (if present)\n"));
5197 fprintf (stream, _("\
5198 -V --version-info Display the version sections (if present)\n"));
5199 fprintf (stream, _("\
5200 -A --arch-specific Display architecture specific information (if any)\n"));
5201 fprintf (stream, _("\
5202 -c --archive-index Display the symbol/file index in an archive\n"));
5203 fprintf (stream, _("\
5204 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5205 fprintf (stream, _("\
5206 -L --lint|--enable-checks\n\
5207 Display warning messages for possible problems\n"));
5208 fprintf (stream, _("\
09c11c86 5209 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5210 Dump the contents of section <number|name> as bytes\n"));
5211 fprintf (stream, _("\
09c11c86 5212 -p --string-dump=<number|name>\n\
d6249f5f
AM
5213 Dump the contents of section <number|name> as strings\n"));
5214 fprintf (stream, _("\
cf13d699 5215 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5216 Dump the relocated contents of section <number|name>\n"));
5217 fprintf (stream, _("\
5218 -z --decompress Decompress section before dumping it\n"));
5219 fprintf (stream, _("\
5220 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5221 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5222 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5223 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5224 U/=trace_info]\n\
5225 Display the contents of DWARF debug sections\n"));
5226 fprintf (stream, _("\
5227 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5228 debuginfo files\n"));
5229 fprintf (stream, _("\
5230 -P --process-links Display the contents of non-debug sections in separate\n\
5231 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5232#if DEFAULT_FOR_FOLLOW_LINKS
5233 fprintf (stream, _("\
d6249f5f
AM
5234 -wK --debug-dump=follow-links\n\
5235 Follow links to separate debug info files (default)\n"));
5236 fprintf (stream, _("\
5237 -wN --debug-dump=no-follow-links\n\
5238 Do not follow links to separate debug info files\n"));
c46b7066
NC
5239#else
5240 fprintf (stream, _("\
d6249f5f
AM
5241 -wK --debug-dump=follow-links\n\
5242 Follow links to separate debug info files\n"));
5243 fprintf (stream, _("\
5244 -wN --debug-dump=no-follow-links\n\
5245 Do not follow links to separate debug info files\n\
5246 (default)\n"));
bed566bb
NC
5247#endif
5248#if HAVE_LIBDEBUGINFOD
5249 fprintf (stream, _("\
5250 -wD --debug-dump=use-debuginfod\n\
5251 When following links, also query debuginfod servers (default)\n"));
5252 fprintf (stream, _("\
5253 -wE --debug-dump=do-not-use-debuginfod\n\
5254 When following links, do not query debuginfod servers\n"));
c46b7066 5255#endif
fd2f0033 5256 fprintf (stream, _("\
d6249f5f
AM
5257 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5258 fprintf (stream, _("\
5259 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5260#ifdef ENABLE_LIBCTF
7d9813f1 5261 fprintf (stream, _("\
d6249f5f
AM
5262 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5263 fprintf (stream, _("\
80b56fad 5264 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5265 fprintf (stream, _("\
7d9813f1 5266 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5267 Use section <number|name> as the CTF external symtab\n"));
5268 fprintf (stream, _("\
7d9813f1 5269 --ctf-strings=<number|name>\n\
d6249f5f 5270 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5271#endif
7d9813f1 5272
252b5132 5273#ifdef SUPPORT_DISASSEMBLY
92f01d61 5274 fprintf (stream, _("\
09c11c86
NC
5275 -i --instruction-dump=<number|name>\n\
5276 Disassemble the contents of section <number|name>\n"));
252b5132 5277#endif
92f01d61 5278 fprintf (stream, _("\
d6249f5f
AM
5279 -I --histogram Display histogram of bucket list lengths\n"));
5280 fprintf (stream, _("\
5281 -W --wide Allow output width to exceed 80 characters\n"));
5282 fprintf (stream, _("\
5283 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5284 fprintf (stream, _("\
5285 @<file> Read options from <file>\n"));
5286 fprintf (stream, _("\
5287 -H --help Display this information\n"));
5288 fprintf (stream, _("\
8b53311e 5289 -v --version Display the version number of readelf\n"));
1118d252 5290
92f01d61
JM
5291 if (REPORT_BUGS_TO[0] && stream == stdout)
5292 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5293
92f01d61 5294 exit (stream == stdout ? 0 : 1);
252b5132
RH
5295}
5296
18bd398b
NC
5297/* Record the fact that the user wants the contents of section number
5298 SECTION to be displayed using the method(s) encoded as flags bits
5299 in TYPE. Note, TYPE can be zero if we are creating the array for
5300 the first time. */
5301
252b5132 5302static void
6431e409
AM
5303request_dump_bynumber (struct dump_data *dumpdata,
5304 unsigned int section, dump_type type)
252b5132 5305{
6431e409 5306 if (section >= dumpdata->num_dump_sects)
252b5132 5307 {
2cf0635d 5308 dump_type * new_dump_sects;
252b5132 5309
3f5e193b 5310 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5311 sizeof (* new_dump_sects));
252b5132
RH
5312
5313 if (new_dump_sects == NULL)
591a748a 5314 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5315 else
5316 {
6431e409 5317 if (dumpdata->dump_sects)
21b65bac
NC
5318 {
5319 /* Copy current flag settings. */
6431e409
AM
5320 memcpy (new_dump_sects, dumpdata->dump_sects,
5321 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5322
6431e409 5323 free (dumpdata->dump_sects);
21b65bac 5324 }
252b5132 5325
6431e409
AM
5326 dumpdata->dump_sects = new_dump_sects;
5327 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5328 }
5329 }
5330
6431e409
AM
5331 if (dumpdata->dump_sects)
5332 dumpdata->dump_sects[section] |= type;
252b5132
RH
5333}
5334
aef1f6d0
DJ
5335/* Request a dump by section name. */
5336
5337static void
2cf0635d 5338request_dump_byname (const char * section, dump_type type)
aef1f6d0 5339{
2cf0635d 5340 struct dump_list_entry * new_request;
aef1f6d0 5341
3f5e193b
NC
5342 new_request = (struct dump_list_entry *)
5343 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5344 if (!new_request)
591a748a 5345 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5346
5347 new_request->name = strdup (section);
5348 if (!new_request->name)
591a748a 5349 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5350
5351 new_request->type = type;
5352
5353 new_request->next = dump_sects_byname;
5354 dump_sects_byname = new_request;
5355}
5356
cf13d699 5357static inline void
6431e409 5358request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5359{
5360 int section;
5361 char * cp;
5362
015dc7e1 5363 do_dump = true;
cf13d699
NC
5364 section = strtoul (optarg, & cp, 0);
5365
5366 if (! *cp && section >= 0)
6431e409 5367 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5368 else
5369 request_dump_byname (optarg, type);
5370}
5371
252b5132 5372static void
6431e409 5373parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5374{
5375 int c;
5376
5377 if (argc < 2)
92f01d61 5378 usage (stderr);
252b5132
RH
5379
5380 while ((c = getopt_long
b3aa80b4 5381 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5382 {
252b5132
RH
5383 switch (c)
5384 {
5385 case 0:
5386 /* Long options. */
5387 break;
5388 case 'H':
92f01d61 5389 usage (stdout);
252b5132
RH
5390 break;
5391
5392 case 'a':
015dc7e1
AM
5393 do_syms = true;
5394 do_reloc = true;
5395 do_unwind = true;
5396 do_dynamic = true;
5397 do_header = true;
5398 do_sections = true;
5399 do_section_groups = true;
5400 do_segments = true;
5401 do_version = true;
5402 do_histogram = true;
5403 do_arch = true;
5404 do_notes = true;
252b5132 5405 break;
79bc120c 5406
f5842774 5407 case 'g':
015dc7e1 5408 do_section_groups = true;
f5842774 5409 break;
5477e8a0 5410 case 't':
595cf52e 5411 case 'N':
015dc7e1
AM
5412 do_sections = true;
5413 do_section_details = true;
595cf52e 5414 break;
252b5132 5415 case 'e':
015dc7e1
AM
5416 do_header = true;
5417 do_sections = true;
5418 do_segments = true;
252b5132 5419 break;
a952a375 5420 case 'A':
015dc7e1 5421 do_arch = true;
a952a375 5422 break;
252b5132 5423 case 'D':
015dc7e1 5424 do_using_dynamic = true;
252b5132
RH
5425 break;
5426 case 'r':
015dc7e1 5427 do_reloc = true;
252b5132 5428 break;
4d6ed7c8 5429 case 'u':
015dc7e1 5430 do_unwind = true;
4d6ed7c8 5431 break;
252b5132 5432 case 'h':
015dc7e1 5433 do_header = true;
252b5132
RH
5434 break;
5435 case 'l':
015dc7e1 5436 do_segments = true;
252b5132
RH
5437 break;
5438 case 's':
015dc7e1 5439 do_syms = true;
252b5132
RH
5440 break;
5441 case 'S':
015dc7e1 5442 do_sections = true;
252b5132
RH
5443 break;
5444 case 'd':
015dc7e1 5445 do_dynamic = true;
252b5132 5446 break;
a952a375 5447 case 'I':
015dc7e1 5448 do_histogram = true;
a952a375 5449 break;
779fe533 5450 case 'n':
015dc7e1 5451 do_notes = true;
779fe533 5452 break;
4145f1d5 5453 case 'c':
015dc7e1 5454 do_archive_index = true;
4145f1d5 5455 break;
1b513401 5456 case 'L':
015dc7e1 5457 do_checks = true;
1b513401 5458 break;
ca0e11aa 5459 case 'P':
015dc7e1
AM
5460 process_links = true;
5461 do_follow_links = true;
e1dbfc17 5462 dump_any_debugging = true;
ca0e11aa 5463 break;
252b5132 5464 case 'x':
6431e409 5465 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5466 break;
09c11c86 5467 case 'p':
6431e409 5468 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5469 break;
5470 case 'R':
6431e409 5471 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5472 break;
0e602686 5473 case 'z':
015dc7e1 5474 decompress_dumps = true;
0e602686 5475 break;
252b5132 5476 case 'w':
0f03783c 5477 if (optarg == NULL)
613ff48b 5478 {
015dc7e1 5479 do_debugging = true;
94585d6d
NC
5480 do_dump = true;
5481 dump_any_debugging = true;
613ff48b
CC
5482 dwarf_select_sections_all ();
5483 }
252b5132
RH
5484 else
5485 {
015dc7e1 5486 do_debugging = false;
94585d6d
NC
5487 if (dwarf_select_sections_by_letters (optarg))
5488 {
5489 do_dump = true;
5490 dump_any_debugging = true;
5491 }
252b5132
RH
5492 }
5493 break;
2979dc34 5494 case OPTION_DEBUG_DUMP:
0f03783c 5495 if (optarg == NULL)
d6249f5f 5496 {
94585d6d 5497 do_dump = true;
d6249f5f 5498 do_debugging = true;
94585d6d 5499 dump_any_debugging = true;
d6249f5f
AM
5500 dwarf_select_sections_all ();
5501 }
2979dc34
JJ
5502 else
5503 {
015dc7e1 5504 do_debugging = false;
94585d6d
NC
5505 if (dwarf_select_sections_by_names (optarg))
5506 {
5507 do_dump = true;
5508 dump_any_debugging = true;
5509 }
2979dc34
JJ
5510 }
5511 break;
fd2f0033
TT
5512 case OPTION_DWARF_DEPTH:
5513 {
5514 char *cp;
5515
5516 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5517 }
5518 break;
5519 case OPTION_DWARF_START:
5520 {
5521 char *cp;
5522
5523 dwarf_start_die = strtoul (optarg, & cp, 0);
5524 }
5525 break;
4723351a 5526 case OPTION_DWARF_CHECK:
015dc7e1 5527 dwarf_check = true;
4723351a 5528 break;
7d9813f1 5529 case OPTION_CTF_DUMP:
015dc7e1 5530 do_ctf = true;
6431e409 5531 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5532 break;
5533 case OPTION_CTF_SYMBOLS:
df16e041 5534 free (dump_ctf_symtab_name);
7d9813f1
NA
5535 dump_ctf_symtab_name = strdup (optarg);
5536 break;
5537 case OPTION_CTF_STRINGS:
df16e041 5538 free (dump_ctf_strtab_name);
7d9813f1
NA
5539 dump_ctf_strtab_name = strdup (optarg);
5540 break;
5541 case OPTION_CTF_PARENT:
df16e041 5542 free (dump_ctf_parent_name);
7d9813f1
NA
5543 dump_ctf_parent_name = strdup (optarg);
5544 break;
2c610e4b 5545 case OPTION_DYN_SYMS:
015dc7e1 5546 do_dyn_syms = true;
2c610e4b 5547 break;
0f03783c 5548 case OPTION_LTO_SYMS:
015dc7e1 5549 do_lto_syms = true;
0f03783c 5550 break;
252b5132
RH
5551#ifdef SUPPORT_DISASSEMBLY
5552 case 'i':
6431e409 5553 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5554 break;
252b5132
RH
5555#endif
5556 case 'v':
5557 print_version (program_name);
5558 break;
5559 case 'V':
015dc7e1 5560 do_version = true;
252b5132 5561 break;
d974e256 5562 case 'W':
015dc7e1 5563 do_wide = true;
d974e256 5564 break;
0942c7ab 5565 case 'T':
015dc7e1 5566 do_not_show_symbol_truncation = true;
0942c7ab 5567 break;
79bc120c 5568 case 'C':
015dc7e1 5569 do_demangle = true;
79bc120c
NC
5570 if (optarg != NULL)
5571 {
5572 enum demangling_styles style;
5573
5574 style = cplus_demangle_name_to_style (optarg);
5575 if (style == unknown_demangling)
5576 error (_("unknown demangling style `%s'"), optarg);
5577
5578 cplus_demangle_set_style (style);
5579 }
5580 break;
5581 case OPTION_NO_DEMANGLING:
015dc7e1 5582 do_demangle = false;
79bc120c
NC
5583 break;
5584 case OPTION_RECURSE_LIMIT:
5585 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5586 break;
5587 case OPTION_NO_RECURSE_LIMIT:
5588 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5589 break;
5590 case OPTION_WITH_SYMBOL_VERSIONS:
5591 /* Ignored for backward compatibility. */
5592 break;
b9e920ec 5593
b3aa80b4
NC
5594 case 'U':
5595 if (optarg == NULL)
5596 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5597 else if (streq (optarg, "default") || streq (optarg, "d"))
5598 unicode_display = unicode_default;
5599 else if (streq (optarg, "locale") || streq (optarg, "l"))
5600 unicode_display = unicode_locale;
5601 else if (streq (optarg, "escape") || streq (optarg, "e"))
5602 unicode_display = unicode_escape;
5603 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5604 unicode_display = unicode_invalid;
5605 else if (streq (optarg, "hex") || streq (optarg, "x"))
5606 unicode_display = unicode_hex;
5607 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5608 unicode_display = unicode_highlight;
5609 else
5610 error (_("invalid argument to -U/--unicode: %s"), optarg);
5611 break;
5612
047c3dbf
NL
5613 case OPTION_SYM_BASE:
5614 sym_base = 0;
5615 if (optarg != NULL)
5616 {
5617 sym_base = strtoul (optarg, NULL, 0);
5618 switch (sym_base)
5619 {
5620 case 0:
5621 case 8:
5622 case 10:
5623 case 16:
5624 break;
5625
5626 default:
5627 sym_base = 0;
5628 break;
5629 }
5630 }
5631 break;
5632
252b5132 5633 default:
252b5132
RH
5634 /* xgettext:c-format */
5635 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5636 /* Fall through. */
252b5132 5637 case '?':
92f01d61 5638 usage (stderr);
252b5132
RH
5639 }
5640 }
5641
4d6ed7c8 5642 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5643 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5644 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5645 && !do_section_groups && !do_archive_index
0f03783c 5646 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5647 {
5648 if (do_checks)
5649 {
015dc7e1
AM
5650 check_all = true;
5651 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5652 do_segments = do_header = do_dump = do_version = true;
5653 do_histogram = do_debugging = do_arch = do_notes = true;
5654 do_section_groups = do_archive_index = do_dyn_syms = true;
5655 do_lto_syms = true;
1b513401
NC
5656 }
5657 else
5658 usage (stderr);
5659 }
252b5132
RH
5660}
5661
5662static const char *
d3ba0551 5663get_elf_class (unsigned int elf_class)
252b5132 5664{
b34976b6 5665 static char buff[32];
103f02d3 5666
252b5132
RH
5667 switch (elf_class)
5668 {
5669 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5670 case ELFCLASS32: return "ELF32";
5671 case ELFCLASS64: return "ELF64";
ab5e7794 5672 default:
e9e44622 5673 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5674 return buff;
252b5132
RH
5675 }
5676}
5677
5678static const char *
d3ba0551 5679get_data_encoding (unsigned int encoding)
252b5132 5680{
b34976b6 5681 static char buff[32];
103f02d3 5682
252b5132
RH
5683 switch (encoding)
5684 {
5685 case ELFDATANONE: return _("none");
33c63f9d
CM
5686 case ELFDATA2LSB: return _("2's complement, little endian");
5687 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5688 default:
e9e44622 5689 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5690 return buff;
252b5132
RH
5691 }
5692}
5693
521f7268
NC
5694static bool
5695check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5696{
5697 if (header->e_ident[EI_MAG0] == ELFMAG0
5698 && header->e_ident[EI_MAG1] == ELFMAG1
5699 && header->e_ident[EI_MAG2] == ELFMAG2
5700 && header->e_ident[EI_MAG3] == ELFMAG3)
5701 return true;
5702
5703 /* Some compilers produce object files that are not in the ELF file format.
5704 As an aid to users of readelf, try to identify these cases and suggest
5705 alternative tools.
5706
5707 FIXME: It is not clear if all four bytes are used as constant magic
5708 valus by all compilers. It may be necessary to recode this function if
5709 different tools use different length sequences. */
5710
5711 static struct
5712 {
5713 unsigned char magic[4];
5714 const char * obj_message;
5715 const char * ar_message;
5716 }
5717 known_magic[] =
5718 {
5719 { { 'B', 'C', 0xc0, 0xde },
5720 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5721 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5722 },
5723 { { 'g', 'o', ' ', 'o' },
5724 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5725 NULL
5726 }
5727 };
5728 int i;
5729
5730 for (i = ARRAY_SIZE (known_magic); i--;)
5731 {
5732 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5733 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5734 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5735 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5736 {
5737 /* Some compiler's analyzer tools do not handle archives,
5738 so we provide two different kinds of error message. */
5739 if (filedata->archive_file_size > 0
5740 && known_magic[i].ar_message != NULL)
b3ea2010 5741 error ("%s", known_magic[i].ar_message);
521f7268 5742 else
b3ea2010 5743 error ("%s", known_magic[i].obj_message);
521f7268
NC
5744 return false;
5745 }
5746 }
5747
5748 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5749 return false;
5750}
5751
dda8d76d 5752/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5753
015dc7e1 5754static bool
dda8d76d 5755process_file_header (Filedata * filedata)
252b5132 5756{
dda8d76d
NC
5757 Elf_Internal_Ehdr * header = & filedata->file_header;
5758
521f7268
NC
5759 if (! check_magic_number (filedata, header))
5760 return false;
252b5132 5761
ca0e11aa
NC
5762 if (! filedata->is_separate)
5763 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5764
252b5132
RH
5765 if (do_header)
5766 {
32ec8896 5767 unsigned i;
252b5132 5768
ca0e11aa
NC
5769 if (filedata->is_separate)
5770 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5771 else
5772 printf (_("ELF Header:\n"));
252b5132 5773 printf (_(" Magic: "));
b34976b6 5774 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5775 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5776 printf ("\n");
5777 printf (_(" Class: %s\n"),
dda8d76d 5778 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5779 printf (_(" Data: %s\n"),
dda8d76d 5780 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5781 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5782 header->e_ident[EI_VERSION],
5783 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5784 ? _(" (current)")
dda8d76d 5785 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5786 ? _(" <unknown>")
789be9f7 5787 : "")));
252b5132 5788 printf (_(" OS/ABI: %s\n"),
dda8d76d 5789 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5790 printf (_(" ABI Version: %d\n"),
dda8d76d 5791 header->e_ident[EI_ABIVERSION]);
252b5132 5792 printf (_(" Type: %s\n"),
93df3340 5793 get_file_type (filedata));
252b5132 5794 printf (_(" Machine: %s\n"),
dda8d76d 5795 get_machine_name (header->e_machine));
252b5132 5796 printf (_(" Version: 0x%lx\n"),
e8a64888 5797 header->e_version);
76da6bbe 5798
f7a99963 5799 printf (_(" Entry point address: "));
e8a64888 5800 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5801 printf (_("\n Start of program headers: "));
e8a64888 5802 print_vma (header->e_phoff, DEC);
f7a99963 5803 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5804 print_vma (header->e_shoff, DEC);
f7a99963 5805 printf (_(" (bytes into file)\n"));
76da6bbe 5806
252b5132 5807 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5808 header->e_flags,
dda8d76d 5809 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5810 printf (_(" Size of this header: %u (bytes)\n"),
5811 header->e_ehsize);
5812 printf (_(" Size of program headers: %u (bytes)\n"),
5813 header->e_phentsize);
5814 printf (_(" Number of program headers: %u"),
5815 header->e_phnum);
dda8d76d
NC
5816 if (filedata->section_headers != NULL
5817 && header->e_phnum == PN_XNUM
5818 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5819 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5820 putc ('\n', stdout);
e8a64888
AM
5821 printf (_(" Size of section headers: %u (bytes)\n"),
5822 header->e_shentsize);
5823 printf (_(" Number of section headers: %u"),
5824 header->e_shnum);
dda8d76d 5825 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5826 {
5827 header->e_shnum = filedata->section_headers[0].sh_size;
5828 printf (" (%u)", header->e_shnum);
5829 }
560f3c1c 5830 putc ('\n', stdout);
e8a64888
AM
5831 printf (_(" Section header string table index: %u"),
5832 header->e_shstrndx);
dda8d76d
NC
5833 if (filedata->section_headers != NULL
5834 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5835 {
5836 header->e_shstrndx = filedata->section_headers[0].sh_link;
5837 printf (" (%u)", header->e_shstrndx);
5838 }
5839 if (header->e_shstrndx != SHN_UNDEF
5840 && header->e_shstrndx >= header->e_shnum)
5841 {
5842 header->e_shstrndx = SHN_UNDEF;
5843 printf (_(" <corrupt: out of range>"));
5844 }
560f3c1c
AM
5845 putc ('\n', stdout);
5846 }
5847
dda8d76d 5848 if (filedata->section_headers != NULL)
560f3c1c 5849 {
dda8d76d
NC
5850 if (header->e_phnum == PN_XNUM
5851 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5852 {
5853 /* Throw away any cached read of PN_XNUM headers. */
5854 free (filedata->program_headers);
5855 filedata->program_headers = NULL;
5856 header->e_phnum = filedata->section_headers[0].sh_info;
5857 }
dda8d76d
NC
5858 if (header->e_shnum == SHN_UNDEF)
5859 header->e_shnum = filedata->section_headers[0].sh_size;
5860 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5861 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5862 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5863 header->e_shstrndx = SHN_UNDEF;
252b5132 5864 }
103f02d3 5865
015dc7e1 5866 return true;
9ea033b2
NC
5867}
5868
dda8d76d
NC
5869/* Read in the program headers from FILEDATA and store them in PHEADERS.
5870 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5871
015dc7e1 5872static bool
dda8d76d 5873get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5874{
2cf0635d
NC
5875 Elf32_External_Phdr * phdrs;
5876 Elf32_External_Phdr * external;
5877 Elf_Internal_Phdr * internal;
b34976b6 5878 unsigned int i;
dda8d76d
NC
5879 unsigned int size = filedata->file_header.e_phentsize;
5880 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5881
5882 /* PR binutils/17531: Cope with unexpected section header sizes. */
5883 if (size == 0 || num == 0)
015dc7e1 5884 return false;
e0a31db1
NC
5885 if (size < sizeof * phdrs)
5886 {
5887 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5888 return false;
e0a31db1
NC
5889 }
5890 if (size > sizeof * phdrs)
5891 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5892
dda8d76d 5893 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5894 size, num, _("program headers"));
5895 if (phdrs == NULL)
015dc7e1 5896 return false;
9ea033b2 5897
91d6fa6a 5898 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5899 i < filedata->file_header.e_phnum;
b34976b6 5900 i++, internal++, external++)
252b5132 5901 {
9ea033b2
NC
5902 internal->p_type = BYTE_GET (external->p_type);
5903 internal->p_offset = BYTE_GET (external->p_offset);
5904 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5905 internal->p_paddr = BYTE_GET (external->p_paddr);
5906 internal->p_filesz = BYTE_GET (external->p_filesz);
5907 internal->p_memsz = BYTE_GET (external->p_memsz);
5908 internal->p_flags = BYTE_GET (external->p_flags);
5909 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5910 }
5911
9ea033b2 5912 free (phdrs);
015dc7e1 5913 return true;
252b5132
RH
5914}
5915
dda8d76d
NC
5916/* Read in the program headers from FILEDATA and store them in PHEADERS.
5917 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5918
015dc7e1 5919static bool
dda8d76d 5920get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5921{
2cf0635d
NC
5922 Elf64_External_Phdr * phdrs;
5923 Elf64_External_Phdr * external;
5924 Elf_Internal_Phdr * internal;
b34976b6 5925 unsigned int i;
dda8d76d
NC
5926 unsigned int size = filedata->file_header.e_phentsize;
5927 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5928
5929 /* PR binutils/17531: Cope with unexpected section header sizes. */
5930 if (size == 0 || num == 0)
015dc7e1 5931 return false;
e0a31db1
NC
5932 if (size < sizeof * phdrs)
5933 {
5934 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5935 return false;
e0a31db1
NC
5936 }
5937 if (size > sizeof * phdrs)
5938 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5939
dda8d76d 5940 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5941 size, num, _("program headers"));
a6e9f9df 5942 if (!phdrs)
015dc7e1 5943 return false;
9ea033b2 5944
91d6fa6a 5945 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5946 i < filedata->file_header.e_phnum;
b34976b6 5947 i++, internal++, external++)
9ea033b2
NC
5948 {
5949 internal->p_type = BYTE_GET (external->p_type);
5950 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5951 internal->p_offset = BYTE_GET (external->p_offset);
5952 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5953 internal->p_paddr = BYTE_GET (external->p_paddr);
5954 internal->p_filesz = BYTE_GET (external->p_filesz);
5955 internal->p_memsz = BYTE_GET (external->p_memsz);
5956 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5957 }
5958
5959 free (phdrs);
015dc7e1 5960 return true;
9ea033b2 5961}
252b5132 5962
32ec8896 5963/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5964
015dc7e1 5965static bool
dda8d76d 5966get_program_headers (Filedata * filedata)
d93f0186 5967{
2cf0635d 5968 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5969
5970 /* Check cache of prior read. */
dda8d76d 5971 if (filedata->program_headers != NULL)
015dc7e1 5972 return true;
d93f0186 5973
82156ab7
NC
5974 /* Be kind to memory checkers by looking for
5975 e_phnum values which we know must be invalid. */
dda8d76d 5976 if (filedata->file_header.e_phnum
82156ab7 5977 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5978 >= filedata->file_size)
82156ab7
NC
5979 {
5980 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5981 filedata->file_header.e_phnum);
015dc7e1 5982 return false;
82156ab7 5983 }
d93f0186 5984
dda8d76d 5985 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5986 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5987 if (phdrs == NULL)
5988 {
8b73c356 5989 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5990 filedata->file_header.e_phnum);
015dc7e1 5991 return false;
d93f0186
NC
5992 }
5993
5994 if (is_32bit_elf
dda8d76d
NC
5995 ? get_32bit_program_headers (filedata, phdrs)
5996 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5997 {
dda8d76d 5998 filedata->program_headers = phdrs;
015dc7e1 5999 return true;
d93f0186
NC
6000 }
6001
6002 free (phdrs);
015dc7e1 6003 return false;
d93f0186
NC
6004}
6005
93df3340 6006/* Print program header info and locate dynamic section. */
2f62977e 6007
93df3340 6008static void
dda8d76d 6009process_program_headers (Filedata * filedata)
252b5132 6010{
2cf0635d 6011 Elf_Internal_Phdr * segment;
b34976b6 6012 unsigned int i;
1a9ccd70 6013 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6014
dda8d76d 6015 if (filedata->file_header.e_phnum == 0)
252b5132 6016 {
82f2dbf7 6017 /* PR binutils/12467. */
dda8d76d 6018 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6019 warn (_("possibly corrupt ELF header - it has a non-zero program"
6020 " header offset, but no program headers\n"));
82f2dbf7 6021 else if (do_segments)
ca0e11aa
NC
6022 {
6023 if (filedata->is_separate)
6024 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6025 filedata->file_name);
6026 else
6027 printf (_("\nThere are no program headers in this file.\n"));
6028 }
93df3340 6029 goto no_headers;
252b5132
RH
6030 }
6031
6032 if (do_segments && !do_header)
6033 {
ca0e11aa
NC
6034 if (filedata->is_separate)
6035 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6036 filedata->file_name, get_file_type (filedata));
ca0e11aa 6037 else
93df3340 6038 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6039 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6040 filedata->file_header.e_entry);
b8281767
AM
6041 printf (ngettext ("There is %d program header,"
6042 " starting at offset %" PRIu64 "\n",
6043 "There are %d program headers,"
6044 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6045 filedata->file_header.e_phnum),
6046 filedata->file_header.e_phnum,
625d49fc 6047 filedata->file_header.e_phoff);
252b5132
RH
6048 }
6049
dda8d76d 6050 if (! get_program_headers (filedata))
93df3340 6051 goto no_headers;
103f02d3 6052
252b5132
RH
6053 if (do_segments)
6054 {
dda8d76d 6055 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6056 printf (_("\nProgram Headers:\n"));
6057 else
6058 printf (_("\nProgram Headers:\n"));
76da6bbe 6059
f7a99963
NC
6060 if (is_32bit_elf)
6061 printf
6062 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6063 else if (do_wide)
6064 printf
6065 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6066 else
6067 {
6068 printf
6069 (_(" Type Offset VirtAddr PhysAddr\n"));
6070 printf
6071 (_(" FileSiz MemSiz Flags Align\n"));
6072 }
252b5132
RH
6073 }
6074
93df3340 6075 unsigned long dynamic_addr = 0;
be7d229a 6076 uint64_t dynamic_size = 0;
dda8d76d
NC
6077 for (i = 0, segment = filedata->program_headers;
6078 i < filedata->file_header.e_phnum;
b34976b6 6079 i++, segment++)
252b5132
RH
6080 {
6081 if (do_segments)
6082 {
dda8d76d 6083 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6084
6085 if (is_32bit_elf)
6086 {
6087 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6088 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6089 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6090 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6091 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6092 printf ("%c%c%c ",
6093 (segment->p_flags & PF_R ? 'R' : ' '),
6094 (segment->p_flags & PF_W ? 'W' : ' '),
6095 (segment->p_flags & PF_X ? 'E' : ' '));
6096 printf ("%#lx", (unsigned long) segment->p_align);
6097 }
d974e256
JJ
6098 else if (do_wide)
6099 {
6100 if ((unsigned long) segment->p_offset == segment->p_offset)
6101 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6102 else
6103 {
6104 print_vma (segment->p_offset, FULL_HEX);
6105 putchar (' ');
6106 }
6107
6108 print_vma (segment->p_vaddr, FULL_HEX);
6109 putchar (' ');
6110 print_vma (segment->p_paddr, FULL_HEX);
6111 putchar (' ');
6112
6113 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6114 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6115 else
6116 {
6117 print_vma (segment->p_filesz, FULL_HEX);
6118 putchar (' ');
6119 }
6120
6121 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6122 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6123 else
6124 {
f48e6c45 6125 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6126 }
6127
6128 printf (" %c%c%c ",
6129 (segment->p_flags & PF_R ? 'R' : ' '),
6130 (segment->p_flags & PF_W ? 'W' : ' '),
6131 (segment->p_flags & PF_X ? 'E' : ' '));
6132
6133 if ((unsigned long) segment->p_align == segment->p_align)
6134 printf ("%#lx", (unsigned long) segment->p_align);
6135 else
6136 {
6137 print_vma (segment->p_align, PREFIX_HEX);
6138 }
6139 }
f7a99963
NC
6140 else
6141 {
6142 print_vma (segment->p_offset, FULL_HEX);
6143 putchar (' ');
6144 print_vma (segment->p_vaddr, FULL_HEX);
6145 putchar (' ');
6146 print_vma (segment->p_paddr, FULL_HEX);
6147 printf ("\n ");
6148 print_vma (segment->p_filesz, FULL_HEX);
6149 putchar (' ');
6150 print_vma (segment->p_memsz, FULL_HEX);
6151 printf (" %c%c%c ",
6152 (segment->p_flags & PF_R ? 'R' : ' '),
6153 (segment->p_flags & PF_W ? 'W' : ' '),
6154 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6155 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6156 }
252b5132 6157
1a9ccd70
NC
6158 putc ('\n', stdout);
6159 }
f54498b4 6160
252b5132
RH
6161 switch (segment->p_type)
6162 {
1a9ccd70 6163 case PT_LOAD:
502d895c
NC
6164#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6165 required by the ELF standard, several programs, including the Linux
6166 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6167 if (previous_load
6168 && previous_load->p_vaddr > segment->p_vaddr)
6169 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6170#endif
1a9ccd70
NC
6171 if (segment->p_memsz < segment->p_filesz)
6172 error (_("the segment's file size is larger than its memory size\n"));
6173 previous_load = segment;
6174 break;
6175
6176 case PT_PHDR:
6177 /* PR 20815 - Verify that the program header is loaded into memory. */
6178 if (i > 0 && previous_load != NULL)
6179 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6180 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6181 {
6182 unsigned int j;
6183
dda8d76d 6184 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6185 {
6186 Elf_Internal_Phdr *load = filedata->program_headers + j;
6187 if (load->p_type == PT_LOAD
6188 && load->p_offset <= segment->p_offset
6189 && (load->p_offset + load->p_filesz
6190 >= segment->p_offset + segment->p_filesz)
6191 && load->p_vaddr <= segment->p_vaddr
6192 && (load->p_vaddr + load->p_filesz
6193 >= segment->p_vaddr + segment->p_filesz))
6194 break;
6195 }
dda8d76d 6196 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6197 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6198 }
6199 break;
6200
252b5132 6201 case PT_DYNAMIC:
93df3340 6202 if (dynamic_addr)
252b5132
RH
6203 error (_("more than one dynamic segment\n"));
6204
20737c13
AM
6205 /* By default, assume that the .dynamic section is the first
6206 section in the DYNAMIC segment. */
93df3340
AM
6207 dynamic_addr = segment->p_offset;
6208 dynamic_size = segment->p_filesz;
20737c13 6209
b2d38a17
NC
6210 /* Try to locate the .dynamic section. If there is
6211 a section header table, we can easily locate it. */
dda8d76d 6212 if (filedata->section_headers != NULL)
b2d38a17 6213 {
2cf0635d 6214 Elf_Internal_Shdr * sec;
b2d38a17 6215
dda8d76d 6216 sec = find_section (filedata, ".dynamic");
89fac5e3 6217 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6218 {
93df3340
AM
6219 /* A corresponding .dynamic section is expected, but on
6220 IA-64/OpenVMS it is OK for it to be missing. */
6221 if (!is_ia64_vms (filedata))
6222 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6223 break;
6224 }
6225
42bb2e33 6226 if (sec->sh_type == SHT_NOBITS)
20737c13 6227 {
93df3340
AM
6228 dynamic_addr = 0;
6229 dynamic_size = 0;
20737c13
AM
6230 break;
6231 }
42bb2e33 6232
93df3340
AM
6233 dynamic_addr = sec->sh_offset;
6234 dynamic_size = sec->sh_size;
b2d38a17 6235
8ac10c5b
L
6236 /* The PT_DYNAMIC segment, which is used by the run-time
6237 loader, should exactly match the .dynamic section. */
6238 if (do_checks
93df3340
AM
6239 && (dynamic_addr != segment->p_offset
6240 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6241 warn (_("\
6242the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6243 }
39e224f6
MW
6244
6245 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6246 segment. Check this after matching against the section headers
6247 so we don't warn on debuginfo file (which have NOBITS .dynamic
6248 sections). */
93df3340
AM
6249 if (dynamic_addr > filedata->file_size
6250 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6251 {
6252 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6253 dynamic_addr = 0;
6254 dynamic_size = 0;
39e224f6 6255 }
252b5132
RH
6256 break;
6257
6258 case PT_INTERP:
13acb58d
AM
6259 if (segment->p_offset >= filedata->file_size
6260 || segment->p_filesz > filedata->file_size - segment->p_offset
6261 || segment->p_filesz - 1 >= (size_t) -2
6262 || fseek (filedata->handle,
6263 filedata->archive_file_offset + (long) segment->p_offset,
6264 SEEK_SET))
252b5132
RH
6265 error (_("Unable to find program interpreter name\n"));
6266 else
6267 {
13acb58d
AM
6268 size_t len = segment->p_filesz;
6269 free (filedata->program_interpreter);
6270 filedata->program_interpreter = xmalloc (len + 1);
6271 len = fread (filedata->program_interpreter, 1, len,
6272 filedata->handle);
6273 filedata->program_interpreter[len] = 0;
252b5132
RH
6274
6275 if (do_segments)
f54498b4 6276 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6277 filedata->program_interpreter);
252b5132
RH
6278 }
6279 break;
6280 }
252b5132
RH
6281 }
6282
dda8d76d
NC
6283 if (do_segments
6284 && filedata->section_headers != NULL
6285 && filedata->string_table != NULL)
252b5132
RH
6286 {
6287 printf (_("\n Section to Segment mapping:\n"));
6288 printf (_(" Segment Sections...\n"));
6289
dda8d76d 6290 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6291 {
9ad5cbcf 6292 unsigned int j;
2cf0635d 6293 Elf_Internal_Shdr * section;
252b5132 6294
dda8d76d
NC
6295 segment = filedata->program_headers + i;
6296 section = filedata->section_headers + 1;
252b5132
RH
6297
6298 printf (" %2.2d ", i);
6299
dda8d76d 6300 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6301 {
f4638467
AM
6302 if (!ELF_TBSS_SPECIAL (section, segment)
6303 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6304 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6305 }
6306
6307 putc ('\n',stdout);
6308 }
6309 }
6310
93df3340
AM
6311 filedata->dynamic_addr = dynamic_addr;
6312 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6313 return;
6314
6315 no_headers:
6316 filedata->dynamic_addr = 0;
6317 filedata->dynamic_size = 1;
252b5132
RH
6318}
6319
6320
d93f0186
NC
6321/* Find the file offset corresponding to VMA by using the program headers. */
6322
6323static long
625d49fc 6324offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6325{
2cf0635d 6326 Elf_Internal_Phdr * seg;
d93f0186 6327
dda8d76d 6328 if (! get_program_headers (filedata))
d93f0186
NC
6329 {
6330 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6331 return (long) vma;
6332 }
6333
dda8d76d
NC
6334 for (seg = filedata->program_headers;
6335 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6336 ++seg)
6337 {
6338 if (seg->p_type != PT_LOAD)
6339 continue;
6340
6341 if (vma >= (seg->p_vaddr & -seg->p_align)
6342 && vma + size <= seg->p_vaddr + seg->p_filesz)
6343 return vma - seg->p_vaddr + seg->p_offset;
6344 }
6345
6346 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6347 (unsigned long) vma);
d93f0186
NC
6348 return (long) vma;
6349}
6350
6351
dda8d76d
NC
6352/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6353 If PROBE is true, this is just a probe and we do not generate any error
6354 messages if the load fails. */
049b0c3a 6355
015dc7e1
AM
6356static bool
6357get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6358{
2cf0635d
NC
6359 Elf32_External_Shdr * shdrs;
6360 Elf_Internal_Shdr * internal;
dda8d76d
NC
6361 unsigned int i;
6362 unsigned int size = filedata->file_header.e_shentsize;
6363 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6364
6365 /* PR binutils/17531: Cope with unexpected section header sizes. */
6366 if (size == 0 || num == 0)
015dc7e1 6367 return false;
049b0c3a
NC
6368 if (size < sizeof * shdrs)
6369 {
6370 if (! probe)
6371 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6372 return false;
049b0c3a
NC
6373 }
6374 if (!probe && size > sizeof * shdrs)
6375 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6376
dda8d76d 6377 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6378 size, num,
6379 probe ? NULL : _("section headers"));
6380 if (shdrs == NULL)
015dc7e1 6381 return false;
252b5132 6382
dda8d76d
NC
6383 filedata->section_headers = (Elf_Internal_Shdr *)
6384 cmalloc (num, sizeof (Elf_Internal_Shdr));
6385 if (filedata->section_headers == NULL)
252b5132 6386 {
049b0c3a 6387 if (!probe)
8b73c356 6388 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6389 free (shdrs);
015dc7e1 6390 return false;
252b5132
RH
6391 }
6392
dda8d76d 6393 for (i = 0, internal = filedata->section_headers;
560f3c1c 6394 i < num;
b34976b6 6395 i++, internal++)
252b5132
RH
6396 {
6397 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6398 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6399 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6400 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6401 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6402 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6403 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6404 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6405 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6406 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6407 if (!probe && internal->sh_link > num)
6408 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6409 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6410 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6411 }
6412
6413 free (shdrs);
015dc7e1 6414 return true;
252b5132
RH
6415}
6416
dda8d76d
NC
6417/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6418
015dc7e1
AM
6419static bool
6420get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6421{
dda8d76d
NC
6422 Elf64_External_Shdr * shdrs;
6423 Elf_Internal_Shdr * internal;
6424 unsigned int i;
6425 unsigned int size = filedata->file_header.e_shentsize;
6426 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6427
6428 /* PR binutils/17531: Cope with unexpected section header sizes. */
6429 if (size == 0 || num == 0)
015dc7e1 6430 return false;
dda8d76d 6431
049b0c3a
NC
6432 if (size < sizeof * shdrs)
6433 {
6434 if (! probe)
6435 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6436 return false;
049b0c3a 6437 }
dda8d76d 6438
049b0c3a
NC
6439 if (! probe && size > sizeof * shdrs)
6440 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6441
dda8d76d
NC
6442 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6443 filedata->file_header.e_shoff,
049b0c3a
NC
6444 size, num,
6445 probe ? NULL : _("section headers"));
6446 if (shdrs == NULL)
015dc7e1 6447 return false;
9ea033b2 6448
dda8d76d
NC
6449 filedata->section_headers = (Elf_Internal_Shdr *)
6450 cmalloc (num, sizeof (Elf_Internal_Shdr));
6451 if (filedata->section_headers == NULL)
9ea033b2 6452 {
049b0c3a 6453 if (! probe)
8b73c356 6454 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6455 free (shdrs);
015dc7e1 6456 return false;
9ea033b2
NC
6457 }
6458
dda8d76d 6459 for (i = 0, internal = filedata->section_headers;
560f3c1c 6460 i < num;
b34976b6 6461 i++, internal++)
9ea033b2
NC
6462 {
6463 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6464 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6465 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6466 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6467 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6468 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6469 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6470 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6471 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6472 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6473 if (!probe && internal->sh_link > num)
6474 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6475 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6476 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6477 }
6478
6479 free (shdrs);
015dc7e1 6480 return true;
9ea033b2
NC
6481}
6482
4de91c10
AM
6483static bool
6484get_section_headers (Filedata *filedata, bool probe)
6485{
6486 if (filedata->section_headers != NULL)
6487 return true;
6488
4de91c10
AM
6489 if (is_32bit_elf)
6490 return get_32bit_section_headers (filedata, probe);
6491 else
6492 return get_64bit_section_headers (filedata, probe);
6493}
6494
252b5132 6495static Elf_Internal_Sym *
dda8d76d
NC
6496get_32bit_elf_symbols (Filedata * filedata,
6497 Elf_Internal_Shdr * section,
6498 unsigned long * num_syms_return)
252b5132 6499{
ba5cdace 6500 unsigned long number = 0;
dd24e3da 6501 Elf32_External_Sym * esyms = NULL;
ba5cdace 6502 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6503 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6504 Elf_Internal_Sym * psym;
b34976b6 6505 unsigned int j;
e3d39609 6506 elf_section_list * entry;
252b5132 6507
c9c1d674
EG
6508 if (section->sh_size == 0)
6509 {
6510 if (num_syms_return != NULL)
6511 * num_syms_return = 0;
6512 return NULL;
6513 }
6514
dd24e3da 6515 /* Run some sanity checks first. */
c9c1d674 6516 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6517 {
c9c1d674 6518 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6519 printable_section_name (filedata, section),
6520 (unsigned long) section->sh_entsize);
ba5cdace 6521 goto exit_point;
dd24e3da
NC
6522 }
6523
dda8d76d 6524 if (section->sh_size > filedata->file_size)
f54498b4
NC
6525 {
6526 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6527 printable_section_name (filedata, section),
6528 (unsigned long) section->sh_size);
f54498b4
NC
6529 goto exit_point;
6530 }
6531
dd24e3da
NC
6532 number = section->sh_size / section->sh_entsize;
6533
6534 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6535 {
c9c1d674 6536 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6537 (unsigned long) section->sh_size,
dda8d76d 6538 printable_section_name (filedata, section),
8066deb1 6539 (unsigned long) section->sh_entsize);
ba5cdace 6540 goto exit_point;
dd24e3da
NC
6541 }
6542
dda8d76d 6543 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6544 section->sh_size, _("symbols"));
dd24e3da 6545 if (esyms == NULL)
ba5cdace 6546 goto exit_point;
252b5132 6547
e3d39609 6548 shndx = NULL;
978c4450 6549 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6550 {
6551 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6552 continue;
6553
6554 if (shndx != NULL)
6555 {
6556 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6557 free (shndx);
6558 }
6559
6560 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6561 entry->hdr->sh_offset,
6562 1, entry->hdr->sh_size,
6563 _("symbol table section indices"));
6564 if (shndx == NULL)
6565 goto exit_point;
6566
6567 /* PR17531: file: heap-buffer-overflow */
6568 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6569 {
6570 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6571 printable_section_name (filedata, entry->hdr),
6572 (unsigned long) entry->hdr->sh_size,
6573 (unsigned long) section->sh_size);
6574 goto exit_point;
c9c1d674 6575 }
e3d39609 6576 }
9ad5cbcf 6577
3f5e193b 6578 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6579
6580 if (isyms == NULL)
6581 {
8b73c356
NC
6582 error (_("Out of memory reading %lu symbols\n"),
6583 (unsigned long) number);
dd24e3da 6584 goto exit_point;
252b5132
RH
6585 }
6586
dd24e3da 6587 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6588 {
6589 psym->st_name = BYTE_GET (esyms[j].st_name);
6590 psym->st_value = BYTE_GET (esyms[j].st_value);
6591 psym->st_size = BYTE_GET (esyms[j].st_size);
6592 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6593 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6594 psym->st_shndx
6595 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6596 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6597 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6598 psym->st_info = BYTE_GET (esyms[j].st_info);
6599 psym->st_other = BYTE_GET (esyms[j].st_other);
6600 }
6601
dd24e3da 6602 exit_point:
e3d39609
NC
6603 free (shndx);
6604 free (esyms);
252b5132 6605
ba5cdace
NC
6606 if (num_syms_return != NULL)
6607 * num_syms_return = isyms == NULL ? 0 : number;
6608
252b5132
RH
6609 return isyms;
6610}
6611
9ea033b2 6612static Elf_Internal_Sym *
dda8d76d
NC
6613get_64bit_elf_symbols (Filedata * filedata,
6614 Elf_Internal_Shdr * section,
6615 unsigned long * num_syms_return)
9ea033b2 6616{
ba5cdace
NC
6617 unsigned long number = 0;
6618 Elf64_External_Sym * esyms = NULL;
6619 Elf_External_Sym_Shndx * shndx = NULL;
6620 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6621 Elf_Internal_Sym * psym;
b34976b6 6622 unsigned int j;
e3d39609 6623 elf_section_list * entry;
9ea033b2 6624
c9c1d674
EG
6625 if (section->sh_size == 0)
6626 {
6627 if (num_syms_return != NULL)
6628 * num_syms_return = 0;
6629 return NULL;
6630 }
6631
dd24e3da 6632 /* Run some sanity checks first. */
c9c1d674 6633 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6634 {
c9c1d674 6635 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6636 printable_section_name (filedata, section),
8066deb1 6637 (unsigned long) section->sh_entsize);
ba5cdace 6638 goto exit_point;
dd24e3da
NC
6639 }
6640
dda8d76d 6641 if (section->sh_size > filedata->file_size)
f54498b4
NC
6642 {
6643 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6644 printable_section_name (filedata, section),
8066deb1 6645 (unsigned long) section->sh_size);
f54498b4
NC
6646 goto exit_point;
6647 }
6648
dd24e3da
NC
6649 number = section->sh_size / section->sh_entsize;
6650
6651 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6652 {
c9c1d674 6653 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6654 (unsigned long) section->sh_size,
dda8d76d 6655 printable_section_name (filedata, section),
8066deb1 6656 (unsigned long) section->sh_entsize);
ba5cdace 6657 goto exit_point;
dd24e3da
NC
6658 }
6659
dda8d76d 6660 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6661 section->sh_size, _("symbols"));
a6e9f9df 6662 if (!esyms)
ba5cdace 6663 goto exit_point;
9ea033b2 6664
e3d39609 6665 shndx = NULL;
978c4450 6666 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6667 {
6668 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6669 continue;
6670
6671 if (shndx != NULL)
6672 {
6673 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6674 free (shndx);
c9c1d674 6675 }
e3d39609
NC
6676
6677 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6678 entry->hdr->sh_offset,
6679 1, entry->hdr->sh_size,
6680 _("symbol table section indices"));
6681 if (shndx == NULL)
6682 goto exit_point;
6683
6684 /* PR17531: file: heap-buffer-overflow */
6685 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6686 {
6687 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6688 printable_section_name (filedata, entry->hdr),
6689 (unsigned long) entry->hdr->sh_size,
6690 (unsigned long) section->sh_size);
6691 goto exit_point;
6692 }
6693 }
9ad5cbcf 6694
3f5e193b 6695 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6696
6697 if (isyms == NULL)
6698 {
8b73c356
NC
6699 error (_("Out of memory reading %lu symbols\n"),
6700 (unsigned long) number);
ba5cdace 6701 goto exit_point;
9ea033b2
NC
6702 }
6703
ba5cdace 6704 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6705 {
6706 psym->st_name = BYTE_GET (esyms[j].st_name);
6707 psym->st_info = BYTE_GET (esyms[j].st_info);
6708 psym->st_other = BYTE_GET (esyms[j].st_other);
6709 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6710
4fbb74a6 6711 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6712 psym->st_shndx
6713 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6714 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6715 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6716
66543521
AM
6717 psym->st_value = BYTE_GET (esyms[j].st_value);
6718 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6719 }
6720
ba5cdace 6721 exit_point:
e3d39609
NC
6722 free (shndx);
6723 free (esyms);
ba5cdace
NC
6724
6725 if (num_syms_return != NULL)
6726 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6727
6728 return isyms;
6729}
6730
4de91c10
AM
6731static Elf_Internal_Sym *
6732get_elf_symbols (Filedata *filedata,
6733 Elf_Internal_Shdr *section,
6734 unsigned long *num_syms_return)
6735{
6736 if (is_32bit_elf)
6737 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6738 else
6739 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6740}
6741
d1133906 6742static const char *
625d49fc 6743get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6744{
5477e8a0 6745 static char buff[1024];
2cf0635d 6746 char * p = buff;
32ec8896
NC
6747 unsigned int field_size = is_32bit_elf ? 8 : 16;
6748 signed int sindex;
6749 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6750 uint64_t os_flags = 0;
6751 uint64_t proc_flags = 0;
6752 uint64_t unknown_flags = 0;
148b93f2 6753 static const struct
5477e8a0 6754 {
2cf0635d 6755 const char * str;
32ec8896 6756 unsigned int len;
5477e8a0
L
6757 }
6758 flags [] =
6759 {
cfcac11d
NC
6760 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6761 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6762 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6763 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6764 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6765 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6766 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6767 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6768 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6769 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6770 /* IA-64 specific. */
6771 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6772 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6773 /* IA-64 OpenVMS specific. */
6774 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6775 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6776 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6777 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6778 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6779 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6780 /* Generic. */
cfcac11d 6781 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6782 /* SPARC specific. */
77115a4a 6783 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6784 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6785 /* ARM specific. */
6786 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6787 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6788 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6789 /* GNU specific. */
6790 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6791 /* VLE specific. */
6792 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6793 /* GNU specific. */
6794 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6795 };
6796
6797 if (do_section_details)
6798 {
8d5ff12c
L
6799 sprintf (buff, "[%*.*lx]: ",
6800 field_size, field_size, (unsigned long) sh_flags);
6801 p += field_size + 4;
5477e8a0 6802 }
76da6bbe 6803
d1133906
NC
6804 while (sh_flags)
6805 {
625d49fc 6806 uint64_t flag;
d1133906
NC
6807
6808 flag = sh_flags & - sh_flags;
6809 sh_flags &= ~ flag;
76da6bbe 6810
5477e8a0 6811 if (do_section_details)
d1133906 6812 {
5477e8a0
L
6813 switch (flag)
6814 {
91d6fa6a
NC
6815 case SHF_WRITE: sindex = 0; break;
6816 case SHF_ALLOC: sindex = 1; break;
6817 case SHF_EXECINSTR: sindex = 2; break;
6818 case SHF_MERGE: sindex = 3; break;
6819 case SHF_STRINGS: sindex = 4; break;
6820 case SHF_INFO_LINK: sindex = 5; break;
6821 case SHF_LINK_ORDER: sindex = 6; break;
6822 case SHF_OS_NONCONFORMING: sindex = 7; break;
6823 case SHF_GROUP: sindex = 8; break;
6824 case SHF_TLS: sindex = 9; break;
18ae9cc1 6825 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6826 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6827
5477e8a0 6828 default:
91d6fa6a 6829 sindex = -1;
dda8d76d 6830 switch (filedata->file_header.e_machine)
148b93f2 6831 {
cfcac11d 6832 case EM_IA_64:
148b93f2 6833 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6834 sindex = 10;
148b93f2 6835 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6836 sindex = 11;
dda8d76d 6837 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6838 switch (flag)
6839 {
91d6fa6a
NC
6840 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6841 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6842 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6843 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6844 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6845 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6846 default: break;
6847 }
cfcac11d
NC
6848 break;
6849
caa83f8b 6850 case EM_386:
22abe556 6851 case EM_IAMCU:
caa83f8b 6852 case EM_X86_64:
7f502d6c 6853 case EM_L1OM:
7a9068fe 6854 case EM_K1OM:
cfcac11d
NC
6855 case EM_OLD_SPARCV9:
6856 case EM_SPARC32PLUS:
6857 case EM_SPARCV9:
6858 case EM_SPARC:
18ae9cc1 6859 if (flag == SHF_ORDERED)
91d6fa6a 6860 sindex = 19;
cfcac11d 6861 break;
ac4c9b04
MG
6862
6863 case EM_ARM:
6864 switch (flag)
6865 {
6866 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6867 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6868 case SHF_COMDEF: sindex = 23; break;
6869 default: break;
6870 }
6871 break;
83eef883
AFB
6872 case EM_PPC:
6873 if (flag == SHF_PPC_VLE)
6874 sindex = 25;
6875 break;
99fabbc9
JL
6876 default:
6877 break;
6878 }
ac4c9b04 6879
99fabbc9
JL
6880 switch (filedata->file_header.e_ident[EI_OSABI])
6881 {
6882 case ELFOSABI_GNU:
6883 case ELFOSABI_FREEBSD:
6884 if (flag == SHF_GNU_RETAIN)
6885 sindex = 26;
6886 /* Fall through */
6887 case ELFOSABI_NONE:
6888 if (flag == SHF_GNU_MBIND)
6889 /* We should not recognize SHF_GNU_MBIND for
6890 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6891 not set the EI_OSABI header byte. */
6892 sindex = 24;
6893 break;
cfcac11d
NC
6894 default:
6895 break;
148b93f2 6896 }
99fabbc9 6897 break;
5477e8a0
L
6898 }
6899
91d6fa6a 6900 if (sindex != -1)
5477e8a0 6901 {
8d5ff12c
L
6902 if (p != buff + field_size + 4)
6903 {
6904 if (size < (10 + 2))
bee0ee85
NC
6905 {
6906 warn (_("Internal error: not enough buffer room for section flag info"));
6907 return _("<unknown>");
6908 }
8d5ff12c
L
6909 size -= 2;
6910 *p++ = ',';
6911 *p++ = ' ';
6912 }
6913
91d6fa6a
NC
6914 size -= flags [sindex].len;
6915 p = stpcpy (p, flags [sindex].str);
5477e8a0 6916 }
3b22753a 6917 else if (flag & SHF_MASKOS)
8d5ff12c 6918 os_flags |= flag;
d1133906 6919 else if (flag & SHF_MASKPROC)
8d5ff12c 6920 proc_flags |= flag;
d1133906 6921 else
8d5ff12c 6922 unknown_flags |= flag;
5477e8a0
L
6923 }
6924 else
6925 {
6926 switch (flag)
6927 {
6928 case SHF_WRITE: *p = 'W'; break;
6929 case SHF_ALLOC: *p = 'A'; break;
6930 case SHF_EXECINSTR: *p = 'X'; break;
6931 case SHF_MERGE: *p = 'M'; break;
6932 case SHF_STRINGS: *p = 'S'; break;
6933 case SHF_INFO_LINK: *p = 'I'; break;
6934 case SHF_LINK_ORDER: *p = 'L'; break;
6935 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6936 case SHF_GROUP: *p = 'G'; break;
6937 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6938 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6939 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6940
6941 default:
dda8d76d
NC
6942 if ((filedata->file_header.e_machine == EM_X86_64
6943 || filedata->file_header.e_machine == EM_L1OM
6944 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6945 && flag == SHF_X86_64_LARGE)
6946 *p = 'l';
dda8d76d 6947 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6948 && flag == SHF_ARM_PURECODE)
99fabbc9 6949 *p = 'y';
dda8d76d 6950 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6951 && flag == SHF_PPC_VLE)
99fabbc9 6952 *p = 'v';
5477e8a0
L
6953 else if (flag & SHF_MASKOS)
6954 {
99fabbc9
JL
6955 switch (filedata->file_header.e_ident[EI_OSABI])
6956 {
6957 case ELFOSABI_GNU:
6958 case ELFOSABI_FREEBSD:
6959 if (flag == SHF_GNU_RETAIN)
6960 {
6961 *p = 'R';
6962 break;
6963 }
6964 /* Fall through */
6965 case ELFOSABI_NONE:
6966 if (flag == SHF_GNU_MBIND)
6967 {
6968 /* We should not recognize SHF_GNU_MBIND for
6969 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6970 not set the EI_OSABI header byte. */
6971 *p = 'D';
6972 break;
6973 }
6974 /* Fall through */
6975 default:
6976 *p = 'o';
6977 sh_flags &= ~SHF_MASKOS;
6978 break;
6979 }
5477e8a0
L
6980 }
6981 else if (flag & SHF_MASKPROC)
6982 {
6983 *p = 'p';
6984 sh_flags &= ~ SHF_MASKPROC;
6985 }
6986 else
6987 *p = 'x';
6988 break;
6989 }
6990 p++;
d1133906
NC
6991 }
6992 }
76da6bbe 6993
8d5ff12c
L
6994 if (do_section_details)
6995 {
6996 if (os_flags)
6997 {
6998 size -= 5 + field_size;
6999 if (p != buff + field_size + 4)
7000 {
7001 if (size < (2 + 1))
bee0ee85
NC
7002 {
7003 warn (_("Internal error: not enough buffer room for section flag info"));
7004 return _("<unknown>");
7005 }
8d5ff12c
L
7006 size -= 2;
7007 *p++ = ',';
7008 *p++ = ' ';
7009 }
7010 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7011 (unsigned long) os_flags);
7012 p += 5 + field_size;
7013 }
7014 if (proc_flags)
7015 {
7016 size -= 7 + field_size;
7017 if (p != buff + field_size + 4)
7018 {
7019 if (size < (2 + 1))
bee0ee85
NC
7020 {
7021 warn (_("Internal error: not enough buffer room for section flag info"));
7022 return _("<unknown>");
7023 }
8d5ff12c
L
7024 size -= 2;
7025 *p++ = ',';
7026 *p++ = ' ';
7027 }
7028 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7029 (unsigned long) proc_flags);
7030 p += 7 + field_size;
7031 }
7032 if (unknown_flags)
7033 {
7034 size -= 10 + field_size;
7035 if (p != buff + field_size + 4)
7036 {
7037 if (size < (2 + 1))
bee0ee85
NC
7038 {
7039 warn (_("Internal error: not enough buffer room for section flag info"));
7040 return _("<unknown>");
7041 }
8d5ff12c
L
7042 size -= 2;
7043 *p++ = ',';
7044 *p++ = ' ';
7045 }
2b692964 7046 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7047 (unsigned long) unknown_flags);
7048 p += 10 + field_size;
7049 }
7050 }
7051
e9e44622 7052 *p = '\0';
d1133906
NC
7053 return buff;
7054}
7055
5844b465 7056static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7057get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7058 uint64_t size)
77115a4a
L
7059{
7060 if (is_32bit_elf)
7061 {
7062 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7063
ebdf1ebf
NC
7064 if (size < sizeof (* echdr))
7065 {
7066 error (_("Compressed section is too small even for a compression header\n"));
7067 return 0;
7068 }
7069
77115a4a
L
7070 chdr->ch_type = BYTE_GET (echdr->ch_type);
7071 chdr->ch_size = BYTE_GET (echdr->ch_size);
7072 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7073 return sizeof (*echdr);
7074 }
7075 else
7076 {
7077 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7078
ebdf1ebf
NC
7079 if (size < sizeof (* echdr))
7080 {
7081 error (_("Compressed section is too small even for a compression header\n"));
7082 return 0;
7083 }
7084
77115a4a
L
7085 chdr->ch_type = BYTE_GET (echdr->ch_type);
7086 chdr->ch_size = BYTE_GET (echdr->ch_size);
7087 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7088 return sizeof (*echdr);
7089 }
7090}
7091
015dc7e1 7092static bool
dda8d76d 7093process_section_headers (Filedata * filedata)
252b5132 7094{
2cf0635d 7095 Elf_Internal_Shdr * section;
b34976b6 7096 unsigned int i;
252b5132 7097
dda8d76d 7098 if (filedata->file_header.e_shnum == 0)
252b5132 7099 {
82f2dbf7 7100 /* PR binutils/12467. */
dda8d76d 7101 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7102 {
7103 warn (_("possibly corrupt ELF file header - it has a non-zero"
7104 " section header offset, but no section headers\n"));
015dc7e1 7105 return false;
32ec8896 7106 }
82f2dbf7 7107 else if (do_sections)
252b5132
RH
7108 printf (_("\nThere are no sections in this file.\n"));
7109
015dc7e1 7110 return true;
252b5132
RH
7111 }
7112
7113 if (do_sections && !do_header)
ca0e11aa
NC
7114 {
7115 if (filedata->is_separate && process_links)
7116 printf (_("In linked file '%s': "), filedata->file_name);
7117 if (! filedata->is_separate || process_links)
7118 printf (ngettext ("There is %d section header, "
7119 "starting at offset 0x%lx:\n",
7120 "There are %d section headers, "
7121 "starting at offset 0x%lx:\n",
7122 filedata->file_header.e_shnum),
7123 filedata->file_header.e_shnum,
7124 (unsigned long) filedata->file_header.e_shoff);
7125 }
252b5132 7126
4de91c10
AM
7127 if (!get_section_headers (filedata, false))
7128 return false;
252b5132
RH
7129
7130 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7131 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7132 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7133 {
dda8d76d 7134 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7135
c256ffe7
JJ
7136 if (section->sh_size != 0)
7137 {
dda8d76d
NC
7138 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7139 1, section->sh_size,
7140 _("string table"));
0de14b54 7141
dda8d76d 7142 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7143 }
252b5132
RH
7144 }
7145
7146 /* Scan the sections for the dynamic symbol table
e3c8793a 7147 and dynamic string table and debug sections. */
89fac5e3 7148 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7149 switch (filedata->file_header.e_machine)
89fac5e3
RS
7150 {
7151 case EM_MIPS:
7152 case EM_MIPS_RS3_LE:
7153 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7154 FDE addresses. However, the ABI also has a semi-official ILP32
7155 variant for which the normal FDE address size rules apply.
7156
7157 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7158 section, where XX is the size of longs in bits. Unfortunately,
7159 earlier compilers provided no way of distinguishing ILP32 objects
7160 from LP64 objects, so if there's any doubt, we should assume that
7161 the official LP64 form is being used. */
dda8d76d
NC
7162 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7163 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7164 eh_addr_size = 8;
7165 break;
0f56a26a
DD
7166
7167 case EM_H8_300:
7168 case EM_H8_300H:
dda8d76d 7169 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7170 {
7171 case E_H8_MACH_H8300:
7172 case E_H8_MACH_H8300HN:
7173 case E_H8_MACH_H8300SN:
7174 case E_H8_MACH_H8300SXN:
7175 eh_addr_size = 2;
7176 break;
7177 case E_H8_MACH_H8300H:
7178 case E_H8_MACH_H8300S:
7179 case E_H8_MACH_H8300SX:
7180 eh_addr_size = 4;
7181 break;
7182 }
f4236fe4
DD
7183 break;
7184
ff7eeb89 7185 case EM_M32C_OLD:
f4236fe4 7186 case EM_M32C:
dda8d76d 7187 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7188 {
7189 case EF_M32C_CPU_M16C:
7190 eh_addr_size = 2;
7191 break;
7192 }
7193 break;
89fac5e3
RS
7194 }
7195
76ca31c0
NC
7196#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7197 do \
7198 { \
be7d229a 7199 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7200 if (section->sh_entsize != expected_entsize) \
9dd3a467 7201 { \
f493c217 7202 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7203 i, section->sh_entsize); \
f493c217 7204 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7205 expected_entsize); \
9dd3a467 7206 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7207 } \
7208 } \
08d8fa11 7209 while (0)
9dd3a467
NC
7210
7211#define CHECK_ENTSIZE(section, i, type) \
1b513401 7212 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7213 sizeof (Elf64_External_##type))
7214
dda8d76d
NC
7215 for (i = 0, section = filedata->section_headers;
7216 i < filedata->file_header.e_shnum;
b34976b6 7217 i++, section++)
252b5132 7218 {
84714f86 7219 const char *name = section_name_print (filedata, section);
252b5132 7220
1b513401
NC
7221 /* Run some sanity checks on the headers and
7222 possibly fill in some file data as well. */
7223 switch (section->sh_type)
252b5132 7224 {
1b513401 7225 case SHT_DYNSYM:
978c4450 7226 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7227 {
7228 error (_("File contains multiple dynamic symbol tables\n"));
7229 continue;
7230 }
7231
08d8fa11 7232 CHECK_ENTSIZE (section, i, Sym);
978c4450 7233 filedata->dynamic_symbols
4de91c10 7234 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7235 filedata->dynamic_symtab_section = section;
1b513401
NC
7236 break;
7237
7238 case SHT_STRTAB:
7239 if (streq (name, ".dynstr"))
252b5132 7240 {
1b513401
NC
7241 if (filedata->dynamic_strings != NULL)
7242 {
7243 error (_("File contains multiple dynamic string tables\n"));
7244 continue;
7245 }
7246
7247 filedata->dynamic_strings
7248 = (char *) get_data (NULL, filedata, section->sh_offset,
7249 1, section->sh_size, _("dynamic strings"));
7250 filedata->dynamic_strings_length
7251 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7252 filedata->dynamic_strtab_section = section;
252b5132 7253 }
1b513401
NC
7254 break;
7255
7256 case SHT_SYMTAB_SHNDX:
7257 {
7258 elf_section_list * entry = xmalloc (sizeof * entry);
7259
7260 entry->hdr = section;
7261 entry->next = filedata->symtab_shndx_list;
7262 filedata->symtab_shndx_list = entry;
7263 }
7264 break;
7265
7266 case SHT_SYMTAB:
7267 CHECK_ENTSIZE (section, i, Sym);
7268 break;
7269
7270 case SHT_GROUP:
7271 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7272 break;
252b5132 7273
1b513401
NC
7274 case SHT_REL:
7275 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7276 if (do_checks && section->sh_size == 0)
1b513401
NC
7277 warn (_("Section '%s': zero-sized relocation section\n"), name);
7278 break;
7279
7280 case SHT_RELA:
7281 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7282 if (do_checks && section->sh_size == 0)
1b513401
NC
7283 warn (_("Section '%s': zero-sized relocation section\n"), name);
7284 break;
7285
682351b9
AM
7286 case SHT_RELR:
7287 CHECK_ENTSIZE (section, i, Relr);
7288 break;
7289
1b513401
NC
7290 case SHT_NOTE:
7291 case SHT_PROGBITS:
546cb2d8
NC
7292 /* Having a zero sized section is not illegal according to the
7293 ELF standard, but it might be an indication that something
7294 is wrong. So issue a warning if we are running in lint mode. */
7295 if (do_checks && section->sh_size == 0)
1b513401
NC
7296 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7297 break;
7298
7299 default:
7300 break;
7301 }
7302
7303 if ((do_debugging || do_debug_info || do_debug_abbrevs
7304 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7305 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7306 || do_debug_str || do_debug_str_offsets || do_debug_loc
7307 || do_debug_ranges
1b513401 7308 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7309 && (startswith (name, ".debug_")
7310 || startswith (name, ".zdebug_")))
252b5132 7311 {
1b315056
CS
7312 if (name[1] == 'z')
7313 name += sizeof (".zdebug_") - 1;
7314 else
7315 name += sizeof (".debug_") - 1;
252b5132
RH
7316
7317 if (do_debugging
24d127aa
ML
7318 || (do_debug_info && startswith (name, "info"))
7319 || (do_debug_info && startswith (name, "types"))
7320 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7321 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7322 || (do_debug_lines && startswith (name, "line."))
7323 || (do_debug_pubnames && startswith (name, "pubnames"))
7324 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7325 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7326 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7327 || (do_debug_aranges && startswith (name, "aranges"))
7328 || (do_debug_ranges && startswith (name, "ranges"))
7329 || (do_debug_ranges && startswith (name, "rnglists"))
7330 || (do_debug_frames && startswith (name, "frame"))
7331 || (do_debug_macinfo && startswith (name, "macinfo"))
7332 || (do_debug_macinfo && startswith (name, "macro"))
7333 || (do_debug_str && startswith (name, "str"))
7334 || (do_debug_links && startswith (name, "sup"))
7335 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7336 || (do_debug_loc && startswith (name, "loc"))
7337 || (do_debug_loc && startswith (name, "loclists"))
7338 || (do_debug_addr && startswith (name, "addr"))
7339 || (do_debug_cu_index && startswith (name, "cu_index"))
7340 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7341 )
6431e409 7342 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7343 }
a262ae96 7344 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7345 else if ((do_debugging || do_debug_info)
24d127aa 7346 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7347 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7348 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7349 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7350 else if (do_gdb_index && (streq (name, ".gdb_index")
7351 || streq (name, ".debug_names")))
6431e409 7352 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7353 /* Trace sections for Itanium VMS. */
7354 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7355 || do_trace_aranges)
24d127aa 7356 && startswith (name, ".trace_"))
6f875884
TG
7357 {
7358 name += sizeof (".trace_") - 1;
7359
7360 if (do_debugging
7361 || (do_trace_info && streq (name, "info"))
7362 || (do_trace_abbrevs && streq (name, "abbrev"))
7363 || (do_trace_aranges && streq (name, "aranges"))
7364 )
6431e409 7365 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7366 }
dda8d76d 7367 else if ((do_debugging || do_debug_links)
24d127aa
ML
7368 && (startswith (name, ".gnu_debuglink")
7369 || startswith (name, ".gnu_debugaltlink")))
6431e409 7370 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7371 }
7372
7373 if (! do_sections)
015dc7e1 7374 return true;
252b5132 7375
ca0e11aa 7376 if (filedata->is_separate && ! process_links)
015dc7e1 7377 return true;
ca0e11aa
NC
7378
7379 if (filedata->is_separate)
7380 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7381 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7382 printf (_("\nSection Headers:\n"));
7383 else
7384 printf (_("\nSection Header:\n"));
76da6bbe 7385
f7a99963 7386 if (is_32bit_elf)
595cf52e 7387 {
5477e8a0 7388 if (do_section_details)
595cf52e
L
7389 {
7390 printf (_(" [Nr] Name\n"));
5477e8a0 7391 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7392 }
7393 else
7394 printf
7395 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7396 }
d974e256 7397 else if (do_wide)
595cf52e 7398 {
5477e8a0 7399 if (do_section_details)
595cf52e
L
7400 {
7401 printf (_(" [Nr] Name\n"));
5477e8a0 7402 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7403 }
7404 else
7405 printf
7406 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7407 }
f7a99963
NC
7408 else
7409 {
5477e8a0 7410 if (do_section_details)
595cf52e
L
7411 {
7412 printf (_(" [Nr] Name\n"));
5477e8a0
L
7413 printf (_(" Type Address Offset Link\n"));
7414 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7415 }
7416 else
7417 {
7418 printf (_(" [Nr] Name Type Address Offset\n"));
7419 printf (_(" Size EntSize Flags Link Info Align\n"));
7420 }
f7a99963 7421 }
252b5132 7422
5477e8a0
L
7423 if (do_section_details)
7424 printf (_(" Flags\n"));
7425
dda8d76d
NC
7426 for (i = 0, section = filedata->section_headers;
7427 i < filedata->file_header.e_shnum;
b34976b6 7428 i++, section++)
252b5132 7429 {
dd905818
NC
7430 /* Run some sanity checks on the section header. */
7431
7432 /* Check the sh_link field. */
7433 switch (section->sh_type)
7434 {
285e3f99
AM
7435 case SHT_REL:
7436 case SHT_RELA:
7437 if (section->sh_link == 0
7438 && (filedata->file_header.e_type == ET_EXEC
7439 || filedata->file_header.e_type == ET_DYN))
7440 /* A dynamic relocation section where all entries use a
7441 zero symbol index need not specify a symtab section. */
7442 break;
7443 /* Fall through. */
dd905818
NC
7444 case SHT_SYMTAB_SHNDX:
7445 case SHT_GROUP:
7446 case SHT_HASH:
7447 case SHT_GNU_HASH:
7448 case SHT_GNU_versym:
285e3f99 7449 if (section->sh_link == 0
dda8d76d
NC
7450 || section->sh_link >= filedata->file_header.e_shnum
7451 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7452 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7453 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7454 i, section->sh_link);
7455 break;
7456
7457 case SHT_DYNAMIC:
7458 case SHT_SYMTAB:
7459 case SHT_DYNSYM:
7460 case SHT_GNU_verneed:
7461 case SHT_GNU_verdef:
7462 case SHT_GNU_LIBLIST:
285e3f99 7463 if (section->sh_link == 0
dda8d76d
NC
7464 || section->sh_link >= filedata->file_header.e_shnum
7465 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7466 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7467 i, section->sh_link);
7468 break;
7469
7470 case SHT_INIT_ARRAY:
7471 case SHT_FINI_ARRAY:
7472 case SHT_PREINIT_ARRAY:
7473 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7474 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7475 i, section->sh_link);
7476 break;
7477
7478 default:
7479 /* FIXME: Add support for target specific section types. */
7480#if 0 /* Currently we do not check other section types as there are too
7481 many special cases. Stab sections for example have a type
7482 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7483 section. */
7484 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7485 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7486 i, section->sh_link);
7487#endif
7488 break;
7489 }
7490
7491 /* Check the sh_info field. */
7492 switch (section->sh_type)
7493 {
7494 case SHT_REL:
7495 case SHT_RELA:
285e3f99
AM
7496 if (section->sh_info == 0
7497 && (filedata->file_header.e_type == ET_EXEC
7498 || filedata->file_header.e_type == ET_DYN))
7499 /* Dynamic relocations apply to segments, so they do not
7500 need to specify the section they relocate. */
7501 break;
7502 if (section->sh_info == 0
dda8d76d
NC
7503 || section->sh_info >= filedata->file_header.e_shnum
7504 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7505 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7506 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7507 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7508 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7509 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7510 /* FIXME: Are other section types valid ? */
dda8d76d 7511 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7512 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7513 i, section->sh_info);
dd905818
NC
7514 break;
7515
7516 case SHT_DYNAMIC:
7517 case SHT_HASH:
7518 case SHT_SYMTAB_SHNDX:
7519 case SHT_INIT_ARRAY:
7520 case SHT_FINI_ARRAY:
7521 case SHT_PREINIT_ARRAY:
7522 if (section->sh_info != 0)
7523 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7524 i, section->sh_info);
7525 break;
7526
7527 case SHT_GROUP:
7528 case SHT_SYMTAB:
7529 case SHT_DYNSYM:
7530 /* A symbol index - we assume that it is valid. */
7531 break;
7532
7533 default:
7534 /* FIXME: Add support for target specific section types. */
7535 if (section->sh_type == SHT_NOBITS)
7536 /* NOBITS section headers with non-zero sh_info fields can be
7537 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7538 information. The stripped sections have their headers
7539 preserved but their types set to SHT_NOBITS. So do not check
7540 this type of section. */
dd905818
NC
7541 ;
7542 else if (section->sh_flags & SHF_INFO_LINK)
7543 {
dda8d76d 7544 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7545 warn (_("[%2u]: Expected link to another section in info field"), i);
7546 }
a91e1603
L
7547 else if (section->sh_type < SHT_LOOS
7548 && (section->sh_flags & SHF_GNU_MBIND) == 0
7549 && section->sh_info != 0)
dd905818
NC
7550 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7551 i, section->sh_info);
7552 break;
7553 }
7554
3e6b6445 7555 /* Check the sh_size field. */
dda8d76d 7556 if (section->sh_size > filedata->file_size
3e6b6445
NC
7557 && section->sh_type != SHT_NOBITS
7558 && section->sh_type != SHT_NULL
7559 && section->sh_type < SHT_LOOS)
7560 warn (_("Size of section %u is larger than the entire file!\n"), i);
7561
7bfd842d 7562 printf (" [%2u] ", i);
5477e8a0 7563 if (do_section_details)
dda8d76d 7564 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7565 else
84714f86 7566 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7567
ea52a088 7568 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7569 get_section_type_name (filedata, section->sh_type));
0b4362b0 7570
f7a99963
NC
7571 if (is_32bit_elf)
7572 {
cfcac11d
NC
7573 const char * link_too_big = NULL;
7574
f7a99963 7575 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7576
f7a99963
NC
7577 printf ( " %6.6lx %6.6lx %2.2lx",
7578 (unsigned long) section->sh_offset,
7579 (unsigned long) section->sh_size,
7580 (unsigned long) section->sh_entsize);
d1133906 7581
5477e8a0
L
7582 if (do_section_details)
7583 fputs (" ", stdout);
7584 else
dda8d76d 7585 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7586
dda8d76d 7587 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7588 {
7589 link_too_big = "";
7590 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7591 an error but it can have special values in Solaris binaries. */
dda8d76d 7592 switch (filedata->file_header.e_machine)
cfcac11d 7593 {
caa83f8b 7594 case EM_386:
22abe556 7595 case EM_IAMCU:
caa83f8b 7596 case EM_X86_64:
7f502d6c 7597 case EM_L1OM:
7a9068fe 7598 case EM_K1OM:
cfcac11d
NC
7599 case EM_OLD_SPARCV9:
7600 case EM_SPARC32PLUS:
7601 case EM_SPARCV9:
7602 case EM_SPARC:
7603 if (section->sh_link == (SHN_BEFORE & 0xffff))
7604 link_too_big = "BEFORE";
7605 else if (section->sh_link == (SHN_AFTER & 0xffff))
7606 link_too_big = "AFTER";
7607 break;
7608 default:
7609 break;
7610 }
7611 }
7612
7613 if (do_section_details)
7614 {
7615 if (link_too_big != NULL && * link_too_big)
7616 printf ("<%s> ", link_too_big);
7617 else
7618 printf ("%2u ", section->sh_link);
7619 printf ("%3u %2lu\n", section->sh_info,
7620 (unsigned long) section->sh_addralign);
7621 }
7622 else
7623 printf ("%2u %3u %2lu\n",
7624 section->sh_link,
7625 section->sh_info,
7626 (unsigned long) section->sh_addralign);
7627
7628 if (link_too_big && ! * link_too_big)
7629 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7630 i, section->sh_link);
f7a99963 7631 }
d974e256
JJ
7632 else if (do_wide)
7633 {
7634 print_vma (section->sh_addr, LONG_HEX);
7635
7636 if ((long) section->sh_offset == section->sh_offset)
7637 printf (" %6.6lx", (unsigned long) section->sh_offset);
7638 else
7639 {
7640 putchar (' ');
7641 print_vma (section->sh_offset, LONG_HEX);
7642 }
7643
7644 if ((unsigned long) section->sh_size == section->sh_size)
7645 printf (" %6.6lx", (unsigned long) section->sh_size);
7646 else
7647 {
7648 putchar (' ');
7649 print_vma (section->sh_size, LONG_HEX);
7650 }
7651
7652 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7653 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7654 else
7655 {
7656 putchar (' ');
7657 print_vma (section->sh_entsize, LONG_HEX);
7658 }
7659
5477e8a0
L
7660 if (do_section_details)
7661 fputs (" ", stdout);
7662 else
dda8d76d 7663 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7664
72de5009 7665 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7666
7667 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7668 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7669 else
7670 {
7671 print_vma (section->sh_addralign, DEC);
7672 putchar ('\n');
7673 }
7674 }
5477e8a0 7675 else if (do_section_details)
595cf52e 7676 {
55cc53e9 7677 putchar (' ');
595cf52e
L
7678 print_vma (section->sh_addr, LONG_HEX);
7679 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7680 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7681 else
7682 {
7683 printf (" ");
7684 print_vma (section->sh_offset, LONG_HEX);
7685 }
72de5009 7686 printf (" %u\n ", section->sh_link);
595cf52e 7687 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7688 putchar (' ');
595cf52e
L
7689 print_vma (section->sh_entsize, LONG_HEX);
7690
72de5009
AM
7691 printf (" %-16u %lu\n",
7692 section->sh_info,
595cf52e
L
7693 (unsigned long) section->sh_addralign);
7694 }
f7a99963
NC
7695 else
7696 {
7697 putchar (' ');
7698 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7699 if ((long) section->sh_offset == section->sh_offset)
7700 printf (" %8.8lx", (unsigned long) section->sh_offset);
7701 else
7702 {
7703 printf (" ");
7704 print_vma (section->sh_offset, LONG_HEX);
7705 }
f7a99963
NC
7706 printf ("\n ");
7707 print_vma (section->sh_size, LONG_HEX);
7708 printf (" ");
7709 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7710
dda8d76d 7711 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7712
72de5009
AM
7713 printf (" %2u %3u %lu\n",
7714 section->sh_link,
7715 section->sh_info,
f7a99963
NC
7716 (unsigned long) section->sh_addralign);
7717 }
5477e8a0
L
7718
7719 if (do_section_details)
77115a4a 7720 {
dda8d76d 7721 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7722 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7723 {
7724 /* Minimum section size is 12 bytes for 32-bit compression
7725 header + 12 bytes for compressed data header. */
7726 unsigned char buf[24];
d8024a91 7727
77115a4a 7728 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7729 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7730 sizeof (buf), _("compression header")))
7731 {
7732 Elf_Internal_Chdr chdr;
d8024a91 7733
5844b465
NC
7734 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7735 printf (_(" [<corrupt>]\n"));
77115a4a 7736 else
5844b465
NC
7737 {
7738 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7739 printf (" ZLIB, ");
1369522f
CC
7740 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7741 printf (" ZSTD, ");
5844b465
NC
7742 else
7743 printf (_(" [<unknown>: 0x%x], "),
7744 chdr.ch_type);
7745 print_vma (chdr.ch_size, LONG_HEX);
7746 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7747 }
77115a4a
L
7748 }
7749 }
7750 }
252b5132
RH
7751 }
7752
5477e8a0 7753 if (!do_section_details)
3dbcc61d 7754 {
9fb71ee4
NC
7755 /* The ordering of the letters shown here matches the ordering of the
7756 corresponding SHF_xxx values, and hence the order in which these
7757 letters will be displayed to the user. */
7758 printf (_("Key to Flags:\n\
7759 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7760 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7761 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7762 switch (filedata->file_header.e_ident[EI_OSABI])
7763 {
7764 case ELFOSABI_GNU:
7765 case ELFOSABI_FREEBSD:
7766 printf (_("R (retain), "));
7767 /* Fall through */
7768 case ELFOSABI_NONE:
7769 printf (_("D (mbind), "));
7770 break;
7771 default:
7772 break;
7773 }
dda8d76d
NC
7774 if (filedata->file_header.e_machine == EM_X86_64
7775 || filedata->file_header.e_machine == EM_L1OM
7776 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7777 printf (_("l (large), "));
dda8d76d 7778 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7779 printf (_("y (purecode), "));
dda8d76d 7780 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7781 printf (_("v (VLE), "));
9fb71ee4 7782 printf ("p (processor specific)\n");
0b4362b0 7783 }
d1133906 7784
015dc7e1 7785 return true;
252b5132
RH
7786}
7787
015dc7e1 7788static bool
28d13567
AM
7789get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7790 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7791 char **strtab, unsigned long *strtablen)
7792{
7793 *strtab = NULL;
7794 *strtablen = 0;
4de91c10 7795 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7796
7797 if (*symtab == NULL)
015dc7e1 7798 return false;
28d13567
AM
7799
7800 if (symsec->sh_link != 0)
7801 {
7802 Elf_Internal_Shdr *strsec;
7803
7804 if (symsec->sh_link >= filedata->file_header.e_shnum)
7805 {
7806 error (_("Bad sh_link in symbol table section\n"));
7807 free (*symtab);
7808 *symtab = NULL;
7809 *nsyms = 0;
015dc7e1 7810 return false;
28d13567
AM
7811 }
7812
7813 strsec = filedata->section_headers + symsec->sh_link;
7814
7815 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7816 1, strsec->sh_size, _("string table"));
7817 if (*strtab == NULL)
7818 {
7819 free (*symtab);
7820 *symtab = NULL;
7821 *nsyms = 0;
015dc7e1 7822 return false;
28d13567
AM
7823 }
7824 *strtablen = strsec->sh_size;
7825 }
015dc7e1 7826 return true;
28d13567
AM
7827}
7828
f5842774
L
7829static const char *
7830get_group_flags (unsigned int flags)
7831{
1449284b 7832 static char buff[128];
220453ec 7833
6d913794
NC
7834 if (flags == 0)
7835 return "";
7836 else if (flags == GRP_COMDAT)
7837 return "COMDAT ";
f5842774 7838
89246a0e
AM
7839 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7840 flags,
7841 flags & GRP_MASKOS ? _("<OS specific>") : "",
7842 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7843 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7844 ? _("<unknown>") : ""));
6d913794 7845
f5842774
L
7846 return buff;
7847}
7848
015dc7e1 7849static bool
dda8d76d 7850process_section_groups (Filedata * filedata)
f5842774 7851{
2cf0635d 7852 Elf_Internal_Shdr * section;
f5842774 7853 unsigned int i;
2cf0635d
NC
7854 struct group * group;
7855 Elf_Internal_Shdr * symtab_sec;
7856 Elf_Internal_Shdr * strtab_sec;
7857 Elf_Internal_Sym * symtab;
ba5cdace 7858 unsigned long num_syms;
2cf0635d 7859 char * strtab;
c256ffe7 7860 size_t strtab_size;
d1f5c6e3
L
7861
7862 /* Don't process section groups unless needed. */
7863 if (!do_unwind && !do_section_groups)
015dc7e1 7864 return true;
f5842774 7865
dda8d76d 7866 if (filedata->file_header.e_shnum == 0)
f5842774
L
7867 {
7868 if (do_section_groups)
ca0e11aa
NC
7869 {
7870 if (filedata->is_separate)
7871 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7872 filedata->file_name);
7873 else
7874 printf (_("\nThere are no section groups in this file.\n"));
7875 }
015dc7e1 7876 return true;
f5842774
L
7877 }
7878
dda8d76d 7879 if (filedata->section_headers == NULL)
f5842774
L
7880 {
7881 error (_("Section headers are not available!\n"));
fa1908fd 7882 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7883 return false;
f5842774
L
7884 }
7885
978c4450
AM
7886 filedata->section_headers_groups
7887 = (struct group **) calloc (filedata->file_header.e_shnum,
7888 sizeof (struct group *));
e4b17d5c 7889
978c4450 7890 if (filedata->section_headers_groups == NULL)
e4b17d5c 7891 {
8b73c356 7892 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7893 filedata->file_header.e_shnum);
015dc7e1 7894 return false;
e4b17d5c
L
7895 }
7896
f5842774 7897 /* Scan the sections for the group section. */
978c4450 7898 filedata->group_count = 0;
dda8d76d
NC
7899 for (i = 0, section = filedata->section_headers;
7900 i < filedata->file_header.e_shnum;
f5842774 7901 i++, section++)
e4b17d5c 7902 if (section->sh_type == SHT_GROUP)
978c4450 7903 filedata->group_count++;
e4b17d5c 7904
978c4450 7905 if (filedata->group_count == 0)
d1f5c6e3
L
7906 {
7907 if (do_section_groups)
ca0e11aa
NC
7908 {
7909 if (filedata->is_separate)
7910 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7911 filedata->file_name);
7912 else
7913 printf (_("\nThere are no section groups in this file.\n"));
7914 }
d1f5c6e3 7915
015dc7e1 7916 return true;
d1f5c6e3
L
7917 }
7918
978c4450
AM
7919 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7920 sizeof (struct group));
e4b17d5c 7921
978c4450 7922 if (filedata->section_groups == NULL)
e4b17d5c 7923 {
8b73c356 7924 error (_("Out of memory reading %lu groups\n"),
978c4450 7925 (unsigned long) filedata->group_count);
015dc7e1 7926 return false;
e4b17d5c
L
7927 }
7928
d1f5c6e3
L
7929 symtab_sec = NULL;
7930 strtab_sec = NULL;
7931 symtab = NULL;
ba5cdace 7932 num_syms = 0;
d1f5c6e3 7933 strtab = NULL;
c256ffe7 7934 strtab_size = 0;
ca0e11aa
NC
7935
7936 if (filedata->is_separate)
7937 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7938
978c4450 7939 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7940 i < filedata->file_header.e_shnum;
e4b17d5c 7941 i++, section++)
f5842774
L
7942 {
7943 if (section->sh_type == SHT_GROUP)
7944 {
dda8d76d 7945 const char * name = printable_section_name (filedata, section);
74e1a04b 7946 const char * group_name;
2cf0635d
NC
7947 unsigned char * start;
7948 unsigned char * indices;
f5842774 7949 unsigned int entry, j, size;
2cf0635d
NC
7950 Elf_Internal_Shdr * sec;
7951 Elf_Internal_Sym * sym;
f5842774
L
7952
7953 /* Get the symbol table. */
dda8d76d
NC
7954 if (section->sh_link >= filedata->file_header.e_shnum
7955 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7956 != SHT_SYMTAB))
f5842774
L
7957 {
7958 error (_("Bad sh_link in group section `%s'\n"), name);
7959 continue;
7960 }
d1f5c6e3
L
7961
7962 if (symtab_sec != sec)
7963 {
7964 symtab_sec = sec;
9db70fc3 7965 free (symtab);
4de91c10 7966 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7967 }
f5842774 7968
dd24e3da
NC
7969 if (symtab == NULL)
7970 {
7971 error (_("Corrupt header in group section `%s'\n"), name);
7972 continue;
7973 }
7974
ba5cdace
NC
7975 if (section->sh_info >= num_syms)
7976 {
7977 error (_("Bad sh_info in group section `%s'\n"), name);
7978 continue;
7979 }
7980
f5842774
L
7981 sym = symtab + section->sh_info;
7982
7983 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7984 {
4fbb74a6 7985 if (sym->st_shndx == 0
dda8d76d 7986 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7987 {
7988 error (_("Bad sh_info in group section `%s'\n"), name);
7989 continue;
7990 }
ba2685cc 7991
84714f86
AM
7992 group_name = section_name_print (filedata,
7993 filedata->section_headers
b9e920ec 7994 + sym->st_shndx);
c256ffe7 7995 strtab_sec = NULL;
9db70fc3 7996 free (strtab);
f5842774 7997 strtab = NULL;
c256ffe7 7998 strtab_size = 0;
f5842774
L
7999 }
8000 else
8001 {
8002 /* Get the string table. */
dda8d76d 8003 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8004 {
8005 strtab_sec = NULL;
9db70fc3 8006 free (strtab);
c256ffe7
JJ
8007 strtab = NULL;
8008 strtab_size = 0;
8009 }
8010 else if (strtab_sec
dda8d76d 8011 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8012 {
8013 strtab_sec = sec;
9db70fc3 8014 free (strtab);
071436c6 8015
dda8d76d 8016 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8017 1, strtab_sec->sh_size,
8018 _("string table"));
c256ffe7 8019 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8020 }
c256ffe7 8021 group_name = sym->st_name < strtab_size
2b692964 8022 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8023 }
8024
c9c1d674
EG
8025 /* PR 17531: file: loop. */
8026 if (section->sh_entsize > section->sh_size)
8027 {
8028 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8029 printable_section_name (filedata, section),
8066deb1
AM
8030 (unsigned long) section->sh_entsize,
8031 (unsigned long) section->sh_size);
61dd8e19 8032 continue;
c9c1d674
EG
8033 }
8034
dda8d76d 8035 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8036 1, section->sh_size,
8037 _("section data"));
59245841
NC
8038 if (start == NULL)
8039 continue;
f5842774
L
8040
8041 indices = start;
8042 size = (section->sh_size / section->sh_entsize) - 1;
8043 entry = byte_get (indices, 4);
8044 indices += 4;
e4b17d5c
L
8045
8046 if (do_section_groups)
8047 {
2b692964 8048 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8049 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8050
e4b17d5c
L
8051 printf (_(" [Index] Name\n"));
8052 }
8053
8054 group->group_index = i;
8055
f5842774
L
8056 for (j = 0; j < size; j++)
8057 {
2cf0635d 8058 struct group_list * g;
e4b17d5c 8059
f5842774
L
8060 entry = byte_get (indices, 4);
8061 indices += 4;
8062
dda8d76d 8063 if (entry >= filedata->file_header.e_shnum)
391cb864 8064 {
57028622
NC
8065 static unsigned num_group_errors = 0;
8066
8067 if (num_group_errors ++ < 10)
8068 {
8069 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8070 entry, i, filedata->file_header.e_shnum - 1);
57028622 8071 if (num_group_errors == 10)
67ce483b 8072 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8073 }
391cb864
L
8074 continue;
8075 }
391cb864 8076
978c4450 8077 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8078 {
d1f5c6e3
L
8079 if (entry)
8080 {
57028622
NC
8081 static unsigned num_errs = 0;
8082
8083 if (num_errs ++ < 10)
8084 {
8085 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8086 entry, i,
978c4450 8087 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8088 if (num_errs == 10)
8089 warn (_("Further error messages about already contained group sections suppressed\n"));
8090 }
d1f5c6e3
L
8091 continue;
8092 }
8093 else
8094 {
8095 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8096 section group. We just warn it the first time
d1f5c6e3 8097 and ignore it afterwards. */
015dc7e1 8098 static bool warned = false;
d1f5c6e3
L
8099 if (!warned)
8100 {
8101 error (_("section 0 in group section [%5u]\n"),
978c4450 8102 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8103 warned = true;
d1f5c6e3
L
8104 }
8105 }
e4b17d5c
L
8106 }
8107
978c4450 8108 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8109
8110 if (do_section_groups)
8111 {
dda8d76d
NC
8112 sec = filedata->section_headers + entry;
8113 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8114 }
8115
3f5e193b 8116 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8117 g->section_index = entry;
8118 g->next = group->root;
8119 group->root = g;
f5842774
L
8120 }
8121
9db70fc3 8122 free (start);
e4b17d5c
L
8123
8124 group++;
f5842774
L
8125 }
8126 }
8127
9db70fc3
AM
8128 free (symtab);
8129 free (strtab);
015dc7e1 8130 return true;
f5842774
L
8131}
8132
28f997cf
TG
8133/* Data used to display dynamic fixups. */
8134
8135struct ia64_vms_dynfixup
8136{
625d49fc
AM
8137 uint64_t needed_ident; /* Library ident number. */
8138 uint64_t needed; /* Index in the dstrtab of the library name. */
8139 uint64_t fixup_needed; /* Index of the library. */
8140 uint64_t fixup_rela_cnt; /* Number of fixups. */
8141 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8142};
8143
8144/* Data used to display dynamic relocations. */
8145
8146struct ia64_vms_dynimgrela
8147{
625d49fc
AM
8148 uint64_t img_rela_cnt; /* Number of relocations. */
8149 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8150};
8151
8152/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8153 library). */
8154
015dc7e1 8155static bool
dda8d76d
NC
8156dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8157 struct ia64_vms_dynfixup * fixup,
8158 const char * strtab,
8159 unsigned int strtab_sz)
28f997cf 8160{
32ec8896 8161 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8162 long i;
32ec8896 8163 const char * lib_name;
28f997cf 8164
978c4450
AM
8165 imfs = get_data (NULL, filedata,
8166 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8167 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8168 _("dynamic section image fixups"));
8169 if (!imfs)
015dc7e1 8170 return false;
28f997cf
TG
8171
8172 if (fixup->needed < strtab_sz)
8173 lib_name = strtab + fixup->needed;
8174 else
8175 {
32ec8896 8176 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8177 (unsigned long) fixup->needed);
28f997cf
TG
8178 lib_name = "???";
8179 }
736990c4 8180
28f997cf
TG
8181 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8182 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8183 printf
8184 (_("Seg Offset Type SymVec DataType\n"));
8185
8186 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8187 {
8188 unsigned int type;
8189 const char *rtype;
8190
8191 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8192 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8193 type = BYTE_GET (imfs [i].type);
8194 rtype = elf_ia64_reloc_type (type);
8195 if (rtype == NULL)
f493c217 8196 printf ("0x%08x ", type);
28f997cf 8197 else
f493c217 8198 printf ("%-32s ", rtype);
28f997cf
TG
8199 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8200 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8201 }
8202
8203 free (imfs);
015dc7e1 8204 return true;
28f997cf
TG
8205}
8206
8207/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8208
015dc7e1 8209static bool
dda8d76d 8210dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8211{
8212 Elf64_External_VMS_IMAGE_RELA *imrs;
8213 long i;
8214
978c4450
AM
8215 imrs = get_data (NULL, filedata,
8216 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8217 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8218 _("dynamic section image relocations"));
28f997cf 8219 if (!imrs)
015dc7e1 8220 return false;
28f997cf
TG
8221
8222 printf (_("\nImage relocs\n"));
8223 printf
8224 (_("Seg Offset Type Addend Seg Sym Off\n"));
8225
8226 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8227 {
8228 unsigned int type;
8229 const char *rtype;
8230
8231 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8232 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8233 type = BYTE_GET (imrs [i].type);
8234 rtype = elf_ia64_reloc_type (type);
8235 if (rtype == NULL)
8236 printf ("0x%08x ", type);
8237 else
8238 printf ("%-31s ", rtype);
8239 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8240 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8241 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8242 }
8243
8244 free (imrs);
015dc7e1 8245 return true;
28f997cf
TG
8246}
8247
8248/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8249
015dc7e1 8250static bool
dda8d76d 8251process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8252{
8253 struct ia64_vms_dynfixup fixup;
8254 struct ia64_vms_dynimgrela imgrela;
8255 Elf_Internal_Dyn *entry;
625d49fc
AM
8256 uint64_t strtab_off = 0;
8257 uint64_t strtab_sz = 0;
28f997cf 8258 char *strtab = NULL;
015dc7e1 8259 bool res = true;
28f997cf
TG
8260
8261 memset (&fixup, 0, sizeof (fixup));
8262 memset (&imgrela, 0, sizeof (imgrela));
8263
8264 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8265 for (entry = filedata->dynamic_section;
8266 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8267 entry++)
8268 {
8269 switch (entry->d_tag)
8270 {
8271 case DT_IA_64_VMS_STRTAB_OFFSET:
8272 strtab_off = entry->d_un.d_val;
8273 break;
8274 case DT_STRSZ:
8275 strtab_sz = entry->d_un.d_val;
8276 if (strtab == NULL)
978c4450
AM
8277 strtab = get_data (NULL, filedata,
8278 filedata->dynamic_addr + strtab_off,
28f997cf 8279 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8280 if (strtab == NULL)
8281 strtab_sz = 0;
28f997cf
TG
8282 break;
8283
8284 case DT_IA_64_VMS_NEEDED_IDENT:
8285 fixup.needed_ident = entry->d_un.d_val;
8286 break;
8287 case DT_NEEDED:
8288 fixup.needed = entry->d_un.d_val;
8289 break;
8290 case DT_IA_64_VMS_FIXUP_NEEDED:
8291 fixup.fixup_needed = entry->d_un.d_val;
8292 break;
8293 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8294 fixup.fixup_rela_cnt = entry->d_un.d_val;
8295 break;
8296 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8297 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8298 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8299 res = false;
28f997cf 8300 break;
28f997cf
TG
8301 case DT_IA_64_VMS_IMG_RELA_CNT:
8302 imgrela.img_rela_cnt = entry->d_un.d_val;
8303 break;
8304 case DT_IA_64_VMS_IMG_RELA_OFF:
8305 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8306 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8307 res = false;
28f997cf
TG
8308 break;
8309
8310 default:
8311 break;
8312 }
8313 }
8314
9db70fc3 8315 free (strtab);
28f997cf
TG
8316
8317 return res;
8318}
8319
85b1c36d 8320static struct
566b0d53 8321{
2cf0635d 8322 const char * name;
566b0d53
L
8323 int reloc;
8324 int size;
a7fd1186 8325 relocation_type rel_type;
32ec8896
NC
8326}
8327 dynamic_relocations [] =
566b0d53 8328{
a7fd1186
FS
8329 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8330 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8331 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8332 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8333};
8334
252b5132 8335/* Process the reloc section. */
18bd398b 8336
015dc7e1 8337static bool
dda8d76d 8338process_relocs (Filedata * filedata)
252b5132 8339{
b34976b6
AM
8340 unsigned long rel_size;
8341 unsigned long rel_offset;
252b5132 8342
252b5132 8343 if (!do_reloc)
015dc7e1 8344 return true;
252b5132
RH
8345
8346 if (do_using_dynamic)
8347 {
a7fd1186 8348 relocation_type rel_type;
2cf0635d 8349 const char * name;
015dc7e1 8350 bool has_dynamic_reloc;
566b0d53 8351 unsigned int i;
0de14b54 8352
015dc7e1 8353 has_dynamic_reloc = false;
252b5132 8354
566b0d53 8355 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8356 {
a7fd1186 8357 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8358 name = dynamic_relocations [i].name;
978c4450
AM
8359 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8360 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8361
32ec8896 8362 if (rel_size)
015dc7e1 8363 has_dynamic_reloc = true;
566b0d53 8364
a7fd1186 8365 if (rel_type == reltype_unknown)
aa903cfb 8366 {
566b0d53 8367 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8368 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8369 {
8370 case DT_REL:
a7fd1186 8371 rel_type = reltype_rel;
566b0d53
L
8372 break;
8373 case DT_RELA:
a7fd1186 8374 rel_type = reltype_rela;
566b0d53
L
8375 break;
8376 }
aa903cfb 8377 }
252b5132 8378
566b0d53
L
8379 if (rel_size)
8380 {
ca0e11aa
NC
8381 if (filedata->is_separate)
8382 printf
8383 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8384 filedata->file_name, name, rel_offset, rel_size);
8385 else
8386 printf
8387 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8388 name, rel_offset, rel_size);
252b5132 8389
dda8d76d
NC
8390 dump_relocations (filedata,
8391 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8392 rel_size,
978c4450
AM
8393 filedata->dynamic_symbols,
8394 filedata->num_dynamic_syms,
8395 filedata->dynamic_strings,
8396 filedata->dynamic_strings_length,
a7fd1186 8397 rel_type, true /* is_dynamic */);
566b0d53 8398 }
252b5132 8399 }
566b0d53 8400
dda8d76d
NC
8401 if (is_ia64_vms (filedata))
8402 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8403 has_dynamic_reloc = true;
28f997cf 8404
566b0d53 8405 if (! has_dynamic_reloc)
ca0e11aa
NC
8406 {
8407 if (filedata->is_separate)
8408 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8409 filedata->file_name);
8410 else
8411 printf (_("\nThere are no dynamic relocations in this file.\n"));
8412 }
252b5132
RH
8413 }
8414 else
8415 {
2cf0635d 8416 Elf_Internal_Shdr * section;
b34976b6 8417 unsigned long i;
015dc7e1 8418 bool found = false;
252b5132 8419
dda8d76d
NC
8420 for (i = 0, section = filedata->section_headers;
8421 i < filedata->file_header.e_shnum;
b34976b6 8422 i++, section++)
252b5132
RH
8423 {
8424 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8425 && section->sh_type != SHT_REL
8426 && section->sh_type != SHT_RELR)
252b5132
RH
8427 continue;
8428
8429 rel_offset = section->sh_offset;
8430 rel_size = section->sh_size;
8431
8432 if (rel_size)
8433 {
a7fd1186 8434 relocation_type rel_type;
d3a49aa8 8435 unsigned long num_rela;
103f02d3 8436
ca0e11aa
NC
8437 if (filedata->is_separate)
8438 printf (_("\nIn linked file '%s' relocation section "),
8439 filedata->file_name);
8440 else
8441 printf (_("\nRelocation section "));
252b5132 8442
dda8d76d 8443 if (filedata->string_table == NULL)
19936277 8444 printf ("%d", section->sh_name);
252b5132 8445 else
dda8d76d 8446 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8447
d3a49aa8
AM
8448 num_rela = rel_size / section->sh_entsize;
8449 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8450 " at offset 0x%lx contains %lu entries:\n",
8451 num_rela),
8452 rel_offset, num_rela);
252b5132 8453
a7fd1186
FS
8454 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8455 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8456
4fbb74a6 8457 if (section->sh_link != 0
dda8d76d 8458 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8459 {
2cf0635d
NC
8460 Elf_Internal_Shdr * symsec;
8461 Elf_Internal_Sym * symtab;
d79b3d50 8462 unsigned long nsyms;
c256ffe7 8463 unsigned long strtablen = 0;
2cf0635d 8464 char * strtab = NULL;
57346661 8465
dda8d76d 8466 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8467 if (symsec->sh_type != SHT_SYMTAB
8468 && symsec->sh_type != SHT_DYNSYM)
8469 continue;
8470
28d13567
AM
8471 if (!get_symtab (filedata, symsec,
8472 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8473 continue;
252b5132 8474
dda8d76d 8475 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8476 symtab, nsyms, strtab, strtablen,
a7fd1186 8477 rel_type,
bb4d2ac2 8478 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8479 free (strtab);
d79b3d50
NC
8480 free (symtab);
8481 }
8482 else
dda8d76d 8483 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8484 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8485
015dc7e1 8486 found = true;
252b5132
RH
8487 }
8488 }
8489
8490 if (! found)
45ac8f4f
NC
8491 {
8492 /* Users sometimes forget the -D option, so try to be helpful. */
8493 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8494 {
978c4450 8495 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8496 {
ca0e11aa
NC
8497 if (filedata->is_separate)
8498 printf (_("\nThere are no static relocations in linked file '%s'."),
8499 filedata->file_name);
8500 else
8501 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8502 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8503
8504 break;
8505 }
8506 }
8507 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8508 {
8509 if (filedata->is_separate)
8510 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8511 filedata->file_name);
8512 else
8513 printf (_("\nThere are no relocations in this file.\n"));
8514 }
45ac8f4f 8515 }
252b5132
RH
8516 }
8517
015dc7e1 8518 return true;
252b5132
RH
8519}
8520
4d6ed7c8
NC
8521/* An absolute address consists of a section and an offset. If the
8522 section is NULL, the offset itself is the address, otherwise, the
8523 address equals to LOAD_ADDRESS(section) + offset. */
8524
8525struct absaddr
948f632f
DA
8526{
8527 unsigned short section;
625d49fc 8528 uint64_t offset;
948f632f 8529};
4d6ed7c8 8530
948f632f
DA
8531/* Find the nearest symbol at or below ADDR. Returns the symbol
8532 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8533
4d6ed7c8 8534static void
dda8d76d
NC
8535find_symbol_for_address (Filedata * filedata,
8536 Elf_Internal_Sym * symtab,
8537 unsigned long nsyms,
8538 const char * strtab,
8539 unsigned long strtab_size,
8540 struct absaddr addr,
8541 const char ** symname,
625d49fc 8542 uint64_t * offset)
4d6ed7c8 8543{
625d49fc 8544 uint64_t dist = 0x100000;
2cf0635d 8545 Elf_Internal_Sym * sym;
948f632f
DA
8546 Elf_Internal_Sym * beg;
8547 Elf_Internal_Sym * end;
2cf0635d 8548 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8549
0b6ae522 8550 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8551 beg = symtab;
8552 end = symtab + nsyms;
0b6ae522 8553
948f632f 8554 while (beg < end)
4d6ed7c8 8555 {
625d49fc 8556 uint64_t value;
948f632f
DA
8557
8558 sym = beg + (end - beg) / 2;
0b6ae522 8559
948f632f 8560 value = sym->st_value;
0b6ae522
DJ
8561 REMOVE_ARCH_BITS (value);
8562
948f632f 8563 if (sym->st_name != 0
4d6ed7c8 8564 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8565 && addr.offset >= value
8566 && addr.offset - value < dist)
4d6ed7c8
NC
8567 {
8568 best = sym;
0b6ae522 8569 dist = addr.offset - value;
4d6ed7c8
NC
8570 if (!dist)
8571 break;
8572 }
948f632f
DA
8573
8574 if (addr.offset < value)
8575 end = sym;
8576 else
8577 beg = sym + 1;
4d6ed7c8 8578 }
1b31d05e 8579
4d6ed7c8
NC
8580 if (best)
8581 {
57346661 8582 *symname = (best->st_name >= strtab_size
2b692964 8583 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8584 *offset = dist;
8585 return;
8586 }
1b31d05e 8587
4d6ed7c8
NC
8588 *symname = NULL;
8589 *offset = addr.offset;
8590}
8591
32ec8896 8592static /* signed */ int
948f632f
DA
8593symcmp (const void *p, const void *q)
8594{
8595 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8596 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8597
8598 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8599}
8600
8601/* Process the unwind section. */
8602
8603#include "unwind-ia64.h"
8604
8605struct ia64_unw_table_entry
8606{
8607 struct absaddr start;
8608 struct absaddr end;
8609 struct absaddr info;
8610};
8611
8612struct ia64_unw_aux_info
8613{
32ec8896
NC
8614 struct ia64_unw_table_entry * table; /* Unwind table. */
8615 unsigned long table_len; /* Length of unwind table. */
8616 unsigned char * info; /* Unwind info. */
8617 unsigned long info_size; /* Size of unwind info. */
625d49fc
AM
8618 uint64_t info_addr; /* Starting address of unwind info. */
8619 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
8620 Elf_Internal_Sym * symtab; /* The symbol table. */
8621 unsigned long nsyms; /* Number of symbols. */
8622 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8623 unsigned long nfuns; /* Number of entries in funtab. */
8624 char * strtab; /* The string table. */
8625 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8626};
8627
015dc7e1 8628static bool
dda8d76d 8629dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8630{
2cf0635d 8631 struct ia64_unw_table_entry * tp;
948f632f 8632 unsigned long j, nfuns;
4d6ed7c8 8633 int in_body;
015dc7e1 8634 bool res = true;
7036c0e1 8635
948f632f
DA
8636 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8637 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8638 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8639 aux->funtab[nfuns++] = aux->symtab[j];
8640 aux->nfuns = nfuns;
8641 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8642
4d6ed7c8
NC
8643 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8644 {
625d49fc
AM
8645 uint64_t stamp;
8646 uint64_t offset;
2cf0635d
NC
8647 const unsigned char * dp;
8648 const unsigned char * head;
53774b7e 8649 const unsigned char * end;
2cf0635d 8650 const char * procname;
4d6ed7c8 8651
dda8d76d 8652 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8653 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8654
8655 fputs ("\n<", stdout);
8656
8657 if (procname)
8658 {
8659 fputs (procname, stdout);
8660
8661 if (offset)
8662 printf ("+%lx", (unsigned long) offset);
8663 }
8664
8665 fputs (">: [", stdout);
8666 print_vma (tp->start.offset, PREFIX_HEX);
8667 fputc ('-', stdout);
8668 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8669 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8670 (unsigned long) (tp->info.offset - aux->seg_base));
8671
53774b7e
NC
8672 /* PR 17531: file: 86232b32. */
8673 if (aux->info == NULL)
8674 continue;
8675
97c0a079
AM
8676 offset = tp->info.offset;
8677 if (tp->info.section)
8678 {
8679 if (tp->info.section >= filedata->file_header.e_shnum)
8680 {
8681 warn (_("Invalid section %u in table entry %ld\n"),
8682 tp->info.section, (long) (tp - aux->table));
015dc7e1 8683 res = false;
97c0a079
AM
8684 continue;
8685 }
8686 offset += filedata->section_headers[tp->info.section].sh_addr;
8687 }
8688 offset -= aux->info_addr;
53774b7e 8689 /* PR 17531: file: 0997b4d1. */
90679903
AM
8690 if (offset >= aux->info_size
8691 || aux->info_size - offset < 8)
53774b7e
NC
8692 {
8693 warn (_("Invalid offset %lx in table entry %ld\n"),
8694 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8695 res = false;
53774b7e
NC
8696 continue;
8697 }
8698
97c0a079 8699 head = aux->info + offset;
a4a00738 8700 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8701
86f55779 8702 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8703 (unsigned) UNW_VER (stamp),
8704 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8705 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8706 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8707 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8708
8709 if (UNW_VER (stamp) != 1)
8710 {
2b692964 8711 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8712 continue;
8713 }
8714
8715 in_body = 0;
53774b7e
NC
8716 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8717 /* PR 17531: file: 16ceda89. */
8718 if (end > aux->info + aux->info_size)
8719 end = aux->info + aux->info_size;
8720 for (dp = head + 8; dp < end;)
b4477bc8 8721 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8722 }
948f632f
DA
8723
8724 free (aux->funtab);
32ec8896
NC
8725
8726 return res;
4d6ed7c8
NC
8727}
8728
015dc7e1 8729static bool
dda8d76d
NC
8730slurp_ia64_unwind_table (Filedata * filedata,
8731 struct ia64_unw_aux_info * aux,
8732 Elf_Internal_Shdr * sec)
4d6ed7c8 8733{
89fac5e3 8734 unsigned long size, nrelas, i;
2cf0635d
NC
8735 Elf_Internal_Phdr * seg;
8736 struct ia64_unw_table_entry * tep;
8737 Elf_Internal_Shdr * relsec;
8738 Elf_Internal_Rela * rela;
8739 Elf_Internal_Rela * rp;
8740 unsigned char * table;
8741 unsigned char * tp;
8742 Elf_Internal_Sym * sym;
8743 const char * relname;
4d6ed7c8 8744
53774b7e
NC
8745 aux->table_len = 0;
8746
4d6ed7c8
NC
8747 /* First, find the starting address of the segment that includes
8748 this section: */
8749
dda8d76d 8750 if (filedata->file_header.e_phnum)
4d6ed7c8 8751 {
dda8d76d 8752 if (! get_program_headers (filedata))
015dc7e1 8753 return false;
4d6ed7c8 8754
dda8d76d
NC
8755 for (seg = filedata->program_headers;
8756 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8757 ++seg)
4d6ed7c8
NC
8758 {
8759 if (seg->p_type != PT_LOAD)
8760 continue;
8761
8762 if (sec->sh_addr >= seg->p_vaddr
8763 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8764 {
8765 aux->seg_base = seg->p_vaddr;
8766 break;
8767 }
8768 }
4d6ed7c8
NC
8769 }
8770
8771 /* Second, build the unwind table from the contents of the unwind section: */
8772 size = sec->sh_size;
dda8d76d 8773 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8774 _("unwind table"));
a6e9f9df 8775 if (!table)
015dc7e1 8776 return false;
4d6ed7c8 8777
53774b7e 8778 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8779 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8780 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8781 tep = aux->table;
53774b7e
NC
8782
8783 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8784 {
8785 tep->start.section = SHN_UNDEF;
8786 tep->end.section = SHN_UNDEF;
8787 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8788 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8789 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8790 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8791 tep->start.offset += aux->seg_base;
8792 tep->end.offset += aux->seg_base;
8793 tep->info.offset += aux->seg_base;
8794 }
8795 free (table);
8796
41e92641 8797 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8798 for (relsec = filedata->section_headers;
8799 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8800 ++relsec)
8801 {
8802 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8803 || relsec->sh_info >= filedata->file_header.e_shnum
8804 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8805 continue;
8806
dda8d76d 8807 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8808 & rela, & nrelas))
53774b7e
NC
8809 {
8810 free (aux->table);
8811 aux->table = NULL;
8812 aux->table_len = 0;
015dc7e1 8813 return false;
53774b7e 8814 }
4d6ed7c8
NC
8815
8816 for (rp = rela; rp < rela + nrelas; ++rp)
8817 {
4770fb94 8818 unsigned int sym_ndx;
726bd37d
AM
8819 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8820 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8821
82b1b41b
NC
8822 /* PR 17531: file: 9fa67536. */
8823 if (relname == NULL)
8824 {
726bd37d 8825 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8826 continue;
8827 }
948f632f 8828
24d127aa 8829 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8830 {
82b1b41b 8831 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8832 continue;
8833 }
8834
89fac5e3 8835 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8836
53774b7e
NC
8837 /* PR 17531: file: 5bc8d9bf. */
8838 if (i >= aux->table_len)
8839 {
8840 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8841 continue;
8842 }
8843
4770fb94
AM
8844 sym_ndx = get_reloc_symindex (rp->r_info);
8845 if (sym_ndx >= aux->nsyms)
8846 {
8847 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8848 sym_ndx);
8849 continue;
8850 }
8851 sym = aux->symtab + sym_ndx;
8852
53774b7e 8853 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8854 {
8855 case 0:
8856 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8857 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8858 break;
8859 case 1:
8860 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8861 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8862 break;
8863 case 2:
8864 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8865 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8866 break;
8867 default:
8868 break;
8869 }
8870 }
8871
8872 free (rela);
8873 }
8874
015dc7e1 8875 return true;
4d6ed7c8
NC
8876}
8877
015dc7e1 8878static bool
dda8d76d 8879ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8880{
2cf0635d
NC
8881 Elf_Internal_Shdr * sec;
8882 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8883 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8884 struct ia64_unw_aux_info aux;
015dc7e1 8885 bool res = true;
f1467e33 8886
4d6ed7c8
NC
8887 memset (& aux, 0, sizeof (aux));
8888
dda8d76d 8889 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8890 {
28d13567 8891 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8892 {
28d13567 8893 if (aux.symtab)
4082ef84 8894 {
28d13567
AM
8895 error (_("Multiple symbol tables encountered\n"));
8896 free (aux.symtab);
8897 aux.symtab = NULL;
4082ef84 8898 free (aux.strtab);
28d13567 8899 aux.strtab = NULL;
4082ef84 8900 }
28d13567
AM
8901 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8902 &aux.strtab, &aux.strtab_size))
015dc7e1 8903 return false;
4d6ed7c8
NC
8904 }
8905 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8906 unwcount++;
8907 }
8908
8909 if (!unwcount)
8910 printf (_("\nThere are no unwind sections in this file.\n"));
8911
8912 while (unwcount-- > 0)
8913 {
84714f86 8914 const char *suffix;
579f31ac
JJ
8915 size_t len, len2;
8916
dda8d76d
NC
8917 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8918 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8919 if (sec->sh_type == SHT_IA_64_UNWIND)
8920 {
8921 unwsec = sec;
8922 break;
8923 }
4082ef84
NC
8924 /* We have already counted the number of SHT_IA64_UNWIND
8925 sections so the loop above should never fail. */
8926 assert (unwsec != NULL);
579f31ac
JJ
8927
8928 unwstart = i + 1;
8929 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8930
e4b17d5c
L
8931 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8932 {
8933 /* We need to find which section group it is in. */
4082ef84 8934 struct group_list * g;
e4b17d5c 8935
978c4450
AM
8936 if (filedata->section_headers_groups == NULL
8937 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8938 i = filedata->file_header.e_shnum;
4082ef84 8939 else
e4b17d5c 8940 {
978c4450 8941 g = filedata->section_headers_groups[i]->root;
18bd398b 8942
4082ef84
NC
8943 for (; g != NULL; g = g->next)
8944 {
dda8d76d 8945 sec = filedata->section_headers + g->section_index;
e4b17d5c 8946
84714f86
AM
8947 if (section_name_valid (filedata, sec)
8948 && streq (section_name (filedata, sec),
8949 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8950 break;
8951 }
8952
8953 if (g == NULL)
dda8d76d 8954 i = filedata->file_header.e_shnum;
4082ef84 8955 }
e4b17d5c 8956 }
84714f86
AM
8957 else if (section_name_valid (filedata, unwsec)
8958 && startswith (section_name (filedata, unwsec),
e9b095a5 8959 ELF_STRING_ia64_unwind_once))
579f31ac 8960 {
18bd398b 8961 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8962 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8963 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8964 for (i = 0, sec = filedata->section_headers;
8965 i < filedata->file_header.e_shnum;
579f31ac 8966 ++i, ++sec)
84714f86
AM
8967 if (section_name_valid (filedata, sec)
8968 && startswith (section_name (filedata, sec),
e9b095a5 8969 ELF_STRING_ia64_unwind_info_once)
84714f86 8970 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8971 break;
8972 }
8973 else
8974 {
8975 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8976 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8977 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8978 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8979 suffix = "";
84714f86
AM
8980 if (section_name_valid (filedata, unwsec)
8981 && startswith (section_name (filedata, unwsec),
8982 ELF_STRING_ia64_unwind))
8983 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8984 for (i = 0, sec = filedata->section_headers;
8985 i < filedata->file_header.e_shnum;
579f31ac 8986 ++i, ++sec)
84714f86
AM
8987 if (section_name_valid (filedata, sec)
8988 && startswith (section_name (filedata, sec),
8989 ELF_STRING_ia64_unwind_info)
8990 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8991 break;
8992 }
8993
dda8d76d 8994 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8995 {
8996 printf (_("\nCould not find unwind info section for "));
8997
dda8d76d 8998 if (filedata->string_table == NULL)
579f31ac
JJ
8999 printf ("%d", unwsec->sh_name);
9000 else
dda8d76d 9001 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9002 }
9003 else
4d6ed7c8 9004 {
4d6ed7c8 9005 aux.info_addr = sec->sh_addr;
dda8d76d 9006 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9007 sec->sh_size,
9008 _("unwind info"));
59245841 9009 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9010
579f31ac 9011 printf (_("\nUnwind section "));
4d6ed7c8 9012
dda8d76d 9013 if (filedata->string_table == NULL)
579f31ac
JJ
9014 printf ("%d", unwsec->sh_name);
9015 else
dda8d76d 9016 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9017
579f31ac 9018 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9019 (unsigned long) unwsec->sh_offset,
89fac5e3 9020 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9021
dda8d76d 9022 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9023 && aux.table_len > 0)
dda8d76d 9024 dump_ia64_unwind (filedata, & aux);
579f31ac 9025
9db70fc3
AM
9026 free ((char *) aux.table);
9027 free ((char *) aux.info);
579f31ac
JJ
9028 aux.table = NULL;
9029 aux.info = NULL;
9030 }
4d6ed7c8 9031 }
4d6ed7c8 9032
9db70fc3
AM
9033 free (aux.symtab);
9034 free ((char *) aux.strtab);
32ec8896
NC
9035
9036 return res;
4d6ed7c8
NC
9037}
9038
3f5e193b 9039struct hppa_unw_table_entry
32ec8896
NC
9040{
9041 struct absaddr start;
9042 struct absaddr end;
9043 unsigned int Cannot_unwind:1; /* 0 */
9044 unsigned int Millicode:1; /* 1 */
9045 unsigned int Millicode_save_sr0:1; /* 2 */
9046 unsigned int Region_description:2; /* 3..4 */
9047 unsigned int reserved1:1; /* 5 */
9048 unsigned int Entry_SR:1; /* 6 */
9049 unsigned int Entry_FR:4; /* Number saved 7..10 */
9050 unsigned int Entry_GR:5; /* Number saved 11..15 */
9051 unsigned int Args_stored:1; /* 16 */
9052 unsigned int Variable_Frame:1; /* 17 */
9053 unsigned int Separate_Package_Body:1; /* 18 */
9054 unsigned int Frame_Extension_Millicode:1; /* 19 */
9055 unsigned int Stack_Overflow_Check:1; /* 20 */
9056 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9057 unsigned int Ada_Region:1; /* 22 */
9058 unsigned int cxx_info:1; /* 23 */
9059 unsigned int cxx_try_catch:1; /* 24 */
9060 unsigned int sched_entry_seq:1; /* 25 */
9061 unsigned int reserved2:1; /* 26 */
9062 unsigned int Save_SP:1; /* 27 */
9063 unsigned int Save_RP:1; /* 28 */
9064 unsigned int Save_MRP_in_frame:1; /* 29 */
9065 unsigned int extn_ptr_defined:1; /* 30 */
9066 unsigned int Cleanup_defined:1; /* 31 */
9067
9068 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9069 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9070 unsigned int Large_frame:1; /* 2 */
9071 unsigned int Pseudo_SP_Set:1; /* 3 */
9072 unsigned int reserved4:1; /* 4 */
9073 unsigned int Total_frame_size:27; /* 5..31 */
9074};
3f5e193b 9075
57346661 9076struct hppa_unw_aux_info
948f632f 9077{
32ec8896
NC
9078 struct hppa_unw_table_entry * table; /* Unwind table. */
9079 unsigned long table_len; /* Length of unwind table. */
625d49fc 9080 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
9081 Elf_Internal_Sym * symtab; /* The symbol table. */
9082 unsigned long nsyms; /* Number of symbols. */
9083 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9084 unsigned long nfuns; /* Number of entries in funtab. */
9085 char * strtab; /* The string table. */
9086 unsigned long strtab_size; /* Size of string table. */
948f632f 9087};
57346661 9088
015dc7e1 9089static bool
dda8d76d 9090dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9091{
2cf0635d 9092 struct hppa_unw_table_entry * tp;
948f632f 9093 unsigned long j, nfuns;
015dc7e1 9094 bool res = true;
948f632f
DA
9095
9096 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9097 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9098 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9099 aux->funtab[nfuns++] = aux->symtab[j];
9100 aux->nfuns = nfuns;
9101 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9102
57346661
AM
9103 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9104 {
625d49fc 9105 uint64_t offset;
2cf0635d 9106 const char * procname;
57346661 9107
dda8d76d 9108 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9109 aux->strtab_size, tp->start, &procname,
9110 &offset);
9111
9112 fputs ("\n<", stdout);
9113
9114 if (procname)
9115 {
9116 fputs (procname, stdout);
9117
9118 if (offset)
9119 printf ("+%lx", (unsigned long) offset);
9120 }
9121
9122 fputs (">: [", stdout);
9123 print_vma (tp->start.offset, PREFIX_HEX);
9124 fputc ('-', stdout);
9125 print_vma (tp->end.offset, PREFIX_HEX);
9126 printf ("]\n\t");
9127
18bd398b
NC
9128#define PF(_m) if (tp->_m) printf (#_m " ");
9129#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9130 PF(Cannot_unwind);
9131 PF(Millicode);
9132 PF(Millicode_save_sr0);
18bd398b 9133 /* PV(Region_description); */
57346661
AM
9134 PF(Entry_SR);
9135 PV(Entry_FR);
9136 PV(Entry_GR);
9137 PF(Args_stored);
9138 PF(Variable_Frame);
9139 PF(Separate_Package_Body);
9140 PF(Frame_Extension_Millicode);
9141 PF(Stack_Overflow_Check);
9142 PF(Two_Instruction_SP_Increment);
9143 PF(Ada_Region);
9144 PF(cxx_info);
9145 PF(cxx_try_catch);
9146 PF(sched_entry_seq);
9147 PF(Save_SP);
9148 PF(Save_RP);
9149 PF(Save_MRP_in_frame);
9150 PF(extn_ptr_defined);
9151 PF(Cleanup_defined);
9152 PF(MPE_XL_interrupt_marker);
9153 PF(HP_UX_interrupt_marker);
9154 PF(Large_frame);
9155 PF(Pseudo_SP_Set);
9156 PV(Total_frame_size);
9157#undef PF
9158#undef PV
9159 }
9160
18bd398b 9161 printf ("\n");
948f632f
DA
9162
9163 free (aux->funtab);
32ec8896
NC
9164
9165 return res;
57346661
AM
9166}
9167
015dc7e1 9168static bool
dda8d76d
NC
9169slurp_hppa_unwind_table (Filedata * filedata,
9170 struct hppa_unw_aux_info * aux,
9171 Elf_Internal_Shdr * sec)
57346661 9172{
1c0751b2 9173 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9174 Elf_Internal_Phdr * seg;
9175 struct hppa_unw_table_entry * tep;
9176 Elf_Internal_Shdr * relsec;
9177 Elf_Internal_Rela * rela;
9178 Elf_Internal_Rela * rp;
9179 unsigned char * table;
9180 unsigned char * tp;
9181 Elf_Internal_Sym * sym;
9182 const char * relname;
57346661 9183
57346661
AM
9184 /* First, find the starting address of the segment that includes
9185 this section. */
dda8d76d 9186 if (filedata->file_header.e_phnum)
57346661 9187 {
dda8d76d 9188 if (! get_program_headers (filedata))
015dc7e1 9189 return false;
57346661 9190
dda8d76d
NC
9191 for (seg = filedata->program_headers;
9192 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9193 ++seg)
9194 {
9195 if (seg->p_type != PT_LOAD)
9196 continue;
9197
9198 if (sec->sh_addr >= seg->p_vaddr
9199 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9200 {
9201 aux->seg_base = seg->p_vaddr;
9202 break;
9203 }
9204 }
9205 }
9206
9207 /* Second, build the unwind table from the contents of the unwind
9208 section. */
9209 size = sec->sh_size;
dda8d76d 9210 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9211 _("unwind table"));
57346661 9212 if (!table)
015dc7e1 9213 return false;
57346661 9214
1c0751b2
DA
9215 unw_ent_size = 16;
9216 nentries = size / unw_ent_size;
9217 size = unw_ent_size * nentries;
57346661 9218
e3fdc001 9219 aux->table_len = nentries;
3f5e193b
NC
9220 tep = aux->table = (struct hppa_unw_table_entry *)
9221 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9222
1c0751b2 9223 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9224 {
9225 unsigned int tmp1, tmp2;
9226
9227 tep->start.section = SHN_UNDEF;
9228 tep->end.section = SHN_UNDEF;
9229
1c0751b2
DA
9230 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9231 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9232 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9233 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9234
9235 tep->start.offset += aux->seg_base;
9236 tep->end.offset += aux->seg_base;
57346661
AM
9237
9238 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9239 tep->Millicode = (tmp1 >> 30) & 0x1;
9240 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9241 tep->Region_description = (tmp1 >> 27) & 0x3;
9242 tep->reserved1 = (tmp1 >> 26) & 0x1;
9243 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9244 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9245 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9246 tep->Args_stored = (tmp1 >> 15) & 0x1;
9247 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9248 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9249 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9250 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9251 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9252 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9253 tep->cxx_info = (tmp1 >> 8) & 0x1;
9254 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9255 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9256 tep->reserved2 = (tmp1 >> 5) & 0x1;
9257 tep->Save_SP = (tmp1 >> 4) & 0x1;
9258 tep->Save_RP = (tmp1 >> 3) & 0x1;
9259 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9260 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9261 tep->Cleanup_defined = tmp1 & 0x1;
9262
9263 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9264 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9265 tep->Large_frame = (tmp2 >> 29) & 0x1;
9266 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9267 tep->reserved4 = (tmp2 >> 27) & 0x1;
9268 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9269 }
9270 free (table);
9271
9272 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9273 for (relsec = filedata->section_headers;
9274 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9275 ++relsec)
9276 {
9277 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9278 || relsec->sh_info >= filedata->file_header.e_shnum
9279 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9280 continue;
9281
dda8d76d 9282 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9283 & rela, & nrelas))
015dc7e1 9284 return false;
57346661
AM
9285
9286 for (rp = rela; rp < rela + nrelas; ++rp)
9287 {
4770fb94 9288 unsigned int sym_ndx;
726bd37d
AM
9289 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9290 relname = elf_hppa_reloc_type (r_type);
57346661 9291
726bd37d
AM
9292 if (relname == NULL)
9293 {
9294 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9295 continue;
9296 }
9297
57346661 9298 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9299 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9300 {
726bd37d 9301 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9302 continue;
9303 }
9304
9305 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9306 if (i >= aux->table_len)
9307 {
9308 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9309 continue;
9310 }
57346661 9311
4770fb94
AM
9312 sym_ndx = get_reloc_symindex (rp->r_info);
9313 if (sym_ndx >= aux->nsyms)
9314 {
9315 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9316 sym_ndx);
9317 continue;
9318 }
9319 sym = aux->symtab + sym_ndx;
9320
43f6cd05 9321 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9322 {
9323 case 0:
9324 aux->table[i].start.section = sym->st_shndx;
1e456d54 9325 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9326 break;
9327 case 1:
9328 aux->table[i].end.section = sym->st_shndx;
1e456d54 9329 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9330 break;
9331 default:
9332 break;
9333 }
9334 }
9335
9336 free (rela);
9337 }
9338
015dc7e1 9339 return true;
57346661
AM
9340}
9341
015dc7e1 9342static bool
dda8d76d 9343hppa_process_unwind (Filedata * filedata)
57346661 9344{
57346661 9345 struct hppa_unw_aux_info aux;
2cf0635d 9346 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9347 Elf_Internal_Shdr * sec;
18bd398b 9348 unsigned long i;
015dc7e1 9349 bool res = true;
57346661 9350
dda8d76d 9351 if (filedata->string_table == NULL)
015dc7e1 9352 return false;
1b31d05e
NC
9353
9354 memset (& aux, 0, sizeof (aux));
57346661 9355
dda8d76d 9356 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9357 {
28d13567 9358 if (sec->sh_type == SHT_SYMTAB)
57346661 9359 {
28d13567 9360 if (aux.symtab)
4082ef84 9361 {
28d13567
AM
9362 error (_("Multiple symbol tables encountered\n"));
9363 free (aux.symtab);
9364 aux.symtab = NULL;
4082ef84 9365 free (aux.strtab);
28d13567 9366 aux.strtab = NULL;
4082ef84 9367 }
28d13567
AM
9368 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9369 &aux.strtab, &aux.strtab_size))
015dc7e1 9370 return false;
57346661 9371 }
84714f86
AM
9372 else if (section_name_valid (filedata, sec)
9373 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9374 unwsec = sec;
9375 }
9376
9377 if (!unwsec)
9378 printf (_("\nThere are no unwind sections in this file.\n"));
9379
dda8d76d 9380 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9381 {
84714f86
AM
9382 if (section_name_valid (filedata, sec)
9383 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9384 {
43f6cd05 9385 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9386
d3a49aa8
AM
9387 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9388 "contains %lu entry:\n",
9389 "\nUnwind section '%s' at offset 0x%lx "
9390 "contains %lu entries:\n",
9391 num_unwind),
dda8d76d 9392 printable_section_name (filedata, sec),
57346661 9393 (unsigned long) sec->sh_offset,
d3a49aa8 9394 num_unwind);
57346661 9395
dda8d76d 9396 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9397 res = false;
66b09c7e
S
9398
9399 if (res && aux.table_len > 0)
32ec8896 9400 {
dda8d76d 9401 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9402 res = false;
32ec8896 9403 }
57346661 9404
9db70fc3 9405 free ((char *) aux.table);
57346661
AM
9406 aux.table = NULL;
9407 }
9408 }
9409
9db70fc3
AM
9410 free (aux.symtab);
9411 free ((char *) aux.strtab);
32ec8896
NC
9412
9413 return res;
57346661
AM
9414}
9415
0b6ae522
DJ
9416struct arm_section
9417{
a734115a
NC
9418 unsigned char * data; /* The unwind data. */
9419 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9420 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9421 unsigned long nrelas; /* The number of relocations. */
9422 unsigned int rel_type; /* REL or RELA ? */
9423 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9424};
9425
9426struct arm_unw_aux_info
9427{
dda8d76d 9428 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9429 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9430 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9431 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9432 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9433 char * strtab; /* The file's string table. */
9434 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9435};
9436
9437static const char *
dda8d76d
NC
9438arm_print_vma_and_name (Filedata * filedata,
9439 struct arm_unw_aux_info * aux,
625d49fc 9440 uint64_t fn,
dda8d76d 9441 struct absaddr addr)
0b6ae522
DJ
9442{
9443 const char *procname;
625d49fc 9444 uint64_t sym_offset;
0b6ae522
DJ
9445
9446 if (addr.section == SHN_UNDEF)
9447 addr.offset = fn;
9448
dda8d76d 9449 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9450 aux->strtab_size, addr, &procname,
9451 &sym_offset);
9452
9453 print_vma (fn, PREFIX_HEX);
9454
9455 if (procname)
9456 {
9457 fputs (" <", stdout);
9458 fputs (procname, stdout);
9459
9460 if (sym_offset)
9461 printf ("+0x%lx", (unsigned long) sym_offset);
9462 fputc ('>', stdout);
9463 }
9464
9465 return procname;
9466}
9467
9468static void
9469arm_free_section (struct arm_section *arm_sec)
9470{
9db70fc3
AM
9471 free (arm_sec->data);
9472 free (arm_sec->rela);
0b6ae522
DJ
9473}
9474
a734115a
NC
9475/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9476 cached section and install SEC instead.
9477 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9478 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9479 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9480 relocation's offset in ADDR.
1b31d05e
NC
9481 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9482 into the string table of the symbol associated with the reloc. If no
9483 reloc was applied store -1 there.
9484 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9485
015dc7e1 9486static bool
dda8d76d
NC
9487get_unwind_section_word (Filedata * filedata,
9488 struct arm_unw_aux_info * aux,
1b31d05e
NC
9489 struct arm_section * arm_sec,
9490 Elf_Internal_Shdr * sec,
625d49fc 9491 uint64_t word_offset,
1b31d05e
NC
9492 unsigned int * wordp,
9493 struct absaddr * addr,
625d49fc 9494 uint64_t * sym_name)
0b6ae522
DJ
9495{
9496 Elf_Internal_Rela *rp;
9497 Elf_Internal_Sym *sym;
9498 const char * relname;
9499 unsigned int word;
015dc7e1 9500 bool wrapped;
0b6ae522 9501
e0a31db1 9502 if (sec == NULL || arm_sec == NULL)
015dc7e1 9503 return false;
e0a31db1 9504
0b6ae522
DJ
9505 addr->section = SHN_UNDEF;
9506 addr->offset = 0;
9507
1b31d05e 9508 if (sym_name != NULL)
625d49fc 9509 *sym_name = (uint64_t) -1;
1b31d05e 9510
a734115a 9511 /* If necessary, update the section cache. */
0b6ae522
DJ
9512 if (sec != arm_sec->sec)
9513 {
9514 Elf_Internal_Shdr *relsec;
9515
9516 arm_free_section (arm_sec);
9517
9518 arm_sec->sec = sec;
dda8d76d 9519 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9520 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9521 arm_sec->rela = NULL;
9522 arm_sec->nrelas = 0;
9523
dda8d76d
NC
9524 for (relsec = filedata->section_headers;
9525 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9526 ++relsec)
9527 {
dda8d76d
NC
9528 if (relsec->sh_info >= filedata->file_header.e_shnum
9529 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9530 /* PR 15745: Check the section type as well. */
9531 || (relsec->sh_type != SHT_REL
9532 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9533 continue;
9534
a734115a 9535 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9536 if (relsec->sh_type == SHT_REL)
9537 {
dda8d76d 9538 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9539 relsec->sh_size,
9540 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9541 return false;
0b6ae522 9542 }
1ae40aa4 9543 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9544 {
dda8d76d 9545 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9546 relsec->sh_size,
9547 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9548 return false;
0b6ae522 9549 }
1ae40aa4 9550 break;
0b6ae522
DJ
9551 }
9552
9553 arm_sec->next_rela = arm_sec->rela;
9554 }
9555
a734115a 9556 /* If there is no unwind data we can do nothing. */
0b6ae522 9557 if (arm_sec->data == NULL)
015dc7e1 9558 return false;
0b6ae522 9559
e0a31db1 9560 /* If the offset is invalid then fail. */
f32ba729
NC
9561 if (/* PR 21343 *//* PR 18879 */
9562 sec->sh_size < 4
625d49fc 9563 || word_offset > sec->sh_size - 4)
015dc7e1 9564 return false;
e0a31db1 9565
a734115a 9566 /* Get the word at the required offset. */
0b6ae522
DJ
9567 word = byte_get (arm_sec->data + word_offset, 4);
9568
0eff7165
NC
9569 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9570 if (arm_sec->rela == NULL)
9571 {
9572 * wordp = word;
015dc7e1 9573 return true;
0eff7165
NC
9574 }
9575
a734115a 9576 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9577 wrapped = false;
0b6ae522
DJ
9578 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9579 {
625d49fc 9580 uint64_t prelval, offset;
0b6ae522
DJ
9581
9582 if (rp->r_offset > word_offset && !wrapped)
9583 {
9584 rp = arm_sec->rela;
015dc7e1 9585 wrapped = true;
0b6ae522
DJ
9586 }
9587 if (rp->r_offset > word_offset)
9588 break;
9589
9590 if (rp->r_offset & 3)
9591 {
9592 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9593 (unsigned long) rp->r_offset);
9594 continue;
9595 }
9596
9597 if (rp->r_offset < word_offset)
9598 continue;
9599
74e1a04b
NC
9600 /* PR 17531: file: 027-161405-0.004 */
9601 if (aux->symtab == NULL)
9602 continue;
9603
0b6ae522
DJ
9604 if (arm_sec->rel_type == SHT_REL)
9605 {
9606 offset = word & 0x7fffffff;
9607 if (offset & 0x40000000)
625d49fc 9608 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9609 }
a734115a 9610 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9611 offset = rp->r_addend;
a734115a 9612 else
74e1a04b
NC
9613 {
9614 error (_("Unknown section relocation type %d encountered\n"),
9615 arm_sec->rel_type);
9616 break;
9617 }
0b6ae522 9618
071436c6
NC
9619 /* PR 17531 file: 027-1241568-0.004. */
9620 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9621 {
9622 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9623 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9624 break;
9625 }
9626
9627 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9628 offset += sym->st_value;
9629 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9630
a734115a 9631 /* Check that we are processing the expected reloc type. */
dda8d76d 9632 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9633 {
9634 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9635 if (relname == NULL)
9636 {
9637 warn (_("Skipping unknown ARM relocation type: %d\n"),
9638 (int) ELF32_R_TYPE (rp->r_info));
9639 continue;
9640 }
a734115a
NC
9641
9642 if (streq (relname, "R_ARM_NONE"))
9643 continue;
0b4362b0 9644
a734115a
NC
9645 if (! streq (relname, "R_ARM_PREL31"))
9646 {
071436c6 9647 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9648 continue;
9649 }
9650 }
dda8d76d 9651 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9652 {
9653 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9654 if (relname == NULL)
9655 {
9656 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9657 (int) ELF32_R_TYPE (rp->r_info));
9658 continue;
9659 }
0b4362b0 9660
a734115a
NC
9661 if (streq (relname, "R_C6000_NONE"))
9662 continue;
9663
9664 if (! streq (relname, "R_C6000_PREL31"))
9665 {
071436c6 9666 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9667 continue;
9668 }
9669
9670 prelval >>= 1;
9671 }
9672 else
74e1a04b
NC
9673 {
9674 /* This function currently only supports ARM and TI unwinders. */
9675 warn (_("Only TI and ARM unwinders are currently supported\n"));
9676 break;
9677 }
fa197c1c 9678
625d49fc 9679 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9680 addr->section = sym->st_shndx;
9681 addr->offset = offset;
74e1a04b 9682
1b31d05e
NC
9683 if (sym_name)
9684 * sym_name = sym->st_name;
0b6ae522
DJ
9685 break;
9686 }
9687
9688 *wordp = word;
9689 arm_sec->next_rela = rp;
9690
015dc7e1 9691 return true;
0b6ae522
DJ
9692}
9693
a734115a
NC
9694static const char *tic6x_unwind_regnames[16] =
9695{
0b4362b0
RM
9696 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9697 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9698 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9699};
fa197c1c 9700
0b6ae522 9701static void
fa197c1c 9702decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9703{
fa197c1c
PB
9704 int i;
9705
9706 for (i = 12; mask; mask >>= 1, i--)
9707 {
9708 if (mask & 1)
9709 {
9710 fputs (tic6x_unwind_regnames[i], stdout);
9711 if (mask > 1)
9712 fputs (", ", stdout);
9713 }
9714 }
9715}
0b6ae522
DJ
9716
9717#define ADVANCE \
9718 if (remaining == 0 && more_words) \
9719 { \
9720 data_offset += 4; \
dda8d76d 9721 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9722 data_offset, & word, & addr, NULL)) \
015dc7e1 9723 return false; \
0b6ae522
DJ
9724 remaining = 4; \
9725 more_words--; \
9726 } \
9727
9728#define GET_OP(OP) \
9729 ADVANCE; \
9730 if (remaining) \
9731 { \
9732 remaining--; \
9733 (OP) = word >> 24; \
9734 word <<= 8; \
9735 } \
9736 else \
9737 { \
2b692964 9738 printf (_("[Truncated opcode]\n")); \
015dc7e1 9739 return false; \
0b6ae522 9740 } \
cc5914eb 9741 printf ("0x%02x ", OP)
0b6ae522 9742
015dc7e1 9743static bool
dda8d76d
NC
9744decode_arm_unwind_bytecode (Filedata * filedata,
9745 struct arm_unw_aux_info * aux,
948f632f
DA
9746 unsigned int word,
9747 unsigned int remaining,
9748 unsigned int more_words,
625d49fc 9749 uint64_t data_offset,
948f632f
DA
9750 Elf_Internal_Shdr * data_sec,
9751 struct arm_section * data_arm_sec)
fa197c1c
PB
9752{
9753 struct absaddr addr;
015dc7e1 9754 bool res = true;
0b6ae522
DJ
9755
9756 /* Decode the unwinding instructions. */
9757 while (1)
9758 {
9759 unsigned int op, op2;
9760
9761 ADVANCE;
9762 if (remaining == 0)
9763 break;
9764 remaining--;
9765 op = word >> 24;
9766 word <<= 8;
9767
cc5914eb 9768 printf (" 0x%02x ", op);
0b6ae522
DJ
9769
9770 if ((op & 0xc0) == 0x00)
9771 {
9772 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9773
cc5914eb 9774 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9775 }
9776 else if ((op & 0xc0) == 0x40)
9777 {
9778 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9779
cc5914eb 9780 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9781 }
9782 else if ((op & 0xf0) == 0x80)
9783 {
9784 GET_OP (op2);
9785 if (op == 0x80 && op2 == 0)
9786 printf (_("Refuse to unwind"));
9787 else
9788 {
9789 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9790 bool first = true;
0b6ae522 9791 int i;
2b692964 9792
0b6ae522
DJ
9793 printf ("pop {");
9794 for (i = 0; i < 12; i++)
9795 if (mask & (1 << i))
9796 {
9797 if (first)
015dc7e1 9798 first = false;
0b6ae522
DJ
9799 else
9800 printf (", ");
9801 printf ("r%d", 4 + i);
9802 }
9803 printf ("}");
9804 }
9805 }
9806 else if ((op & 0xf0) == 0x90)
9807 {
9808 if (op == 0x9d || op == 0x9f)
9809 printf (_(" [Reserved]"));
9810 else
cc5914eb 9811 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9812 }
9813 else if ((op & 0xf0) == 0xa0)
9814 {
9815 int end = 4 + (op & 0x07);
015dc7e1 9816 bool first = true;
0b6ae522 9817 int i;
61865e30 9818
0b6ae522
DJ
9819 printf (" pop {");
9820 for (i = 4; i <= end; i++)
9821 {
9822 if (first)
015dc7e1 9823 first = false;
0b6ae522
DJ
9824 else
9825 printf (", ");
9826 printf ("r%d", i);
9827 }
9828 if (op & 0x08)
9829 {
1b31d05e 9830 if (!first)
0b6ae522
DJ
9831 printf (", ");
9832 printf ("r14");
9833 }
9834 printf ("}");
9835 }
9836 else if (op == 0xb0)
9837 printf (_(" finish"));
9838 else if (op == 0xb1)
9839 {
9840 GET_OP (op2);
9841 if (op2 == 0 || (op2 & 0xf0) != 0)
9842 printf (_("[Spare]"));
9843 else
9844 {
9845 unsigned int mask = op2 & 0x0f;
015dc7e1 9846 bool first = true;
0b6ae522 9847 int i;
61865e30 9848
0b6ae522
DJ
9849 printf ("pop {");
9850 for (i = 0; i < 12; i++)
9851 if (mask & (1 << i))
9852 {
9853 if (first)
015dc7e1 9854 first = false;
0b6ae522
DJ
9855 else
9856 printf (", ");
9857 printf ("r%d", i);
9858 }
9859 printf ("}");
9860 }
9861 }
9862 else if (op == 0xb2)
9863 {
b115cf96 9864 unsigned char buf[9];
0b6ae522
DJ
9865 unsigned int i, len;
9866 unsigned long offset;
61865e30 9867
b115cf96 9868 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9869 {
9870 GET_OP (buf[i]);
9871 if ((buf[i] & 0x80) == 0)
9872 break;
9873 }
4082ef84 9874 if (i == sizeof (buf))
32ec8896 9875 {
27a45f42 9876 error (_("corrupt change to vsp\n"));
015dc7e1 9877 res = false;
32ec8896 9878 }
4082ef84
NC
9879 else
9880 {
015dc7e1 9881 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9882 assert (len == i + 1);
9883 offset = offset * 4 + 0x204;
9884 printf ("vsp = vsp + %ld", offset);
9885 }
0b6ae522 9886 }
61865e30 9887 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9888 {
61865e30
NC
9889 unsigned int first, last;
9890
9891 GET_OP (op2);
9892 first = op2 >> 4;
9893 last = op2 & 0x0f;
9894 if (op == 0xc8)
9895 first = first + 16;
9896 printf ("pop {D%d", first);
9897 if (last)
9898 printf ("-D%d", first + last);
9899 printf ("}");
9900 }
09854a88
TB
9901 else if (op == 0xb4)
9902 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9903 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9904 {
9905 unsigned int count = op & 0x07;
9906
9907 printf ("pop {D8");
9908 if (count)
9909 printf ("-D%d", 8 + count);
9910 printf ("}");
9911 }
9912 else if (op >= 0xc0 && op <= 0xc5)
9913 {
9914 unsigned int count = op & 0x07;
9915
9916 printf (" pop {wR10");
9917 if (count)
9918 printf ("-wR%d", 10 + count);
9919 printf ("}");
9920 }
9921 else if (op == 0xc6)
9922 {
9923 unsigned int first, last;
9924
9925 GET_OP (op2);
9926 first = op2 >> 4;
9927 last = op2 & 0x0f;
9928 printf ("pop {wR%d", first);
9929 if (last)
9930 printf ("-wR%d", first + last);
9931 printf ("}");
9932 }
9933 else if (op == 0xc7)
9934 {
9935 GET_OP (op2);
9936 if (op2 == 0 || (op2 & 0xf0) != 0)
9937 printf (_("[Spare]"));
0b6ae522
DJ
9938 else
9939 {
61865e30 9940 unsigned int mask = op2 & 0x0f;
015dc7e1 9941 bool first = true;
61865e30
NC
9942 int i;
9943
9944 printf ("pop {");
9945 for (i = 0; i < 4; i++)
9946 if (mask & (1 << i))
9947 {
9948 if (first)
015dc7e1 9949 first = false;
61865e30
NC
9950 else
9951 printf (", ");
9952 printf ("wCGR%d", i);
9953 }
9954 printf ("}");
0b6ae522
DJ
9955 }
9956 }
61865e30 9957 else
32ec8896
NC
9958 {
9959 printf (_(" [unsupported opcode]"));
015dc7e1 9960 res = false;
32ec8896
NC
9961 }
9962
0b6ae522
DJ
9963 printf ("\n");
9964 }
32ec8896
NC
9965
9966 return res;
fa197c1c
PB
9967}
9968
015dc7e1 9969static bool
dda8d76d
NC
9970decode_tic6x_unwind_bytecode (Filedata * filedata,
9971 struct arm_unw_aux_info * aux,
948f632f
DA
9972 unsigned int word,
9973 unsigned int remaining,
9974 unsigned int more_words,
625d49fc 9975 uint64_t data_offset,
948f632f
DA
9976 Elf_Internal_Shdr * data_sec,
9977 struct arm_section * data_arm_sec)
fa197c1c
PB
9978{
9979 struct absaddr addr;
9980
9981 /* Decode the unwinding instructions. */
9982 while (1)
9983 {
9984 unsigned int op, op2;
9985
9986 ADVANCE;
9987 if (remaining == 0)
9988 break;
9989 remaining--;
9990 op = word >> 24;
9991 word <<= 8;
9992
9cf03b7e 9993 printf (" 0x%02x ", op);
fa197c1c
PB
9994
9995 if ((op & 0xc0) == 0x00)
9996 {
9997 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9998 printf (" sp = sp + %d", offset);
fa197c1c
PB
9999 }
10000 else if ((op & 0xc0) == 0x80)
10001 {
10002 GET_OP (op2);
10003 if (op == 0x80 && op2 == 0)
10004 printf (_("Refuse to unwind"));
10005 else
10006 {
10007 unsigned int mask = ((op & 0x1f) << 8) | op2;
10008 if (op & 0x20)
10009 printf ("pop compact {");
10010 else
10011 printf ("pop {");
10012
10013 decode_tic6x_unwind_regmask (mask);
10014 printf("}");
10015 }
10016 }
10017 else if ((op & 0xf0) == 0xc0)
10018 {
10019 unsigned int reg;
10020 unsigned int nregs;
10021 unsigned int i;
10022 const char *name;
a734115a
NC
10023 struct
10024 {
32ec8896
NC
10025 unsigned int offset;
10026 unsigned int reg;
fa197c1c
PB
10027 } regpos[16];
10028
10029 /* Scan entire instruction first so that GET_OP output is not
10030 interleaved with disassembly. */
10031 nregs = 0;
10032 for (i = 0; nregs < (op & 0xf); i++)
10033 {
10034 GET_OP (op2);
10035 reg = op2 >> 4;
10036 if (reg != 0xf)
10037 {
10038 regpos[nregs].offset = i * 2;
10039 regpos[nregs].reg = reg;
10040 nregs++;
10041 }
10042
10043 reg = op2 & 0xf;
10044 if (reg != 0xf)
10045 {
10046 regpos[nregs].offset = i * 2 + 1;
10047 regpos[nregs].reg = reg;
10048 nregs++;
10049 }
10050 }
10051
10052 printf (_("pop frame {"));
18344509 10053 if (nregs == 0)
fa197c1c 10054 {
18344509
NC
10055 printf (_("*corrupt* - no registers specified"));
10056 }
10057 else
10058 {
10059 reg = nregs - 1;
10060 for (i = i * 2; i > 0; i--)
fa197c1c 10061 {
18344509
NC
10062 if (regpos[reg].offset == i - 1)
10063 {
10064 name = tic6x_unwind_regnames[regpos[reg].reg];
10065 if (reg > 0)
10066 reg--;
10067 }
10068 else
10069 name = _("[pad]");
fa197c1c 10070
18344509
NC
10071 fputs (name, stdout);
10072 if (i > 1)
10073 printf (", ");
10074 }
fa197c1c
PB
10075 }
10076
10077 printf ("}");
10078 }
10079 else if (op == 0xd0)
10080 printf (" MOV FP, SP");
10081 else if (op == 0xd1)
10082 printf (" __c6xabi_pop_rts");
10083 else if (op == 0xd2)
10084 {
10085 unsigned char buf[9];
10086 unsigned int i, len;
10087 unsigned long offset;
a734115a 10088
fa197c1c
PB
10089 for (i = 0; i < sizeof (buf); i++)
10090 {
10091 GET_OP (buf[i]);
10092 if ((buf[i] & 0x80) == 0)
10093 break;
10094 }
0eff7165
NC
10095 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10096 if (i == sizeof (buf))
10097 {
0eff7165 10098 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10099 return false;
0eff7165 10100 }
948f632f 10101
015dc7e1 10102 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10103 assert (len == i + 1);
10104 offset = offset * 8 + 0x408;
10105 printf (_("sp = sp + %ld"), offset);
10106 }
10107 else if ((op & 0xf0) == 0xe0)
10108 {
10109 if ((op & 0x0f) == 7)
10110 printf (" RETURN");
10111 else
10112 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10113 }
10114 else
10115 {
10116 printf (_(" [unsupported opcode]"));
10117 }
10118 putchar ('\n');
10119 }
32ec8896 10120
015dc7e1 10121 return true;
fa197c1c
PB
10122}
10123
625d49fc
AM
10124static uint64_t
10125arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10126{
625d49fc 10127 uint64_t offset;
fa197c1c
PB
10128
10129 offset = word & 0x7fffffff;
10130 if (offset & 0x40000000)
625d49fc 10131 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10132
dda8d76d 10133 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10134 offset <<= 1;
10135
10136 return offset + where;
10137}
10138
015dc7e1 10139static bool
dda8d76d
NC
10140decode_arm_unwind (Filedata * filedata,
10141 struct arm_unw_aux_info * aux,
1b31d05e
NC
10142 unsigned int word,
10143 unsigned int remaining,
625d49fc 10144 uint64_t data_offset,
1b31d05e
NC
10145 Elf_Internal_Shdr * data_sec,
10146 struct arm_section * data_arm_sec)
fa197c1c
PB
10147{
10148 int per_index;
10149 unsigned int more_words = 0;
37e14bc3 10150 struct absaddr addr;
625d49fc 10151 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10152 bool res = true;
fa197c1c
PB
10153
10154 if (remaining == 0)
10155 {
1b31d05e
NC
10156 /* Fetch the first word.
10157 Note - when decoding an object file the address extracted
10158 here will always be 0. So we also pass in the sym_name
10159 parameter so that we can find the symbol associated with
10160 the personality routine. */
dda8d76d 10161 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10162 & word, & addr, & sym_name))
015dc7e1 10163 return false;
1b31d05e 10164
fa197c1c
PB
10165 remaining = 4;
10166 }
c93dbb25
CZ
10167 else
10168 {
10169 addr.section = SHN_UNDEF;
10170 addr.offset = 0;
10171 }
fa197c1c
PB
10172
10173 if ((word & 0x80000000) == 0)
10174 {
10175 /* Expand prel31 for personality routine. */
625d49fc 10176 uint64_t fn;
fa197c1c
PB
10177 const char *procname;
10178
dda8d76d 10179 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10180 printf (_(" Personality routine: "));
1b31d05e
NC
10181 if (fn == 0
10182 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10183 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10184 {
10185 procname = aux->strtab + sym_name;
10186 print_vma (fn, PREFIX_HEX);
10187 if (procname)
10188 {
10189 fputs (" <", stdout);
10190 fputs (procname, stdout);
10191 fputc ('>', stdout);
10192 }
10193 }
10194 else
dda8d76d 10195 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10196 fputc ('\n', stdout);
10197
10198 /* The GCC personality routines use the standard compact
10199 encoding, starting with one byte giving the number of
10200 words. */
10201 if (procname != NULL
24d127aa
ML
10202 && (startswith (procname, "__gcc_personality_v0")
10203 || startswith (procname, "__gxx_personality_v0")
10204 || startswith (procname, "__gcj_personality_v0")
10205 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10206 {
10207 remaining = 0;
10208 more_words = 1;
10209 ADVANCE;
10210 if (!remaining)
10211 {
10212 printf (_(" [Truncated data]\n"));
015dc7e1 10213 return false;
fa197c1c
PB
10214 }
10215 more_words = word >> 24;
10216 word <<= 8;
10217 remaining--;
10218 per_index = -1;
10219 }
10220 else
015dc7e1 10221 return true;
fa197c1c
PB
10222 }
10223 else
10224 {
1b31d05e 10225 /* ARM EHABI Section 6.3:
0b4362b0 10226
1b31d05e 10227 An exception-handling table entry for the compact model looks like:
0b4362b0 10228
1b31d05e
NC
10229 31 30-28 27-24 23-0
10230 -- ----- ----- ----
10231 1 0 index Data for personalityRoutine[index] */
10232
dda8d76d 10233 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10234 && (word & 0x70000000))
32ec8896
NC
10235 {
10236 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10237 res = false;
32ec8896 10238 }
1b31d05e 10239
fa197c1c 10240 per_index = (word >> 24) & 0x7f;
1b31d05e 10241 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10242 if (per_index == 0)
10243 {
10244 more_words = 0;
10245 word <<= 8;
10246 remaining--;
10247 }
10248 else if (per_index < 3)
10249 {
10250 more_words = (word >> 16) & 0xff;
10251 word <<= 16;
10252 remaining -= 2;
10253 }
10254 }
10255
dda8d76d 10256 switch (filedata->file_header.e_machine)
fa197c1c
PB
10257 {
10258 case EM_ARM:
10259 if (per_index < 3)
10260 {
dda8d76d 10261 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10262 data_offset, data_sec, data_arm_sec))
015dc7e1 10263 res = false;
fa197c1c
PB
10264 }
10265 else
1b31d05e
NC
10266 {
10267 warn (_("Unknown ARM compact model index encountered\n"));
10268 printf (_(" [reserved]\n"));
015dc7e1 10269 res = false;
1b31d05e 10270 }
fa197c1c
PB
10271 break;
10272
10273 case EM_TI_C6000:
10274 if (per_index < 3)
10275 {
dda8d76d 10276 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10277 data_offset, data_sec, data_arm_sec))
015dc7e1 10278 res = false;
fa197c1c
PB
10279 }
10280 else if (per_index < 5)
10281 {
10282 if (((word >> 17) & 0x7f) == 0x7f)
10283 printf (_(" Restore stack from frame pointer\n"));
10284 else
10285 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10286 printf (_(" Registers restored: "));
10287 if (per_index == 4)
10288 printf (" (compact) ");
10289 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10290 putchar ('\n');
10291 printf (_(" Return register: %s\n"),
10292 tic6x_unwind_regnames[word & 0xf]);
10293 }
10294 else
1b31d05e 10295 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10296 break;
10297
10298 default:
74e1a04b 10299 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10300 filedata->file_header.e_machine);
015dc7e1 10301 res = false;
fa197c1c 10302 }
0b6ae522
DJ
10303
10304 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10305
10306 return res;
0b6ae522
DJ
10307}
10308
015dc7e1 10309static bool
dda8d76d
NC
10310dump_arm_unwind (Filedata * filedata,
10311 struct arm_unw_aux_info * aux,
10312 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10313{
10314 struct arm_section exidx_arm_sec, extab_arm_sec;
10315 unsigned int i, exidx_len;
948f632f 10316 unsigned long j, nfuns;
015dc7e1 10317 bool res = true;
0b6ae522
DJ
10318
10319 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10320 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10321 exidx_len = exidx_sec->sh_size / 8;
10322
948f632f
DA
10323 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10324 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10325 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10326 aux->funtab[nfuns++] = aux->symtab[j];
10327 aux->nfuns = nfuns;
10328 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10329
0b6ae522
DJ
10330 for (i = 0; i < exidx_len; i++)
10331 {
10332 unsigned int exidx_fn, exidx_entry;
10333 struct absaddr fn_addr, entry_addr;
625d49fc 10334 uint64_t fn;
0b6ae522
DJ
10335
10336 fputc ('\n', stdout);
10337
dda8d76d 10338 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10339 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10340 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10341 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10342 {
948f632f 10343 free (aux->funtab);
1b31d05e
NC
10344 arm_free_section (& exidx_arm_sec);
10345 arm_free_section (& extab_arm_sec);
015dc7e1 10346 return false;
0b6ae522
DJ
10347 }
10348
83c257ca
NC
10349 /* ARM EHABI, Section 5:
10350 An index table entry consists of 2 words.
10351 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10352 if (exidx_fn & 0x80000000)
32ec8896
NC
10353 {
10354 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10355 res = false;
32ec8896 10356 }
83c257ca 10357
dda8d76d 10358 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10359
dda8d76d 10360 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10361 fputs (": ", stdout);
10362
10363 if (exidx_entry == 1)
10364 {
10365 print_vma (exidx_entry, PREFIX_HEX);
10366 fputs (" [cantunwind]\n", stdout);
10367 }
10368 else if (exidx_entry & 0x80000000)
10369 {
10370 print_vma (exidx_entry, PREFIX_HEX);
10371 fputc ('\n', stdout);
dda8d76d 10372 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10373 }
10374 else
10375 {
625d49fc 10376 uint64_t table, table_offset = 0;
0b6ae522
DJ
10377 Elf_Internal_Shdr *table_sec;
10378
10379 fputs ("@", stdout);
dda8d76d 10380 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10381 print_vma (table, PREFIX_HEX);
10382 printf ("\n");
10383
10384 /* Locate the matching .ARM.extab. */
10385 if (entry_addr.section != SHN_UNDEF
dda8d76d 10386 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10387 {
dda8d76d 10388 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10389 table_offset = entry_addr.offset;
1a915552 10390 /* PR 18879 */
625d49fc 10391 if (table_offset > table_sec->sh_size)
1a915552
NC
10392 {
10393 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10394 (unsigned long) table_offset,
dda8d76d 10395 printable_section_name (filedata, table_sec));
015dc7e1 10396 res = false;
1a915552
NC
10397 continue;
10398 }
0b6ae522
DJ
10399 }
10400 else
10401 {
dda8d76d 10402 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10403 if (table_sec != NULL)
10404 table_offset = table - table_sec->sh_addr;
10405 }
32ec8896 10406
0b6ae522
DJ
10407 if (table_sec == NULL)
10408 {
10409 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10410 (unsigned long) table);
015dc7e1 10411 res = false;
0b6ae522
DJ
10412 continue;
10413 }
32ec8896 10414
dda8d76d 10415 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10416 &extab_arm_sec))
015dc7e1 10417 res = false;
0b6ae522
DJ
10418 }
10419 }
10420
10421 printf ("\n");
10422
948f632f 10423 free (aux->funtab);
0b6ae522
DJ
10424 arm_free_section (&exidx_arm_sec);
10425 arm_free_section (&extab_arm_sec);
32ec8896
NC
10426
10427 return res;
0b6ae522
DJ
10428}
10429
fa197c1c 10430/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10431
015dc7e1 10432static bool
dda8d76d 10433arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10434{
10435 struct arm_unw_aux_info aux;
10436 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10437 Elf_Internal_Shdr *sec;
10438 unsigned long i;
fa197c1c 10439 unsigned int sec_type;
015dc7e1 10440 bool res = true;
0b6ae522 10441
dda8d76d 10442 switch (filedata->file_header.e_machine)
fa197c1c
PB
10443 {
10444 case EM_ARM:
10445 sec_type = SHT_ARM_EXIDX;
10446 break;
10447
10448 case EM_TI_C6000:
10449 sec_type = SHT_C6000_UNWIND;
10450 break;
10451
0b4362b0 10452 default:
74e1a04b 10453 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10454 filedata->file_header.e_machine);
015dc7e1 10455 return false;
fa197c1c
PB
10456 }
10457
dda8d76d 10458 if (filedata->string_table == NULL)
015dc7e1 10459 return false;
1b31d05e
NC
10460
10461 memset (& aux, 0, sizeof (aux));
dda8d76d 10462 aux.filedata = filedata;
0b6ae522 10463
dda8d76d 10464 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10465 {
28d13567 10466 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10467 {
28d13567 10468 if (aux.symtab)
74e1a04b 10469 {
28d13567
AM
10470 error (_("Multiple symbol tables encountered\n"));
10471 free (aux.symtab);
10472 aux.symtab = NULL;
74e1a04b 10473 free (aux.strtab);
28d13567 10474 aux.strtab = NULL;
74e1a04b 10475 }
28d13567
AM
10476 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10477 &aux.strtab, &aux.strtab_size))
015dc7e1 10478 return false;
0b6ae522 10479 }
fa197c1c 10480 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10481 unwsec = sec;
10482 }
10483
1b31d05e 10484 if (unwsec == NULL)
0b6ae522 10485 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10486 else
dda8d76d 10487 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10488 {
10489 if (sec->sh_type == sec_type)
10490 {
d3a49aa8
AM
10491 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10492 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10493 "contains %lu entry:\n",
10494 "\nUnwind section '%s' at offset 0x%lx "
10495 "contains %lu entries:\n",
10496 num_unwind),
dda8d76d 10497 printable_section_name (filedata, sec),
1b31d05e 10498 (unsigned long) sec->sh_offset,
d3a49aa8 10499 num_unwind);
0b6ae522 10500
dda8d76d 10501 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10502 res = false;
1b31d05e
NC
10503 }
10504 }
0b6ae522 10505
9db70fc3
AM
10506 free (aux.symtab);
10507 free ((char *) aux.strtab);
32ec8896
NC
10508
10509 return res;
0b6ae522
DJ
10510}
10511
3ecc00ec
NC
10512static bool
10513no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10514{
10515 printf (_("No processor specific unwind information to decode\n"));
10516 return true;
10517}
10518
015dc7e1 10519static bool
dda8d76d 10520process_unwind (Filedata * filedata)
57346661 10521{
2cf0635d
NC
10522 struct unwind_handler
10523 {
32ec8896 10524 unsigned int machtype;
015dc7e1 10525 bool (* handler)(Filedata *);
2cf0635d
NC
10526 } handlers[] =
10527 {
0b6ae522 10528 { EM_ARM, arm_process_unwind },
57346661
AM
10529 { EM_IA_64, ia64_process_unwind },
10530 { EM_PARISC, hppa_process_unwind },
fa197c1c 10531 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10532 { EM_386, no_processor_specific_unwind },
10533 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10534 { 0, NULL }
57346661
AM
10535 };
10536 int i;
10537
10538 if (!do_unwind)
015dc7e1 10539 return true;
57346661
AM
10540
10541 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10542 if (filedata->file_header.e_machine == handlers[i].machtype)
10543 return handlers[i].handler (filedata);
57346661 10544
1b31d05e 10545 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10546 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10547 return true;
57346661
AM
10548}
10549
37c18eed
SD
10550static void
10551dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10552{
10553 switch (entry->d_tag)
10554 {
10555 case DT_AARCH64_BTI_PLT:
1dbade74 10556 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10557 break;
10558 default:
10559 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10560 break;
10561 }
10562 putchar ('\n');
10563}
10564
252b5132 10565static void
978c4450 10566dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10567{
10568 switch (entry->d_tag)
10569 {
10570 case DT_MIPS_FLAGS:
10571 if (entry->d_un.d_val == 0)
4b68bca3 10572 printf (_("NONE"));
252b5132
RH
10573 else
10574 {
10575 static const char * opts[] =
10576 {
10577 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10578 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10579 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10580 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10581 "RLD_ORDER_SAFE"
10582 };
10583 unsigned int cnt;
015dc7e1 10584 bool first = true;
2b692964 10585
60bca95a 10586 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10587 if (entry->d_un.d_val & (1 << cnt))
10588 {
10589 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10590 first = false;
252b5132 10591 }
252b5132
RH
10592 }
10593 break;
103f02d3 10594
252b5132 10595 case DT_MIPS_IVERSION:
84714f86 10596 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10597 printf (_("Interface Version: %s"),
84714f86 10598 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10599 else
f493c217 10600 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10601 entry->d_un.d_ptr);
252b5132 10602 break;
103f02d3 10603
252b5132
RH
10604 case DT_MIPS_TIME_STAMP:
10605 {
d5b07ef4 10606 char timebuf[128];
2cf0635d 10607 struct tm * tmp;
91d6fa6a 10608 time_t atime = entry->d_un.d_val;
82b1b41b 10609
91d6fa6a 10610 tmp = gmtime (&atime);
82b1b41b
NC
10611 /* PR 17531: file: 6accc532. */
10612 if (tmp == NULL)
10613 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10614 else
10615 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10616 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10617 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10618 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10619 }
10620 break;
103f02d3 10621
252b5132
RH
10622 case DT_MIPS_RLD_VERSION:
10623 case DT_MIPS_LOCAL_GOTNO:
10624 case DT_MIPS_CONFLICTNO:
10625 case DT_MIPS_LIBLISTNO:
10626 case DT_MIPS_SYMTABNO:
10627 case DT_MIPS_UNREFEXTNO:
10628 case DT_MIPS_HIPAGENO:
10629 case DT_MIPS_DELTA_CLASS_NO:
10630 case DT_MIPS_DELTA_INSTANCE_NO:
10631 case DT_MIPS_DELTA_RELOC_NO:
10632 case DT_MIPS_DELTA_SYM_NO:
10633 case DT_MIPS_DELTA_CLASSSYM_NO:
10634 case DT_MIPS_COMPACT_SIZE:
c69075ac 10635 print_vma (entry->d_un.d_val, DEC);
252b5132 10636 break;
103f02d3 10637
f16a9783 10638 case DT_MIPS_XHASH:
978c4450
AM
10639 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10640 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10641 /* Falls through. */
10642
103f02d3 10643 default:
4b68bca3 10644 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10645 }
4b68bca3 10646 putchar ('\n');
103f02d3
UD
10647}
10648
103f02d3 10649static void
2cf0635d 10650dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10651{
10652 switch (entry->d_tag)
10653 {
10654 case DT_HP_DLD_FLAGS:
10655 {
10656 static struct
10657 {
10658 long int bit;
2cf0635d 10659 const char * str;
5e220199
NC
10660 }
10661 flags[] =
10662 {
10663 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10664 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10665 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10666 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10667 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10668 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10669 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10670 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10671 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10672 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10673 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10674 { DT_HP_GST, "HP_GST" },
10675 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10676 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10677 { DT_HP_NODELETE, "HP_NODELETE" },
10678 { DT_HP_GROUP, "HP_GROUP" },
10679 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10680 };
015dc7e1 10681 bool first = true;
5e220199 10682 size_t cnt;
625d49fc 10683 uint64_t val = entry->d_un.d_val;
103f02d3 10684
60bca95a 10685 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10686 if (val & flags[cnt].bit)
30800947
NC
10687 {
10688 if (! first)
10689 putchar (' ');
10690 fputs (flags[cnt].str, stdout);
015dc7e1 10691 first = false;
30800947
NC
10692 val ^= flags[cnt].bit;
10693 }
76da6bbe 10694
103f02d3 10695 if (val != 0 || first)
f7a99963
NC
10696 {
10697 if (! first)
10698 putchar (' ');
10699 print_vma (val, HEX);
10700 }
103f02d3
UD
10701 }
10702 break;
76da6bbe 10703
252b5132 10704 default:
f7a99963
NC
10705 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10706 break;
252b5132 10707 }
35b1837e 10708 putchar ('\n');
252b5132
RH
10709}
10710
28f997cf
TG
10711/* VMS vs Unix time offset and factor. */
10712
10713#define VMS_EPOCH_OFFSET 35067168000000000LL
10714#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10715#ifndef INT64_MIN
10716#define INT64_MIN (-9223372036854775807LL - 1)
10717#endif
28f997cf
TG
10718
10719/* Display a VMS time in a human readable format. */
10720
10721static void
0e3c1eeb 10722print_vms_time (int64_t vmstime)
28f997cf 10723{
dccc31de 10724 struct tm *tm = NULL;
28f997cf
TG
10725 time_t unxtime;
10726
dccc31de
AM
10727 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10728 {
10729 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10730 unxtime = vmstime;
10731 if (unxtime == vmstime)
10732 tm = gmtime (&unxtime);
10733 }
10734 if (tm != NULL)
10735 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10736 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10737 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10738}
28f997cf 10739
ecc51f48 10740static void
2cf0635d 10741dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10742{
10743 switch (entry->d_tag)
10744 {
0de14b54 10745 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10746 /* First 3 slots reserved. */
ecc51f48
NC
10747 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10748 printf (" -- ");
10749 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10750 break;
10751
28f997cf 10752 case DT_IA_64_VMS_LINKTIME:
28f997cf 10753 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10754 break;
10755
10756 case DT_IA_64_VMS_LNKFLAGS:
10757 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10758 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10759 printf (" CALL_DEBUG");
10760 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10761 printf (" NOP0BUFS");
10762 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10763 printf (" P0IMAGE");
10764 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10765 printf (" MKTHREADS");
10766 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10767 printf (" UPCALLS");
10768 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10769 printf (" IMGSTA");
10770 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10771 printf (" INITIALIZE");
10772 if (entry->d_un.d_val & VMS_LF_MAIN)
10773 printf (" MAIN");
10774 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10775 printf (" EXE_INIT");
10776 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10777 printf (" TBK_IN_IMG");
10778 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10779 printf (" DBG_IN_IMG");
10780 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10781 printf (" TBK_IN_DSF");
10782 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10783 printf (" DBG_IN_DSF");
10784 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10785 printf (" SIGNATURES");
10786 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10787 printf (" REL_SEG_OFF");
10788 break;
10789
bdf4d63a
JJ
10790 default:
10791 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10792 break;
ecc51f48 10793 }
bdf4d63a 10794 putchar ('\n');
ecc51f48
NC
10795}
10796
015dc7e1 10797static bool
dda8d76d 10798get_32bit_dynamic_section (Filedata * filedata)
252b5132 10799{
2cf0635d
NC
10800 Elf32_External_Dyn * edyn;
10801 Elf32_External_Dyn * ext;
10802 Elf_Internal_Dyn * entry;
103f02d3 10803
978c4450
AM
10804 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10805 filedata->dynamic_addr, 1,
10806 filedata->dynamic_size,
10807 _("dynamic section"));
a6e9f9df 10808 if (!edyn)
015dc7e1 10809 return false;
103f02d3 10810
071436c6
NC
10811 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10812 might not have the luxury of section headers. Look for the DT_NULL
10813 terminator to determine the number of entries. */
978c4450
AM
10814 for (ext = edyn, filedata->dynamic_nent = 0;
10815 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10816 ext++)
10817 {
978c4450 10818 filedata->dynamic_nent++;
ba2685cc
AM
10819 if (BYTE_GET (ext->d_tag) == DT_NULL)
10820 break;
10821 }
252b5132 10822
978c4450
AM
10823 filedata->dynamic_section
10824 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10825 if (filedata->dynamic_section == NULL)
252b5132 10826 {
8b73c356 10827 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10828 (unsigned long) filedata->dynamic_nent);
9ea033b2 10829 free (edyn);
015dc7e1 10830 return false;
9ea033b2 10831 }
252b5132 10832
978c4450
AM
10833 for (ext = edyn, entry = filedata->dynamic_section;
10834 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10835 ext++, entry++)
9ea033b2 10836 {
fb514b26
AM
10837 entry->d_tag = BYTE_GET (ext->d_tag);
10838 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10839 }
10840
9ea033b2
NC
10841 free (edyn);
10842
015dc7e1 10843 return true;
9ea033b2
NC
10844}
10845
015dc7e1 10846static bool
dda8d76d 10847get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10848{
2cf0635d
NC
10849 Elf64_External_Dyn * edyn;
10850 Elf64_External_Dyn * ext;
10851 Elf_Internal_Dyn * entry;
103f02d3 10852
071436c6 10853 /* Read in the data. */
978c4450
AM
10854 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10855 filedata->dynamic_addr, 1,
10856 filedata->dynamic_size,
10857 _("dynamic section"));
a6e9f9df 10858 if (!edyn)
015dc7e1 10859 return false;
103f02d3 10860
071436c6
NC
10861 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10862 might not have the luxury of section headers. Look for the DT_NULL
10863 terminator to determine the number of entries. */
978c4450 10864 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10865 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10866 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10867 ext++)
10868 {
978c4450 10869 filedata->dynamic_nent++;
66543521 10870 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10871 break;
10872 }
252b5132 10873
978c4450
AM
10874 filedata->dynamic_section
10875 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10876 if (filedata->dynamic_section == NULL)
252b5132 10877 {
8b73c356 10878 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10879 (unsigned long) filedata->dynamic_nent);
252b5132 10880 free (edyn);
015dc7e1 10881 return false;
252b5132
RH
10882 }
10883
071436c6 10884 /* Convert from external to internal formats. */
978c4450
AM
10885 for (ext = edyn, entry = filedata->dynamic_section;
10886 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10887 ext++, entry++)
252b5132 10888 {
66543521
AM
10889 entry->d_tag = BYTE_GET (ext->d_tag);
10890 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10891 }
10892
10893 free (edyn);
10894
015dc7e1 10895 return true;
9ea033b2
NC
10896}
10897
4de91c10
AM
10898static bool
10899get_dynamic_section (Filedata *filedata)
10900{
10901 if (filedata->dynamic_section)
10902 return true;
10903
10904 if (is_32bit_elf)
10905 return get_32bit_dynamic_section (filedata);
10906 else
10907 return get_64bit_dynamic_section (filedata);
10908}
10909
e9e44622 10910static void
625d49fc 10911print_dynamic_flags (uint64_t flags)
d1133906 10912{
015dc7e1 10913 bool first = true;
13ae64f3 10914
d1133906
NC
10915 while (flags)
10916 {
625d49fc 10917 uint64_t flag;
d1133906
NC
10918
10919 flag = flags & - flags;
10920 flags &= ~ flag;
10921
e9e44622 10922 if (first)
015dc7e1 10923 first = false;
e9e44622
JJ
10924 else
10925 putc (' ', stdout);
13ae64f3 10926
d1133906
NC
10927 switch (flag)
10928 {
e9e44622
JJ
10929 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10930 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10931 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10932 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10933 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10934 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10935 }
10936 }
e9e44622 10937 puts ("");
d1133906
NC
10938}
10939
625d49fc 10940static uint64_t *
be7d229a 10941get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10942{
10943 unsigned char * e_data;
625d49fc 10944 uint64_t * i_data;
10ca4b04 10945
be7d229a
AM
10946 /* If size_t is smaller than uint64_t, eg because you are building
10947 on a 32-bit host, then make sure that when number is cast to
10948 size_t no information is lost. */
10949 if ((size_t) number != number
10950 || ent_size * number / ent_size != number)
10ca4b04 10951 {
be7d229a 10952 error (_("Size overflow prevents reading %" PRIu64
b8281767 10953 " elements of size %u\n"),
be7d229a 10954 number, ent_size);
10ca4b04
L
10955 return NULL;
10956 }
10957
10958 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10959 attempting to allocate memory when the read is bound to fail. */
10960 if (ent_size * number > filedata->file_size)
10961 {
b8281767 10962 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10963 number);
10ca4b04
L
10964 return NULL;
10965 }
10966
10967 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10968 if (e_data == NULL)
10969 {
b8281767 10970 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10971 number);
10ca4b04
L
10972 return NULL;
10973 }
10974
10975 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10976 {
b8281767 10977 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10978 number * ent_size);
10ca4b04
L
10979 free (e_data);
10980 return NULL;
10981 }
10982
625d49fc 10983 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
10984 if (i_data == NULL)
10985 {
b8281767 10986 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 10987 number);
10ca4b04
L
10988 free (e_data);
10989 return NULL;
10990 }
10991
10992 while (number--)
10993 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10994
10995 free (e_data);
10996
10997 return i_data;
10998}
10999
11000static unsigned long
11001get_num_dynamic_syms (Filedata * filedata)
11002{
11003 unsigned long num_of_syms = 0;
11004
11005 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11006 return num_of_syms;
11007
978c4450 11008 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11009 {
11010 unsigned char nb[8];
11011 unsigned char nc[8];
11012 unsigned int hash_ent_size = 4;
11013
11014 if ((filedata->file_header.e_machine == EM_ALPHA
11015 || filedata->file_header.e_machine == EM_S390
11016 || filedata->file_header.e_machine == EM_S390_OLD)
11017 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11018 hash_ent_size = 8;
11019
11020 if (fseek (filedata->handle,
978c4450
AM
11021 (filedata->archive_file_offset
11022 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11023 sizeof nb + sizeof nc)),
11024 SEEK_SET))
11025 {
11026 error (_("Unable to seek to start of dynamic information\n"));
11027 goto no_hash;
11028 }
11029
11030 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11031 {
11032 error (_("Failed to read in number of buckets\n"));
11033 goto no_hash;
11034 }
11035
11036 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11037 {
11038 error (_("Failed to read in number of chains\n"));
11039 goto no_hash;
11040 }
11041
978c4450
AM
11042 filedata->nbuckets = byte_get (nb, hash_ent_size);
11043 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11044
2482f306
AM
11045 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11046 {
11047 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11048 hash_ent_size);
11049 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11050 hash_ent_size);
001890e1 11051
2482f306
AM
11052 if (filedata->buckets != NULL && filedata->chains != NULL)
11053 num_of_syms = filedata->nchains;
11054 }
ceb9bf11 11055 no_hash:
10ca4b04
L
11056 if (num_of_syms == 0)
11057 {
9db70fc3
AM
11058 free (filedata->buckets);
11059 filedata->buckets = NULL;
11060 free (filedata->chains);
11061 filedata->chains = NULL;
978c4450 11062 filedata->nbuckets = 0;
10ca4b04
L
11063 }
11064 }
11065
978c4450 11066 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11067 {
11068 unsigned char nb[16];
625d49fc
AM
11069 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11070 uint64_t buckets_vma;
10ca4b04 11071 unsigned long hn;
10ca4b04
L
11072
11073 if (fseek (filedata->handle,
978c4450
AM
11074 (filedata->archive_file_offset
11075 + offset_from_vma (filedata,
11076 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11077 sizeof nb)),
11078 SEEK_SET))
11079 {
11080 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11081 goto no_gnu_hash;
11082 }
11083
11084 if (fread (nb, 16, 1, filedata->handle) != 1)
11085 {
11086 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11087 goto no_gnu_hash;
11088 }
11089
978c4450
AM
11090 filedata->ngnubuckets = byte_get (nb, 4);
11091 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11092 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11093 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11094 if (is_32bit_elf)
11095 buckets_vma += bitmaskwords * 4;
11096 else
11097 buckets_vma += bitmaskwords * 8;
11098
11099 if (fseek (filedata->handle,
978c4450 11100 (filedata->archive_file_offset
10ca4b04
L
11101 + offset_from_vma (filedata, buckets_vma, 4)),
11102 SEEK_SET))
11103 {
11104 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11105 goto no_gnu_hash;
11106 }
11107
978c4450
AM
11108 filedata->gnubuckets
11109 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11110
978c4450 11111 if (filedata->gnubuckets == NULL)
90837ea7 11112 goto no_gnu_hash;
10ca4b04 11113
978c4450
AM
11114 for (i = 0; i < filedata->ngnubuckets; i++)
11115 if (filedata->gnubuckets[i] != 0)
10ca4b04 11116 {
978c4450 11117 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11118 goto no_gnu_hash;
10ca4b04 11119
978c4450
AM
11120 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11121 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11122 }
11123
11124 if (maxchain == 0xffffffff)
90837ea7 11125 goto no_gnu_hash;
10ca4b04 11126
978c4450 11127 maxchain -= filedata->gnusymidx;
10ca4b04
L
11128
11129 if (fseek (filedata->handle,
978c4450
AM
11130 (filedata->archive_file_offset
11131 + offset_from_vma (filedata,
11132 buckets_vma + 4 * (filedata->ngnubuckets
11133 + maxchain),
11134 4)),
10ca4b04
L
11135 SEEK_SET))
11136 {
11137 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11138 goto no_gnu_hash;
11139 }
11140
11141 do
11142 {
11143 if (fread (nb, 4, 1, filedata->handle) != 1)
11144 {
11145 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11146 goto no_gnu_hash;
11147 }
11148
11149 if (maxchain + 1 == 0)
90837ea7 11150 goto no_gnu_hash;
10ca4b04
L
11151
11152 ++maxchain;
11153 }
11154 while ((byte_get (nb, 4) & 1) == 0);
11155
11156 if (fseek (filedata->handle,
978c4450
AM
11157 (filedata->archive_file_offset
11158 + offset_from_vma (filedata, (buckets_vma
11159 + 4 * filedata->ngnubuckets),
11160 4)),
10ca4b04
L
11161 SEEK_SET))
11162 {
11163 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11164 goto no_gnu_hash;
11165 }
11166
978c4450
AM
11167 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11168 filedata->ngnuchains = maxchain;
10ca4b04 11169
978c4450 11170 if (filedata->gnuchains == NULL)
90837ea7 11171 goto no_gnu_hash;
10ca4b04 11172
978c4450 11173 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11174 {
11175 if (fseek (filedata->handle,
978c4450 11176 (filedata->archive_file_offset
10ca4b04 11177 + offset_from_vma (filedata, (buckets_vma
978c4450 11178 + 4 * (filedata->ngnubuckets
10ca4b04
L
11179 + maxchain)), 4)),
11180 SEEK_SET))
11181 {
11182 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11183 goto no_gnu_hash;
11184 }
11185
978c4450 11186 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11187 if (filedata->mipsxlat == NULL)
11188 goto no_gnu_hash;
10ca4b04
L
11189 }
11190
978c4450
AM
11191 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11192 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11193 {
625d49fc
AM
11194 uint64_t si = filedata->gnubuckets[hn];
11195 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11196
11197 do
11198 {
978c4450 11199 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11200 {
c31ab5a0
AM
11201 if (off < filedata->ngnuchains
11202 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11203 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11204 }
11205 else
11206 {
11207 if (si >= num_of_syms)
11208 num_of_syms = si + 1;
11209 }
11210 si++;
11211 }
978c4450
AM
11212 while (off < filedata->ngnuchains
11213 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11214 }
11215
90837ea7 11216 if (num_of_syms == 0)
10ca4b04 11217 {
90837ea7 11218 no_gnu_hash:
9db70fc3
AM
11219 free (filedata->mipsxlat);
11220 filedata->mipsxlat = NULL;
11221 free (filedata->gnuchains);
11222 filedata->gnuchains = NULL;
11223 free (filedata->gnubuckets);
11224 filedata->gnubuckets = NULL;
978c4450
AM
11225 filedata->ngnubuckets = 0;
11226 filedata->ngnuchains = 0;
10ca4b04
L
11227 }
11228 }
11229
11230 return num_of_syms;
11231}
11232
b2d38a17
NC
11233/* Parse and display the contents of the dynamic section. */
11234
015dc7e1 11235static bool
dda8d76d 11236process_dynamic_section (Filedata * filedata)
9ea033b2 11237{
2cf0635d 11238 Elf_Internal_Dyn * entry;
9ea033b2 11239
93df3340 11240 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11241 {
11242 if (do_dynamic)
ca0e11aa
NC
11243 {
11244 if (filedata->is_separate)
11245 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11246 filedata->file_name);
11247 else
11248 printf (_("\nThere is no dynamic section in this file.\n"));
11249 }
9ea033b2 11250
015dc7e1 11251 return true;
9ea033b2
NC
11252 }
11253
4de91c10
AM
11254 if (!get_dynamic_section (filedata))
11255 return false;
9ea033b2 11256
252b5132 11257 /* Find the appropriate symbol table. */
978c4450 11258 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11259 {
2482f306
AM
11260 unsigned long num_of_syms;
11261
978c4450
AM
11262 for (entry = filedata->dynamic_section;
11263 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11264 ++entry)
10ca4b04 11265 if (entry->d_tag == DT_SYMTAB)
978c4450 11266 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11267 else if (entry->d_tag == DT_SYMENT)
978c4450 11268 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11269 else if (entry->d_tag == DT_HASH)
978c4450 11270 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11271 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11272 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11273 else if ((filedata->file_header.e_machine == EM_MIPS
11274 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11275 && entry->d_tag == DT_MIPS_XHASH)
11276 {
978c4450
AM
11277 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11278 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11279 }
252b5132 11280
2482f306
AM
11281 num_of_syms = get_num_dynamic_syms (filedata);
11282
11283 if (num_of_syms != 0
11284 && filedata->dynamic_symbols == NULL
11285 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11286 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11287 {
11288 Elf_Internal_Phdr *seg;
625d49fc 11289 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11290
2482f306
AM
11291 if (! get_program_headers (filedata))
11292 {
11293 error (_("Cannot interpret virtual addresses "
11294 "without program headers.\n"));
015dc7e1 11295 return false;
2482f306 11296 }
252b5132 11297
2482f306
AM
11298 for (seg = filedata->program_headers;
11299 seg < filedata->program_headers + filedata->file_header.e_phnum;
11300 ++seg)
11301 {
11302 if (seg->p_type != PT_LOAD)
11303 continue;
252b5132 11304
2482f306
AM
11305 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11306 {
11307 /* See PR 21379 for a reproducer. */
11308 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11309 return false;
2482f306 11310 }
252b5132 11311
2482f306
AM
11312 if (vma >= (seg->p_vaddr & -seg->p_align)
11313 && vma < seg->p_vaddr + seg->p_filesz)
11314 {
11315 /* Since we do not know how big the symbol table is,
11316 we default to reading in up to the end of PT_LOAD
11317 segment and processing that. This is overkill, I
11318 know, but it should work. */
11319 Elf_Internal_Shdr section;
11320 section.sh_offset = (vma - seg->p_vaddr
11321 + seg->p_offset);
11322 section.sh_size = (num_of_syms
11323 * filedata->dynamic_info[DT_SYMENT]);
11324 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11325
11326 if (do_checks
11327 && filedata->dynamic_symtab_section != NULL
11328 && ((filedata->dynamic_symtab_section->sh_offset
11329 != section.sh_offset)
11330 || (filedata->dynamic_symtab_section->sh_size
11331 != section.sh_size)
11332 || (filedata->dynamic_symtab_section->sh_entsize
11333 != section.sh_entsize)))
11334 warn (_("\
11335the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11336
2482f306
AM
11337 section.sh_name = filedata->string_table_length;
11338 filedata->dynamic_symbols
4de91c10 11339 = get_elf_symbols (filedata, &section,
2482f306
AM
11340 &filedata->num_dynamic_syms);
11341 if (filedata->dynamic_symbols == NULL
11342 || filedata->num_dynamic_syms != num_of_syms)
11343 {
11344 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11345 return false;
2482f306
AM
11346 }
11347 break;
11348 }
11349 }
11350 }
11351 }
252b5132
RH
11352
11353 /* Similarly find a string table. */
978c4450
AM
11354 if (filedata->dynamic_strings == NULL)
11355 for (entry = filedata->dynamic_section;
11356 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11357 ++entry)
11358 {
11359 if (entry->d_tag == DT_STRTAB)
978c4450 11360 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11361
10ca4b04 11362 if (entry->d_tag == DT_STRSZ)
978c4450 11363 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11364
978c4450
AM
11365 if (filedata->dynamic_info[DT_STRTAB]
11366 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11367 {
11368 unsigned long offset;
be7d229a 11369 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11370
11371 offset = offset_from_vma (filedata,
978c4450 11372 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11373 str_tab_len);
8ac10c5b
L
11374 if (do_checks
11375 && filedata->dynamic_strtab_section
11376 && ((filedata->dynamic_strtab_section->sh_offset
11377 != (file_ptr) offset)
11378 || (filedata->dynamic_strtab_section->sh_size
11379 != str_tab_len)))
11380 warn (_("\
11381the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11382
978c4450
AM
11383 filedata->dynamic_strings
11384 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11385 _("dynamic string table"));
11386 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11387 {
11388 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11389 break;
11390 }
e3d39609 11391
978c4450 11392 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11393 break;
11394 }
11395 }
252b5132
RH
11396
11397 /* And find the syminfo section if available. */
978c4450 11398 if (filedata->dynamic_syminfo == NULL)
252b5132 11399 {
3e8bba36 11400 unsigned long syminsz = 0;
252b5132 11401
978c4450
AM
11402 for (entry = filedata->dynamic_section;
11403 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11404 ++entry)
252b5132
RH
11405 {
11406 if (entry->d_tag == DT_SYMINENT)
11407 {
11408 /* Note: these braces are necessary to avoid a syntax
11409 error from the SunOS4 C compiler. */
049b0c3a
NC
11410 /* PR binutils/17531: A corrupt file can trigger this test.
11411 So do not use an assert, instead generate an error message. */
11412 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11413 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11414 (int) entry->d_un.d_val);
252b5132
RH
11415 }
11416 else if (entry->d_tag == DT_SYMINSZ)
11417 syminsz = entry->d_un.d_val;
11418 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11419 filedata->dynamic_syminfo_offset
11420 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11421 }
11422
978c4450 11423 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11424 {
2cf0635d
NC
11425 Elf_External_Syminfo * extsyminfo;
11426 Elf_External_Syminfo * extsym;
11427 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11428
11429 /* There is a syminfo section. Read the data. */
3f5e193b 11430 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11431 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11432 1, syminsz, _("symbol information"));
a6e9f9df 11433 if (!extsyminfo)
015dc7e1 11434 return false;
252b5132 11435
978c4450 11436 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11437 {
11438 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11439 free (filedata->dynamic_syminfo);
e3d39609 11440 }
978c4450
AM
11441 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11442 if (filedata->dynamic_syminfo == NULL)
252b5132 11443 {
2482f306
AM
11444 error (_("Out of memory allocating %lu bytes "
11445 "for dynamic symbol info\n"),
8b73c356 11446 (unsigned long) syminsz);
015dc7e1 11447 return false;
252b5132
RH
11448 }
11449
2482f306
AM
11450 filedata->dynamic_syminfo_nent
11451 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11452 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11453 syminfo < (filedata->dynamic_syminfo
11454 + filedata->dynamic_syminfo_nent);
86dba8ee 11455 ++syminfo, ++extsym)
252b5132 11456 {
86dba8ee
AM
11457 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11458 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11459 }
11460
11461 free (extsyminfo);
11462 }
11463 }
11464
978c4450 11465 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11466 {
f253158f
NC
11467 if (filedata->is_separate)
11468 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11469 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11470 (unsigned long) filedata->dynamic_nent),
11471 filedata->file_name,
11472 filedata->dynamic_addr,
11473 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11474 else
11475 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11476 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11477 (unsigned long) filedata->dynamic_nent),
11478 filedata->dynamic_addr,
11479 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11480 }
252b5132
RH
11481 if (do_dynamic)
11482 printf (_(" Tag Type Name/Value\n"));
11483
978c4450
AM
11484 for (entry = filedata->dynamic_section;
11485 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11486 entry++)
252b5132
RH
11487 {
11488 if (do_dynamic)
f7a99963 11489 {
2cf0635d 11490 const char * dtype;
e699b9ff 11491
f7a99963
NC
11492 putchar (' ');
11493 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11494 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11495 printf (" (%s)%*s", dtype,
32ec8896 11496 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11497 }
252b5132
RH
11498
11499 switch (entry->d_tag)
11500 {
d1133906
NC
11501 case DT_FLAGS:
11502 if (do_dynamic)
e9e44622 11503 print_dynamic_flags (entry->d_un.d_val);
d1133906 11504 break;
76da6bbe 11505
252b5132
RH
11506 case DT_AUXILIARY:
11507 case DT_FILTER:
019148e4
L
11508 case DT_CONFIG:
11509 case DT_DEPAUDIT:
11510 case DT_AUDIT:
252b5132
RH
11511 if (do_dynamic)
11512 {
019148e4 11513 switch (entry->d_tag)
b34976b6 11514 {
019148e4
L
11515 case DT_AUXILIARY:
11516 printf (_("Auxiliary library"));
11517 break;
11518
11519 case DT_FILTER:
11520 printf (_("Filter library"));
11521 break;
11522
b34976b6 11523 case DT_CONFIG:
019148e4
L
11524 printf (_("Configuration file"));
11525 break;
11526
11527 case DT_DEPAUDIT:
11528 printf (_("Dependency audit library"));
11529 break;
11530
11531 case DT_AUDIT:
11532 printf (_("Audit library"));
11533 break;
11534 }
252b5132 11535
84714f86 11536 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11537 printf (": [%s]\n",
84714f86 11538 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11539 else
f7a99963
NC
11540 {
11541 printf (": ");
11542 print_vma (entry->d_un.d_val, PREFIX_HEX);
11543 putchar ('\n');
11544 }
252b5132
RH
11545 }
11546 break;
11547
dcefbbbd 11548 case DT_FEATURE:
252b5132
RH
11549 if (do_dynamic)
11550 {
11551 printf (_("Flags:"));
86f55779 11552
252b5132
RH
11553 if (entry->d_un.d_val == 0)
11554 printf (_(" None\n"));
11555 else
11556 {
11557 unsigned long int val = entry->d_un.d_val;
86f55779 11558
252b5132
RH
11559 if (val & DTF_1_PARINIT)
11560 {
11561 printf (" PARINIT");
11562 val ^= DTF_1_PARINIT;
11563 }
dcefbbbd
L
11564 if (val & DTF_1_CONFEXP)
11565 {
11566 printf (" CONFEXP");
11567 val ^= DTF_1_CONFEXP;
11568 }
252b5132
RH
11569 if (val != 0)
11570 printf (" %lx", val);
11571 puts ("");
11572 }
11573 }
11574 break;
11575
11576 case DT_POSFLAG_1:
11577 if (do_dynamic)
11578 {
11579 printf (_("Flags:"));
86f55779 11580
252b5132
RH
11581 if (entry->d_un.d_val == 0)
11582 printf (_(" None\n"));
11583 else
11584 {
11585 unsigned long int val = entry->d_un.d_val;
86f55779 11586
252b5132
RH
11587 if (val & DF_P1_LAZYLOAD)
11588 {
11589 printf (" LAZYLOAD");
11590 val ^= DF_P1_LAZYLOAD;
11591 }
11592 if (val & DF_P1_GROUPPERM)
11593 {
11594 printf (" GROUPPERM");
11595 val ^= DF_P1_GROUPPERM;
11596 }
11597 if (val != 0)
11598 printf (" %lx", val);
11599 puts ("");
11600 }
11601 }
11602 break;
11603
11604 case DT_FLAGS_1:
11605 if (do_dynamic)
11606 {
11607 printf (_("Flags:"));
11608 if (entry->d_un.d_val == 0)
11609 printf (_(" None\n"));
11610 else
11611 {
11612 unsigned long int val = entry->d_un.d_val;
86f55779 11613
252b5132
RH
11614 if (val & DF_1_NOW)
11615 {
11616 printf (" NOW");
11617 val ^= DF_1_NOW;
11618 }
11619 if (val & DF_1_GLOBAL)
11620 {
11621 printf (" GLOBAL");
11622 val ^= DF_1_GLOBAL;
11623 }
11624 if (val & DF_1_GROUP)
11625 {
11626 printf (" GROUP");
11627 val ^= DF_1_GROUP;
11628 }
11629 if (val & DF_1_NODELETE)
11630 {
11631 printf (" NODELETE");
11632 val ^= DF_1_NODELETE;
11633 }
11634 if (val & DF_1_LOADFLTR)
11635 {
11636 printf (" LOADFLTR");
11637 val ^= DF_1_LOADFLTR;
11638 }
11639 if (val & DF_1_INITFIRST)
11640 {
11641 printf (" INITFIRST");
11642 val ^= DF_1_INITFIRST;
11643 }
11644 if (val & DF_1_NOOPEN)
11645 {
11646 printf (" NOOPEN");
11647 val ^= DF_1_NOOPEN;
11648 }
11649 if (val & DF_1_ORIGIN)
11650 {
11651 printf (" ORIGIN");
11652 val ^= DF_1_ORIGIN;
11653 }
11654 if (val & DF_1_DIRECT)
11655 {
11656 printf (" DIRECT");
11657 val ^= DF_1_DIRECT;
11658 }
11659 if (val & DF_1_TRANS)
11660 {
11661 printf (" TRANS");
11662 val ^= DF_1_TRANS;
11663 }
11664 if (val & DF_1_INTERPOSE)
11665 {
11666 printf (" INTERPOSE");
11667 val ^= DF_1_INTERPOSE;
11668 }
f7db6139 11669 if (val & DF_1_NODEFLIB)
dcefbbbd 11670 {
f7db6139
L
11671 printf (" NODEFLIB");
11672 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11673 }
11674 if (val & DF_1_NODUMP)
11675 {
11676 printf (" NODUMP");
11677 val ^= DF_1_NODUMP;
11678 }
34b60028 11679 if (val & DF_1_CONFALT)
dcefbbbd 11680 {
34b60028
L
11681 printf (" CONFALT");
11682 val ^= DF_1_CONFALT;
11683 }
11684 if (val & DF_1_ENDFILTEE)
11685 {
11686 printf (" ENDFILTEE");
11687 val ^= DF_1_ENDFILTEE;
11688 }
11689 if (val & DF_1_DISPRELDNE)
11690 {
11691 printf (" DISPRELDNE");
11692 val ^= DF_1_DISPRELDNE;
11693 }
11694 if (val & DF_1_DISPRELPND)
11695 {
11696 printf (" DISPRELPND");
11697 val ^= DF_1_DISPRELPND;
11698 }
11699 if (val & DF_1_NODIRECT)
11700 {
11701 printf (" NODIRECT");
11702 val ^= DF_1_NODIRECT;
11703 }
11704 if (val & DF_1_IGNMULDEF)
11705 {
11706 printf (" IGNMULDEF");
11707 val ^= DF_1_IGNMULDEF;
11708 }
11709 if (val & DF_1_NOKSYMS)
11710 {
11711 printf (" NOKSYMS");
11712 val ^= DF_1_NOKSYMS;
11713 }
11714 if (val & DF_1_NOHDR)
11715 {
11716 printf (" NOHDR");
11717 val ^= DF_1_NOHDR;
11718 }
11719 if (val & DF_1_EDITED)
11720 {
11721 printf (" EDITED");
11722 val ^= DF_1_EDITED;
11723 }
11724 if (val & DF_1_NORELOC)
11725 {
11726 printf (" NORELOC");
11727 val ^= DF_1_NORELOC;
11728 }
11729 if (val & DF_1_SYMINTPOSE)
11730 {
11731 printf (" SYMINTPOSE");
11732 val ^= DF_1_SYMINTPOSE;
11733 }
11734 if (val & DF_1_GLOBAUDIT)
11735 {
11736 printf (" GLOBAUDIT");
11737 val ^= DF_1_GLOBAUDIT;
11738 }
11739 if (val & DF_1_SINGLETON)
11740 {
11741 printf (" SINGLETON");
11742 val ^= DF_1_SINGLETON;
dcefbbbd 11743 }
5c383f02
RO
11744 if (val & DF_1_STUB)
11745 {
11746 printf (" STUB");
11747 val ^= DF_1_STUB;
11748 }
11749 if (val & DF_1_PIE)
11750 {
11751 printf (" PIE");
11752 val ^= DF_1_PIE;
11753 }
b1202ffa
L
11754 if (val & DF_1_KMOD)
11755 {
11756 printf (" KMOD");
11757 val ^= DF_1_KMOD;
11758 }
11759 if (val & DF_1_WEAKFILTER)
11760 {
11761 printf (" WEAKFILTER");
11762 val ^= DF_1_WEAKFILTER;
11763 }
11764 if (val & DF_1_NOCOMMON)
11765 {
11766 printf (" NOCOMMON");
11767 val ^= DF_1_NOCOMMON;
11768 }
252b5132
RH
11769 if (val != 0)
11770 printf (" %lx", val);
11771 puts ("");
11772 }
11773 }
11774 break;
11775
11776 case DT_PLTREL:
978c4450 11777 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11778 if (do_dynamic)
dda8d76d 11779 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11780 break;
11781
11782 case DT_NULL :
11783 case DT_NEEDED :
11784 case DT_PLTGOT :
11785 case DT_HASH :
11786 case DT_STRTAB :
11787 case DT_SYMTAB :
11788 case DT_RELA :
11789 case DT_INIT :
11790 case DT_FINI :
11791 case DT_SONAME :
11792 case DT_RPATH :
11793 case DT_SYMBOLIC:
11794 case DT_REL :
a7fd1186 11795 case DT_RELR :
252b5132
RH
11796 case DT_DEBUG :
11797 case DT_TEXTREL :
11798 case DT_JMPREL :
019148e4 11799 case DT_RUNPATH :
978c4450 11800 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11801
11802 if (do_dynamic)
11803 {
84714f86 11804 const char *name;
252b5132 11805
84714f86
AM
11806 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11807 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11808 else
d79b3d50 11809 name = NULL;
252b5132
RH
11810
11811 if (name)
11812 {
11813 switch (entry->d_tag)
11814 {
11815 case DT_NEEDED:
11816 printf (_("Shared library: [%s]"), name);
11817
13acb58d
AM
11818 if (filedata->program_interpreter
11819 && streq (name, filedata->program_interpreter))
f7a99963 11820 printf (_(" program interpreter"));
252b5132
RH
11821 break;
11822
11823 case DT_SONAME:
f7a99963 11824 printf (_("Library soname: [%s]"), name);
252b5132
RH
11825 break;
11826
11827 case DT_RPATH:
f7a99963 11828 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11829 break;
11830
019148e4
L
11831 case DT_RUNPATH:
11832 printf (_("Library runpath: [%s]"), name);
11833 break;
11834
252b5132 11835 default:
f7a99963
NC
11836 print_vma (entry->d_un.d_val, PREFIX_HEX);
11837 break;
252b5132
RH
11838 }
11839 }
11840 else
f7a99963
NC
11841 print_vma (entry->d_un.d_val, PREFIX_HEX);
11842
11843 putchar ('\n');
252b5132
RH
11844 }
11845 break;
11846
11847 case DT_PLTRELSZ:
11848 case DT_RELASZ :
11849 case DT_STRSZ :
11850 case DT_RELSZ :
11851 case DT_RELAENT :
a7fd1186
FS
11852 case DT_RELRENT :
11853 case DT_RELRSZ :
252b5132
RH
11854 case DT_SYMENT :
11855 case DT_RELENT :
978c4450 11856 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11857 /* Fall through. */
252b5132
RH
11858 case DT_PLTPADSZ:
11859 case DT_MOVEENT :
11860 case DT_MOVESZ :
04d8355a 11861 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11862 case DT_INIT_ARRAYSZ:
11863 case DT_FINI_ARRAYSZ:
047b2264
JJ
11864 case DT_GNU_CONFLICTSZ:
11865 case DT_GNU_LIBLISTSZ:
252b5132 11866 if (do_dynamic)
f7a99963
NC
11867 {
11868 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11869 printf (_(" (bytes)\n"));
f7a99963 11870 }
252b5132
RH
11871 break;
11872
11873 case DT_VERDEFNUM:
11874 case DT_VERNEEDNUM:
11875 case DT_RELACOUNT:
11876 case DT_RELCOUNT:
11877 if (do_dynamic)
f7a99963
NC
11878 {
11879 print_vma (entry->d_un.d_val, UNSIGNED);
11880 putchar ('\n');
11881 }
252b5132
RH
11882 break;
11883
11884 case DT_SYMINSZ:
11885 case DT_SYMINENT:
11886 case DT_SYMINFO:
11887 case DT_USED:
11888 case DT_INIT_ARRAY:
11889 case DT_FINI_ARRAY:
11890 if (do_dynamic)
11891 {
d79b3d50 11892 if (entry->d_tag == DT_USED
84714f86 11893 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11894 {
84714f86
AM
11895 const char *name
11896 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11897
b34976b6 11898 if (*name)
252b5132
RH
11899 {
11900 printf (_("Not needed object: [%s]\n"), name);
11901 break;
11902 }
11903 }
103f02d3 11904
f7a99963
NC
11905 print_vma (entry->d_un.d_val, PREFIX_HEX);
11906 putchar ('\n');
252b5132
RH
11907 }
11908 break;
11909
11910 case DT_BIND_NOW:
11911 /* The value of this entry is ignored. */
35b1837e
AM
11912 if (do_dynamic)
11913 putchar ('\n');
252b5132 11914 break;
103f02d3 11915
047b2264
JJ
11916 case DT_GNU_PRELINKED:
11917 if (do_dynamic)
11918 {
2cf0635d 11919 struct tm * tmp;
91d6fa6a 11920 time_t atime = entry->d_un.d_val;
047b2264 11921
91d6fa6a 11922 tmp = gmtime (&atime);
071436c6
NC
11923 /* PR 17533 file: 041-1244816-0.004. */
11924 if (tmp == NULL)
5a2cbcf4
L
11925 printf (_("<corrupt time val: %lx"),
11926 (unsigned long) atime);
071436c6
NC
11927 else
11928 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11929 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11930 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11931
11932 }
11933 break;
11934
fdc90cb4 11935 case DT_GNU_HASH:
978c4450 11936 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11937 if (do_dynamic)
11938 {
11939 print_vma (entry->d_un.d_val, PREFIX_HEX);
11940 putchar ('\n');
11941 }
11942 break;
11943
a5da3dee
VDM
11944 case DT_GNU_FLAGS_1:
11945 if (do_dynamic)
11946 {
11947 printf (_("Flags:"));
11948 if (entry->d_un.d_val == 0)
11949 printf (_(" None\n"));
11950 else
11951 {
11952 unsigned long int val = entry->d_un.d_val;
11953
11954 if (val & DF_GNU_1_UNIQUE)
11955 {
11956 printf (" UNIQUE");
11957 val ^= DF_GNU_1_UNIQUE;
11958 }
11959 if (val != 0)
11960 printf (" %lx", val);
11961 puts ("");
11962 }
11963 }
11964 break;
11965
252b5132
RH
11966 default:
11967 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11968 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11969 = entry->d_un.d_val;
252b5132
RH
11970
11971 if (do_dynamic)
11972 {
dda8d76d 11973 switch (filedata->file_header.e_machine)
252b5132 11974 {
37c18eed
SD
11975 case EM_AARCH64:
11976 dynamic_section_aarch64_val (entry);
11977 break;
252b5132 11978 case EM_MIPS:
4fe85591 11979 case EM_MIPS_RS3_LE:
978c4450 11980 dynamic_section_mips_val (filedata, entry);
252b5132 11981 break;
103f02d3 11982 case EM_PARISC:
b2d38a17 11983 dynamic_section_parisc_val (entry);
103f02d3 11984 break;
ecc51f48 11985 case EM_IA_64:
b2d38a17 11986 dynamic_section_ia64_val (entry);
ecc51f48 11987 break;
252b5132 11988 default:
f7a99963
NC
11989 print_vma (entry->d_un.d_val, PREFIX_HEX);
11990 putchar ('\n');
252b5132
RH
11991 }
11992 }
11993 break;
11994 }
11995 }
11996
015dc7e1 11997 return true;
252b5132
RH
11998}
11999
12000static char *
d3ba0551 12001get_ver_flags (unsigned int flags)
252b5132 12002{
6d4f21f6 12003 static char buff[128];
252b5132
RH
12004
12005 buff[0] = 0;
12006
12007 if (flags == 0)
12008 return _("none");
12009
12010 if (flags & VER_FLG_BASE)
7bb1ad17 12011 strcat (buff, "BASE");
252b5132
RH
12012
12013 if (flags & VER_FLG_WEAK)
12014 {
12015 if (flags & VER_FLG_BASE)
7bb1ad17 12016 strcat (buff, " | ");
252b5132 12017
7bb1ad17 12018 strcat (buff, "WEAK");
252b5132
RH
12019 }
12020
44ec90b9
RO
12021 if (flags & VER_FLG_INFO)
12022 {
12023 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12024 strcat (buff, " | ");
44ec90b9 12025
7bb1ad17 12026 strcat (buff, "INFO");
44ec90b9
RO
12027 }
12028
12029 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12030 {
12031 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12032 strcat (buff, " | ");
12033
12034 strcat (buff, _("<unknown>"));
12035 }
252b5132
RH
12036
12037 return buff;
12038}
12039
12040/* Display the contents of the version sections. */
98fb390a 12041
015dc7e1 12042static bool
dda8d76d 12043process_version_sections (Filedata * filedata)
252b5132 12044{
2cf0635d 12045 Elf_Internal_Shdr * section;
b34976b6 12046 unsigned i;
015dc7e1 12047 bool found = false;
252b5132
RH
12048
12049 if (! do_version)
015dc7e1 12050 return true;
252b5132 12051
dda8d76d
NC
12052 for (i = 0, section = filedata->section_headers;
12053 i < filedata->file_header.e_shnum;
b34976b6 12054 i++, section++)
252b5132
RH
12055 {
12056 switch (section->sh_type)
12057 {
12058 case SHT_GNU_verdef:
12059 {
2cf0635d 12060 Elf_External_Verdef * edefs;
452bf675
AM
12061 unsigned long idx;
12062 unsigned long cnt;
2cf0635d 12063 char * endbuf;
252b5132 12064
015dc7e1 12065 found = true;
252b5132 12066
ca0e11aa
NC
12067 if (filedata->is_separate)
12068 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12069 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12070 section->sh_info),
12071 filedata->file_name,
12072 printable_section_name (filedata, section),
12073 section->sh_info);
12074 else
12075 printf (ngettext ("\nVersion definition section '%s' "
12076 "contains %u entry:\n",
12077 "\nVersion definition section '%s' "
12078 "contains %u entries:\n",
12079 section->sh_info),
12080 printable_section_name (filedata, section),
12081 section->sh_info);
047c3dbf 12082
625d49fc 12083 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
233f82cf 12084 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12085 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12086 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12087
3f5e193b 12088 edefs = (Elf_External_Verdef *)
dda8d76d 12089 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12090 _("version definition section"));
a6e9f9df
AM
12091 if (!edefs)
12092 break;
59245841 12093 endbuf = (char *) edefs + section->sh_size;
252b5132 12094
1445030f 12095 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12096 {
2cf0635d
NC
12097 char * vstart;
12098 Elf_External_Verdef * edef;
b34976b6 12099 Elf_Internal_Verdef ent;
2cf0635d 12100 Elf_External_Verdaux * eaux;
b34976b6 12101 Elf_Internal_Verdaux aux;
452bf675 12102 unsigned long isum;
b34976b6 12103 int j;
103f02d3 12104
252b5132 12105 vstart = ((char *) edefs) + idx;
54806181
AM
12106 if (vstart + sizeof (*edef) > endbuf)
12107 break;
252b5132
RH
12108
12109 edef = (Elf_External_Verdef *) vstart;
12110
12111 ent.vd_version = BYTE_GET (edef->vd_version);
12112 ent.vd_flags = BYTE_GET (edef->vd_flags);
12113 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12114 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12115 ent.vd_hash = BYTE_GET (edef->vd_hash);
12116 ent.vd_aux = BYTE_GET (edef->vd_aux);
12117 ent.vd_next = BYTE_GET (edef->vd_next);
12118
452bf675 12119 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12120 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12121
12122 printf (_(" Index: %d Cnt: %d "),
12123 ent.vd_ndx, ent.vd_cnt);
12124
452bf675 12125 /* Check for overflow. */
1445030f 12126 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12127 break;
12128
252b5132
RH
12129 vstart += ent.vd_aux;
12130
1445030f
AM
12131 if (vstart + sizeof (*eaux) > endbuf)
12132 break;
252b5132
RH
12133 eaux = (Elf_External_Verdaux *) vstart;
12134
12135 aux.vda_name = BYTE_GET (eaux->vda_name);
12136 aux.vda_next = BYTE_GET (eaux->vda_next);
12137
84714f86 12138 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12139 printf (_("Name: %s\n"),
84714f86 12140 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12141 else
12142 printf (_("Name index: %ld\n"), aux.vda_name);
12143
12144 isum = idx + ent.vd_aux;
12145
b34976b6 12146 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12147 {
1445030f
AM
12148 if (aux.vda_next < sizeof (*eaux)
12149 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12150 {
12151 warn (_("Invalid vda_next field of %lx\n"),
12152 aux.vda_next);
12153 j = ent.vd_cnt;
12154 break;
12155 }
dd24e3da 12156 /* Check for overflow. */
7e26601c 12157 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12158 break;
12159
252b5132
RH
12160 isum += aux.vda_next;
12161 vstart += aux.vda_next;
12162
54806181
AM
12163 if (vstart + sizeof (*eaux) > endbuf)
12164 break;
1445030f 12165 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12166
12167 aux.vda_name = BYTE_GET (eaux->vda_name);
12168 aux.vda_next = BYTE_GET (eaux->vda_next);
12169
84714f86 12170 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12171 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12172 isum, j,
84714f86 12173 get_dynamic_name (filedata, aux.vda_name));
252b5132 12174 else
452bf675 12175 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12176 isum, j, aux.vda_name);
12177 }
dd24e3da 12178
54806181
AM
12179 if (j < ent.vd_cnt)
12180 printf (_(" Version def aux past end of section\n"));
252b5132 12181
c9f02c3e
MR
12182 /* PR 17531:
12183 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12184 if (ent.vd_next < sizeof (*edef)
12185 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12186 {
12187 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12188 cnt = section->sh_info;
12189 break;
12190 }
452bf675 12191 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12192 break;
12193
252b5132
RH
12194 idx += ent.vd_next;
12195 }
dd24e3da 12196
54806181
AM
12197 if (cnt < section->sh_info)
12198 printf (_(" Version definition past end of section\n"));
252b5132
RH
12199
12200 free (edefs);
12201 }
12202 break;
103f02d3 12203
252b5132
RH
12204 case SHT_GNU_verneed:
12205 {
2cf0635d 12206 Elf_External_Verneed * eneed;
452bf675
AM
12207 unsigned long idx;
12208 unsigned long cnt;
2cf0635d 12209 char * endbuf;
252b5132 12210
015dc7e1 12211 found = true;
252b5132 12212
ca0e11aa
NC
12213 if (filedata->is_separate)
12214 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12215 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12216 section->sh_info),
12217 filedata->file_name,
12218 printable_section_name (filedata, section),
12219 section->sh_info);
12220 else
12221 printf (ngettext ("\nVersion needs section '%s' "
12222 "contains %u entry:\n",
12223 "\nVersion needs section '%s' "
12224 "contains %u entries:\n",
12225 section->sh_info),
12226 printable_section_name (filedata, section),
12227 section->sh_info);
047c3dbf 12228
625d49fc 12229 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12230 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12231 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12232 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12233
dda8d76d 12234 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12235 section->sh_offset, 1,
12236 section->sh_size,
9cf03b7e 12237 _("Version Needs section"));
a6e9f9df
AM
12238 if (!eneed)
12239 break;
59245841 12240 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12241
12242 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12243 {
2cf0635d 12244 Elf_External_Verneed * entry;
b34976b6 12245 Elf_Internal_Verneed ent;
452bf675 12246 unsigned long isum;
b34976b6 12247 int j;
2cf0635d 12248 char * vstart;
252b5132
RH
12249
12250 vstart = ((char *) eneed) + idx;
54806181
AM
12251 if (vstart + sizeof (*entry) > endbuf)
12252 break;
252b5132
RH
12253
12254 entry = (Elf_External_Verneed *) vstart;
12255
12256 ent.vn_version = BYTE_GET (entry->vn_version);
12257 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12258 ent.vn_file = BYTE_GET (entry->vn_file);
12259 ent.vn_aux = BYTE_GET (entry->vn_aux);
12260 ent.vn_next = BYTE_GET (entry->vn_next);
12261
452bf675 12262 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12263
84714f86 12264 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12265 printf (_(" File: %s"),
84714f86 12266 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12267 else
12268 printf (_(" File: %lx"), ent.vn_file);
12269
12270 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12271
dd24e3da 12272 /* Check for overflow. */
7e26601c 12273 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12274 break;
252b5132
RH
12275 vstart += ent.vn_aux;
12276
12277 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12278 {
2cf0635d 12279 Elf_External_Vernaux * eaux;
b34976b6 12280 Elf_Internal_Vernaux aux;
252b5132 12281
54806181
AM
12282 if (vstart + sizeof (*eaux) > endbuf)
12283 break;
252b5132
RH
12284 eaux = (Elf_External_Vernaux *) vstart;
12285
12286 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12287 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12288 aux.vna_other = BYTE_GET (eaux->vna_other);
12289 aux.vna_name = BYTE_GET (eaux->vna_name);
12290 aux.vna_next = BYTE_GET (eaux->vna_next);
12291
84714f86 12292 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12293 printf (_(" %#06lx: Name: %s"),
84714f86 12294 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12295 else
452bf675 12296 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12297 isum, aux.vna_name);
12298
12299 printf (_(" Flags: %s Version: %d\n"),
12300 get_ver_flags (aux.vna_flags), aux.vna_other);
12301
1445030f
AM
12302 if (aux.vna_next < sizeof (*eaux)
12303 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12304 {
12305 warn (_("Invalid vna_next field of %lx\n"),
12306 aux.vna_next);
12307 j = ent.vn_cnt;
12308 break;
12309 }
1445030f
AM
12310 /* Check for overflow. */
12311 if (aux.vna_next > (size_t) (endbuf - vstart))
12312 break;
252b5132
RH
12313 isum += aux.vna_next;
12314 vstart += aux.vna_next;
12315 }
9cf03b7e 12316
54806181 12317 if (j < ent.vn_cnt)
f9a6a8f0 12318 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12319
1445030f
AM
12320 if (ent.vn_next < sizeof (*entry)
12321 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12322 {
452bf675 12323 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12324 cnt = section->sh_info;
12325 break;
12326 }
1445030f
AM
12327 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12328 break;
252b5132
RH
12329 idx += ent.vn_next;
12330 }
9cf03b7e 12331
54806181 12332 if (cnt < section->sh_info)
9cf03b7e 12333 warn (_("Missing Version Needs information\n"));
103f02d3 12334
252b5132
RH
12335 free (eneed);
12336 }
12337 break;
12338
12339 case SHT_GNU_versym:
12340 {
2cf0635d 12341 Elf_Internal_Shdr * link_section;
8b73c356
NC
12342 size_t total;
12343 unsigned int cnt;
2cf0635d
NC
12344 unsigned char * edata;
12345 unsigned short * data;
12346 char * strtab;
12347 Elf_Internal_Sym * symbols;
12348 Elf_Internal_Shdr * string_sec;
ba5cdace 12349 unsigned long num_syms;
d3ba0551 12350 long off;
252b5132 12351
dda8d76d 12352 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12353 break;
12354
dda8d76d 12355 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12356 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12357
dda8d76d 12358 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12359 break;
12360
015dc7e1 12361 found = true;
252b5132 12362
4de91c10 12363 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12364 if (symbols == NULL)
12365 break;
252b5132 12366
dda8d76d 12367 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12368
dda8d76d 12369 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12370 string_sec->sh_size,
12371 _("version string table"));
a6e9f9df 12372 if (!strtab)
0429c154
MS
12373 {
12374 free (symbols);
12375 break;
12376 }
252b5132 12377
ca0e11aa
NC
12378 if (filedata->is_separate)
12379 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12380 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12381 total),
12382 filedata->file_name,
12383 printable_section_name (filedata, section),
12384 (unsigned long) total);
12385 else
12386 printf (ngettext ("\nVersion symbols section '%s' "
12387 "contains %lu entry:\n",
12388 "\nVersion symbols section '%s' "
12389 "contains %lu entries:\n",
12390 total),
12391 printable_section_name (filedata, section),
12392 (unsigned long) total);
252b5132 12393
625d49fc 12394 printf (_(" Addr: 0x%016" PRIx64), 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
625d49fc 13126print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
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
928c411d 13416 uint64_t size = byte_get (data, 8);
0f03783c
NC
13417 data += 8;
13418
928c411d 13419 uint64_t slot = byte_get (data, 4);
0f03783c
NC
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
31e5a3a3 13429 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13430 * comdat_key == 0 ? "-" : (char *) comdat_key,
13431 get_lto_kind (kind),
13432 get_lto_visibility (visibility),
31e5a3a3
AM
13433 size,
13434 slot,
0f03783c 13435 get_lto_sym_type (sym_type),
31e5a3a3 13436 sec_kind);
0f03783c
NC
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 {
31e5a3a3 13448 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13449 * comdat_key == 0 ? "-" : (char *) comdat_key,
13450 get_lto_kind (kind),
13451 get_lto_visibility (visibility),
31e5a3a3
AM
13452 size,
13453 slot);
0f03783c
NC
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 13632 unsigned long hn;
625d49fc 13633 uint64_t si;
66543521
AM
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 13738 {
625d49fc 13739 uint64_t off, length = 1;
fdc90cb4 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 {
625d49fc 13974 uint64_t 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;
625d49fc 14054 uint64_t 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 {
625d49fc
AM
14085 static uint64_t saved_sym1 = 0;
14086 static uint64_t saved_sym2 = 0;
14087 static uint64_t value;
6ff71e76 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 14267 case EM_NDS32:
81c5e376 14268 return reloc_type == 20; /* R_NDS32_32_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. */
f6c1a2d5
NC
14331 case EM_XGATE:
14332 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14333 case EM_XSTORMY16:
14334 return reloc_type == 1; /* R_XSTROMY16_32. */
14335 case EM_XTENSA_OLD:
14336 case EM_XTENSA:
14337 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14338 case EM_Z80:
14339 return reloc_type == 6; /* R_Z80_32. */
aca88567 14340 default:
bee0ee85
NC
14341 {
14342 static unsigned int prev_warn = 0;
14343
14344 /* Avoid repeating the same warning multiple times. */
dda8d76d 14345 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14346 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14347 filedata->file_header.e_machine);
14348 prev_warn = filedata->file_header.e_machine;
015dc7e1 14349 return false;
bee0ee85 14350 }
aca88567
NC
14351 }
14352}
14353
14354/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14355 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14356
015dc7e1 14357static bool
dda8d76d 14358is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14359{
dda8d76d 14360 switch (filedata->file_header.e_machine)
d347c9df 14361 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14362 {
41e92641 14363 case EM_386:
22abe556 14364 case EM_IAMCU:
3e0873ac 14365 return reloc_type == 2; /* R_386_PC32. */
aca88567 14366 case EM_68K:
3e0873ac 14367 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14368 case EM_AARCH64:
14369 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14370 case EM_ADAPTEVA_EPIPHANY:
14371 return reloc_type == 6;
aca88567
NC
14372 case EM_ALPHA:
14373 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14374 case EM_ARC_COMPACT:
14375 case EM_ARC_COMPACT2:
14376 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14377 case EM_ARM:
3e0873ac 14378 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14379 case EM_AVR_OLD:
14380 case EM_AVR:
14381 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14382 case EM_LOONGARCH:
14383 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14384 case EM_MICROBLAZE:
14385 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14386 case EM_OR1K:
14387 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14388 case EM_PARISC:
85acf597 14389 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14390 case EM_PPC:
14391 return reloc_type == 26; /* R_PPC_REL32. */
14392 case EM_PPC64:
3e0873ac 14393 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14394 case EM_RISCV:
14395 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14396 case EM_S390_OLD:
14397 case EM_S390:
3e0873ac 14398 return reloc_type == 5; /* R_390_PC32. */
aca88567 14399 case EM_SH:
3e0873ac 14400 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14401 case EM_SPARC32PLUS:
14402 case EM_SPARCV9:
14403 case EM_SPARC:
3e0873ac 14404 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14405 case EM_SPU:
14406 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14407 case EM_TILEGX:
14408 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14409 case EM_TILEPRO:
14410 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14411 case EM_VISIUM:
14412 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14413 case EM_X86_64:
8a9036a4 14414 case EM_L1OM:
7a9068fe 14415 case EM_K1OM:
3e0873ac 14416 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14417 case EM_VAX:
14418 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14419 case EM_XTENSA_OLD:
14420 case EM_XTENSA:
14421 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14422 default:
14423 /* Do not abort or issue an error message here. Not all targets use
14424 pc-relative 32-bit relocs in their DWARF debug information and we
14425 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14426 more helpful warning message will be generated by apply_relocations
14427 anyway, so just return. */
015dc7e1 14428 return false;
aca88567
NC
14429 }
14430}
14431
14432/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14433 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14434
015dc7e1 14435static bool
dda8d76d 14436is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14437{
dda8d76d 14438 switch (filedata->file_header.e_machine)
aca88567 14439 {
a06ea964
NC
14440 case EM_AARCH64:
14441 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14442 case EM_ALPHA:
14443 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14444 case EM_IA_64:
262cdac7
AM
14445 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14446 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14447 case EM_LOONGARCH:
14448 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14449 case EM_PARISC:
14450 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14451 case EM_PPC64:
14452 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14453 case EM_RISCV:
14454 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14455 case EM_SPARC32PLUS:
14456 case EM_SPARCV9:
14457 case EM_SPARC:
714da62f
NC
14458 return reloc_type == 32 /* R_SPARC_64. */
14459 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14460 case EM_X86_64:
8a9036a4 14461 case EM_L1OM:
7a9068fe 14462 case EM_K1OM:
aca88567 14463 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14464 case EM_S390_OLD:
14465 case EM_S390:
aa137e4d
NC
14466 return reloc_type == 22; /* R_S390_64. */
14467 case EM_TILEGX:
14468 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14469 case EM_MIPS:
aa137e4d 14470 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14471 default:
015dc7e1 14472 return false;
aca88567
NC
14473 }
14474}
14475
85acf597
RH
14476/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14477 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14478
015dc7e1 14479static bool
dda8d76d 14480is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14481{
dda8d76d 14482 switch (filedata->file_header.e_machine)
85acf597 14483 {
a06ea964
NC
14484 case EM_AARCH64:
14485 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14486 case EM_ALPHA:
aa137e4d 14487 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14488 case EM_IA_64:
262cdac7
AM
14489 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14490 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14491 case EM_PARISC:
aa137e4d 14492 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14493 case EM_PPC64:
aa137e4d 14494 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14495 case EM_SPARC32PLUS:
14496 case EM_SPARCV9:
14497 case EM_SPARC:
aa137e4d 14498 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14499 case EM_X86_64:
8a9036a4 14500 case EM_L1OM:
7a9068fe 14501 case EM_K1OM:
aa137e4d 14502 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14503 case EM_S390_OLD:
14504 case EM_S390:
aa137e4d
NC
14505 return reloc_type == 23; /* R_S390_PC64. */
14506 case EM_TILEGX:
14507 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14508 default:
015dc7e1 14509 return false;
85acf597
RH
14510 }
14511}
14512
4dc3c23d
AM
14513/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14514 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14515
015dc7e1 14516static bool
dda8d76d 14517is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14518{
dda8d76d 14519 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14520 {
14521 case EM_CYGNUS_MN10200:
14522 case EM_MN10200:
14523 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14524 case EM_FT32:
14525 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14526 case EM_Z80:
14527 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14528 default:
015dc7e1 14529 return false;
4dc3c23d
AM
14530 }
14531}
14532
aca88567
NC
14533/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14534 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14535
015dc7e1 14536static bool
dda8d76d 14537is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14538{
d347c9df 14539 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14540 switch (filedata->file_header.e_machine)
4b78141a 14541 {
886a2506
NC
14542 case EM_ARC:
14543 case EM_ARC_COMPACT:
14544 case EM_ARC_COMPACT2:
14545 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14546 case EM_ADAPTEVA_EPIPHANY:
14547 return reloc_type == 5;
aca88567
NC
14548 case EM_AVR_OLD:
14549 case EM_AVR:
14550 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14551 case EM_CYGNUS_D10V:
14552 case EM_D10V:
14553 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14554 case EM_FT32:
14555 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14556 case EM_H8S:
14557 case EM_H8_300:
14558 case EM_H8_300H:
aca88567
NC
14559 return reloc_type == R_H8_DIR16;
14560 case EM_IP2K_OLD:
14561 case EM_IP2K:
14562 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14563 case EM_M32C_OLD:
f4236fe4
DD
14564 case EM_M32C:
14565 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14566 case EM_CYGNUS_MN10200:
14567 case EM_MN10200:
14568 return reloc_type == 2; /* R_MN10200_16. */
14569 case EM_CYGNUS_MN10300:
14570 case EM_MN10300:
14571 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14572 case EM_MSP430:
dda8d76d 14573 if (uses_msp430x_relocs (filedata))
13761a11 14574 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14575 /* Fall through. */
78c8d46c 14576 case EM_MSP430_OLD:
aca88567 14577 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14578 case EM_NDS32:
81c5e376 14579 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14580 case EM_ALTERA_NIOS2:
36591ba1 14581 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14582 case EM_NIOS32:
14583 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14584 case EM_OR1K:
14585 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14586 case EM_RISCV:
14587 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14588 case EM_TI_PRU:
14589 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14590 case EM_TI_C6000:
14591 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14592 case EM_VISIUM:
14593 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14594 case EM_XGATE:
14595 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14596 case EM_Z80:
14597 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14598 default:
015dc7e1 14599 return false;
4b78141a
NC
14600 }
14601}
14602
39e07931
AS
14603/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14604 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14605
015dc7e1 14606static bool
39e07931
AS
14607is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14608{
14609 switch (filedata->file_header.e_machine)
14610 {
14611 case EM_RISCV:
14612 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14613 case EM_Z80:
14614 return reloc_type == 1; /* R_Z80_8. */
39e07931 14615 default:
015dc7e1 14616 return false;
39e07931
AS
14617 }
14618}
14619
14620/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14621 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14622
015dc7e1 14623static bool
39e07931
AS
14624is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14625{
14626 switch (filedata->file_header.e_machine)
14627 {
14628 case EM_RISCV:
14629 return reloc_type == 53; /* R_RISCV_SET6. */
14630 default:
015dc7e1 14631 return false;
39e07931
AS
14632 }
14633}
14634
03336641
JW
14635/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14636 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14637
015dc7e1 14638static bool
03336641
JW
14639is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14640{
14641 /* Please keep this table alpha-sorted for ease of visual lookup. */
14642 switch (filedata->file_header.e_machine)
14643 {
14644 case EM_RISCV:
14645 return reloc_type == 35; /* R_RISCV_ADD32. */
14646 default:
015dc7e1 14647 return false;
03336641
JW
14648 }
14649}
14650
14651/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14652 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14653
015dc7e1 14654static bool
03336641
JW
14655is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14656{
14657 /* Please keep this table alpha-sorted for ease of visual lookup. */
14658 switch (filedata->file_header.e_machine)
14659 {
14660 case EM_RISCV:
14661 return reloc_type == 39; /* R_RISCV_SUB32. */
14662 default:
015dc7e1 14663 return false;
03336641
JW
14664 }
14665}
14666
14667/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14668 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14669
015dc7e1 14670static bool
03336641
JW
14671is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14672{
14673 /* Please keep this table alpha-sorted for ease of visual lookup. */
14674 switch (filedata->file_header.e_machine)
14675 {
14676 case EM_RISCV:
14677 return reloc_type == 36; /* R_RISCV_ADD64. */
14678 default:
015dc7e1 14679 return false;
03336641
JW
14680 }
14681}
14682
14683/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14684 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14685
015dc7e1 14686static bool
03336641
JW
14687is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14688{
14689 /* Please keep this table alpha-sorted for ease of visual lookup. */
14690 switch (filedata->file_header.e_machine)
14691 {
14692 case EM_RISCV:
14693 return reloc_type == 40; /* R_RISCV_SUB64. */
14694 default:
015dc7e1 14695 return false;
03336641
JW
14696 }
14697}
14698
14699/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14700 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14701
015dc7e1 14702static bool
03336641
JW
14703is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14704{
14705 /* Please keep this table alpha-sorted for ease of visual lookup. */
14706 switch (filedata->file_header.e_machine)
14707 {
14708 case EM_RISCV:
14709 return reloc_type == 34; /* R_RISCV_ADD16. */
14710 default:
015dc7e1 14711 return false;
03336641
JW
14712 }
14713}
14714
14715/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14716 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14717
015dc7e1 14718static bool
03336641
JW
14719is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14720{
14721 /* Please keep this table alpha-sorted for ease of visual lookup. */
14722 switch (filedata->file_header.e_machine)
14723 {
14724 case EM_RISCV:
14725 return reloc_type == 38; /* R_RISCV_SUB16. */
14726 default:
015dc7e1 14727 return false;
03336641
JW
14728 }
14729}
14730
14731/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14732 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14733
015dc7e1 14734static bool
03336641
JW
14735is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14736{
14737 /* Please keep this table alpha-sorted for ease of visual lookup. */
14738 switch (filedata->file_header.e_machine)
14739 {
14740 case EM_RISCV:
14741 return reloc_type == 33; /* R_RISCV_ADD8. */
14742 default:
015dc7e1 14743 return false;
03336641
JW
14744 }
14745}
14746
14747/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14748 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14749
015dc7e1 14750static bool
03336641
JW
14751is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14752{
14753 /* Please keep this table alpha-sorted for ease of visual lookup. */
14754 switch (filedata->file_header.e_machine)
14755 {
14756 case EM_RISCV:
14757 return reloc_type == 37; /* R_RISCV_SUB8. */
14758 default:
015dc7e1 14759 return false;
03336641
JW
14760 }
14761}
14762
39e07931
AS
14763/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14764 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14765
015dc7e1 14766static bool
39e07931
AS
14767is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14768{
14769 switch (filedata->file_header.e_machine)
14770 {
14771 case EM_RISCV:
14772 return reloc_type == 52; /* R_RISCV_SUB6. */
14773 default:
015dc7e1 14774 return false;
39e07931
AS
14775 }
14776}
14777
2a7b2e88
JK
14778/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14779 relocation entries (possibly formerly used for SHT_GROUP sections). */
14780
015dc7e1 14781static bool
dda8d76d 14782is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14783{
dda8d76d 14784 switch (filedata->file_header.e_machine)
2a7b2e88 14785 {
cb8f3167 14786 case EM_386: /* R_386_NONE. */
d347c9df 14787 case EM_68K: /* R_68K_NONE. */
cfb8c092 14788 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14789 case EM_ALPHA: /* R_ALPHA_NONE. */
14790 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14791 case EM_ARC: /* R_ARC_NONE. */
886a2506 14792 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14793 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14794 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14795 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14796 case EM_FT32: /* R_FT32_NONE. */
14797 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14798 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14799 case EM_L1OM: /* R_X86_64_NONE. */
14800 case EM_M32R: /* R_M32R_NONE. */
14801 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14802 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14803 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14804 case EM_NIOS32: /* R_NIOS_NONE. */
14805 case EM_OR1K: /* R_OR1K_NONE. */
14806 case EM_PARISC: /* R_PARISC_NONE. */
14807 case EM_PPC64: /* R_PPC64_NONE. */
14808 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14809 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14810 case EM_S390: /* R_390_NONE. */
14811 case EM_S390_OLD:
14812 case EM_SH: /* R_SH_NONE. */
14813 case EM_SPARC32PLUS:
14814 case EM_SPARC: /* R_SPARC_NONE. */
14815 case EM_SPARCV9:
aa137e4d
NC
14816 case EM_TILEGX: /* R_TILEGX_NONE. */
14817 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14818 case EM_TI_C6000:/* R_C6000_NONE. */
14819 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14820 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14821 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14822 return reloc_type == 0;
d347c9df 14823
a06ea964
NC
14824 case EM_AARCH64:
14825 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14826 case EM_AVR_OLD:
14827 case EM_AVR:
14828 return (reloc_type == 0 /* R_AVR_NONE. */
14829 || reloc_type == 30 /* R_AVR_DIFF8. */
14830 || reloc_type == 31 /* R_AVR_DIFF16. */
14831 || reloc_type == 32 /* R_AVR_DIFF32. */);
14832 case EM_METAG:
14833 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14834 case EM_NDS32:
81c5e376
AM
14835 return (reloc_type == 0 /* R_NDS32_NONE. */
14836 || reloc_type == 205 /* R_NDS32_DIFF8. */
14837 || reloc_type == 206 /* R_NDS32_DIFF16. */
14838 || reloc_type == 207 /* R_NDS32_DIFF32. */
14839 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14840 case EM_TI_PRU:
14841 return (reloc_type == 0 /* R_PRU_NONE. */
14842 || reloc_type == 65 /* R_PRU_DIFF8. */
14843 || reloc_type == 66 /* R_PRU_DIFF16. */
14844 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14845 case EM_XTENSA_OLD:
14846 case EM_XTENSA:
4dc3c23d
AM
14847 return (reloc_type == 0 /* R_XTENSA_NONE. */
14848 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14849 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14850 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14851 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14852 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14853 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14854 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14855 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14856 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14857 }
015dc7e1 14858 return false;
2a7b2e88
JK
14859}
14860
d1c4b12b
NC
14861/* Returns TRUE if there is a relocation against
14862 section NAME at OFFSET bytes. */
14863
015dc7e1 14864bool
31e5a3a3 14865reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14866{
14867 Elf_Internal_Rela * relocs;
14868 Elf_Internal_Rela * rp;
14869
14870 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14871 return false;
d1c4b12b
NC
14872
14873 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14874
14875 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14876 if (rp->r_offset == offset)
015dc7e1 14877 return true;
d1c4b12b 14878
015dc7e1 14879 return false;
d1c4b12b
NC
14880}
14881
cf13d699 14882/* Apply relocations to a section.
32ec8896
NC
14883 Returns TRUE upon success, FALSE otherwise.
14884 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14885 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14886 will be set to the number of relocs loaded.
14887
cf13d699 14888 Note: So far support has been added only for those relocations
32ec8896
NC
14889 which can be found in debug sections. FIXME: Add support for
14890 more relocations ? */
1b315056 14891
015dc7e1 14892static bool
be7d229a
AM
14893apply_relocations (Filedata *filedata,
14894 const Elf_Internal_Shdr *section,
14895 unsigned char *start,
14896 size_t size,
14897 void **relocs_return,
14898 unsigned long *num_relocs_return)
1b315056 14899{
cf13d699 14900 Elf_Internal_Shdr * relsec;
0d2a7a93 14901 unsigned char * end = start + size;
cb8f3167 14902
d1c4b12b
NC
14903 if (relocs_return != NULL)
14904 {
14905 * (Elf_Internal_Rela **) relocs_return = NULL;
14906 * num_relocs_return = 0;
14907 }
14908
dda8d76d 14909 if (filedata->file_header.e_type != ET_REL)
32ec8896 14910 /* No relocs to apply. */
015dc7e1 14911 return true;
1b315056 14912
cf13d699 14913 /* Find the reloc section associated with the section. */
dda8d76d
NC
14914 for (relsec = filedata->section_headers;
14915 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14916 ++relsec)
252b5132 14917 {
015dc7e1 14918 bool is_rela;
41e92641 14919 unsigned long num_relocs;
2cf0635d
NC
14920 Elf_Internal_Rela * relocs;
14921 Elf_Internal_Rela * rp;
14922 Elf_Internal_Shdr * symsec;
14923 Elf_Internal_Sym * symtab;
ba5cdace 14924 unsigned long num_syms;
2cf0635d 14925 Elf_Internal_Sym * sym;
252b5132 14926
41e92641 14927 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14928 || relsec->sh_info >= filedata->file_header.e_shnum
14929 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14930 || relsec->sh_size == 0
dda8d76d 14931 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14932 continue;
428409d5 14933
a788aedd
AM
14934 symsec = filedata->section_headers + relsec->sh_link;
14935 if (symsec->sh_type != SHT_SYMTAB
14936 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14937 return false;
a788aedd 14938
41e92641
NC
14939 is_rela = relsec->sh_type == SHT_RELA;
14940
14941 if (is_rela)
14942 {
dda8d76d 14943 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14944 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14945 return false;
41e92641
NC
14946 }
14947 else
14948 {
dda8d76d 14949 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14950 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14951 return false;
41e92641
NC
14952 }
14953
14954 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14955 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14956 is_rela = false;
428409d5 14957
4de91c10 14958 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14959
41e92641 14960 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14961 {
625d49fc 14962 uint64_t addend;
015dc7e1
AM
14963 unsigned int reloc_type;
14964 unsigned int reloc_size;
14965 bool reloc_inplace = false;
14966 bool reloc_subtract = false;
14967 unsigned char *rloc;
14968 unsigned long sym_index;
4b78141a 14969
dda8d76d 14970 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14971
dda8d76d 14972 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14973 continue;
dda8d76d 14974 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14975 continue;
dda8d76d
NC
14976 else if (is_32bit_abs_reloc (filedata, reloc_type)
14977 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14978 reloc_size = 4;
dda8d76d
NC
14979 else if (is_64bit_abs_reloc (filedata, reloc_type)
14980 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14981 reloc_size = 8;
dda8d76d 14982 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14983 reloc_size = 3;
dda8d76d 14984 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14985 reloc_size = 2;
39e07931
AS
14986 else if (is_8bit_abs_reloc (filedata, reloc_type)
14987 || is_6bit_abs_reloc (filedata, reloc_type))
14988 reloc_size = 1;
03336641
JW
14989 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14990 reloc_type))
14991 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14992 {
14993 reloc_size = 4;
015dc7e1 14994 reloc_inplace = true;
03336641
JW
14995 }
14996 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14997 reloc_type))
14998 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14999 {
15000 reloc_size = 8;
015dc7e1 15001 reloc_inplace = true;
03336641
JW
15002 }
15003 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15004 reloc_type))
15005 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15006 {
15007 reloc_size = 2;
015dc7e1 15008 reloc_inplace = true;
03336641
JW
15009 }
15010 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15011 reloc_type))
15012 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15013 {
15014 reloc_size = 1;
015dc7e1 15015 reloc_inplace = true;
03336641 15016 }
39e07931
AS
15017 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15018 reloc_type)))
15019 {
15020 reloc_size = 1;
015dc7e1 15021 reloc_inplace = true;
39e07931 15022 }
aca88567 15023 else
4b78141a 15024 {
bee0ee85 15025 static unsigned int prev_reloc = 0;
dda8d76d 15026
bee0ee85
NC
15027 if (reloc_type != prev_reloc)
15028 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15029 reloc_type, printable_section_name (filedata, section));
bee0ee85 15030 prev_reloc = reloc_type;
4b78141a
NC
15031 continue;
15032 }
103f02d3 15033
91d6fa6a 15034 rloc = start + rp->r_offset;
75802ccb 15035 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15036 {
15037 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15038 (unsigned long) rp->r_offset,
dda8d76d 15039 printable_section_name (filedata, section));
700dd8b7
L
15040 continue;
15041 }
103f02d3 15042
ba5cdace
NC
15043 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15044 if (sym_index >= num_syms)
15045 {
15046 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15047 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15048 continue;
15049 }
15050 sym = symtab + sym_index;
41e92641
NC
15051
15052 /* If the reloc has a symbol associated with it,
55f25fc3
L
15053 make sure that it is of an appropriate type.
15054
15055 Relocations against symbols without type can happen.
15056 Gcc -feliminate-dwarf2-dups may generate symbols
15057 without type for debug info.
15058
15059 Icc generates relocations against function symbols
15060 instead of local labels.
15061
15062 Relocations against object symbols can happen, eg when
15063 referencing a global array. For an example of this see
15064 the _clz.o binary in libgcc.a. */
aca88567 15065 if (sym != symtab
b8871f35 15066 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15067 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15068 {
d3a49aa8 15069 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15070 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15071 printable_section_name (filedata, relsec),
d3a49aa8 15072 (long int)(rp - relocs));
aca88567 15073 continue;
5b18a4bc 15074 }
252b5132 15075
4dc3c23d
AM
15076 addend = 0;
15077 if (is_rela)
15078 addend += rp->r_addend;
c47320c3
AM
15079 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15080 partial_inplace. */
4dc3c23d 15081 if (!is_rela
dda8d76d 15082 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15083 && reloc_type == 1)
dda8d76d
NC
15084 || ((filedata->file_header.e_machine == EM_PJ
15085 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15086 && reloc_type == 1)
dda8d76d
NC
15087 || ((filedata->file_header.e_machine == EM_D30V
15088 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15089 && reloc_type == 12)
15090 || reloc_inplace)
39e07931
AS
15091 {
15092 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15093 addend += byte_get (rloc, reloc_size) & 0x3f;
15094 else
15095 addend += byte_get (rloc, reloc_size);
15096 }
cb8f3167 15097
dda8d76d
NC
15098 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15099 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15100 {
15101 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15102 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15103 addend -= 8;
91d6fa6a 15104 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15105 reloc_size);
15106 }
39e07931
AS
15107 else if (is_6bit_abs_reloc (filedata, reloc_type)
15108 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15109 {
15110 if (reloc_subtract)
15111 addend -= sym->st_value;
15112 else
15113 addend += sym->st_value;
15114 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15115 byte_put (rloc, addend, reloc_size);
15116 }
03336641
JW
15117 else if (reloc_subtract)
15118 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15119 else
91d6fa6a 15120 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15121 }
252b5132 15122
5b18a4bc 15123 free (symtab);
f84ce13b
NC
15124 /* Let the target specific reloc processing code know that
15125 we have finished with these relocs. */
dda8d76d 15126 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15127
15128 if (relocs_return)
15129 {
15130 * (Elf_Internal_Rela **) relocs_return = relocs;
15131 * num_relocs_return = num_relocs;
15132 }
15133 else
15134 free (relocs);
15135
5b18a4bc
NC
15136 break;
15137 }
32ec8896 15138
015dc7e1 15139 return true;
5b18a4bc 15140}
103f02d3 15141
cf13d699 15142#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15143static bool
dda8d76d 15144disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15145{
dda8d76d 15146 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15147
74e1a04b 15148 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15149
015dc7e1 15150 return true;
cf13d699
NC
15151}
15152#endif
15153
15154/* Reads in the contents of SECTION from FILE, returning a pointer
15155 to a malloc'ed buffer or NULL if something went wrong. */
15156
15157static char *
dda8d76d 15158get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15159{
be7d229a 15160 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15161
15162 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15163 {
c6b78c96 15164 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15165 printable_section_name (filedata, section));
cf13d699
NC
15166 return NULL;
15167 }
15168
dda8d76d 15169 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15170 _("section contents"));
cf13d699
NC
15171}
15172
0e602686
NC
15173/* Uncompresses a section that was compressed using zlib, in place. */
15174
015dc7e1 15175static bool
31e5a3a3
AM
15176uncompress_section_contents (unsigned char **buffer,
15177 uint64_t uncompressed_size,
15178 uint64_t *size)
0e602686 15179{
31e5a3a3
AM
15180 uint64_t compressed_size = *size;
15181 unsigned char *compressed_buffer = *buffer;
15182 unsigned char *uncompressed_buffer;
0e602686
NC
15183 z_stream strm;
15184 int rc;
15185
15186 /* It is possible the section consists of several compressed
15187 buffers concatenated together, so we uncompress in a loop. */
15188 /* PR 18313: The state field in the z_stream structure is supposed
15189 to be invisible to the user (ie us), but some compilers will
15190 still complain about it being used without initialisation. So
15191 we first zero the entire z_stream structure and then set the fields
15192 that we need. */
15193 memset (& strm, 0, sizeof strm);
15194 strm.avail_in = compressed_size;
15195 strm.next_in = (Bytef *) compressed_buffer;
15196 strm.avail_out = uncompressed_size;
15197 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15198
15199 rc = inflateInit (& strm);
15200 while (strm.avail_in > 0)
15201 {
15202 if (rc != Z_OK)
3624a6c1 15203 break;
0e602686
NC
15204 strm.next_out = ((Bytef *) uncompressed_buffer
15205 + (uncompressed_size - strm.avail_out));
15206 rc = inflate (&strm, Z_FINISH);
15207 if (rc != Z_STREAM_END)
3624a6c1 15208 break;
0e602686
NC
15209 rc = inflateReset (& strm);
15210 }
ad92f33d
AM
15211 if (inflateEnd (& strm) != Z_OK
15212 || rc != Z_OK
0e602686
NC
15213 || strm.avail_out != 0)
15214 goto fail;
15215
15216 *buffer = uncompressed_buffer;
15217 *size = uncompressed_size;
015dc7e1 15218 return true;
0e602686
NC
15219
15220 fail:
15221 free (uncompressed_buffer);
15222 /* Indicate decompression failure. */
15223 *buffer = NULL;
015dc7e1 15224 return false;
0e602686 15225}
dd24e3da 15226
015dc7e1 15227static bool
dda8d76d 15228dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15229{
015dc7e1 15230 Elf_Internal_Shdr *relsec;
be7d229a 15231 uint64_t num_bytes;
015dc7e1
AM
15232 unsigned char *data;
15233 unsigned char *end;
15234 unsigned char *real_start;
15235 unsigned char *start;
15236 bool some_strings_shown;
cf13d699 15237
dda8d76d 15238 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15239 if (start == NULL)
c6b78c96 15240 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15241 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15242
0e602686 15243 num_bytes = section->sh_size;
cf13d699 15244
835f2fae
NC
15245 if (filedata->is_separate)
15246 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15247 printable_section_name (filedata, section),
15248 filedata->file_name);
15249 else
15250 printf (_("\nString dump of section '%s':\n"),
15251 printable_section_name (filedata, section));
cf13d699 15252
0e602686
NC
15253 if (decompress_dumps)
15254 {
31e5a3a3
AM
15255 uint64_t new_size = num_bytes;
15256 uint64_t uncompressed_size = 0;
0e602686
NC
15257
15258 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15259 {
15260 Elf_Internal_Chdr chdr;
15261 unsigned int compression_header_size
ebdf1ebf
NC
15262 = get_compression_header (& chdr, (unsigned char *) start,
15263 num_bytes);
5844b465
NC
15264 if (compression_header_size == 0)
15265 /* An error message will have already been generated
15266 by get_compression_header. */
15267 goto error_out;
0e602686 15268
813dabb9 15269 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15270 {
813dabb9 15271 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15272 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15273 goto error_out;
813dabb9 15274 }
813dabb9
L
15275 uncompressed_size = chdr.ch_size;
15276 start += compression_header_size;
15277 new_size -= compression_header_size;
0e602686
NC
15278 }
15279 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15280 {
15281 /* Read the zlib header. In this case, it should be "ZLIB"
15282 followed by the uncompressed section size, 8 bytes in
15283 big-endian order. */
15284 uncompressed_size = start[4]; uncompressed_size <<= 8;
15285 uncompressed_size += start[5]; uncompressed_size <<= 8;
15286 uncompressed_size += start[6]; uncompressed_size <<= 8;
15287 uncompressed_size += start[7]; uncompressed_size <<= 8;
15288 uncompressed_size += start[8]; uncompressed_size <<= 8;
15289 uncompressed_size += start[9]; uncompressed_size <<= 8;
15290 uncompressed_size += start[10]; uncompressed_size <<= 8;
15291 uncompressed_size += start[11];
15292 start += 12;
15293 new_size -= 12;
15294 }
15295
1835f746
NC
15296 if (uncompressed_size)
15297 {
15298 if (uncompress_section_contents (& start,
15299 uncompressed_size, & new_size))
15300 num_bytes = new_size;
15301 else
15302 {
15303 error (_("Unable to decompress section %s\n"),
dda8d76d 15304 printable_section_name (filedata, section));
f761cb13 15305 goto error_out;
1835f746
NC
15306 }
15307 }
bc303e5d
NC
15308 else
15309 start = real_start;
0e602686 15310 }
fd8008d8 15311
cf13d699
NC
15312 /* If the section being dumped has relocations against it the user might
15313 be expecting these relocations to have been applied. Check for this
15314 case and issue a warning message in order to avoid confusion.
15315 FIXME: Maybe we ought to have an option that dumps a section with
15316 relocs applied ? */
dda8d76d
NC
15317 for (relsec = filedata->section_headers;
15318 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15319 ++relsec)
15320 {
15321 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15322 || relsec->sh_info >= filedata->file_header.e_shnum
15323 || filedata->section_headers + relsec->sh_info != section
cf13d699 15324 || relsec->sh_size == 0
dda8d76d 15325 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15326 continue;
15327
15328 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15329 break;
15330 }
15331
cf13d699
NC
15332 data = start;
15333 end = start + num_bytes;
015dc7e1 15334 some_strings_shown = false;
cf13d699 15335
ba3265d0
NC
15336#ifdef HAVE_MBSTATE_T
15337 mbstate_t state;
15338 /* Initialise the multibyte conversion state. */
15339 memset (& state, 0, sizeof (state));
15340#endif
15341
015dc7e1 15342 bool continuing = false;
ba3265d0 15343
cf13d699
NC
15344 while (data < end)
15345 {
15346 while (!ISPRINT (* data))
15347 if (++ data >= end)
15348 break;
15349
15350 if (data < end)
15351 {
071436c6
NC
15352 size_t maxlen = end - data;
15353
ba3265d0
NC
15354 if (continuing)
15355 {
15356 printf (" ");
015dc7e1 15357 continuing = false;
ba3265d0
NC
15358 }
15359 else
15360 {
d1ce973e 15361 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15362 }
15363
4082ef84
NC
15364 if (maxlen > 0)
15365 {
f3da8a96 15366 char c = 0;
ba3265d0
NC
15367
15368 while (maxlen)
15369 {
15370 c = *data++;
15371
15372 if (c == 0)
15373 break;
15374
15375 /* PR 25543: Treat new-lines as string-ending characters. */
15376 if (c == '\n')
15377 {
15378 printf ("\\n\n");
15379 if (*data != 0)
015dc7e1 15380 continuing = true;
ba3265d0
NC
15381 break;
15382 }
15383
15384 /* Do not print control characters directly as they can affect terminal
15385 settings. Such characters usually appear in the names generated
15386 by the assembler for local labels. */
15387 if (ISCNTRL (c))
15388 {
15389 printf ("^%c", c + 0x40);
15390 }
15391 else if (ISPRINT (c))
15392 {
15393 putchar (c);
15394 }
15395 else
15396 {
15397 size_t n;
15398#ifdef HAVE_MBSTATE_T
15399 wchar_t w;
15400#endif
15401 /* Let printf do the hard work of displaying multibyte characters. */
15402 printf ("%.1s", data - 1);
15403#ifdef HAVE_MBSTATE_T
15404 /* Try to find out how many bytes made up the character that was
15405 just printed. Advance the symbol pointer past the bytes that
15406 were displayed. */
15407 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15408#else
15409 n = 1;
15410#endif
15411 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15412 data += (n - 1);
15413 }
15414 }
15415
15416 if (c != '\n')
15417 putchar ('\n');
4082ef84
NC
15418 }
15419 else
15420 {
15421 printf (_("<corrupt>\n"));
15422 data = end;
15423 }
015dc7e1 15424 some_strings_shown = true;
cf13d699
NC
15425 }
15426 }
15427
15428 if (! some_strings_shown)
15429 printf (_(" No strings found in this section."));
15430
0e602686 15431 free (real_start);
cf13d699
NC
15432
15433 putchar ('\n');
015dc7e1 15434 return true;
f761cb13
AM
15435
15436error_out:
15437 free (real_start);
015dc7e1 15438 return false;
cf13d699
NC
15439}
15440
015dc7e1
AM
15441static bool
15442dump_section_as_bytes (Elf_Internal_Shdr *section,
15443 Filedata *filedata,
15444 bool relocate)
cf13d699 15445{
be7d229a
AM
15446 Elf_Internal_Shdr *relsec;
15447 size_t bytes;
15448 uint64_t section_size;
625d49fc 15449 uint64_t addr;
be7d229a
AM
15450 unsigned char *data;
15451 unsigned char *real_start;
15452 unsigned char *start;
0e602686 15453
dda8d76d 15454 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15455 if (start == NULL)
c6b78c96 15456 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15457 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15458
0e602686 15459 section_size = section->sh_size;
cf13d699 15460
835f2fae
NC
15461 if (filedata->is_separate)
15462 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15463 printable_section_name (filedata, section),
15464 filedata->file_name);
15465 else
15466 printf (_("\nHex dump of section '%s':\n"),
15467 printable_section_name (filedata, section));
cf13d699 15468
0e602686
NC
15469 if (decompress_dumps)
15470 {
31e5a3a3
AM
15471 uint64_t new_size = section_size;
15472 uint64_t uncompressed_size = 0;
0e602686
NC
15473
15474 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15475 {
15476 Elf_Internal_Chdr chdr;
15477 unsigned int compression_header_size
ebdf1ebf 15478 = get_compression_header (& chdr, start, section_size);
0e602686 15479
5844b465
NC
15480 if (compression_header_size == 0)
15481 /* An error message will have already been generated
15482 by get_compression_header. */
15483 goto error_out;
15484
813dabb9 15485 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15486 {
813dabb9 15487 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15488 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15489 goto error_out;
0e602686 15490 }
813dabb9
L
15491 uncompressed_size = chdr.ch_size;
15492 start += compression_header_size;
15493 new_size -= compression_header_size;
0e602686
NC
15494 }
15495 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15496 {
15497 /* Read the zlib header. In this case, it should be "ZLIB"
15498 followed by the uncompressed section size, 8 bytes in
15499 big-endian order. */
15500 uncompressed_size = start[4]; uncompressed_size <<= 8;
15501 uncompressed_size += start[5]; uncompressed_size <<= 8;
15502 uncompressed_size += start[6]; uncompressed_size <<= 8;
15503 uncompressed_size += start[7]; uncompressed_size <<= 8;
15504 uncompressed_size += start[8]; uncompressed_size <<= 8;
15505 uncompressed_size += start[9]; uncompressed_size <<= 8;
15506 uncompressed_size += start[10]; uncompressed_size <<= 8;
15507 uncompressed_size += start[11];
15508 start += 12;
15509 new_size -= 12;
15510 }
15511
f055032e
NC
15512 if (uncompressed_size)
15513 {
15514 if (uncompress_section_contents (& start, uncompressed_size,
15515 & new_size))
bc303e5d
NC
15516 {
15517 section_size = new_size;
15518 }
f055032e
NC
15519 else
15520 {
15521 error (_("Unable to decompress section %s\n"),
dda8d76d 15522 printable_section_name (filedata, section));
bc303e5d 15523 /* FIXME: Print the section anyway ? */
f761cb13 15524 goto error_out;
f055032e
NC
15525 }
15526 }
bc303e5d
NC
15527 else
15528 start = real_start;
0e602686 15529 }
14ae95f2 15530
cf13d699
NC
15531 if (relocate)
15532 {
dda8d76d 15533 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15534 goto error_out;
cf13d699
NC
15535 }
15536 else
15537 {
15538 /* If the section being dumped has relocations against it the user might
15539 be expecting these relocations to have been applied. Check for this
15540 case and issue a warning message in order to avoid confusion.
15541 FIXME: Maybe we ought to have an option that dumps a section with
15542 relocs applied ? */
dda8d76d
NC
15543 for (relsec = filedata->section_headers;
15544 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15545 ++relsec)
15546 {
15547 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15548 || relsec->sh_info >= filedata->file_header.e_shnum
15549 || filedata->section_headers + relsec->sh_info != section
cf13d699 15550 || relsec->sh_size == 0
dda8d76d 15551 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15552 continue;
15553
15554 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15555 break;
15556 }
15557 }
15558
15559 addr = section->sh_addr;
0e602686 15560 bytes = section_size;
cf13d699
NC
15561 data = start;
15562
15563 while (bytes)
15564 {
15565 int j;
15566 int k;
15567 int lbytes;
15568
15569 lbytes = (bytes > 16 ? 16 : bytes);
15570
15571 printf (" 0x%8.8lx ", (unsigned long) addr);
15572
15573 for (j = 0; j < 16; j++)
15574 {
15575 if (j < lbytes)
15576 printf ("%2.2x", data[j]);
15577 else
15578 printf (" ");
15579
15580 if ((j & 3) == 3)
15581 printf (" ");
15582 }
15583
15584 for (j = 0; j < lbytes; j++)
15585 {
15586 k = data[j];
15587 if (k >= ' ' && k < 0x7f)
15588 printf ("%c", k);
15589 else
15590 printf (".");
15591 }
15592
15593 putchar ('\n');
15594
15595 data += lbytes;
15596 addr += lbytes;
15597 bytes -= lbytes;
15598 }
15599
0e602686 15600 free (real_start);
cf13d699
NC
15601
15602 putchar ('\n');
015dc7e1 15603 return true;
f761cb13
AM
15604
15605 error_out:
15606 free (real_start);
015dc7e1 15607 return false;
cf13d699
NC
15608}
15609
094e34f2 15610#ifdef ENABLE_LIBCTF
7d9813f1
NA
15611static ctf_sect_t *
15612shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15613{
84714f86 15614 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15615 buf->cts_size = shdr->sh_size;
15616 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15617
15618 return buf;
15619}
15620
15621/* Formatting callback function passed to ctf_dump. Returns either the pointer
15622 it is passed, or a pointer to newly-allocated storage, in which case
15623 dump_ctf() will free it when it no longer needs it. */
15624
2f6ecaed
NA
15625static char *
15626dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15627 char *s, void *arg)
7d9813f1 15628{
3e50a591 15629 const char *blanks = arg;
7d9813f1
NA
15630 char *new_s;
15631
3e50a591 15632 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15633 return s;
15634 return new_s;
15635}
15636
926c9e76
NA
15637/* Dump CTF errors/warnings. */
15638static void
139633c3 15639dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15640{
15641 ctf_next_t *it = NULL;
15642 char *errtext;
15643 int is_warning;
15644 int err;
15645
15646 /* Dump accumulated errors and warnings. */
15647 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15648 {
5e9b84f7 15649 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15650 errtext);
15651 free (errtext);
15652 }
15653 if (err != ECTF_NEXT_END)
15654 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15655}
15656
2f6ecaed
NA
15657/* Dump one CTF archive member. */
15658
80b56fad
NA
15659static void
15660dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15661 size_t member)
2f6ecaed 15662{
2f6ecaed
NA
15663 const char *things[] = {"Header", "Labels", "Data objects",
15664 "Function objects", "Variables", "Types", "Strings",
15665 ""};
15666 const char **thing;
15667 size_t i;
15668
80b56fad
NA
15669 /* Don't print out the name of the default-named archive member if it appears
15670 first in the list. The name .ctf appears everywhere, even for things that
15671 aren't really archives, so printing it out is liable to be confusing; also,
15672 the common case by far is for only one archive member to exist, and hiding
15673 it in that case seems worthwhile. */
2f6ecaed 15674
80b56fad
NA
15675 if (strcmp (name, ".ctf") != 0 || member != 0)
15676 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15677
80b56fad
NA
15678 if (ctf_parent_name (ctf) != NULL)
15679 ctf_import (ctf, parent);
2f6ecaed
NA
15680
15681 for (i = 0, thing = things; *thing[0]; thing++, i++)
15682 {
15683 ctf_dump_state_t *s = NULL;
15684 char *item;
15685
15686 printf ("\n %s:\n", *thing);
15687 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15688 (void *) " ")) != NULL)
15689 {
15690 printf ("%s\n", item);
15691 free (item);
15692 }
15693
15694 if (ctf_errno (ctf))
15695 {
15696 error (_("Iteration failed: %s, %s\n"), *thing,
15697 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15698 break;
2f6ecaed
NA
15699 }
15700 }
8b37e7b6 15701
926c9e76 15702 dump_ctf_errs (ctf);
2f6ecaed
NA
15703}
15704
015dc7e1 15705static bool
7d9813f1
NA
15706dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15707{
7d9813f1
NA
15708 Elf_Internal_Shdr * symtab_sec = NULL;
15709 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15710 void * data = NULL;
15711 void * symdata = NULL;
15712 void * strdata = NULL;
80b56fad 15713 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15714 ctf_sect_t * symsectp = NULL;
15715 ctf_sect_t * strsectp = NULL;
2f6ecaed 15716 ctf_archive_t * ctfa = NULL;
139633c3 15717 ctf_dict_t * parent = NULL;
80b56fad 15718 ctf_dict_t * fp;
7d9813f1 15719
80b56fad
NA
15720 ctf_next_t *i = NULL;
15721 const char *name;
15722 size_t member = 0;
7d9813f1 15723 int err;
015dc7e1 15724 bool ret = false;
7d9813f1
NA
15725
15726 shdr_to_ctf_sect (&ctfsect, section, filedata);
15727 data = get_section_contents (section, filedata);
15728 ctfsect.cts_data = data;
15729
616febde 15730 if (!dump_ctf_symtab_name)
3d16b64e 15731 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15732
15733 if (!dump_ctf_strtab_name)
3d16b64e 15734 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15735
15736 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15737 {
15738 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15739 {
15740 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15741 goto fail;
15742 }
15743 if ((symdata = (void *) get_data (NULL, filedata,
15744 symtab_sec->sh_offset, 1,
15745 symtab_sec->sh_size,
15746 _("symbols"))) == NULL)
15747 goto fail;
15748 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15749 symsect.cts_data = symdata;
15750 }
835f2fae 15751
df16e041 15752 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15753 {
15754 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15755 {
15756 error (_("No string table section named %s\n"),
15757 dump_ctf_strtab_name);
15758 goto fail;
15759 }
15760 if ((strdata = (void *) get_data (NULL, filedata,
15761 strtab_sec->sh_offset, 1,
15762 strtab_sec->sh_size,
15763 _("strings"))) == NULL)
15764 goto fail;
15765 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15766 strsect.cts_data = strdata;
15767 }
835f2fae 15768
2f6ecaed
NA
15769 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15770 libctf papers over the difference, so we can pretend it is always an
80b56fad 15771 archive. */
7d9813f1 15772
2f6ecaed 15773 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15774 {
926c9e76 15775 dump_ctf_errs (NULL);
7d9813f1
NA
15776 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15777 goto fail;
15778 }
15779
96c61be5
NA
15780 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15781 != ELFDATA2MSB);
15782
80b56fad
NA
15783 /* Preload the parent dict, since it will need to be imported into every
15784 child in turn. */
15785 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15786 {
926c9e76 15787 dump_ctf_errs (NULL);
2f6ecaed
NA
15788 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15789 goto fail;
7d9813f1
NA
15790 }
15791
015dc7e1 15792 ret = true;
7d9813f1 15793
835f2fae
NC
15794 if (filedata->is_separate)
15795 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15796 printable_section_name (filedata, section),
15797 filedata->file_name);
15798 else
15799 printf (_("\nDump of CTF section '%s':\n"),
15800 printable_section_name (filedata, section));
7d9813f1 15801
80b56fad
NA
15802 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15803 dump_ctf_archive_member (fp, name, parent, member++);
15804 if (err != ECTF_NEXT_END)
15805 {
15806 dump_ctf_errs (NULL);
15807 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15808 ret = false;
15809 }
7d9813f1
NA
15810
15811 fail:
139633c3 15812 ctf_dict_close (parent);
2f6ecaed 15813 ctf_close (ctfa);
7d9813f1
NA
15814 free (data);
15815 free (symdata);
15816 free (strdata);
15817 return ret;
15818}
094e34f2 15819#endif
7d9813f1 15820
015dc7e1 15821static bool
dda8d76d
NC
15822load_specific_debug_section (enum dwarf_section_display_enum debug,
15823 const Elf_Internal_Shdr * sec,
15824 void * data)
1007acb3 15825{
2cf0635d 15826 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15827 char buf [64];
dda8d76d 15828 Filedata * filedata = (Filedata *) data;
9abca702 15829
19e6b90e 15830 if (section->start != NULL)
dda8d76d
NC
15831 {
15832 /* If it is already loaded, do nothing. */
15833 if (streq (section->filename, filedata->file_name))
015dc7e1 15834 return true;
dda8d76d
NC
15835 free (section->start);
15836 }
1007acb3 15837
19e6b90e
L
15838 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15839 section->address = sec->sh_addr;
dda8d76d
NC
15840 section->filename = filedata->file_name;
15841 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15842 sec->sh_offset, 1,
15843 sec->sh_size, buf);
59245841
NC
15844 if (section->start == NULL)
15845 section->size = 0;
15846 else
15847 {
77115a4a 15848 unsigned char *start = section->start;
31e5a3a3
AM
15849 uint64_t size = sec->sh_size;
15850 uint64_t uncompressed_size = 0;
77115a4a
L
15851
15852 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15853 {
15854 Elf_Internal_Chdr chdr;
d8024a91
NC
15855 unsigned int compression_header_size;
15856
f53be977
L
15857 if (size < (is_32bit_elf
15858 ? sizeof (Elf32_External_Chdr)
15859 : sizeof (Elf64_External_Chdr)))
d8024a91 15860 {
55be8fd0 15861 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15862 section->name);
015dc7e1 15863 return false;
d8024a91
NC
15864 }
15865
ebdf1ebf 15866 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15867 if (compression_header_size == 0)
15868 /* An error message will have already been generated
15869 by get_compression_header. */
015dc7e1 15870 return false;
d8024a91 15871
813dabb9
L
15872 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15873 {
15874 warn (_("section '%s' has unsupported compress type: %d\n"),
15875 section->name, chdr.ch_type);
015dc7e1 15876 return false;
813dabb9 15877 }
dab394de 15878 uncompressed_size = chdr.ch_size;
77115a4a
L
15879 start += compression_header_size;
15880 size -= compression_header_size;
15881 }
dab394de
L
15882 else if (size > 12 && streq ((char *) start, "ZLIB"))
15883 {
15884 /* Read the zlib header. In this case, it should be "ZLIB"
15885 followed by the uncompressed section size, 8 bytes in
15886 big-endian order. */
15887 uncompressed_size = start[4]; uncompressed_size <<= 8;
15888 uncompressed_size += start[5]; uncompressed_size <<= 8;
15889 uncompressed_size += start[6]; uncompressed_size <<= 8;
15890 uncompressed_size += start[7]; uncompressed_size <<= 8;
15891 uncompressed_size += start[8]; uncompressed_size <<= 8;
15892 uncompressed_size += start[9]; uncompressed_size <<= 8;
15893 uncompressed_size += start[10]; uncompressed_size <<= 8;
15894 uncompressed_size += start[11];
15895 start += 12;
15896 size -= 12;
15897 }
15898
1835f746 15899 if (uncompressed_size)
77115a4a 15900 {
1835f746
NC
15901 if (uncompress_section_contents (&start, uncompressed_size,
15902 &size))
15903 {
15904 /* Free the compressed buffer, update the section buffer
15905 and the section size if uncompress is successful. */
15906 free (section->start);
15907 section->start = start;
15908 }
15909 else
15910 {
15911 error (_("Unable to decompress section %s\n"),
dda8d76d 15912 printable_section_name (filedata, sec));
015dc7e1 15913 return false;
1835f746 15914 }
77115a4a 15915 }
bc303e5d 15916
77115a4a 15917 section->size = size;
59245841 15918 }
4a114e3e 15919
1b315056 15920 if (section->start == NULL)
015dc7e1 15921 return false;
1b315056 15922
19e6b90e 15923 if (debug_displays [debug].relocate)
32ec8896 15924 {
dda8d76d 15925 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15926 & section->reloc_info, & section->num_relocs))
015dc7e1 15927 return false;
32ec8896 15928 }
d1c4b12b
NC
15929 else
15930 {
15931 section->reloc_info = NULL;
15932 section->num_relocs = 0;
15933 }
1007acb3 15934
015dc7e1 15935 return true;
1007acb3
L
15936}
15937
301a9420
AM
15938#if HAVE_LIBDEBUGINFOD
15939/* Return a hex string representation of the build-id. */
15940unsigned char *
15941get_build_id (void * data)
15942{
ca0e11aa 15943 Filedata * filedata = (Filedata *) data;
301a9420
AM
15944 Elf_Internal_Shdr * shdr;
15945 unsigned long i;
15946
55be8fd0
NC
15947 /* Iterate through notes to find note.gnu.build-id.
15948 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15949 for (i = 0, shdr = filedata->section_headers;
15950 i < filedata->file_header.e_shnum && shdr != NULL;
15951 i++, shdr++)
15952 {
15953 if (shdr->sh_type != SHT_NOTE)
15954 continue;
15955
15956 char * next;
15957 char * end;
15958 size_t data_remaining;
15959 size_t min_notesz;
15960 Elf_External_Note * enote;
15961 Elf_Internal_Note inote;
15962
625d49fc
AM
15963 uint64_t offset = shdr->sh_offset;
15964 uint64_t align = shdr->sh_addralign;
15965 uint64_t length = shdr->sh_size;
301a9420
AM
15966
15967 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15968 if (enote == NULL)
15969 continue;
15970
15971 if (align < 4)
15972 align = 4;
15973 else if (align != 4 && align != 8)
f761cb13
AM
15974 {
15975 free (enote);
15976 continue;
15977 }
301a9420
AM
15978
15979 end = (char *) enote + length;
15980 data_remaining = end - (char *) enote;
15981
15982 if (!is_ia64_vms (filedata))
15983 {
15984 min_notesz = offsetof (Elf_External_Note, name);
15985 if (data_remaining < min_notesz)
15986 {
55be8fd0
NC
15987 warn (_("\
15988malformed note encountered in section %s whilst scanning for build-id note\n"),
15989 printable_section_name (filedata, shdr));
f761cb13 15990 free (enote);
55be8fd0 15991 continue;
301a9420
AM
15992 }
15993 data_remaining -= min_notesz;
15994
15995 inote.type = BYTE_GET (enote->type);
15996 inote.namesz = BYTE_GET (enote->namesz);
15997 inote.namedata = enote->name;
15998 inote.descsz = BYTE_GET (enote->descsz);
15999 inote.descdata = ((char *) enote
16000 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16001 inote.descpos = offset + (inote.descdata - (char *) enote);
16002 next = ((char *) enote
16003 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16004 }
16005 else
16006 {
16007 Elf64_External_VMS_Note *vms_enote;
16008
16009 /* PR binutils/15191
16010 Make sure that there is enough data to read. */
16011 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16012 if (data_remaining < min_notesz)
16013 {
55be8fd0
NC
16014 warn (_("\
16015malformed note encountered in section %s whilst scanning for build-id note\n"),
16016 printable_section_name (filedata, shdr));
f761cb13 16017 free (enote);
55be8fd0 16018 continue;
301a9420
AM
16019 }
16020 data_remaining -= min_notesz;
16021
16022 vms_enote = (Elf64_External_VMS_Note *) enote;
16023 inote.type = BYTE_GET (vms_enote->type);
16024 inote.namesz = BYTE_GET (vms_enote->namesz);
16025 inote.namedata = vms_enote->name;
16026 inote.descsz = BYTE_GET (vms_enote->descsz);
16027 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16028 inote.descpos = offset + (inote.descdata - (char *) enote);
16029 next = inote.descdata + align_power (inote.descsz, 3);
16030 }
16031
16032 /* Skip malformed notes. */
16033 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16034 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16035 || (size_t) (next - inote.descdata) < inote.descsz
16036 || ((size_t) (next - inote.descdata)
16037 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16038 {
55be8fd0
NC
16039 warn (_("\
16040malformed note encountered in section %s whilst scanning for build-id note\n"),
16041 printable_section_name (filedata, shdr));
f761cb13 16042 free (enote);
301a9420
AM
16043 continue;
16044 }
16045
16046 /* Check if this is the build-id note. If so then convert the build-id
16047 bytes to a hex string. */
16048 if (inote.namesz > 0
24d127aa 16049 && startswith (inote.namedata, "GNU")
301a9420
AM
16050 && inote.type == NT_GNU_BUILD_ID)
16051 {
16052 unsigned long j;
16053 char * build_id;
16054
16055 build_id = malloc (inote.descsz * 2 + 1);
16056 if (build_id == NULL)
f761cb13
AM
16057 {
16058 free (enote);
16059 return NULL;
16060 }
301a9420
AM
16061
16062 for (j = 0; j < inote.descsz; ++j)
16063 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16064 build_id[inote.descsz * 2] = '\0';
f761cb13 16065 free (enote);
301a9420 16066
55be8fd0 16067 return (unsigned char *) build_id;
301a9420 16068 }
f761cb13 16069 free (enote);
301a9420
AM
16070 }
16071
16072 return NULL;
16073}
16074#endif /* HAVE_LIBDEBUGINFOD */
16075
657d0d47
CC
16076/* If this is not NULL, load_debug_section will only look for sections
16077 within the list of sections given here. */
32ec8896 16078static unsigned int * section_subset = NULL;
657d0d47 16079
015dc7e1 16080bool
dda8d76d 16081load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16082{
2cf0635d
NC
16083 struct dwarf_section * section = &debug_displays [debug].section;
16084 Elf_Internal_Shdr * sec;
dda8d76d
NC
16085 Filedata * filedata = (Filedata *) data;
16086
e1dbfc17
L
16087 if (!dump_any_debugging)
16088 return false;
16089
f425ec66
NC
16090 /* Without section headers we cannot find any sections. */
16091 if (filedata->section_headers == NULL)
015dc7e1 16092 return false;
f425ec66 16093
9c1ce108
AM
16094 if (filedata->string_table == NULL
16095 && filedata->file_header.e_shstrndx != SHN_UNDEF
16096 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16097 {
16098 Elf_Internal_Shdr * strs;
16099
16100 /* Read in the string table, so that we have section names to scan. */
16101 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16102
4dff97b2 16103 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16104 {
9c1ce108
AM
16105 filedata->string_table
16106 = (char *) get_data (NULL, filedata, strs->sh_offset,
16107 1, strs->sh_size, _("string table"));
dda8d76d 16108
9c1ce108
AM
16109 filedata->string_table_length
16110 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16111 }
16112 }
d966045b
DJ
16113
16114 /* Locate the debug section. */
dda8d76d 16115 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16116 if (sec != NULL)
16117 section->name = section->uncompressed_name;
16118 else
16119 {
dda8d76d 16120 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16121 if (sec != NULL)
16122 section->name = section->compressed_name;
16123 }
16124 if (sec == NULL)
015dc7e1 16125 return false;
d966045b 16126
657d0d47
CC
16127 /* If we're loading from a subset of sections, and we've loaded
16128 a section matching this name before, it's likely that it's a
16129 different one. */
16130 if (section_subset != NULL)
16131 free_debug_section (debug);
16132
dda8d76d 16133 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16134}
16135
19e6b90e
L
16136void
16137free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16138{
2cf0635d 16139 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16140
19e6b90e
L
16141 if (section->start == NULL)
16142 return;
1007acb3 16143
19e6b90e
L
16144 free ((char *) section->start);
16145 section->start = NULL;
16146 section->address = 0;
16147 section->size = 0;
a788aedd 16148
9db70fc3
AM
16149 free (section->reloc_info);
16150 section->reloc_info = NULL;
16151 section->num_relocs = 0;
1007acb3
L
16152}
16153
015dc7e1 16154static bool
dda8d76d 16155display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16156{
84714f86
AM
16157 const char *name = (section_name_valid (filedata, section)
16158 ? section_name (filedata, section) : "");
16159 const char *print_name = printable_section_name (filedata, section);
be7d229a 16160 uint64_t length;
015dc7e1 16161 bool result = true;
3f5e193b 16162 int i;
1007acb3 16163
19e6b90e
L
16164 length = section->sh_size;
16165 if (length == 0)
1007acb3 16166 {
74e1a04b 16167 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16168 return true;
1007acb3 16169 }
5dff79d8
NC
16170 if (section->sh_type == SHT_NOBITS)
16171 {
16172 /* There is no point in dumping the contents of a debugging section
16173 which has the NOBITS type - the bits in the file will be random.
16174 This can happen when a file containing a .eh_frame section is
16175 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16176 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16177 print_name);
015dc7e1 16178 return false;
5dff79d8 16179 }
1007acb3 16180
24d127aa 16181 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16182 name = ".debug_info";
1007acb3 16183
19e6b90e
L
16184 /* See if we know how to display the contents of this section. */
16185 for (i = 0; i < max; i++)
d85bf2ba
NC
16186 {
16187 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16188 struct dwarf_section_display * display = debug_displays + i;
16189 struct dwarf_section * sec = & display->section;
d966045b 16190
d85bf2ba 16191 if (streq (sec->uncompressed_name, name)
24d127aa 16192 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16193 || streq (sec->compressed_name, name))
16194 {
015dc7e1 16195 bool secondary = (section != find_section (filedata, name));
1007acb3 16196
d85bf2ba
NC
16197 if (secondary)
16198 free_debug_section (id);
dda8d76d 16199
24d127aa 16200 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16201 sec->name = name;
16202 else if (streq (sec->uncompressed_name, name))
16203 sec->name = sec->uncompressed_name;
16204 else
16205 sec->name = sec->compressed_name;
657d0d47 16206
d85bf2ba
NC
16207 if (load_specific_debug_section (id, section, filedata))
16208 {
16209 /* If this debug section is part of a CU/TU set in a .dwp file,
16210 restrict load_debug_section to the sections in that set. */
16211 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16212
d85bf2ba 16213 result &= display->display (sec, filedata);
657d0d47 16214
d85bf2ba 16215 section_subset = NULL;
1007acb3 16216
44266f36 16217 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16218 free_debug_section (id);
16219 }
16220 break;
16221 }
16222 }
1007acb3 16223
19e6b90e 16224 if (i == max)
1007acb3 16225 {
74e1a04b 16226 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16227 result = false;
1007acb3
L
16228 }
16229
19e6b90e 16230 return result;
5b18a4bc 16231}
103f02d3 16232
aef1f6d0
DJ
16233/* Set DUMP_SECTS for all sections where dumps were requested
16234 based on section name. */
16235
16236static void
dda8d76d 16237initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16238{
2cf0635d 16239 struct dump_list_entry * cur;
aef1f6d0
DJ
16240
16241 for (cur = dump_sects_byname; cur; cur = cur->next)
16242 {
16243 unsigned int i;
015dc7e1 16244 bool any = false;
aef1f6d0 16245
dda8d76d 16246 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16247 if (section_name_valid (filedata, filedata->section_headers + i)
16248 && streq (section_name (filedata, filedata->section_headers + i),
16249 cur->name))
aef1f6d0 16250 {
6431e409 16251 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16252 any = true;
aef1f6d0
DJ
16253 }
16254
835f2fae
NC
16255 if (!any && !filedata->is_separate)
16256 warn (_("Section '%s' was not dumped because it does not exist\n"),
16257 cur->name);
aef1f6d0
DJ
16258 }
16259}
16260
015dc7e1 16261static bool
dda8d76d 16262process_section_contents (Filedata * filedata)
5b18a4bc 16263{
2cf0635d 16264 Elf_Internal_Shdr * section;
19e6b90e 16265 unsigned int i;
015dc7e1 16266 bool res = true;
103f02d3 16267
19e6b90e 16268 if (! do_dump)
015dc7e1 16269 return true;
103f02d3 16270
dda8d76d 16271 initialise_dumps_byname (filedata);
aef1f6d0 16272
dda8d76d 16273 for (i = 0, section = filedata->section_headers;
6431e409 16274 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16275 i++, section++)
16276 {
6431e409 16277 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16278
d6bfbc39
NC
16279 if (filedata->is_separate && ! process_links)
16280 dump &= DEBUG_DUMP;
047c3dbf 16281
19e6b90e 16282#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16283 if (dump & DISASS_DUMP)
16284 {
16285 if (! disassemble_section (section, filedata))
015dc7e1 16286 res = false;
dda8d76d 16287 }
19e6b90e 16288#endif
dda8d76d 16289 if (dump & HEX_DUMP)
32ec8896 16290 {
015dc7e1
AM
16291 if (! dump_section_as_bytes (section, filedata, false))
16292 res = false;
32ec8896 16293 }
103f02d3 16294
dda8d76d 16295 if (dump & RELOC_DUMP)
32ec8896 16296 {
015dc7e1
AM
16297 if (! dump_section_as_bytes (section, filedata, true))
16298 res = false;
32ec8896 16299 }
09c11c86 16300
dda8d76d 16301 if (dump & STRING_DUMP)
32ec8896 16302 {
dda8d76d 16303 if (! dump_section_as_strings (section, filedata))
015dc7e1 16304 res = false;
32ec8896 16305 }
cf13d699 16306
dda8d76d 16307 if (dump & DEBUG_DUMP)
32ec8896 16308 {
dda8d76d 16309 if (! display_debug_section (i, section, filedata))
015dc7e1 16310 res = false;
32ec8896 16311 }
7d9813f1 16312
094e34f2 16313#ifdef ENABLE_LIBCTF
7d9813f1
NA
16314 if (dump & CTF_DUMP)
16315 {
16316 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16317 res = false;
7d9813f1 16318 }
094e34f2 16319#endif
5b18a4bc 16320 }
103f02d3 16321
835f2fae 16322 if (! filedata->is_separate)
0ee3043f 16323 {
835f2fae
NC
16324 /* Check to see if the user requested a
16325 dump of a section that does not exist. */
16326 for (; i < filedata->dump.num_dump_sects; i++)
16327 if (filedata->dump.dump_sects[i])
16328 {
ca0e11aa 16329 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16330 res = false;
835f2fae 16331 }
0ee3043f 16332 }
32ec8896
NC
16333
16334 return res;
5b18a4bc 16335}
103f02d3 16336
5b18a4bc 16337static void
19e6b90e 16338process_mips_fpe_exception (int mask)
5b18a4bc 16339{
19e6b90e
L
16340 if (mask)
16341 {
015dc7e1 16342 bool first = true;
32ec8896 16343
19e6b90e 16344 if (mask & OEX_FPU_INEX)
015dc7e1 16345 fputs ("INEX", stdout), first = false;
19e6b90e 16346 if (mask & OEX_FPU_UFLO)
015dc7e1 16347 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16348 if (mask & OEX_FPU_OFLO)
015dc7e1 16349 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16350 if (mask & OEX_FPU_DIV0)
015dc7e1 16351 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16352 if (mask & OEX_FPU_INVAL)
16353 printf ("%sINVAL", first ? "" : "|");
16354 }
5b18a4bc 16355 else
19e6b90e 16356 fputs ("0", stdout);
5b18a4bc 16357}
103f02d3 16358
f6f0e17b
NC
16359/* Display's the value of TAG at location P. If TAG is
16360 greater than 0 it is assumed to be an unknown tag, and
16361 a message is printed to this effect. Otherwise it is
16362 assumed that a message has already been printed.
16363
16364 If the bottom bit of TAG is set it assumed to have a
16365 string value, otherwise it is assumed to have an integer
16366 value.
16367
16368 Returns an updated P pointing to the first unread byte
16369 beyond the end of TAG's value.
16370
16371 Reads at or beyond END will not be made. */
16372
16373static unsigned char *
60abdbed 16374display_tag_value (signed int tag,
f6f0e17b
NC
16375 unsigned char * p,
16376 const unsigned char * const end)
16377{
16378 unsigned long val;
16379
16380 if (tag > 0)
16381 printf (" Tag_unknown_%d: ", tag);
16382
16383 if (p >= end)
16384 {
4082ef84 16385 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16386 }
16387 else if (tag & 1)
16388 {
071436c6
NC
16389 /* PR 17531 file: 027-19978-0.004. */
16390 size_t maxlen = (end - p) - 1;
16391
16392 putchar ('"');
4082ef84
NC
16393 if (maxlen > 0)
16394 {
16395 print_symbol ((int) maxlen, (const char *) p);
16396 p += strnlen ((char *) p, maxlen) + 1;
16397 }
16398 else
16399 {
16400 printf (_("<corrupt string tag>"));
16401 p = (unsigned char *) end;
16402 }
071436c6 16403 printf ("\"\n");
f6f0e17b
NC
16404 }
16405 else
16406 {
cd30bcef 16407 READ_ULEB (val, p, end);
f6f0e17b
NC
16408 printf ("%ld (0x%lx)\n", val, val);
16409 }
16410
4082ef84 16411 assert (p <= end);
f6f0e17b
NC
16412 return p;
16413}
16414
53a346d8
CZ
16415/* ARC ABI attributes section. */
16416
16417static unsigned char *
16418display_arc_attribute (unsigned char * p,
16419 const unsigned char * const end)
16420{
16421 unsigned int tag;
53a346d8
CZ
16422 unsigned int val;
16423
cd30bcef 16424 READ_ULEB (tag, p, end);
53a346d8
CZ
16425
16426 switch (tag)
16427 {
16428 case Tag_ARC_PCS_config:
cd30bcef 16429 READ_ULEB (val, p, end);
53a346d8
CZ
16430 printf (" Tag_ARC_PCS_config: ");
16431 switch (val)
16432 {
16433 case 0:
16434 printf (_("Absent/Non standard\n"));
16435 break;
16436 case 1:
16437 printf (_("Bare metal/mwdt\n"));
16438 break;
16439 case 2:
16440 printf (_("Bare metal/newlib\n"));
16441 break;
16442 case 3:
16443 printf (_("Linux/uclibc\n"));
16444 break;
16445 case 4:
16446 printf (_("Linux/glibc\n"));
16447 break;
16448 default:
16449 printf (_("Unknown\n"));
16450 break;
16451 }
16452 break;
16453
16454 case Tag_ARC_CPU_base:
cd30bcef 16455 READ_ULEB (val, p, end);
53a346d8
CZ
16456 printf (" Tag_ARC_CPU_base: ");
16457 switch (val)
16458 {
16459 default:
16460 case TAG_CPU_NONE:
16461 printf (_("Absent\n"));
16462 break;
16463 case TAG_CPU_ARC6xx:
16464 printf ("ARC6xx\n");
16465 break;
16466 case TAG_CPU_ARC7xx:
16467 printf ("ARC7xx\n");
16468 break;
16469 case TAG_CPU_ARCEM:
16470 printf ("ARCEM\n");
16471 break;
16472 case TAG_CPU_ARCHS:
16473 printf ("ARCHS\n");
16474 break;
16475 }
16476 break;
16477
16478 case Tag_ARC_CPU_variation:
cd30bcef 16479 READ_ULEB (val, p, end);
53a346d8
CZ
16480 printf (" Tag_ARC_CPU_variation: ");
16481 switch (val)
16482 {
16483 default:
16484 if (val > 0 && val < 16)
53a346d8 16485 printf ("Core%d\n", val);
d8cbc93b
JL
16486 else
16487 printf ("Unknown\n");
16488 break;
16489
53a346d8
CZ
16490 case 0:
16491 printf (_("Absent\n"));
16492 break;
16493 }
16494 break;
16495
16496 case Tag_ARC_CPU_name:
16497 printf (" Tag_ARC_CPU_name: ");
16498 p = display_tag_value (-1, p, end);
16499 break;
16500
16501 case Tag_ARC_ABI_rf16:
cd30bcef 16502 READ_ULEB (val, p, end);
53a346d8
CZ
16503 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16504 break;
16505
16506 case Tag_ARC_ABI_osver:
cd30bcef 16507 READ_ULEB (val, p, end);
53a346d8
CZ
16508 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16509 break;
16510
16511 case Tag_ARC_ABI_pic:
16512 case Tag_ARC_ABI_sda:
cd30bcef 16513 READ_ULEB (val, p, end);
53a346d8
CZ
16514 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16515 : " Tag_ARC_ABI_pic: ");
16516 switch (val)
16517 {
16518 case 0:
16519 printf (_("Absent\n"));
16520 break;
16521 case 1:
16522 printf ("MWDT\n");
16523 break;
16524 case 2:
16525 printf ("GNU\n");
16526 break;
16527 default:
16528 printf (_("Unknown\n"));
16529 break;
16530 }
16531 break;
16532
16533 case Tag_ARC_ABI_tls:
cd30bcef 16534 READ_ULEB (val, p, end);
53a346d8
CZ
16535 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16536 break;
16537
16538 case Tag_ARC_ABI_enumsize:
cd30bcef 16539 READ_ULEB (val, p, end);
53a346d8
CZ
16540 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16541 _("smallest"));
16542 break;
16543
16544 case Tag_ARC_ABI_exceptions:
cd30bcef 16545 READ_ULEB (val, p, end);
53a346d8
CZ
16546 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16547 : _("default"));
16548 break;
16549
16550 case Tag_ARC_ABI_double_size:
cd30bcef 16551 READ_ULEB (val, p, end);
53a346d8
CZ
16552 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16553 break;
16554
16555 case Tag_ARC_ISA_config:
16556 printf (" Tag_ARC_ISA_config: ");
16557 p = display_tag_value (-1, p, end);
16558 break;
16559
16560 case Tag_ARC_ISA_apex:
16561 printf (" Tag_ARC_ISA_apex: ");
16562 p = display_tag_value (-1, p, end);
16563 break;
16564
16565 case Tag_ARC_ISA_mpy_option:
cd30bcef 16566 READ_ULEB (val, p, end);
53a346d8
CZ
16567 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16568 break;
16569
db1e1b45 16570 case Tag_ARC_ATR_version:
cd30bcef 16571 READ_ULEB (val, p, end);
db1e1b45 16572 printf (" Tag_ARC_ATR_version: %d\n", val);
16573 break;
16574
53a346d8
CZ
16575 default:
16576 return display_tag_value (tag & 1, p, end);
16577 }
16578
16579 return p;
16580}
16581
11c1ff18
PB
16582/* ARM EABI attributes section. */
16583typedef struct
16584{
70e99720 16585 unsigned int tag;
2cf0635d 16586 const char * name;
11c1ff18 16587 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16588 unsigned int type;
288f0ba2 16589 const char *const *table;
11c1ff18
PB
16590} arm_attr_public_tag;
16591
288f0ba2 16592static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16593 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16594 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16595 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16596 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16597static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16598static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16599 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16600static const char *const arm_attr_tag_FP_arch[] =
bca38921 16601 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16602 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16603static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16604static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16605 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16606 "NEON for ARMv8.1"};
288f0ba2 16607static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16608 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16609 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16610static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16611 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16612static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16613 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16614static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16615 {"Absolute", "PC-relative", "None"};
288f0ba2 16616static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16617 {"None", "direct", "GOT-indirect"};
288f0ba2 16618static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16619 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16620static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16621static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16622 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16623static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16624static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16625static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16626 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16627static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16628 {"Unused", "small", "int", "forced to int"};
288f0ba2 16629static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16630 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16631static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16632 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16633static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16634 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16635static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16636 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16637 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16638static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16639 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16640 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16641static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16642static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16643 {"Not Allowed", "Allowed"};
288f0ba2 16644static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16645 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16646static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16647 {"Follow architecture", "Allowed"};
288f0ba2 16648static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16649 {"Not Allowed", "Allowed"};
288f0ba2 16650static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16651 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16652 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16653static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16654static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16655 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16656 "TrustZone and Virtualization Extensions"};
288f0ba2 16657static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16658 {"Not Allowed", "Allowed"};
11c1ff18 16659
288f0ba2 16660static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16661 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16662
99db83d0
AC
16663static const char * arm_attr_tag_PAC_extension[] =
16664 {"No PAC/AUT instructions",
16665 "PAC/AUT instructions permitted in the NOP space",
16666 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16667
4b535030
AC
16668static const char * arm_attr_tag_BTI_extension[] =
16669 {"BTI instructions not permitted",
16670 "BTI instructions permitted in the NOP space",
16671 "BTI instructions permitted in the NOP and in the non-NOP space"};
16672
b81ee92f
AC
16673static const char * arm_attr_tag_BTI_use[] =
16674 {"Compiled without branch target enforcement",
16675 "Compiled with branch target enforcement"};
16676
c9fed665
AC
16677static const char * arm_attr_tag_PACRET_use[] =
16678 {"Compiled without return address signing and authentication",
16679 "Compiled with return address signing and authentication"};
16680
11c1ff18
PB
16681#define LOOKUP(id, name) \
16682 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16683static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16684{
16685 {4, "CPU_raw_name", 1, NULL},
16686 {5, "CPU_name", 1, NULL},
16687 LOOKUP(6, CPU_arch),
16688 {7, "CPU_arch_profile", 0, NULL},
16689 LOOKUP(8, ARM_ISA_use),
16690 LOOKUP(9, THUMB_ISA_use),
75375b3e 16691 LOOKUP(10, FP_arch),
11c1ff18 16692 LOOKUP(11, WMMX_arch),
f5f53991
AS
16693 LOOKUP(12, Advanced_SIMD_arch),
16694 LOOKUP(13, PCS_config),
11c1ff18
PB
16695 LOOKUP(14, ABI_PCS_R9_use),
16696 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16697 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16698 LOOKUP(17, ABI_PCS_GOT_use),
16699 LOOKUP(18, ABI_PCS_wchar_t),
16700 LOOKUP(19, ABI_FP_rounding),
16701 LOOKUP(20, ABI_FP_denormal),
16702 LOOKUP(21, ABI_FP_exceptions),
16703 LOOKUP(22, ABI_FP_user_exceptions),
16704 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16705 {24, "ABI_align_needed", 0, NULL},
16706 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16707 LOOKUP(26, ABI_enum_size),
16708 LOOKUP(27, ABI_HardFP_use),
16709 LOOKUP(28, ABI_VFP_args),
16710 LOOKUP(29, ABI_WMMX_args),
16711 LOOKUP(30, ABI_optimization_goals),
16712 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16713 {32, "compatibility", 0, NULL},
f5f53991 16714 LOOKUP(34, CPU_unaligned_access),
75375b3e 16715 LOOKUP(36, FP_HP_extension),
8e79c3df 16716 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16717 LOOKUP(42, MPextension_use),
16718 LOOKUP(44, DIV_use),
15afaa63 16719 LOOKUP(46, DSP_extension),
a7ad558c 16720 LOOKUP(48, MVE_arch),
99db83d0 16721 LOOKUP(50, PAC_extension),
4b535030 16722 LOOKUP(52, BTI_extension),
b81ee92f 16723 LOOKUP(74, BTI_use),
c9fed665 16724 LOOKUP(76, PACRET_use),
f5f53991
AS
16725 {64, "nodefaults", 0, NULL},
16726 {65, "also_compatible_with", 0, NULL},
16727 LOOKUP(66, T2EE_use),
16728 {67, "conformance", 1, NULL},
16729 LOOKUP(68, Virtualization_use),
cd21e546 16730 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16731};
16732#undef LOOKUP
16733
11c1ff18 16734static unsigned char *
f6f0e17b
NC
16735display_arm_attribute (unsigned char * p,
16736 const unsigned char * const end)
11c1ff18 16737{
70e99720 16738 unsigned int tag;
70e99720 16739 unsigned int val;
2cf0635d 16740 arm_attr_public_tag * attr;
11c1ff18 16741 unsigned i;
70e99720 16742 unsigned int type;
11c1ff18 16743
cd30bcef 16744 READ_ULEB (tag, p, end);
11c1ff18 16745 attr = NULL;
2cf0635d 16746 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16747 {
16748 if (arm_attr_public_tags[i].tag == tag)
16749 {
16750 attr = &arm_attr_public_tags[i];
16751 break;
16752 }
16753 }
16754
16755 if (attr)
16756 {
16757 printf (" Tag_%s: ", attr->name);
16758 switch (attr->type)
16759 {
16760 case 0:
16761 switch (tag)
16762 {
16763 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16764 READ_ULEB (val, p, end);
11c1ff18
PB
16765 switch (val)
16766 {
2b692964
NC
16767 case 0: printf (_("None\n")); break;
16768 case 'A': printf (_("Application\n")); break;
16769 case 'R': printf (_("Realtime\n")); break;
16770 case 'M': printf (_("Microcontroller\n")); break;
16771 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16772 default: printf ("??? (%d)\n", val); break;
16773 }
16774 break;
16775
75375b3e 16776 case 24: /* Tag_align_needed. */
cd30bcef 16777 READ_ULEB (val, p, end);
75375b3e
MGD
16778 switch (val)
16779 {
2b692964
NC
16780 case 0: printf (_("None\n")); break;
16781 case 1: printf (_("8-byte\n")); break;
16782 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16783 case 3: printf ("??? 3\n"); break;
16784 default:
16785 if (val <= 12)
dd24e3da 16786 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16787 1 << val);
16788 else
16789 printf ("??? (%d)\n", val);
16790 break;
16791 }
16792 break;
16793
16794 case 25: /* Tag_align_preserved. */
cd30bcef 16795 READ_ULEB (val, p, end);
75375b3e
MGD
16796 switch (val)
16797 {
2b692964
NC
16798 case 0: printf (_("None\n")); break;
16799 case 1: printf (_("8-byte, except leaf SP\n")); break;
16800 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16801 case 3: printf ("??? 3\n"); break;
16802 default:
16803 if (val <= 12)
dd24e3da 16804 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16805 1 << val);
16806 else
16807 printf ("??? (%d)\n", val);
16808 break;
16809 }
16810 break;
16811
11c1ff18 16812 case 32: /* Tag_compatibility. */
071436c6 16813 {
cd30bcef 16814 READ_ULEB (val, p, end);
071436c6 16815 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16816 if (p < end - 1)
16817 {
16818 size_t maxlen = (end - p) - 1;
16819
16820 print_symbol ((int) maxlen, (const char *) p);
16821 p += strnlen ((char *) p, maxlen) + 1;
16822 }
16823 else
16824 {
16825 printf (_("<corrupt>"));
16826 p = (unsigned char *) end;
16827 }
071436c6 16828 putchar ('\n');
071436c6 16829 }
11c1ff18
PB
16830 break;
16831
f5f53991 16832 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16833 /* PR 17531: file: 001-505008-0.01. */
16834 if (p < end)
16835 p++;
2b692964 16836 printf (_("True\n"));
f5f53991
AS
16837 break;
16838
16839 case 65: /* Tag_also_compatible_with. */
cd30bcef 16840 READ_ULEB (val, p, end);
f5f53991
AS
16841 if (val == 6 /* Tag_CPU_arch. */)
16842 {
cd30bcef 16843 READ_ULEB (val, p, end);
071436c6 16844 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16845 printf ("??? (%d)\n", val);
16846 else
16847 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16848 }
16849 else
16850 printf ("???\n");
071436c6
NC
16851 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16852 ;
f5f53991
AS
16853 break;
16854
11c1ff18 16855 default:
bee0ee85
NC
16856 printf (_("<unknown: %d>\n"), tag);
16857 break;
11c1ff18
PB
16858 }
16859 return p;
16860
16861 case 1:
f6f0e17b 16862 return display_tag_value (-1, p, end);
11c1ff18 16863 case 2:
f6f0e17b 16864 return display_tag_value (0, p, end);
11c1ff18
PB
16865
16866 default:
16867 assert (attr->type & 0x80);
cd30bcef 16868 READ_ULEB (val, p, end);
11c1ff18
PB
16869 type = attr->type & 0x7f;
16870 if (val >= type)
16871 printf ("??? (%d)\n", val);
16872 else
16873 printf ("%s\n", attr->table[val]);
16874 return p;
16875 }
16876 }
11c1ff18 16877
f6f0e17b 16878 return display_tag_value (tag, p, end);
11c1ff18
PB
16879}
16880
104d59d1 16881static unsigned char *
60bca95a 16882display_gnu_attribute (unsigned char * p,
60abdbed 16883 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16884 const unsigned char * const end)
104d59d1 16885{
cd30bcef 16886 unsigned int tag;
60abdbed 16887 unsigned int val;
104d59d1 16888
cd30bcef 16889 READ_ULEB (tag, p, end);
104d59d1
JM
16890
16891 /* Tag_compatibility is the only generic GNU attribute defined at
16892 present. */
16893 if (tag == 32)
16894 {
cd30bcef 16895 READ_ULEB (val, p, end);
071436c6
NC
16896
16897 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16898 if (p == end)
16899 {
071436c6 16900 printf (_("<corrupt>\n"));
f6f0e17b
NC
16901 warn (_("corrupt vendor attribute\n"));
16902 }
16903 else
16904 {
4082ef84
NC
16905 if (p < end - 1)
16906 {
16907 size_t maxlen = (end - p) - 1;
071436c6 16908
4082ef84
NC
16909 print_symbol ((int) maxlen, (const char *) p);
16910 p += strnlen ((char *) p, maxlen) + 1;
16911 }
16912 else
16913 {
16914 printf (_("<corrupt>"));
16915 p = (unsigned char *) end;
16916 }
071436c6 16917 putchar ('\n');
f6f0e17b 16918 }
104d59d1
JM
16919 return p;
16920 }
16921
16922 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16923 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16924
f6f0e17b 16925 return display_tag_value (tag, p, end);
104d59d1
JM
16926}
16927
85f7484a
PB
16928static unsigned char *
16929display_m68k_gnu_attribute (unsigned char * p,
16930 unsigned int tag,
16931 const unsigned char * const end)
16932{
16933 unsigned int val;
16934
16935 if (tag == Tag_GNU_M68K_ABI_FP)
16936 {
16937 printf (" Tag_GNU_M68K_ABI_FP: ");
16938 if (p == end)
16939 {
16940 printf (_("<corrupt>\n"));
16941 return p;
16942 }
16943 READ_ULEB (val, p, end);
16944
16945 if (val > 3)
16946 printf ("(%#x), ", val);
16947
16948 switch (val & 3)
16949 {
16950 case 0:
16951 printf (_("unspecified hard/soft float\n"));
16952 break;
16953 case 1:
16954 printf (_("hard float\n"));
16955 break;
16956 case 2:
16957 printf (_("soft float\n"));
16958 break;
16959 }
16960 return p;
16961 }
16962
16963 return display_tag_value (tag & 1, p, end);
16964}
16965
34c8bcba 16966static unsigned char *
f6f0e17b 16967display_power_gnu_attribute (unsigned char * p,
60abdbed 16968 unsigned int tag,
f6f0e17b 16969 const unsigned char * const end)
34c8bcba 16970{
005d79fd 16971 unsigned int val;
34c8bcba
JM
16972
16973 if (tag == Tag_GNU_Power_ABI_FP)
16974 {
34c8bcba 16975 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16976 if (p == end)
005d79fd
AM
16977 {
16978 printf (_("<corrupt>\n"));
16979 return p;
16980 }
cd30bcef 16981 READ_ULEB (val, p, end);
60bca95a 16982
005d79fd
AM
16983 if (val > 15)
16984 printf ("(%#x), ", val);
16985
16986 switch (val & 3)
34c8bcba
JM
16987 {
16988 case 0:
005d79fd 16989 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16990 break;
16991 case 1:
005d79fd 16992 printf (_("hard float, "));
34c8bcba
JM
16993 break;
16994 case 2:
005d79fd 16995 printf (_("soft float, "));
34c8bcba 16996 break;
3c7b9897 16997 case 3:
005d79fd 16998 printf (_("single-precision hard float, "));
3c7b9897 16999 break;
005d79fd
AM
17000 }
17001
17002 switch (val & 0xC)
17003 {
17004 case 0:
17005 printf (_("unspecified long double\n"));
17006 break;
17007 case 4:
17008 printf (_("128-bit IBM long double\n"));
17009 break;
17010 case 8:
17011 printf (_("64-bit long double\n"));
17012 break;
17013 case 12:
17014 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17015 break;
17016 }
17017 return p;
005d79fd 17018 }
34c8bcba 17019
c6e65352
DJ
17020 if (tag == Tag_GNU_Power_ABI_Vector)
17021 {
c6e65352 17022 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17023 if (p == end)
005d79fd
AM
17024 {
17025 printf (_("<corrupt>\n"));
17026 return p;
17027 }
cd30bcef 17028 READ_ULEB (val, p, end);
005d79fd
AM
17029
17030 if (val > 3)
17031 printf ("(%#x), ", val);
17032
17033 switch (val & 3)
c6e65352
DJ
17034 {
17035 case 0:
005d79fd 17036 printf (_("unspecified\n"));
c6e65352
DJ
17037 break;
17038 case 1:
005d79fd 17039 printf (_("generic\n"));
c6e65352
DJ
17040 break;
17041 case 2:
17042 printf ("AltiVec\n");
17043 break;
17044 case 3:
17045 printf ("SPE\n");
17046 break;
c6e65352
DJ
17047 }
17048 return p;
005d79fd 17049 }
c6e65352 17050
f82e0623
NF
17051 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17052 {
005d79fd 17053 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17054 if (p == end)
f6f0e17b 17055 {
005d79fd 17056 printf (_("<corrupt>\n"));
f6f0e17b
NC
17057 return p;
17058 }
cd30bcef 17059 READ_ULEB (val, p, end);
0b4362b0 17060
005d79fd
AM
17061 if (val > 2)
17062 printf ("(%#x), ", val);
17063
17064 switch (val & 3)
17065 {
17066 case 0:
17067 printf (_("unspecified\n"));
17068 break;
17069 case 1:
17070 printf ("r3/r4\n");
17071 break;
17072 case 2:
17073 printf (_("memory\n"));
17074 break;
17075 case 3:
17076 printf ("???\n");
17077 break;
17078 }
f82e0623
NF
17079 return p;
17080 }
17081
f6f0e17b 17082 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17083}
17084
643f7afb
AK
17085static unsigned char *
17086display_s390_gnu_attribute (unsigned char * p,
60abdbed 17087 unsigned int tag,
643f7afb
AK
17088 const unsigned char * const end)
17089{
cd30bcef 17090 unsigned int val;
643f7afb
AK
17091
17092 if (tag == Tag_GNU_S390_ABI_Vector)
17093 {
643f7afb 17094 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17095 READ_ULEB (val, p, end);
643f7afb
AK
17096
17097 switch (val)
17098 {
17099 case 0:
17100 printf (_("any\n"));
17101 break;
17102 case 1:
17103 printf (_("software\n"));
17104 break;
17105 case 2:
17106 printf (_("hardware\n"));
17107 break;
17108 default:
17109 printf ("??? (%d)\n", val);
17110 break;
17111 }
17112 return p;
17113 }
17114
17115 return display_tag_value (tag & 1, p, end);
17116}
17117
9e8c70f9 17118static void
60abdbed 17119display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17120{
17121 if (mask)
17122 {
015dc7e1 17123 bool first = true;
071436c6 17124
9e8c70f9 17125 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17126 fputs ("mul32", stdout), first = false;
9e8c70f9 17127 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17128 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17129 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17130 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17131 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17132 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17133 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17134 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17135 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17136 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17137 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17138 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17139 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17140 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17141 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17142 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17143 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17144 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17145 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17146 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17147 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17148 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17149 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17150 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17151 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17152 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17153 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17154 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17155 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17156 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17157 }
17158 else
071436c6
NC
17159 fputc ('0', stdout);
17160 fputc ('\n', stdout);
9e8c70f9
DM
17161}
17162
3d68f91c 17163static void
60abdbed 17164display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17165{
17166 if (mask)
17167 {
015dc7e1 17168 bool first = true;
071436c6 17169
3d68f91c 17170 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17171 fputs ("fjathplus", stdout), first = false;
3d68f91c 17172 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17173 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17174 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17175 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17176 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17177 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17178 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17179 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17180 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17181 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17182 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17183 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17184 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17185 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17186 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17187 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17188 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17189 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17190 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17191 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17192 }
17193 else
071436c6
NC
17194 fputc ('0', stdout);
17195 fputc ('\n', stdout);
3d68f91c
JM
17196}
17197
9e8c70f9 17198static unsigned char *
f6f0e17b 17199display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17200 unsigned int tag,
f6f0e17b 17201 const unsigned char * const end)
9e8c70f9 17202{
cd30bcef 17203 unsigned int val;
3d68f91c 17204
9e8c70f9
DM
17205 if (tag == Tag_GNU_Sparc_HWCAPS)
17206 {
cd30bcef 17207 READ_ULEB (val, p, end);
9e8c70f9 17208 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17209 display_sparc_hwcaps (val);
17210 return p;
3d68f91c
JM
17211 }
17212 if (tag == Tag_GNU_Sparc_HWCAPS2)
17213 {
cd30bcef 17214 READ_ULEB (val, p, end);
3d68f91c
JM
17215 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17216 display_sparc_hwcaps2 (val);
17217 return p;
17218 }
9e8c70f9 17219
f6f0e17b 17220 return display_tag_value (tag, p, end);
9e8c70f9
DM
17221}
17222
351cdf24 17223static void
32ec8896 17224print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17225{
17226 switch (val)
17227 {
17228 case Val_GNU_MIPS_ABI_FP_ANY:
17229 printf (_("Hard or soft float\n"));
17230 break;
17231 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17232 printf (_("Hard float (double precision)\n"));
17233 break;
17234 case Val_GNU_MIPS_ABI_FP_SINGLE:
17235 printf (_("Hard float (single precision)\n"));
17236 break;
17237 case Val_GNU_MIPS_ABI_FP_SOFT:
17238 printf (_("Soft float\n"));
17239 break;
17240 case Val_GNU_MIPS_ABI_FP_OLD_64:
17241 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17242 break;
17243 case Val_GNU_MIPS_ABI_FP_XX:
17244 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17245 break;
17246 case Val_GNU_MIPS_ABI_FP_64:
17247 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17248 break;
17249 case Val_GNU_MIPS_ABI_FP_64A:
17250 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17251 break;
3350cc01
CM
17252 case Val_GNU_MIPS_ABI_FP_NAN2008:
17253 printf (_("NaN 2008 compatibility\n"));
17254 break;
351cdf24
MF
17255 default:
17256 printf ("??? (%d)\n", val);
17257 break;
17258 }
17259}
17260
2cf19d5c 17261static unsigned char *
f6f0e17b 17262display_mips_gnu_attribute (unsigned char * p,
60abdbed 17263 unsigned int tag,
f6f0e17b 17264 const unsigned char * const end)
2cf19d5c 17265{
2cf19d5c
JM
17266 if (tag == Tag_GNU_MIPS_ABI_FP)
17267 {
32ec8896 17268 unsigned int val;
f6f0e17b 17269
2cf19d5c 17270 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17271 READ_ULEB (val, p, end);
351cdf24 17272 print_mips_fp_abi_value (val);
2cf19d5c
JM
17273 return p;
17274 }
17275
a9f58168
CF
17276 if (tag == Tag_GNU_MIPS_ABI_MSA)
17277 {
32ec8896 17278 unsigned int val;
a9f58168 17279
a9f58168 17280 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17281 READ_ULEB (val, p, end);
a9f58168
CF
17282
17283 switch (val)
17284 {
17285 case Val_GNU_MIPS_ABI_MSA_ANY:
17286 printf (_("Any MSA or not\n"));
17287 break;
17288 case Val_GNU_MIPS_ABI_MSA_128:
17289 printf (_("128-bit MSA\n"));
17290 break;
17291 default:
17292 printf ("??? (%d)\n", val);
17293 break;
17294 }
17295 return p;
17296 }
17297
f6f0e17b 17298 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17299}
17300
59e6276b 17301static unsigned char *
f6f0e17b
NC
17302display_tic6x_attribute (unsigned char * p,
17303 const unsigned char * const end)
59e6276b 17304{
60abdbed 17305 unsigned int tag;
cd30bcef 17306 unsigned int val;
59e6276b 17307
cd30bcef 17308 READ_ULEB (tag, p, end);
59e6276b
JM
17309
17310 switch (tag)
17311 {
75fa6dc1 17312 case Tag_ISA:
75fa6dc1 17313 printf (" Tag_ISA: ");
cd30bcef 17314 READ_ULEB (val, p, end);
59e6276b
JM
17315
17316 switch (val)
17317 {
75fa6dc1 17318 case C6XABI_Tag_ISA_none:
59e6276b
JM
17319 printf (_("None\n"));
17320 break;
75fa6dc1 17321 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17322 printf ("C62x\n");
17323 break;
75fa6dc1 17324 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17325 printf ("C67x\n");
17326 break;
75fa6dc1 17327 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17328 printf ("C67x+\n");
17329 break;
75fa6dc1 17330 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17331 printf ("C64x\n");
17332 break;
75fa6dc1 17333 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17334 printf ("C64x+\n");
17335 break;
75fa6dc1 17336 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17337 printf ("C674x\n");
17338 break;
17339 default:
17340 printf ("??? (%d)\n", val);
17341 break;
17342 }
17343 return p;
17344
87779176 17345 case Tag_ABI_wchar_t:
87779176 17346 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17347 READ_ULEB (val, p, end);
87779176
JM
17348 switch (val)
17349 {
17350 case 0:
17351 printf (_("Not used\n"));
17352 break;
17353 case 1:
17354 printf (_("2 bytes\n"));
17355 break;
17356 case 2:
17357 printf (_("4 bytes\n"));
17358 break;
17359 default:
17360 printf ("??? (%d)\n", val);
17361 break;
17362 }
17363 return p;
17364
17365 case Tag_ABI_stack_align_needed:
87779176 17366 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17367 READ_ULEB (val, p, end);
87779176
JM
17368 switch (val)
17369 {
17370 case 0:
17371 printf (_("8-byte\n"));
17372 break;
17373 case 1:
17374 printf (_("16-byte\n"));
17375 break;
17376 default:
17377 printf ("??? (%d)\n", val);
17378 break;
17379 }
17380 return p;
17381
17382 case Tag_ABI_stack_align_preserved:
cd30bcef 17383 READ_ULEB (val, p, end);
87779176
JM
17384 printf (" Tag_ABI_stack_align_preserved: ");
17385 switch (val)
17386 {
17387 case 0:
17388 printf (_("8-byte\n"));
17389 break;
17390 case 1:
17391 printf (_("16-byte\n"));
17392 break;
17393 default:
17394 printf ("??? (%d)\n", val);
17395 break;
17396 }
17397 return p;
17398
b5593623 17399 case Tag_ABI_DSBT:
cd30bcef 17400 READ_ULEB (val, p, end);
b5593623
JM
17401 printf (" Tag_ABI_DSBT: ");
17402 switch (val)
17403 {
17404 case 0:
17405 printf (_("DSBT addressing not used\n"));
17406 break;
17407 case 1:
17408 printf (_("DSBT addressing used\n"));
17409 break;
17410 default:
17411 printf ("??? (%d)\n", val);
17412 break;
17413 }
17414 return p;
17415
87779176 17416 case Tag_ABI_PID:
cd30bcef 17417 READ_ULEB (val, p, end);
87779176
JM
17418 printf (" Tag_ABI_PID: ");
17419 switch (val)
17420 {
17421 case 0:
17422 printf (_("Data addressing position-dependent\n"));
17423 break;
17424 case 1:
17425 printf (_("Data addressing position-independent, GOT near DP\n"));
17426 break;
17427 case 2:
17428 printf (_("Data addressing position-independent, GOT far from DP\n"));
17429 break;
17430 default:
17431 printf ("??? (%d)\n", val);
17432 break;
17433 }
17434 return p;
17435
17436 case Tag_ABI_PIC:
cd30bcef 17437 READ_ULEB (val, p, end);
87779176
JM
17438 printf (" Tag_ABI_PIC: ");
17439 switch (val)
17440 {
17441 case 0:
17442 printf (_("Code addressing position-dependent\n"));
17443 break;
17444 case 1:
17445 printf (_("Code addressing position-independent\n"));
17446 break;
17447 default:
17448 printf ("??? (%d)\n", val);
17449 break;
17450 }
17451 return p;
17452
17453 case Tag_ABI_array_object_alignment:
cd30bcef 17454 READ_ULEB (val, p, end);
87779176
JM
17455 printf (" Tag_ABI_array_object_alignment: ");
17456 switch (val)
17457 {
17458 case 0:
17459 printf (_("8-byte\n"));
17460 break;
17461 case 1:
17462 printf (_("4-byte\n"));
17463 break;
17464 case 2:
17465 printf (_("16-byte\n"));
17466 break;
17467 default:
17468 printf ("??? (%d)\n", val);
17469 break;
17470 }
17471 return p;
17472
17473 case Tag_ABI_array_object_align_expected:
cd30bcef 17474 READ_ULEB (val, p, end);
87779176
JM
17475 printf (" Tag_ABI_array_object_align_expected: ");
17476 switch (val)
17477 {
17478 case 0:
17479 printf (_("8-byte\n"));
17480 break;
17481 case 1:
17482 printf (_("4-byte\n"));
17483 break;
17484 case 2:
17485 printf (_("16-byte\n"));
17486 break;
17487 default:
17488 printf ("??? (%d)\n", val);
17489 break;
17490 }
17491 return p;
17492
3cbd1c06 17493 case Tag_ABI_compatibility:
071436c6 17494 {
cd30bcef 17495 READ_ULEB (val, p, end);
071436c6 17496 printf (" Tag_ABI_compatibility: ");
071436c6 17497 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17498 if (p < end - 1)
17499 {
17500 size_t maxlen = (end - p) - 1;
17501
17502 print_symbol ((int) maxlen, (const char *) p);
17503 p += strnlen ((char *) p, maxlen) + 1;
17504 }
17505 else
17506 {
17507 printf (_("<corrupt>"));
17508 p = (unsigned char *) end;
17509 }
071436c6 17510 putchar ('\n');
071436c6
NC
17511 return p;
17512 }
87779176
JM
17513
17514 case Tag_ABI_conformance:
071436c6 17515 {
4082ef84
NC
17516 printf (" Tag_ABI_conformance: \"");
17517 if (p < end - 1)
17518 {
17519 size_t maxlen = (end - p) - 1;
071436c6 17520
4082ef84
NC
17521 print_symbol ((int) maxlen, (const char *) p);
17522 p += strnlen ((char *) p, maxlen) + 1;
17523 }
17524 else
17525 {
17526 printf (_("<corrupt>"));
17527 p = (unsigned char *) end;
17528 }
071436c6 17529 printf ("\"\n");
071436c6
NC
17530 return p;
17531 }
59e6276b
JM
17532 }
17533
f6f0e17b
NC
17534 return display_tag_value (tag, p, end);
17535}
59e6276b 17536
f6f0e17b 17537static void
60abdbed 17538display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17539{
17540 unsigned long addr = 0;
17541 size_t bytes = end - p;
17542
feceaa59 17543 assert (end >= p);
f6f0e17b 17544 while (bytes)
87779176 17545 {
f6f0e17b
NC
17546 int j;
17547 int k;
17548 int lbytes = (bytes > 16 ? 16 : bytes);
17549
17550 printf (" 0x%8.8lx ", addr);
17551
17552 for (j = 0; j < 16; j++)
17553 {
17554 if (j < lbytes)
17555 printf ("%2.2x", p[j]);
17556 else
17557 printf (" ");
17558
17559 if ((j & 3) == 3)
17560 printf (" ");
17561 }
17562
17563 for (j = 0; j < lbytes; j++)
17564 {
17565 k = p[j];
17566 if (k >= ' ' && k < 0x7f)
17567 printf ("%c", k);
17568 else
17569 printf (".");
17570 }
17571
17572 putchar ('\n');
17573
17574 p += lbytes;
17575 bytes -= lbytes;
17576 addr += lbytes;
87779176 17577 }
59e6276b 17578
f6f0e17b 17579 putchar ('\n');
59e6276b
JM
17580}
17581
13761a11 17582static unsigned char *
b0191216 17583display_msp430_attribute (unsigned char * p,
13761a11
NC
17584 const unsigned char * const end)
17585{
60abdbed
NC
17586 unsigned int val;
17587 unsigned int tag;
13761a11 17588
cd30bcef 17589 READ_ULEB (tag, p, end);
0b4362b0 17590
13761a11
NC
17591 switch (tag)
17592 {
17593 case OFBA_MSPABI_Tag_ISA:
13761a11 17594 printf (" Tag_ISA: ");
cd30bcef 17595 READ_ULEB (val, p, end);
13761a11
NC
17596 switch (val)
17597 {
17598 case 0: printf (_("None\n")); break;
17599 case 1: printf (_("MSP430\n")); break;
17600 case 2: printf (_("MSP430X\n")); break;
17601 default: printf ("??? (%d)\n", val); break;
17602 }
17603 break;
17604
17605 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17606 printf (" Tag_Code_Model: ");
cd30bcef 17607 READ_ULEB (val, p, end);
13761a11
NC
17608 switch (val)
17609 {
17610 case 0: printf (_("None\n")); break;
17611 case 1: printf (_("Small\n")); break;
17612 case 2: printf (_("Large\n")); break;
17613 default: printf ("??? (%d)\n", val); break;
17614 }
17615 break;
17616
17617 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17618 printf (" Tag_Data_Model: ");
cd30bcef 17619 READ_ULEB (val, p, end);
13761a11
NC
17620 switch (val)
17621 {
17622 case 0: printf (_("None\n")); break;
17623 case 1: printf (_("Small\n")); break;
17624 case 2: printf (_("Large\n")); break;
17625 case 3: printf (_("Restricted Large\n")); break;
17626 default: printf ("??? (%d)\n", val); break;
17627 }
17628 break;
17629
17630 default:
17631 printf (_(" <unknown tag %d>: "), tag);
17632
17633 if (tag & 1)
17634 {
071436c6 17635 putchar ('"');
4082ef84
NC
17636 if (p < end - 1)
17637 {
17638 size_t maxlen = (end - p) - 1;
17639
17640 print_symbol ((int) maxlen, (const char *) p);
17641 p += strnlen ((char *) p, maxlen) + 1;
17642 }
17643 else
17644 {
17645 printf (_("<corrupt>"));
17646 p = (unsigned char *) end;
17647 }
071436c6 17648 printf ("\"\n");
13761a11
NC
17649 }
17650 else
17651 {
cd30bcef 17652 READ_ULEB (val, p, end);
13761a11
NC
17653 printf ("%d (0x%x)\n", val, val);
17654 }
17655 break;
17656 }
17657
4082ef84 17658 assert (p <= end);
13761a11
NC
17659 return p;
17660}
17661
c0ea7c52
JL
17662static unsigned char *
17663display_msp430_gnu_attribute (unsigned char * p,
17664 unsigned int tag,
17665 const unsigned char * const end)
17666{
17667 if (tag == Tag_GNU_MSP430_Data_Region)
17668 {
cd30bcef 17669 unsigned int val;
c0ea7c52 17670
c0ea7c52 17671 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17672 READ_ULEB (val, p, end);
c0ea7c52
JL
17673
17674 switch (val)
17675 {
17676 case Val_GNU_MSP430_Data_Region_Any:
17677 printf (_("Any Region\n"));
17678 break;
17679 case Val_GNU_MSP430_Data_Region_Lower:
17680 printf (_("Lower Region Only\n"));
17681 break;
17682 default:
cd30bcef 17683 printf ("??? (%u)\n", val);
c0ea7c52
JL
17684 }
17685 return p;
17686 }
17687 return display_tag_value (tag & 1, p, end);
17688}
17689
2dc8dd17
JW
17690struct riscv_attr_tag_t {
17691 const char *name;
cd30bcef 17692 unsigned int tag;
2dc8dd17
JW
17693};
17694
17695static struct riscv_attr_tag_t riscv_attr_tag[] =
17696{
17697#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17698 T(arch),
17699 T(priv_spec),
17700 T(priv_spec_minor),
17701 T(priv_spec_revision),
17702 T(unaligned_access),
17703 T(stack_align),
17704#undef T
17705};
17706
17707static unsigned char *
17708display_riscv_attribute (unsigned char *p,
17709 const unsigned char * const end)
17710{
cd30bcef
AM
17711 unsigned int val;
17712 unsigned int tag;
2dc8dd17
JW
17713 struct riscv_attr_tag_t *attr = NULL;
17714 unsigned i;
17715
cd30bcef 17716 READ_ULEB (tag, p, end);
2dc8dd17
JW
17717
17718 /* Find the name of attribute. */
17719 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17720 {
17721 if (riscv_attr_tag[i].tag == tag)
17722 {
17723 attr = &riscv_attr_tag[i];
17724 break;
17725 }
17726 }
17727
17728 if (attr)
17729 printf (" %s: ", attr->name);
17730 else
17731 return display_tag_value (tag, p, end);
17732
17733 switch (tag)
17734 {
17735 case Tag_RISCV_priv_spec:
17736 case Tag_RISCV_priv_spec_minor:
17737 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17738 READ_ULEB (val, p, end);
17739 printf (_("%u\n"), val);
2dc8dd17
JW
17740 break;
17741 case Tag_RISCV_unaligned_access:
cd30bcef 17742 READ_ULEB (val, p, end);
2dc8dd17
JW
17743 switch (val)
17744 {
17745 case 0:
17746 printf (_("No unaligned access\n"));
17747 break;
17748 case 1:
17749 printf (_("Unaligned access\n"));
17750 break;
17751 }
17752 break;
17753 case Tag_RISCV_stack_align:
cd30bcef
AM
17754 READ_ULEB (val, p, end);
17755 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17756 break;
17757 case Tag_RISCV_arch:
17758 p = display_tag_value (-1, p, end);
17759 break;
17760 default:
17761 return display_tag_value (tag, p, end);
17762 }
17763
17764 return p;
17765}
17766
0861f561
CQ
17767static unsigned char *
17768display_csky_attribute (unsigned char * p,
17769 const unsigned char * const end)
17770{
17771 unsigned int tag;
17772 unsigned int val;
17773 READ_ULEB (tag, p, end);
17774
17775 if (tag >= Tag_CSKY_MAX)
17776 {
17777 return display_tag_value (-1, p, end);
17778 }
17779
17780 switch (tag)
17781 {
17782 case Tag_CSKY_ARCH_NAME:
17783 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17784 return display_tag_value (-1, p, end);
17785 case Tag_CSKY_CPU_NAME:
17786 printf (" Tag_CSKY_CPU_NAME:\t\t");
17787 return display_tag_value (-1, p, end);
17788
17789 case Tag_CSKY_ISA_FLAGS:
17790 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17791 return display_tag_value (0, p, end);
17792 case Tag_CSKY_ISA_EXT_FLAGS:
17793 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17794 return display_tag_value (0, p, end);
17795
17796 case Tag_CSKY_DSP_VERSION:
17797 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17798 READ_ULEB (val, p, end);
17799 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17800 printf ("DSP Extension\n");
17801 else if (val == VAL_CSKY_DSP_VERSION_2)
17802 printf ("DSP 2.0\n");
17803 break;
17804
17805 case Tag_CSKY_VDSP_VERSION:
17806 printf (" Tag_CSKY_VDSP_VERSION:\t");
17807 READ_ULEB (val, p, end);
17808 printf ("VDSP Version %d\n", val);
17809 break;
17810
17811 case Tag_CSKY_FPU_VERSION:
17812 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17813 READ_ULEB (val, p, end);
17814 if (val == VAL_CSKY_FPU_VERSION_1)
17815 printf ("ABIV1 FPU Version 1\n");
17816 else if (val == VAL_CSKY_FPU_VERSION_2)
17817 printf ("FPU Version 2\n");
17818 break;
17819
17820 case Tag_CSKY_FPU_ABI:
17821 printf (" Tag_CSKY_FPU_ABI:\t\t");
17822 READ_ULEB (val, p, end);
17823 if (val == VAL_CSKY_FPU_ABI_HARD)
17824 printf ("Hard\n");
17825 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17826 printf ("SoftFP\n");
17827 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17828 printf ("Soft\n");
17829 break;
17830 case Tag_CSKY_FPU_ROUNDING:
17831 READ_ULEB (val, p, end);
f253158f
NC
17832 if (val == 1)
17833 {
17834 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17835 printf ("Needed\n");
17836 }
0861f561
CQ
17837 break;
17838 case Tag_CSKY_FPU_DENORMAL:
17839 READ_ULEB (val, p, end);
f253158f
NC
17840 if (val == 1)
17841 {
17842 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17843 printf ("Needed\n");
17844 }
0861f561
CQ
17845 break;
17846 case Tag_CSKY_FPU_Exception:
17847 READ_ULEB (val, p, end);
f253158f
NC
17848 if (val == 1)
17849 {
17850 printf (" Tag_CSKY_FPU_Exception:\t");
17851 printf ("Needed\n");
17852 }
0861f561
CQ
17853 break;
17854 case Tag_CSKY_FPU_NUMBER_MODULE:
17855 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17856 return display_tag_value (-1, p, end);
17857 case Tag_CSKY_FPU_HARDFP:
17858 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17859 READ_ULEB (val, p, end);
17860 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17861 printf (" Half");
17862 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17863 printf (" Single");
17864 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17865 printf (" Double");
17866 printf ("\n");
17867 break;
17868 default:
17869 return display_tag_value (tag, p, end);
17870 }
17871 return p;
17872}
17873
015dc7e1 17874static bool
dda8d76d 17875process_attributes (Filedata * filedata,
60bca95a 17876 const char * public_name,
104d59d1 17877 unsigned int proc_type,
f6f0e17b 17878 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17879 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17880{
2cf0635d 17881 Elf_Internal_Shdr * sect;
11c1ff18 17882 unsigned i;
015dc7e1 17883 bool res = true;
11c1ff18
PB
17884
17885 /* Find the section header so that we get the size. */
dda8d76d
NC
17886 for (i = 0, sect = filedata->section_headers;
17887 i < filedata->file_header.e_shnum;
11c1ff18
PB
17888 i++, sect++)
17889 {
071436c6
NC
17890 unsigned char * contents;
17891 unsigned char * p;
17892
104d59d1 17893 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17894 continue;
17895
dda8d76d 17896 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17897 sect->sh_size, _("attributes"));
60bca95a 17898 if (contents == NULL)
32ec8896 17899 {
015dc7e1 17900 res = false;
32ec8896
NC
17901 continue;
17902 }
60bca95a 17903
11c1ff18 17904 p = contents;
60abdbed
NC
17905 /* The first character is the version of the attributes.
17906 Currently only version 1, (aka 'A') is recognised here. */
17907 if (*p != 'A')
32ec8896
NC
17908 {
17909 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17910 res = false;
32ec8896 17911 }
60abdbed 17912 else
11c1ff18 17913 {
625d49fc 17914 uint64_t section_len;
071436c6
NC
17915
17916 section_len = sect->sh_size - 1;
11c1ff18 17917 p++;
60bca95a 17918
071436c6 17919 while (section_len > 0)
11c1ff18 17920 {
625d49fc 17921 uint64_t attr_len;
e9847026 17922 unsigned int namelen;
015dc7e1
AM
17923 bool public_section;
17924 bool gnu_section;
11c1ff18 17925
071436c6 17926 if (section_len <= 4)
e0a31db1
NC
17927 {
17928 error (_("Tag section ends prematurely\n"));
015dc7e1 17929 res = false;
e0a31db1
NC
17930 break;
17931 }
071436c6 17932 attr_len = byte_get (p, 4);
11c1ff18 17933 p += 4;
60bca95a 17934
071436c6 17935 if (attr_len > section_len)
11c1ff18 17936 {
071436c6
NC
17937 error (_("Bad attribute length (%u > %u)\n"),
17938 (unsigned) attr_len, (unsigned) section_len);
17939 attr_len = section_len;
015dc7e1 17940 res = false;
11c1ff18 17941 }
74e1a04b 17942 /* PR 17531: file: 001-101425-0.004 */
071436c6 17943 else if (attr_len < 5)
74e1a04b 17944 {
071436c6 17945 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17946 res = false;
74e1a04b
NC
17947 break;
17948 }
e9847026 17949
071436c6
NC
17950 section_len -= attr_len;
17951 attr_len -= 4;
17952
17953 namelen = strnlen ((char *) p, attr_len) + 1;
17954 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17955 {
17956 error (_("Corrupt attribute section name\n"));
015dc7e1 17957 res = false;
e9847026
NC
17958 break;
17959 }
17960
071436c6
NC
17961 printf (_("Attribute Section: "));
17962 print_symbol (INT_MAX, (const char *) p);
17963 putchar ('\n');
60bca95a
NC
17964
17965 if (public_name && streq ((char *) p, public_name))
015dc7e1 17966 public_section = true;
11c1ff18 17967 else
015dc7e1 17968 public_section = false;
60bca95a
NC
17969
17970 if (streq ((char *) p, "gnu"))
015dc7e1 17971 gnu_section = true;
104d59d1 17972 else
015dc7e1 17973 gnu_section = false;
60bca95a 17974
11c1ff18 17975 p += namelen;
071436c6 17976 attr_len -= namelen;
e0a31db1 17977
071436c6 17978 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17979 {
e0a31db1 17980 int tag;
cd30bcef 17981 unsigned int val;
625d49fc 17982 uint64_t size;
071436c6 17983 unsigned char * end;
60bca95a 17984
e0a31db1 17985 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17986 if (attr_len < 6)
e0a31db1
NC
17987 {
17988 error (_("Unused bytes at end of section\n"));
015dc7e1 17989 res = false;
e0a31db1
NC
17990 section_len = 0;
17991 break;
17992 }
17993
17994 tag = *(p++);
11c1ff18 17995 size = byte_get (p, 4);
071436c6 17996 if (size > attr_len)
11c1ff18 17997 {
e9847026 17998 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17999 (unsigned) size, (unsigned) attr_len);
015dc7e1 18000 res = false;
071436c6 18001 size = attr_len;
11c1ff18 18002 }
e0a31db1
NC
18003 /* PR binutils/17531: Safe handling of corrupt files. */
18004 if (size < 6)
18005 {
18006 error (_("Bad subsection length (%u < 6)\n"),
18007 (unsigned) size);
015dc7e1 18008 res = false;
e0a31db1
NC
18009 section_len = 0;
18010 break;
18011 }
60bca95a 18012
071436c6 18013 attr_len -= size;
11c1ff18 18014 end = p + size - 1;
071436c6 18015 assert (end <= contents + sect->sh_size);
11c1ff18 18016 p += 4;
60bca95a 18017
11c1ff18
PB
18018 switch (tag)
18019 {
18020 case 1:
2b692964 18021 printf (_("File Attributes\n"));
11c1ff18
PB
18022 break;
18023 case 2:
2b692964 18024 printf (_("Section Attributes:"));
11c1ff18
PB
18025 goto do_numlist;
18026 case 3:
2b692964 18027 printf (_("Symbol Attributes:"));
1a0670f3 18028 /* Fall through. */
11c1ff18
PB
18029 do_numlist:
18030 for (;;)
18031 {
cd30bcef 18032 READ_ULEB (val, p, end);
11c1ff18
PB
18033 if (val == 0)
18034 break;
18035 printf (" %d", val);
18036 }
18037 printf ("\n");
18038 break;
18039 default:
2b692964 18040 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18041 public_section = false;
11c1ff18
PB
18042 break;
18043 }
60bca95a 18044
071436c6 18045 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18046 {
18047 while (p < end)
f6f0e17b 18048 p = display_pub_attribute (p, end);
60abdbed 18049 assert (p == end);
104d59d1 18050 }
071436c6 18051 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18052 {
18053 while (p < end)
18054 p = display_gnu_attribute (p,
f6f0e17b
NC
18055 display_proc_gnu_attribute,
18056 end);
60abdbed 18057 assert (p == end);
11c1ff18 18058 }
071436c6 18059 else if (p < end)
11c1ff18 18060 {
071436c6 18061 printf (_(" Unknown attribute:\n"));
f6f0e17b 18062 display_raw_attribute (p, end);
11c1ff18
PB
18063 p = end;
18064 }
071436c6
NC
18065 else
18066 attr_len = 0;
11c1ff18
PB
18067 }
18068 }
18069 }
d70c5fc7 18070
60bca95a 18071 free (contents);
11c1ff18 18072 }
32ec8896
NC
18073
18074 return res;
11c1ff18
PB
18075}
18076
ccb4c951
RS
18077/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18078 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18079 and return the VMA of the next entry, or -1 if there was a problem.
18080 Does not read from DATA_END or beyond. */
ccb4c951 18081
625d49fc
AM
18082static uint64_t
18083print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18084 unsigned char * data_end)
ccb4c951
RS
18085{
18086 printf (" ");
18087 print_vma (addr, LONG_HEX);
18088 printf (" ");
18089 if (addr < pltgot + 0xfff0)
18090 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18091 else
18092 printf ("%10s", "");
18093 printf (" ");
18094 if (data == NULL)
2b692964 18095 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18096 else
18097 {
625d49fc 18098 uint64_t entry;
82b1b41b 18099 unsigned char * from = data + addr - pltgot;
ccb4c951 18100
82b1b41b
NC
18101 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18102 {
18103 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18104 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18105 return (uint64_t) -1;
82b1b41b
NC
18106 }
18107 else
18108 {
18109 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18110 print_vma (entry, LONG_HEX);
18111 }
ccb4c951
RS
18112 }
18113 return addr + (is_32bit_elf ? 4 : 8);
18114}
18115
861fb55a
DJ
18116/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18117 PLTGOT. Print the Address and Initial fields of an entry at VMA
18118 ADDR and return the VMA of the next entry. */
18119
625d49fc
AM
18120static uint64_t
18121print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18122{
18123 printf (" ");
18124 print_vma (addr, LONG_HEX);
18125 printf (" ");
18126 if (data == NULL)
2b692964 18127 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18128 else
18129 {
625d49fc 18130 uint64_t entry;
861fb55a
DJ
18131
18132 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18133 print_vma (entry, LONG_HEX);
18134 }
18135 return addr + (is_32bit_elf ? 4 : 8);
18136}
18137
351cdf24
MF
18138static void
18139print_mips_ases (unsigned int mask)
18140{
18141 if (mask & AFL_ASE_DSP)
18142 fputs ("\n\tDSP ASE", stdout);
18143 if (mask & AFL_ASE_DSPR2)
18144 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18145 if (mask & AFL_ASE_DSPR3)
18146 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18147 if (mask & AFL_ASE_EVA)
18148 fputs ("\n\tEnhanced VA Scheme", stdout);
18149 if (mask & AFL_ASE_MCU)
18150 fputs ("\n\tMCU (MicroController) ASE", stdout);
18151 if (mask & AFL_ASE_MDMX)
18152 fputs ("\n\tMDMX ASE", stdout);
18153 if (mask & AFL_ASE_MIPS3D)
18154 fputs ("\n\tMIPS-3D ASE", stdout);
18155 if (mask & AFL_ASE_MT)
18156 fputs ("\n\tMT ASE", stdout);
18157 if (mask & AFL_ASE_SMARTMIPS)
18158 fputs ("\n\tSmartMIPS ASE", stdout);
18159 if (mask & AFL_ASE_VIRT)
18160 fputs ("\n\tVZ ASE", stdout);
18161 if (mask & AFL_ASE_MSA)
18162 fputs ("\n\tMSA ASE", stdout);
18163 if (mask & AFL_ASE_MIPS16)
18164 fputs ("\n\tMIPS16 ASE", stdout);
18165 if (mask & AFL_ASE_MICROMIPS)
18166 fputs ("\n\tMICROMIPS ASE", stdout);
18167 if (mask & AFL_ASE_XPA)
18168 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18169 if (mask & AFL_ASE_MIPS16E2)
18170 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18171 if (mask & AFL_ASE_CRC)
18172 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18173 if (mask & AFL_ASE_GINV)
18174 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18175 if (mask & AFL_ASE_LOONGSON_MMI)
18176 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18177 if (mask & AFL_ASE_LOONGSON_CAM)
18178 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18179 if (mask & AFL_ASE_LOONGSON_EXT)
18180 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18181 if (mask & AFL_ASE_LOONGSON_EXT2)
18182 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18183 if (mask == 0)
18184 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18185 else if ((mask & ~AFL_ASE_MASK) != 0)
18186 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18187}
18188
18189static void
18190print_mips_isa_ext (unsigned int isa_ext)
18191{
18192 switch (isa_ext)
18193 {
18194 case 0:
18195 fputs (_("None"), stdout);
18196 break;
18197 case AFL_EXT_XLR:
18198 fputs ("RMI XLR", stdout);
18199 break;
2c629856
N
18200 case AFL_EXT_OCTEON3:
18201 fputs ("Cavium Networks Octeon3", stdout);
18202 break;
351cdf24
MF
18203 case AFL_EXT_OCTEON2:
18204 fputs ("Cavium Networks Octeon2", stdout);
18205 break;
18206 case AFL_EXT_OCTEONP:
18207 fputs ("Cavium Networks OcteonP", stdout);
18208 break;
351cdf24
MF
18209 case AFL_EXT_OCTEON:
18210 fputs ("Cavium Networks Octeon", stdout);
18211 break;
18212 case AFL_EXT_5900:
18213 fputs ("Toshiba R5900", stdout);
18214 break;
18215 case AFL_EXT_4650:
18216 fputs ("MIPS R4650", stdout);
18217 break;
18218 case AFL_EXT_4010:
18219 fputs ("LSI R4010", stdout);
18220 break;
18221 case AFL_EXT_4100:
18222 fputs ("NEC VR4100", stdout);
18223 break;
18224 case AFL_EXT_3900:
18225 fputs ("Toshiba R3900", stdout);
18226 break;
18227 case AFL_EXT_10000:
18228 fputs ("MIPS R10000", stdout);
18229 break;
18230 case AFL_EXT_SB1:
18231 fputs ("Broadcom SB-1", stdout);
18232 break;
18233 case AFL_EXT_4111:
18234 fputs ("NEC VR4111/VR4181", stdout);
18235 break;
18236 case AFL_EXT_4120:
18237 fputs ("NEC VR4120", stdout);
18238 break;
18239 case AFL_EXT_5400:
18240 fputs ("NEC VR5400", stdout);
18241 break;
18242 case AFL_EXT_5500:
18243 fputs ("NEC VR5500", stdout);
18244 break;
18245 case AFL_EXT_LOONGSON_2E:
18246 fputs ("ST Microelectronics Loongson 2E", stdout);
18247 break;
18248 case AFL_EXT_LOONGSON_2F:
18249 fputs ("ST Microelectronics Loongson 2F", stdout);
18250 break;
38bf472a
MR
18251 case AFL_EXT_INTERAPTIV_MR2:
18252 fputs ("Imagination interAptiv MR2", stdout);
18253 break;
351cdf24 18254 default:
00ac7aa0 18255 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18256 }
18257}
18258
32ec8896 18259static signed int
351cdf24
MF
18260get_mips_reg_size (int reg_size)
18261{
18262 return (reg_size == AFL_REG_NONE) ? 0
18263 : (reg_size == AFL_REG_32) ? 32
18264 : (reg_size == AFL_REG_64) ? 64
18265 : (reg_size == AFL_REG_128) ? 128
18266 : -1;
18267}
18268
015dc7e1 18269static bool
dda8d76d 18270process_mips_specific (Filedata * filedata)
5b18a4bc 18271{
2cf0635d 18272 Elf_Internal_Dyn * entry;
351cdf24 18273 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18274 size_t liblist_offset = 0;
18275 size_t liblistno = 0;
18276 size_t conflictsno = 0;
18277 size_t options_offset = 0;
18278 size_t conflicts_offset = 0;
861fb55a
DJ
18279 size_t pltrelsz = 0;
18280 size_t pltrel = 0;
625d49fc
AM
18281 uint64_t pltgot = 0;
18282 uint64_t mips_pltgot = 0;
18283 uint64_t jmprel = 0;
18284 uint64_t local_gotno = 0;
18285 uint64_t gotsym = 0;
18286 uint64_t symtabno = 0;
015dc7e1 18287 bool res = true;
103f02d3 18288
dda8d76d 18289 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18290 display_mips_gnu_attribute))
015dc7e1 18291 res = false;
2cf19d5c 18292
dda8d76d 18293 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18294
18295 if (sect != NULL)
18296 {
18297 Elf_External_ABIFlags_v0 *abiflags_ext;
18298 Elf_Internal_ABIFlags_v0 abiflags_in;
18299
18300 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18301 {
18302 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18303 res = false;
32ec8896 18304 }
351cdf24
MF
18305 else
18306 {
dda8d76d 18307 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18308 sect->sh_size, _("MIPS ABI Flags section"));
18309 if (abiflags_ext)
18310 {
18311 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18312 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18313 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18314 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18315 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18316 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18317 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18318 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18319 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18320 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18321 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18322
18323 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18324 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18325 if (abiflags_in.isa_rev > 1)
18326 printf ("r%d", abiflags_in.isa_rev);
18327 printf ("\nGPR size: %d",
18328 get_mips_reg_size (abiflags_in.gpr_size));
18329 printf ("\nCPR1 size: %d",
18330 get_mips_reg_size (abiflags_in.cpr1_size));
18331 printf ("\nCPR2 size: %d",
18332 get_mips_reg_size (abiflags_in.cpr2_size));
18333 fputs ("\nFP ABI: ", stdout);
18334 print_mips_fp_abi_value (abiflags_in.fp_abi);
18335 fputs ("ISA Extension: ", stdout);
18336 print_mips_isa_ext (abiflags_in.isa_ext);
18337 fputs ("\nASEs:", stdout);
18338 print_mips_ases (abiflags_in.ases);
18339 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18340 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18341 fputc ('\n', stdout);
18342 free (abiflags_ext);
18343 }
18344 }
18345 }
18346
19e6b90e 18347 /* We have a lot of special sections. Thanks SGI! */
978c4450 18348 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18349 {
18350 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18351 sect = find_section (filedata, ".got");
bbdd9a68
MR
18352 if (sect != NULL)
18353 {
18354 unsigned char *data_end;
18355 unsigned char *data;
625d49fc 18356 uint64_t ent, end;
bbdd9a68
MR
18357 int addr_size;
18358
18359 pltgot = sect->sh_addr;
18360
18361 ent = pltgot;
18362 addr_size = (is_32bit_elf ? 4 : 8);
18363 end = pltgot + sect->sh_size;
18364
dda8d76d 18365 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18366 end - pltgot, 1,
18367 _("Global Offset Table data"));
18368 /* PR 12855: Null data is handled gracefully throughout. */
18369 data_end = data + (end - pltgot);
18370
18371 printf (_("\nStatic GOT:\n"));
18372 printf (_(" Canonical gp value: "));
18373 print_vma (ent + 0x7ff0, LONG_HEX);
18374 printf ("\n\n");
18375
18376 /* In a dynamic binary GOT[0] is reserved for the dynamic
18377 loader to store the lazy resolver pointer, however in
18378 a static binary it may well have been omitted and GOT
18379 reduced to a table of addresses.
18380 PR 21344: Check for the entry being fully available
18381 before fetching it. */
18382 if (data
18383 && data + ent - pltgot + addr_size <= data_end
18384 && byte_get (data + ent - pltgot, addr_size) == 0)
18385 {
18386 printf (_(" Reserved entries:\n"));
18387 printf (_(" %*s %10s %*s\n"),
18388 addr_size * 2, _("Address"), _("Access"),
18389 addr_size * 2, _("Value"));
18390 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18391 printf ("\n");
625d49fc 18392 if (ent == (uint64_t) -1)
bbdd9a68
MR
18393 goto sgot_print_fail;
18394
18395 /* Check for the MSB of GOT[1] being set, identifying a
18396 GNU object. This entry will be used by some runtime
18397 loaders, to store the module pointer. Otherwise this
18398 is an ordinary local entry.
18399 PR 21344: Check for the entry being fully available
18400 before fetching it. */
18401 if (data
18402 && data + ent - pltgot + addr_size <= data_end
18403 && (byte_get (data + ent - pltgot, addr_size)
18404 >> (addr_size * 8 - 1)) != 0)
18405 {
18406 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18407 printf ("\n");
625d49fc 18408 if (ent == (uint64_t) -1)
bbdd9a68
MR
18409 goto sgot_print_fail;
18410 }
18411 printf ("\n");
18412 }
18413
f17e9d8a 18414 if (data != NULL && ent < end)
bbdd9a68
MR
18415 {
18416 printf (_(" Local entries:\n"));
18417 printf (" %*s %10s %*s\n",
18418 addr_size * 2, _("Address"), _("Access"),
18419 addr_size * 2, _("Value"));
18420 while (ent < end)
18421 {
18422 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18423 printf ("\n");
625d49fc 18424 if (ent == (uint64_t) -1)
bbdd9a68
MR
18425 goto sgot_print_fail;
18426 }
18427 printf ("\n");
18428 }
18429
18430 sgot_print_fail:
9db70fc3 18431 free (data);
bbdd9a68
MR
18432 }
18433 return res;
18434 }
252b5132 18435
978c4450 18436 for (entry = filedata->dynamic_section;
071436c6 18437 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18438 (entry < filedata->dynamic_section + filedata->dynamic_nent
18439 && entry->d_tag != DT_NULL);
071436c6 18440 ++entry)
252b5132
RH
18441 switch (entry->d_tag)
18442 {
18443 case DT_MIPS_LIBLIST:
d93f0186 18444 liblist_offset
dda8d76d 18445 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18446 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18447 break;
18448 case DT_MIPS_LIBLISTNO:
18449 liblistno = entry->d_un.d_val;
18450 break;
18451 case DT_MIPS_OPTIONS:
dda8d76d 18452 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18453 break;
18454 case DT_MIPS_CONFLICT:
d93f0186 18455 conflicts_offset
dda8d76d 18456 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18457 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18458 break;
18459 case DT_MIPS_CONFLICTNO:
18460 conflictsno = entry->d_un.d_val;
18461 break;
ccb4c951 18462 case DT_PLTGOT:
861fb55a
DJ
18463 pltgot = entry->d_un.d_ptr;
18464 break;
ccb4c951
RS
18465 case DT_MIPS_LOCAL_GOTNO:
18466 local_gotno = entry->d_un.d_val;
18467 break;
18468 case DT_MIPS_GOTSYM:
18469 gotsym = entry->d_un.d_val;
18470 break;
18471 case DT_MIPS_SYMTABNO:
18472 symtabno = entry->d_un.d_val;
18473 break;
861fb55a
DJ
18474 case DT_MIPS_PLTGOT:
18475 mips_pltgot = entry->d_un.d_ptr;
18476 break;
18477 case DT_PLTREL:
18478 pltrel = entry->d_un.d_val;
18479 break;
18480 case DT_PLTRELSZ:
18481 pltrelsz = entry->d_un.d_val;
18482 break;
18483 case DT_JMPREL:
18484 jmprel = entry->d_un.d_ptr;
18485 break;
252b5132
RH
18486 default:
18487 break;
18488 }
18489
18490 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18491 {
2cf0635d 18492 Elf32_External_Lib * elib;
252b5132
RH
18493 size_t cnt;
18494
dda8d76d 18495 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18496 sizeof (Elf32_External_Lib),
18497 liblistno,
18498 _("liblist section data"));
a6e9f9df 18499 if (elib)
252b5132 18500 {
d3a49aa8
AM
18501 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18502 "\nSection '.liblist' contains %lu entries:\n",
18503 (unsigned long) liblistno),
a6e9f9df 18504 (unsigned long) liblistno);
2b692964 18505 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18506 stdout);
18507
18508 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18509 {
a6e9f9df 18510 Elf32_Lib liblist;
91d6fa6a 18511 time_t atime;
d5b07ef4 18512 char timebuf[128];
2cf0635d 18513 struct tm * tmp;
a6e9f9df
AM
18514
18515 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18516 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18517 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18518 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18519 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18520
91d6fa6a 18521 tmp = gmtime (&atime);
e9e44622
JJ
18522 snprintf (timebuf, sizeof (timebuf),
18523 "%04u-%02u-%02uT%02u:%02u:%02u",
18524 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18525 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18526
31104126 18527 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18528 if (valid_dynamic_name (filedata, liblist.l_name))
18529 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18530 else
2b692964 18531 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18532 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18533 liblist.l_version);
a6e9f9df
AM
18534
18535 if (liblist.l_flags == 0)
2b692964 18536 puts (_(" NONE"));
a6e9f9df
AM
18537 else
18538 {
18539 static const struct
252b5132 18540 {
2cf0635d 18541 const char * name;
a6e9f9df 18542 int bit;
252b5132 18543 }
a6e9f9df
AM
18544 l_flags_vals[] =
18545 {
18546 { " EXACT_MATCH", LL_EXACT_MATCH },
18547 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18548 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18549 { " EXPORTS", LL_EXPORTS },
18550 { " DELAY_LOAD", LL_DELAY_LOAD },
18551 { " DELTA", LL_DELTA }
18552 };
18553 int flags = liblist.l_flags;
18554 size_t fcnt;
18555
60bca95a 18556 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18557 if ((flags & l_flags_vals[fcnt].bit) != 0)
18558 {
18559 fputs (l_flags_vals[fcnt].name, stdout);
18560 flags ^= l_flags_vals[fcnt].bit;
18561 }
18562 if (flags != 0)
18563 printf (" %#x", (unsigned int) flags);
252b5132 18564
a6e9f9df
AM
18565 puts ("");
18566 }
252b5132 18567 }
252b5132 18568
a6e9f9df
AM
18569 free (elib);
18570 }
32ec8896 18571 else
015dc7e1 18572 res = false;
252b5132
RH
18573 }
18574
18575 if (options_offset != 0)
18576 {
2cf0635d 18577 Elf_External_Options * eopt;
252b5132
RH
18578 size_t offset;
18579 int cnt;
18580
18581 /* Find the section header so that we get the size. */
dda8d76d 18582 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18583 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18584 if (sect == NULL)
18585 {
18586 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18587 return false;
071436c6 18588 }
7fc0c668
NC
18589 /* PR 24243 */
18590 if (sect->sh_size < sizeof (* eopt))
18591 {
18592 error (_("The MIPS options section is too small.\n"));
015dc7e1 18593 return false;
7fc0c668 18594 }
252b5132 18595
dda8d76d 18596 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18597 sect->sh_size, _("options"));
a6e9f9df 18598 if (eopt)
252b5132 18599 {
fd17d1e6 18600 Elf_Internal_Options option;
76da6bbe 18601
a6e9f9df 18602 offset = cnt = 0;
82b1b41b 18603 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18604 {
2cf0635d 18605 Elf_External_Options * eoption;
fd17d1e6 18606 unsigned int optsize;
252b5132 18607
a6e9f9df 18608 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18609
fd17d1e6 18610 optsize = BYTE_GET (eoption->size);
76da6bbe 18611
82b1b41b 18612 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18613 if (optsize < sizeof (* eopt)
18614 || optsize > sect->sh_size - offset)
82b1b41b 18615 {
645f43a8 18616 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18617 optsize);
645f43a8 18618 free (eopt);
015dc7e1 18619 return false;
82b1b41b 18620 }
fd17d1e6 18621 offset += optsize;
a6e9f9df
AM
18622 ++cnt;
18623 }
252b5132 18624
d3a49aa8
AM
18625 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18626 "\nSection '%s' contains %d entries:\n",
18627 cnt),
dda8d76d 18628 printable_section_name (filedata, sect), cnt);
76da6bbe 18629
82b1b41b 18630 offset = 0;
a6e9f9df 18631 while (cnt-- > 0)
252b5132 18632 {
a6e9f9df 18633 size_t len;
fd17d1e6
AM
18634 Elf_External_Options * eoption;
18635
18636 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18637
18638 option.kind = BYTE_GET (eoption->kind);
18639 option.size = BYTE_GET (eoption->size);
18640 option.section = BYTE_GET (eoption->section);
18641 option.info = BYTE_GET (eoption->info);
a6e9f9df 18642
fd17d1e6 18643 switch (option.kind)
252b5132 18644 {
a6e9f9df
AM
18645 case ODK_NULL:
18646 /* This shouldn't happen. */
d0c4e780 18647 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18648 option.section, option.info);
a6e9f9df 18649 break;
2e6be59c 18650
a6e9f9df
AM
18651 case ODK_REGINFO:
18652 printf (" REGINFO ");
dda8d76d 18653 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18654 {
2cf0635d 18655 Elf32_External_RegInfo * ereg;
b34976b6 18656 Elf32_RegInfo reginfo;
a6e9f9df 18657
2e6be59c 18658 /* 32bit form. */
fd17d1e6
AM
18659 if (option.size < (sizeof (Elf_External_Options)
18660 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18661 {
18662 printf (_("<corrupt>\n"));
18663 error (_("Truncated MIPS REGINFO option\n"));
18664 cnt = 0;
18665 break;
18666 }
18667
fd17d1e6 18668 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18669
a6e9f9df
AM
18670 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18671 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18672 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18673 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18674 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18675 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18676
d0c4e780
AM
18677 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18678 reginfo.ri_gprmask, reginfo.ri_gp_value);
18679 printf (" "
18680 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18681 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18682 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18683 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18684 }
18685 else
18686 {
18687 /* 64 bit form. */
2cf0635d 18688 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18689 Elf64_Internal_RegInfo reginfo;
18690
fd17d1e6
AM
18691 if (option.size < (sizeof (Elf_External_Options)
18692 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18693 {
18694 printf (_("<corrupt>\n"));
18695 error (_("Truncated MIPS REGINFO option\n"));
18696 cnt = 0;
18697 break;
18698 }
18699
fd17d1e6 18700 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18701 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18702 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18703 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18704 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18705 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18706 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18707
d0c4e780
AM
18708 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18709 reginfo.ri_gprmask, reginfo.ri_gp_value);
18710 printf (" "
18711 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18712 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18713 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18714 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18715 }
fd17d1e6 18716 offset += option.size;
a6e9f9df 18717 continue;
2e6be59c 18718
a6e9f9df
AM
18719 case ODK_EXCEPTIONS:
18720 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18721 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18722 fputs (") fpe_max(", stdout);
fd17d1e6 18723 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18724 fputs (")", stdout);
18725
fd17d1e6 18726 if (option.info & OEX_PAGE0)
a6e9f9df 18727 fputs (" PAGE0", stdout);
fd17d1e6 18728 if (option.info & OEX_SMM)
a6e9f9df 18729 fputs (" SMM", stdout);
fd17d1e6 18730 if (option.info & OEX_FPDBUG)
a6e9f9df 18731 fputs (" FPDBUG", stdout);
fd17d1e6 18732 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18733 fputs (" DISMISS", stdout);
18734 break;
2e6be59c 18735
a6e9f9df
AM
18736 case ODK_PAD:
18737 fputs (" PAD ", stdout);
fd17d1e6 18738 if (option.info & OPAD_PREFIX)
a6e9f9df 18739 fputs (" PREFIX", stdout);
fd17d1e6 18740 if (option.info & OPAD_POSTFIX)
a6e9f9df 18741 fputs (" POSTFIX", stdout);
fd17d1e6 18742 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18743 fputs (" SYMBOL", stdout);
18744 break;
2e6be59c 18745
a6e9f9df
AM
18746 case ODK_HWPATCH:
18747 fputs (" HWPATCH ", stdout);
fd17d1e6 18748 if (option.info & OHW_R4KEOP)
a6e9f9df 18749 fputs (" R4KEOP", stdout);
fd17d1e6 18750 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18751 fputs (" R8KPFETCH", stdout);
fd17d1e6 18752 if (option.info & OHW_R5KEOP)
a6e9f9df 18753 fputs (" R5KEOP", stdout);
fd17d1e6 18754 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18755 fputs (" R5KCVTL", stdout);
18756 break;
2e6be59c 18757
a6e9f9df
AM
18758 case ODK_FILL:
18759 fputs (" FILL ", stdout);
18760 /* XXX Print content of info word? */
18761 break;
2e6be59c 18762
a6e9f9df
AM
18763 case ODK_TAGS:
18764 fputs (" TAGS ", stdout);
18765 /* XXX Print content of info word? */
18766 break;
2e6be59c 18767
a6e9f9df
AM
18768 case ODK_HWAND:
18769 fputs (" HWAND ", stdout);
fd17d1e6 18770 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18771 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18772 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18773 fputs (" R4KEOP_CLEAN", stdout);
18774 break;
2e6be59c 18775
a6e9f9df
AM
18776 case ODK_HWOR:
18777 fputs (" HWOR ", stdout);
fd17d1e6 18778 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18779 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18780 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18781 fputs (" R4KEOP_CLEAN", stdout);
18782 break;
2e6be59c 18783
a6e9f9df 18784 case ODK_GP_GROUP:
d0c4e780 18785 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18786 option.info & OGP_GROUP,
18787 (option.info & OGP_SELF) >> 16);
a6e9f9df 18788 break;
2e6be59c 18789
a6e9f9df 18790 case ODK_IDENT:
d0c4e780 18791 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18792 option.info & OGP_GROUP,
18793 (option.info & OGP_SELF) >> 16);
a6e9f9df 18794 break;
2e6be59c 18795
a6e9f9df
AM
18796 default:
18797 /* This shouldn't happen. */
d0c4e780 18798 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18799 option.kind, option.section, option.info);
a6e9f9df 18800 break;
252b5132 18801 }
a6e9f9df 18802
2cf0635d 18803 len = sizeof (* eopt);
fd17d1e6 18804 while (len < option.size)
82b1b41b 18805 {
fd17d1e6 18806 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18807
82b1b41b
NC
18808 if (ISPRINT (datum))
18809 printf ("%c", datum);
18810 else
18811 printf ("\\%03o", datum);
18812 len ++;
18813 }
a6e9f9df 18814 fputs ("\n", stdout);
82b1b41b 18815
fd17d1e6 18816 offset += option.size;
252b5132 18817 }
a6e9f9df 18818 free (eopt);
252b5132 18819 }
32ec8896 18820 else
015dc7e1 18821 res = false;
252b5132
RH
18822 }
18823
18824 if (conflicts_offset != 0 && conflictsno != 0)
18825 {
2cf0635d 18826 Elf32_Conflict * iconf;
252b5132
RH
18827 size_t cnt;
18828
978c4450 18829 if (filedata->dynamic_symbols == NULL)
252b5132 18830 {
591a748a 18831 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18832 return false;
252b5132
RH
18833 }
18834
7296a62a
NC
18835 /* PR 21345 - print a slightly more helpful error message
18836 if we are sure that the cmalloc will fail. */
645f43a8 18837 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18838 {
18839 error (_("Overlarge number of conflicts detected: %lx\n"),
18840 (long) conflictsno);
015dc7e1 18841 return false;
7296a62a
NC
18842 }
18843
3f5e193b 18844 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18845 if (iconf == NULL)
18846 {
8b73c356 18847 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18848 return false;
252b5132
RH
18849 }
18850
9ea033b2 18851 if (is_32bit_elf)
252b5132 18852 {
2cf0635d 18853 Elf32_External_Conflict * econf32;
a6e9f9df 18854
3f5e193b 18855 econf32 = (Elf32_External_Conflict *)
95099889
AM
18856 get_data (NULL, filedata, conflicts_offset,
18857 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18858 if (!econf32)
5a814d6d
AM
18859 {
18860 free (iconf);
015dc7e1 18861 return false;
5a814d6d 18862 }
252b5132
RH
18863
18864 for (cnt = 0; cnt < conflictsno; ++cnt)
18865 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18866
18867 free (econf32);
252b5132
RH
18868 }
18869 else
18870 {
2cf0635d 18871 Elf64_External_Conflict * econf64;
a6e9f9df 18872
3f5e193b 18873 econf64 = (Elf64_External_Conflict *)
95099889
AM
18874 get_data (NULL, filedata, conflicts_offset,
18875 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18876 if (!econf64)
5a814d6d
AM
18877 {
18878 free (iconf);
015dc7e1 18879 return false;
5a814d6d 18880 }
252b5132
RH
18881
18882 for (cnt = 0; cnt < conflictsno; ++cnt)
18883 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18884
18885 free (econf64);
252b5132
RH
18886 }
18887
d3a49aa8
AM
18888 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18889 "\nSection '.conflict' contains %lu entries:\n",
18890 (unsigned long) conflictsno),
c7e7ca54 18891 (unsigned long) conflictsno);
252b5132
RH
18892 puts (_(" Num: Index Value Name"));
18893
18894 for (cnt = 0; cnt < conflictsno; ++cnt)
18895 {
b34976b6 18896 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18897
978c4450 18898 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18899 printf (_("<corrupt symbol index>"));
d79b3d50 18900 else
e0a31db1
NC
18901 {
18902 Elf_Internal_Sym * psym;
18903
978c4450 18904 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18905 print_vma (psym->st_value, FULL_HEX);
18906 putchar (' ');
84714f86
AM
18907 if (valid_dynamic_name (filedata, psym->st_name))
18908 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18909 else
18910 printf (_("<corrupt: %14ld>"), psym->st_name);
18911 }
31104126 18912 putchar ('\n');
252b5132
RH
18913 }
18914
252b5132
RH
18915 free (iconf);
18916 }
18917
ccb4c951
RS
18918 if (pltgot != 0 && local_gotno != 0)
18919 {
625d49fc 18920 uint64_t ent, local_end, global_end;
bbeee7ea 18921 size_t i, offset;
2cf0635d 18922 unsigned char * data;
82b1b41b 18923 unsigned char * data_end;
bbeee7ea 18924 int addr_size;
ccb4c951 18925
91d6fa6a 18926 ent = pltgot;
ccb4c951
RS
18927 addr_size = (is_32bit_elf ? 4 : 8);
18928 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18929
74e1a04b
NC
18930 /* PR binutils/17533 file: 012-111227-0.004 */
18931 if (symtabno < gotsym)
18932 {
18933 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18934 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18935 return false;
74e1a04b 18936 }
82b1b41b 18937
74e1a04b 18938 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18939 /* PR 17531: file: 54c91a34. */
18940 if (global_end < local_end)
18941 {
18942 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18943 return false;
82b1b41b 18944 }
948f632f 18945
dda8d76d
NC
18946 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18947 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18948 global_end - pltgot, 1,
18949 _("Global Offset Table data"));
919383ac 18950 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18951 data_end = data + (global_end - pltgot);
59245841 18952
ccb4c951
RS
18953 printf (_("\nPrimary GOT:\n"));
18954 printf (_(" Canonical gp value: "));
18955 print_vma (pltgot + 0x7ff0, LONG_HEX);
18956 printf ("\n\n");
18957
18958 printf (_(" Reserved entries:\n"));
18959 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18960 addr_size * 2, _("Address"), _("Access"),
18961 addr_size * 2, _("Initial"));
82b1b41b 18962 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18963 printf (_(" Lazy resolver\n"));
625d49fc 18964 if (ent == (uint64_t) -1)
82b1b41b 18965 goto got_print_fail;
75ec1fdb 18966
c4ab9505
MR
18967 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18968 This entry will be used by some runtime loaders, to store the
18969 module pointer. Otherwise this is an ordinary local entry.
18970 PR 21344: Check for the entry being fully available before
18971 fetching it. */
18972 if (data
18973 && data + ent - pltgot + addr_size <= data_end
18974 && (byte_get (data + ent - pltgot, addr_size)
18975 >> (addr_size * 8 - 1)) != 0)
18976 {
18977 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18978 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 18979 if (ent == (uint64_t) -1)
c4ab9505 18980 goto got_print_fail;
ccb4c951
RS
18981 }
18982 printf ("\n");
18983
f17e9d8a 18984 if (data != NULL && ent < local_end)
ccb4c951
RS
18985 {
18986 printf (_(" Local entries:\n"));
cc5914eb 18987 printf (" %*s %10s %*s\n",
2b692964
NC
18988 addr_size * 2, _("Address"), _("Access"),
18989 addr_size * 2, _("Initial"));
91d6fa6a 18990 while (ent < local_end)
ccb4c951 18991 {
82b1b41b 18992 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18993 printf ("\n");
625d49fc 18994 if (ent == (uint64_t) -1)
82b1b41b 18995 goto got_print_fail;
ccb4c951
RS
18996 }
18997 printf ("\n");
18998 }
18999
f17e9d8a 19000 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19001 {
19002 int sym_width;
19003
19004 printf (_(" Global entries:\n"));
cc5914eb 19005 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19006 addr_size * 2, _("Address"),
19007 _("Access"),
2b692964 19008 addr_size * 2, _("Initial"),
9cf03b7e
NC
19009 addr_size * 2, _("Sym.Val."),
19010 _("Type"),
19011 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19012 _("Ndx"), _("Name"));
0b4362b0 19013
ccb4c951 19014 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19015
ccb4c951
RS
19016 for (i = gotsym; i < symtabno; i++)
19017 {
82b1b41b 19018 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19019 printf (" ");
e0a31db1 19020
978c4450 19021 if (filedata->dynamic_symbols == NULL)
e0a31db1 19022 printf (_("<no dynamic symbols>"));
978c4450 19023 else if (i < filedata->num_dynamic_syms)
e0a31db1 19024 {
978c4450 19025 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19026
19027 print_vma (psym->st_value, LONG_HEX);
19028 printf (" %-7s %3s ",
dda8d76d
NC
19029 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19030 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19031
84714f86 19032 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19033 print_symbol (sym_width,
84714f86 19034 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19035 else
19036 printf (_("<corrupt: %14ld>"), psym->st_name);
19037 }
ccb4c951 19038 else
7fc5ac57
JBG
19039 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19040 (unsigned long) i);
e0a31db1 19041
ccb4c951 19042 printf ("\n");
625d49fc 19043 if (ent == (uint64_t) -1)
82b1b41b 19044 break;
ccb4c951
RS
19045 }
19046 printf ("\n");
19047 }
19048
82b1b41b 19049 got_print_fail:
9db70fc3 19050 free (data);
ccb4c951
RS
19051 }
19052
861fb55a
DJ
19053 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19054 {
625d49fc 19055 uint64_t ent, end;
861fb55a
DJ
19056 size_t offset, rel_offset;
19057 unsigned long count, i;
2cf0635d 19058 unsigned char * data;
861fb55a 19059 int addr_size, sym_width;
2cf0635d 19060 Elf_Internal_Rela * rels;
861fb55a 19061
dda8d76d 19062 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19063 if (pltrel == DT_RELA)
19064 {
dda8d76d 19065 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19066 return false;
861fb55a
DJ
19067 }
19068 else
19069 {
dda8d76d 19070 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19071 return false;
861fb55a
DJ
19072 }
19073
91d6fa6a 19074 ent = mips_pltgot;
861fb55a
DJ
19075 addr_size = (is_32bit_elf ? 4 : 8);
19076 end = mips_pltgot + (2 + count) * addr_size;
19077
dda8d76d
NC
19078 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19079 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19080 1, _("Procedure Linkage Table data"));
59245841 19081 if (data == NULL)
288f0ba2
AM
19082 {
19083 free (rels);
015dc7e1 19084 return false;
288f0ba2 19085 }
59245841 19086
9cf03b7e 19087 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19088 printf (_(" Reserved entries:\n"));
19089 printf (_(" %*s %*s Purpose\n"),
2b692964 19090 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19091 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19092 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19093 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19094 printf (_(" Module pointer\n"));
861fb55a
DJ
19095 printf ("\n");
19096
19097 printf (_(" Entries:\n"));
cc5914eb 19098 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19099 addr_size * 2, _("Address"),
19100 addr_size * 2, _("Initial"),
19101 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19102 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19103 for (i = 0; i < count; i++)
19104 {
df97ab2a 19105 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19106
91d6fa6a 19107 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19108 printf (" ");
e0a31db1 19109
978c4450 19110 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19111 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19112 else
e0a31db1 19113 {
978c4450 19114 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19115
19116 print_vma (psym->st_value, LONG_HEX);
19117 printf (" %-7s %3s ",
dda8d76d
NC
19118 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19119 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19120 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19121 print_symbol (sym_width,
84714f86 19122 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19123 else
19124 printf (_("<corrupt: %14ld>"), psym->st_name);
19125 }
861fb55a
DJ
19126 printf ("\n");
19127 }
19128 printf ("\n");
19129
9db70fc3 19130 free (data);
861fb55a
DJ
19131 free (rels);
19132 }
19133
32ec8896 19134 return res;
252b5132
RH
19135}
19136
015dc7e1 19137static bool
dda8d76d 19138process_nds32_specific (Filedata * filedata)
35c08157
KLC
19139{
19140 Elf_Internal_Shdr *sect = NULL;
19141
dda8d76d 19142 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19143 if (sect != NULL && sect->sh_size >= 4)
35c08157 19144 {
9c7b8e9b
AM
19145 unsigned char *buf;
19146 unsigned int flag;
35c08157
KLC
19147
19148 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19149 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19150 _("NDS32 elf flags section"));
35c08157 19151
9c7b8e9b 19152 if (buf == NULL)
015dc7e1 19153 return false;
32ec8896 19154
9c7b8e9b
AM
19155 flag = byte_get (buf, 4);
19156 free (buf);
19157 switch (flag & 0x3)
35c08157
KLC
19158 {
19159 case 0:
19160 printf ("(VEC_SIZE):\tNo entry.\n");
19161 break;
19162 case 1:
19163 printf ("(VEC_SIZE):\t4 bytes\n");
19164 break;
19165 case 2:
19166 printf ("(VEC_SIZE):\t16 bytes\n");
19167 break;
19168 case 3:
19169 printf ("(VEC_SIZE):\treserved\n");
19170 break;
19171 }
19172 }
19173
015dc7e1 19174 return true;
35c08157
KLC
19175}
19176
015dc7e1 19177static bool
dda8d76d 19178process_gnu_liblist (Filedata * filedata)
047b2264 19179{
2cf0635d
NC
19180 Elf_Internal_Shdr * section;
19181 Elf_Internal_Shdr * string_sec;
19182 Elf32_External_Lib * elib;
19183 char * strtab;
c256ffe7 19184 size_t strtab_size;
047b2264 19185 size_t cnt;
d3a49aa8 19186 unsigned long num_liblist;
047b2264 19187 unsigned i;
015dc7e1 19188 bool res = true;
047b2264
JJ
19189
19190 if (! do_arch)
015dc7e1 19191 return true;
047b2264 19192
dda8d76d
NC
19193 for (i = 0, section = filedata->section_headers;
19194 i < filedata->file_header.e_shnum;
b34976b6 19195 i++, section++)
047b2264
JJ
19196 {
19197 switch (section->sh_type)
19198 {
19199 case SHT_GNU_LIBLIST:
dda8d76d 19200 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19201 break;
19202
3f5e193b 19203 elib = (Elf32_External_Lib *)
dda8d76d 19204 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19205 _("liblist section data"));
047b2264
JJ
19206
19207 if (elib == NULL)
32ec8896 19208 {
015dc7e1 19209 res = false;
32ec8896
NC
19210 break;
19211 }
047b2264 19212
dda8d76d
NC
19213 string_sec = filedata->section_headers + section->sh_link;
19214 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19215 string_sec->sh_size,
19216 _("liblist string table"));
047b2264
JJ
19217 if (strtab == NULL
19218 || section->sh_entsize != sizeof (Elf32_External_Lib))
19219 {
19220 free (elib);
2842702f 19221 free (strtab);
015dc7e1 19222 res = false;
047b2264
JJ
19223 break;
19224 }
59245841 19225 strtab_size = string_sec->sh_size;
047b2264 19226
d3a49aa8
AM
19227 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19228 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19229 "\nLibrary list section '%s' contains %lu entries:\n",
19230 num_liblist),
dda8d76d 19231 printable_section_name (filedata, section),
d3a49aa8 19232 num_liblist);
047b2264 19233
2b692964 19234 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19235
19236 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19237 ++cnt)
19238 {
19239 Elf32_Lib liblist;
91d6fa6a 19240 time_t atime;
d5b07ef4 19241 char timebuf[128];
2cf0635d 19242 struct tm * tmp;
047b2264
JJ
19243
19244 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19245 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19246 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19247 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19248 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19249
91d6fa6a 19250 tmp = gmtime (&atime);
e9e44622
JJ
19251 snprintf (timebuf, sizeof (timebuf),
19252 "%04u-%02u-%02uT%02u:%02u:%02u",
19253 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19254 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19255
19256 printf ("%3lu: ", (unsigned long) cnt);
19257 if (do_wide)
c256ffe7 19258 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19259 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19260 else
c256ffe7 19261 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19262 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19263 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19264 liblist.l_version, liblist.l_flags);
19265 }
19266
19267 free (elib);
2842702f 19268 free (strtab);
047b2264
JJ
19269 }
19270 }
19271
32ec8896 19272 return res;
047b2264
JJ
19273}
19274
9437c45b 19275static const char *
dda8d76d 19276get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19277{
19278 static char buff[64];
103f02d3 19279
dda8d76d 19280 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19281 switch (e_type)
19282 {
57346661 19283 case NT_AUXV:
1ec5cd37 19284 return _("NT_AUXV (auxiliary vector)");
57346661 19285 case NT_PRSTATUS:
1ec5cd37 19286 return _("NT_PRSTATUS (prstatus structure)");
57346661 19287 case NT_FPREGSET:
1ec5cd37 19288 return _("NT_FPREGSET (floating point registers)");
57346661 19289 case NT_PRPSINFO:
1ec5cd37 19290 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19291 case NT_TASKSTRUCT:
1ec5cd37 19292 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19293 case NT_GDB_TDESC:
19294 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19295 case NT_PRXFPREG:
1ec5cd37 19296 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19297 case NT_PPC_VMX:
19298 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19299 case NT_PPC_VSX:
19300 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19301 case NT_PPC_TAR:
19302 return _("NT_PPC_TAR (ppc TAR register)");
19303 case NT_PPC_PPR:
19304 return _("NT_PPC_PPR (ppc PPR register)");
19305 case NT_PPC_DSCR:
19306 return _("NT_PPC_DSCR (ppc DSCR register)");
19307 case NT_PPC_EBB:
19308 return _("NT_PPC_EBB (ppc EBB registers)");
19309 case NT_PPC_PMU:
19310 return _("NT_PPC_PMU (ppc PMU registers)");
19311 case NT_PPC_TM_CGPR:
19312 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19313 case NT_PPC_TM_CFPR:
19314 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19315 case NT_PPC_TM_CVMX:
19316 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19317 case NT_PPC_TM_CVSX:
3fd21718 19318 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19319 case NT_PPC_TM_SPR:
19320 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19321 case NT_PPC_TM_CTAR:
19322 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19323 case NT_PPC_TM_CPPR:
19324 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19325 case NT_PPC_TM_CDSCR:
19326 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19327 case NT_386_TLS:
19328 return _("NT_386_TLS (x86 TLS information)");
19329 case NT_386_IOPERM:
19330 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19331 case NT_X86_XSTATE:
19332 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19333 case NT_X86_CET:
19334 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19335 case NT_S390_HIGH_GPRS:
19336 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19337 case NT_S390_TIMER:
19338 return _("NT_S390_TIMER (s390 timer register)");
19339 case NT_S390_TODCMP:
19340 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19341 case NT_S390_TODPREG:
19342 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19343 case NT_S390_CTRS:
19344 return _("NT_S390_CTRS (s390 control registers)");
19345 case NT_S390_PREFIX:
19346 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19347 case NT_S390_LAST_BREAK:
19348 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19349 case NT_S390_SYSTEM_CALL:
19350 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19351 case NT_S390_TDB:
19352 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19353 case NT_S390_VXRS_LOW:
19354 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19355 case NT_S390_VXRS_HIGH:
19356 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19357 case NT_S390_GS_CB:
19358 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19359 case NT_S390_GS_BC:
19360 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19361 case NT_ARM_VFP:
19362 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19363 case NT_ARM_TLS:
19364 return _("NT_ARM_TLS (AArch TLS registers)");
19365 case NT_ARM_HW_BREAK:
19366 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19367 case NT_ARM_HW_WATCH:
19368 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19369 case NT_ARM_SYSTEM_CALL:
19370 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19371 case NT_ARM_SVE:
19372 return _("NT_ARM_SVE (AArch SVE registers)");
19373 case NT_ARM_PAC_MASK:
19374 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19375 case NT_ARM_PACA_KEYS:
19376 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19377 case NT_ARM_PACG_KEYS:
19378 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19379 case NT_ARM_TAGGED_ADDR_CTRL:
19380 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19381 case NT_ARM_PAC_ENABLED_KEYS:
19382 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19383 case NT_ARC_V2:
19384 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19385 case NT_RISCV_CSR:
19386 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19387 case NT_PSTATUS:
1ec5cd37 19388 return _("NT_PSTATUS (pstatus structure)");
57346661 19389 case NT_FPREGS:
1ec5cd37 19390 return _("NT_FPREGS (floating point registers)");
57346661 19391 case NT_PSINFO:
1ec5cd37 19392 return _("NT_PSINFO (psinfo structure)");
57346661 19393 case NT_LWPSTATUS:
1ec5cd37 19394 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19395 case NT_LWPSINFO:
1ec5cd37 19396 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19397 case NT_WIN32PSTATUS:
1ec5cd37 19398 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19399 case NT_SIGINFO:
19400 return _("NT_SIGINFO (siginfo_t data)");
19401 case NT_FILE:
19402 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19403 default:
19404 break;
19405 }
19406 else
19407 switch (e_type)
19408 {
19409 case NT_VERSION:
19410 return _("NT_VERSION (version)");
19411 case NT_ARCH:
19412 return _("NT_ARCH (architecture)");
9ef920e9 19413 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19414 return _("OPEN");
9ef920e9 19415 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19416 return _("func");
c8795e1f
NC
19417 case NT_GO_BUILDID:
19418 return _("GO BUILDID");
3ac925fc
LB
19419 case FDO_PACKAGING_METADATA:
19420 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19421 default:
19422 break;
19423 }
19424
e9e44622 19425 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19426 return buff;
779fe533
NC
19427}
19428
015dc7e1 19429static bool
9ece1fa9
TT
19430print_core_note (Elf_Internal_Note *pnote)
19431{
19432 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19433 uint64_t count, page_size;
9ece1fa9
TT
19434 unsigned char *descdata, *filenames, *descend;
19435
19436 if (pnote->type != NT_FILE)
04ac15ab
AS
19437 {
19438 if (do_wide)
19439 printf ("\n");
015dc7e1 19440 return true;
04ac15ab 19441 }
9ece1fa9 19442
9ece1fa9
TT
19443 if (!is_32bit_elf)
19444 {
19445 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19446 /* Still "successful". */
015dc7e1 19447 return true;
9ece1fa9 19448 }
9ece1fa9
TT
19449
19450 if (pnote->descsz < 2 * addr_size)
19451 {
32ec8896 19452 error (_(" Malformed note - too short for header\n"));
015dc7e1 19453 return false;
9ece1fa9
TT
19454 }
19455
19456 descdata = (unsigned char *) pnote->descdata;
19457 descend = descdata + pnote->descsz;
19458
19459 if (descdata[pnote->descsz - 1] != '\0')
19460 {
32ec8896 19461 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19462 return false;
9ece1fa9
TT
19463 }
19464
19465 count = byte_get (descdata, addr_size);
19466 descdata += addr_size;
19467
19468 page_size = byte_get (descdata, addr_size);
19469 descdata += addr_size;
19470
625d49fc 19471 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19472 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19473 {
32ec8896 19474 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19475 return false;
9ece1fa9
TT
19476 }
19477
19478 printf (_(" Page size: "));
19479 print_vma (page_size, DEC);
19480 printf ("\n");
19481
19482 printf (_(" %*s%*s%*s\n"),
19483 (int) (2 + 2 * addr_size), _("Start"),
19484 (int) (4 + 2 * addr_size), _("End"),
19485 (int) (4 + 2 * addr_size), _("Page Offset"));
19486 filenames = descdata + count * 3 * addr_size;
595712bb 19487 while (count-- > 0)
9ece1fa9 19488 {
625d49fc 19489 uint64_t start, end, file_ofs;
9ece1fa9
TT
19490
19491 if (filenames == descend)
19492 {
32ec8896 19493 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19494 return false;
9ece1fa9
TT
19495 }
19496
19497 start = byte_get (descdata, addr_size);
19498 descdata += addr_size;
19499 end = byte_get (descdata, addr_size);
19500 descdata += addr_size;
19501 file_ofs = byte_get (descdata, addr_size);
19502 descdata += addr_size;
19503
19504 printf (" ");
19505 print_vma (start, FULL_HEX);
19506 printf (" ");
19507 print_vma (end, FULL_HEX);
19508 printf (" ");
19509 print_vma (file_ofs, FULL_HEX);
19510 printf ("\n %s\n", filenames);
19511
19512 filenames += 1 + strlen ((char *) filenames);
19513 }
19514
015dc7e1 19515 return true;
9ece1fa9
TT
19516}
19517
1118d252
RM
19518static const char *
19519get_gnu_elf_note_type (unsigned e_type)
19520{
1449284b 19521 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19522 switch (e_type)
19523 {
19524 case NT_GNU_ABI_TAG:
19525 return _("NT_GNU_ABI_TAG (ABI version tag)");
19526 case NT_GNU_HWCAP:
19527 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19528 case NT_GNU_BUILD_ID:
19529 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19530 case NT_GNU_GOLD_VERSION:
19531 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19532 case NT_GNU_PROPERTY_TYPE_0:
19533 return _("NT_GNU_PROPERTY_TYPE_0");
19534 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19535 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19536 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19537 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19538 default:
1449284b
NC
19539 {
19540 static char buff[64];
1118d252 19541
1449284b
NC
19542 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19543 return buff;
19544 }
19545 }
1118d252
RM
19546}
19547
a9eafb08
L
19548static void
19549decode_x86_compat_isa (unsigned int bitmask)
19550{
19551 while (bitmask)
19552 {
19553 unsigned int bit = bitmask & (- bitmask);
19554
19555 bitmask &= ~ bit;
19556 switch (bit)
19557 {
19558 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19559 printf ("i486");
19560 break;
19561 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19562 printf ("586");
19563 break;
19564 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19565 printf ("686");
19566 break;
19567 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19568 printf ("SSE");
19569 break;
19570 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19571 printf ("SSE2");
19572 break;
19573 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19574 printf ("SSE3");
19575 break;
19576 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19577 printf ("SSSE3");
19578 break;
19579 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19580 printf ("SSE4_1");
19581 break;
19582 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19583 printf ("SSE4_2");
19584 break;
19585 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19586 printf ("AVX");
19587 break;
19588 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19589 printf ("AVX2");
19590 break;
19591 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19592 printf ("AVX512F");
19593 break;
19594 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19595 printf ("AVX512CD");
19596 break;
19597 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19598 printf ("AVX512ER");
19599 break;
19600 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19601 printf ("AVX512PF");
19602 break;
19603 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19604 printf ("AVX512VL");
19605 break;
19606 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19607 printf ("AVX512DQ");
19608 break;
19609 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19610 printf ("AVX512BW");
19611 break;
65b3d26e
L
19612 default:
19613 printf (_("<unknown: %x>"), bit);
19614 break;
a9eafb08
L
19615 }
19616 if (bitmask)
19617 printf (", ");
19618 }
19619}
19620
9ef920e9 19621static void
32930e4e 19622decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19623{
0a59decb 19624 if (!bitmask)
90c745dc
L
19625 {
19626 printf (_("<None>"));
19627 return;
19628 }
90c745dc 19629
9ef920e9
NC
19630 while (bitmask)
19631 {
1fc87489 19632 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19633
19634 bitmask &= ~ bit;
19635 switch (bit)
19636 {
32930e4e 19637 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19638 printf ("CMOV");
19639 break;
32930e4e 19640 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19641 printf ("SSE");
19642 break;
32930e4e 19643 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19644 printf ("SSE2");
19645 break;
32930e4e 19646 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19647 printf ("SSE3");
19648 break;
32930e4e 19649 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19650 printf ("SSSE3");
19651 break;
32930e4e 19652 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19653 printf ("SSE4_1");
19654 break;
32930e4e 19655 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19656 printf ("SSE4_2");
19657 break;
32930e4e 19658 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19659 printf ("AVX");
19660 break;
32930e4e 19661 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19662 printf ("AVX2");
19663 break;
32930e4e 19664 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19665 printf ("FMA");
19666 break;
32930e4e 19667 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19668 printf ("AVX512F");
19669 break;
32930e4e 19670 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19671 printf ("AVX512CD");
19672 break;
32930e4e 19673 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19674 printf ("AVX512ER");
19675 break;
32930e4e 19676 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19677 printf ("AVX512PF");
19678 break;
32930e4e 19679 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19680 printf ("AVX512VL");
19681 break;
32930e4e 19682 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19683 printf ("AVX512DQ");
19684 break;
32930e4e 19685 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19686 printf ("AVX512BW");
19687 break;
32930e4e 19688 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19689 printf ("AVX512_4FMAPS");
19690 break;
32930e4e 19691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19692 printf ("AVX512_4VNNIW");
19693 break;
32930e4e 19694 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19695 printf ("AVX512_BITALG");
19696 break;
32930e4e 19697 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19698 printf ("AVX512_IFMA");
19699 break;
32930e4e 19700 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19701 printf ("AVX512_VBMI");
19702 break;
32930e4e 19703 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19704 printf ("AVX512_VBMI2");
19705 break;
32930e4e 19706 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19707 printf ("AVX512_VNNI");
19708 break;
32930e4e 19709 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19710 printf ("AVX512_BF16");
19711 break;
65b3d26e
L
19712 default:
19713 printf (_("<unknown: %x>"), bit);
19714 break;
9ef920e9
NC
19715 }
19716 if (bitmask)
19717 printf (", ");
19718 }
19719}
19720
28cdbb18
SM
19721static const char *
19722get_amdgpu_elf_note_type (unsigned int e_type)
19723{
19724 switch (e_type)
19725 {
19726 case NT_AMDGPU_METADATA:
19727 return _("NT_AMDGPU_METADATA (code object metadata)");
19728 default:
19729 {
19730 static char buf[64];
19731 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19732 return buf;
19733 }
19734 }
19735}
19736
32930e4e
L
19737static void
19738decode_x86_isa (unsigned int bitmask)
19739{
32930e4e
L
19740 while (bitmask)
19741 {
19742 unsigned int bit = bitmask & (- bitmask);
19743
19744 bitmask &= ~ bit;
19745 switch (bit)
19746 {
b0ab0693
L
19747 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19748 printf ("x86-64-baseline");
19749 break;
32930e4e
L
19750 case GNU_PROPERTY_X86_ISA_1_V2:
19751 printf ("x86-64-v2");
19752 break;
19753 case GNU_PROPERTY_X86_ISA_1_V3:
19754 printf ("x86-64-v3");
19755 break;
19756 case GNU_PROPERTY_X86_ISA_1_V4:
19757 printf ("x86-64-v4");
19758 break;
19759 default:
19760 printf (_("<unknown: %x>"), bit);
19761 break;
19762 }
19763 if (bitmask)
19764 printf (", ");
19765 }
19766}
19767
ee2fdd6f 19768static void
a9eafb08 19769decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19770{
0a59decb 19771 if (!bitmask)
90c745dc
L
19772 {
19773 printf (_("<None>"));
19774 return;
19775 }
90c745dc 19776
ee2fdd6f
L
19777 while (bitmask)
19778 {
19779 unsigned int bit = bitmask & (- bitmask);
19780
19781 bitmask &= ~ bit;
19782 switch (bit)
19783 {
19784 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19785 printf ("IBT");
ee2fdd6f 19786 break;
48580982 19787 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19788 printf ("SHSTK");
48580982 19789 break;
279d901e
L
19790 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19791 printf ("LAM_U48");
19792 break;
19793 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19794 printf ("LAM_U57");
19795 break;
ee2fdd6f
L
19796 default:
19797 printf (_("<unknown: %x>"), bit);
19798 break;
19799 }
19800 if (bitmask)
19801 printf (", ");
19802 }
19803}
19804
a9eafb08
L
19805static void
19806decode_x86_feature_2 (unsigned int bitmask)
19807{
0a59decb 19808 if (!bitmask)
90c745dc
L
19809 {
19810 printf (_("<None>"));
19811 return;
19812 }
90c745dc 19813
a9eafb08
L
19814 while (bitmask)
19815 {
19816 unsigned int bit = bitmask & (- bitmask);
19817
19818 bitmask &= ~ bit;
19819 switch (bit)
19820 {
19821 case GNU_PROPERTY_X86_FEATURE_2_X86:
19822 printf ("x86");
19823 break;
19824 case GNU_PROPERTY_X86_FEATURE_2_X87:
19825 printf ("x87");
19826 break;
19827 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19828 printf ("MMX");
19829 break;
19830 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19831 printf ("XMM");
19832 break;
19833 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19834 printf ("YMM");
19835 break;
19836 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19837 printf ("ZMM");
19838 break;
a308b89d
L
19839 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19840 printf ("TMM");
19841 break;
32930e4e
L
19842 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19843 printf ("MASK");
19844 break;
a9eafb08
L
19845 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19846 printf ("FXSR");
19847 break;
19848 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19849 printf ("XSAVE");
19850 break;
19851 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19852 printf ("XSAVEOPT");
19853 break;
19854 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19855 printf ("XSAVEC");
19856 break;
65b3d26e
L
19857 default:
19858 printf (_("<unknown: %x>"), bit);
19859 break;
a9eafb08
L
19860 }
19861 if (bitmask)
19862 printf (", ");
19863 }
19864}
19865
cd702818
SD
19866static void
19867decode_aarch64_feature_1_and (unsigned int bitmask)
19868{
19869 while (bitmask)
19870 {
19871 unsigned int bit = bitmask & (- bitmask);
19872
19873 bitmask &= ~ bit;
19874 switch (bit)
19875 {
19876 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19877 printf ("BTI");
19878 break;
19879
19880 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19881 printf ("PAC");
19882 break;
19883
19884 default:
19885 printf (_("<unknown: %x>"), bit);
19886 break;
19887 }
19888 if (bitmask)
19889 printf (", ");
19890 }
19891}
19892
6320fd00
L
19893static void
19894decode_1_needed (unsigned int bitmask)
19895{
19896 while (bitmask)
19897 {
19898 unsigned int bit = bitmask & (- bitmask);
19899
19900 bitmask &= ~ bit;
19901 switch (bit)
19902 {
19903 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19904 printf ("indirect external access");
19905 break;
19906 default:
19907 printf (_("<unknown: %x>"), bit);
19908 break;
19909 }
19910 if (bitmask)
19911 printf (", ");
19912 }
19913}
19914
9ef920e9 19915static void
dda8d76d 19916print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19917{
19918 unsigned char * ptr = (unsigned char *) pnote->descdata;
19919 unsigned char * ptr_end = ptr + pnote->descsz;
19920 unsigned int size = is_32bit_elf ? 4 : 8;
19921
19922 printf (_(" Properties: "));
19923
1fc87489 19924 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19925 {
19926 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19927 return;
19928 }
19929
6ab2c4ed 19930 while (ptr < ptr_end)
9ef920e9 19931 {
1fc87489 19932 unsigned int j;
6ab2c4ed
MC
19933 unsigned int type;
19934 unsigned int datasz;
19935
19936 if ((size_t) (ptr_end - ptr) < 8)
19937 {
19938 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19939 break;
19940 }
19941
19942 type = byte_get (ptr, 4);
19943 datasz = byte_get (ptr + 4, 4);
9ef920e9 19944
1fc87489 19945 ptr += 8;
9ef920e9 19946
6ab2c4ed 19947 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19948 {
1fc87489
L
19949 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19950 type, datasz);
9ef920e9 19951 break;
1fc87489 19952 }
9ef920e9 19953
1fc87489
L
19954 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19955 {
dda8d76d
NC
19956 if (filedata->file_header.e_machine == EM_X86_64
19957 || filedata->file_header.e_machine == EM_IAMCU
19958 || filedata->file_header.e_machine == EM_386)
1fc87489 19959 {
aa7bca9b
L
19960 unsigned int bitmask;
19961
19962 if (datasz == 4)
0a59decb 19963 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19964 else
19965 bitmask = 0;
19966
1fc87489
L
19967 switch (type)
19968 {
19969 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19970 if (datasz != 4)
aa7bca9b
L
19971 printf (_("x86 ISA used: <corrupt length: %#x> "),
19972 datasz);
1fc87489 19973 else
aa7bca9b
L
19974 {
19975 printf ("x86 ISA used: ");
19976 decode_x86_isa (bitmask);
19977 }
1fc87489 19978 goto next;
9ef920e9 19979
1fc87489 19980 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19981 if (datasz != 4)
aa7bca9b
L
19982 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19983 datasz);
1fc87489 19984 else
aa7bca9b
L
19985 {
19986 printf ("x86 ISA needed: ");
19987 decode_x86_isa (bitmask);
19988 }
1fc87489 19989 goto next;
9ef920e9 19990
ee2fdd6f 19991 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19992 if (datasz != 4)
aa7bca9b
L
19993 printf (_("x86 feature: <corrupt length: %#x> "),
19994 datasz);
ee2fdd6f 19995 else
aa7bca9b
L
19996 {
19997 printf ("x86 feature: ");
a9eafb08
L
19998 decode_x86_feature_1 (bitmask);
19999 }
20000 goto next;
20001
20002 case GNU_PROPERTY_X86_FEATURE_2_USED:
20003 if (datasz != 4)
20004 printf (_("x86 feature used: <corrupt length: %#x> "),
20005 datasz);
20006 else
20007 {
20008 printf ("x86 feature used: ");
20009 decode_x86_feature_2 (bitmask);
20010 }
20011 goto next;
20012
20013 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20014 if (datasz != 4)
20015 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20016 else
20017 {
20018 printf ("x86 feature needed: ");
20019 decode_x86_feature_2 (bitmask);
20020 }
20021 goto next;
20022
20023 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20024 if (datasz != 4)
20025 printf (_("x86 ISA used: <corrupt length: %#x> "),
20026 datasz);
20027 else
20028 {
20029 printf ("x86 ISA used: ");
20030 decode_x86_compat_isa (bitmask);
20031 }
20032 goto next;
20033
20034 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20035 if (datasz != 4)
20036 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20037 datasz);
20038 else
20039 {
20040 printf ("x86 ISA needed: ");
20041 decode_x86_compat_isa (bitmask);
aa7bca9b 20042 }
ee2fdd6f
L
20043 goto next;
20044
32930e4e
L
20045 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20046 if (datasz != 4)
20047 printf (_("x86 ISA used: <corrupt length: %#x> "),
20048 datasz);
20049 else
20050 {
20051 printf ("x86 ISA used: ");
20052 decode_x86_compat_2_isa (bitmask);
20053 }
20054 goto next;
20055
20056 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20057 if (datasz != 4)
20058 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20059 datasz);
20060 else
20061 {
20062 printf ("x86 ISA needed: ");
20063 decode_x86_compat_2_isa (bitmask);
20064 }
20065 goto next;
20066
1fc87489
L
20067 default:
20068 break;
20069 }
20070 }
cd702818
SD
20071 else if (filedata->file_header.e_machine == EM_AARCH64)
20072 {
20073 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20074 {
20075 printf ("AArch64 feature: ");
20076 if (datasz != 4)
20077 printf (_("<corrupt length: %#x> "), datasz);
20078 else
20079 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20080 goto next;
20081 }
20082 }
1fc87489
L
20083 }
20084 else
20085 {
20086 switch (type)
9ef920e9 20087 {
1fc87489
L
20088 case GNU_PROPERTY_STACK_SIZE:
20089 printf (_("stack size: "));
20090 if (datasz != size)
20091 printf (_("<corrupt length: %#x> "), datasz);
20092 else
20093 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20094 goto next;
20095
20096 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20097 printf ("no copy on protected ");
20098 if (datasz)
20099 printf (_("<corrupt length: %#x> "), datasz);
20100 goto next;
20101
20102 default:
5a767724
L
20103 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20104 && type <= GNU_PROPERTY_UINT32_AND_HI)
20105 || (type >= GNU_PROPERTY_UINT32_OR_LO
20106 && type <= GNU_PROPERTY_UINT32_OR_HI))
20107 {
6320fd00
L
20108 switch (type)
20109 {
20110 case GNU_PROPERTY_1_NEEDED:
20111 if (datasz != 4)
20112 printf (_("1_needed: <corrupt length: %#x> "),
20113 datasz);
20114 else
20115 {
20116 unsigned int bitmask = byte_get (ptr, 4);
20117 printf ("1_needed: ");
20118 decode_1_needed (bitmask);
20119 }
20120 goto next;
20121
20122 default:
20123 break;
20124 }
5a767724
L
20125 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20126 printf (_("UINT32_AND (%#x): "), type);
20127 else
20128 printf (_("UINT32_OR (%#x): "), type);
20129 if (datasz != 4)
20130 printf (_("<corrupt length: %#x> "), datasz);
20131 else
20132 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20133 goto next;
20134 }
9ef920e9
NC
20135 break;
20136 }
9ef920e9
NC
20137 }
20138
1fc87489
L
20139 if (type < GNU_PROPERTY_LOPROC)
20140 printf (_("<unknown type %#x data: "), type);
20141 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20142 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20143 else
20144 printf (_("<application-specific type %#x data: "), type);
20145 for (j = 0; j < datasz; ++j)
20146 printf ("%02x ", ptr[j] & 0xff);
20147 printf (">");
20148
dc1e8a47 20149 next:
9ef920e9 20150 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20151 if (ptr == ptr_end)
20152 break;
1fc87489 20153
6ab2c4ed
MC
20154 if (do_wide)
20155 printf (", ");
20156 else
20157 printf ("\n\t");
9ef920e9
NC
20158 }
20159
20160 printf ("\n");
20161}
20162
015dc7e1 20163static bool
dda8d76d 20164print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20165{
1449284b 20166 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20167 switch (pnote->type)
20168 {
20169 case NT_GNU_BUILD_ID:
20170 {
20171 unsigned long i;
20172
20173 printf (_(" Build ID: "));
20174 for (i = 0; i < pnote->descsz; ++i)
20175 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20176 printf ("\n");
664f90a3
TT
20177 }
20178 break;
20179
20180 case NT_GNU_ABI_TAG:
20181 {
20182 unsigned long os, major, minor, subminor;
20183 const char *osname;
20184
3102e897
NC
20185 /* PR 17531: file: 030-599401-0.004. */
20186 if (pnote->descsz < 16)
20187 {
20188 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20189 break;
20190 }
20191
664f90a3
TT
20192 os = byte_get ((unsigned char *) pnote->descdata, 4);
20193 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20194 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20195 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20196
20197 switch (os)
20198 {
20199 case GNU_ABI_TAG_LINUX:
20200 osname = "Linux";
20201 break;
20202 case GNU_ABI_TAG_HURD:
20203 osname = "Hurd";
20204 break;
20205 case GNU_ABI_TAG_SOLARIS:
20206 osname = "Solaris";
20207 break;
20208 case GNU_ABI_TAG_FREEBSD:
20209 osname = "FreeBSD";
20210 break;
20211 case GNU_ABI_TAG_NETBSD:
20212 osname = "NetBSD";
20213 break;
14ae95f2
RM
20214 case GNU_ABI_TAG_SYLLABLE:
20215 osname = "Syllable";
20216 break;
20217 case GNU_ABI_TAG_NACL:
20218 osname = "NaCl";
20219 break;
664f90a3
TT
20220 default:
20221 osname = "Unknown";
20222 break;
20223 }
20224
20225 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20226 major, minor, subminor);
20227 }
20228 break;
926c5385
CC
20229
20230 case NT_GNU_GOLD_VERSION:
20231 {
20232 unsigned long i;
20233
20234 printf (_(" Version: "));
20235 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20236 printf ("%c", pnote->descdata[i]);
20237 printf ("\n");
20238 }
20239 break;
1449284b
NC
20240
20241 case NT_GNU_HWCAP:
20242 {
20243 unsigned long num_entries, mask;
20244
20245 /* Hardware capabilities information. Word 0 is the number of entries.
20246 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20247 is a series of entries, where each entry is a single byte followed
20248 by a nul terminated string. The byte gives the bit number to test
20249 if enabled in the bitmask. */
20250 printf (_(" Hardware Capabilities: "));
20251 if (pnote->descsz < 8)
20252 {
32ec8896 20253 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20254 return false;
1449284b
NC
20255 }
20256 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20257 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20258 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20259 /* FIXME: Add code to display the entries... */
20260 }
20261 break;
20262
9ef920e9 20263 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20264 print_gnu_property_note (filedata, pnote);
9ef920e9 20265 break;
9abca702 20266
1449284b
NC
20267 default:
20268 /* Handle unrecognised types. An error message should have already been
20269 created by get_gnu_elf_note_type(), so all that we need to do is to
20270 display the data. */
20271 {
20272 unsigned long i;
20273
20274 printf (_(" Description data: "));
20275 for (i = 0; i < pnote->descsz; ++i)
20276 printf ("%02x ", pnote->descdata[i] & 0xff);
20277 printf ("\n");
20278 }
20279 break;
664f90a3
TT
20280 }
20281
015dc7e1 20282 return true;
664f90a3
TT
20283}
20284
685080f2
NC
20285static const char *
20286get_v850_elf_note_type (enum v850_notes n_type)
20287{
20288 static char buff[64];
20289
20290 switch (n_type)
20291 {
20292 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20293 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20294 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20295 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20296 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20297 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20298 default:
20299 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20300 return buff;
20301 }
20302}
20303
015dc7e1 20304static bool
685080f2
NC
20305print_v850_note (Elf_Internal_Note * pnote)
20306{
20307 unsigned int val;
20308
20309 if (pnote->descsz != 4)
015dc7e1 20310 return false;
32ec8896 20311
685080f2
NC
20312 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20313
20314 if (val == 0)
20315 {
20316 printf (_("not set\n"));
015dc7e1 20317 return true;
685080f2
NC
20318 }
20319
20320 switch (pnote->type)
20321 {
20322 case V850_NOTE_ALIGNMENT:
20323 switch (val)
20324 {
015dc7e1
AM
20325 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20326 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20327 }
20328 break;
14ae95f2 20329
685080f2
NC
20330 case V850_NOTE_DATA_SIZE:
20331 switch (val)
20332 {
015dc7e1
AM
20333 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20334 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20335 }
20336 break;
14ae95f2 20337
685080f2
NC
20338 case V850_NOTE_FPU_INFO:
20339 switch (val)
20340 {
015dc7e1
AM
20341 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20342 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20343 }
20344 break;
14ae95f2 20345
685080f2
NC
20346 case V850_NOTE_MMU_INFO:
20347 case V850_NOTE_CACHE_INFO:
20348 case V850_NOTE_SIMD_INFO:
20349 if (val == EF_RH850_SIMD)
20350 {
20351 printf (_("yes\n"));
015dc7e1 20352 return true;
685080f2
NC
20353 }
20354 break;
20355
20356 default:
20357 /* An 'unknown note type' message will already have been displayed. */
20358 break;
20359 }
20360
20361 printf (_("unknown value: %x\n"), val);
015dc7e1 20362 return false;
685080f2
NC
20363}
20364
015dc7e1 20365static bool
c6056a74
SF
20366process_netbsd_elf_note (Elf_Internal_Note * pnote)
20367{
20368 unsigned int version;
20369
20370 switch (pnote->type)
20371 {
20372 case NT_NETBSD_IDENT:
b966f55f
AM
20373 if (pnote->descsz < 1)
20374 break;
c6056a74
SF
20375 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20376 if ((version / 10000) % 100)
b966f55f 20377 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20378 version, version / 100000000, (version / 1000000) % 100,
20379 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20380 'A' + (version / 10000) % 26);
c6056a74
SF
20381 else
20382 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20383 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20384 (version / 100) % 100);
015dc7e1 20385 return true;
c6056a74
SF
20386
20387 case NT_NETBSD_MARCH:
9abca702 20388 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20389 pnote->descdata);
015dc7e1 20390 return true;
c6056a74 20391
9abca702 20392 case NT_NETBSD_PAX:
b966f55f
AM
20393 if (pnote->descsz < 1)
20394 break;
9abca702
CZ
20395 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20396 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20397 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20398 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20399 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20400 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20401 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20402 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20403 return true;
c6056a74 20404 }
b966f55f
AM
20405
20406 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20407 pnote->descsz, pnote->type);
015dc7e1 20408 return false;
c6056a74
SF
20409}
20410
f4ddf30f 20411static const char *
dda8d76d 20412get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20413{
f4ddf30f
JB
20414 switch (e_type)
20415 {
20416 case NT_FREEBSD_THRMISC:
20417 return _("NT_THRMISC (thrmisc structure)");
20418 case NT_FREEBSD_PROCSTAT_PROC:
20419 return _("NT_PROCSTAT_PROC (proc data)");
20420 case NT_FREEBSD_PROCSTAT_FILES:
20421 return _("NT_PROCSTAT_FILES (files data)");
20422 case NT_FREEBSD_PROCSTAT_VMMAP:
20423 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20424 case NT_FREEBSD_PROCSTAT_GROUPS:
20425 return _("NT_PROCSTAT_GROUPS (groups data)");
20426 case NT_FREEBSD_PROCSTAT_UMASK:
20427 return _("NT_PROCSTAT_UMASK (umask data)");
20428 case NT_FREEBSD_PROCSTAT_RLIMIT:
20429 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20430 case NT_FREEBSD_PROCSTAT_OSREL:
20431 return _("NT_PROCSTAT_OSREL (osreldate data)");
20432 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20433 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20434 case NT_FREEBSD_PROCSTAT_AUXV:
20435 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20436 case NT_FREEBSD_PTLWPINFO:
20437 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20438 case NT_FREEBSD_X86_SEGBASES:
20439 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20440 }
dda8d76d 20441 return get_note_type (filedata, e_type);
f4ddf30f
JB
20442}
20443
9437c45b 20444static const char *
dda8d76d 20445get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20446{
20447 static char buff[64];
20448
540e6170
CZ
20449 switch (e_type)
20450 {
20451 case NT_NETBSDCORE_PROCINFO:
20452 /* NetBSD core "procinfo" structure. */
20453 return _("NetBSD procinfo structure");
9437c45b 20454
540e6170
CZ
20455 case NT_NETBSDCORE_AUXV:
20456 return _("NetBSD ELF auxiliary vector data");
9437c45b 20457
06d949ec
KR
20458 case NT_NETBSDCORE_LWPSTATUS:
20459 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20460
540e6170 20461 default:
06d949ec 20462 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20463 defined for NetBSD core files. If the note type is less
20464 than the start of the machine-dependent note types, we don't
20465 understand it. */
20466
20467 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20468 {
20469 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20470 return buff;
20471 }
20472 break;
9437c45b
JT
20473 }
20474
dda8d76d 20475 switch (filedata->file_header.e_machine)
9437c45b
JT
20476 {
20477 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20478 and PT_GETFPREGS == mach+2. */
20479
20480 case EM_OLD_ALPHA:
20481 case EM_ALPHA:
20482 case EM_SPARC:
20483 case EM_SPARC32PLUS:
20484 case EM_SPARCV9:
20485 switch (e_type)
20486 {
2b692964 20487 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20488 return _("PT_GETREGS (reg structure)");
2b692964 20489 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20490 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20491 default:
20492 break;
20493 }
20494 break;
20495
c0d38b0e
CZ
20496 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20497 There's also old PT___GETREGS40 == mach + 1 for old reg
20498 structure which lacks GBR. */
20499 case EM_SH:
20500 switch (e_type)
20501 {
20502 case NT_NETBSDCORE_FIRSTMACH + 1:
20503 return _("PT___GETREGS40 (old reg structure)");
20504 case NT_NETBSDCORE_FIRSTMACH + 3:
20505 return _("PT_GETREGS (reg structure)");
20506 case NT_NETBSDCORE_FIRSTMACH + 5:
20507 return _("PT_GETFPREGS (fpreg structure)");
20508 default:
20509 break;
20510 }
20511 break;
20512
9437c45b
JT
20513 /* On all other arch's, PT_GETREGS == mach+1 and
20514 PT_GETFPREGS == mach+3. */
20515 default:
20516 switch (e_type)
20517 {
2b692964 20518 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20519 return _("PT_GETREGS (reg structure)");
2b692964 20520 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20521 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20522 default:
20523 break;
20524 }
20525 }
20526
9cf03b7e 20527 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20528 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20529 return buff;
20530}
20531
98ca73af
FC
20532static const char *
20533get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20534{
20535 switch (e_type)
20536 {
20537 case NT_OPENBSD_PROCINFO:
20538 return _("OpenBSD procinfo structure");
20539 case NT_OPENBSD_AUXV:
20540 return _("OpenBSD ELF auxiliary vector data");
20541 case NT_OPENBSD_REGS:
20542 return _("OpenBSD regular registers");
20543 case NT_OPENBSD_FPREGS:
20544 return _("OpenBSD floating point registers");
20545 case NT_OPENBSD_WCOOKIE:
20546 return _("OpenBSD window cookie");
20547 }
20548
20549 return get_note_type (filedata, e_type);
20550}
20551
70616151
TT
20552static const char *
20553get_stapsdt_note_type (unsigned e_type)
20554{
20555 static char buff[64];
20556
20557 switch (e_type)
20558 {
20559 case NT_STAPSDT:
20560 return _("NT_STAPSDT (SystemTap probe descriptors)");
20561
20562 default:
20563 break;
20564 }
20565
20566 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20567 return buff;
20568}
20569
015dc7e1 20570static bool
c6a9fc58
TT
20571print_stapsdt_note (Elf_Internal_Note *pnote)
20572{
3ca60c57
NC
20573 size_t len, maxlen;
20574 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20575 char *data = pnote->descdata;
20576 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20577 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20578 char *provider, *probe, *arg_fmt;
20579
3ca60c57
NC
20580 if (pnote->descsz < (addr_size * 3))
20581 goto stapdt_note_too_small;
20582
c6a9fc58
TT
20583 pc = byte_get ((unsigned char *) data, addr_size);
20584 data += addr_size;
3ca60c57 20585
c6a9fc58
TT
20586 base_addr = byte_get ((unsigned char *) data, addr_size);
20587 data += addr_size;
3ca60c57 20588
c6a9fc58
TT
20589 semaphore = byte_get ((unsigned char *) data, addr_size);
20590 data += addr_size;
20591
3ca60c57
NC
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 provider = data;
20599 data += len + 1;
20600 }
20601 else
20602 goto stapdt_note_too_small;
20603
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 probe = data;
20611 data += len + 1;
20612 }
20613 else
20614 goto stapdt_note_too_small;
9abca702 20615
3ca60c57
NC
20616 if (data >= data_end)
20617 goto stapdt_note_too_small;
20618 maxlen = data_end - data;
20619 len = strnlen (data, maxlen);
20620 if (len < maxlen)
20621 {
20622 arg_fmt = data;
20623 data += len + 1;
20624 }
20625 else
20626 goto stapdt_note_too_small;
c6a9fc58
TT
20627
20628 printf (_(" Provider: %s\n"), provider);
20629 printf (_(" Name: %s\n"), probe);
20630 printf (_(" Location: "));
20631 print_vma (pc, FULL_HEX);
20632 printf (_(", Base: "));
20633 print_vma (base_addr, FULL_HEX);
20634 printf (_(", Semaphore: "));
20635 print_vma (semaphore, FULL_HEX);
9cf03b7e 20636 printf ("\n");
c6a9fc58
TT
20637 printf (_(" Arguments: %s\n"), arg_fmt);
20638
20639 return data == data_end;
3ca60c57
NC
20640
20641 stapdt_note_too_small:
20642 printf (_(" <corrupt - note is too small>\n"));
20643 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20644 return false;
c6a9fc58
TT
20645}
20646
e5382207
LB
20647static bool
20648print_fdo_note (Elf_Internal_Note * pnote)
20649{
20650 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20651 {
20652 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20653 return true;
20654 }
20655 return false;
20656}
20657
00e98fc7
TG
20658static const char *
20659get_ia64_vms_note_type (unsigned e_type)
20660{
20661 static char buff[64];
20662
20663 switch (e_type)
20664 {
20665 case NT_VMS_MHD:
20666 return _("NT_VMS_MHD (module header)");
20667 case NT_VMS_LNM:
20668 return _("NT_VMS_LNM (language name)");
20669 case NT_VMS_SRC:
20670 return _("NT_VMS_SRC (source files)");
20671 case NT_VMS_TITLE:
9cf03b7e 20672 return "NT_VMS_TITLE";
00e98fc7
TG
20673 case NT_VMS_EIDC:
20674 return _("NT_VMS_EIDC (consistency check)");
20675 case NT_VMS_FPMODE:
20676 return _("NT_VMS_FPMODE (FP mode)");
20677 case NT_VMS_LINKTIME:
9cf03b7e 20678 return "NT_VMS_LINKTIME";
00e98fc7
TG
20679 case NT_VMS_IMGNAM:
20680 return _("NT_VMS_IMGNAM (image name)");
20681 case NT_VMS_IMGID:
20682 return _("NT_VMS_IMGID (image id)");
20683 case NT_VMS_LINKID:
20684 return _("NT_VMS_LINKID (link id)");
20685 case NT_VMS_IMGBID:
20686 return _("NT_VMS_IMGBID (build id)");
20687 case NT_VMS_GSTNAM:
20688 return _("NT_VMS_GSTNAM (sym table name)");
20689 case NT_VMS_ORIG_DYN:
9cf03b7e 20690 return "NT_VMS_ORIG_DYN";
00e98fc7 20691 case NT_VMS_PATCHTIME:
9cf03b7e 20692 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20693 default:
20694 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20695 return buff;
20696 }
20697}
20698
015dc7e1 20699static bool
00e98fc7
TG
20700print_ia64_vms_note (Elf_Internal_Note * pnote)
20701{
8d18bf79
NC
20702 int maxlen = pnote->descsz;
20703
20704 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20705 goto desc_size_fail;
20706
00e98fc7
TG
20707 switch (pnote->type)
20708 {
20709 case NT_VMS_MHD:
8d18bf79
NC
20710 if (maxlen <= 36)
20711 goto desc_size_fail;
20712
20713 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20714
20715 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20716 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20717 if (l + 34 < maxlen)
20718 {
20719 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20720 if (l + 35 < maxlen)
20721 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20722 else
20723 printf (_(" Module version : <missing>\n"));
20724 }
00e98fc7 20725 else
8d18bf79
NC
20726 {
20727 printf (_(" Module name : <missing>\n"));
20728 printf (_(" Module version : <missing>\n"));
20729 }
00e98fc7 20730 break;
8d18bf79 20731
00e98fc7 20732 case NT_VMS_LNM:
8d18bf79 20733 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20734 break;
8d18bf79 20735
00e98fc7 20736 case NT_VMS_FPMODE:
9cf03b7e 20737 printf (_(" Floating Point mode: "));
8d18bf79
NC
20738 if (maxlen < 8)
20739 goto desc_size_fail;
20740 /* FIXME: Generate an error if descsz > 8 ? */
20741
b8281767 20742 printf ("0x%016" PRIx64 "\n",
625d49fc 20743 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20744 break;
8d18bf79 20745
00e98fc7
TG
20746 case NT_VMS_LINKTIME:
20747 printf (_(" Link time: "));
8d18bf79
NC
20748 if (maxlen < 8)
20749 goto desc_size_fail;
20750 /* FIXME: Generate an error if descsz > 8 ? */
20751
0e3c1eeb 20752 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20753 printf ("\n");
20754 break;
8d18bf79 20755
00e98fc7
TG
20756 case NT_VMS_PATCHTIME:
20757 printf (_(" Patch time: "));
8d18bf79
NC
20758 if (maxlen < 8)
20759 goto desc_size_fail;
20760 /* FIXME: Generate an error if descsz > 8 ? */
20761
0e3c1eeb 20762 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20763 printf ("\n");
20764 break;
8d18bf79 20765
00e98fc7 20766 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20767 if (maxlen < 34)
20768 goto desc_size_fail;
20769
00e98fc7 20770 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20771 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20772 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20773 printf (_(" Last modified : "));
0e3c1eeb 20774 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20775 printf (_("\n Link flags : "));
b8281767 20776 printf ("0x%016" PRIx64 "\n",
625d49fc 20777 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20778 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20779 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20780 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20781 break;
8d18bf79 20782
00e98fc7 20783 case NT_VMS_IMGNAM:
8d18bf79 20784 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20785 break;
8d18bf79 20786
00e98fc7 20787 case NT_VMS_GSTNAM:
8d18bf79 20788 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20789 break;
8d18bf79 20790
00e98fc7 20791 case NT_VMS_IMGID:
8d18bf79 20792 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20793 break;
8d18bf79 20794
00e98fc7 20795 case NT_VMS_LINKID:
8d18bf79 20796 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20797 break;
8d18bf79 20798
00e98fc7 20799 default:
015dc7e1 20800 return false;
00e98fc7 20801 }
8d18bf79 20802
015dc7e1 20803 return true;
8d18bf79
NC
20804
20805 desc_size_fail:
20806 printf (_(" <corrupt - data size is too small>\n"));
20807 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20808 return false;
00e98fc7
TG
20809}
20810
fd486f32
AM
20811struct build_attr_cache {
20812 Filedata *filedata;
20813 char *strtab;
20814 unsigned long strtablen;
20815 Elf_Internal_Sym *symtab;
20816 unsigned long nsyms;
20817} ba_cache;
20818
6f156d7a
NC
20819/* Find the symbol associated with a build attribute that is attached
20820 to address OFFSET. If PNAME is non-NULL then store the name of
20821 the symbol (if found) in the provided pointer, Returns NULL if a
20822 symbol could not be found. */
c799a79d 20823
6f156d7a 20824static Elf_Internal_Sym *
015dc7e1
AM
20825get_symbol_for_build_attribute (Filedata *filedata,
20826 unsigned long offset,
20827 bool is_open_attr,
20828 const char **pname)
9ef920e9 20829{
fd486f32
AM
20830 Elf_Internal_Sym *saved_sym = NULL;
20831 Elf_Internal_Sym *sym;
9ef920e9 20832
dda8d76d 20833 if (filedata->section_headers != NULL
fd486f32 20834 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20835 {
c799a79d 20836 Elf_Internal_Shdr * symsec;
9ef920e9 20837
fd486f32
AM
20838 free (ba_cache.strtab);
20839 ba_cache.strtab = NULL;
20840 free (ba_cache.symtab);
20841 ba_cache.symtab = NULL;
20842
c799a79d 20843 /* Load the symbol and string sections. */
dda8d76d
NC
20844 for (symsec = filedata->section_headers;
20845 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20846 symsec ++)
9ef920e9 20847 {
28d13567
AM
20848 if (symsec->sh_type == SHT_SYMTAB
20849 && get_symtab (filedata, symsec,
20850 &ba_cache.symtab, &ba_cache.nsyms,
20851 &ba_cache.strtab, &ba_cache.strtablen))
20852 break;
9ef920e9 20853 }
fd486f32 20854 ba_cache.filedata = filedata;
9ef920e9
NC
20855 }
20856
fd486f32 20857 if (ba_cache.symtab == NULL)
6f156d7a 20858 return NULL;
9ef920e9 20859
c799a79d 20860 /* Find a symbol whose value matches offset. */
fd486f32 20861 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20862 if (sym->st_value == offset)
20863 {
fd486f32 20864 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20865 /* Huh ? This should not happen. */
20866 continue;
9ef920e9 20867
fd486f32 20868 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20869 continue;
9ef920e9 20870
9b9b1092 20871 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20872 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20873 if (ba_cache.strtab[sym->st_name] == '$'
20874 && ba_cache.strtab[sym->st_name + 1] != 0
20875 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20876 continue;
20877
c799a79d
NC
20878 if (is_open_attr)
20879 {
20880 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20881 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20882 FUNC symbols entirely. */
20883 switch (ELF_ST_TYPE (sym->st_info))
20884 {
c799a79d 20885 case STT_OBJECT:
6f156d7a 20886 case STT_FILE:
c799a79d 20887 saved_sym = sym;
6f156d7a
NC
20888 if (sym->st_size)
20889 {
20890 /* If the symbol has a size associated
20891 with it then we can stop searching. */
fd486f32 20892 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20893 }
c799a79d 20894 continue;
9ef920e9 20895
c799a79d
NC
20896 case STT_FUNC:
20897 /* Ignore function symbols. */
20898 continue;
20899
20900 default:
20901 break;
20902 }
20903
20904 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20905 {
c799a79d
NC
20906 case STB_GLOBAL:
20907 if (saved_sym == NULL
20908 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20909 saved_sym = sym;
20910 break;
c871dade 20911
c799a79d
NC
20912 case STB_LOCAL:
20913 if (saved_sym == NULL)
20914 saved_sym = sym;
20915 break;
20916
20917 default:
9ef920e9
NC
20918 break;
20919 }
20920 }
c799a79d
NC
20921 else
20922 {
20923 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20924 continue;
20925
20926 saved_sym = sym;
20927 break;
20928 }
20929 }
20930
6f156d7a 20931 if (saved_sym && pname)
fd486f32 20932 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20933
20934 return saved_sym;
c799a79d
NC
20935}
20936
d20e98ab
NC
20937/* Returns true iff addr1 and addr2 are in the same section. */
20938
015dc7e1 20939static bool
d20e98ab
NC
20940same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20941{
20942 Elf_Internal_Shdr * a1;
20943 Elf_Internal_Shdr * a2;
20944
20945 a1 = find_section_by_address (filedata, addr1);
20946 a2 = find_section_by_address (filedata, addr2);
9abca702 20947
d20e98ab
NC
20948 return a1 == a2 && a1 != NULL;
20949}
20950
015dc7e1 20951static bool
dda8d76d
NC
20952print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20953 Filedata * filedata)
c799a79d 20954{
015dc7e1
AM
20955 static unsigned long global_offset = 0;
20956 static unsigned long global_end = 0;
20957 static unsigned long func_offset = 0;
20958 static unsigned long func_end = 0;
c871dade 20959
015dc7e1
AM
20960 Elf_Internal_Sym *sym;
20961 const char *name;
20962 unsigned long start;
20963 unsigned long end;
20964 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20965
20966 switch (pnote->descsz)
c799a79d 20967 {
6f156d7a
NC
20968 case 0:
20969 /* A zero-length description means that the range of
20970 the previous note of the same type should be used. */
c799a79d 20971 if (is_open_attr)
c871dade 20972 {
6f156d7a
NC
20973 if (global_end > global_offset)
20974 printf (_(" Applies to region from %#lx to %#lx\n"),
20975 global_offset, global_end);
20976 else
20977 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20978 }
20979 else
20980 {
6f156d7a
NC
20981 if (func_end > func_offset)
20982 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20983 else
20984 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20985 }
015dc7e1 20986 return true;
9ef920e9 20987
6f156d7a
NC
20988 case 4:
20989 start = byte_get ((unsigned char *) pnote->descdata, 4);
20990 end = 0;
20991 break;
20992
20993 case 8:
c74147bb
NC
20994 start = byte_get ((unsigned char *) pnote->descdata, 4);
20995 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20996 break;
20997
20998 case 16:
20999 start = byte_get ((unsigned char *) pnote->descdata, 8);
21000 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21001 break;
9abca702 21002
6f156d7a 21003 default:
c799a79d
NC
21004 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21005 printf (_(" <invalid descsz>"));
015dc7e1 21006 return false;
c799a79d
NC
21007 }
21008
6f156d7a
NC
21009 name = NULL;
21010 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21011 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21012 in order to avoid them being confused with the start address of the
21013 first function in the file... */
21014 if (sym == NULL && is_open_attr)
21015 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21016 & name);
6f156d7a
NC
21017
21018 if (end == 0 && sym != NULL && sym->st_size > 0)
21019 end = start + sym->st_size;
c799a79d
NC
21020
21021 if (is_open_attr)
21022 {
d20e98ab
NC
21023 /* FIXME: Need to properly allow for section alignment.
21024 16 is just the alignment used on x86_64. */
21025 if (global_end > 0
21026 && start > BFD_ALIGN (global_end, 16)
21027 /* Build notes are not guaranteed to be organised in order of
21028 increasing address, but we should find the all of the notes
21029 for one section in the same place. */
21030 && same_section (filedata, start, global_end))
6f156d7a
NC
21031 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21032 global_end + 1, start - 1);
21033
21034 printf (_(" Applies to region from %#lx"), start);
21035 global_offset = start;
21036
21037 if (end)
21038 {
21039 printf (_(" to %#lx"), end);
21040 global_end = end;
21041 }
c799a79d
NC
21042 }
21043 else
21044 {
6f156d7a
NC
21045 printf (_(" Applies to region from %#lx"), start);
21046 func_offset = start;
21047
21048 if (end)
21049 {
21050 printf (_(" to %#lx"), end);
21051 func_end = end;
21052 }
c799a79d
NC
21053 }
21054
6f156d7a
NC
21055 if (sym && name)
21056 printf (_(" (%s)"), name);
21057
21058 printf ("\n");
015dc7e1 21059 return true;
9ef920e9
NC
21060}
21061
015dc7e1 21062static bool
9ef920e9
NC
21063print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21064{
1d15e434
NC
21065 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21066 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21067 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21068 char name_type;
21069 char name_attribute;
1d15e434 21070 const char * expected_types;
9ef920e9
NC
21071 const char * name = pnote->namedata;
21072 const char * text;
88305e1b 21073 signed int left;
9ef920e9
NC
21074
21075 if (name == NULL || pnote->namesz < 2)
21076 {
21077 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21078 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21079 return false;
9ef920e9
NC
21080 }
21081
6f156d7a
NC
21082 if (do_wide)
21083 left = 28;
21084 else
21085 left = 20;
88305e1b
NC
21086
21087 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21088 if (name[0] == 'G' && name[1] == 'A')
21089 {
6f156d7a
NC
21090 if (pnote->namesz < 4)
21091 {
21092 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21093 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21094 return false;
6f156d7a
NC
21095 }
21096
88305e1b
NC
21097 printf ("GA");
21098 name += 2;
21099 left -= 2;
21100 }
21101
9ef920e9
NC
21102 switch ((name_type = * name))
21103 {
21104 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21105 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21106 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21107 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21108 printf ("%c", * name);
88305e1b 21109 left --;
9ef920e9
NC
21110 break;
21111 default:
21112 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21113 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21114 return false;
9ef920e9
NC
21115 }
21116
9ef920e9
NC
21117 ++ name;
21118 text = NULL;
21119
21120 switch ((name_attribute = * name))
21121 {
21122 case GNU_BUILD_ATTRIBUTE_VERSION:
21123 text = _("<version>");
1d15e434 21124 expected_types = string_expected;
9ef920e9
NC
21125 ++ name;
21126 break;
21127 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21128 text = _("<stack prot>");
75d7d298 21129 expected_types = "!+*";
9ef920e9
NC
21130 ++ name;
21131 break;
21132 case GNU_BUILD_ATTRIBUTE_RELRO:
21133 text = _("<relro>");
1d15e434 21134 expected_types = bool_expected;
9ef920e9
NC
21135 ++ name;
21136 break;
21137 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21138 text = _("<stack size>");
1d15e434 21139 expected_types = number_expected;
9ef920e9
NC
21140 ++ name;
21141 break;
21142 case GNU_BUILD_ATTRIBUTE_TOOL:
21143 text = _("<tool>");
1d15e434 21144 expected_types = string_expected;
9ef920e9
NC
21145 ++ name;
21146 break;
21147 case GNU_BUILD_ATTRIBUTE_ABI:
21148 text = _("<ABI>");
21149 expected_types = "$*";
21150 ++ name;
21151 break;
21152 case GNU_BUILD_ATTRIBUTE_PIC:
21153 text = _("<PIC>");
1d15e434 21154 expected_types = number_expected;
9ef920e9
NC
21155 ++ name;
21156 break;
a8be5506
NC
21157 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21158 text = _("<short enum>");
1d15e434 21159 expected_types = bool_expected;
a8be5506
NC
21160 ++ name;
21161 break;
9ef920e9
NC
21162 default:
21163 if (ISPRINT (* name))
21164 {
21165 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21166
21167 if (len > left && ! do_wide)
21168 len = left;
75d7d298 21169 printf ("%.*s:", len, name);
9ef920e9 21170 left -= len;
0dd6ae21 21171 name += len;
9ef920e9
NC
21172 }
21173 else
21174 {
3e6b6445 21175 static char tmpbuf [128];
88305e1b 21176
3e6b6445
NC
21177 error (_("unrecognised byte in name field: %d\n"), * name);
21178 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21179 text = tmpbuf;
21180 name ++;
9ef920e9
NC
21181 }
21182 expected_types = "*$!+";
21183 break;
21184 }
21185
21186 if (text)
88305e1b 21187 left -= printf ("%s", text);
9ef920e9
NC
21188
21189 if (strchr (expected_types, name_type) == NULL)
75d7d298 21190 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21191
21192 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21193 {
21194 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21195 (unsigned long) pnote->namesz,
21196 (long) (name - pnote->namedata));
015dc7e1 21197 return false;
9ef920e9
NC
21198 }
21199
21200 if (left < 1 && ! do_wide)
015dc7e1 21201 return true;
9ef920e9
NC
21202
21203 switch (name_type)
21204 {
21205 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21206 {
b06b2c92 21207 unsigned int bytes;
ddef72cd
NC
21208 unsigned long long val = 0;
21209 unsigned int shift = 0;
21210 char * decoded = NULL;
21211
b06b2c92
NC
21212 bytes = pnote->namesz - (name - pnote->namedata);
21213 if (bytes > 0)
21214 /* The -1 is because the name field is always 0 terminated, and we
21215 want to be able to ensure that the shift in the while loop below
21216 will not overflow. */
21217 -- bytes;
21218
ddef72cd
NC
21219 if (bytes > sizeof (val))
21220 {
3e6b6445
NC
21221 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21222 bytes);
21223 bytes = sizeof (val);
ddef72cd 21224 }
3e6b6445
NC
21225 /* We do not bother to warn if bytes == 0 as this can
21226 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21227
21228 while (bytes --)
21229 {
54b8331d 21230 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21231
21232 val |= byte << shift;
9ef920e9
NC
21233 shift += 8;
21234 }
21235
75d7d298 21236 switch (name_attribute)
9ef920e9 21237 {
75d7d298 21238 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21239 switch (val)
21240 {
75d7d298
NC
21241 case 0: decoded = "static"; break;
21242 case 1: decoded = "pic"; break;
21243 case 2: decoded = "PIC"; break;
21244 case 3: decoded = "pie"; break;
21245 case 4: decoded = "PIE"; break;
21246 default: break;
9ef920e9 21247 }
75d7d298
NC
21248 break;
21249 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21250 switch (val)
9ef920e9 21251 {
75d7d298
NC
21252 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21253 case 0: decoded = "off"; break;
21254 case 1: decoded = "on"; break;
21255 case 2: decoded = "all"; break;
21256 case 3: decoded = "strong"; break;
21257 case 4: decoded = "explicit"; break;
21258 default: break;
9ef920e9 21259 }
75d7d298
NC
21260 break;
21261 default:
21262 break;
9ef920e9
NC
21263 }
21264
75d7d298 21265 if (decoded != NULL)
3e6b6445
NC
21266 {
21267 print_symbol (-left, decoded);
21268 left = 0;
21269 }
21270 else if (val == 0)
21271 {
21272 printf ("0x0");
21273 left -= 3;
21274 }
9ef920e9 21275 else
75d7d298
NC
21276 {
21277 if (do_wide)
ddef72cd 21278 left -= printf ("0x%llx", val);
75d7d298 21279 else
ddef72cd 21280 left -= printf ("0x%-.*llx", left, val);
75d7d298 21281 }
9ef920e9
NC
21282 }
21283 break;
21284 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21285 left -= print_symbol (- left, name);
21286 break;
21287 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21288 left -= print_symbol (- left, "true");
21289 break;
21290 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21291 left -= print_symbol (- left, "false");
21292 break;
21293 }
21294
21295 if (do_wide && left > 0)
21296 printf ("%-*s", left, " ");
9abca702 21297
015dc7e1 21298 return true;
9ef920e9
NC
21299}
21300
2952f10c
SM
21301/* Print the contents of PNOTE as hex. */
21302
21303static void
21304print_note_contents_hex (Elf_Internal_Note *pnote)
21305{
21306 if (pnote->descsz)
21307 {
21308 unsigned long i;
21309
21310 printf (_(" description data: "));
21311 for (i = 0; i < pnote->descsz; i++)
21312 printf ("%02x ", pnote->descdata[i] & 0xff);
21313 if (!do_wide)
21314 printf ("\n");
21315 }
21316
21317 if (do_wide)
21318 printf ("\n");
21319}
21320
21321#if defined HAVE_MSGPACK
21322
21323static void
21324print_indents (int n)
21325{
21326 printf (" ");
21327
21328 for (int i = 0; i < n; i++)
21329 printf (" ");
21330}
21331
21332/* Print OBJ in human-readable form. */
21333
21334static void
21335dump_msgpack_obj (const msgpack_object *obj, int indent)
21336{
21337 switch (obj->type)
21338 {
21339 case MSGPACK_OBJECT_NIL:
21340 printf ("(nil)");
21341 break;
21342
21343 case MSGPACK_OBJECT_BOOLEAN:
21344 printf ("%s", obj->via.boolean ? "true" : "false");
21345 break;
21346
21347 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21348 printf ("%" PRIu64, obj->via.u64);
21349 break;
21350
21351 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21352 printf ("%" PRIi64, obj->via.i64);
21353 break;
21354
21355 case MSGPACK_OBJECT_FLOAT32:
21356 case MSGPACK_OBJECT_FLOAT64:
21357 printf ("%f", obj->via.f64);
21358 break;
21359
21360 case MSGPACK_OBJECT_STR:
21361 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21362 break;
21363
21364 case MSGPACK_OBJECT_ARRAY:
21365 {
21366 const msgpack_object_array *array = &obj->via.array;
21367
21368 printf ("[\n");
21369 ++indent;
21370
21371 for (uint32_t i = 0; i < array->size; ++i)
21372 {
21373 const msgpack_object *item = &array->ptr[i];
21374
21375 print_indents (indent);
21376 dump_msgpack_obj (item, indent);
21377 printf (",\n");
21378 }
21379
21380 --indent;
21381 print_indents (indent);
21382 printf ("]");
21383 break;
21384 }
21385 break;
21386
21387 case MSGPACK_OBJECT_MAP:
21388 {
21389 const msgpack_object_map *map = &obj->via.map;
21390
21391 printf ("{\n");
21392 ++indent;
21393
21394 for (uint32_t i = 0; i < map->size; ++i)
21395 {
21396 const msgpack_object_kv *kv = &map->ptr[i];
21397 const msgpack_object *key = &kv->key;
21398 const msgpack_object *val = &kv->val;
21399
21400 print_indents (indent);
21401 dump_msgpack_obj (key, indent);
21402 printf (": ");
21403 dump_msgpack_obj (val, indent);
21404
21405 printf (",\n");
21406 }
21407
21408 --indent;
21409 print_indents (indent);
21410 printf ("}");
21411
21412 break;
21413 }
21414
21415 case MSGPACK_OBJECT_BIN:
21416 printf ("(bin)");
21417 break;
21418
21419 case MSGPACK_OBJECT_EXT:
21420 printf ("(ext)");
21421 break;
21422 }
21423}
21424
21425static void
21426dump_msgpack (const msgpack_unpacked *msg)
21427{
21428 print_indents (0);
21429 dump_msgpack_obj (&msg->data, 0);
21430 printf ("\n");
21431}
21432
21433#endif /* defined HAVE_MSGPACK */
21434
21435static bool
21436print_amdgpu_note (Elf_Internal_Note *pnote)
21437{
21438#if defined HAVE_MSGPACK
21439 /* If msgpack is available, decode and dump the note's content. */
21440 bool ret;
21441 msgpack_unpacked msg;
21442 msgpack_unpack_return msgpack_ret;
21443
21444 assert (pnote->type == NT_AMDGPU_METADATA);
21445
21446 msgpack_unpacked_init (&msg);
21447 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21448 NULL);
21449
21450 switch (msgpack_ret)
21451 {
21452 case MSGPACK_UNPACK_SUCCESS:
21453 dump_msgpack (&msg);
21454 ret = true;
21455 break;
21456
21457 default:
21458 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21459 ret = false;
21460 break;
21461 }
21462
21463 msgpack_unpacked_destroy (&msg);
21464 return ret;
21465#else
21466 /* msgpack is not available, dump contents as hex. */
21467 print_note_contents_hex (pnote);
21468 return true;
21469#endif
21470}
21471
6d118b09
NC
21472/* Note that by the ELF standard, the name field is already null byte
21473 terminated, and namesz includes the terminating null byte.
21474 I.E. the value of namesz for the name "FSF" is 4.
21475
e3c8793a 21476 If the value of namesz is zero, there is no name present. */
9ef920e9 21477
015dc7e1 21478static bool
9ef920e9 21479process_note (Elf_Internal_Note * pnote,
dda8d76d 21480 Filedata * filedata)
779fe533 21481{
2cf0635d
NC
21482 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21483 const char * nt;
9437c45b
JT
21484
21485 if (pnote->namesz == 0)
1ec5cd37
NC
21486 /* If there is no note name, then use the default set of
21487 note type strings. */
dda8d76d 21488 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21489
24d127aa 21490 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21491 /* GNU-specific object file notes. */
21492 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21493
28cdbb18
SM
21494 else if (startswith (pnote->namedata, "AMDGPU"))
21495 /* AMDGPU-specific object file notes. */
21496 nt = get_amdgpu_elf_note_type (pnote->type);
21497
24d127aa 21498 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21499 /* FreeBSD-specific core file notes. */
dda8d76d 21500 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21501
24d127aa 21502 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21503 /* NetBSD-specific core file notes. */
dda8d76d 21504 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21505
24d127aa 21506 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21507 /* NetBSD-specific core file notes. */
21508 return process_netbsd_elf_note (pnote);
21509
24d127aa 21510 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21511 /* NetBSD-specific core file notes. */
21512 return process_netbsd_elf_note (pnote);
21513
98ca73af
FC
21514 else if (startswith (pnote->namedata, "OpenBSD"))
21515 /* OpenBSD-specific core file notes. */
21516 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21517
e9b095a5 21518 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21519 {
21520 /* SPU-specific core file notes. */
21521 nt = pnote->namedata + 4;
21522 name = "SPU";
21523 }
21524
24d127aa 21525 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21526 /* VMS/ia64-specific file notes. */
21527 nt = get_ia64_vms_note_type (pnote->type);
21528
24d127aa 21529 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21530 nt = get_stapsdt_note_type (pnote->type);
21531
9437c45b 21532 else
1ec5cd37
NC
21533 /* Don't recognize this note name; just use the default set of
21534 note type strings. */
dda8d76d 21535 nt = get_note_type (filedata, pnote->type);
9437c45b 21536
1449284b 21537 printf (" ");
9ef920e9 21538
24d127aa 21539 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21540 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21541 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21542 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21543 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21544 print_gnu_build_attribute_name (pnote);
21545 else
21546 print_symbol (-20, name);
21547
21548 if (do_wide)
21549 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21550 else
21551 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21552
24d127aa 21553 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21554 return print_ia64_vms_note (pnote);
24d127aa 21555 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21556 return print_gnu_note (filedata, pnote);
24d127aa 21557 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21558 return print_stapsdt_note (pnote);
24d127aa 21559 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21560 return print_core_note (pnote);
e5382207
LB
21561 else if (startswith (pnote->namedata, "FDO"))
21562 return print_fdo_note (pnote);
24d127aa 21563 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21564 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21565 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21566 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21567 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21568 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21569 else if (startswith (pnote->namedata, "AMDGPU")
21570 && pnote->type == NT_AMDGPU_METADATA)
21571 return print_amdgpu_note (pnote);
779fe533 21572
2952f10c 21573 print_note_contents_hex (pnote);
015dc7e1 21574 return true;
1449284b 21575}
6d118b09 21576
015dc7e1 21577static bool
dda8d76d
NC
21578process_notes_at (Filedata * filedata,
21579 Elf_Internal_Shdr * section,
625d49fc
AM
21580 uint64_t offset,
21581 uint64_t length,
21582 uint64_t align)
779fe533 21583{
015dc7e1
AM
21584 Elf_External_Note *pnotes;
21585 Elf_External_Note *external;
21586 char *end;
21587 bool res = true;
103f02d3 21588
779fe533 21589 if (length <= 0)
015dc7e1 21590 return false;
103f02d3 21591
1449284b
NC
21592 if (section)
21593 {
dda8d76d 21594 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21595 if (pnotes)
32ec8896 21596 {
dda8d76d 21597 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21598 {
21599 free (pnotes);
015dc7e1 21600 return false;
f761cb13 21601 }
32ec8896 21602 }
1449284b
NC
21603 }
21604 else
82ed9683 21605 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21606 _("notes"));
4dff97b2 21607
dd24e3da 21608 if (pnotes == NULL)
015dc7e1 21609 return false;
779fe533 21610
103f02d3 21611 external = pnotes;
103f02d3 21612
ca0e11aa
NC
21613 if (filedata->is_separate)
21614 printf (_("In linked file '%s': "), filedata->file_name);
21615 else
21616 printf ("\n");
1449284b 21617 if (section)
ca0e11aa 21618 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21619 else
ca0e11aa 21620 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21621 (unsigned long) offset, (unsigned long) length);
21622
82ed9683
L
21623 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21624 specifies that notes should be aligned to 4 bytes in 32-bit
21625 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21626 we also support 4 byte alignment in 64-bit objects. If section
21627 alignment is less than 4, we treate alignment as 4 bytes. */
21628 if (align < 4)
21629 align = 4;
21630 else if (align != 4 && align != 8)
21631 {
21632 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21633 (long) align);
a788aedd 21634 free (pnotes);
015dc7e1 21635 return false;
82ed9683
L
21636 }
21637
dbe15e4e 21638 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21639
c8071705
NC
21640 end = (char *) pnotes + length;
21641 while ((char *) external < end)
779fe533 21642 {
b34976b6 21643 Elf_Internal_Note inote;
15b42fb0 21644 size_t min_notesz;
4dff97b2 21645 char * next;
2cf0635d 21646 char * temp = NULL;
c8071705 21647 size_t data_remaining = end - (char *) external;
6d118b09 21648
dda8d76d 21649 if (!is_ia64_vms (filedata))
15b42fb0 21650 {
9dd3a467
NC
21651 /* PR binutils/15191
21652 Make sure that there is enough data to read. */
15b42fb0
AM
21653 min_notesz = offsetof (Elf_External_Note, name);
21654 if (data_remaining < min_notesz)
9dd3a467 21655 {
d3a49aa8
AM
21656 warn (ngettext ("Corrupt note: only %ld byte remains, "
21657 "not enough for a full note\n",
21658 "Corrupt note: only %ld bytes remain, "
21659 "not enough for a full note\n",
21660 data_remaining),
21661 (long) data_remaining);
9dd3a467
NC
21662 break;
21663 }
5396a86e
AM
21664 data_remaining -= min_notesz;
21665
15b42fb0
AM
21666 inote.type = BYTE_GET (external->type);
21667 inote.namesz = BYTE_GET (external->namesz);
21668 inote.namedata = external->name;
21669 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21670 inote.descdata = ((char *) external
4dff97b2 21671 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21672 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21673 next = ((char *) external
4dff97b2 21674 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21675 }
00e98fc7 21676 else
15b42fb0
AM
21677 {
21678 Elf64_External_VMS_Note *vms_external;
00e98fc7 21679
9dd3a467
NC
21680 /* PR binutils/15191
21681 Make sure that there is enough data to read. */
15b42fb0
AM
21682 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21683 if (data_remaining < min_notesz)
9dd3a467 21684 {
d3a49aa8
AM
21685 warn (ngettext ("Corrupt note: only %ld byte remains, "
21686 "not enough for a full note\n",
21687 "Corrupt note: only %ld bytes remain, "
21688 "not enough for a full note\n",
21689 data_remaining),
21690 (long) data_remaining);
9dd3a467
NC
21691 break;
21692 }
5396a86e 21693 data_remaining -= min_notesz;
3e55a963 21694
15b42fb0
AM
21695 vms_external = (Elf64_External_VMS_Note *) external;
21696 inote.type = BYTE_GET (vms_external->type);
21697 inote.namesz = BYTE_GET (vms_external->namesz);
21698 inote.namedata = vms_external->name;
21699 inote.descsz = BYTE_GET (vms_external->descsz);
21700 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21701 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21702 next = inote.descdata + align_power (inote.descsz, 3);
21703 }
21704
5396a86e
AM
21705 /* PR 17531: file: 3443835e. */
21706 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21707 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21708 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21709 || (size_t) (next - inote.descdata) < inote.descsz
21710 || ((size_t) (next - inote.descdata)
21711 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21712 {
15b42fb0 21713 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21714 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21715 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21716 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21717 break;
21718 }
21719
15b42fb0 21720 external = (Elf_External_Note *) next;
dd24e3da 21721
6d118b09
NC
21722 /* Verify that name is null terminated. It appears that at least
21723 one version of Linux (RedHat 6.0) generates corefiles that don't
21724 comply with the ELF spec by failing to include the null byte in
21725 namesz. */
18344509 21726 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21727 {
5396a86e 21728 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21729 {
5396a86e
AM
21730 temp = (char *) malloc (inote.namesz + 1);
21731 if (temp == NULL)
21732 {
21733 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21734 res = false;
5396a86e
AM
21735 break;
21736 }
76da6bbe 21737
5396a86e
AM
21738 memcpy (temp, inote.namedata, inote.namesz);
21739 inote.namedata = temp;
21740 }
21741 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21742 }
21743
dda8d76d 21744 if (! process_note (& inote, filedata))
015dc7e1 21745 res = false;
103f02d3 21746
9db70fc3
AM
21747 free (temp);
21748 temp = NULL;
779fe533
NC
21749 }
21750
21751 free (pnotes);
103f02d3 21752
779fe533
NC
21753 return res;
21754}
21755
015dc7e1 21756static bool
dda8d76d 21757process_corefile_note_segments (Filedata * filedata)
779fe533 21758{
015dc7e1 21759 Elf_Internal_Phdr *segment;
b34976b6 21760 unsigned int i;
015dc7e1 21761 bool res = true;
103f02d3 21762
dda8d76d 21763 if (! get_program_headers (filedata))
015dc7e1 21764 return true;
103f02d3 21765
dda8d76d
NC
21766 for (i = 0, segment = filedata->program_headers;
21767 i < filedata->file_header.e_phnum;
b34976b6 21768 i++, segment++)
779fe533
NC
21769 {
21770 if (segment->p_type == PT_NOTE)
625d49fc
AM
21771 if (! process_notes_at (filedata, NULL, segment->p_offset,
21772 segment->p_filesz, segment->p_align))
015dc7e1 21773 res = false;
779fe533 21774 }
103f02d3 21775
779fe533
NC
21776 return res;
21777}
21778
015dc7e1 21779static bool
625d49fc 21780process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21781{
21782 Elf_External_Note * pnotes;
21783 Elf_External_Note * external;
c8071705 21784 char * end;
015dc7e1 21785 bool res = true;
685080f2
NC
21786
21787 if (length <= 0)
015dc7e1 21788 return false;
685080f2 21789
dda8d76d 21790 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21791 _("v850 notes"));
21792 if (pnotes == NULL)
015dc7e1 21793 return false;
685080f2
NC
21794
21795 external = pnotes;
c8071705 21796 end = (char*) pnotes + length;
685080f2
NC
21797
21798 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21799 (unsigned long) offset, (unsigned long) length);
21800
c8071705 21801 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21802 {
21803 Elf_External_Note * next;
21804 Elf_Internal_Note inote;
21805
21806 inote.type = BYTE_GET (external->type);
21807 inote.namesz = BYTE_GET (external->namesz);
21808 inote.namedata = external->name;
21809 inote.descsz = BYTE_GET (external->descsz);
21810 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21811 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21812
c8071705
NC
21813 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21814 {
21815 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21816 inote.descdata = inote.namedata;
21817 inote.namesz = 0;
21818 }
21819
685080f2
NC
21820 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21821
c8071705 21822 if ( ((char *) next > end)
685080f2
NC
21823 || ((char *) next < (char *) pnotes))
21824 {
21825 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21826 (unsigned long) ((char *) external - (char *) pnotes));
21827 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21828 inote.type, inote.namesz, inote.descsz);
21829 break;
21830 }
21831
21832 external = next;
21833
21834 /* Prevent out-of-bounds indexing. */
c8071705 21835 if ( inote.namedata + inote.namesz > end
685080f2
NC
21836 || inote.namedata + inote.namesz < inote.namedata)
21837 {
21838 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21839 (unsigned long) ((char *) external - (char *) pnotes));
21840 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21841 inote.type, inote.namesz, inote.descsz);
21842 break;
21843 }
21844
21845 printf (" %s: ", get_v850_elf_note_type (inote.type));
21846
21847 if (! print_v850_note (& inote))
21848 {
015dc7e1 21849 res = false;
685080f2
NC
21850 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21851 inote.namesz, inote.descsz);
21852 }
21853 }
21854
21855 free (pnotes);
21856
21857 return res;
21858}
21859
015dc7e1 21860static bool
dda8d76d 21861process_note_sections (Filedata * filedata)
1ec5cd37 21862{
015dc7e1 21863 Elf_Internal_Shdr *section;
1ec5cd37 21864 unsigned long i;
32ec8896 21865 unsigned int n = 0;
015dc7e1 21866 bool res = true;
1ec5cd37 21867
dda8d76d
NC
21868 for (i = 0, section = filedata->section_headers;
21869 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21870 i++, section++)
685080f2
NC
21871 {
21872 if (section->sh_type == SHT_NOTE)
21873 {
625d49fc
AM
21874 if (! process_notes_at (filedata, section, section->sh_offset,
21875 section->sh_size, section->sh_addralign))
015dc7e1 21876 res = false;
685080f2
NC
21877 n++;
21878 }
21879
dda8d76d
NC
21880 if (( filedata->file_header.e_machine == EM_V800
21881 || filedata->file_header.e_machine == EM_V850
21882 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21883 && section->sh_type == SHT_RENESAS_INFO)
21884 {
625d49fc
AM
21885 if (! process_v850_notes (filedata, section->sh_offset,
21886 section->sh_size))
015dc7e1 21887 res = false;
685080f2
NC
21888 n++;
21889 }
21890 }
df565f32
NC
21891
21892 if (n == 0)
21893 /* Try processing NOTE segments instead. */
dda8d76d 21894 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21895
21896 return res;
21897}
21898
015dc7e1 21899static bool
dda8d76d 21900process_notes (Filedata * filedata)
779fe533
NC
21901{
21902 /* If we have not been asked to display the notes then do nothing. */
21903 if (! do_notes)
015dc7e1 21904 return true;
103f02d3 21905
dda8d76d
NC
21906 if (filedata->file_header.e_type != ET_CORE)
21907 return process_note_sections (filedata);
103f02d3 21908
779fe533 21909 /* No program headers means no NOTE segment. */
dda8d76d
NC
21910 if (filedata->file_header.e_phnum > 0)
21911 return process_corefile_note_segments (filedata);
779fe533 21912
ca0e11aa
NC
21913 if (filedata->is_separate)
21914 printf (_("No notes found in linked file '%s'.\n"),
21915 filedata->file_name);
21916 else
21917 printf (_("No notes found file.\n"));
21918
015dc7e1 21919 return true;
779fe533
NC
21920}
21921
60abdbed
NC
21922static unsigned char *
21923display_public_gnu_attributes (unsigned char * start,
21924 const unsigned char * const end)
21925{
21926 printf (_(" Unknown GNU attribute: %s\n"), start);
21927
21928 start += strnlen ((char *) start, end - start);
21929 display_raw_attribute (start, end);
21930
21931 return (unsigned char *) end;
21932}
21933
21934static unsigned char *
21935display_generic_attribute (unsigned char * start,
21936 unsigned int tag,
21937 const unsigned char * const end)
21938{
21939 if (tag == 0)
21940 return (unsigned char *) end;
21941
21942 return display_tag_value (tag, start, end);
21943}
21944
015dc7e1 21945static bool
dda8d76d 21946process_arch_specific (Filedata * filedata)
252b5132 21947{
a952a375 21948 if (! do_arch)
015dc7e1 21949 return true;
a952a375 21950
dda8d76d 21951 switch (filedata->file_header.e_machine)
252b5132 21952 {
53a346d8
CZ
21953 case EM_ARC:
21954 case EM_ARC_COMPACT:
21955 case EM_ARC_COMPACT2:
dda8d76d 21956 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21957 display_arc_attribute,
21958 display_generic_attribute);
11c1ff18 21959 case EM_ARM:
dda8d76d 21960 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21961 display_arm_attribute,
21962 display_generic_attribute);
21963
252b5132 21964 case EM_MIPS:
4fe85591 21965 case EM_MIPS_RS3_LE:
dda8d76d 21966 return process_mips_specific (filedata);
60abdbed
NC
21967
21968 case EM_MSP430:
dda8d76d 21969 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21970 display_msp430_attribute,
c0ea7c52 21971 display_msp430_gnu_attribute);
60abdbed 21972
2dc8dd17
JW
21973 case EM_RISCV:
21974 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21975 display_riscv_attribute,
21976 display_generic_attribute);
21977
35c08157 21978 case EM_NDS32:
dda8d76d 21979 return process_nds32_specific (filedata);
60abdbed 21980
85f7484a
PB
21981 case EM_68K:
21982 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21983 display_m68k_gnu_attribute);
21984
34c8bcba 21985 case EM_PPC:
b82317dd 21986 case EM_PPC64:
dda8d76d 21987 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21988 display_power_gnu_attribute);
21989
643f7afb
AK
21990 case EM_S390:
21991 case EM_S390_OLD:
dda8d76d 21992 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21993 display_s390_gnu_attribute);
21994
9e8c70f9
DM
21995 case EM_SPARC:
21996 case EM_SPARC32PLUS:
21997 case EM_SPARCV9:
dda8d76d 21998 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21999 display_sparc_gnu_attribute);
22000
59e6276b 22001 case EM_TI_C6000:
dda8d76d 22002 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22003 display_tic6x_attribute,
22004 display_generic_attribute);
22005
0861f561
CQ
22006 case EM_CSKY:
22007 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22008 display_csky_attribute, NULL);
22009
252b5132 22010 default:
dda8d76d 22011 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22012 display_public_gnu_attributes,
22013 display_generic_attribute);
252b5132 22014 }
252b5132
RH
22015}
22016
015dc7e1 22017static bool
dda8d76d 22018get_file_header (Filedata * filedata)
252b5132 22019{
9ea033b2 22020 /* Read in the identity array. */
dda8d76d 22021 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22022 return false;
252b5132 22023
9ea033b2 22024 /* Determine how to read the rest of the header. */
dda8d76d 22025 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22026 {
1a0670f3
AM
22027 default:
22028 case ELFDATANONE:
adab8cdc
AO
22029 case ELFDATA2LSB:
22030 byte_get = byte_get_little_endian;
22031 byte_put = byte_put_little_endian;
22032 break;
22033 case ELFDATA2MSB:
22034 byte_get = byte_get_big_endian;
22035 byte_put = byte_put_big_endian;
22036 break;
9ea033b2
NC
22037 }
22038
22039 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22040 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22041
22042 /* Read in the rest of the header. */
22043 if (is_32bit_elf)
22044 {
22045 Elf32_External_Ehdr ehdr32;
252b5132 22046
dda8d76d 22047 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22048 return false;
103f02d3 22049
dda8d76d
NC
22050 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22051 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22052 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22053 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22054 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22055 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22056 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22057 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22058 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22059 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22060 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22061 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22062 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22063 }
252b5132 22064 else
9ea033b2
NC
22065 {
22066 Elf64_External_Ehdr ehdr64;
a952a375 22067
dda8d76d 22068 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22069 return false;
103f02d3 22070
dda8d76d
NC
22071 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22072 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22073 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22074 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22075 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22076 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22077 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22078 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22079 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22080 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22081 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22082 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22083 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22084 }
252b5132 22085
015dc7e1 22086 return true;
252b5132
RH
22087}
22088
13acb58d
AM
22089static void
22090free_filedata (Filedata *filedata)
22091{
22092 free (filedata->program_interpreter);
13acb58d 22093 free (filedata->program_headers);
13acb58d 22094 free (filedata->section_headers);
13acb58d 22095 free (filedata->string_table);
13acb58d 22096 free (filedata->dump.dump_sects);
13acb58d 22097 free (filedata->dynamic_strings);
13acb58d 22098 free (filedata->dynamic_symbols);
13acb58d 22099 free (filedata->dynamic_syminfo);
13acb58d 22100 free (filedata->dynamic_section);
13acb58d
AM
22101
22102 while (filedata->symtab_shndx_list != NULL)
22103 {
22104 elf_section_list *next = filedata->symtab_shndx_list->next;
22105 free (filedata->symtab_shndx_list);
22106 filedata->symtab_shndx_list = next;
22107 }
22108
22109 free (filedata->section_headers_groups);
13acb58d
AM
22110
22111 if (filedata->section_groups)
22112 {
22113 size_t i;
22114 struct group_list * g;
22115 struct group_list * next;
22116
22117 for (i = 0; i < filedata->group_count; i++)
22118 {
22119 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22120 {
22121 next = g->next;
22122 free (g);
22123 }
22124 }
22125
22126 free (filedata->section_groups);
13acb58d 22127 }
066f8fbe
AM
22128 memset (&filedata->section_headers, 0,
22129 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22130}
22131
dda8d76d
NC
22132static void
22133close_file (Filedata * filedata)
22134{
22135 if (filedata)
22136 {
22137 if (filedata->handle)
22138 fclose (filedata->handle);
22139 free (filedata);
22140 }
22141}
22142
22143void
22144close_debug_file (void * data)
22145{
13acb58d 22146 free_filedata ((Filedata *) data);
dda8d76d
NC
22147 close_file ((Filedata *) data);
22148}
22149
22150static Filedata *
015dc7e1 22151open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22152{
22153 struct stat statbuf;
22154 Filedata * filedata = NULL;
22155
22156 if (stat (pathname, & statbuf) < 0
22157 || ! S_ISREG (statbuf.st_mode))
22158 goto fail;
22159
22160 filedata = calloc (1, sizeof * filedata);
22161 if (filedata == NULL)
22162 goto fail;
22163
22164 filedata->handle = fopen (pathname, "rb");
22165 if (filedata->handle == NULL)
22166 goto fail;
22167
be7d229a 22168 filedata->file_size = statbuf.st_size;
dda8d76d 22169 filedata->file_name = pathname;
ca0e11aa 22170 filedata->is_separate = is_separate;
dda8d76d
NC
22171
22172 if (! get_file_header (filedata))
22173 goto fail;
22174
4de91c10
AM
22175 if (!get_section_headers (filedata, false))
22176 goto fail;
dda8d76d
NC
22177
22178 return filedata;
22179
22180 fail:
22181 if (filedata)
22182 {
22183 if (filedata->handle)
22184 fclose (filedata->handle);
22185 free (filedata);
22186 }
22187 return NULL;
22188}
22189
22190void *
22191open_debug_file (const char * pathname)
22192{
015dc7e1 22193 return open_file (pathname, true);
dda8d76d
NC
22194}
22195
835f2fae
NC
22196static void
22197initialise_dump_sects (Filedata * filedata)
22198{
22199 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22200 Note we do this even if cmdline_dump_sects is empty because we
22201 must make sure that the dump_sets array is zeroed out before each
22202 object file is processed. */
22203 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22204 memset (filedata->dump.dump_sects, 0,
22205 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22206
22207 if (cmdline.num_dump_sects > 0)
22208 {
22209 if (filedata->dump.num_dump_sects == 0)
22210 /* A sneaky way of allocating the dump_sects array. */
22211 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22212
22213 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22214 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22215 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22216 }
22217}
22218
94585d6d
NC
22219static bool
22220might_need_separate_debug_info (Filedata * filedata)
22221{
22222 /* Debuginfo files do not need further separate file loading. */
22223 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22224 return false;
22225
22226 /* Since do_follow_links might be enabled by default, only treat it as an
22227 indication that separate files should be loaded if setting it was a
22228 deliberate user action. */
22229 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22230 return true;
22231
22232 if (process_links || do_syms || do_unwind
22233 || dump_any_debugging || do_dump || do_debugging)
22234 return true;
22235
22236 return false;
22237}
22238
fb52b2f4
NC
22239/* Process one ELF object file according to the command line options.
22240 This file may actually be stored in an archive. The file is
32ec8896
NC
22241 positioned at the start of the ELF object. Returns TRUE if no
22242 problems were encountered, FALSE otherwise. */
fb52b2f4 22243
015dc7e1 22244static bool
dda8d76d 22245process_object (Filedata * filedata)
252b5132 22246{
015dc7e1 22247 bool have_separate_files;
252b5132 22248 unsigned int i;
015dc7e1 22249 bool res;
252b5132 22250
dda8d76d 22251 if (! get_file_header (filedata))
252b5132 22252 {
dda8d76d 22253 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22254 return false;
252b5132
RH
22255 }
22256
22257 /* Initialise per file variables. */
978c4450
AM
22258 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22259 filedata->version_info[i] = 0;
252b5132 22260
978c4450
AM
22261 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22262 filedata->dynamic_info[i] = 0;
22263 filedata->dynamic_info_DT_GNU_HASH = 0;
22264 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22265
22266 /* Process the file. */
22267 if (show_name)
dda8d76d 22268 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22269
835f2fae 22270 initialise_dump_sects (filedata);
d70c5fc7 22271
4de91c10
AM
22272 /* There may be some extensions in the first section header. Don't
22273 bomb if we can't read it. */
22274 get_section_headers (filedata, true);
22275
dda8d76d 22276 if (! process_file_header (filedata))
4de91c10
AM
22277 {
22278 res = false;
22279 goto out;
22280 }
252b5132 22281
e331b18d
AM
22282 /* Throw away the single section header read above, so that we
22283 re-read the entire set. */
22284 free (filedata->section_headers);
22285 filedata->section_headers = NULL;
22286
dda8d76d 22287 if (! process_section_headers (filedata))
2f62977e 22288 {
32ec8896 22289 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22290 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22291
2f62977e 22292 if (! do_using_dynamic)
015dc7e1 22293 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22294 }
252b5132 22295
dda8d76d 22296 if (! process_section_groups (filedata))
32ec8896 22297 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22298 do_unwind = false;
d1f5c6e3 22299
93df3340
AM
22300 process_program_headers (filedata);
22301
22302 res = process_dynamic_section (filedata);
252b5132 22303
dda8d76d 22304 if (! process_relocs (filedata))
015dc7e1 22305 res = false;
252b5132 22306
dda8d76d 22307 if (! process_unwind (filedata))
015dc7e1 22308 res = false;
4d6ed7c8 22309
dda8d76d 22310 if (! process_symbol_table (filedata))
015dc7e1 22311 res = false;
252b5132 22312
0f03783c 22313 if (! process_lto_symbol_tables (filedata))
015dc7e1 22314 res = false;
b9e920ec 22315
dda8d76d 22316 if (! process_syminfo (filedata))
015dc7e1 22317 res = false;
252b5132 22318
dda8d76d 22319 if (! process_version_sections (filedata))
015dc7e1 22320 res = false;
252b5132 22321
94585d6d 22322 if (might_need_separate_debug_info (filedata))
24841daa 22323 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22324 else
015dc7e1 22325 have_separate_files = false;
dda8d76d
NC
22326
22327 if (! process_section_contents (filedata))
015dc7e1 22328 res = false;
f5842774 22329
24841daa 22330 if (have_separate_files)
dda8d76d 22331 {
24841daa
NC
22332 separate_info * d;
22333
22334 for (d = first_separate_info; d != NULL; d = d->next)
22335 {
835f2fae
NC
22336 initialise_dump_sects (d->handle);
22337
ca0e11aa 22338 if (process_links && ! process_file_header (d->handle))
015dc7e1 22339 res = false;
ca0e11aa 22340 else if (! process_section_headers (d->handle))
015dc7e1 22341 res = false;
d6bfbc39 22342 else if (! process_section_contents (d->handle))
015dc7e1 22343 res = false;
ca0e11aa
NC
22344 else if (process_links)
22345 {
ca0e11aa 22346 if (! process_section_groups (d->handle))
015dc7e1 22347 res = false;
93df3340 22348 process_program_headers (d->handle);
ca0e11aa 22349 if (! process_dynamic_section (d->handle))
015dc7e1 22350 res = false;
ca0e11aa 22351 if (! process_relocs (d->handle))
015dc7e1 22352 res = false;
ca0e11aa 22353 if (! process_unwind (d->handle))
015dc7e1 22354 res = false;
ca0e11aa 22355 if (! process_symbol_table (d->handle))
015dc7e1 22356 res = false;
ca0e11aa 22357 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22358 res = false;
ca0e11aa 22359 if (! process_syminfo (d->handle))
015dc7e1 22360 res = false;
ca0e11aa 22361 if (! process_version_sections (d->handle))
015dc7e1 22362 res = false;
ca0e11aa 22363 if (! process_notes (d->handle))
015dc7e1 22364 res = false;
ca0e11aa 22365 }
24841daa
NC
22366 }
22367
22368 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22369 }
22370
22371 if (! process_notes (filedata))
015dc7e1 22372 res = false;
103f02d3 22373
dda8d76d 22374 if (! process_gnu_liblist (filedata))
015dc7e1 22375 res = false;
047b2264 22376
dda8d76d 22377 if (! process_arch_specific (filedata))
015dc7e1 22378 res = false;
252b5132 22379
4de91c10 22380 out:
13acb58d 22381 free_filedata (filedata);
e4b17d5c 22382
19e6b90e 22383 free_debug_memory ();
18bd398b 22384
32ec8896 22385 return res;
252b5132
RH
22386}
22387
2cf0635d 22388/* Process an ELF archive.
32ec8896
NC
22389 On entry the file is positioned just after the ARMAG string.
22390 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22391
015dc7e1
AM
22392static bool
22393process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22394{
22395 struct archive_info arch;
22396 struct archive_info nested_arch;
22397 size_t got;
015dc7e1 22398 bool ret = true;
2cf0635d 22399
015dc7e1 22400 show_name = true;
2cf0635d
NC
22401
22402 /* The ARCH structure is used to hold information about this archive. */
22403 arch.file_name = NULL;
22404 arch.file = NULL;
22405 arch.index_array = NULL;
22406 arch.sym_table = NULL;
22407 arch.longnames = NULL;
22408
22409 /* The NESTED_ARCH structure is used as a single-item cache of information
22410 about a nested archive (when members of a thin archive reside within
22411 another regular archive file). */
22412 nested_arch.file_name = NULL;
22413 nested_arch.file = NULL;
22414 nested_arch.index_array = NULL;
22415 nested_arch.sym_table = NULL;
22416 nested_arch.longnames = NULL;
22417
dda8d76d 22418 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22419 filedata->file_size, is_thin_archive,
22420 do_archive_index) != 0)
2cf0635d 22421 {
015dc7e1 22422 ret = false;
2cf0635d 22423 goto out;
4145f1d5 22424 }
fb52b2f4 22425
4145f1d5
NC
22426 if (do_archive_index)
22427 {
2cf0635d 22428 if (arch.sym_table == NULL)
1cb7d8b1
AM
22429 error (_("%s: unable to dump the index as none was found\n"),
22430 filedata->file_name);
4145f1d5
NC
22431 else
22432 {
591f7597 22433 unsigned long i, l;
4145f1d5
NC
22434 unsigned long current_pos;
22435
1cb7d8b1
AM
22436 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22437 "in the symbol table)\n"),
22438 filedata->file_name, (unsigned long) arch.index_num,
22439 arch.sym_size);
dda8d76d
NC
22440
22441 current_pos = ftell (filedata->handle);
4145f1d5 22442
2cf0635d 22443 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22444 {
1cb7d8b1
AM
22445 if (i == 0
22446 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22447 {
22448 char * member_name
22449 = get_archive_member_name_at (&arch, arch.index_array[i],
22450 &nested_arch);
2cf0635d 22451
1cb7d8b1
AM
22452 if (member_name != NULL)
22453 {
22454 char * qualified_name
22455 = make_qualified_name (&arch, &nested_arch,
22456 member_name);
2cf0635d 22457
1cb7d8b1
AM
22458 if (qualified_name != NULL)
22459 {
22460 printf (_("Contents of binary %s at offset "),
22461 qualified_name);
c2a7d3f5
NC
22462 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22463 putchar ('\n');
1cb7d8b1
AM
22464 free (qualified_name);
22465 }
fd486f32 22466 free (member_name);
4145f1d5
NC
22467 }
22468 }
2cf0635d
NC
22469
22470 if (l >= arch.sym_size)
4145f1d5 22471 {
1cb7d8b1
AM
22472 error (_("%s: end of the symbol table reached "
22473 "before the end of the index\n"),
dda8d76d 22474 filedata->file_name);
015dc7e1 22475 ret = false;
cb8f3167 22476 break;
4145f1d5 22477 }
591f7597 22478 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22479 printf ("\t%.*s\n",
22480 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22481 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22482 }
22483
67ce483b 22484 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22485 l = (l + 7) & ~ 7;
22486 else
22487 l += l & 1;
22488
2cf0635d 22489 if (l < arch.sym_size)
32ec8896 22490 {
d3a49aa8
AM
22491 error (ngettext ("%s: %ld byte remains in the symbol table, "
22492 "but without corresponding entries in "
22493 "the index table\n",
22494 "%s: %ld bytes remain in the symbol table, "
22495 "but without corresponding entries in "
22496 "the index table\n",
22497 arch.sym_size - l),
dda8d76d 22498 filedata->file_name, arch.sym_size - l);
015dc7e1 22499 ret = false;
32ec8896 22500 }
4145f1d5 22501
dda8d76d 22502 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22503 {
1cb7d8b1
AM
22504 error (_("%s: failed to seek back to start of object files "
22505 "in the archive\n"),
dda8d76d 22506 filedata->file_name);
015dc7e1 22507 ret = false;
2cf0635d 22508 goto out;
4145f1d5 22509 }
fb52b2f4 22510 }
4145f1d5
NC
22511
22512 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22513 && !do_segments && !do_header && !do_dump && !do_version
22514 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22515 && !do_section_groups && !do_dyn_syms)
2cf0635d 22516 {
015dc7e1 22517 ret = true; /* Archive index only. */
2cf0635d
NC
22518 goto out;
22519 }
fb52b2f4
NC
22520 }
22521
fb52b2f4
NC
22522 while (1)
22523 {
2cf0635d
NC
22524 char * name;
22525 size_t namelen;
22526 char * qualified_name;
22527
22528 /* Read the next archive header. */
dda8d76d 22529 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22530 {
22531 error (_("%s: failed to seek to next archive header\n"),
22532 arch.file_name);
015dc7e1 22533 ret = false;
1cb7d8b1
AM
22534 break;
22535 }
dda8d76d 22536 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22537 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22538 {
22539 if (got == 0)
2cf0635d 22540 break;
28e817cc
NC
22541 /* PR 24049 - we cannot use filedata->file_name as this will
22542 have already been freed. */
22543 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22544
015dc7e1 22545 ret = false;
1cb7d8b1
AM
22546 break;
22547 }
2cf0635d 22548 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22549 {
22550 error (_("%s: did not find a valid archive header\n"),
22551 arch.file_name);
015dc7e1 22552 ret = false;
1cb7d8b1
AM
22553 break;
22554 }
2cf0635d
NC
22555
22556 arch.next_arhdr_offset += sizeof arch.arhdr;
22557
978c4450 22558 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22559
22560 name = get_archive_member_name (&arch, &nested_arch);
22561 if (name == NULL)
fb52b2f4 22562 {
28e817cc 22563 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22564 ret = false;
d989285c 22565 break;
fb52b2f4 22566 }
2cf0635d 22567 namelen = strlen (name);
fb52b2f4 22568
2cf0635d
NC
22569 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22570 if (qualified_name == NULL)
fb52b2f4 22571 {
28e817cc 22572 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22573 free (name);
015dc7e1 22574 ret = false;
d989285c 22575 break;
fb52b2f4
NC
22576 }
22577
2cf0635d 22578 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22579 {
22580 /* This is a proxy for an external member of a thin archive. */
22581 Filedata * member_filedata;
22582 char * member_file_name = adjust_relative_path
dda8d76d 22583 (filedata->file_name, name, namelen);
32ec8896 22584
fd486f32 22585 free (name);
1cb7d8b1
AM
22586 if (member_file_name == NULL)
22587 {
fd486f32 22588 free (qualified_name);
015dc7e1 22589 ret = false;
1cb7d8b1
AM
22590 break;
22591 }
2cf0635d 22592
015dc7e1 22593 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22594 if (member_filedata == NULL)
22595 {
22596 error (_("Input file '%s' is not readable.\n"), member_file_name);
22597 free (member_file_name);
fd486f32 22598 free (qualified_name);
015dc7e1 22599 ret = false;
1cb7d8b1
AM
22600 break;
22601 }
2cf0635d 22602
978c4450 22603 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22604 member_filedata->file_name = qualified_name;
2cf0635d 22605
75a2da57
AH
22606 /* The call to process_object() expects the file to be at the beginning. */
22607 rewind (member_filedata->handle);
22608
1cb7d8b1 22609 if (! process_object (member_filedata))
015dc7e1 22610 ret = false;
2cf0635d 22611
1cb7d8b1
AM
22612 close_file (member_filedata);
22613 free (member_file_name);
1cb7d8b1 22614 }
2cf0635d 22615 else if (is_thin_archive)
1cb7d8b1
AM
22616 {
22617 Filedata thin_filedata;
eb02c04d 22618
1cb7d8b1 22619 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22620
a043396b
NC
22621 /* PR 15140: Allow for corrupt thin archives. */
22622 if (nested_arch.file == NULL)
22623 {
22624 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22625 qualified_name, name);
fd486f32
AM
22626 free (qualified_name);
22627 free (name);
015dc7e1 22628 ret = false;
a043396b
NC
22629 break;
22630 }
fd486f32 22631 free (name);
a043396b 22632
1cb7d8b1 22633 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22634 filedata->archive_file_offset
22635 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22636
1cb7d8b1
AM
22637 /* The nested archive file will have been opened and setup by
22638 get_archive_member_name. */
978c4450
AM
22639 if (fseek (nested_arch.file, filedata->archive_file_offset,
22640 SEEK_SET) != 0)
1cb7d8b1
AM
22641 {
22642 error (_("%s: failed to seek to archive member.\n"),
22643 nested_arch.file_name);
fd486f32 22644 free (qualified_name);
015dc7e1 22645 ret = false;
1cb7d8b1
AM
22646 break;
22647 }
2cf0635d 22648
dda8d76d
NC
22649 thin_filedata.handle = nested_arch.file;
22650 thin_filedata.file_name = qualified_name;
9abca702 22651
1cb7d8b1 22652 if (! process_object (& thin_filedata))
015dc7e1 22653 ret = false;
1cb7d8b1 22654 }
2cf0635d 22655 else
1cb7d8b1 22656 {
fd486f32 22657 free (name);
978c4450 22658 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22659 filedata->file_name = qualified_name;
1cb7d8b1 22660 if (! process_object (filedata))
015dc7e1 22661 ret = false;
237877b8 22662 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22663 /* Stop looping with "negative" archive_file_size. */
978c4450 22664 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22665 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22666 }
fb52b2f4 22667
2cf0635d 22668 free (qualified_name);
fb52b2f4
NC
22669 }
22670
4145f1d5 22671 out:
2cf0635d
NC
22672 if (nested_arch.file != NULL)
22673 fclose (nested_arch.file);
22674 release_archive (&nested_arch);
22675 release_archive (&arch);
fb52b2f4 22676
d989285c 22677 return ret;
fb52b2f4
NC
22678}
22679
015dc7e1 22680static bool
2cf0635d 22681process_file (char * file_name)
fb52b2f4 22682{
dda8d76d 22683 Filedata * filedata = NULL;
fb52b2f4
NC
22684 struct stat statbuf;
22685 char armag[SARMAG];
015dc7e1 22686 bool ret = true;
fb52b2f4
NC
22687
22688 if (stat (file_name, &statbuf) < 0)
22689 {
f24ddbdd
NC
22690 if (errno == ENOENT)
22691 error (_("'%s': No such file\n"), file_name);
22692 else
22693 error (_("Could not locate '%s'. System error message: %s\n"),
22694 file_name, strerror (errno));
015dc7e1 22695 return false;
f24ddbdd
NC
22696 }
22697
22698 if (! S_ISREG (statbuf.st_mode))
22699 {
22700 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22701 return false;
fb52b2f4
NC
22702 }
22703
dda8d76d
NC
22704 filedata = calloc (1, sizeof * filedata);
22705 if (filedata == NULL)
22706 {
22707 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22708 return false;
dda8d76d
NC
22709 }
22710
22711 filedata->file_name = file_name;
22712 filedata->handle = fopen (file_name, "rb");
22713 if (filedata->handle == NULL)
fb52b2f4 22714 {
f24ddbdd 22715 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22716 free (filedata);
015dc7e1 22717 return false;
fb52b2f4
NC
22718 }
22719
dda8d76d 22720 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22721 {
4145f1d5 22722 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22723 fclose (filedata->handle);
22724 free (filedata);
015dc7e1 22725 return false;
fb52b2f4
NC
22726 }
22727
be7d229a 22728 filedata->file_size = statbuf.st_size;
015dc7e1 22729 filedata->is_separate = false;
f54498b4 22730
fb52b2f4 22731 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22732 {
015dc7e1
AM
22733 if (! process_archive (filedata, false))
22734 ret = false;
32ec8896 22735 }
2cf0635d 22736 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22737 {
015dc7e1
AM
22738 if ( ! process_archive (filedata, true))
22739 ret = false;
32ec8896 22740 }
fb52b2f4
NC
22741 else
22742 {
1b513401 22743 if (do_archive_index && !check_all)
4145f1d5
NC
22744 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22745 file_name);
22746
dda8d76d 22747 rewind (filedata->handle);
978c4450 22748 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22749
dda8d76d 22750 if (! process_object (filedata))
015dc7e1 22751 ret = false;
fb52b2f4
NC
22752 }
22753
dda8d76d 22754 fclose (filedata->handle);
8fb879cd
AM
22755 free (filedata->section_headers);
22756 free (filedata->program_headers);
22757 free (filedata->string_table);
6431e409 22758 free (filedata->dump.dump_sects);
dda8d76d 22759 free (filedata);
32ec8896 22760
fd486f32 22761 free (ba_cache.strtab);
1bd6175a 22762 ba_cache.strtab = NULL;
fd486f32 22763 free (ba_cache.symtab);
1bd6175a 22764 ba_cache.symtab = NULL;
fd486f32
AM
22765 ba_cache.filedata = NULL;
22766
fb52b2f4
NC
22767 return ret;
22768}
22769
252b5132
RH
22770#ifdef SUPPORT_DISASSEMBLY
22771/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22772 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22773 symbols. */
252b5132
RH
22774
22775void
2cf0635d 22776print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22777{
22778 fprintf (outfile,"0x%8.8x", addr);
22779}
22780
e3c8793a 22781/* Needed by the i386 disassembler. */
dda8d76d 22782
252b5132
RH
22783void
22784db_task_printsym (unsigned int addr)
22785{
22786 print_address (addr, stderr);
22787}
22788#endif
22789
22790int
2cf0635d 22791main (int argc, char ** argv)
252b5132 22792{
ff78d6d6
L
22793 int err;
22794
87b9f255 22795#ifdef HAVE_LC_MESSAGES
252b5132 22796 setlocale (LC_MESSAGES, "");
3882b010 22797#endif
3882b010 22798 setlocale (LC_CTYPE, "");
252b5132
RH
22799 bindtextdomain (PACKAGE, LOCALEDIR);
22800 textdomain (PACKAGE);
22801
869b9d07
MM
22802 expandargv (&argc, &argv);
22803
dda8d76d 22804 parse_args (& cmdline, argc, argv);
59f14fc0 22805
18bd398b 22806 if (optind < (argc - 1))
1b513401
NC
22807 /* When displaying information for more than one file,
22808 prefix the information with the file name. */
015dc7e1 22809 show_name = true;
5656ba2c
L
22810 else if (optind >= argc)
22811 {
1b513401 22812 /* Ensure that the warning is always displayed. */
015dc7e1 22813 do_checks = true;
1b513401 22814
5656ba2c
L
22815 warn (_("Nothing to do.\n"));
22816 usage (stderr);
22817 }
18bd398b 22818
015dc7e1 22819 err = false;
252b5132 22820 while (optind < argc)
32ec8896 22821 if (! process_file (argv[optind++]))
015dc7e1 22822 err = true;
252b5132 22823
9db70fc3 22824 free (cmdline.dump_sects);
252b5132 22825
7d9813f1
NA
22826 free (dump_ctf_symtab_name);
22827 free (dump_ctf_strtab_name);
22828 free (dump_ctf_parent_name);
22829
32ec8896 22830 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22831}