]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
RISC-V: Always generate R_RISCV_CALL_PLT reloc for call in assembler.
[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
2922d21d
AW
4082 switch (e_flags & EF_RISCV_FLOAT_ABI)
4083 {
4084 case EF_RISCV_FLOAT_ABI_SOFT:
4085 strcat (buf, ", soft-float ABI");
4086 break;
4087
4088 case EF_RISCV_FLOAT_ABI_SINGLE:
4089 strcat (buf, ", single-float ABI");
4090 break;
4091
4092 case EF_RISCV_FLOAT_ABI_DOUBLE:
4093 strcat (buf, ", double-float ABI");
4094 break;
4095
4096 case EF_RISCV_FLOAT_ABI_QUAD:
4097 strcat (buf, ", quad-float ABI");
4098 break;
4099 }
e23eba97
NC
4100 break;
4101
ccde1100
AO
4102 case EM_SH:
4103 switch ((e_flags & EF_SH_MACH_MASK))
4104 {
4105 case EF_SH1: strcat (buf, ", sh1"); break;
4106 case EF_SH2: strcat (buf, ", sh2"); break;
4107 case EF_SH3: strcat (buf, ", sh3"); break;
4108 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4109 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4110 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4111 case EF_SH3E: strcat (buf, ", sh3e"); break;
4112 case EF_SH4: strcat (buf, ", sh4"); break;
4113 case EF_SH5: strcat (buf, ", sh5"); break;
4114 case EF_SH2E: strcat (buf, ", sh2e"); break;
4115 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4116 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4117 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4118 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4119 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4120 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4121 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4122 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4123 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4124 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4125 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4126 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4127 }
4128
cec6a5b8
MR
4129 if (e_flags & EF_SH_PIC)
4130 strcat (buf, ", pic");
4131
4132 if (e_flags & EF_SH_FDPIC)
4133 strcat (buf, ", fdpic");
ccde1100 4134 break;
948f632f 4135
73589c9d
CS
4136 case EM_OR1K:
4137 if (e_flags & EF_OR1K_NODELAY)
4138 strcat (buf, ", no delay");
4139 break;
57346661 4140
351b4b40
RH
4141 case EM_SPARCV9:
4142 if (e_flags & EF_SPARC_32PLUS)
4143 strcat (buf, ", v8+");
4144
4145 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4146 strcat (buf, ", ultrasparcI");
4147
4148 if (e_flags & EF_SPARC_SUN_US3)
4149 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4150
4151 if (e_flags & EF_SPARC_HAL_R1)
4152 strcat (buf, ", halr1");
4153
4154 if (e_flags & EF_SPARC_LEDATA)
4155 strcat (buf, ", ledata");
4156
4157 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4158 strcat (buf, ", tso");
4159
4160 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4161 strcat (buf, ", pso");
4162
4163 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4164 strcat (buf, ", rmo");
4165 break;
7d466069 4166
103f02d3
UD
4167 case EM_PARISC:
4168 switch (e_flags & EF_PARISC_ARCH)
4169 {
4170 case EFA_PARISC_1_0:
4171 strcpy (buf, ", PA-RISC 1.0");
4172 break;
4173 case EFA_PARISC_1_1:
4174 strcpy (buf, ", PA-RISC 1.1");
4175 break;
4176 case EFA_PARISC_2_0:
4177 strcpy (buf, ", PA-RISC 2.0");
4178 break;
4179 default:
4180 break;
4181 }
4182 if (e_flags & EF_PARISC_TRAPNIL)
4183 strcat (buf, ", trapnil");
4184 if (e_flags & EF_PARISC_EXT)
4185 strcat (buf, ", ext");
4186 if (e_flags & EF_PARISC_LSB)
4187 strcat (buf, ", lsb");
4188 if (e_flags & EF_PARISC_WIDE)
4189 strcat (buf, ", wide");
4190 if (e_flags & EF_PARISC_NO_KABP)
4191 strcat (buf, ", no kabp");
4192 if (e_flags & EF_PARISC_LAZYSWAP)
4193 strcat (buf, ", lazyswap");
30800947 4194 break;
76da6bbe 4195
7d466069 4196 case EM_PJ:
2b0337b0 4197 case EM_PJ_OLD:
7d466069
ILT
4198 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4199 strcat (buf, ", new calling convention");
4200
4201 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4202 strcat (buf, ", gnu calling convention");
4203 break;
4d6ed7c8
NC
4204
4205 case EM_IA_64:
4206 if ((e_flags & EF_IA_64_ABI64))
4207 strcat (buf, ", 64-bit");
4208 else
4209 strcat (buf, ", 32-bit");
4210 if ((e_flags & EF_IA_64_REDUCEDFP))
4211 strcat (buf, ", reduced fp model");
4212 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4213 strcat (buf, ", no function descriptors, constant gp");
4214 else if ((e_flags & EF_IA_64_CONS_GP))
4215 strcat (buf, ", constant gp");
4216 if ((e_flags & EF_IA_64_ABSOLUTE))
4217 strcat (buf, ", absolute");
dda8d76d 4218 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4219 {
4220 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4221 strcat (buf, ", vms_linkages");
4222 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4223 {
4224 case EF_IA_64_VMS_COMCOD_SUCCESS:
4225 break;
4226 case EF_IA_64_VMS_COMCOD_WARNING:
4227 strcat (buf, ", warning");
4228 break;
4229 case EF_IA_64_VMS_COMCOD_ERROR:
4230 strcat (buf, ", error");
4231 break;
4232 case EF_IA_64_VMS_COMCOD_ABORT:
4233 strcat (buf, ", abort");
4234 break;
4235 default:
bee0ee85
NC
4236 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4237 e_flags & EF_IA_64_VMS_COMCOD);
4238 strcat (buf, ", <unknown>");
28f997cf
TG
4239 }
4240 }
4d6ed7c8 4241 break;
179d3252
JT
4242
4243 case EM_VAX:
4244 if ((e_flags & EF_VAX_NONPIC))
4245 strcat (buf, ", non-PIC");
4246 if ((e_flags & EF_VAX_DFLOAT))
4247 strcat (buf, ", D-Float");
4248 if ((e_flags & EF_VAX_GFLOAT))
4249 strcat (buf, ", G-Float");
4250 break;
c7927a3c 4251
619ed720
EB
4252 case EM_VISIUM:
4253 if (e_flags & EF_VISIUM_ARCH_MCM)
4254 strcat (buf, ", mcm");
4255 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4256 strcat (buf, ", mcm24");
4257 if (e_flags & EF_VISIUM_ARCH_GR6)
4258 strcat (buf, ", gr6");
4259 break;
4260
4046d87a 4261 case EM_RL78:
1740ba0c
NC
4262 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4263 {
4264 case E_FLAG_RL78_ANY_CPU: break;
4265 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4266 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4267 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4268 }
856ea05c
KP
4269 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4270 strcat (buf, ", 64-bit doubles");
4046d87a 4271 break;
0b4362b0 4272
c7927a3c
NC
4273 case EM_RX:
4274 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4275 strcat (buf, ", 64-bit doubles");
4276 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4277 strcat (buf, ", dsp");
d4cb0ea0 4278 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4279 strcat (buf, ", pid");
708e2187
NC
4280 if (e_flags & E_FLAG_RX_ABI)
4281 strcat (buf, ", RX ABI");
3525236c
NC
4282 if (e_flags & E_FLAG_RX_SINSNS_SET)
4283 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4284 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4285 if (e_flags & E_FLAG_RX_V2)
4286 strcat (buf, ", V2");
f87673e0
YS
4287 if (e_flags & E_FLAG_RX_V3)
4288 strcat (buf, ", V3");
d4cb0ea0 4289 break;
55786da2
AK
4290
4291 case EM_S390:
4292 if (e_flags & EF_S390_HIGH_GPRS)
4293 strcat (buf, ", highgprs");
d4cb0ea0 4294 break;
40b36596
JM
4295
4296 case EM_TI_C6000:
4297 if ((e_flags & EF_C6000_REL))
4298 strcat (buf, ", relocatable module");
d4cb0ea0 4299 break;
13761a11
NC
4300
4301 case EM_MSP430:
4302 strcat (buf, _(": architecture variant: "));
4303 switch (e_flags & EF_MSP430_MACH)
4304 {
4305 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4306 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4307 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4308 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4309 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4310 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4311 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4312 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4313 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4314 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4315 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4316 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4317 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4318 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4319 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4320 default:
4321 strcat (buf, _(": unknown")); break;
4322 }
4323
4324 if (e_flags & ~ EF_MSP430_MACH)
4325 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4326 break;
4327
4328 case EM_Z80:
4329 switch (e_flags & EF_Z80_MACH_MSK)
4330 {
4331 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4332 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4333 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4334 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4335 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4336 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4337 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4338 default:
4339 strcat (buf, _(", unknown")); break;
4340 }
4341 break;
e9a0721f 4342 case EM_LOONGARCH:
4343 if (EF_LOONGARCH_IS_LP64 (e_flags))
4344 strcat (buf, ", LP64");
4345 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4346 strcat (buf, ", ILP32");
4347
4348 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4349 strcat (buf, ", SOFT-FLOAT");
4350 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4351 strcat (buf, ", SINGLE-FLOAT");
4352 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4353 strcat (buf, ", DOUBLE-FLOAT");
4354
4355 break;
252b5132
RH
4356 }
4357 }
4358
4359 return buf;
4360}
4361
252b5132 4362static const char *
dda8d76d 4363get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4364{
4365 static char buff[32];
4366
4367 switch (osabi)
4368 {
4369 case ELFOSABI_NONE: return "UNIX - System V";
4370 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4371 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4372 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4373 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4374 case ELFOSABI_AIX: return "UNIX - AIX";
4375 case ELFOSABI_IRIX: return "UNIX - IRIX";
4376 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4377 case ELFOSABI_TRU64: return "UNIX - TRU64";
4378 case ELFOSABI_MODESTO: return "Novell - Modesto";
4379 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4380 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4381 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4382 case ELFOSABI_AROS: return "AROS";
11636f9e 4383 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4384 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4385 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4386 default:
40b36596 4387 if (osabi >= 64)
dda8d76d 4388 switch (filedata->file_header.e_machine)
40b36596 4389 {
37870be8
SM
4390 case EM_AMDGPU:
4391 switch (osabi)
4392 {
4393 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4394 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4395 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4396 default:
4397 break;
4398 }
4399 break;
4400
40b36596
JM
4401 case EM_ARM:
4402 switch (osabi)
4403 {
4404 case ELFOSABI_ARM: return "ARM";
18a20338 4405 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4406 default:
4407 break;
4408 }
4409 break;
4410
4411 case EM_MSP430:
4412 case EM_MSP430_OLD:
619ed720 4413 case EM_VISIUM:
40b36596
JM
4414 switch (osabi)
4415 {
4416 case ELFOSABI_STANDALONE: return _("Standalone App");
4417 default:
4418 break;
4419 }
4420 break;
4421
4422 case EM_TI_C6000:
4423 switch (osabi)
4424 {
4425 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4426 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4427 default:
4428 break;
4429 }
4430 break;
4431
4432 default:
4433 break;
4434 }
e9e44622 4435 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4436 return buff;
4437 }
4438}
4439
a06ea964
NC
4440static const char *
4441get_aarch64_segment_type (unsigned long type)
4442{
4443 switch (type)
4444 {
32ec8896 4445 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4446 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4447 default: return NULL;
a06ea964 4448 }
a06ea964
NC
4449}
4450
b294bdf8
MM
4451static const char *
4452get_arm_segment_type (unsigned long type)
4453{
4454 switch (type)
4455 {
32ec8896
NC
4456 case PT_ARM_EXIDX: return "EXIDX";
4457 default: return NULL;
b294bdf8 4458 }
b294bdf8
MM
4459}
4460
b4cbbe8f
AK
4461static const char *
4462get_s390_segment_type (unsigned long type)
4463{
4464 switch (type)
4465 {
4466 case PT_S390_PGSTE: return "S390_PGSTE";
4467 default: return NULL;
4468 }
4469}
4470
d3ba0551
AM
4471static const char *
4472get_mips_segment_type (unsigned long type)
252b5132
RH
4473{
4474 switch (type)
4475 {
32ec8896
NC
4476 case PT_MIPS_REGINFO: return "REGINFO";
4477 case PT_MIPS_RTPROC: return "RTPROC";
4478 case PT_MIPS_OPTIONS: return "OPTIONS";
4479 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4480 default: return NULL;
252b5132 4481 }
252b5132
RH
4482}
4483
103f02d3 4484static const char *
d3ba0551 4485get_parisc_segment_type (unsigned long type)
103f02d3
UD
4486{
4487 switch (type)
4488 {
103f02d3
UD
4489 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4490 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4491 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4492 default: return NULL;
103f02d3 4493 }
103f02d3
UD
4494}
4495
4d6ed7c8 4496static const char *
d3ba0551 4497get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4498{
4499 switch (type)
4500 {
4501 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4502 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4503 default: return NULL;
4d6ed7c8 4504 }
4d6ed7c8
NC
4505}
4506
40b36596
JM
4507static const char *
4508get_tic6x_segment_type (unsigned long type)
4509{
4510 switch (type)
4511 {
32ec8896
NC
4512 case PT_C6000_PHATTR: return "C6000_PHATTR";
4513 default: return NULL;
40b36596 4514 }
40b36596
JM
4515}
4516
fbc95f1e
KC
4517static const char *
4518get_riscv_segment_type (unsigned long type)
4519{
4520 switch (type)
4521 {
4522 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4523 default: return NULL;
4524 }
4525}
4526
df3a023b
AM
4527static const char *
4528get_hpux_segment_type (unsigned long type, unsigned e_machine)
4529{
4530 if (e_machine == EM_PARISC)
4531 switch (type)
4532 {
4533 case PT_HP_TLS: return "HP_TLS";
4534 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4535 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4536 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4537 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4538 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4539 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4540 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4541 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4542 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4543 case PT_HP_PARALLEL: return "HP_PARALLEL";
4544 case PT_HP_FASTBIND: return "HP_FASTBIND";
4545 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4546 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4547 case PT_HP_STACK: return "HP_STACK";
4548 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4549 default: return NULL;
4550 }
4551
4552 if (e_machine == EM_IA_64)
4553 switch (type)
4554 {
4555 case PT_HP_TLS: return "HP_TLS";
4556 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4557 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4558 case PT_IA_64_HP_STACK: return "HP_STACK";
4559 default: return NULL;
4560 }
4561
4562 return NULL;
4563}
4564
5522f910
NC
4565static const char *
4566get_solaris_segment_type (unsigned long type)
4567{
4568 switch (type)
4569 {
4570 case 0x6464e550: return "PT_SUNW_UNWIND";
4571 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4572 case 0x6ffffff7: return "PT_LOSUNW";
4573 case 0x6ffffffa: return "PT_SUNWBSS";
4574 case 0x6ffffffb: return "PT_SUNWSTACK";
4575 case 0x6ffffffc: return "PT_SUNWDTRACE";
4576 case 0x6ffffffd: return "PT_SUNWCAP";
4577 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4578 default: return NULL;
5522f910
NC
4579 }
4580}
4581
252b5132 4582static const char *
dda8d76d 4583get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4584{
b34976b6 4585 static char buff[32];
252b5132
RH
4586
4587 switch (p_type)
4588 {
b34976b6
AM
4589 case PT_NULL: return "NULL";
4590 case PT_LOAD: return "LOAD";
252b5132 4591 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4592 case PT_INTERP: return "INTERP";
4593 case PT_NOTE: return "NOTE";
4594 case PT_SHLIB: return "SHLIB";
4595 case PT_PHDR: return "PHDR";
13ae64f3 4596 case PT_TLS: return "TLS";
32ec8896 4597 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4598 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4599 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4600 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4601
3eba3ef3
NC
4602 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4603 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4604 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4605
252b5132 4606 default:
df3a023b 4607 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4608 {
2cf0635d 4609 const char * result;
103f02d3 4610
dda8d76d 4611 switch (filedata->file_header.e_machine)
252b5132 4612 {
a06ea964
NC
4613 case EM_AARCH64:
4614 result = get_aarch64_segment_type (p_type);
4615 break;
b294bdf8
MM
4616 case EM_ARM:
4617 result = get_arm_segment_type (p_type);
4618 break;
252b5132 4619 case EM_MIPS:
4fe85591 4620 case EM_MIPS_RS3_LE:
252b5132
RH
4621 result = get_mips_segment_type (p_type);
4622 break;
103f02d3
UD
4623 case EM_PARISC:
4624 result = get_parisc_segment_type (p_type);
4625 break;
4d6ed7c8
NC
4626 case EM_IA_64:
4627 result = get_ia64_segment_type (p_type);
4628 break;
40b36596
JM
4629 case EM_TI_C6000:
4630 result = get_tic6x_segment_type (p_type);
4631 break;
b4cbbe8f
AK
4632 case EM_S390:
4633 case EM_S390_OLD:
4634 result = get_s390_segment_type (p_type);
4635 break;
fbc95f1e
KC
4636 case EM_RISCV:
4637 result = get_riscv_segment_type (p_type);
4638 break;
252b5132
RH
4639 default:
4640 result = NULL;
4641 break;
4642 }
103f02d3 4643
252b5132
RH
4644 if (result != NULL)
4645 return result;
103f02d3 4646
1a9ccd70 4647 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4648 }
4649 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4650 {
df3a023b 4651 const char * result = NULL;
103f02d3 4652
df3a023b 4653 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4654 {
df3a023b
AM
4655 case ELFOSABI_GNU:
4656 case ELFOSABI_FREEBSD:
4657 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4658 {
4659 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4660 result = buff;
4661 }
103f02d3 4662 break;
df3a023b
AM
4663 case ELFOSABI_HPUX:
4664 result = get_hpux_segment_type (p_type,
4665 filedata->file_header.e_machine);
4666 break;
4667 case ELFOSABI_SOLARIS:
4668 result = get_solaris_segment_type (p_type);
00428cca 4669 break;
103f02d3 4670 default:
103f02d3
UD
4671 break;
4672 }
103f02d3
UD
4673 if (result != NULL)
4674 return result;
4675
1a9ccd70 4676 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4677 }
252b5132 4678 else
e9e44622 4679 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4680
4681 return buff;
4682 }
4683}
4684
53a346d8
CZ
4685static const char *
4686get_arc_section_type_name (unsigned int sh_type)
4687{
4688 switch (sh_type)
4689 {
4690 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4691 default:
4692 break;
4693 }
4694 return NULL;
4695}
4696
252b5132 4697static const char *
d3ba0551 4698get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4699{
4700 switch (sh_type)
4701 {
b34976b6
AM
4702 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4703 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4704 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4705 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4706 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4707 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4708 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4709 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4710 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4711 case SHT_MIPS_RELD: return "MIPS_RELD";
4712 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4713 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4714 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4715 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4716 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4717 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4718 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4719 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4720 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4721 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4722 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4723 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4724 case SHT_MIPS_LINE: return "MIPS_LINE";
4725 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4726 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4727 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4728 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4729 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4730 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4731 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4732 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4733 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4734 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4735 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4736 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4737 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4738 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4739 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4740 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4741 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4742 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4743 default:
4744 break;
4745 }
4746 return NULL;
4747}
4748
103f02d3 4749static const char *
d3ba0551 4750get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4751{
4752 switch (sh_type)
4753 {
4754 case SHT_PARISC_EXT: return "PARISC_EXT";
4755 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4756 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4757 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4758 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4759 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4760 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4761 default: return NULL;
103f02d3 4762 }
103f02d3
UD
4763}
4764
4d6ed7c8 4765static const char *
dda8d76d 4766get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4767{
18bd398b 4768 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4769 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4770 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4771
4d6ed7c8
NC
4772 switch (sh_type)
4773 {
148b93f2
NC
4774 case SHT_IA_64_EXT: return "IA_64_EXT";
4775 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4776 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4777 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4778 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4779 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4780 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4781 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4782 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4783 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4784 default:
4785 break;
4786 }
4787 return NULL;
4788}
4789
d2b2c203
DJ
4790static const char *
4791get_x86_64_section_type_name (unsigned int sh_type)
4792{
4793 switch (sh_type)
4794 {
4795 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4796 default: return NULL;
d2b2c203 4797 }
d2b2c203
DJ
4798}
4799
a06ea964
NC
4800static const char *
4801get_aarch64_section_type_name (unsigned int sh_type)
4802{
4803 switch (sh_type)
4804 {
32ec8896
NC
4805 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4806 default: return NULL;
a06ea964 4807 }
a06ea964
NC
4808}
4809
40a18ebd
NC
4810static const char *
4811get_arm_section_type_name (unsigned int sh_type)
4812{
4813 switch (sh_type)
4814 {
7f6fed87
NC
4815 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4816 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4817 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4818 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4819 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4820 default: return NULL;
40a18ebd 4821 }
40a18ebd
NC
4822}
4823
40b36596
JM
4824static const char *
4825get_tic6x_section_type_name (unsigned int sh_type)
4826{
4827 switch (sh_type)
4828 {
32ec8896
NC
4829 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4830 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4831 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4832 case SHT_TI_ICODE: return "TI_ICODE";
4833 case SHT_TI_XREF: return "TI_XREF";
4834 case SHT_TI_HANDLER: return "TI_HANDLER";
4835 case SHT_TI_INITINFO: return "TI_INITINFO";
4836 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4837 default: return NULL;
40b36596 4838 }
40b36596
JM
4839}
4840
13761a11 4841static const char *
b0191216 4842get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4843{
4844 switch (sh_type)
4845 {
32ec8896
NC
4846 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4847 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4848 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4849 default: return NULL;
13761a11
NC
4850 }
4851}
4852
fe944acf
FT
4853static const char *
4854get_nfp_section_type_name (unsigned int sh_type)
4855{
4856 switch (sh_type)
4857 {
4858 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4859 case SHT_NFP_INITREG: return "NFP_INITREG";
4860 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4861 default: return NULL;
4862 }
4863}
4864
685080f2
NC
4865static const char *
4866get_v850_section_type_name (unsigned int sh_type)
4867{
4868 switch (sh_type)
4869 {
32ec8896
NC
4870 case SHT_V850_SCOMMON: return "V850 Small Common";
4871 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4872 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4873 case SHT_RENESAS_IOP: return "RENESAS IOP";
4874 case SHT_RENESAS_INFO: return "RENESAS INFO";
4875 default: return NULL;
685080f2
NC
4876 }
4877}
4878
2dc8dd17
JW
4879static const char *
4880get_riscv_section_type_name (unsigned int sh_type)
4881{
4882 switch (sh_type)
4883 {
4884 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4885 default: return NULL;
4886 }
4887}
4888
0861f561
CQ
4889static const char *
4890get_csky_section_type_name (unsigned int sh_type)
4891{
4892 switch (sh_type)
4893 {
4894 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4895 default: return NULL;
4896 }
4897}
4898
252b5132 4899static const char *
dda8d76d 4900get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4901{
b34976b6 4902 static char buff[32];
9fb71ee4 4903 const char * result;
252b5132
RH
4904
4905 switch (sh_type)
4906 {
4907 case SHT_NULL: return "NULL";
4908 case SHT_PROGBITS: return "PROGBITS";
4909 case SHT_SYMTAB: return "SYMTAB";
4910 case SHT_STRTAB: return "STRTAB";
4911 case SHT_RELA: return "RELA";
dd207c13 4912 case SHT_RELR: return "RELR";
252b5132
RH
4913 case SHT_HASH: return "HASH";
4914 case SHT_DYNAMIC: return "DYNAMIC";
4915 case SHT_NOTE: return "NOTE";
4916 case SHT_NOBITS: return "NOBITS";
4917 case SHT_REL: return "REL";
4918 case SHT_SHLIB: return "SHLIB";
4919 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4920 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4921 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4922 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4923 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4924 case SHT_GROUP: return "GROUP";
67ce483b 4925 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4926 case SHT_GNU_verdef: return "VERDEF";
4927 case SHT_GNU_verneed: return "VERNEED";
4928 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4929 case 0x6ffffff0: return "VERSYM";
4930 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4931 case 0x7ffffffd: return "AUXILIARY";
4932 case 0x7fffffff: return "FILTER";
047b2264 4933 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4934
4935 default:
4936 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4937 {
dda8d76d 4938 switch (filedata->file_header.e_machine)
252b5132 4939 {
53a346d8
CZ
4940 case EM_ARC:
4941 case EM_ARC_COMPACT:
4942 case EM_ARC_COMPACT2:
4943 result = get_arc_section_type_name (sh_type);
4944 break;
252b5132 4945 case EM_MIPS:
4fe85591 4946 case EM_MIPS_RS3_LE:
252b5132
RH
4947 result = get_mips_section_type_name (sh_type);
4948 break;
103f02d3
UD
4949 case EM_PARISC:
4950 result = get_parisc_section_type_name (sh_type);
4951 break;
4d6ed7c8 4952 case EM_IA_64:
dda8d76d 4953 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4954 break;
d2b2c203 4955 case EM_X86_64:
8a9036a4 4956 case EM_L1OM:
7a9068fe 4957 case EM_K1OM:
d2b2c203
DJ
4958 result = get_x86_64_section_type_name (sh_type);
4959 break;
a06ea964
NC
4960 case EM_AARCH64:
4961 result = get_aarch64_section_type_name (sh_type);
4962 break;
40a18ebd
NC
4963 case EM_ARM:
4964 result = get_arm_section_type_name (sh_type);
4965 break;
40b36596
JM
4966 case EM_TI_C6000:
4967 result = get_tic6x_section_type_name (sh_type);
4968 break;
13761a11 4969 case EM_MSP430:
b0191216 4970 result = get_msp430_section_type_name (sh_type);
13761a11 4971 break;
fe944acf
FT
4972 case EM_NFP:
4973 result = get_nfp_section_type_name (sh_type);
4974 break;
685080f2
NC
4975 case EM_V800:
4976 case EM_V850:
4977 case EM_CYGNUS_V850:
4978 result = get_v850_section_type_name (sh_type);
4979 break;
2dc8dd17
JW
4980 case EM_RISCV:
4981 result = get_riscv_section_type_name (sh_type);
4982 break;
0861f561
CQ
4983 case EM_CSKY:
4984 result = get_csky_section_type_name (sh_type);
4985 break;
252b5132
RH
4986 default:
4987 result = NULL;
4988 break;
4989 }
4990
4991 if (result != NULL)
4992 return result;
4993
9fb71ee4 4994 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4995 }
4996 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4997 {
dda8d76d 4998 switch (filedata->file_header.e_machine)
148b93f2
NC
4999 {
5000 case EM_IA_64:
dda8d76d 5001 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5002 break;
5003 default:
dda8d76d 5004 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5005 result = get_solaris_section_type (sh_type);
5006 else
1b4b80bf
NC
5007 {
5008 switch (sh_type)
5009 {
5010 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5011 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5012 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5013 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5014 default:
5015 result = NULL;
5016 break;
5017 }
5018 }
148b93f2
NC
5019 break;
5020 }
5021
5022 if (result != NULL)
5023 return result;
5024
9fb71ee4 5025 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5026 }
252b5132 5027 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5028 {
dda8d76d 5029 switch (filedata->file_header.e_machine)
685080f2
NC
5030 {
5031 case EM_V800:
5032 case EM_V850:
5033 case EM_CYGNUS_V850:
9fb71ee4 5034 result = get_v850_section_type_name (sh_type);
a9fb83be 5035 break;
685080f2 5036 default:
9fb71ee4 5037 result = NULL;
685080f2
NC
5038 break;
5039 }
5040
9fb71ee4
NC
5041 if (result != NULL)
5042 return result;
5043
5044 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5045 }
252b5132 5046 else
a7dbfd1c
NC
5047 /* This message is probably going to be displayed in a 15
5048 character wide field, so put the hex value first. */
5049 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5050
252b5132
RH
5051 return buff;
5052 }
5053}
5054
79bc120c
NC
5055enum long_option_values
5056{
5057 OPTION_DEBUG_DUMP = 512,
5058 OPTION_DYN_SYMS,
0f03783c 5059 OPTION_LTO_SYMS,
79bc120c
NC
5060 OPTION_DWARF_DEPTH,
5061 OPTION_DWARF_START,
5062 OPTION_DWARF_CHECK,
5063 OPTION_CTF_DUMP,
5064 OPTION_CTF_PARENT,
5065 OPTION_CTF_SYMBOLS,
5066 OPTION_CTF_STRINGS,
5067 OPTION_WITH_SYMBOL_VERSIONS,
5068 OPTION_RECURSE_LIMIT,
5069 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
5070 OPTION_NO_DEMANGLING,
5071 OPTION_SYM_BASE
79bc120c 5072};
2979dc34 5073
85b1c36d 5074static struct option options[] =
252b5132 5075{
79bc120c
NC
5076 /* Note - This table is alpha-sorted on the 'val'
5077 field in order to make adding new options easier. */
5078 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5079 {"all", no_argument, 0, 'a'},
79bc120c
NC
5080 {"demangle", optional_argument, 0, 'C'},
5081 {"archive-index", no_argument, 0, 'c'},
5082 {"use-dynamic", no_argument, 0, 'D'},
5083 {"dynamic", no_argument, 0, 'd'},
b34976b6 5084 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5085 {"section-groups", no_argument, 0, 'g'},
5086 {"help", no_argument, 0, 'H'},
5087 {"file-header", no_argument, 0, 'h'},
b34976b6 5088 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5089 {"lint", no_argument, 0, 'L'},
5090 {"enable-checks", no_argument, 0, 'L'},
5091 {"program-headers", no_argument, 0, 'l'},
b34976b6 5092 {"segments", no_argument, 0, 'l'},
595cf52e 5093 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5094 {"notes", no_argument, 0, 'n'},
ca0e11aa 5095 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5096 {"string-dump", required_argument, 0, 'p'},
5097 {"relocated-dump", required_argument, 0, 'R'},
5098 {"relocs", no_argument, 0, 'r'},
5099 {"section-headers", no_argument, 0, 'S'},
5100 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5101 {"symbols", no_argument, 0, 's'},
5102 {"syms", no_argument, 0, 's'},
79bc120c
NC
5103 {"silent-truncation",no_argument, 0, 'T'},
5104 {"section-details", no_argument, 0, 't'},
b3aa80b4 5105 {"unicode", required_argument, NULL, 'U'},
09c11c86 5106 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5107 {"version-info", no_argument, 0, 'V'},
5108 {"version", no_argument, 0, 'v'},
5109 {"wide", no_argument, 0, 'W'},
b34976b6 5110 {"hex-dump", required_argument, 0, 'x'},
0e602686 5111 {"decompress", no_argument, 0, 'z'},
252b5132 5112
79bc120c
NC
5113 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5114 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5115 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5116 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5117 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5118 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5119 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5120 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5121 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5122 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5123#ifdef ENABLE_LIBCTF
d344b407 5124 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5125 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5126 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5127 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5128#endif
047c3dbf 5129 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5130
b34976b6 5131 {0, no_argument, 0, 0}
252b5132
RH
5132};
5133
5134static void
2cf0635d 5135usage (FILE * stream)
252b5132 5136{
92f01d61
JM
5137 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5138 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5139 fprintf (stream, _(" Options are:\n"));
5140 fprintf (stream, _("\
5141 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5142 fprintf (stream, _("\
5143 -h --file-header Display the ELF file header\n"));
5144 fprintf (stream, _("\
5145 -l --program-headers Display the program headers\n"));
5146 fprintf (stream, _("\
5147 --segments An alias for --program-headers\n"));
5148 fprintf (stream, _("\
5149 -S --section-headers Display the sections' header\n"));
5150 fprintf (stream, _("\
5151 --sections An alias for --section-headers\n"));
5152 fprintf (stream, _("\
5153 -g --section-groups Display the section groups\n"));
5154 fprintf (stream, _("\
5155 -t --section-details Display the section details\n"));
5156 fprintf (stream, _("\
5157 -e --headers Equivalent to: -h -l -S\n"));
5158 fprintf (stream, _("\
5159 -s --syms Display the symbol table\n"));
5160 fprintf (stream, _("\
5161 --symbols An alias for --syms\n"));
5162 fprintf (stream, _("\
5163 --dyn-syms Display the dynamic symbol table\n"));
5164 fprintf (stream, _("\
5165 --lto-syms Display LTO symbol tables\n"));
5166 fprintf (stream, _("\
047c3dbf
NL
5167 --sym-base=[0|8|10|16] \n\
5168 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5169 mixed (the default), octal, decimal, hexadecimal.\n"));
5170 fprintf (stream, _("\
0d646226
AM
5171 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5172 display_demangler_styles (stream, _("\
5173 STYLE can be "));
d6249f5f
AM
5174 fprintf (stream, _("\
5175 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5176 fprintf (stream, _("\
5177 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5178 fprintf (stream, _("\
5179 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5180 fprintf (stream, _("\
5181 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5182 Display unicode characters as determined by the current locale\n\
5183 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5184 escape sequences, or treat them as invalid and display as\n\
5185 \"{hex sequences}\"\n"));
d6249f5f
AM
5186 fprintf (stream, _("\
5187 -n --notes Display the core notes (if present)\n"));
5188 fprintf (stream, _("\
5189 -r --relocs Display the relocations (if present)\n"));
5190 fprintf (stream, _("\
5191 -u --unwind Display the unwind info (if present)\n"));
5192 fprintf (stream, _("\
5193 -d --dynamic Display the dynamic section (if present)\n"));
5194 fprintf (stream, _("\
5195 -V --version-info Display the version sections (if present)\n"));
5196 fprintf (stream, _("\
5197 -A --arch-specific Display architecture specific information (if any)\n"));
5198 fprintf (stream, _("\
5199 -c --archive-index Display the symbol/file index in an archive\n"));
5200 fprintf (stream, _("\
5201 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5202 fprintf (stream, _("\
5203 -L --lint|--enable-checks\n\
5204 Display warning messages for possible problems\n"));
5205 fprintf (stream, _("\
09c11c86 5206 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5207 Dump the contents of section <number|name> as bytes\n"));
5208 fprintf (stream, _("\
09c11c86 5209 -p --string-dump=<number|name>\n\
d6249f5f
AM
5210 Dump the contents of section <number|name> as strings\n"));
5211 fprintf (stream, _("\
cf13d699 5212 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5213 Dump the relocated contents of section <number|name>\n"));
5214 fprintf (stream, _("\
5215 -z --decompress Decompress section before dumping it\n"));
5216 fprintf (stream, _("\
5217 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5218 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5219 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5220 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5221 U/=trace_info]\n\
5222 Display the contents of DWARF debug sections\n"));
5223 fprintf (stream, _("\
5224 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5225 debuginfo files\n"));
5226 fprintf (stream, _("\
5227 -P --process-links Display the contents of non-debug sections in separate\n\
5228 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5229#if DEFAULT_FOR_FOLLOW_LINKS
5230 fprintf (stream, _("\
d6249f5f
AM
5231 -wK --debug-dump=follow-links\n\
5232 Follow links to separate debug info files (default)\n"));
5233 fprintf (stream, _("\
5234 -wN --debug-dump=no-follow-links\n\
5235 Do not follow links to separate debug info files\n"));
c46b7066
NC
5236#else
5237 fprintf (stream, _("\
d6249f5f
AM
5238 -wK --debug-dump=follow-links\n\
5239 Follow links to separate debug info files\n"));
5240 fprintf (stream, _("\
5241 -wN --debug-dump=no-follow-links\n\
5242 Do not follow links to separate debug info files\n\
5243 (default)\n"));
bed566bb
NC
5244#endif
5245#if HAVE_LIBDEBUGINFOD
5246 fprintf (stream, _("\
5247 -wD --debug-dump=use-debuginfod\n\
5248 When following links, also query debuginfod servers (default)\n"));
5249 fprintf (stream, _("\
5250 -wE --debug-dump=do-not-use-debuginfod\n\
5251 When following links, do not query debuginfod servers\n"));
c46b7066 5252#endif
fd2f0033 5253 fprintf (stream, _("\
d6249f5f
AM
5254 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5255 fprintf (stream, _("\
5256 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5257#ifdef ENABLE_LIBCTF
7d9813f1 5258 fprintf (stream, _("\
d6249f5f
AM
5259 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5260 fprintf (stream, _("\
80b56fad 5261 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5262 fprintf (stream, _("\
7d9813f1 5263 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5264 Use section <number|name> as the CTF external symtab\n"));
5265 fprintf (stream, _("\
7d9813f1 5266 --ctf-strings=<number|name>\n\
d6249f5f 5267 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5268#endif
7d9813f1 5269
252b5132 5270#ifdef SUPPORT_DISASSEMBLY
92f01d61 5271 fprintf (stream, _("\
09c11c86
NC
5272 -i --instruction-dump=<number|name>\n\
5273 Disassemble the contents of section <number|name>\n"));
252b5132 5274#endif
92f01d61 5275 fprintf (stream, _("\
d6249f5f
AM
5276 -I --histogram Display histogram of bucket list lengths\n"));
5277 fprintf (stream, _("\
5278 -W --wide Allow output width to exceed 80 characters\n"));
5279 fprintf (stream, _("\
5280 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5281 fprintf (stream, _("\
5282 @<file> Read options from <file>\n"));
5283 fprintf (stream, _("\
5284 -H --help Display this information\n"));
5285 fprintf (stream, _("\
8b53311e 5286 -v --version Display the version number of readelf\n"));
1118d252 5287
92f01d61
JM
5288 if (REPORT_BUGS_TO[0] && stream == stdout)
5289 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5290
92f01d61 5291 exit (stream == stdout ? 0 : 1);
252b5132
RH
5292}
5293
18bd398b
NC
5294/* Record the fact that the user wants the contents of section number
5295 SECTION to be displayed using the method(s) encoded as flags bits
5296 in TYPE. Note, TYPE can be zero if we are creating the array for
5297 the first time. */
5298
252b5132 5299static void
6431e409
AM
5300request_dump_bynumber (struct dump_data *dumpdata,
5301 unsigned int section, dump_type type)
252b5132 5302{
6431e409 5303 if (section >= dumpdata->num_dump_sects)
252b5132 5304 {
2cf0635d 5305 dump_type * new_dump_sects;
252b5132 5306
3f5e193b 5307 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5308 sizeof (* new_dump_sects));
252b5132
RH
5309
5310 if (new_dump_sects == NULL)
591a748a 5311 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5312 else
5313 {
6431e409 5314 if (dumpdata->dump_sects)
21b65bac
NC
5315 {
5316 /* Copy current flag settings. */
6431e409
AM
5317 memcpy (new_dump_sects, dumpdata->dump_sects,
5318 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5319
6431e409 5320 free (dumpdata->dump_sects);
21b65bac 5321 }
252b5132 5322
6431e409
AM
5323 dumpdata->dump_sects = new_dump_sects;
5324 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5325 }
5326 }
5327
6431e409
AM
5328 if (dumpdata->dump_sects)
5329 dumpdata->dump_sects[section] |= type;
252b5132
RH
5330}
5331
aef1f6d0
DJ
5332/* Request a dump by section name. */
5333
5334static void
2cf0635d 5335request_dump_byname (const char * section, dump_type type)
aef1f6d0 5336{
2cf0635d 5337 struct dump_list_entry * new_request;
aef1f6d0 5338
3f5e193b
NC
5339 new_request = (struct dump_list_entry *)
5340 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5341 if (!new_request)
591a748a 5342 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5343
5344 new_request->name = strdup (section);
5345 if (!new_request->name)
591a748a 5346 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5347
5348 new_request->type = type;
5349
5350 new_request->next = dump_sects_byname;
5351 dump_sects_byname = new_request;
5352}
5353
cf13d699 5354static inline void
6431e409 5355request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5356{
5357 int section;
5358 char * cp;
5359
015dc7e1 5360 do_dump = true;
cf13d699
NC
5361 section = strtoul (optarg, & cp, 0);
5362
5363 if (! *cp && section >= 0)
6431e409 5364 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5365 else
5366 request_dump_byname (optarg, type);
5367}
5368
252b5132 5369static void
6431e409 5370parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5371{
5372 int c;
5373
5374 if (argc < 2)
92f01d61 5375 usage (stderr);
252b5132
RH
5376
5377 while ((c = getopt_long
b3aa80b4 5378 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5379 {
252b5132
RH
5380 switch (c)
5381 {
5382 case 0:
5383 /* Long options. */
5384 break;
5385 case 'H':
92f01d61 5386 usage (stdout);
252b5132
RH
5387 break;
5388
5389 case 'a':
015dc7e1
AM
5390 do_syms = true;
5391 do_reloc = true;
5392 do_unwind = true;
5393 do_dynamic = true;
5394 do_header = true;
5395 do_sections = true;
5396 do_section_groups = true;
5397 do_segments = true;
5398 do_version = true;
5399 do_histogram = true;
5400 do_arch = true;
5401 do_notes = true;
252b5132 5402 break;
79bc120c 5403
f5842774 5404 case 'g':
015dc7e1 5405 do_section_groups = true;
f5842774 5406 break;
5477e8a0 5407 case 't':
595cf52e 5408 case 'N':
015dc7e1
AM
5409 do_sections = true;
5410 do_section_details = true;
595cf52e 5411 break;
252b5132 5412 case 'e':
015dc7e1
AM
5413 do_header = true;
5414 do_sections = true;
5415 do_segments = true;
252b5132 5416 break;
a952a375 5417 case 'A':
015dc7e1 5418 do_arch = true;
a952a375 5419 break;
252b5132 5420 case 'D':
015dc7e1 5421 do_using_dynamic = true;
252b5132
RH
5422 break;
5423 case 'r':
015dc7e1 5424 do_reloc = true;
252b5132 5425 break;
4d6ed7c8 5426 case 'u':
015dc7e1 5427 do_unwind = true;
4d6ed7c8 5428 break;
252b5132 5429 case 'h':
015dc7e1 5430 do_header = true;
252b5132
RH
5431 break;
5432 case 'l':
015dc7e1 5433 do_segments = true;
252b5132
RH
5434 break;
5435 case 's':
015dc7e1 5436 do_syms = true;
252b5132
RH
5437 break;
5438 case 'S':
015dc7e1 5439 do_sections = true;
252b5132
RH
5440 break;
5441 case 'd':
015dc7e1 5442 do_dynamic = true;
252b5132 5443 break;
a952a375 5444 case 'I':
015dc7e1 5445 do_histogram = true;
a952a375 5446 break;
779fe533 5447 case 'n':
015dc7e1 5448 do_notes = true;
779fe533 5449 break;
4145f1d5 5450 case 'c':
015dc7e1 5451 do_archive_index = true;
4145f1d5 5452 break;
1b513401 5453 case 'L':
015dc7e1 5454 do_checks = true;
1b513401 5455 break;
ca0e11aa 5456 case 'P':
015dc7e1
AM
5457 process_links = true;
5458 do_follow_links = true;
e1dbfc17 5459 dump_any_debugging = true;
ca0e11aa 5460 break;
252b5132 5461 case 'x':
6431e409 5462 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5463 break;
09c11c86 5464 case 'p':
6431e409 5465 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5466 break;
5467 case 'R':
6431e409 5468 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5469 break;
0e602686 5470 case 'z':
015dc7e1 5471 decompress_dumps = true;
0e602686 5472 break;
252b5132 5473 case 'w':
0f03783c 5474 if (optarg == NULL)
613ff48b 5475 {
015dc7e1 5476 do_debugging = true;
94585d6d
NC
5477 do_dump = true;
5478 dump_any_debugging = true;
613ff48b
CC
5479 dwarf_select_sections_all ();
5480 }
252b5132
RH
5481 else
5482 {
015dc7e1 5483 do_debugging = false;
94585d6d
NC
5484 if (dwarf_select_sections_by_letters (optarg))
5485 {
5486 do_dump = true;
5487 dump_any_debugging = true;
5488 }
252b5132
RH
5489 }
5490 break;
2979dc34 5491 case OPTION_DEBUG_DUMP:
0f03783c 5492 if (optarg == NULL)
d6249f5f 5493 {
94585d6d 5494 do_dump = true;
d6249f5f 5495 do_debugging = true;
94585d6d 5496 dump_any_debugging = true;
d6249f5f
AM
5497 dwarf_select_sections_all ();
5498 }
2979dc34
JJ
5499 else
5500 {
015dc7e1 5501 do_debugging = false;
94585d6d
NC
5502 if (dwarf_select_sections_by_names (optarg))
5503 {
5504 do_dump = true;
5505 dump_any_debugging = true;
5506 }
2979dc34
JJ
5507 }
5508 break;
fd2f0033
TT
5509 case OPTION_DWARF_DEPTH:
5510 {
5511 char *cp;
5512
5513 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5514 }
5515 break;
5516 case OPTION_DWARF_START:
5517 {
5518 char *cp;
5519
5520 dwarf_start_die = strtoul (optarg, & cp, 0);
5521 }
5522 break;
4723351a 5523 case OPTION_DWARF_CHECK:
015dc7e1 5524 dwarf_check = true;
4723351a 5525 break;
7d9813f1 5526 case OPTION_CTF_DUMP:
015dc7e1 5527 do_ctf = true;
6431e409 5528 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5529 break;
5530 case OPTION_CTF_SYMBOLS:
df16e041 5531 free (dump_ctf_symtab_name);
7d9813f1
NA
5532 dump_ctf_symtab_name = strdup (optarg);
5533 break;
5534 case OPTION_CTF_STRINGS:
df16e041 5535 free (dump_ctf_strtab_name);
7d9813f1
NA
5536 dump_ctf_strtab_name = strdup (optarg);
5537 break;
5538 case OPTION_CTF_PARENT:
df16e041 5539 free (dump_ctf_parent_name);
7d9813f1
NA
5540 dump_ctf_parent_name = strdup (optarg);
5541 break;
2c610e4b 5542 case OPTION_DYN_SYMS:
015dc7e1 5543 do_dyn_syms = true;
2c610e4b 5544 break;
0f03783c 5545 case OPTION_LTO_SYMS:
015dc7e1 5546 do_lto_syms = true;
0f03783c 5547 break;
252b5132
RH
5548#ifdef SUPPORT_DISASSEMBLY
5549 case 'i':
6431e409 5550 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5551 break;
252b5132
RH
5552#endif
5553 case 'v':
5554 print_version (program_name);
5555 break;
5556 case 'V':
015dc7e1 5557 do_version = true;
252b5132 5558 break;
d974e256 5559 case 'W':
015dc7e1 5560 do_wide = true;
d974e256 5561 break;
0942c7ab 5562 case 'T':
015dc7e1 5563 do_not_show_symbol_truncation = true;
0942c7ab 5564 break;
79bc120c 5565 case 'C':
015dc7e1 5566 do_demangle = true;
79bc120c
NC
5567 if (optarg != NULL)
5568 {
5569 enum demangling_styles style;
5570
5571 style = cplus_demangle_name_to_style (optarg);
5572 if (style == unknown_demangling)
5573 error (_("unknown demangling style `%s'"), optarg);
5574
5575 cplus_demangle_set_style (style);
5576 }
5577 break;
5578 case OPTION_NO_DEMANGLING:
015dc7e1 5579 do_demangle = false;
79bc120c
NC
5580 break;
5581 case OPTION_RECURSE_LIMIT:
5582 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5583 break;
5584 case OPTION_NO_RECURSE_LIMIT:
5585 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5586 break;
5587 case OPTION_WITH_SYMBOL_VERSIONS:
5588 /* Ignored for backward compatibility. */
5589 break;
b9e920ec 5590
b3aa80b4
NC
5591 case 'U':
5592 if (optarg == NULL)
5593 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5594 else if (streq (optarg, "default") || streq (optarg, "d"))
5595 unicode_display = unicode_default;
5596 else if (streq (optarg, "locale") || streq (optarg, "l"))
5597 unicode_display = unicode_locale;
5598 else if (streq (optarg, "escape") || streq (optarg, "e"))
5599 unicode_display = unicode_escape;
5600 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5601 unicode_display = unicode_invalid;
5602 else if (streq (optarg, "hex") || streq (optarg, "x"))
5603 unicode_display = unicode_hex;
5604 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5605 unicode_display = unicode_highlight;
5606 else
5607 error (_("invalid argument to -U/--unicode: %s"), optarg);
5608 break;
5609
047c3dbf
NL
5610 case OPTION_SYM_BASE:
5611 sym_base = 0;
5612 if (optarg != NULL)
5613 {
5614 sym_base = strtoul (optarg, NULL, 0);
5615 switch (sym_base)
5616 {
5617 case 0:
5618 case 8:
5619 case 10:
5620 case 16:
5621 break;
5622
5623 default:
5624 sym_base = 0;
5625 break;
5626 }
5627 }
5628 break;
5629
252b5132 5630 default:
252b5132
RH
5631 /* xgettext:c-format */
5632 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5633 /* Fall through. */
252b5132 5634 case '?':
92f01d61 5635 usage (stderr);
252b5132
RH
5636 }
5637 }
5638
4d6ed7c8 5639 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5640 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5641 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5642 && !do_section_groups && !do_archive_index
0f03783c 5643 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5644 {
5645 if (do_checks)
5646 {
015dc7e1
AM
5647 check_all = true;
5648 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5649 do_segments = do_header = do_dump = do_version = true;
5650 do_histogram = do_debugging = do_arch = do_notes = true;
5651 do_section_groups = do_archive_index = do_dyn_syms = true;
5652 do_lto_syms = true;
1b513401
NC
5653 }
5654 else
5655 usage (stderr);
5656 }
252b5132
RH
5657}
5658
5659static const char *
d3ba0551 5660get_elf_class (unsigned int elf_class)
252b5132 5661{
b34976b6 5662 static char buff[32];
103f02d3 5663
252b5132
RH
5664 switch (elf_class)
5665 {
5666 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5667 case ELFCLASS32: return "ELF32";
5668 case ELFCLASS64: return "ELF64";
ab5e7794 5669 default:
e9e44622 5670 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5671 return buff;
252b5132
RH
5672 }
5673}
5674
5675static const char *
d3ba0551 5676get_data_encoding (unsigned int encoding)
252b5132 5677{
b34976b6 5678 static char buff[32];
103f02d3 5679
252b5132
RH
5680 switch (encoding)
5681 {
5682 case ELFDATANONE: return _("none");
33c63f9d
CM
5683 case ELFDATA2LSB: return _("2's complement, little endian");
5684 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5685 default:
e9e44622 5686 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5687 return buff;
252b5132
RH
5688 }
5689}
5690
521f7268
NC
5691static bool
5692check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
5693{
5694 if (header->e_ident[EI_MAG0] == ELFMAG0
5695 && header->e_ident[EI_MAG1] == ELFMAG1
5696 && header->e_ident[EI_MAG2] == ELFMAG2
5697 && header->e_ident[EI_MAG3] == ELFMAG3)
5698 return true;
5699
5700 /* Some compilers produce object files that are not in the ELF file format.
5701 As an aid to users of readelf, try to identify these cases and suggest
5702 alternative tools.
5703
5704 FIXME: It is not clear if all four bytes are used as constant magic
5705 valus by all compilers. It may be necessary to recode this function if
5706 different tools use different length sequences. */
5707
5708 static struct
5709 {
5710 unsigned char magic[4];
5711 const char * obj_message;
5712 const char * ar_message;
5713 }
5714 known_magic[] =
5715 {
5716 { { 'B', 'C', 0xc0, 0xde },
5717 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
5718 N_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")
5719 },
5720 { { 'g', 'o', ' ', 'o' },
5721 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
5722 NULL
5723 }
5724 };
5725 int i;
5726
5727 for (i = ARRAY_SIZE (known_magic); i--;)
5728 {
5729 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
5730 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
5731 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
5732 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
5733 {
5734 /* Some compiler's analyzer tools do not handle archives,
5735 so we provide two different kinds of error message. */
5736 if (filedata->archive_file_size > 0
5737 && known_magic[i].ar_message != NULL)
b3ea2010 5738 error ("%s", known_magic[i].ar_message);
521f7268 5739 else
b3ea2010 5740 error ("%s", known_magic[i].obj_message);
521f7268
NC
5741 return false;
5742 }
5743 }
5744
5745 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
5746 return false;
5747}
5748
dda8d76d 5749/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5750
015dc7e1 5751static bool
dda8d76d 5752process_file_header (Filedata * filedata)
252b5132 5753{
dda8d76d
NC
5754 Elf_Internal_Ehdr * header = & filedata->file_header;
5755
521f7268
NC
5756 if (! check_magic_number (filedata, header))
5757 return false;
252b5132 5758
ca0e11aa
NC
5759 if (! filedata->is_separate)
5760 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5761
252b5132
RH
5762 if (do_header)
5763 {
32ec8896 5764 unsigned i;
252b5132 5765
ca0e11aa
NC
5766 if (filedata->is_separate)
5767 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5768 else
5769 printf (_("ELF Header:\n"));
252b5132 5770 printf (_(" Magic: "));
b34976b6 5771 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5772 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5773 printf ("\n");
5774 printf (_(" Class: %s\n"),
dda8d76d 5775 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5776 printf (_(" Data: %s\n"),
dda8d76d 5777 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5778 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5779 header->e_ident[EI_VERSION],
5780 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5781 ? _(" (current)")
dda8d76d 5782 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5783 ? _(" <unknown>")
789be9f7 5784 : "")));
252b5132 5785 printf (_(" OS/ABI: %s\n"),
dda8d76d 5786 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5787 printf (_(" ABI Version: %d\n"),
dda8d76d 5788 header->e_ident[EI_ABIVERSION]);
252b5132 5789 printf (_(" Type: %s\n"),
93df3340 5790 get_file_type (filedata));
252b5132 5791 printf (_(" Machine: %s\n"),
dda8d76d 5792 get_machine_name (header->e_machine));
252b5132 5793 printf (_(" Version: 0x%lx\n"),
e8a64888 5794 header->e_version);
76da6bbe 5795
f7a99963 5796 printf (_(" Entry point address: "));
e8a64888 5797 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5798 printf (_("\n Start of program headers: "));
e8a64888 5799 print_vma (header->e_phoff, DEC);
f7a99963 5800 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5801 print_vma (header->e_shoff, DEC);
f7a99963 5802 printf (_(" (bytes into file)\n"));
76da6bbe 5803
252b5132 5804 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5805 header->e_flags,
dda8d76d 5806 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5807 printf (_(" Size of this header: %u (bytes)\n"),
5808 header->e_ehsize);
5809 printf (_(" Size of program headers: %u (bytes)\n"),
5810 header->e_phentsize);
5811 printf (_(" Number of program headers: %u"),
5812 header->e_phnum);
dda8d76d
NC
5813 if (filedata->section_headers != NULL
5814 && header->e_phnum == PN_XNUM
5815 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5816 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5817 putc ('\n', stdout);
e8a64888
AM
5818 printf (_(" Size of section headers: %u (bytes)\n"),
5819 header->e_shentsize);
5820 printf (_(" Number of section headers: %u"),
5821 header->e_shnum);
dda8d76d 5822 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5823 {
5824 header->e_shnum = filedata->section_headers[0].sh_size;
5825 printf (" (%u)", header->e_shnum);
5826 }
560f3c1c 5827 putc ('\n', stdout);
e8a64888
AM
5828 printf (_(" Section header string table index: %u"),
5829 header->e_shstrndx);
dda8d76d
NC
5830 if (filedata->section_headers != NULL
5831 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5832 {
5833 header->e_shstrndx = filedata->section_headers[0].sh_link;
5834 printf (" (%u)", header->e_shstrndx);
5835 }
5836 if (header->e_shstrndx != SHN_UNDEF
5837 && header->e_shstrndx >= header->e_shnum)
5838 {
5839 header->e_shstrndx = SHN_UNDEF;
5840 printf (_(" <corrupt: out of range>"));
5841 }
560f3c1c
AM
5842 putc ('\n', stdout);
5843 }
5844
dda8d76d 5845 if (filedata->section_headers != NULL)
560f3c1c 5846 {
dda8d76d
NC
5847 if (header->e_phnum == PN_XNUM
5848 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5849 {
5850 /* Throw away any cached read of PN_XNUM headers. */
5851 free (filedata->program_headers);
5852 filedata->program_headers = NULL;
5853 header->e_phnum = filedata->section_headers[0].sh_info;
5854 }
dda8d76d
NC
5855 if (header->e_shnum == SHN_UNDEF)
5856 header->e_shnum = filedata->section_headers[0].sh_size;
5857 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5858 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5859 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5860 header->e_shstrndx = SHN_UNDEF;
252b5132 5861 }
103f02d3 5862
015dc7e1 5863 return true;
9ea033b2
NC
5864}
5865
dda8d76d
NC
5866/* Read in the program headers from FILEDATA and store them in PHEADERS.
5867 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5868
015dc7e1 5869static bool
dda8d76d 5870get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5871{
2cf0635d
NC
5872 Elf32_External_Phdr * phdrs;
5873 Elf32_External_Phdr * external;
5874 Elf_Internal_Phdr * internal;
b34976b6 5875 unsigned int i;
dda8d76d
NC
5876 unsigned int size = filedata->file_header.e_phentsize;
5877 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5878
5879 /* PR binutils/17531: Cope with unexpected section header sizes. */
5880 if (size == 0 || num == 0)
015dc7e1 5881 return false;
e0a31db1
NC
5882 if (size < sizeof * phdrs)
5883 {
5884 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5885 return false;
e0a31db1
NC
5886 }
5887 if (size > sizeof * phdrs)
5888 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5889
dda8d76d 5890 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5891 size, num, _("program headers"));
5892 if (phdrs == NULL)
015dc7e1 5893 return false;
9ea033b2 5894
91d6fa6a 5895 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5896 i < filedata->file_header.e_phnum;
b34976b6 5897 i++, internal++, external++)
252b5132 5898 {
9ea033b2
NC
5899 internal->p_type = BYTE_GET (external->p_type);
5900 internal->p_offset = BYTE_GET (external->p_offset);
5901 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5902 internal->p_paddr = BYTE_GET (external->p_paddr);
5903 internal->p_filesz = BYTE_GET (external->p_filesz);
5904 internal->p_memsz = BYTE_GET (external->p_memsz);
5905 internal->p_flags = BYTE_GET (external->p_flags);
5906 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5907 }
5908
9ea033b2 5909 free (phdrs);
015dc7e1 5910 return true;
252b5132
RH
5911}
5912
dda8d76d
NC
5913/* Read in the program headers from FILEDATA and store them in PHEADERS.
5914 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5915
015dc7e1 5916static bool
dda8d76d 5917get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5918{
2cf0635d
NC
5919 Elf64_External_Phdr * phdrs;
5920 Elf64_External_Phdr * external;
5921 Elf_Internal_Phdr * internal;
b34976b6 5922 unsigned int i;
dda8d76d
NC
5923 unsigned int size = filedata->file_header.e_phentsize;
5924 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5925
5926 /* PR binutils/17531: Cope with unexpected section header sizes. */
5927 if (size == 0 || num == 0)
015dc7e1 5928 return false;
e0a31db1
NC
5929 if (size < sizeof * phdrs)
5930 {
5931 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5932 return false;
e0a31db1
NC
5933 }
5934 if (size > sizeof * phdrs)
5935 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5936
dda8d76d 5937 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5938 size, num, _("program headers"));
a6e9f9df 5939 if (!phdrs)
015dc7e1 5940 return false;
9ea033b2 5941
91d6fa6a 5942 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5943 i < filedata->file_header.e_phnum;
b34976b6 5944 i++, internal++, external++)
9ea033b2
NC
5945 {
5946 internal->p_type = BYTE_GET (external->p_type);
5947 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5948 internal->p_offset = BYTE_GET (external->p_offset);
5949 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5950 internal->p_paddr = BYTE_GET (external->p_paddr);
5951 internal->p_filesz = BYTE_GET (external->p_filesz);
5952 internal->p_memsz = BYTE_GET (external->p_memsz);
5953 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5954 }
5955
5956 free (phdrs);
015dc7e1 5957 return true;
9ea033b2 5958}
252b5132 5959
32ec8896 5960/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5961
015dc7e1 5962static bool
dda8d76d 5963get_program_headers (Filedata * filedata)
d93f0186 5964{
2cf0635d 5965 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5966
5967 /* Check cache of prior read. */
dda8d76d 5968 if (filedata->program_headers != NULL)
015dc7e1 5969 return true;
d93f0186 5970
82156ab7
NC
5971 /* Be kind to memory checkers by looking for
5972 e_phnum values which we know must be invalid. */
dda8d76d 5973 if (filedata->file_header.e_phnum
82156ab7 5974 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5975 >= filedata->file_size)
82156ab7
NC
5976 {
5977 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5978 filedata->file_header.e_phnum);
015dc7e1 5979 return false;
82156ab7 5980 }
d93f0186 5981
dda8d76d 5982 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5983 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5984 if (phdrs == NULL)
5985 {
8b73c356 5986 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5987 filedata->file_header.e_phnum);
015dc7e1 5988 return false;
d93f0186
NC
5989 }
5990
5991 if (is_32bit_elf
dda8d76d
NC
5992 ? get_32bit_program_headers (filedata, phdrs)
5993 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5994 {
dda8d76d 5995 filedata->program_headers = phdrs;
015dc7e1 5996 return true;
d93f0186
NC
5997 }
5998
5999 free (phdrs);
015dc7e1 6000 return false;
d93f0186
NC
6001}
6002
93df3340 6003/* Print program header info and locate dynamic section. */
2f62977e 6004
93df3340 6005static void
dda8d76d 6006process_program_headers (Filedata * filedata)
252b5132 6007{
2cf0635d 6008 Elf_Internal_Phdr * segment;
b34976b6 6009 unsigned int i;
1a9ccd70 6010 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6011
dda8d76d 6012 if (filedata->file_header.e_phnum == 0)
252b5132 6013 {
82f2dbf7 6014 /* PR binutils/12467. */
dda8d76d 6015 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6016 warn (_("possibly corrupt ELF header - it has a non-zero program"
6017 " header offset, but no program headers\n"));
82f2dbf7 6018 else if (do_segments)
ca0e11aa
NC
6019 {
6020 if (filedata->is_separate)
6021 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6022 filedata->file_name);
6023 else
6024 printf (_("\nThere are no program headers in this file.\n"));
6025 }
93df3340 6026 goto no_headers;
252b5132
RH
6027 }
6028
6029 if (do_segments && !do_header)
6030 {
ca0e11aa
NC
6031 if (filedata->is_separate)
6032 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6033 filedata->file_name, get_file_type (filedata));
ca0e11aa 6034 else
93df3340 6035 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6036 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6037 filedata->file_header.e_entry);
b8281767
AM
6038 printf (ngettext ("There is %d program header,"
6039 " starting at offset %" PRIu64 "\n",
6040 "There are %d program headers,"
6041 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6042 filedata->file_header.e_phnum),
6043 filedata->file_header.e_phnum,
625d49fc 6044 filedata->file_header.e_phoff);
252b5132
RH
6045 }
6046
dda8d76d 6047 if (! get_program_headers (filedata))
93df3340 6048 goto no_headers;
103f02d3 6049
252b5132
RH
6050 if (do_segments)
6051 {
dda8d76d 6052 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6053 printf (_("\nProgram Headers:\n"));
6054 else
6055 printf (_("\nProgram Headers:\n"));
76da6bbe 6056
f7a99963
NC
6057 if (is_32bit_elf)
6058 printf
6059 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6060 else if (do_wide)
6061 printf
6062 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6063 else
6064 {
6065 printf
6066 (_(" Type Offset VirtAddr PhysAddr\n"));
6067 printf
6068 (_(" FileSiz MemSiz Flags Align\n"));
6069 }
252b5132
RH
6070 }
6071
93df3340 6072 unsigned long dynamic_addr = 0;
be7d229a 6073 uint64_t dynamic_size = 0;
dda8d76d
NC
6074 for (i = 0, segment = filedata->program_headers;
6075 i < filedata->file_header.e_phnum;
b34976b6 6076 i++, segment++)
252b5132
RH
6077 {
6078 if (do_segments)
6079 {
dda8d76d 6080 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6081
6082 if (is_32bit_elf)
6083 {
6084 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6085 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6086 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6087 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6088 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6089 printf ("%c%c%c ",
6090 (segment->p_flags & PF_R ? 'R' : ' '),
6091 (segment->p_flags & PF_W ? 'W' : ' '),
6092 (segment->p_flags & PF_X ? 'E' : ' '));
6093 printf ("%#lx", (unsigned long) segment->p_align);
6094 }
d974e256
JJ
6095 else if (do_wide)
6096 {
6097 if ((unsigned long) segment->p_offset == segment->p_offset)
6098 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6099 else
6100 {
6101 print_vma (segment->p_offset, FULL_HEX);
6102 putchar (' ');
6103 }
6104
6105 print_vma (segment->p_vaddr, FULL_HEX);
6106 putchar (' ');
6107 print_vma (segment->p_paddr, FULL_HEX);
6108 putchar (' ');
6109
6110 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6111 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6112 else
6113 {
6114 print_vma (segment->p_filesz, FULL_HEX);
6115 putchar (' ');
6116 }
6117
6118 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6119 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6120 else
6121 {
f48e6c45 6122 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6123 }
6124
6125 printf (" %c%c%c ",
6126 (segment->p_flags & PF_R ? 'R' : ' '),
6127 (segment->p_flags & PF_W ? 'W' : ' '),
6128 (segment->p_flags & PF_X ? 'E' : ' '));
6129
6130 if ((unsigned long) segment->p_align == segment->p_align)
6131 printf ("%#lx", (unsigned long) segment->p_align);
6132 else
6133 {
6134 print_vma (segment->p_align, PREFIX_HEX);
6135 }
6136 }
f7a99963
NC
6137 else
6138 {
6139 print_vma (segment->p_offset, FULL_HEX);
6140 putchar (' ');
6141 print_vma (segment->p_vaddr, FULL_HEX);
6142 putchar (' ');
6143 print_vma (segment->p_paddr, FULL_HEX);
6144 printf ("\n ");
6145 print_vma (segment->p_filesz, FULL_HEX);
6146 putchar (' ');
6147 print_vma (segment->p_memsz, FULL_HEX);
6148 printf (" %c%c%c ",
6149 (segment->p_flags & PF_R ? 'R' : ' '),
6150 (segment->p_flags & PF_W ? 'W' : ' '),
6151 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6152 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6153 }
252b5132 6154
1a9ccd70
NC
6155 putc ('\n', stdout);
6156 }
f54498b4 6157
252b5132
RH
6158 switch (segment->p_type)
6159 {
1a9ccd70 6160 case PT_LOAD:
502d895c
NC
6161#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6162 required by the ELF standard, several programs, including the Linux
6163 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6164 if (previous_load
6165 && previous_load->p_vaddr > segment->p_vaddr)
6166 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6167#endif
1a9ccd70
NC
6168 if (segment->p_memsz < segment->p_filesz)
6169 error (_("the segment's file size is larger than its memory size\n"));
6170 previous_load = segment;
6171 break;
6172
6173 case PT_PHDR:
6174 /* PR 20815 - Verify that the program header is loaded into memory. */
6175 if (i > 0 && previous_load != NULL)
6176 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6177 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6178 {
6179 unsigned int j;
6180
dda8d76d 6181 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6182 {
6183 Elf_Internal_Phdr *load = filedata->program_headers + j;
6184 if (load->p_type == PT_LOAD
6185 && load->p_offset <= segment->p_offset
6186 && (load->p_offset + load->p_filesz
6187 >= segment->p_offset + segment->p_filesz)
6188 && load->p_vaddr <= segment->p_vaddr
6189 && (load->p_vaddr + load->p_filesz
6190 >= segment->p_vaddr + segment->p_filesz))
6191 break;
6192 }
dda8d76d 6193 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6194 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6195 }
6196 break;
6197
252b5132 6198 case PT_DYNAMIC:
93df3340 6199 if (dynamic_addr)
252b5132
RH
6200 error (_("more than one dynamic segment\n"));
6201
20737c13
AM
6202 /* By default, assume that the .dynamic section is the first
6203 section in the DYNAMIC segment. */
93df3340
AM
6204 dynamic_addr = segment->p_offset;
6205 dynamic_size = segment->p_filesz;
20737c13 6206
b2d38a17
NC
6207 /* Try to locate the .dynamic section. If there is
6208 a section header table, we can easily locate it. */
dda8d76d 6209 if (filedata->section_headers != NULL)
b2d38a17 6210 {
2cf0635d 6211 Elf_Internal_Shdr * sec;
b2d38a17 6212
dda8d76d 6213 sec = find_section (filedata, ".dynamic");
89fac5e3 6214 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6215 {
93df3340
AM
6216 /* A corresponding .dynamic section is expected, but on
6217 IA-64/OpenVMS it is OK for it to be missing. */
6218 if (!is_ia64_vms (filedata))
6219 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6220 break;
6221 }
6222
42bb2e33 6223 if (sec->sh_type == SHT_NOBITS)
20737c13 6224 {
93df3340
AM
6225 dynamic_addr = 0;
6226 dynamic_size = 0;
20737c13
AM
6227 break;
6228 }
42bb2e33 6229
93df3340
AM
6230 dynamic_addr = sec->sh_offset;
6231 dynamic_size = sec->sh_size;
b2d38a17 6232
8ac10c5b
L
6233 /* The PT_DYNAMIC segment, which is used by the run-time
6234 loader, should exactly match the .dynamic section. */
6235 if (do_checks
93df3340
AM
6236 && (dynamic_addr != segment->p_offset
6237 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6238 warn (_("\
6239the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6240 }
39e224f6
MW
6241
6242 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6243 segment. Check this after matching against the section headers
6244 so we don't warn on debuginfo file (which have NOBITS .dynamic
6245 sections). */
93df3340
AM
6246 if (dynamic_addr > filedata->file_size
6247 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6248 {
6249 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6250 dynamic_addr = 0;
6251 dynamic_size = 0;
39e224f6 6252 }
252b5132
RH
6253 break;
6254
6255 case PT_INTERP:
13acb58d
AM
6256 if (segment->p_offset >= filedata->file_size
6257 || segment->p_filesz > filedata->file_size - segment->p_offset
6258 || segment->p_filesz - 1 >= (size_t) -2
6259 || fseek (filedata->handle,
6260 filedata->archive_file_offset + (long) segment->p_offset,
6261 SEEK_SET))
252b5132
RH
6262 error (_("Unable to find program interpreter name\n"));
6263 else
6264 {
13acb58d
AM
6265 size_t len = segment->p_filesz;
6266 free (filedata->program_interpreter);
6267 filedata->program_interpreter = xmalloc (len + 1);
6268 len = fread (filedata->program_interpreter, 1, len,
6269 filedata->handle);
6270 filedata->program_interpreter[len] = 0;
252b5132
RH
6271
6272 if (do_segments)
f54498b4 6273 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6274 filedata->program_interpreter);
252b5132
RH
6275 }
6276 break;
6277 }
252b5132
RH
6278 }
6279
dda8d76d
NC
6280 if (do_segments
6281 && filedata->section_headers != NULL
6282 && filedata->string_table != NULL)
252b5132
RH
6283 {
6284 printf (_("\n Section to Segment mapping:\n"));
6285 printf (_(" Segment Sections...\n"));
6286
dda8d76d 6287 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6288 {
9ad5cbcf 6289 unsigned int j;
2cf0635d 6290 Elf_Internal_Shdr * section;
252b5132 6291
dda8d76d
NC
6292 segment = filedata->program_headers + i;
6293 section = filedata->section_headers + 1;
252b5132
RH
6294
6295 printf (" %2.2d ", i);
6296
dda8d76d 6297 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6298 {
f4638467
AM
6299 if (!ELF_TBSS_SPECIAL (section, segment)
6300 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6301 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6302 }
6303
6304 putc ('\n',stdout);
6305 }
6306 }
6307
93df3340
AM
6308 filedata->dynamic_addr = dynamic_addr;
6309 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6310 return;
6311
6312 no_headers:
6313 filedata->dynamic_addr = 0;
6314 filedata->dynamic_size = 1;
252b5132
RH
6315}
6316
6317
d93f0186
NC
6318/* Find the file offset corresponding to VMA by using the program headers. */
6319
6320static long
625d49fc 6321offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6322{
2cf0635d 6323 Elf_Internal_Phdr * seg;
d93f0186 6324
dda8d76d 6325 if (! get_program_headers (filedata))
d93f0186
NC
6326 {
6327 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6328 return (long) vma;
6329 }
6330
dda8d76d
NC
6331 for (seg = filedata->program_headers;
6332 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6333 ++seg)
6334 {
6335 if (seg->p_type != PT_LOAD)
6336 continue;
6337
6338 if (vma >= (seg->p_vaddr & -seg->p_align)
6339 && vma + size <= seg->p_vaddr + seg->p_filesz)
6340 return vma - seg->p_vaddr + seg->p_offset;
6341 }
6342
6343 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6344 (unsigned long) vma);
d93f0186
NC
6345 return (long) vma;
6346}
6347
6348
dda8d76d
NC
6349/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6350 If PROBE is true, this is just a probe and we do not generate any error
6351 messages if the load fails. */
049b0c3a 6352
015dc7e1
AM
6353static bool
6354get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6355{
2cf0635d
NC
6356 Elf32_External_Shdr * shdrs;
6357 Elf_Internal_Shdr * internal;
dda8d76d
NC
6358 unsigned int i;
6359 unsigned int size = filedata->file_header.e_shentsize;
6360 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6361
6362 /* PR binutils/17531: Cope with unexpected section header sizes. */
6363 if (size == 0 || num == 0)
015dc7e1 6364 return false;
049b0c3a
NC
6365 if (size < sizeof * shdrs)
6366 {
6367 if (! probe)
6368 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6369 return false;
049b0c3a
NC
6370 }
6371 if (!probe && size > sizeof * shdrs)
6372 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6373
dda8d76d 6374 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6375 size, num,
6376 probe ? NULL : _("section headers"));
6377 if (shdrs == NULL)
015dc7e1 6378 return false;
252b5132 6379
dda8d76d
NC
6380 filedata->section_headers = (Elf_Internal_Shdr *)
6381 cmalloc (num, sizeof (Elf_Internal_Shdr));
6382 if (filedata->section_headers == NULL)
252b5132 6383 {
049b0c3a 6384 if (!probe)
8b73c356 6385 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6386 free (shdrs);
015dc7e1 6387 return false;
252b5132
RH
6388 }
6389
dda8d76d 6390 for (i = 0, internal = filedata->section_headers;
560f3c1c 6391 i < num;
b34976b6 6392 i++, internal++)
252b5132
RH
6393 {
6394 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6395 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6396 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6397 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6398 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6399 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6400 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6401 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6402 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6403 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6404 if (!probe && internal->sh_link > num)
6405 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6406 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6407 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6408 }
6409
6410 free (shdrs);
015dc7e1 6411 return true;
252b5132
RH
6412}
6413
dda8d76d
NC
6414/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6415
015dc7e1
AM
6416static bool
6417get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6418{
dda8d76d
NC
6419 Elf64_External_Shdr * shdrs;
6420 Elf_Internal_Shdr * internal;
6421 unsigned int i;
6422 unsigned int size = filedata->file_header.e_shentsize;
6423 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6424
6425 /* PR binutils/17531: Cope with unexpected section header sizes. */
6426 if (size == 0 || num == 0)
015dc7e1 6427 return false;
dda8d76d 6428
049b0c3a
NC
6429 if (size < sizeof * shdrs)
6430 {
6431 if (! probe)
6432 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6433 return false;
049b0c3a 6434 }
dda8d76d 6435
049b0c3a
NC
6436 if (! probe && size > sizeof * shdrs)
6437 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6438
dda8d76d
NC
6439 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6440 filedata->file_header.e_shoff,
049b0c3a
NC
6441 size, num,
6442 probe ? NULL : _("section headers"));
6443 if (shdrs == NULL)
015dc7e1 6444 return false;
9ea033b2 6445
dda8d76d
NC
6446 filedata->section_headers = (Elf_Internal_Shdr *)
6447 cmalloc (num, sizeof (Elf_Internal_Shdr));
6448 if (filedata->section_headers == NULL)
9ea033b2 6449 {
049b0c3a 6450 if (! probe)
8b73c356 6451 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6452 free (shdrs);
015dc7e1 6453 return false;
9ea033b2
NC
6454 }
6455
dda8d76d 6456 for (i = 0, internal = filedata->section_headers;
560f3c1c 6457 i < num;
b34976b6 6458 i++, internal++)
9ea033b2
NC
6459 {
6460 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6461 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6462 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6463 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6464 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6465 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6466 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6467 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6468 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6469 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6470 if (!probe && internal->sh_link > num)
6471 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6472 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6473 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6474 }
6475
6476 free (shdrs);
015dc7e1 6477 return true;
9ea033b2
NC
6478}
6479
4de91c10
AM
6480static bool
6481get_section_headers (Filedata *filedata, bool probe)
6482{
6483 if (filedata->section_headers != NULL)
6484 return true;
6485
4de91c10
AM
6486 if (is_32bit_elf)
6487 return get_32bit_section_headers (filedata, probe);
6488 else
6489 return get_64bit_section_headers (filedata, probe);
6490}
6491
252b5132 6492static Elf_Internal_Sym *
dda8d76d
NC
6493get_32bit_elf_symbols (Filedata * filedata,
6494 Elf_Internal_Shdr * section,
6495 unsigned long * num_syms_return)
252b5132 6496{
ba5cdace 6497 unsigned long number = 0;
dd24e3da 6498 Elf32_External_Sym * esyms = NULL;
ba5cdace 6499 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6500 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6501 Elf_Internal_Sym * psym;
b34976b6 6502 unsigned int j;
e3d39609 6503 elf_section_list * entry;
252b5132 6504
c9c1d674
EG
6505 if (section->sh_size == 0)
6506 {
6507 if (num_syms_return != NULL)
6508 * num_syms_return = 0;
6509 return NULL;
6510 }
6511
dd24e3da 6512 /* Run some sanity checks first. */
c9c1d674 6513 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6514 {
c9c1d674 6515 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6516 printable_section_name (filedata, section),
6517 (unsigned long) section->sh_entsize);
ba5cdace 6518 goto exit_point;
dd24e3da
NC
6519 }
6520
dda8d76d 6521 if (section->sh_size > filedata->file_size)
f54498b4
NC
6522 {
6523 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6524 printable_section_name (filedata, section),
6525 (unsigned long) section->sh_size);
f54498b4
NC
6526 goto exit_point;
6527 }
6528
dd24e3da
NC
6529 number = section->sh_size / section->sh_entsize;
6530
6531 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6532 {
c9c1d674 6533 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6534 (unsigned long) section->sh_size,
dda8d76d 6535 printable_section_name (filedata, section),
8066deb1 6536 (unsigned long) section->sh_entsize);
ba5cdace 6537 goto exit_point;
dd24e3da
NC
6538 }
6539
dda8d76d 6540 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6541 section->sh_size, _("symbols"));
dd24e3da 6542 if (esyms == NULL)
ba5cdace 6543 goto exit_point;
252b5132 6544
e3d39609 6545 shndx = NULL;
978c4450 6546 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6547 {
6548 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6549 continue;
6550
6551 if (shndx != NULL)
6552 {
6553 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6554 free (shndx);
6555 }
6556
6557 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6558 entry->hdr->sh_offset,
6559 1, entry->hdr->sh_size,
6560 _("symbol table section indices"));
6561 if (shndx == NULL)
6562 goto exit_point;
6563
6564 /* PR17531: file: heap-buffer-overflow */
6565 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6566 {
6567 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6568 printable_section_name (filedata, entry->hdr),
6569 (unsigned long) entry->hdr->sh_size,
6570 (unsigned long) section->sh_size);
6571 goto exit_point;
c9c1d674 6572 }
e3d39609 6573 }
9ad5cbcf 6574
3f5e193b 6575 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6576
6577 if (isyms == NULL)
6578 {
8b73c356
NC
6579 error (_("Out of memory reading %lu symbols\n"),
6580 (unsigned long) number);
dd24e3da 6581 goto exit_point;
252b5132
RH
6582 }
6583
dd24e3da 6584 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6585 {
6586 psym->st_name = BYTE_GET (esyms[j].st_name);
6587 psym->st_value = BYTE_GET (esyms[j].st_value);
6588 psym->st_size = BYTE_GET (esyms[j].st_size);
6589 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6590 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6591 psym->st_shndx
6592 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6593 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6594 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6595 psym->st_info = BYTE_GET (esyms[j].st_info);
6596 psym->st_other = BYTE_GET (esyms[j].st_other);
6597 }
6598
dd24e3da 6599 exit_point:
e3d39609
NC
6600 free (shndx);
6601 free (esyms);
252b5132 6602
ba5cdace
NC
6603 if (num_syms_return != NULL)
6604 * num_syms_return = isyms == NULL ? 0 : number;
6605
252b5132
RH
6606 return isyms;
6607}
6608
9ea033b2 6609static Elf_Internal_Sym *
dda8d76d
NC
6610get_64bit_elf_symbols (Filedata * filedata,
6611 Elf_Internal_Shdr * section,
6612 unsigned long * num_syms_return)
9ea033b2 6613{
ba5cdace
NC
6614 unsigned long number = 0;
6615 Elf64_External_Sym * esyms = NULL;
6616 Elf_External_Sym_Shndx * shndx = NULL;
6617 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6618 Elf_Internal_Sym * psym;
b34976b6 6619 unsigned int j;
e3d39609 6620 elf_section_list * entry;
9ea033b2 6621
c9c1d674
EG
6622 if (section->sh_size == 0)
6623 {
6624 if (num_syms_return != NULL)
6625 * num_syms_return = 0;
6626 return NULL;
6627 }
6628
dd24e3da 6629 /* Run some sanity checks first. */
c9c1d674 6630 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6631 {
c9c1d674 6632 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6633 printable_section_name (filedata, section),
8066deb1 6634 (unsigned long) section->sh_entsize);
ba5cdace 6635 goto exit_point;
dd24e3da
NC
6636 }
6637
dda8d76d 6638 if (section->sh_size > filedata->file_size)
f54498b4
NC
6639 {
6640 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6641 printable_section_name (filedata, section),
8066deb1 6642 (unsigned long) section->sh_size);
f54498b4
NC
6643 goto exit_point;
6644 }
6645
dd24e3da
NC
6646 number = section->sh_size / section->sh_entsize;
6647
6648 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6649 {
c9c1d674 6650 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6651 (unsigned long) section->sh_size,
dda8d76d 6652 printable_section_name (filedata, section),
8066deb1 6653 (unsigned long) section->sh_entsize);
ba5cdace 6654 goto exit_point;
dd24e3da
NC
6655 }
6656
dda8d76d 6657 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6658 section->sh_size, _("symbols"));
a6e9f9df 6659 if (!esyms)
ba5cdace 6660 goto exit_point;
9ea033b2 6661
e3d39609 6662 shndx = NULL;
978c4450 6663 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6664 {
6665 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6666 continue;
6667
6668 if (shndx != NULL)
6669 {
6670 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6671 free (shndx);
c9c1d674 6672 }
e3d39609
NC
6673
6674 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6675 entry->hdr->sh_offset,
6676 1, entry->hdr->sh_size,
6677 _("symbol table section indices"));
6678 if (shndx == NULL)
6679 goto exit_point;
6680
6681 /* PR17531: file: heap-buffer-overflow */
6682 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6683 {
6684 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6685 printable_section_name (filedata, entry->hdr),
6686 (unsigned long) entry->hdr->sh_size,
6687 (unsigned long) section->sh_size);
6688 goto exit_point;
6689 }
6690 }
9ad5cbcf 6691
3f5e193b 6692 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6693
6694 if (isyms == NULL)
6695 {
8b73c356
NC
6696 error (_("Out of memory reading %lu symbols\n"),
6697 (unsigned long) number);
ba5cdace 6698 goto exit_point;
9ea033b2
NC
6699 }
6700
ba5cdace 6701 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6702 {
6703 psym->st_name = BYTE_GET (esyms[j].st_name);
6704 psym->st_info = BYTE_GET (esyms[j].st_info);
6705 psym->st_other = BYTE_GET (esyms[j].st_other);
6706 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6707
4fbb74a6 6708 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6709 psym->st_shndx
6710 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6711 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6712 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6713
66543521
AM
6714 psym->st_value = BYTE_GET (esyms[j].st_value);
6715 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6716 }
6717
ba5cdace 6718 exit_point:
e3d39609
NC
6719 free (shndx);
6720 free (esyms);
ba5cdace
NC
6721
6722 if (num_syms_return != NULL)
6723 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6724
6725 return isyms;
6726}
6727
4de91c10
AM
6728static Elf_Internal_Sym *
6729get_elf_symbols (Filedata *filedata,
6730 Elf_Internal_Shdr *section,
6731 unsigned long *num_syms_return)
6732{
6733 if (is_32bit_elf)
6734 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6735 else
6736 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6737}
6738
d1133906 6739static const char *
625d49fc 6740get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6741{
5477e8a0 6742 static char buff[1024];
2cf0635d 6743 char * p = buff;
32ec8896
NC
6744 unsigned int field_size = is_32bit_elf ? 8 : 16;
6745 signed int sindex;
6746 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6747 uint64_t os_flags = 0;
6748 uint64_t proc_flags = 0;
6749 uint64_t unknown_flags = 0;
148b93f2 6750 static const struct
5477e8a0 6751 {
2cf0635d 6752 const char * str;
32ec8896 6753 unsigned int len;
5477e8a0
L
6754 }
6755 flags [] =
6756 {
cfcac11d
NC
6757 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6758 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6759 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6760 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6761 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6762 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6763 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6764 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6765 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6766 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6767 /* IA-64 specific. */
6768 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6769 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6770 /* IA-64 OpenVMS specific. */
6771 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6772 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6773 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6774 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6775 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6776 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6777 /* Generic. */
cfcac11d 6778 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6779 /* SPARC specific. */
77115a4a 6780 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6781 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6782 /* ARM specific. */
6783 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6784 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6785 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6786 /* GNU specific. */
6787 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6788 /* VLE specific. */
6789 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6790 /* GNU specific. */
6791 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6792 };
6793
6794 if (do_section_details)
6795 {
8d5ff12c
L
6796 sprintf (buff, "[%*.*lx]: ",
6797 field_size, field_size, (unsigned long) sh_flags);
6798 p += field_size + 4;
5477e8a0 6799 }
76da6bbe 6800
d1133906
NC
6801 while (sh_flags)
6802 {
625d49fc 6803 uint64_t flag;
d1133906
NC
6804
6805 flag = sh_flags & - sh_flags;
6806 sh_flags &= ~ flag;
76da6bbe 6807
5477e8a0 6808 if (do_section_details)
d1133906 6809 {
5477e8a0
L
6810 switch (flag)
6811 {
91d6fa6a
NC
6812 case SHF_WRITE: sindex = 0; break;
6813 case SHF_ALLOC: sindex = 1; break;
6814 case SHF_EXECINSTR: sindex = 2; break;
6815 case SHF_MERGE: sindex = 3; break;
6816 case SHF_STRINGS: sindex = 4; break;
6817 case SHF_INFO_LINK: sindex = 5; break;
6818 case SHF_LINK_ORDER: sindex = 6; break;
6819 case SHF_OS_NONCONFORMING: sindex = 7; break;
6820 case SHF_GROUP: sindex = 8; break;
6821 case SHF_TLS: sindex = 9; break;
18ae9cc1 6822 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6823 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6824
5477e8a0 6825 default:
91d6fa6a 6826 sindex = -1;
dda8d76d 6827 switch (filedata->file_header.e_machine)
148b93f2 6828 {
cfcac11d 6829 case EM_IA_64:
148b93f2 6830 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6831 sindex = 10;
148b93f2 6832 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6833 sindex = 11;
dda8d76d 6834 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6835 switch (flag)
6836 {
91d6fa6a
NC
6837 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6838 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6839 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6840 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6841 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6842 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6843 default: break;
6844 }
cfcac11d
NC
6845 break;
6846
caa83f8b 6847 case EM_386:
22abe556 6848 case EM_IAMCU:
caa83f8b 6849 case EM_X86_64:
7f502d6c 6850 case EM_L1OM:
7a9068fe 6851 case EM_K1OM:
cfcac11d
NC
6852 case EM_OLD_SPARCV9:
6853 case EM_SPARC32PLUS:
6854 case EM_SPARCV9:
6855 case EM_SPARC:
18ae9cc1 6856 if (flag == SHF_ORDERED)
91d6fa6a 6857 sindex = 19;
cfcac11d 6858 break;
ac4c9b04
MG
6859
6860 case EM_ARM:
6861 switch (flag)
6862 {
6863 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6864 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6865 case SHF_COMDEF: sindex = 23; break;
6866 default: break;
6867 }
6868 break;
83eef883
AFB
6869 case EM_PPC:
6870 if (flag == SHF_PPC_VLE)
6871 sindex = 25;
6872 break;
99fabbc9
JL
6873 default:
6874 break;
6875 }
ac4c9b04 6876
99fabbc9
JL
6877 switch (filedata->file_header.e_ident[EI_OSABI])
6878 {
6879 case ELFOSABI_GNU:
6880 case ELFOSABI_FREEBSD:
6881 if (flag == SHF_GNU_RETAIN)
6882 sindex = 26;
6883 /* Fall through */
6884 case ELFOSABI_NONE:
6885 if (flag == SHF_GNU_MBIND)
6886 /* We should not recognize SHF_GNU_MBIND for
6887 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6888 not set the EI_OSABI header byte. */
6889 sindex = 24;
6890 break;
cfcac11d
NC
6891 default:
6892 break;
148b93f2 6893 }
99fabbc9 6894 break;
5477e8a0
L
6895 }
6896
91d6fa6a 6897 if (sindex != -1)
5477e8a0 6898 {
8d5ff12c
L
6899 if (p != buff + field_size + 4)
6900 {
6901 if (size < (10 + 2))
bee0ee85
NC
6902 {
6903 warn (_("Internal error: not enough buffer room for section flag info"));
6904 return _("<unknown>");
6905 }
8d5ff12c
L
6906 size -= 2;
6907 *p++ = ',';
6908 *p++ = ' ';
6909 }
6910
91d6fa6a
NC
6911 size -= flags [sindex].len;
6912 p = stpcpy (p, flags [sindex].str);
5477e8a0 6913 }
3b22753a 6914 else if (flag & SHF_MASKOS)
8d5ff12c 6915 os_flags |= flag;
d1133906 6916 else if (flag & SHF_MASKPROC)
8d5ff12c 6917 proc_flags |= flag;
d1133906 6918 else
8d5ff12c 6919 unknown_flags |= flag;
5477e8a0
L
6920 }
6921 else
6922 {
6923 switch (flag)
6924 {
6925 case SHF_WRITE: *p = 'W'; break;
6926 case SHF_ALLOC: *p = 'A'; break;
6927 case SHF_EXECINSTR: *p = 'X'; break;
6928 case SHF_MERGE: *p = 'M'; break;
6929 case SHF_STRINGS: *p = 'S'; break;
6930 case SHF_INFO_LINK: *p = 'I'; break;
6931 case SHF_LINK_ORDER: *p = 'L'; break;
6932 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6933 case SHF_GROUP: *p = 'G'; break;
6934 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6935 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6936 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6937
6938 default:
dda8d76d
NC
6939 if ((filedata->file_header.e_machine == EM_X86_64
6940 || filedata->file_header.e_machine == EM_L1OM
6941 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6942 && flag == SHF_X86_64_LARGE)
6943 *p = 'l';
dda8d76d 6944 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6945 && flag == SHF_ARM_PURECODE)
99fabbc9 6946 *p = 'y';
dda8d76d 6947 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6948 && flag == SHF_PPC_VLE)
99fabbc9 6949 *p = 'v';
5477e8a0
L
6950 else if (flag & SHF_MASKOS)
6951 {
99fabbc9
JL
6952 switch (filedata->file_header.e_ident[EI_OSABI])
6953 {
6954 case ELFOSABI_GNU:
6955 case ELFOSABI_FREEBSD:
6956 if (flag == SHF_GNU_RETAIN)
6957 {
6958 *p = 'R';
6959 break;
6960 }
6961 /* Fall through */
6962 case ELFOSABI_NONE:
6963 if (flag == SHF_GNU_MBIND)
6964 {
6965 /* We should not recognize SHF_GNU_MBIND for
6966 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6967 not set the EI_OSABI header byte. */
6968 *p = 'D';
6969 break;
6970 }
6971 /* Fall through */
6972 default:
6973 *p = 'o';
6974 sh_flags &= ~SHF_MASKOS;
6975 break;
6976 }
5477e8a0
L
6977 }
6978 else if (flag & SHF_MASKPROC)
6979 {
6980 *p = 'p';
6981 sh_flags &= ~ SHF_MASKPROC;
6982 }
6983 else
6984 *p = 'x';
6985 break;
6986 }
6987 p++;
d1133906
NC
6988 }
6989 }
76da6bbe 6990
8d5ff12c
L
6991 if (do_section_details)
6992 {
6993 if (os_flags)
6994 {
6995 size -= 5 + field_size;
6996 if (p != buff + field_size + 4)
6997 {
6998 if (size < (2 + 1))
bee0ee85
NC
6999 {
7000 warn (_("Internal error: not enough buffer room for section flag info"));
7001 return _("<unknown>");
7002 }
8d5ff12c
L
7003 size -= 2;
7004 *p++ = ',';
7005 *p++ = ' ';
7006 }
7007 sprintf (p, "OS (%*.*lx)", field_size, field_size,
7008 (unsigned long) os_flags);
7009 p += 5 + field_size;
7010 }
7011 if (proc_flags)
7012 {
7013 size -= 7 + field_size;
7014 if (p != buff + field_size + 4)
7015 {
7016 if (size < (2 + 1))
bee0ee85
NC
7017 {
7018 warn (_("Internal error: not enough buffer room for section flag info"));
7019 return _("<unknown>");
7020 }
8d5ff12c
L
7021 size -= 2;
7022 *p++ = ',';
7023 *p++ = ' ';
7024 }
7025 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7026 (unsigned long) proc_flags);
7027 p += 7 + field_size;
7028 }
7029 if (unknown_flags)
7030 {
7031 size -= 10 + field_size;
7032 if (p != buff + field_size + 4)
7033 {
7034 if (size < (2 + 1))
bee0ee85
NC
7035 {
7036 warn (_("Internal error: not enough buffer room for section flag info"));
7037 return _("<unknown>");
7038 }
8d5ff12c
L
7039 size -= 2;
7040 *p++ = ',';
7041 *p++ = ' ';
7042 }
2b692964 7043 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
7044 (unsigned long) unknown_flags);
7045 p += 10 + field_size;
7046 }
7047 }
7048
e9e44622 7049 *p = '\0';
d1133906
NC
7050 return buff;
7051}
7052
5844b465 7053static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7054get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7055 uint64_t size)
77115a4a
L
7056{
7057 if (is_32bit_elf)
7058 {
7059 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7060
ebdf1ebf
NC
7061 if (size < sizeof (* echdr))
7062 {
7063 error (_("Compressed section is too small even for a compression header\n"));
7064 return 0;
7065 }
7066
77115a4a
L
7067 chdr->ch_type = BYTE_GET (echdr->ch_type);
7068 chdr->ch_size = BYTE_GET (echdr->ch_size);
7069 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7070 return sizeof (*echdr);
7071 }
7072 else
7073 {
7074 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7075
ebdf1ebf
NC
7076 if (size < sizeof (* echdr))
7077 {
7078 error (_("Compressed section is too small even for a compression header\n"));
7079 return 0;
7080 }
7081
77115a4a
L
7082 chdr->ch_type = BYTE_GET (echdr->ch_type);
7083 chdr->ch_size = BYTE_GET (echdr->ch_size);
7084 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7085 return sizeof (*echdr);
7086 }
7087}
7088
015dc7e1 7089static bool
dda8d76d 7090process_section_headers (Filedata * filedata)
252b5132 7091{
2cf0635d 7092 Elf_Internal_Shdr * section;
b34976b6 7093 unsigned int i;
252b5132 7094
dda8d76d 7095 if (filedata->file_header.e_shnum == 0)
252b5132 7096 {
82f2dbf7 7097 /* PR binutils/12467. */
dda8d76d 7098 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7099 {
7100 warn (_("possibly corrupt ELF file header - it has a non-zero"
7101 " section header offset, but no section headers\n"));
015dc7e1 7102 return false;
32ec8896 7103 }
82f2dbf7 7104 else if (do_sections)
252b5132
RH
7105 printf (_("\nThere are no sections in this file.\n"));
7106
015dc7e1 7107 return true;
252b5132
RH
7108 }
7109
7110 if (do_sections && !do_header)
ca0e11aa
NC
7111 {
7112 if (filedata->is_separate && process_links)
7113 printf (_("In linked file '%s': "), filedata->file_name);
7114 if (! filedata->is_separate || process_links)
7115 printf (ngettext ("There is %d section header, "
7116 "starting at offset 0x%lx:\n",
7117 "There are %d section headers, "
7118 "starting at offset 0x%lx:\n",
7119 filedata->file_header.e_shnum),
7120 filedata->file_header.e_shnum,
7121 (unsigned long) filedata->file_header.e_shoff);
7122 }
252b5132 7123
4de91c10
AM
7124 if (!get_section_headers (filedata, false))
7125 return false;
252b5132
RH
7126
7127 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7128 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7129 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7130 {
dda8d76d 7131 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7132
c256ffe7
JJ
7133 if (section->sh_size != 0)
7134 {
dda8d76d
NC
7135 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7136 1, section->sh_size,
7137 _("string table"));
0de14b54 7138
dda8d76d 7139 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7140 }
252b5132
RH
7141 }
7142
7143 /* Scan the sections for the dynamic symbol table
e3c8793a 7144 and dynamic string table and debug sections. */
89fac5e3 7145 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7146 switch (filedata->file_header.e_machine)
89fac5e3
RS
7147 {
7148 case EM_MIPS:
7149 case EM_MIPS_RS3_LE:
7150 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7151 FDE addresses. However, the ABI also has a semi-official ILP32
7152 variant for which the normal FDE address size rules apply.
7153
7154 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7155 section, where XX is the size of longs in bits. Unfortunately,
7156 earlier compilers provided no way of distinguishing ILP32 objects
7157 from LP64 objects, so if there's any doubt, we should assume that
7158 the official LP64 form is being used. */
dda8d76d
NC
7159 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7160 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7161 eh_addr_size = 8;
7162 break;
0f56a26a
DD
7163
7164 case EM_H8_300:
7165 case EM_H8_300H:
dda8d76d 7166 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7167 {
7168 case E_H8_MACH_H8300:
7169 case E_H8_MACH_H8300HN:
7170 case E_H8_MACH_H8300SN:
7171 case E_H8_MACH_H8300SXN:
7172 eh_addr_size = 2;
7173 break;
7174 case E_H8_MACH_H8300H:
7175 case E_H8_MACH_H8300S:
7176 case E_H8_MACH_H8300SX:
7177 eh_addr_size = 4;
7178 break;
7179 }
f4236fe4
DD
7180 break;
7181
ff7eeb89 7182 case EM_M32C_OLD:
f4236fe4 7183 case EM_M32C:
dda8d76d 7184 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7185 {
7186 case EF_M32C_CPU_M16C:
7187 eh_addr_size = 2;
7188 break;
7189 }
7190 break;
89fac5e3
RS
7191 }
7192
76ca31c0
NC
7193#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7194 do \
7195 { \
be7d229a 7196 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7197 if (section->sh_entsize != expected_entsize) \
9dd3a467 7198 { \
f493c217 7199 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7200 i, section->sh_entsize); \
f493c217 7201 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7202 expected_entsize); \
9dd3a467 7203 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7204 } \
7205 } \
08d8fa11 7206 while (0)
9dd3a467
NC
7207
7208#define CHECK_ENTSIZE(section, i, type) \
1b513401 7209 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7210 sizeof (Elf64_External_##type))
7211
dda8d76d
NC
7212 for (i = 0, section = filedata->section_headers;
7213 i < filedata->file_header.e_shnum;
b34976b6 7214 i++, section++)
252b5132 7215 {
84714f86 7216 const char *name = section_name_print (filedata, section);
252b5132 7217
1b513401
NC
7218 /* Run some sanity checks on the headers and
7219 possibly fill in some file data as well. */
7220 switch (section->sh_type)
252b5132 7221 {
1b513401 7222 case SHT_DYNSYM:
978c4450 7223 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7224 {
7225 error (_("File contains multiple dynamic symbol tables\n"));
7226 continue;
7227 }
7228
08d8fa11 7229 CHECK_ENTSIZE (section, i, Sym);
978c4450 7230 filedata->dynamic_symbols
4de91c10 7231 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7232 filedata->dynamic_symtab_section = section;
1b513401
NC
7233 break;
7234
7235 case SHT_STRTAB:
7236 if (streq (name, ".dynstr"))
252b5132 7237 {
1b513401
NC
7238 if (filedata->dynamic_strings != NULL)
7239 {
7240 error (_("File contains multiple dynamic string tables\n"));
7241 continue;
7242 }
7243
7244 filedata->dynamic_strings
7245 = (char *) get_data (NULL, filedata, section->sh_offset,
7246 1, section->sh_size, _("dynamic strings"));
7247 filedata->dynamic_strings_length
7248 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7249 filedata->dynamic_strtab_section = section;
252b5132 7250 }
1b513401
NC
7251 break;
7252
7253 case SHT_SYMTAB_SHNDX:
7254 {
7255 elf_section_list * entry = xmalloc (sizeof * entry);
7256
7257 entry->hdr = section;
7258 entry->next = filedata->symtab_shndx_list;
7259 filedata->symtab_shndx_list = entry;
7260 }
7261 break;
7262
7263 case SHT_SYMTAB:
7264 CHECK_ENTSIZE (section, i, Sym);
7265 break;
7266
7267 case SHT_GROUP:
7268 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7269 break;
252b5132 7270
1b513401
NC
7271 case SHT_REL:
7272 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7273 if (do_checks && section->sh_size == 0)
1b513401
NC
7274 warn (_("Section '%s': zero-sized relocation section\n"), name);
7275 break;
7276
7277 case SHT_RELA:
7278 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7279 if (do_checks && section->sh_size == 0)
1b513401
NC
7280 warn (_("Section '%s': zero-sized relocation section\n"), name);
7281 break;
7282
682351b9
AM
7283 case SHT_RELR:
7284 CHECK_ENTSIZE (section, i, Relr);
7285 break;
7286
1b513401
NC
7287 case SHT_NOTE:
7288 case SHT_PROGBITS:
546cb2d8
NC
7289 /* Having a zero sized section is not illegal according to the
7290 ELF standard, but it might be an indication that something
7291 is wrong. So issue a warning if we are running in lint mode. */
7292 if (do_checks && section->sh_size == 0)
1b513401
NC
7293 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7294 break;
7295
7296 default:
7297 break;
7298 }
7299
7300 if ((do_debugging || do_debug_info || do_debug_abbrevs
7301 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7302 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7303 || do_debug_str || do_debug_str_offsets || do_debug_loc
7304 || do_debug_ranges
1b513401 7305 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7306 && (startswith (name, ".debug_")
7307 || startswith (name, ".zdebug_")))
252b5132 7308 {
1b315056
CS
7309 if (name[1] == 'z')
7310 name += sizeof (".zdebug_") - 1;
7311 else
7312 name += sizeof (".debug_") - 1;
252b5132
RH
7313
7314 if (do_debugging
24d127aa
ML
7315 || (do_debug_info && startswith (name, "info"))
7316 || (do_debug_info && startswith (name, "types"))
7317 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7318 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7319 || (do_debug_lines && startswith (name, "line."))
7320 || (do_debug_pubnames && startswith (name, "pubnames"))
7321 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7322 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7323 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7324 || (do_debug_aranges && startswith (name, "aranges"))
7325 || (do_debug_ranges && startswith (name, "ranges"))
7326 || (do_debug_ranges && startswith (name, "rnglists"))
7327 || (do_debug_frames && startswith (name, "frame"))
7328 || (do_debug_macinfo && startswith (name, "macinfo"))
7329 || (do_debug_macinfo && startswith (name, "macro"))
7330 || (do_debug_str && startswith (name, "str"))
7331 || (do_debug_links && startswith (name, "sup"))
7332 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7333 || (do_debug_loc && startswith (name, "loc"))
7334 || (do_debug_loc && startswith (name, "loclists"))
7335 || (do_debug_addr && startswith (name, "addr"))
7336 || (do_debug_cu_index && startswith (name, "cu_index"))
7337 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7338 )
6431e409 7339 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7340 }
a262ae96 7341 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7342 else if ((do_debugging || do_debug_info)
24d127aa 7343 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7344 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7345 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7346 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7347 else if (do_gdb_index && (streq (name, ".gdb_index")
7348 || streq (name, ".debug_names")))
6431e409 7349 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7350 /* Trace sections for Itanium VMS. */
7351 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7352 || do_trace_aranges)
24d127aa 7353 && startswith (name, ".trace_"))
6f875884
TG
7354 {
7355 name += sizeof (".trace_") - 1;
7356
7357 if (do_debugging
7358 || (do_trace_info && streq (name, "info"))
7359 || (do_trace_abbrevs && streq (name, "abbrev"))
7360 || (do_trace_aranges && streq (name, "aranges"))
7361 )
6431e409 7362 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7363 }
dda8d76d 7364 else if ((do_debugging || do_debug_links)
24d127aa
ML
7365 && (startswith (name, ".gnu_debuglink")
7366 || startswith (name, ".gnu_debugaltlink")))
6431e409 7367 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7368 }
7369
7370 if (! do_sections)
015dc7e1 7371 return true;
252b5132 7372
ca0e11aa 7373 if (filedata->is_separate && ! process_links)
015dc7e1 7374 return true;
ca0e11aa
NC
7375
7376 if (filedata->is_separate)
7377 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7378 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7379 printf (_("\nSection Headers:\n"));
7380 else
7381 printf (_("\nSection Header:\n"));
76da6bbe 7382
f7a99963 7383 if (is_32bit_elf)
595cf52e 7384 {
5477e8a0 7385 if (do_section_details)
595cf52e
L
7386 {
7387 printf (_(" [Nr] Name\n"));
5477e8a0 7388 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7389 }
7390 else
7391 printf
7392 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7393 }
d974e256 7394 else if (do_wide)
595cf52e 7395 {
5477e8a0 7396 if (do_section_details)
595cf52e
L
7397 {
7398 printf (_(" [Nr] Name\n"));
5477e8a0 7399 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7400 }
7401 else
7402 printf
7403 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7404 }
f7a99963
NC
7405 else
7406 {
5477e8a0 7407 if (do_section_details)
595cf52e
L
7408 {
7409 printf (_(" [Nr] Name\n"));
5477e8a0
L
7410 printf (_(" Type Address Offset Link\n"));
7411 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7412 }
7413 else
7414 {
7415 printf (_(" [Nr] Name Type Address Offset\n"));
7416 printf (_(" Size EntSize Flags Link Info Align\n"));
7417 }
f7a99963 7418 }
252b5132 7419
5477e8a0
L
7420 if (do_section_details)
7421 printf (_(" Flags\n"));
7422
dda8d76d
NC
7423 for (i = 0, section = filedata->section_headers;
7424 i < filedata->file_header.e_shnum;
b34976b6 7425 i++, section++)
252b5132 7426 {
dd905818
NC
7427 /* Run some sanity checks on the section header. */
7428
7429 /* Check the sh_link field. */
7430 switch (section->sh_type)
7431 {
285e3f99
AM
7432 case SHT_REL:
7433 case SHT_RELA:
7434 if (section->sh_link == 0
7435 && (filedata->file_header.e_type == ET_EXEC
7436 || filedata->file_header.e_type == ET_DYN))
7437 /* A dynamic relocation section where all entries use a
7438 zero symbol index need not specify a symtab section. */
7439 break;
7440 /* Fall through. */
dd905818
NC
7441 case SHT_SYMTAB_SHNDX:
7442 case SHT_GROUP:
7443 case SHT_HASH:
7444 case SHT_GNU_HASH:
7445 case SHT_GNU_versym:
285e3f99 7446 if (section->sh_link == 0
dda8d76d
NC
7447 || section->sh_link >= filedata->file_header.e_shnum
7448 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7449 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7450 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7451 i, section->sh_link);
7452 break;
7453
7454 case SHT_DYNAMIC:
7455 case SHT_SYMTAB:
7456 case SHT_DYNSYM:
7457 case SHT_GNU_verneed:
7458 case SHT_GNU_verdef:
7459 case SHT_GNU_LIBLIST:
285e3f99 7460 if (section->sh_link == 0
dda8d76d
NC
7461 || section->sh_link >= filedata->file_header.e_shnum
7462 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7463 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7464 i, section->sh_link);
7465 break;
7466
7467 case SHT_INIT_ARRAY:
7468 case SHT_FINI_ARRAY:
7469 case SHT_PREINIT_ARRAY:
7470 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7471 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7472 i, section->sh_link);
7473 break;
7474
7475 default:
7476 /* FIXME: Add support for target specific section types. */
7477#if 0 /* Currently we do not check other section types as there are too
7478 many special cases. Stab sections for example have a type
7479 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7480 section. */
7481 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7482 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7483 i, section->sh_link);
7484#endif
7485 break;
7486 }
7487
7488 /* Check the sh_info field. */
7489 switch (section->sh_type)
7490 {
7491 case SHT_REL:
7492 case SHT_RELA:
285e3f99
AM
7493 if (section->sh_info == 0
7494 && (filedata->file_header.e_type == ET_EXEC
7495 || filedata->file_header.e_type == ET_DYN))
7496 /* Dynamic relocations apply to segments, so they do not
7497 need to specify the section they relocate. */
7498 break;
7499 if (section->sh_info == 0
dda8d76d
NC
7500 || section->sh_info >= filedata->file_header.e_shnum
7501 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7502 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7503 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7504 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7505 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7506 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7507 /* FIXME: Are other section types valid ? */
dda8d76d 7508 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7509 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7510 i, section->sh_info);
dd905818
NC
7511 break;
7512
7513 case SHT_DYNAMIC:
7514 case SHT_HASH:
7515 case SHT_SYMTAB_SHNDX:
7516 case SHT_INIT_ARRAY:
7517 case SHT_FINI_ARRAY:
7518 case SHT_PREINIT_ARRAY:
7519 if (section->sh_info != 0)
7520 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7521 i, section->sh_info);
7522 break;
7523
7524 case SHT_GROUP:
7525 case SHT_SYMTAB:
7526 case SHT_DYNSYM:
7527 /* A symbol index - we assume that it is valid. */
7528 break;
7529
7530 default:
7531 /* FIXME: Add support for target specific section types. */
7532 if (section->sh_type == SHT_NOBITS)
7533 /* NOBITS section headers with non-zero sh_info fields can be
7534 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7535 information. The stripped sections have their headers
7536 preserved but their types set to SHT_NOBITS. So do not check
7537 this type of section. */
dd905818
NC
7538 ;
7539 else if (section->sh_flags & SHF_INFO_LINK)
7540 {
dda8d76d 7541 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7542 warn (_("[%2u]: Expected link to another section in info field"), i);
7543 }
a91e1603
L
7544 else if (section->sh_type < SHT_LOOS
7545 && (section->sh_flags & SHF_GNU_MBIND) == 0
7546 && section->sh_info != 0)
dd905818
NC
7547 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7548 i, section->sh_info);
7549 break;
7550 }
7551
3e6b6445 7552 /* Check the sh_size field. */
dda8d76d 7553 if (section->sh_size > filedata->file_size
3e6b6445
NC
7554 && section->sh_type != SHT_NOBITS
7555 && section->sh_type != SHT_NULL
7556 && section->sh_type < SHT_LOOS)
7557 warn (_("Size of section %u is larger than the entire file!\n"), i);
7558
7bfd842d 7559 printf (" [%2u] ", i);
5477e8a0 7560 if (do_section_details)
dda8d76d 7561 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7562 else
84714f86 7563 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7564
ea52a088 7565 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7566 get_section_type_name (filedata, section->sh_type));
0b4362b0 7567
f7a99963
NC
7568 if (is_32bit_elf)
7569 {
cfcac11d
NC
7570 const char * link_too_big = NULL;
7571
f7a99963 7572 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7573
f7a99963
NC
7574 printf ( " %6.6lx %6.6lx %2.2lx",
7575 (unsigned long) section->sh_offset,
7576 (unsigned long) section->sh_size,
7577 (unsigned long) section->sh_entsize);
d1133906 7578
5477e8a0
L
7579 if (do_section_details)
7580 fputs (" ", stdout);
7581 else
dda8d76d 7582 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7583
dda8d76d 7584 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7585 {
7586 link_too_big = "";
7587 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7588 an error but it can have special values in Solaris binaries. */
dda8d76d 7589 switch (filedata->file_header.e_machine)
cfcac11d 7590 {
caa83f8b 7591 case EM_386:
22abe556 7592 case EM_IAMCU:
caa83f8b 7593 case EM_X86_64:
7f502d6c 7594 case EM_L1OM:
7a9068fe 7595 case EM_K1OM:
cfcac11d
NC
7596 case EM_OLD_SPARCV9:
7597 case EM_SPARC32PLUS:
7598 case EM_SPARCV9:
7599 case EM_SPARC:
7600 if (section->sh_link == (SHN_BEFORE & 0xffff))
7601 link_too_big = "BEFORE";
7602 else if (section->sh_link == (SHN_AFTER & 0xffff))
7603 link_too_big = "AFTER";
7604 break;
7605 default:
7606 break;
7607 }
7608 }
7609
7610 if (do_section_details)
7611 {
7612 if (link_too_big != NULL && * link_too_big)
7613 printf ("<%s> ", link_too_big);
7614 else
7615 printf ("%2u ", section->sh_link);
7616 printf ("%3u %2lu\n", section->sh_info,
7617 (unsigned long) section->sh_addralign);
7618 }
7619 else
7620 printf ("%2u %3u %2lu\n",
7621 section->sh_link,
7622 section->sh_info,
7623 (unsigned long) section->sh_addralign);
7624
7625 if (link_too_big && ! * link_too_big)
7626 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7627 i, section->sh_link);
f7a99963 7628 }
d974e256
JJ
7629 else if (do_wide)
7630 {
7631 print_vma (section->sh_addr, LONG_HEX);
7632
7633 if ((long) section->sh_offset == section->sh_offset)
7634 printf (" %6.6lx", (unsigned long) section->sh_offset);
7635 else
7636 {
7637 putchar (' ');
7638 print_vma (section->sh_offset, LONG_HEX);
7639 }
7640
7641 if ((unsigned long) section->sh_size == section->sh_size)
7642 printf (" %6.6lx", (unsigned long) section->sh_size);
7643 else
7644 {
7645 putchar (' ');
7646 print_vma (section->sh_size, LONG_HEX);
7647 }
7648
7649 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7650 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7651 else
7652 {
7653 putchar (' ');
7654 print_vma (section->sh_entsize, LONG_HEX);
7655 }
7656
5477e8a0
L
7657 if (do_section_details)
7658 fputs (" ", stdout);
7659 else
dda8d76d 7660 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7661
72de5009 7662 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7663
7664 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7665 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7666 else
7667 {
7668 print_vma (section->sh_addralign, DEC);
7669 putchar ('\n');
7670 }
7671 }
5477e8a0 7672 else if (do_section_details)
595cf52e 7673 {
55cc53e9 7674 putchar (' ');
595cf52e
L
7675 print_vma (section->sh_addr, LONG_HEX);
7676 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7677 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7678 else
7679 {
7680 printf (" ");
7681 print_vma (section->sh_offset, LONG_HEX);
7682 }
72de5009 7683 printf (" %u\n ", section->sh_link);
595cf52e 7684 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7685 putchar (' ');
595cf52e
L
7686 print_vma (section->sh_entsize, LONG_HEX);
7687
72de5009
AM
7688 printf (" %-16u %lu\n",
7689 section->sh_info,
595cf52e
L
7690 (unsigned long) section->sh_addralign);
7691 }
f7a99963
NC
7692 else
7693 {
7694 putchar (' ');
7695 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7696 if ((long) section->sh_offset == section->sh_offset)
7697 printf (" %8.8lx", (unsigned long) section->sh_offset);
7698 else
7699 {
7700 printf (" ");
7701 print_vma (section->sh_offset, LONG_HEX);
7702 }
f7a99963
NC
7703 printf ("\n ");
7704 print_vma (section->sh_size, LONG_HEX);
7705 printf (" ");
7706 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7707
dda8d76d 7708 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7709
72de5009
AM
7710 printf (" %2u %3u %lu\n",
7711 section->sh_link,
7712 section->sh_info,
f7a99963
NC
7713 (unsigned long) section->sh_addralign);
7714 }
5477e8a0
L
7715
7716 if (do_section_details)
77115a4a 7717 {
dda8d76d 7718 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7719 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7720 {
7721 /* Minimum section size is 12 bytes for 32-bit compression
7722 header + 12 bytes for compressed data header. */
7723 unsigned char buf[24];
d8024a91 7724
77115a4a 7725 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7726 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7727 sizeof (buf), _("compression header")))
7728 {
7729 Elf_Internal_Chdr chdr;
d8024a91 7730
5844b465
NC
7731 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7732 printf (_(" [<corrupt>]\n"));
77115a4a 7733 else
5844b465
NC
7734 {
7735 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7736 printf (" ZLIB, ");
1369522f
CC
7737 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7738 printf (" ZSTD, ");
5844b465
NC
7739 else
7740 printf (_(" [<unknown>: 0x%x], "),
7741 chdr.ch_type);
7742 print_vma (chdr.ch_size, LONG_HEX);
7743 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7744 }
77115a4a
L
7745 }
7746 }
7747 }
252b5132
RH
7748 }
7749
5477e8a0 7750 if (!do_section_details)
3dbcc61d 7751 {
9fb71ee4
NC
7752 /* The ordering of the letters shown here matches the ordering of the
7753 corresponding SHF_xxx values, and hence the order in which these
7754 letters will be displayed to the user. */
7755 printf (_("Key to Flags:\n\
7756 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7757 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7758 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7759 switch (filedata->file_header.e_ident[EI_OSABI])
7760 {
7761 case ELFOSABI_GNU:
7762 case ELFOSABI_FREEBSD:
7763 printf (_("R (retain), "));
7764 /* Fall through */
7765 case ELFOSABI_NONE:
7766 printf (_("D (mbind), "));
7767 break;
7768 default:
7769 break;
7770 }
dda8d76d
NC
7771 if (filedata->file_header.e_machine == EM_X86_64
7772 || filedata->file_header.e_machine == EM_L1OM
7773 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7774 printf (_("l (large), "));
dda8d76d 7775 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7776 printf (_("y (purecode), "));
dda8d76d 7777 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7778 printf (_("v (VLE), "));
9fb71ee4 7779 printf ("p (processor specific)\n");
0b4362b0 7780 }
d1133906 7781
015dc7e1 7782 return true;
252b5132
RH
7783}
7784
015dc7e1 7785static bool
28d13567
AM
7786get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7787 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7788 char **strtab, unsigned long *strtablen)
7789{
7790 *strtab = NULL;
7791 *strtablen = 0;
4de91c10 7792 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7793
7794 if (*symtab == NULL)
015dc7e1 7795 return false;
28d13567
AM
7796
7797 if (symsec->sh_link != 0)
7798 {
7799 Elf_Internal_Shdr *strsec;
7800
7801 if (symsec->sh_link >= filedata->file_header.e_shnum)
7802 {
7803 error (_("Bad sh_link in symbol table section\n"));
7804 free (*symtab);
7805 *symtab = NULL;
7806 *nsyms = 0;
015dc7e1 7807 return false;
28d13567
AM
7808 }
7809
7810 strsec = filedata->section_headers + symsec->sh_link;
7811
7812 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7813 1, strsec->sh_size, _("string table"));
7814 if (*strtab == NULL)
7815 {
7816 free (*symtab);
7817 *symtab = NULL;
7818 *nsyms = 0;
015dc7e1 7819 return false;
28d13567
AM
7820 }
7821 *strtablen = strsec->sh_size;
7822 }
015dc7e1 7823 return true;
28d13567
AM
7824}
7825
f5842774
L
7826static const char *
7827get_group_flags (unsigned int flags)
7828{
1449284b 7829 static char buff[128];
220453ec 7830
6d913794
NC
7831 if (flags == 0)
7832 return "";
7833 else if (flags == GRP_COMDAT)
7834 return "COMDAT ";
f5842774 7835
89246a0e
AM
7836 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7837 flags,
7838 flags & GRP_MASKOS ? _("<OS specific>") : "",
7839 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7840 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7841 ? _("<unknown>") : ""));
6d913794 7842
f5842774
L
7843 return buff;
7844}
7845
015dc7e1 7846static bool
dda8d76d 7847process_section_groups (Filedata * filedata)
f5842774 7848{
2cf0635d 7849 Elf_Internal_Shdr * section;
f5842774 7850 unsigned int i;
2cf0635d
NC
7851 struct group * group;
7852 Elf_Internal_Shdr * symtab_sec;
7853 Elf_Internal_Shdr * strtab_sec;
7854 Elf_Internal_Sym * symtab;
ba5cdace 7855 unsigned long num_syms;
2cf0635d 7856 char * strtab;
c256ffe7 7857 size_t strtab_size;
d1f5c6e3
L
7858
7859 /* Don't process section groups unless needed. */
7860 if (!do_unwind && !do_section_groups)
015dc7e1 7861 return true;
f5842774 7862
dda8d76d 7863 if (filedata->file_header.e_shnum == 0)
f5842774
L
7864 {
7865 if (do_section_groups)
ca0e11aa
NC
7866 {
7867 if (filedata->is_separate)
7868 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7869 filedata->file_name);
7870 else
7871 printf (_("\nThere are no section groups in this file.\n"));
7872 }
015dc7e1 7873 return true;
f5842774
L
7874 }
7875
dda8d76d 7876 if (filedata->section_headers == NULL)
f5842774
L
7877 {
7878 error (_("Section headers are not available!\n"));
fa1908fd 7879 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7880 return false;
f5842774
L
7881 }
7882
978c4450
AM
7883 filedata->section_headers_groups
7884 = (struct group **) calloc (filedata->file_header.e_shnum,
7885 sizeof (struct group *));
e4b17d5c 7886
978c4450 7887 if (filedata->section_headers_groups == NULL)
e4b17d5c 7888 {
8b73c356 7889 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7890 filedata->file_header.e_shnum);
015dc7e1 7891 return false;
e4b17d5c
L
7892 }
7893
f5842774 7894 /* Scan the sections for the group section. */
978c4450 7895 filedata->group_count = 0;
dda8d76d
NC
7896 for (i = 0, section = filedata->section_headers;
7897 i < filedata->file_header.e_shnum;
f5842774 7898 i++, section++)
e4b17d5c 7899 if (section->sh_type == SHT_GROUP)
978c4450 7900 filedata->group_count++;
e4b17d5c 7901
978c4450 7902 if (filedata->group_count == 0)
d1f5c6e3
L
7903 {
7904 if (do_section_groups)
ca0e11aa
NC
7905 {
7906 if (filedata->is_separate)
7907 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7908 filedata->file_name);
7909 else
7910 printf (_("\nThere are no section groups in this file.\n"));
7911 }
d1f5c6e3 7912
015dc7e1 7913 return true;
d1f5c6e3
L
7914 }
7915
978c4450
AM
7916 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7917 sizeof (struct group));
e4b17d5c 7918
978c4450 7919 if (filedata->section_groups == NULL)
e4b17d5c 7920 {
8b73c356 7921 error (_("Out of memory reading %lu groups\n"),
978c4450 7922 (unsigned long) filedata->group_count);
015dc7e1 7923 return false;
e4b17d5c
L
7924 }
7925
d1f5c6e3
L
7926 symtab_sec = NULL;
7927 strtab_sec = NULL;
7928 symtab = NULL;
ba5cdace 7929 num_syms = 0;
d1f5c6e3 7930 strtab = NULL;
c256ffe7 7931 strtab_size = 0;
ca0e11aa
NC
7932
7933 if (filedata->is_separate)
7934 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7935
978c4450 7936 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7937 i < filedata->file_header.e_shnum;
e4b17d5c 7938 i++, section++)
f5842774
L
7939 {
7940 if (section->sh_type == SHT_GROUP)
7941 {
dda8d76d 7942 const char * name = printable_section_name (filedata, section);
74e1a04b 7943 const char * group_name;
2cf0635d
NC
7944 unsigned char * start;
7945 unsigned char * indices;
f5842774 7946 unsigned int entry, j, size;
2cf0635d
NC
7947 Elf_Internal_Shdr * sec;
7948 Elf_Internal_Sym * sym;
f5842774
L
7949
7950 /* Get the symbol table. */
dda8d76d
NC
7951 if (section->sh_link >= filedata->file_header.e_shnum
7952 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7953 != SHT_SYMTAB))
f5842774
L
7954 {
7955 error (_("Bad sh_link in group section `%s'\n"), name);
7956 continue;
7957 }
d1f5c6e3
L
7958
7959 if (symtab_sec != sec)
7960 {
7961 symtab_sec = sec;
9db70fc3 7962 free (symtab);
4de91c10 7963 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7964 }
f5842774 7965
dd24e3da
NC
7966 if (symtab == NULL)
7967 {
7968 error (_("Corrupt header in group section `%s'\n"), name);
7969 continue;
7970 }
7971
ba5cdace
NC
7972 if (section->sh_info >= num_syms)
7973 {
7974 error (_("Bad sh_info in group section `%s'\n"), name);
7975 continue;
7976 }
7977
f5842774
L
7978 sym = symtab + section->sh_info;
7979
7980 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7981 {
4fbb74a6 7982 if (sym->st_shndx == 0
dda8d76d 7983 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7984 {
7985 error (_("Bad sh_info in group section `%s'\n"), name);
7986 continue;
7987 }
ba2685cc 7988
84714f86
AM
7989 group_name = section_name_print (filedata,
7990 filedata->section_headers
b9e920ec 7991 + sym->st_shndx);
c256ffe7 7992 strtab_sec = NULL;
9db70fc3 7993 free (strtab);
f5842774 7994 strtab = NULL;
c256ffe7 7995 strtab_size = 0;
f5842774
L
7996 }
7997 else
7998 {
7999 /* Get the string table. */
dda8d76d 8000 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8001 {
8002 strtab_sec = NULL;
9db70fc3 8003 free (strtab);
c256ffe7
JJ
8004 strtab = NULL;
8005 strtab_size = 0;
8006 }
8007 else if (strtab_sec
dda8d76d 8008 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8009 {
8010 strtab_sec = sec;
9db70fc3 8011 free (strtab);
071436c6 8012
dda8d76d 8013 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8014 1, strtab_sec->sh_size,
8015 _("string table"));
c256ffe7 8016 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8017 }
c256ffe7 8018 group_name = sym->st_name < strtab_size
2b692964 8019 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8020 }
8021
c9c1d674
EG
8022 /* PR 17531: file: loop. */
8023 if (section->sh_entsize > section->sh_size)
8024 {
8025 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 8026 printable_section_name (filedata, section),
8066deb1
AM
8027 (unsigned long) section->sh_entsize,
8028 (unsigned long) section->sh_size);
61dd8e19 8029 continue;
c9c1d674
EG
8030 }
8031
dda8d76d 8032 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8033 1, section->sh_size,
8034 _("section data"));
59245841
NC
8035 if (start == NULL)
8036 continue;
f5842774
L
8037
8038 indices = start;
8039 size = (section->sh_size / section->sh_entsize) - 1;
8040 entry = byte_get (indices, 4);
8041 indices += 4;
e4b17d5c
L
8042
8043 if (do_section_groups)
8044 {
2b692964 8045 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8046 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8047
e4b17d5c
L
8048 printf (_(" [Index] Name\n"));
8049 }
8050
8051 group->group_index = i;
8052
f5842774
L
8053 for (j = 0; j < size; j++)
8054 {
2cf0635d 8055 struct group_list * g;
e4b17d5c 8056
f5842774
L
8057 entry = byte_get (indices, 4);
8058 indices += 4;
8059
dda8d76d 8060 if (entry >= filedata->file_header.e_shnum)
391cb864 8061 {
57028622
NC
8062 static unsigned num_group_errors = 0;
8063
8064 if (num_group_errors ++ < 10)
8065 {
8066 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8067 entry, i, filedata->file_header.e_shnum - 1);
57028622 8068 if (num_group_errors == 10)
67ce483b 8069 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8070 }
391cb864
L
8071 continue;
8072 }
391cb864 8073
978c4450 8074 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8075 {
d1f5c6e3
L
8076 if (entry)
8077 {
57028622
NC
8078 static unsigned num_errs = 0;
8079
8080 if (num_errs ++ < 10)
8081 {
8082 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8083 entry, i,
978c4450 8084 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8085 if (num_errs == 10)
8086 warn (_("Further error messages about already contained group sections suppressed\n"));
8087 }
d1f5c6e3
L
8088 continue;
8089 }
8090 else
8091 {
8092 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8093 section group. We just warn it the first time
d1f5c6e3 8094 and ignore it afterwards. */
015dc7e1 8095 static bool warned = false;
d1f5c6e3
L
8096 if (!warned)
8097 {
8098 error (_("section 0 in group section [%5u]\n"),
978c4450 8099 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8100 warned = true;
d1f5c6e3
L
8101 }
8102 }
e4b17d5c
L
8103 }
8104
978c4450 8105 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8106
8107 if (do_section_groups)
8108 {
dda8d76d
NC
8109 sec = filedata->section_headers + entry;
8110 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8111 }
8112
3f5e193b 8113 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8114 g->section_index = entry;
8115 g->next = group->root;
8116 group->root = g;
f5842774
L
8117 }
8118
9db70fc3 8119 free (start);
e4b17d5c
L
8120
8121 group++;
f5842774
L
8122 }
8123 }
8124
9db70fc3
AM
8125 free (symtab);
8126 free (strtab);
015dc7e1 8127 return true;
f5842774
L
8128}
8129
28f997cf
TG
8130/* Data used to display dynamic fixups. */
8131
8132struct ia64_vms_dynfixup
8133{
625d49fc
AM
8134 uint64_t needed_ident; /* Library ident number. */
8135 uint64_t needed; /* Index in the dstrtab of the library name. */
8136 uint64_t fixup_needed; /* Index of the library. */
8137 uint64_t fixup_rela_cnt; /* Number of fixups. */
8138 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8139};
8140
8141/* Data used to display dynamic relocations. */
8142
8143struct ia64_vms_dynimgrela
8144{
625d49fc
AM
8145 uint64_t img_rela_cnt; /* Number of relocations. */
8146 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8147};
8148
8149/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8150 library). */
8151
015dc7e1 8152static bool
dda8d76d
NC
8153dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8154 struct ia64_vms_dynfixup * fixup,
8155 const char * strtab,
8156 unsigned int strtab_sz)
28f997cf 8157{
32ec8896 8158 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8159 long i;
32ec8896 8160 const char * lib_name;
28f997cf 8161
978c4450
AM
8162 imfs = get_data (NULL, filedata,
8163 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8164 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8165 _("dynamic section image fixups"));
8166 if (!imfs)
015dc7e1 8167 return false;
28f997cf
TG
8168
8169 if (fixup->needed < strtab_sz)
8170 lib_name = strtab + fixup->needed;
8171 else
8172 {
32ec8896 8173 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8174 (unsigned long) fixup->needed);
28f997cf
TG
8175 lib_name = "???";
8176 }
736990c4 8177
28f997cf
TG
8178 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8179 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8180 printf
8181 (_("Seg Offset Type SymVec DataType\n"));
8182
8183 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8184 {
8185 unsigned int type;
8186 const char *rtype;
8187
8188 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8189 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8190 type = BYTE_GET (imfs [i].type);
8191 rtype = elf_ia64_reloc_type (type);
8192 if (rtype == NULL)
f493c217 8193 printf ("0x%08x ", type);
28f997cf 8194 else
f493c217 8195 printf ("%-32s ", rtype);
28f997cf
TG
8196 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8197 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8198 }
8199
8200 free (imfs);
015dc7e1 8201 return true;
28f997cf
TG
8202}
8203
8204/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8205
015dc7e1 8206static bool
dda8d76d 8207dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8208{
8209 Elf64_External_VMS_IMAGE_RELA *imrs;
8210 long i;
8211
978c4450
AM
8212 imrs = get_data (NULL, filedata,
8213 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8214 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8215 _("dynamic section image relocations"));
28f997cf 8216 if (!imrs)
015dc7e1 8217 return false;
28f997cf
TG
8218
8219 printf (_("\nImage relocs\n"));
8220 printf
8221 (_("Seg Offset Type Addend Seg Sym Off\n"));
8222
8223 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8224 {
8225 unsigned int type;
8226 const char *rtype;
8227
8228 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8229 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8230 type = BYTE_GET (imrs [i].type);
8231 rtype = elf_ia64_reloc_type (type);
8232 if (rtype == NULL)
8233 printf ("0x%08x ", type);
8234 else
8235 printf ("%-31s ", rtype);
8236 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8237 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8238 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8239 }
8240
8241 free (imrs);
015dc7e1 8242 return true;
28f997cf
TG
8243}
8244
8245/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8246
015dc7e1 8247static bool
dda8d76d 8248process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8249{
8250 struct ia64_vms_dynfixup fixup;
8251 struct ia64_vms_dynimgrela imgrela;
8252 Elf_Internal_Dyn *entry;
625d49fc
AM
8253 uint64_t strtab_off = 0;
8254 uint64_t strtab_sz = 0;
28f997cf 8255 char *strtab = NULL;
015dc7e1 8256 bool res = true;
28f997cf
TG
8257
8258 memset (&fixup, 0, sizeof (fixup));
8259 memset (&imgrela, 0, sizeof (imgrela));
8260
8261 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8262 for (entry = filedata->dynamic_section;
8263 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8264 entry++)
8265 {
8266 switch (entry->d_tag)
8267 {
8268 case DT_IA_64_VMS_STRTAB_OFFSET:
8269 strtab_off = entry->d_un.d_val;
8270 break;
8271 case DT_STRSZ:
8272 strtab_sz = entry->d_un.d_val;
8273 if (strtab == NULL)
978c4450
AM
8274 strtab = get_data (NULL, filedata,
8275 filedata->dynamic_addr + strtab_off,
28f997cf 8276 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8277 if (strtab == NULL)
8278 strtab_sz = 0;
28f997cf
TG
8279 break;
8280
8281 case DT_IA_64_VMS_NEEDED_IDENT:
8282 fixup.needed_ident = entry->d_un.d_val;
8283 break;
8284 case DT_NEEDED:
8285 fixup.needed = entry->d_un.d_val;
8286 break;
8287 case DT_IA_64_VMS_FIXUP_NEEDED:
8288 fixup.fixup_needed = entry->d_un.d_val;
8289 break;
8290 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8291 fixup.fixup_rela_cnt = entry->d_un.d_val;
8292 break;
8293 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8294 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8295 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8296 res = false;
28f997cf 8297 break;
28f997cf
TG
8298 case DT_IA_64_VMS_IMG_RELA_CNT:
8299 imgrela.img_rela_cnt = entry->d_un.d_val;
8300 break;
8301 case DT_IA_64_VMS_IMG_RELA_OFF:
8302 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8303 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8304 res = false;
28f997cf
TG
8305 break;
8306
8307 default:
8308 break;
8309 }
8310 }
8311
9db70fc3 8312 free (strtab);
28f997cf
TG
8313
8314 return res;
8315}
8316
85b1c36d 8317static struct
566b0d53 8318{
2cf0635d 8319 const char * name;
566b0d53
L
8320 int reloc;
8321 int size;
a7fd1186 8322 relocation_type rel_type;
32ec8896
NC
8323}
8324 dynamic_relocations [] =
566b0d53 8325{
a7fd1186
FS
8326 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8327 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8328 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8329 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8330};
8331
252b5132 8332/* Process the reloc section. */
18bd398b 8333
015dc7e1 8334static bool
dda8d76d 8335process_relocs (Filedata * filedata)
252b5132 8336{
b34976b6
AM
8337 unsigned long rel_size;
8338 unsigned long rel_offset;
252b5132 8339
252b5132 8340 if (!do_reloc)
015dc7e1 8341 return true;
252b5132
RH
8342
8343 if (do_using_dynamic)
8344 {
a7fd1186 8345 relocation_type rel_type;
2cf0635d 8346 const char * name;
015dc7e1 8347 bool has_dynamic_reloc;
566b0d53 8348 unsigned int i;
0de14b54 8349
015dc7e1 8350 has_dynamic_reloc = false;
252b5132 8351
566b0d53 8352 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8353 {
a7fd1186 8354 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8355 name = dynamic_relocations [i].name;
978c4450
AM
8356 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8357 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8358
32ec8896 8359 if (rel_size)
015dc7e1 8360 has_dynamic_reloc = true;
566b0d53 8361
a7fd1186 8362 if (rel_type == reltype_unknown)
aa903cfb 8363 {
566b0d53 8364 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8365 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8366 {
8367 case DT_REL:
a7fd1186 8368 rel_type = reltype_rel;
566b0d53
L
8369 break;
8370 case DT_RELA:
a7fd1186 8371 rel_type = reltype_rela;
566b0d53
L
8372 break;
8373 }
aa903cfb 8374 }
252b5132 8375
566b0d53
L
8376 if (rel_size)
8377 {
ca0e11aa
NC
8378 if (filedata->is_separate)
8379 printf
8380 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8381 filedata->file_name, name, rel_offset, rel_size);
8382 else
8383 printf
8384 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8385 name, rel_offset, rel_size);
252b5132 8386
dda8d76d
NC
8387 dump_relocations (filedata,
8388 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8389 rel_size,
978c4450
AM
8390 filedata->dynamic_symbols,
8391 filedata->num_dynamic_syms,
8392 filedata->dynamic_strings,
8393 filedata->dynamic_strings_length,
a7fd1186 8394 rel_type, true /* is_dynamic */);
566b0d53 8395 }
252b5132 8396 }
566b0d53 8397
dda8d76d
NC
8398 if (is_ia64_vms (filedata))
8399 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8400 has_dynamic_reloc = true;
28f997cf 8401
566b0d53 8402 if (! has_dynamic_reloc)
ca0e11aa
NC
8403 {
8404 if (filedata->is_separate)
8405 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8406 filedata->file_name);
8407 else
8408 printf (_("\nThere are no dynamic relocations in this file.\n"));
8409 }
252b5132
RH
8410 }
8411 else
8412 {
2cf0635d 8413 Elf_Internal_Shdr * section;
b34976b6 8414 unsigned long i;
015dc7e1 8415 bool found = false;
252b5132 8416
dda8d76d
NC
8417 for (i = 0, section = filedata->section_headers;
8418 i < filedata->file_header.e_shnum;
b34976b6 8419 i++, section++)
252b5132
RH
8420 {
8421 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8422 && section->sh_type != SHT_REL
8423 && section->sh_type != SHT_RELR)
252b5132
RH
8424 continue;
8425
8426 rel_offset = section->sh_offset;
8427 rel_size = section->sh_size;
8428
8429 if (rel_size)
8430 {
a7fd1186 8431 relocation_type rel_type;
d3a49aa8 8432 unsigned long num_rela;
103f02d3 8433
ca0e11aa
NC
8434 if (filedata->is_separate)
8435 printf (_("\nIn linked file '%s' relocation section "),
8436 filedata->file_name);
8437 else
8438 printf (_("\nRelocation section "));
252b5132 8439
dda8d76d 8440 if (filedata->string_table == NULL)
19936277 8441 printf ("%d", section->sh_name);
252b5132 8442 else
dda8d76d 8443 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8444
d3a49aa8
AM
8445 num_rela = rel_size / section->sh_entsize;
8446 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8447 " at offset 0x%lx contains %lu entries:\n",
8448 num_rela),
8449 rel_offset, num_rela);
252b5132 8450
a7fd1186
FS
8451 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8452 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8453
4fbb74a6 8454 if (section->sh_link != 0
dda8d76d 8455 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8456 {
2cf0635d
NC
8457 Elf_Internal_Shdr * symsec;
8458 Elf_Internal_Sym * symtab;
d79b3d50 8459 unsigned long nsyms;
c256ffe7 8460 unsigned long strtablen = 0;
2cf0635d 8461 char * strtab = NULL;
57346661 8462
dda8d76d 8463 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8464 if (symsec->sh_type != SHT_SYMTAB
8465 && symsec->sh_type != SHT_DYNSYM)
8466 continue;
8467
28d13567
AM
8468 if (!get_symtab (filedata, symsec,
8469 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8470 continue;
252b5132 8471
dda8d76d 8472 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8473 symtab, nsyms, strtab, strtablen,
a7fd1186 8474 rel_type,
bb4d2ac2 8475 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8476 free (strtab);
d79b3d50
NC
8477 free (symtab);
8478 }
8479 else
dda8d76d 8480 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8481 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8482
015dc7e1 8483 found = true;
252b5132
RH
8484 }
8485 }
8486
8487 if (! found)
45ac8f4f
NC
8488 {
8489 /* Users sometimes forget the -D option, so try to be helpful. */
8490 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8491 {
978c4450 8492 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8493 {
ca0e11aa
NC
8494 if (filedata->is_separate)
8495 printf (_("\nThere are no static relocations in linked file '%s'."),
8496 filedata->file_name);
8497 else
8498 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8499 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8500
8501 break;
8502 }
8503 }
8504 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8505 {
8506 if (filedata->is_separate)
8507 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8508 filedata->file_name);
8509 else
8510 printf (_("\nThere are no relocations in this file.\n"));
8511 }
45ac8f4f 8512 }
252b5132
RH
8513 }
8514
015dc7e1 8515 return true;
252b5132
RH
8516}
8517
4d6ed7c8
NC
8518/* An absolute address consists of a section and an offset. If the
8519 section is NULL, the offset itself is the address, otherwise, the
8520 address equals to LOAD_ADDRESS(section) + offset. */
8521
8522struct absaddr
948f632f
DA
8523{
8524 unsigned short section;
625d49fc 8525 uint64_t offset;
948f632f 8526};
4d6ed7c8 8527
948f632f
DA
8528/* Find the nearest symbol at or below ADDR. Returns the symbol
8529 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8530
4d6ed7c8 8531static void
dda8d76d
NC
8532find_symbol_for_address (Filedata * filedata,
8533 Elf_Internal_Sym * symtab,
8534 unsigned long nsyms,
8535 const char * strtab,
8536 unsigned long strtab_size,
8537 struct absaddr addr,
8538 const char ** symname,
625d49fc 8539 uint64_t * offset)
4d6ed7c8 8540{
625d49fc 8541 uint64_t dist = 0x100000;
2cf0635d 8542 Elf_Internal_Sym * sym;
948f632f
DA
8543 Elf_Internal_Sym * beg;
8544 Elf_Internal_Sym * end;
2cf0635d 8545 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8546
0b6ae522 8547 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8548 beg = symtab;
8549 end = symtab + nsyms;
0b6ae522 8550
948f632f 8551 while (beg < end)
4d6ed7c8 8552 {
625d49fc 8553 uint64_t value;
948f632f
DA
8554
8555 sym = beg + (end - beg) / 2;
0b6ae522 8556
948f632f 8557 value = sym->st_value;
0b6ae522
DJ
8558 REMOVE_ARCH_BITS (value);
8559
948f632f 8560 if (sym->st_name != 0
4d6ed7c8 8561 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8562 && addr.offset >= value
8563 && addr.offset - value < dist)
4d6ed7c8
NC
8564 {
8565 best = sym;
0b6ae522 8566 dist = addr.offset - value;
4d6ed7c8
NC
8567 if (!dist)
8568 break;
8569 }
948f632f
DA
8570
8571 if (addr.offset < value)
8572 end = sym;
8573 else
8574 beg = sym + 1;
4d6ed7c8 8575 }
1b31d05e 8576
4d6ed7c8
NC
8577 if (best)
8578 {
57346661 8579 *symname = (best->st_name >= strtab_size
2b692964 8580 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8581 *offset = dist;
8582 return;
8583 }
1b31d05e 8584
4d6ed7c8
NC
8585 *symname = NULL;
8586 *offset = addr.offset;
8587}
8588
32ec8896 8589static /* signed */ int
948f632f
DA
8590symcmp (const void *p, const void *q)
8591{
8592 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8593 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8594
8595 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8596}
8597
8598/* Process the unwind section. */
8599
8600#include "unwind-ia64.h"
8601
8602struct ia64_unw_table_entry
8603{
8604 struct absaddr start;
8605 struct absaddr end;
8606 struct absaddr info;
8607};
8608
8609struct ia64_unw_aux_info
8610{
32ec8896
NC
8611 struct ia64_unw_table_entry * table; /* Unwind table. */
8612 unsigned long table_len; /* Length of unwind table. */
8613 unsigned char * info; /* Unwind info. */
8614 unsigned long info_size; /* Size of unwind info. */
625d49fc
AM
8615 uint64_t info_addr; /* Starting address of unwind info. */
8616 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
8617 Elf_Internal_Sym * symtab; /* The symbol table. */
8618 unsigned long nsyms; /* Number of symbols. */
8619 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8620 unsigned long nfuns; /* Number of entries in funtab. */
8621 char * strtab; /* The string table. */
8622 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8623};
8624
015dc7e1 8625static bool
dda8d76d 8626dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8627{
2cf0635d 8628 struct ia64_unw_table_entry * tp;
948f632f 8629 unsigned long j, nfuns;
4d6ed7c8 8630 int in_body;
015dc7e1 8631 bool res = true;
7036c0e1 8632
948f632f
DA
8633 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8634 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8635 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8636 aux->funtab[nfuns++] = aux->symtab[j];
8637 aux->nfuns = nfuns;
8638 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8639
4d6ed7c8
NC
8640 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8641 {
625d49fc
AM
8642 uint64_t stamp;
8643 uint64_t offset;
2cf0635d
NC
8644 const unsigned char * dp;
8645 const unsigned char * head;
53774b7e 8646 const unsigned char * end;
2cf0635d 8647 const char * procname;
4d6ed7c8 8648
dda8d76d 8649 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8650 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8651
8652 fputs ("\n<", stdout);
8653
8654 if (procname)
8655 {
8656 fputs (procname, stdout);
8657
8658 if (offset)
8659 printf ("+%lx", (unsigned long) offset);
8660 }
8661
8662 fputs (">: [", stdout);
8663 print_vma (tp->start.offset, PREFIX_HEX);
8664 fputc ('-', stdout);
8665 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8666 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8667 (unsigned long) (tp->info.offset - aux->seg_base));
8668
53774b7e
NC
8669 /* PR 17531: file: 86232b32. */
8670 if (aux->info == NULL)
8671 continue;
8672
97c0a079
AM
8673 offset = tp->info.offset;
8674 if (tp->info.section)
8675 {
8676 if (tp->info.section >= filedata->file_header.e_shnum)
8677 {
8678 warn (_("Invalid section %u in table entry %ld\n"),
8679 tp->info.section, (long) (tp - aux->table));
015dc7e1 8680 res = false;
97c0a079
AM
8681 continue;
8682 }
8683 offset += filedata->section_headers[tp->info.section].sh_addr;
8684 }
8685 offset -= aux->info_addr;
53774b7e 8686 /* PR 17531: file: 0997b4d1. */
90679903
AM
8687 if (offset >= aux->info_size
8688 || aux->info_size - offset < 8)
53774b7e
NC
8689 {
8690 warn (_("Invalid offset %lx in table entry %ld\n"),
8691 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8692 res = false;
53774b7e
NC
8693 continue;
8694 }
8695
97c0a079 8696 head = aux->info + offset;
a4a00738 8697 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8698
86f55779 8699 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8700 (unsigned) UNW_VER (stamp),
8701 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8702 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8703 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8704 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8705
8706 if (UNW_VER (stamp) != 1)
8707 {
2b692964 8708 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8709 continue;
8710 }
8711
8712 in_body = 0;
53774b7e
NC
8713 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8714 /* PR 17531: file: 16ceda89. */
8715 if (end > aux->info + aux->info_size)
8716 end = aux->info + aux->info_size;
8717 for (dp = head + 8; dp < end;)
b4477bc8 8718 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8719 }
948f632f
DA
8720
8721 free (aux->funtab);
32ec8896
NC
8722
8723 return res;
4d6ed7c8
NC
8724}
8725
015dc7e1 8726static bool
dda8d76d
NC
8727slurp_ia64_unwind_table (Filedata * filedata,
8728 struct ia64_unw_aux_info * aux,
8729 Elf_Internal_Shdr * sec)
4d6ed7c8 8730{
89fac5e3 8731 unsigned long size, nrelas, i;
2cf0635d
NC
8732 Elf_Internal_Phdr * seg;
8733 struct ia64_unw_table_entry * tep;
8734 Elf_Internal_Shdr * relsec;
8735 Elf_Internal_Rela * rela;
8736 Elf_Internal_Rela * rp;
8737 unsigned char * table;
8738 unsigned char * tp;
8739 Elf_Internal_Sym * sym;
8740 const char * relname;
4d6ed7c8 8741
53774b7e
NC
8742 aux->table_len = 0;
8743
4d6ed7c8
NC
8744 /* First, find the starting address of the segment that includes
8745 this section: */
8746
dda8d76d 8747 if (filedata->file_header.e_phnum)
4d6ed7c8 8748 {
dda8d76d 8749 if (! get_program_headers (filedata))
015dc7e1 8750 return false;
4d6ed7c8 8751
dda8d76d
NC
8752 for (seg = filedata->program_headers;
8753 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8754 ++seg)
4d6ed7c8
NC
8755 {
8756 if (seg->p_type != PT_LOAD)
8757 continue;
8758
8759 if (sec->sh_addr >= seg->p_vaddr
8760 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8761 {
8762 aux->seg_base = seg->p_vaddr;
8763 break;
8764 }
8765 }
4d6ed7c8
NC
8766 }
8767
8768 /* Second, build the unwind table from the contents of the unwind section: */
8769 size = sec->sh_size;
dda8d76d 8770 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8771 _("unwind table"));
a6e9f9df 8772 if (!table)
015dc7e1 8773 return false;
4d6ed7c8 8774
53774b7e 8775 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8776 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8777 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8778 tep = aux->table;
53774b7e
NC
8779
8780 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8781 {
8782 tep->start.section = SHN_UNDEF;
8783 tep->end.section = SHN_UNDEF;
8784 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8785 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8786 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8787 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8788 tep->start.offset += aux->seg_base;
8789 tep->end.offset += aux->seg_base;
8790 tep->info.offset += aux->seg_base;
8791 }
8792 free (table);
8793
41e92641 8794 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8795 for (relsec = filedata->section_headers;
8796 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8797 ++relsec)
8798 {
8799 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8800 || relsec->sh_info >= filedata->file_header.e_shnum
8801 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8802 continue;
8803
dda8d76d 8804 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8805 & rela, & nrelas))
53774b7e
NC
8806 {
8807 free (aux->table);
8808 aux->table = NULL;
8809 aux->table_len = 0;
015dc7e1 8810 return false;
53774b7e 8811 }
4d6ed7c8
NC
8812
8813 for (rp = rela; rp < rela + nrelas; ++rp)
8814 {
4770fb94 8815 unsigned int sym_ndx;
726bd37d
AM
8816 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8817 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8818
82b1b41b
NC
8819 /* PR 17531: file: 9fa67536. */
8820 if (relname == NULL)
8821 {
726bd37d 8822 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8823 continue;
8824 }
948f632f 8825
24d127aa 8826 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8827 {
82b1b41b 8828 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8829 continue;
8830 }
8831
89fac5e3 8832 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8833
53774b7e
NC
8834 /* PR 17531: file: 5bc8d9bf. */
8835 if (i >= aux->table_len)
8836 {
8837 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8838 continue;
8839 }
8840
4770fb94
AM
8841 sym_ndx = get_reloc_symindex (rp->r_info);
8842 if (sym_ndx >= aux->nsyms)
8843 {
8844 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8845 sym_ndx);
8846 continue;
8847 }
8848 sym = aux->symtab + sym_ndx;
8849
53774b7e 8850 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8851 {
8852 case 0:
8853 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8854 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8855 break;
8856 case 1:
8857 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8858 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8859 break;
8860 case 2:
8861 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8862 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8863 break;
8864 default:
8865 break;
8866 }
8867 }
8868
8869 free (rela);
8870 }
8871
015dc7e1 8872 return true;
4d6ed7c8
NC
8873}
8874
015dc7e1 8875static bool
dda8d76d 8876ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8877{
2cf0635d
NC
8878 Elf_Internal_Shdr * sec;
8879 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8880 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8881 struct ia64_unw_aux_info aux;
015dc7e1 8882 bool res = true;
f1467e33 8883
4d6ed7c8
NC
8884 memset (& aux, 0, sizeof (aux));
8885
dda8d76d 8886 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8887 {
28d13567 8888 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8889 {
28d13567 8890 if (aux.symtab)
4082ef84 8891 {
28d13567
AM
8892 error (_("Multiple symbol tables encountered\n"));
8893 free (aux.symtab);
8894 aux.symtab = NULL;
4082ef84 8895 free (aux.strtab);
28d13567 8896 aux.strtab = NULL;
4082ef84 8897 }
28d13567
AM
8898 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8899 &aux.strtab, &aux.strtab_size))
015dc7e1 8900 return false;
4d6ed7c8
NC
8901 }
8902 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8903 unwcount++;
8904 }
8905
8906 if (!unwcount)
8907 printf (_("\nThere are no unwind sections in this file.\n"));
8908
8909 while (unwcount-- > 0)
8910 {
84714f86 8911 const char *suffix;
579f31ac
JJ
8912 size_t len, len2;
8913
dda8d76d
NC
8914 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8915 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8916 if (sec->sh_type == SHT_IA_64_UNWIND)
8917 {
8918 unwsec = sec;
8919 break;
8920 }
4082ef84
NC
8921 /* We have already counted the number of SHT_IA64_UNWIND
8922 sections so the loop above should never fail. */
8923 assert (unwsec != NULL);
579f31ac
JJ
8924
8925 unwstart = i + 1;
8926 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8927
e4b17d5c
L
8928 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8929 {
8930 /* We need to find which section group it is in. */
4082ef84 8931 struct group_list * g;
e4b17d5c 8932
978c4450
AM
8933 if (filedata->section_headers_groups == NULL
8934 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8935 i = filedata->file_header.e_shnum;
4082ef84 8936 else
e4b17d5c 8937 {
978c4450 8938 g = filedata->section_headers_groups[i]->root;
18bd398b 8939
4082ef84
NC
8940 for (; g != NULL; g = g->next)
8941 {
dda8d76d 8942 sec = filedata->section_headers + g->section_index;
e4b17d5c 8943
84714f86
AM
8944 if (section_name_valid (filedata, sec)
8945 && streq (section_name (filedata, sec),
8946 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8947 break;
8948 }
8949
8950 if (g == NULL)
dda8d76d 8951 i = filedata->file_header.e_shnum;
4082ef84 8952 }
e4b17d5c 8953 }
84714f86
AM
8954 else if (section_name_valid (filedata, unwsec)
8955 && startswith (section_name (filedata, unwsec),
e9b095a5 8956 ELF_STRING_ia64_unwind_once))
579f31ac 8957 {
18bd398b 8958 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8959 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8960 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8961 for (i = 0, sec = filedata->section_headers;
8962 i < filedata->file_header.e_shnum;
579f31ac 8963 ++i, ++sec)
84714f86
AM
8964 if (section_name_valid (filedata, sec)
8965 && startswith (section_name (filedata, sec),
e9b095a5 8966 ELF_STRING_ia64_unwind_info_once)
84714f86 8967 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8968 break;
8969 }
8970 else
8971 {
8972 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8973 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8974 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8975 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8976 suffix = "";
84714f86
AM
8977 if (section_name_valid (filedata, unwsec)
8978 && startswith (section_name (filedata, unwsec),
8979 ELF_STRING_ia64_unwind))
8980 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8981 for (i = 0, sec = filedata->section_headers;
8982 i < filedata->file_header.e_shnum;
579f31ac 8983 ++i, ++sec)
84714f86
AM
8984 if (section_name_valid (filedata, sec)
8985 && startswith (section_name (filedata, sec),
8986 ELF_STRING_ia64_unwind_info)
8987 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8988 break;
8989 }
8990
dda8d76d 8991 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8992 {
8993 printf (_("\nCould not find unwind info section for "));
8994
dda8d76d 8995 if (filedata->string_table == NULL)
579f31ac
JJ
8996 printf ("%d", unwsec->sh_name);
8997 else
dda8d76d 8998 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8999 }
9000 else
4d6ed7c8 9001 {
4d6ed7c8 9002 aux.info_addr = sec->sh_addr;
dda8d76d 9003 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9004 sec->sh_size,
9005 _("unwind info"));
59245841 9006 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9007
579f31ac 9008 printf (_("\nUnwind section "));
4d6ed7c8 9009
dda8d76d 9010 if (filedata->string_table == NULL)
579f31ac
JJ
9011 printf ("%d", unwsec->sh_name);
9012 else
dda8d76d 9013 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9014
579f31ac 9015 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 9016 (unsigned long) unwsec->sh_offset,
89fac5e3 9017 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 9018
dda8d76d 9019 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9020 && aux.table_len > 0)
dda8d76d 9021 dump_ia64_unwind (filedata, & aux);
579f31ac 9022
9db70fc3
AM
9023 free ((char *) aux.table);
9024 free ((char *) aux.info);
579f31ac
JJ
9025 aux.table = NULL;
9026 aux.info = NULL;
9027 }
4d6ed7c8 9028 }
4d6ed7c8 9029
9db70fc3
AM
9030 free (aux.symtab);
9031 free ((char *) aux.strtab);
32ec8896
NC
9032
9033 return res;
4d6ed7c8
NC
9034}
9035
3f5e193b 9036struct hppa_unw_table_entry
32ec8896
NC
9037{
9038 struct absaddr start;
9039 struct absaddr end;
9040 unsigned int Cannot_unwind:1; /* 0 */
9041 unsigned int Millicode:1; /* 1 */
9042 unsigned int Millicode_save_sr0:1; /* 2 */
9043 unsigned int Region_description:2; /* 3..4 */
9044 unsigned int reserved1:1; /* 5 */
9045 unsigned int Entry_SR:1; /* 6 */
9046 unsigned int Entry_FR:4; /* Number saved 7..10 */
9047 unsigned int Entry_GR:5; /* Number saved 11..15 */
9048 unsigned int Args_stored:1; /* 16 */
9049 unsigned int Variable_Frame:1; /* 17 */
9050 unsigned int Separate_Package_Body:1; /* 18 */
9051 unsigned int Frame_Extension_Millicode:1; /* 19 */
9052 unsigned int Stack_Overflow_Check:1; /* 20 */
9053 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9054 unsigned int Ada_Region:1; /* 22 */
9055 unsigned int cxx_info:1; /* 23 */
9056 unsigned int cxx_try_catch:1; /* 24 */
9057 unsigned int sched_entry_seq:1; /* 25 */
9058 unsigned int reserved2:1; /* 26 */
9059 unsigned int Save_SP:1; /* 27 */
9060 unsigned int Save_RP:1; /* 28 */
9061 unsigned int Save_MRP_in_frame:1; /* 29 */
9062 unsigned int extn_ptr_defined:1; /* 30 */
9063 unsigned int Cleanup_defined:1; /* 31 */
9064
9065 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9066 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9067 unsigned int Large_frame:1; /* 2 */
9068 unsigned int Pseudo_SP_Set:1; /* 3 */
9069 unsigned int reserved4:1; /* 4 */
9070 unsigned int Total_frame_size:27; /* 5..31 */
9071};
3f5e193b 9072
57346661 9073struct hppa_unw_aux_info
948f632f 9074{
32ec8896
NC
9075 struct hppa_unw_table_entry * table; /* Unwind table. */
9076 unsigned long table_len; /* Length of unwind table. */
625d49fc 9077 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
9078 Elf_Internal_Sym * symtab; /* The symbol table. */
9079 unsigned long nsyms; /* Number of symbols. */
9080 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9081 unsigned long nfuns; /* Number of entries in funtab. */
9082 char * strtab; /* The string table. */
9083 unsigned long strtab_size; /* Size of string table. */
948f632f 9084};
57346661 9085
015dc7e1 9086static bool
dda8d76d 9087dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9088{
2cf0635d 9089 struct hppa_unw_table_entry * tp;
948f632f 9090 unsigned long j, nfuns;
015dc7e1 9091 bool res = true;
948f632f
DA
9092
9093 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9094 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9095 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9096 aux->funtab[nfuns++] = aux->symtab[j];
9097 aux->nfuns = nfuns;
9098 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9099
57346661
AM
9100 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9101 {
625d49fc 9102 uint64_t offset;
2cf0635d 9103 const char * procname;
57346661 9104
dda8d76d 9105 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9106 aux->strtab_size, tp->start, &procname,
9107 &offset);
9108
9109 fputs ("\n<", stdout);
9110
9111 if (procname)
9112 {
9113 fputs (procname, stdout);
9114
9115 if (offset)
9116 printf ("+%lx", (unsigned long) offset);
9117 }
9118
9119 fputs (">: [", stdout);
9120 print_vma (tp->start.offset, PREFIX_HEX);
9121 fputc ('-', stdout);
9122 print_vma (tp->end.offset, PREFIX_HEX);
9123 printf ("]\n\t");
9124
18bd398b
NC
9125#define PF(_m) if (tp->_m) printf (#_m " ");
9126#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9127 PF(Cannot_unwind);
9128 PF(Millicode);
9129 PF(Millicode_save_sr0);
18bd398b 9130 /* PV(Region_description); */
57346661
AM
9131 PF(Entry_SR);
9132 PV(Entry_FR);
9133 PV(Entry_GR);
9134 PF(Args_stored);
9135 PF(Variable_Frame);
9136 PF(Separate_Package_Body);
9137 PF(Frame_Extension_Millicode);
9138 PF(Stack_Overflow_Check);
9139 PF(Two_Instruction_SP_Increment);
9140 PF(Ada_Region);
9141 PF(cxx_info);
9142 PF(cxx_try_catch);
9143 PF(sched_entry_seq);
9144 PF(Save_SP);
9145 PF(Save_RP);
9146 PF(Save_MRP_in_frame);
9147 PF(extn_ptr_defined);
9148 PF(Cleanup_defined);
9149 PF(MPE_XL_interrupt_marker);
9150 PF(HP_UX_interrupt_marker);
9151 PF(Large_frame);
9152 PF(Pseudo_SP_Set);
9153 PV(Total_frame_size);
9154#undef PF
9155#undef PV
9156 }
9157
18bd398b 9158 printf ("\n");
948f632f
DA
9159
9160 free (aux->funtab);
32ec8896
NC
9161
9162 return res;
57346661
AM
9163}
9164
015dc7e1 9165static bool
dda8d76d
NC
9166slurp_hppa_unwind_table (Filedata * filedata,
9167 struct hppa_unw_aux_info * aux,
9168 Elf_Internal_Shdr * sec)
57346661 9169{
1c0751b2 9170 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9171 Elf_Internal_Phdr * seg;
9172 struct hppa_unw_table_entry * tep;
9173 Elf_Internal_Shdr * relsec;
9174 Elf_Internal_Rela * rela;
9175 Elf_Internal_Rela * rp;
9176 unsigned char * table;
9177 unsigned char * tp;
9178 Elf_Internal_Sym * sym;
9179 const char * relname;
57346661 9180
57346661
AM
9181 /* First, find the starting address of the segment that includes
9182 this section. */
dda8d76d 9183 if (filedata->file_header.e_phnum)
57346661 9184 {
dda8d76d 9185 if (! get_program_headers (filedata))
015dc7e1 9186 return false;
57346661 9187
dda8d76d
NC
9188 for (seg = filedata->program_headers;
9189 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9190 ++seg)
9191 {
9192 if (seg->p_type != PT_LOAD)
9193 continue;
9194
9195 if (sec->sh_addr >= seg->p_vaddr
9196 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9197 {
9198 aux->seg_base = seg->p_vaddr;
9199 break;
9200 }
9201 }
9202 }
9203
9204 /* Second, build the unwind table from the contents of the unwind
9205 section. */
9206 size = sec->sh_size;
dda8d76d 9207 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9208 _("unwind table"));
57346661 9209 if (!table)
015dc7e1 9210 return false;
57346661 9211
1c0751b2
DA
9212 unw_ent_size = 16;
9213 nentries = size / unw_ent_size;
9214 size = unw_ent_size * nentries;
57346661 9215
e3fdc001 9216 aux->table_len = nentries;
3f5e193b
NC
9217 tep = aux->table = (struct hppa_unw_table_entry *)
9218 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9219
1c0751b2 9220 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9221 {
9222 unsigned int tmp1, tmp2;
9223
9224 tep->start.section = SHN_UNDEF;
9225 tep->end.section = SHN_UNDEF;
9226
1c0751b2
DA
9227 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9228 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9229 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9230 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9231
9232 tep->start.offset += aux->seg_base;
9233 tep->end.offset += aux->seg_base;
57346661
AM
9234
9235 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9236 tep->Millicode = (tmp1 >> 30) & 0x1;
9237 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9238 tep->Region_description = (tmp1 >> 27) & 0x3;
9239 tep->reserved1 = (tmp1 >> 26) & 0x1;
9240 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9241 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9242 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9243 tep->Args_stored = (tmp1 >> 15) & 0x1;
9244 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9245 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9246 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9247 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9248 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9249 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9250 tep->cxx_info = (tmp1 >> 8) & 0x1;
9251 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9252 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9253 tep->reserved2 = (tmp1 >> 5) & 0x1;
9254 tep->Save_SP = (tmp1 >> 4) & 0x1;
9255 tep->Save_RP = (tmp1 >> 3) & 0x1;
9256 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9257 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9258 tep->Cleanup_defined = tmp1 & 0x1;
9259
9260 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9261 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9262 tep->Large_frame = (tmp2 >> 29) & 0x1;
9263 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9264 tep->reserved4 = (tmp2 >> 27) & 0x1;
9265 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9266 }
9267 free (table);
9268
9269 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9270 for (relsec = filedata->section_headers;
9271 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9272 ++relsec)
9273 {
9274 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9275 || relsec->sh_info >= filedata->file_header.e_shnum
9276 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9277 continue;
9278
dda8d76d 9279 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9280 & rela, & nrelas))
015dc7e1 9281 return false;
57346661
AM
9282
9283 for (rp = rela; rp < rela + nrelas; ++rp)
9284 {
4770fb94 9285 unsigned int sym_ndx;
726bd37d
AM
9286 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9287 relname = elf_hppa_reloc_type (r_type);
57346661 9288
726bd37d
AM
9289 if (relname == NULL)
9290 {
9291 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9292 continue;
9293 }
9294
57346661 9295 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9296 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9297 {
726bd37d 9298 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9299 continue;
9300 }
9301
9302 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9303 if (i >= aux->table_len)
9304 {
9305 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9306 continue;
9307 }
57346661 9308
4770fb94
AM
9309 sym_ndx = get_reloc_symindex (rp->r_info);
9310 if (sym_ndx >= aux->nsyms)
9311 {
9312 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9313 sym_ndx);
9314 continue;
9315 }
9316 sym = aux->symtab + sym_ndx;
9317
43f6cd05 9318 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9319 {
9320 case 0:
9321 aux->table[i].start.section = sym->st_shndx;
1e456d54 9322 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9323 break;
9324 case 1:
9325 aux->table[i].end.section = sym->st_shndx;
1e456d54 9326 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9327 break;
9328 default:
9329 break;
9330 }
9331 }
9332
9333 free (rela);
9334 }
9335
015dc7e1 9336 return true;
57346661
AM
9337}
9338
015dc7e1 9339static bool
dda8d76d 9340hppa_process_unwind (Filedata * filedata)
57346661 9341{
57346661 9342 struct hppa_unw_aux_info aux;
2cf0635d 9343 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9344 Elf_Internal_Shdr * sec;
18bd398b 9345 unsigned long i;
015dc7e1 9346 bool res = true;
57346661 9347
dda8d76d 9348 if (filedata->string_table == NULL)
015dc7e1 9349 return false;
1b31d05e
NC
9350
9351 memset (& aux, 0, sizeof (aux));
57346661 9352
dda8d76d 9353 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9354 {
28d13567 9355 if (sec->sh_type == SHT_SYMTAB)
57346661 9356 {
28d13567 9357 if (aux.symtab)
4082ef84 9358 {
28d13567
AM
9359 error (_("Multiple symbol tables encountered\n"));
9360 free (aux.symtab);
9361 aux.symtab = NULL;
4082ef84 9362 free (aux.strtab);
28d13567 9363 aux.strtab = NULL;
4082ef84 9364 }
28d13567
AM
9365 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9366 &aux.strtab, &aux.strtab_size))
015dc7e1 9367 return false;
57346661 9368 }
84714f86
AM
9369 else if (section_name_valid (filedata, sec)
9370 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9371 unwsec = sec;
9372 }
9373
9374 if (!unwsec)
9375 printf (_("\nThere are no unwind sections in this file.\n"));
9376
dda8d76d 9377 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9378 {
84714f86
AM
9379 if (section_name_valid (filedata, sec)
9380 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9381 {
43f6cd05 9382 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9383
d3a49aa8
AM
9384 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9385 "contains %lu entry:\n",
9386 "\nUnwind section '%s' at offset 0x%lx "
9387 "contains %lu entries:\n",
9388 num_unwind),
dda8d76d 9389 printable_section_name (filedata, sec),
57346661 9390 (unsigned long) sec->sh_offset,
d3a49aa8 9391 num_unwind);
57346661 9392
dda8d76d 9393 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9394 res = false;
66b09c7e
S
9395
9396 if (res && aux.table_len > 0)
32ec8896 9397 {
dda8d76d 9398 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9399 res = false;
32ec8896 9400 }
57346661 9401
9db70fc3 9402 free ((char *) aux.table);
57346661
AM
9403 aux.table = NULL;
9404 }
9405 }
9406
9db70fc3
AM
9407 free (aux.symtab);
9408 free ((char *) aux.strtab);
32ec8896
NC
9409
9410 return res;
57346661
AM
9411}
9412
0b6ae522
DJ
9413struct arm_section
9414{
a734115a
NC
9415 unsigned char * data; /* The unwind data. */
9416 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9417 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9418 unsigned long nrelas; /* The number of relocations. */
9419 unsigned int rel_type; /* REL or RELA ? */
9420 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9421};
9422
9423struct arm_unw_aux_info
9424{
dda8d76d 9425 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9426 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9427 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9428 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9429 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9430 char * strtab; /* The file's string table. */
9431 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9432};
9433
9434static const char *
dda8d76d
NC
9435arm_print_vma_and_name (Filedata * filedata,
9436 struct arm_unw_aux_info * aux,
625d49fc 9437 uint64_t fn,
dda8d76d 9438 struct absaddr addr)
0b6ae522
DJ
9439{
9440 const char *procname;
625d49fc 9441 uint64_t sym_offset;
0b6ae522
DJ
9442
9443 if (addr.section == SHN_UNDEF)
9444 addr.offset = fn;
9445
dda8d76d 9446 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9447 aux->strtab_size, addr, &procname,
9448 &sym_offset);
9449
9450 print_vma (fn, PREFIX_HEX);
9451
9452 if (procname)
9453 {
9454 fputs (" <", stdout);
9455 fputs (procname, stdout);
9456
9457 if (sym_offset)
9458 printf ("+0x%lx", (unsigned long) sym_offset);
9459 fputc ('>', stdout);
9460 }
9461
9462 return procname;
9463}
9464
9465static void
9466arm_free_section (struct arm_section *arm_sec)
9467{
9db70fc3
AM
9468 free (arm_sec->data);
9469 free (arm_sec->rela);
0b6ae522
DJ
9470}
9471
a734115a
NC
9472/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9473 cached section and install SEC instead.
9474 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9475 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9476 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9477 relocation's offset in ADDR.
1b31d05e
NC
9478 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9479 into the string table of the symbol associated with the reloc. If no
9480 reloc was applied store -1 there.
9481 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9482
015dc7e1 9483static bool
dda8d76d
NC
9484get_unwind_section_word (Filedata * filedata,
9485 struct arm_unw_aux_info * aux,
1b31d05e
NC
9486 struct arm_section * arm_sec,
9487 Elf_Internal_Shdr * sec,
625d49fc 9488 uint64_t word_offset,
1b31d05e
NC
9489 unsigned int * wordp,
9490 struct absaddr * addr,
625d49fc 9491 uint64_t * sym_name)
0b6ae522
DJ
9492{
9493 Elf_Internal_Rela *rp;
9494 Elf_Internal_Sym *sym;
9495 const char * relname;
9496 unsigned int word;
015dc7e1 9497 bool wrapped;
0b6ae522 9498
e0a31db1 9499 if (sec == NULL || arm_sec == NULL)
015dc7e1 9500 return false;
e0a31db1 9501
0b6ae522
DJ
9502 addr->section = SHN_UNDEF;
9503 addr->offset = 0;
9504
1b31d05e 9505 if (sym_name != NULL)
625d49fc 9506 *sym_name = (uint64_t) -1;
1b31d05e 9507
a734115a 9508 /* If necessary, update the section cache. */
0b6ae522
DJ
9509 if (sec != arm_sec->sec)
9510 {
9511 Elf_Internal_Shdr *relsec;
9512
9513 arm_free_section (arm_sec);
9514
9515 arm_sec->sec = sec;
dda8d76d 9516 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9517 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9518 arm_sec->rela = NULL;
9519 arm_sec->nrelas = 0;
9520
dda8d76d
NC
9521 for (relsec = filedata->section_headers;
9522 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9523 ++relsec)
9524 {
dda8d76d
NC
9525 if (relsec->sh_info >= filedata->file_header.e_shnum
9526 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9527 /* PR 15745: Check the section type as well. */
9528 || (relsec->sh_type != SHT_REL
9529 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9530 continue;
9531
a734115a 9532 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9533 if (relsec->sh_type == SHT_REL)
9534 {
dda8d76d 9535 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9536 relsec->sh_size,
9537 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9538 return false;
0b6ae522 9539 }
1ae40aa4 9540 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9541 {
dda8d76d 9542 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9543 relsec->sh_size,
9544 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9545 return false;
0b6ae522 9546 }
1ae40aa4 9547 break;
0b6ae522
DJ
9548 }
9549
9550 arm_sec->next_rela = arm_sec->rela;
9551 }
9552
a734115a 9553 /* If there is no unwind data we can do nothing. */
0b6ae522 9554 if (arm_sec->data == NULL)
015dc7e1 9555 return false;
0b6ae522 9556
e0a31db1 9557 /* If the offset is invalid then fail. */
f32ba729
NC
9558 if (/* PR 21343 *//* PR 18879 */
9559 sec->sh_size < 4
625d49fc 9560 || word_offset > sec->sh_size - 4)
015dc7e1 9561 return false;
e0a31db1 9562
a734115a 9563 /* Get the word at the required offset. */
0b6ae522
DJ
9564 word = byte_get (arm_sec->data + word_offset, 4);
9565
0eff7165
NC
9566 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9567 if (arm_sec->rela == NULL)
9568 {
9569 * wordp = word;
015dc7e1 9570 return true;
0eff7165
NC
9571 }
9572
a734115a 9573 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9574 wrapped = false;
0b6ae522
DJ
9575 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9576 {
625d49fc 9577 uint64_t prelval, offset;
0b6ae522
DJ
9578
9579 if (rp->r_offset > word_offset && !wrapped)
9580 {
9581 rp = arm_sec->rela;
015dc7e1 9582 wrapped = true;
0b6ae522
DJ
9583 }
9584 if (rp->r_offset > word_offset)
9585 break;
9586
9587 if (rp->r_offset & 3)
9588 {
9589 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9590 (unsigned long) rp->r_offset);
9591 continue;
9592 }
9593
9594 if (rp->r_offset < word_offset)
9595 continue;
9596
74e1a04b
NC
9597 /* PR 17531: file: 027-161405-0.004 */
9598 if (aux->symtab == NULL)
9599 continue;
9600
0b6ae522
DJ
9601 if (arm_sec->rel_type == SHT_REL)
9602 {
9603 offset = word & 0x7fffffff;
9604 if (offset & 0x40000000)
625d49fc 9605 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9606 }
a734115a 9607 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9608 offset = rp->r_addend;
a734115a 9609 else
74e1a04b
NC
9610 {
9611 error (_("Unknown section relocation type %d encountered\n"),
9612 arm_sec->rel_type);
9613 break;
9614 }
0b6ae522 9615
071436c6
NC
9616 /* PR 17531 file: 027-1241568-0.004. */
9617 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9618 {
9619 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9620 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9621 break;
9622 }
9623
9624 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9625 offset += sym->st_value;
9626 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9627
a734115a 9628 /* Check that we are processing the expected reloc type. */
dda8d76d 9629 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9630 {
9631 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9632 if (relname == NULL)
9633 {
9634 warn (_("Skipping unknown ARM relocation type: %d\n"),
9635 (int) ELF32_R_TYPE (rp->r_info));
9636 continue;
9637 }
a734115a
NC
9638
9639 if (streq (relname, "R_ARM_NONE"))
9640 continue;
0b4362b0 9641
a734115a
NC
9642 if (! streq (relname, "R_ARM_PREL31"))
9643 {
071436c6 9644 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9645 continue;
9646 }
9647 }
dda8d76d 9648 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9649 {
9650 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9651 if (relname == NULL)
9652 {
9653 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9654 (int) ELF32_R_TYPE (rp->r_info));
9655 continue;
9656 }
0b4362b0 9657
a734115a
NC
9658 if (streq (relname, "R_C6000_NONE"))
9659 continue;
9660
9661 if (! streq (relname, "R_C6000_PREL31"))
9662 {
071436c6 9663 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9664 continue;
9665 }
9666
9667 prelval >>= 1;
9668 }
9669 else
74e1a04b
NC
9670 {
9671 /* This function currently only supports ARM and TI unwinders. */
9672 warn (_("Only TI and ARM unwinders are currently supported\n"));
9673 break;
9674 }
fa197c1c 9675
625d49fc 9676 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9677 addr->section = sym->st_shndx;
9678 addr->offset = offset;
74e1a04b 9679
1b31d05e
NC
9680 if (sym_name)
9681 * sym_name = sym->st_name;
0b6ae522
DJ
9682 break;
9683 }
9684
9685 *wordp = word;
9686 arm_sec->next_rela = rp;
9687
015dc7e1 9688 return true;
0b6ae522
DJ
9689}
9690
a734115a
NC
9691static const char *tic6x_unwind_regnames[16] =
9692{
0b4362b0
RM
9693 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9694 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9695 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9696};
fa197c1c 9697
0b6ae522 9698static void
fa197c1c 9699decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9700{
fa197c1c
PB
9701 int i;
9702
9703 for (i = 12; mask; mask >>= 1, i--)
9704 {
9705 if (mask & 1)
9706 {
9707 fputs (tic6x_unwind_regnames[i], stdout);
9708 if (mask > 1)
9709 fputs (", ", stdout);
9710 }
9711 }
9712}
0b6ae522
DJ
9713
9714#define ADVANCE \
9715 if (remaining == 0 && more_words) \
9716 { \
9717 data_offset += 4; \
dda8d76d 9718 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9719 data_offset, & word, & addr, NULL)) \
015dc7e1 9720 return false; \
0b6ae522
DJ
9721 remaining = 4; \
9722 more_words--; \
9723 } \
9724
9725#define GET_OP(OP) \
9726 ADVANCE; \
9727 if (remaining) \
9728 { \
9729 remaining--; \
9730 (OP) = word >> 24; \
9731 word <<= 8; \
9732 } \
9733 else \
9734 { \
2b692964 9735 printf (_("[Truncated opcode]\n")); \
015dc7e1 9736 return false; \
0b6ae522 9737 } \
cc5914eb 9738 printf ("0x%02x ", OP)
0b6ae522 9739
015dc7e1 9740static bool
dda8d76d
NC
9741decode_arm_unwind_bytecode (Filedata * filedata,
9742 struct arm_unw_aux_info * aux,
948f632f
DA
9743 unsigned int word,
9744 unsigned int remaining,
9745 unsigned int more_words,
625d49fc 9746 uint64_t data_offset,
948f632f
DA
9747 Elf_Internal_Shdr * data_sec,
9748 struct arm_section * data_arm_sec)
fa197c1c
PB
9749{
9750 struct absaddr addr;
015dc7e1 9751 bool res = true;
0b6ae522
DJ
9752
9753 /* Decode the unwinding instructions. */
9754 while (1)
9755 {
9756 unsigned int op, op2;
9757
9758 ADVANCE;
9759 if (remaining == 0)
9760 break;
9761 remaining--;
9762 op = word >> 24;
9763 word <<= 8;
9764
cc5914eb 9765 printf (" 0x%02x ", op);
0b6ae522
DJ
9766
9767 if ((op & 0xc0) == 0x00)
9768 {
9769 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9770
cc5914eb 9771 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9772 }
9773 else if ((op & 0xc0) == 0x40)
9774 {
9775 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9776
cc5914eb 9777 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9778 }
9779 else if ((op & 0xf0) == 0x80)
9780 {
9781 GET_OP (op2);
9782 if (op == 0x80 && op2 == 0)
9783 printf (_("Refuse to unwind"));
9784 else
9785 {
9786 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9787 bool first = true;
0b6ae522 9788 int i;
2b692964 9789
0b6ae522
DJ
9790 printf ("pop {");
9791 for (i = 0; i < 12; i++)
9792 if (mask & (1 << i))
9793 {
9794 if (first)
015dc7e1 9795 first = false;
0b6ae522
DJ
9796 else
9797 printf (", ");
9798 printf ("r%d", 4 + i);
9799 }
9800 printf ("}");
9801 }
9802 }
9803 else if ((op & 0xf0) == 0x90)
9804 {
9805 if (op == 0x9d || op == 0x9f)
9806 printf (_(" [Reserved]"));
9807 else
cc5914eb 9808 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9809 }
9810 else if ((op & 0xf0) == 0xa0)
9811 {
9812 int end = 4 + (op & 0x07);
015dc7e1 9813 bool first = true;
0b6ae522 9814 int i;
61865e30 9815
0b6ae522
DJ
9816 printf (" pop {");
9817 for (i = 4; i <= end; i++)
9818 {
9819 if (first)
015dc7e1 9820 first = false;
0b6ae522
DJ
9821 else
9822 printf (", ");
9823 printf ("r%d", i);
9824 }
9825 if (op & 0x08)
9826 {
1b31d05e 9827 if (!first)
0b6ae522
DJ
9828 printf (", ");
9829 printf ("r14");
9830 }
9831 printf ("}");
9832 }
9833 else if (op == 0xb0)
9834 printf (_(" finish"));
9835 else if (op == 0xb1)
9836 {
9837 GET_OP (op2);
9838 if (op2 == 0 || (op2 & 0xf0) != 0)
9839 printf (_("[Spare]"));
9840 else
9841 {
9842 unsigned int mask = op2 & 0x0f;
015dc7e1 9843 bool first = true;
0b6ae522 9844 int i;
61865e30 9845
0b6ae522
DJ
9846 printf ("pop {");
9847 for (i = 0; i < 12; i++)
9848 if (mask & (1 << i))
9849 {
9850 if (first)
015dc7e1 9851 first = false;
0b6ae522
DJ
9852 else
9853 printf (", ");
9854 printf ("r%d", i);
9855 }
9856 printf ("}");
9857 }
9858 }
9859 else if (op == 0xb2)
9860 {
b115cf96 9861 unsigned char buf[9];
0b6ae522
DJ
9862 unsigned int i, len;
9863 unsigned long offset;
61865e30 9864
b115cf96 9865 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9866 {
9867 GET_OP (buf[i]);
9868 if ((buf[i] & 0x80) == 0)
9869 break;
9870 }
4082ef84 9871 if (i == sizeof (buf))
32ec8896 9872 {
27a45f42 9873 error (_("corrupt change to vsp\n"));
015dc7e1 9874 res = false;
32ec8896 9875 }
4082ef84
NC
9876 else
9877 {
015dc7e1 9878 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9879 assert (len == i + 1);
9880 offset = offset * 4 + 0x204;
9881 printf ("vsp = vsp + %ld", offset);
9882 }
0b6ae522 9883 }
61865e30 9884 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9885 {
61865e30
NC
9886 unsigned int first, last;
9887
9888 GET_OP (op2);
9889 first = op2 >> 4;
9890 last = op2 & 0x0f;
9891 if (op == 0xc8)
9892 first = first + 16;
9893 printf ("pop {D%d", first);
9894 if (last)
9895 printf ("-D%d", first + last);
9896 printf ("}");
9897 }
09854a88
TB
9898 else if (op == 0xb4)
9899 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9900 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9901 {
9902 unsigned int count = op & 0x07;
9903
9904 printf ("pop {D8");
9905 if (count)
9906 printf ("-D%d", 8 + count);
9907 printf ("}");
9908 }
9909 else if (op >= 0xc0 && op <= 0xc5)
9910 {
9911 unsigned int count = op & 0x07;
9912
9913 printf (" pop {wR10");
9914 if (count)
9915 printf ("-wR%d", 10 + count);
9916 printf ("}");
9917 }
9918 else if (op == 0xc6)
9919 {
9920 unsigned int first, last;
9921
9922 GET_OP (op2);
9923 first = op2 >> 4;
9924 last = op2 & 0x0f;
9925 printf ("pop {wR%d", first);
9926 if (last)
9927 printf ("-wR%d", first + last);
9928 printf ("}");
9929 }
9930 else if (op == 0xc7)
9931 {
9932 GET_OP (op2);
9933 if (op2 == 0 || (op2 & 0xf0) != 0)
9934 printf (_("[Spare]"));
0b6ae522
DJ
9935 else
9936 {
61865e30 9937 unsigned int mask = op2 & 0x0f;
015dc7e1 9938 bool first = true;
61865e30
NC
9939 int i;
9940
9941 printf ("pop {");
9942 for (i = 0; i < 4; i++)
9943 if (mask & (1 << i))
9944 {
9945 if (first)
015dc7e1 9946 first = false;
61865e30
NC
9947 else
9948 printf (", ");
9949 printf ("wCGR%d", i);
9950 }
9951 printf ("}");
0b6ae522
DJ
9952 }
9953 }
61865e30 9954 else
32ec8896
NC
9955 {
9956 printf (_(" [unsupported opcode]"));
015dc7e1 9957 res = false;
32ec8896
NC
9958 }
9959
0b6ae522
DJ
9960 printf ("\n");
9961 }
32ec8896
NC
9962
9963 return res;
fa197c1c
PB
9964}
9965
015dc7e1 9966static bool
dda8d76d
NC
9967decode_tic6x_unwind_bytecode (Filedata * filedata,
9968 struct arm_unw_aux_info * aux,
948f632f
DA
9969 unsigned int word,
9970 unsigned int remaining,
9971 unsigned int more_words,
625d49fc 9972 uint64_t data_offset,
948f632f
DA
9973 Elf_Internal_Shdr * data_sec,
9974 struct arm_section * data_arm_sec)
fa197c1c
PB
9975{
9976 struct absaddr addr;
9977
9978 /* Decode the unwinding instructions. */
9979 while (1)
9980 {
9981 unsigned int op, op2;
9982
9983 ADVANCE;
9984 if (remaining == 0)
9985 break;
9986 remaining--;
9987 op = word >> 24;
9988 word <<= 8;
9989
9cf03b7e 9990 printf (" 0x%02x ", op);
fa197c1c
PB
9991
9992 if ((op & 0xc0) == 0x00)
9993 {
9994 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9995 printf (" sp = sp + %d", offset);
fa197c1c
PB
9996 }
9997 else if ((op & 0xc0) == 0x80)
9998 {
9999 GET_OP (op2);
10000 if (op == 0x80 && op2 == 0)
10001 printf (_("Refuse to unwind"));
10002 else
10003 {
10004 unsigned int mask = ((op & 0x1f) << 8) | op2;
10005 if (op & 0x20)
10006 printf ("pop compact {");
10007 else
10008 printf ("pop {");
10009
10010 decode_tic6x_unwind_regmask (mask);
10011 printf("}");
10012 }
10013 }
10014 else if ((op & 0xf0) == 0xc0)
10015 {
10016 unsigned int reg;
10017 unsigned int nregs;
10018 unsigned int i;
10019 const char *name;
a734115a
NC
10020 struct
10021 {
32ec8896
NC
10022 unsigned int offset;
10023 unsigned int reg;
fa197c1c
PB
10024 } regpos[16];
10025
10026 /* Scan entire instruction first so that GET_OP output is not
10027 interleaved with disassembly. */
10028 nregs = 0;
10029 for (i = 0; nregs < (op & 0xf); i++)
10030 {
10031 GET_OP (op2);
10032 reg = op2 >> 4;
10033 if (reg != 0xf)
10034 {
10035 regpos[nregs].offset = i * 2;
10036 regpos[nregs].reg = reg;
10037 nregs++;
10038 }
10039
10040 reg = op2 & 0xf;
10041 if (reg != 0xf)
10042 {
10043 regpos[nregs].offset = i * 2 + 1;
10044 regpos[nregs].reg = reg;
10045 nregs++;
10046 }
10047 }
10048
10049 printf (_("pop frame {"));
18344509 10050 if (nregs == 0)
fa197c1c 10051 {
18344509
NC
10052 printf (_("*corrupt* - no registers specified"));
10053 }
10054 else
10055 {
10056 reg = nregs - 1;
10057 for (i = i * 2; i > 0; i--)
fa197c1c 10058 {
18344509
NC
10059 if (regpos[reg].offset == i - 1)
10060 {
10061 name = tic6x_unwind_regnames[regpos[reg].reg];
10062 if (reg > 0)
10063 reg--;
10064 }
10065 else
10066 name = _("[pad]");
fa197c1c 10067
18344509
NC
10068 fputs (name, stdout);
10069 if (i > 1)
10070 printf (", ");
10071 }
fa197c1c
PB
10072 }
10073
10074 printf ("}");
10075 }
10076 else if (op == 0xd0)
10077 printf (" MOV FP, SP");
10078 else if (op == 0xd1)
10079 printf (" __c6xabi_pop_rts");
10080 else if (op == 0xd2)
10081 {
10082 unsigned char buf[9];
10083 unsigned int i, len;
10084 unsigned long offset;
a734115a 10085
fa197c1c
PB
10086 for (i = 0; i < sizeof (buf); i++)
10087 {
10088 GET_OP (buf[i]);
10089 if ((buf[i] & 0x80) == 0)
10090 break;
10091 }
0eff7165
NC
10092 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10093 if (i == sizeof (buf))
10094 {
0eff7165 10095 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10096 return false;
0eff7165 10097 }
948f632f 10098
015dc7e1 10099 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10100 assert (len == i + 1);
10101 offset = offset * 8 + 0x408;
10102 printf (_("sp = sp + %ld"), offset);
10103 }
10104 else if ((op & 0xf0) == 0xe0)
10105 {
10106 if ((op & 0x0f) == 7)
10107 printf (" RETURN");
10108 else
10109 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10110 }
10111 else
10112 {
10113 printf (_(" [unsupported opcode]"));
10114 }
10115 putchar ('\n');
10116 }
32ec8896 10117
015dc7e1 10118 return true;
fa197c1c
PB
10119}
10120
625d49fc
AM
10121static uint64_t
10122arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10123{
625d49fc 10124 uint64_t offset;
fa197c1c
PB
10125
10126 offset = word & 0x7fffffff;
10127 if (offset & 0x40000000)
625d49fc 10128 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10129
dda8d76d 10130 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10131 offset <<= 1;
10132
10133 return offset + where;
10134}
10135
015dc7e1 10136static bool
dda8d76d
NC
10137decode_arm_unwind (Filedata * filedata,
10138 struct arm_unw_aux_info * aux,
1b31d05e
NC
10139 unsigned int word,
10140 unsigned int remaining,
625d49fc 10141 uint64_t data_offset,
1b31d05e
NC
10142 Elf_Internal_Shdr * data_sec,
10143 struct arm_section * data_arm_sec)
fa197c1c
PB
10144{
10145 int per_index;
10146 unsigned int more_words = 0;
37e14bc3 10147 struct absaddr addr;
625d49fc 10148 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10149 bool res = true;
fa197c1c
PB
10150
10151 if (remaining == 0)
10152 {
1b31d05e
NC
10153 /* Fetch the first word.
10154 Note - when decoding an object file the address extracted
10155 here will always be 0. So we also pass in the sym_name
10156 parameter so that we can find the symbol associated with
10157 the personality routine. */
dda8d76d 10158 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10159 & word, & addr, & sym_name))
015dc7e1 10160 return false;
1b31d05e 10161
fa197c1c
PB
10162 remaining = 4;
10163 }
c93dbb25
CZ
10164 else
10165 {
10166 addr.section = SHN_UNDEF;
10167 addr.offset = 0;
10168 }
fa197c1c
PB
10169
10170 if ((word & 0x80000000) == 0)
10171 {
10172 /* Expand prel31 for personality routine. */
625d49fc 10173 uint64_t fn;
fa197c1c
PB
10174 const char *procname;
10175
dda8d76d 10176 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10177 printf (_(" Personality routine: "));
1b31d05e
NC
10178 if (fn == 0
10179 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10180 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10181 {
10182 procname = aux->strtab + sym_name;
10183 print_vma (fn, PREFIX_HEX);
10184 if (procname)
10185 {
10186 fputs (" <", stdout);
10187 fputs (procname, stdout);
10188 fputc ('>', stdout);
10189 }
10190 }
10191 else
dda8d76d 10192 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10193 fputc ('\n', stdout);
10194
10195 /* The GCC personality routines use the standard compact
10196 encoding, starting with one byte giving the number of
10197 words. */
10198 if (procname != NULL
24d127aa
ML
10199 && (startswith (procname, "__gcc_personality_v0")
10200 || startswith (procname, "__gxx_personality_v0")
10201 || startswith (procname, "__gcj_personality_v0")
10202 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10203 {
10204 remaining = 0;
10205 more_words = 1;
10206 ADVANCE;
10207 if (!remaining)
10208 {
10209 printf (_(" [Truncated data]\n"));
015dc7e1 10210 return false;
fa197c1c
PB
10211 }
10212 more_words = word >> 24;
10213 word <<= 8;
10214 remaining--;
10215 per_index = -1;
10216 }
10217 else
015dc7e1 10218 return true;
fa197c1c
PB
10219 }
10220 else
10221 {
1b31d05e 10222 /* ARM EHABI Section 6.3:
0b4362b0 10223
1b31d05e 10224 An exception-handling table entry for the compact model looks like:
0b4362b0 10225
1b31d05e
NC
10226 31 30-28 27-24 23-0
10227 -- ----- ----- ----
10228 1 0 index Data for personalityRoutine[index] */
10229
dda8d76d 10230 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10231 && (word & 0x70000000))
32ec8896
NC
10232 {
10233 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10234 res = false;
32ec8896 10235 }
1b31d05e 10236
fa197c1c 10237 per_index = (word >> 24) & 0x7f;
1b31d05e 10238 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10239 if (per_index == 0)
10240 {
10241 more_words = 0;
10242 word <<= 8;
10243 remaining--;
10244 }
10245 else if (per_index < 3)
10246 {
10247 more_words = (word >> 16) & 0xff;
10248 word <<= 16;
10249 remaining -= 2;
10250 }
10251 }
10252
dda8d76d 10253 switch (filedata->file_header.e_machine)
fa197c1c
PB
10254 {
10255 case EM_ARM:
10256 if (per_index < 3)
10257 {
dda8d76d 10258 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10259 data_offset, data_sec, data_arm_sec))
015dc7e1 10260 res = false;
fa197c1c
PB
10261 }
10262 else
1b31d05e
NC
10263 {
10264 warn (_("Unknown ARM compact model index encountered\n"));
10265 printf (_(" [reserved]\n"));
015dc7e1 10266 res = false;
1b31d05e 10267 }
fa197c1c
PB
10268 break;
10269
10270 case EM_TI_C6000:
10271 if (per_index < 3)
10272 {
dda8d76d 10273 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10274 data_offset, data_sec, data_arm_sec))
015dc7e1 10275 res = false;
fa197c1c
PB
10276 }
10277 else if (per_index < 5)
10278 {
10279 if (((word >> 17) & 0x7f) == 0x7f)
10280 printf (_(" Restore stack from frame pointer\n"));
10281 else
10282 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10283 printf (_(" Registers restored: "));
10284 if (per_index == 4)
10285 printf (" (compact) ");
10286 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10287 putchar ('\n');
10288 printf (_(" Return register: %s\n"),
10289 tic6x_unwind_regnames[word & 0xf]);
10290 }
10291 else
1b31d05e 10292 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10293 break;
10294
10295 default:
74e1a04b 10296 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10297 filedata->file_header.e_machine);
015dc7e1 10298 res = false;
fa197c1c 10299 }
0b6ae522
DJ
10300
10301 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10302
10303 return res;
0b6ae522
DJ
10304}
10305
015dc7e1 10306static bool
dda8d76d
NC
10307dump_arm_unwind (Filedata * filedata,
10308 struct arm_unw_aux_info * aux,
10309 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10310{
10311 struct arm_section exidx_arm_sec, extab_arm_sec;
10312 unsigned int i, exidx_len;
948f632f 10313 unsigned long j, nfuns;
015dc7e1 10314 bool res = true;
0b6ae522
DJ
10315
10316 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10317 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10318 exidx_len = exidx_sec->sh_size / 8;
10319
948f632f
DA
10320 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10321 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10322 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10323 aux->funtab[nfuns++] = aux->symtab[j];
10324 aux->nfuns = nfuns;
10325 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10326
0b6ae522
DJ
10327 for (i = 0; i < exidx_len; i++)
10328 {
10329 unsigned int exidx_fn, exidx_entry;
10330 struct absaddr fn_addr, entry_addr;
625d49fc 10331 uint64_t fn;
0b6ae522
DJ
10332
10333 fputc ('\n', stdout);
10334
dda8d76d 10335 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10336 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10337 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10338 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10339 {
948f632f 10340 free (aux->funtab);
1b31d05e
NC
10341 arm_free_section (& exidx_arm_sec);
10342 arm_free_section (& extab_arm_sec);
015dc7e1 10343 return false;
0b6ae522
DJ
10344 }
10345
83c257ca
NC
10346 /* ARM EHABI, Section 5:
10347 An index table entry consists of 2 words.
10348 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10349 if (exidx_fn & 0x80000000)
32ec8896
NC
10350 {
10351 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10352 res = false;
32ec8896 10353 }
83c257ca 10354
dda8d76d 10355 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10356
dda8d76d 10357 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10358 fputs (": ", stdout);
10359
10360 if (exidx_entry == 1)
10361 {
10362 print_vma (exidx_entry, PREFIX_HEX);
10363 fputs (" [cantunwind]\n", stdout);
10364 }
10365 else if (exidx_entry & 0x80000000)
10366 {
10367 print_vma (exidx_entry, PREFIX_HEX);
10368 fputc ('\n', stdout);
dda8d76d 10369 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10370 }
10371 else
10372 {
625d49fc 10373 uint64_t table, table_offset = 0;
0b6ae522
DJ
10374 Elf_Internal_Shdr *table_sec;
10375
10376 fputs ("@", stdout);
dda8d76d 10377 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10378 print_vma (table, PREFIX_HEX);
10379 printf ("\n");
10380
10381 /* Locate the matching .ARM.extab. */
10382 if (entry_addr.section != SHN_UNDEF
dda8d76d 10383 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10384 {
dda8d76d 10385 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10386 table_offset = entry_addr.offset;
1a915552 10387 /* PR 18879 */
625d49fc 10388 if (table_offset > table_sec->sh_size)
1a915552
NC
10389 {
10390 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10391 (unsigned long) table_offset,
dda8d76d 10392 printable_section_name (filedata, table_sec));
015dc7e1 10393 res = false;
1a915552
NC
10394 continue;
10395 }
0b6ae522
DJ
10396 }
10397 else
10398 {
dda8d76d 10399 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10400 if (table_sec != NULL)
10401 table_offset = table - table_sec->sh_addr;
10402 }
32ec8896 10403
0b6ae522
DJ
10404 if (table_sec == NULL)
10405 {
10406 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10407 (unsigned long) table);
015dc7e1 10408 res = false;
0b6ae522
DJ
10409 continue;
10410 }
32ec8896 10411
dda8d76d 10412 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10413 &extab_arm_sec))
015dc7e1 10414 res = false;
0b6ae522
DJ
10415 }
10416 }
10417
10418 printf ("\n");
10419
948f632f 10420 free (aux->funtab);
0b6ae522
DJ
10421 arm_free_section (&exidx_arm_sec);
10422 arm_free_section (&extab_arm_sec);
32ec8896
NC
10423
10424 return res;
0b6ae522
DJ
10425}
10426
fa197c1c 10427/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10428
015dc7e1 10429static bool
dda8d76d 10430arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10431{
10432 struct arm_unw_aux_info aux;
10433 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10434 Elf_Internal_Shdr *sec;
10435 unsigned long i;
fa197c1c 10436 unsigned int sec_type;
015dc7e1 10437 bool res = true;
0b6ae522 10438
dda8d76d 10439 switch (filedata->file_header.e_machine)
fa197c1c
PB
10440 {
10441 case EM_ARM:
10442 sec_type = SHT_ARM_EXIDX;
10443 break;
10444
10445 case EM_TI_C6000:
10446 sec_type = SHT_C6000_UNWIND;
10447 break;
10448
0b4362b0 10449 default:
74e1a04b 10450 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10451 filedata->file_header.e_machine);
015dc7e1 10452 return false;
fa197c1c
PB
10453 }
10454
dda8d76d 10455 if (filedata->string_table == NULL)
015dc7e1 10456 return false;
1b31d05e
NC
10457
10458 memset (& aux, 0, sizeof (aux));
dda8d76d 10459 aux.filedata = filedata;
0b6ae522 10460
dda8d76d 10461 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10462 {
28d13567 10463 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10464 {
28d13567 10465 if (aux.symtab)
74e1a04b 10466 {
28d13567
AM
10467 error (_("Multiple symbol tables encountered\n"));
10468 free (aux.symtab);
10469 aux.symtab = NULL;
74e1a04b 10470 free (aux.strtab);
28d13567 10471 aux.strtab = NULL;
74e1a04b 10472 }
28d13567
AM
10473 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10474 &aux.strtab, &aux.strtab_size))
015dc7e1 10475 return false;
0b6ae522 10476 }
fa197c1c 10477 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10478 unwsec = sec;
10479 }
10480
1b31d05e 10481 if (unwsec == NULL)
0b6ae522 10482 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10483 else
dda8d76d 10484 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10485 {
10486 if (sec->sh_type == sec_type)
10487 {
d3a49aa8
AM
10488 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10489 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10490 "contains %lu entry:\n",
10491 "\nUnwind section '%s' at offset 0x%lx "
10492 "contains %lu entries:\n",
10493 num_unwind),
dda8d76d 10494 printable_section_name (filedata, sec),
1b31d05e 10495 (unsigned long) sec->sh_offset,
d3a49aa8 10496 num_unwind);
0b6ae522 10497
dda8d76d 10498 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10499 res = false;
1b31d05e
NC
10500 }
10501 }
0b6ae522 10502
9db70fc3
AM
10503 free (aux.symtab);
10504 free ((char *) aux.strtab);
32ec8896
NC
10505
10506 return res;
0b6ae522
DJ
10507}
10508
3ecc00ec
NC
10509static bool
10510no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10511{
10512 printf (_("No processor specific unwind information to decode\n"));
10513 return true;
10514}
10515
015dc7e1 10516static bool
dda8d76d 10517process_unwind (Filedata * filedata)
57346661 10518{
2cf0635d
NC
10519 struct unwind_handler
10520 {
32ec8896 10521 unsigned int machtype;
015dc7e1 10522 bool (* handler)(Filedata *);
2cf0635d
NC
10523 } handlers[] =
10524 {
0b6ae522 10525 { EM_ARM, arm_process_unwind },
57346661
AM
10526 { EM_IA_64, ia64_process_unwind },
10527 { EM_PARISC, hppa_process_unwind },
fa197c1c 10528 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10529 { EM_386, no_processor_specific_unwind },
10530 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10531 { 0, NULL }
57346661
AM
10532 };
10533 int i;
10534
10535 if (!do_unwind)
015dc7e1 10536 return true;
57346661
AM
10537
10538 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10539 if (filedata->file_header.e_machine == handlers[i].machtype)
10540 return handlers[i].handler (filedata);
57346661 10541
1b31d05e 10542 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10543 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10544 return true;
57346661
AM
10545}
10546
37c18eed
SD
10547static void
10548dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10549{
10550 switch (entry->d_tag)
10551 {
10552 case DT_AARCH64_BTI_PLT:
1dbade74 10553 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10554 break;
10555 default:
10556 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10557 break;
10558 }
10559 putchar ('\n');
10560}
10561
252b5132 10562static void
978c4450 10563dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10564{
10565 switch (entry->d_tag)
10566 {
10567 case DT_MIPS_FLAGS:
10568 if (entry->d_un.d_val == 0)
4b68bca3 10569 printf (_("NONE"));
252b5132
RH
10570 else
10571 {
10572 static const char * opts[] =
10573 {
10574 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10575 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10576 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10577 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10578 "RLD_ORDER_SAFE"
10579 };
10580 unsigned int cnt;
015dc7e1 10581 bool first = true;
2b692964 10582
60bca95a 10583 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10584 if (entry->d_un.d_val & (1 << cnt))
10585 {
10586 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10587 first = false;
252b5132 10588 }
252b5132
RH
10589 }
10590 break;
103f02d3 10591
252b5132 10592 case DT_MIPS_IVERSION:
84714f86 10593 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10594 printf (_("Interface Version: %s"),
84714f86 10595 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10596 else
f493c217 10597 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10598 entry->d_un.d_ptr);
252b5132 10599 break;
103f02d3 10600
252b5132
RH
10601 case DT_MIPS_TIME_STAMP:
10602 {
d5b07ef4 10603 char timebuf[128];
2cf0635d 10604 struct tm * tmp;
91d6fa6a 10605 time_t atime = entry->d_un.d_val;
82b1b41b 10606
91d6fa6a 10607 tmp = gmtime (&atime);
82b1b41b
NC
10608 /* PR 17531: file: 6accc532. */
10609 if (tmp == NULL)
10610 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10611 else
10612 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10613 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10614 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10615 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10616 }
10617 break;
103f02d3 10618
252b5132
RH
10619 case DT_MIPS_RLD_VERSION:
10620 case DT_MIPS_LOCAL_GOTNO:
10621 case DT_MIPS_CONFLICTNO:
10622 case DT_MIPS_LIBLISTNO:
10623 case DT_MIPS_SYMTABNO:
10624 case DT_MIPS_UNREFEXTNO:
10625 case DT_MIPS_HIPAGENO:
10626 case DT_MIPS_DELTA_CLASS_NO:
10627 case DT_MIPS_DELTA_INSTANCE_NO:
10628 case DT_MIPS_DELTA_RELOC_NO:
10629 case DT_MIPS_DELTA_SYM_NO:
10630 case DT_MIPS_DELTA_CLASSSYM_NO:
10631 case DT_MIPS_COMPACT_SIZE:
c69075ac 10632 print_vma (entry->d_un.d_val, DEC);
252b5132 10633 break;
103f02d3 10634
f16a9783 10635 case DT_MIPS_XHASH:
978c4450
AM
10636 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10637 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10638 /* Falls through. */
10639
103f02d3 10640 default:
4b68bca3 10641 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10642 }
4b68bca3 10643 putchar ('\n');
103f02d3
UD
10644}
10645
103f02d3 10646static void
2cf0635d 10647dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10648{
10649 switch (entry->d_tag)
10650 {
10651 case DT_HP_DLD_FLAGS:
10652 {
10653 static struct
10654 {
10655 long int bit;
2cf0635d 10656 const char * str;
5e220199
NC
10657 }
10658 flags[] =
10659 {
10660 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10661 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10662 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10663 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10664 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10665 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10666 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10667 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10668 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10669 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10670 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10671 { DT_HP_GST, "HP_GST" },
10672 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10673 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10674 { DT_HP_NODELETE, "HP_NODELETE" },
10675 { DT_HP_GROUP, "HP_GROUP" },
10676 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10677 };
015dc7e1 10678 bool first = true;
5e220199 10679 size_t cnt;
625d49fc 10680 uint64_t val = entry->d_un.d_val;
103f02d3 10681
60bca95a 10682 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10683 if (val & flags[cnt].bit)
30800947
NC
10684 {
10685 if (! first)
10686 putchar (' ');
10687 fputs (flags[cnt].str, stdout);
015dc7e1 10688 first = false;
30800947
NC
10689 val ^= flags[cnt].bit;
10690 }
76da6bbe 10691
103f02d3 10692 if (val != 0 || first)
f7a99963
NC
10693 {
10694 if (! first)
10695 putchar (' ');
10696 print_vma (val, HEX);
10697 }
103f02d3
UD
10698 }
10699 break;
76da6bbe 10700
252b5132 10701 default:
f7a99963
NC
10702 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10703 break;
252b5132 10704 }
35b1837e 10705 putchar ('\n');
252b5132
RH
10706}
10707
28f997cf
TG
10708/* VMS vs Unix time offset and factor. */
10709
10710#define VMS_EPOCH_OFFSET 35067168000000000LL
10711#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10712#ifndef INT64_MIN
10713#define INT64_MIN (-9223372036854775807LL - 1)
10714#endif
28f997cf
TG
10715
10716/* Display a VMS time in a human readable format. */
10717
10718static void
0e3c1eeb 10719print_vms_time (int64_t vmstime)
28f997cf 10720{
dccc31de 10721 struct tm *tm = NULL;
28f997cf
TG
10722 time_t unxtime;
10723
dccc31de
AM
10724 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10725 {
10726 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10727 unxtime = vmstime;
10728 if (unxtime == vmstime)
10729 tm = gmtime (&unxtime);
10730 }
10731 if (tm != NULL)
10732 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10733 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10734 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10735}
28f997cf 10736
ecc51f48 10737static void
2cf0635d 10738dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10739{
10740 switch (entry->d_tag)
10741 {
0de14b54 10742 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10743 /* First 3 slots reserved. */
ecc51f48
NC
10744 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10745 printf (" -- ");
10746 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10747 break;
10748
28f997cf 10749 case DT_IA_64_VMS_LINKTIME:
28f997cf 10750 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10751 break;
10752
10753 case DT_IA_64_VMS_LNKFLAGS:
10754 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10755 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10756 printf (" CALL_DEBUG");
10757 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10758 printf (" NOP0BUFS");
10759 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10760 printf (" P0IMAGE");
10761 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10762 printf (" MKTHREADS");
10763 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10764 printf (" UPCALLS");
10765 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10766 printf (" IMGSTA");
10767 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10768 printf (" INITIALIZE");
10769 if (entry->d_un.d_val & VMS_LF_MAIN)
10770 printf (" MAIN");
10771 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10772 printf (" EXE_INIT");
10773 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10774 printf (" TBK_IN_IMG");
10775 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10776 printf (" DBG_IN_IMG");
10777 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10778 printf (" TBK_IN_DSF");
10779 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10780 printf (" DBG_IN_DSF");
10781 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10782 printf (" SIGNATURES");
10783 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10784 printf (" REL_SEG_OFF");
10785 break;
10786
bdf4d63a
JJ
10787 default:
10788 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10789 break;
ecc51f48 10790 }
bdf4d63a 10791 putchar ('\n');
ecc51f48
NC
10792}
10793
015dc7e1 10794static bool
dda8d76d 10795get_32bit_dynamic_section (Filedata * filedata)
252b5132 10796{
2cf0635d
NC
10797 Elf32_External_Dyn * edyn;
10798 Elf32_External_Dyn * ext;
10799 Elf_Internal_Dyn * entry;
103f02d3 10800
978c4450
AM
10801 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10802 filedata->dynamic_addr, 1,
10803 filedata->dynamic_size,
10804 _("dynamic section"));
a6e9f9df 10805 if (!edyn)
015dc7e1 10806 return false;
103f02d3 10807
071436c6
NC
10808 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10809 might not have the luxury of section headers. Look for the DT_NULL
10810 terminator to determine the number of entries. */
978c4450
AM
10811 for (ext = edyn, filedata->dynamic_nent = 0;
10812 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10813 ext++)
10814 {
978c4450 10815 filedata->dynamic_nent++;
ba2685cc
AM
10816 if (BYTE_GET (ext->d_tag) == DT_NULL)
10817 break;
10818 }
252b5132 10819
978c4450
AM
10820 filedata->dynamic_section
10821 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10822 if (filedata->dynamic_section == NULL)
252b5132 10823 {
8b73c356 10824 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10825 (unsigned long) filedata->dynamic_nent);
9ea033b2 10826 free (edyn);
015dc7e1 10827 return false;
9ea033b2 10828 }
252b5132 10829
978c4450
AM
10830 for (ext = edyn, entry = filedata->dynamic_section;
10831 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10832 ext++, entry++)
9ea033b2 10833 {
fb514b26
AM
10834 entry->d_tag = BYTE_GET (ext->d_tag);
10835 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10836 }
10837
9ea033b2
NC
10838 free (edyn);
10839
015dc7e1 10840 return true;
9ea033b2
NC
10841}
10842
015dc7e1 10843static bool
dda8d76d 10844get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10845{
2cf0635d
NC
10846 Elf64_External_Dyn * edyn;
10847 Elf64_External_Dyn * ext;
10848 Elf_Internal_Dyn * entry;
103f02d3 10849
071436c6 10850 /* Read in the data. */
978c4450
AM
10851 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10852 filedata->dynamic_addr, 1,
10853 filedata->dynamic_size,
10854 _("dynamic section"));
a6e9f9df 10855 if (!edyn)
015dc7e1 10856 return false;
103f02d3 10857
071436c6
NC
10858 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10859 might not have the luxury of section headers. Look for the DT_NULL
10860 terminator to determine the number of entries. */
978c4450 10861 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10862 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10863 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10864 ext++)
10865 {
978c4450 10866 filedata->dynamic_nent++;
66543521 10867 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10868 break;
10869 }
252b5132 10870
978c4450
AM
10871 filedata->dynamic_section
10872 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10873 if (filedata->dynamic_section == NULL)
252b5132 10874 {
8b73c356 10875 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10876 (unsigned long) filedata->dynamic_nent);
252b5132 10877 free (edyn);
015dc7e1 10878 return false;
252b5132
RH
10879 }
10880
071436c6 10881 /* Convert from external to internal formats. */
978c4450
AM
10882 for (ext = edyn, entry = filedata->dynamic_section;
10883 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10884 ext++, entry++)
252b5132 10885 {
66543521
AM
10886 entry->d_tag = BYTE_GET (ext->d_tag);
10887 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10888 }
10889
10890 free (edyn);
10891
015dc7e1 10892 return true;
9ea033b2
NC
10893}
10894
4de91c10
AM
10895static bool
10896get_dynamic_section (Filedata *filedata)
10897{
10898 if (filedata->dynamic_section)
10899 return true;
10900
10901 if (is_32bit_elf)
10902 return get_32bit_dynamic_section (filedata);
10903 else
10904 return get_64bit_dynamic_section (filedata);
10905}
10906
e9e44622 10907static void
625d49fc 10908print_dynamic_flags (uint64_t flags)
d1133906 10909{
015dc7e1 10910 bool first = true;
13ae64f3 10911
d1133906
NC
10912 while (flags)
10913 {
625d49fc 10914 uint64_t flag;
d1133906
NC
10915
10916 flag = flags & - flags;
10917 flags &= ~ flag;
10918
e9e44622 10919 if (first)
015dc7e1 10920 first = false;
e9e44622
JJ
10921 else
10922 putc (' ', stdout);
13ae64f3 10923
d1133906
NC
10924 switch (flag)
10925 {
e9e44622
JJ
10926 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10927 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10928 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10929 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10930 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10931 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10932 }
10933 }
e9e44622 10934 puts ("");
d1133906
NC
10935}
10936
625d49fc 10937static uint64_t *
be7d229a 10938get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10939{
10940 unsigned char * e_data;
625d49fc 10941 uint64_t * i_data;
10ca4b04 10942
be7d229a
AM
10943 /* If size_t is smaller than uint64_t, eg because you are building
10944 on a 32-bit host, then make sure that when number is cast to
10945 size_t no information is lost. */
10946 if ((size_t) number != number
10947 || ent_size * number / ent_size != number)
10ca4b04 10948 {
be7d229a 10949 error (_("Size overflow prevents reading %" PRIu64
b8281767 10950 " elements of size %u\n"),
be7d229a 10951 number, ent_size);
10ca4b04
L
10952 return NULL;
10953 }
10954
10955 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10956 attempting to allocate memory when the read is bound to fail. */
10957 if (ent_size * number > filedata->file_size)
10958 {
b8281767 10959 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10960 number);
10ca4b04
L
10961 return NULL;
10962 }
10963
10964 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10965 if (e_data == NULL)
10966 {
b8281767 10967 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10968 number);
10ca4b04
L
10969 return NULL;
10970 }
10971
10972 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10973 {
b8281767 10974 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10975 number * ent_size);
10ca4b04
L
10976 free (e_data);
10977 return NULL;
10978 }
10979
625d49fc 10980 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
10981 if (i_data == NULL)
10982 {
b8281767 10983 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 10984 number);
10ca4b04
L
10985 free (e_data);
10986 return NULL;
10987 }
10988
10989 while (number--)
10990 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10991
10992 free (e_data);
10993
10994 return i_data;
10995}
10996
10997static unsigned long
10998get_num_dynamic_syms (Filedata * filedata)
10999{
11000 unsigned long num_of_syms = 0;
11001
11002 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11003 return num_of_syms;
11004
978c4450 11005 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11006 {
11007 unsigned char nb[8];
11008 unsigned char nc[8];
11009 unsigned int hash_ent_size = 4;
11010
11011 if ((filedata->file_header.e_machine == EM_ALPHA
11012 || filedata->file_header.e_machine == EM_S390
11013 || filedata->file_header.e_machine == EM_S390_OLD)
11014 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11015 hash_ent_size = 8;
11016
11017 if (fseek (filedata->handle,
978c4450
AM
11018 (filedata->archive_file_offset
11019 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
11020 sizeof nb + sizeof nc)),
11021 SEEK_SET))
11022 {
11023 error (_("Unable to seek to start of dynamic information\n"));
11024 goto no_hash;
11025 }
11026
11027 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11028 {
11029 error (_("Failed to read in number of buckets\n"));
11030 goto no_hash;
11031 }
11032
11033 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11034 {
11035 error (_("Failed to read in number of chains\n"));
11036 goto no_hash;
11037 }
11038
978c4450
AM
11039 filedata->nbuckets = byte_get (nb, hash_ent_size);
11040 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11041
2482f306
AM
11042 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11043 {
11044 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11045 hash_ent_size);
11046 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11047 hash_ent_size);
001890e1 11048
2482f306
AM
11049 if (filedata->buckets != NULL && filedata->chains != NULL)
11050 num_of_syms = filedata->nchains;
11051 }
ceb9bf11 11052 no_hash:
10ca4b04
L
11053 if (num_of_syms == 0)
11054 {
9db70fc3
AM
11055 free (filedata->buckets);
11056 filedata->buckets = NULL;
11057 free (filedata->chains);
11058 filedata->chains = NULL;
978c4450 11059 filedata->nbuckets = 0;
10ca4b04
L
11060 }
11061 }
11062
978c4450 11063 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11064 {
11065 unsigned char nb[16];
625d49fc
AM
11066 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11067 uint64_t buckets_vma;
10ca4b04 11068 unsigned long hn;
10ca4b04
L
11069
11070 if (fseek (filedata->handle,
978c4450
AM
11071 (filedata->archive_file_offset
11072 + offset_from_vma (filedata,
11073 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11074 sizeof nb)),
11075 SEEK_SET))
11076 {
11077 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11078 goto no_gnu_hash;
11079 }
11080
11081 if (fread (nb, 16, 1, filedata->handle) != 1)
11082 {
11083 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11084 goto no_gnu_hash;
11085 }
11086
978c4450
AM
11087 filedata->ngnubuckets = byte_get (nb, 4);
11088 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11089 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11090 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11091 if (is_32bit_elf)
11092 buckets_vma += bitmaskwords * 4;
11093 else
11094 buckets_vma += bitmaskwords * 8;
11095
11096 if (fseek (filedata->handle,
978c4450 11097 (filedata->archive_file_offset
10ca4b04
L
11098 + offset_from_vma (filedata, buckets_vma, 4)),
11099 SEEK_SET))
11100 {
11101 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11102 goto no_gnu_hash;
11103 }
11104
978c4450
AM
11105 filedata->gnubuckets
11106 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11107
978c4450 11108 if (filedata->gnubuckets == NULL)
90837ea7 11109 goto no_gnu_hash;
10ca4b04 11110
978c4450
AM
11111 for (i = 0; i < filedata->ngnubuckets; i++)
11112 if (filedata->gnubuckets[i] != 0)
10ca4b04 11113 {
978c4450 11114 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11115 goto no_gnu_hash;
10ca4b04 11116
978c4450
AM
11117 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11118 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11119 }
11120
11121 if (maxchain == 0xffffffff)
90837ea7 11122 goto no_gnu_hash;
10ca4b04 11123
978c4450 11124 maxchain -= filedata->gnusymidx;
10ca4b04
L
11125
11126 if (fseek (filedata->handle,
978c4450
AM
11127 (filedata->archive_file_offset
11128 + offset_from_vma (filedata,
11129 buckets_vma + 4 * (filedata->ngnubuckets
11130 + maxchain),
11131 4)),
10ca4b04
L
11132 SEEK_SET))
11133 {
11134 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11135 goto no_gnu_hash;
11136 }
11137
11138 do
11139 {
11140 if (fread (nb, 4, 1, filedata->handle) != 1)
11141 {
11142 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11143 goto no_gnu_hash;
11144 }
11145
11146 if (maxchain + 1 == 0)
90837ea7 11147 goto no_gnu_hash;
10ca4b04
L
11148
11149 ++maxchain;
11150 }
11151 while ((byte_get (nb, 4) & 1) == 0);
11152
11153 if (fseek (filedata->handle,
978c4450
AM
11154 (filedata->archive_file_offset
11155 + offset_from_vma (filedata, (buckets_vma
11156 + 4 * filedata->ngnubuckets),
11157 4)),
10ca4b04
L
11158 SEEK_SET))
11159 {
11160 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11161 goto no_gnu_hash;
11162 }
11163
978c4450
AM
11164 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11165 filedata->ngnuchains = maxchain;
10ca4b04 11166
978c4450 11167 if (filedata->gnuchains == NULL)
90837ea7 11168 goto no_gnu_hash;
10ca4b04 11169
978c4450 11170 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11171 {
11172 if (fseek (filedata->handle,
978c4450 11173 (filedata->archive_file_offset
10ca4b04 11174 + offset_from_vma (filedata, (buckets_vma
978c4450 11175 + 4 * (filedata->ngnubuckets
10ca4b04
L
11176 + maxchain)), 4)),
11177 SEEK_SET))
11178 {
11179 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11180 goto no_gnu_hash;
11181 }
11182
978c4450 11183 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11184 if (filedata->mipsxlat == NULL)
11185 goto no_gnu_hash;
10ca4b04
L
11186 }
11187
978c4450
AM
11188 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11189 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11190 {
625d49fc
AM
11191 uint64_t si = filedata->gnubuckets[hn];
11192 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11193
11194 do
11195 {
978c4450 11196 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11197 {
c31ab5a0
AM
11198 if (off < filedata->ngnuchains
11199 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11200 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11201 }
11202 else
11203 {
11204 if (si >= num_of_syms)
11205 num_of_syms = si + 1;
11206 }
11207 si++;
11208 }
978c4450
AM
11209 while (off < filedata->ngnuchains
11210 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11211 }
11212
90837ea7 11213 if (num_of_syms == 0)
10ca4b04 11214 {
90837ea7 11215 no_gnu_hash:
9db70fc3
AM
11216 free (filedata->mipsxlat);
11217 filedata->mipsxlat = NULL;
11218 free (filedata->gnuchains);
11219 filedata->gnuchains = NULL;
11220 free (filedata->gnubuckets);
11221 filedata->gnubuckets = NULL;
978c4450
AM
11222 filedata->ngnubuckets = 0;
11223 filedata->ngnuchains = 0;
10ca4b04
L
11224 }
11225 }
11226
11227 return num_of_syms;
11228}
11229
b2d38a17
NC
11230/* Parse and display the contents of the dynamic section. */
11231
015dc7e1 11232static bool
dda8d76d 11233process_dynamic_section (Filedata * filedata)
9ea033b2 11234{
2cf0635d 11235 Elf_Internal_Dyn * entry;
9ea033b2 11236
93df3340 11237 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11238 {
11239 if (do_dynamic)
ca0e11aa
NC
11240 {
11241 if (filedata->is_separate)
11242 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11243 filedata->file_name);
11244 else
11245 printf (_("\nThere is no dynamic section in this file.\n"));
11246 }
9ea033b2 11247
015dc7e1 11248 return true;
9ea033b2
NC
11249 }
11250
4de91c10
AM
11251 if (!get_dynamic_section (filedata))
11252 return false;
9ea033b2 11253
252b5132 11254 /* Find the appropriate symbol table. */
978c4450 11255 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11256 {
2482f306
AM
11257 unsigned long num_of_syms;
11258
978c4450
AM
11259 for (entry = filedata->dynamic_section;
11260 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11261 ++entry)
10ca4b04 11262 if (entry->d_tag == DT_SYMTAB)
978c4450 11263 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11264 else if (entry->d_tag == DT_SYMENT)
978c4450 11265 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11266 else if (entry->d_tag == DT_HASH)
978c4450 11267 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11268 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11269 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11270 else if ((filedata->file_header.e_machine == EM_MIPS
11271 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11272 && entry->d_tag == DT_MIPS_XHASH)
11273 {
978c4450
AM
11274 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11275 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11276 }
252b5132 11277
2482f306
AM
11278 num_of_syms = get_num_dynamic_syms (filedata);
11279
11280 if (num_of_syms != 0
11281 && filedata->dynamic_symbols == NULL
11282 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11283 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11284 {
11285 Elf_Internal_Phdr *seg;
625d49fc 11286 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11287
2482f306
AM
11288 if (! get_program_headers (filedata))
11289 {
11290 error (_("Cannot interpret virtual addresses "
11291 "without program headers.\n"));
015dc7e1 11292 return false;
2482f306 11293 }
252b5132 11294
2482f306
AM
11295 for (seg = filedata->program_headers;
11296 seg < filedata->program_headers + filedata->file_header.e_phnum;
11297 ++seg)
11298 {
11299 if (seg->p_type != PT_LOAD)
11300 continue;
252b5132 11301
2482f306
AM
11302 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11303 {
11304 /* See PR 21379 for a reproducer. */
11305 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11306 return false;
2482f306 11307 }
252b5132 11308
2482f306
AM
11309 if (vma >= (seg->p_vaddr & -seg->p_align)
11310 && vma < seg->p_vaddr + seg->p_filesz)
11311 {
11312 /* Since we do not know how big the symbol table is,
11313 we default to reading in up to the end of PT_LOAD
11314 segment and processing that. This is overkill, I
11315 know, but it should work. */
11316 Elf_Internal_Shdr section;
11317 section.sh_offset = (vma - seg->p_vaddr
11318 + seg->p_offset);
11319 section.sh_size = (num_of_syms
11320 * filedata->dynamic_info[DT_SYMENT]);
11321 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11322
11323 if (do_checks
11324 && filedata->dynamic_symtab_section != NULL
11325 && ((filedata->dynamic_symtab_section->sh_offset
11326 != section.sh_offset)
11327 || (filedata->dynamic_symtab_section->sh_size
11328 != section.sh_size)
11329 || (filedata->dynamic_symtab_section->sh_entsize
11330 != section.sh_entsize)))
11331 warn (_("\
11332the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11333
2482f306
AM
11334 section.sh_name = filedata->string_table_length;
11335 filedata->dynamic_symbols
4de91c10 11336 = get_elf_symbols (filedata, &section,
2482f306
AM
11337 &filedata->num_dynamic_syms);
11338 if (filedata->dynamic_symbols == NULL
11339 || filedata->num_dynamic_syms != num_of_syms)
11340 {
11341 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11342 return false;
2482f306
AM
11343 }
11344 break;
11345 }
11346 }
11347 }
11348 }
252b5132
RH
11349
11350 /* Similarly find a string table. */
978c4450
AM
11351 if (filedata->dynamic_strings == NULL)
11352 for (entry = filedata->dynamic_section;
11353 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11354 ++entry)
11355 {
11356 if (entry->d_tag == DT_STRTAB)
978c4450 11357 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11358
10ca4b04 11359 if (entry->d_tag == DT_STRSZ)
978c4450 11360 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11361
978c4450
AM
11362 if (filedata->dynamic_info[DT_STRTAB]
11363 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11364 {
11365 unsigned long offset;
be7d229a 11366 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11367
11368 offset = offset_from_vma (filedata,
978c4450 11369 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11370 str_tab_len);
8ac10c5b
L
11371 if (do_checks
11372 && filedata->dynamic_strtab_section
11373 && ((filedata->dynamic_strtab_section->sh_offset
11374 != (file_ptr) offset)
11375 || (filedata->dynamic_strtab_section->sh_size
11376 != str_tab_len)))
11377 warn (_("\
11378the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11379
978c4450
AM
11380 filedata->dynamic_strings
11381 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11382 _("dynamic string table"));
11383 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11384 {
11385 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11386 break;
11387 }
e3d39609 11388
978c4450 11389 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11390 break;
11391 }
11392 }
252b5132
RH
11393
11394 /* And find the syminfo section if available. */
978c4450 11395 if (filedata->dynamic_syminfo == NULL)
252b5132 11396 {
3e8bba36 11397 unsigned long syminsz = 0;
252b5132 11398
978c4450
AM
11399 for (entry = filedata->dynamic_section;
11400 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11401 ++entry)
252b5132
RH
11402 {
11403 if (entry->d_tag == DT_SYMINENT)
11404 {
11405 /* Note: these braces are necessary to avoid a syntax
11406 error from the SunOS4 C compiler. */
049b0c3a
NC
11407 /* PR binutils/17531: A corrupt file can trigger this test.
11408 So do not use an assert, instead generate an error message. */
11409 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11410 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11411 (int) entry->d_un.d_val);
252b5132
RH
11412 }
11413 else if (entry->d_tag == DT_SYMINSZ)
11414 syminsz = entry->d_un.d_val;
11415 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11416 filedata->dynamic_syminfo_offset
11417 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11418 }
11419
978c4450 11420 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11421 {
2cf0635d
NC
11422 Elf_External_Syminfo * extsyminfo;
11423 Elf_External_Syminfo * extsym;
11424 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11425
11426 /* There is a syminfo section. Read the data. */
3f5e193b 11427 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11428 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11429 1, syminsz, _("symbol information"));
a6e9f9df 11430 if (!extsyminfo)
015dc7e1 11431 return false;
252b5132 11432
978c4450 11433 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11434 {
11435 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11436 free (filedata->dynamic_syminfo);
e3d39609 11437 }
978c4450
AM
11438 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11439 if (filedata->dynamic_syminfo == NULL)
252b5132 11440 {
2482f306
AM
11441 error (_("Out of memory allocating %lu bytes "
11442 "for dynamic symbol info\n"),
8b73c356 11443 (unsigned long) syminsz);
015dc7e1 11444 return false;
252b5132
RH
11445 }
11446
2482f306
AM
11447 filedata->dynamic_syminfo_nent
11448 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11449 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11450 syminfo < (filedata->dynamic_syminfo
11451 + filedata->dynamic_syminfo_nent);
86dba8ee 11452 ++syminfo, ++extsym)
252b5132 11453 {
86dba8ee
AM
11454 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11455 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11456 }
11457
11458 free (extsyminfo);
11459 }
11460 }
11461
978c4450 11462 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11463 {
f253158f
NC
11464 if (filedata->is_separate)
11465 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11466 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11467 (unsigned long) filedata->dynamic_nent),
11468 filedata->file_name,
11469 filedata->dynamic_addr,
11470 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11471 else
11472 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11473 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11474 (unsigned long) filedata->dynamic_nent),
11475 filedata->dynamic_addr,
11476 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11477 }
252b5132
RH
11478 if (do_dynamic)
11479 printf (_(" Tag Type Name/Value\n"));
11480
978c4450
AM
11481 for (entry = filedata->dynamic_section;
11482 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11483 entry++)
252b5132
RH
11484 {
11485 if (do_dynamic)
f7a99963 11486 {
2cf0635d 11487 const char * dtype;
e699b9ff 11488
f7a99963
NC
11489 putchar (' ');
11490 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11491 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11492 printf (" (%s)%*s", dtype,
32ec8896 11493 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11494 }
252b5132
RH
11495
11496 switch (entry->d_tag)
11497 {
d1133906
NC
11498 case DT_FLAGS:
11499 if (do_dynamic)
e9e44622 11500 print_dynamic_flags (entry->d_un.d_val);
d1133906 11501 break;
76da6bbe 11502
252b5132
RH
11503 case DT_AUXILIARY:
11504 case DT_FILTER:
019148e4
L
11505 case DT_CONFIG:
11506 case DT_DEPAUDIT:
11507 case DT_AUDIT:
252b5132
RH
11508 if (do_dynamic)
11509 {
019148e4 11510 switch (entry->d_tag)
b34976b6 11511 {
019148e4
L
11512 case DT_AUXILIARY:
11513 printf (_("Auxiliary library"));
11514 break;
11515
11516 case DT_FILTER:
11517 printf (_("Filter library"));
11518 break;
11519
b34976b6 11520 case DT_CONFIG:
019148e4
L
11521 printf (_("Configuration file"));
11522 break;
11523
11524 case DT_DEPAUDIT:
11525 printf (_("Dependency audit library"));
11526 break;
11527
11528 case DT_AUDIT:
11529 printf (_("Audit library"));
11530 break;
11531 }
252b5132 11532
84714f86 11533 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11534 printf (": [%s]\n",
84714f86 11535 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11536 else
f7a99963
NC
11537 {
11538 printf (": ");
11539 print_vma (entry->d_un.d_val, PREFIX_HEX);
11540 putchar ('\n');
11541 }
252b5132
RH
11542 }
11543 break;
11544
dcefbbbd 11545 case DT_FEATURE:
252b5132
RH
11546 if (do_dynamic)
11547 {
11548 printf (_("Flags:"));
86f55779 11549
252b5132
RH
11550 if (entry->d_un.d_val == 0)
11551 printf (_(" None\n"));
11552 else
11553 {
11554 unsigned long int val = entry->d_un.d_val;
86f55779 11555
252b5132
RH
11556 if (val & DTF_1_PARINIT)
11557 {
11558 printf (" PARINIT");
11559 val ^= DTF_1_PARINIT;
11560 }
dcefbbbd
L
11561 if (val & DTF_1_CONFEXP)
11562 {
11563 printf (" CONFEXP");
11564 val ^= DTF_1_CONFEXP;
11565 }
252b5132
RH
11566 if (val != 0)
11567 printf (" %lx", val);
11568 puts ("");
11569 }
11570 }
11571 break;
11572
11573 case DT_POSFLAG_1:
11574 if (do_dynamic)
11575 {
11576 printf (_("Flags:"));
86f55779 11577
252b5132
RH
11578 if (entry->d_un.d_val == 0)
11579 printf (_(" None\n"));
11580 else
11581 {
11582 unsigned long int val = entry->d_un.d_val;
86f55779 11583
252b5132
RH
11584 if (val & DF_P1_LAZYLOAD)
11585 {
11586 printf (" LAZYLOAD");
11587 val ^= DF_P1_LAZYLOAD;
11588 }
11589 if (val & DF_P1_GROUPPERM)
11590 {
11591 printf (" GROUPPERM");
11592 val ^= DF_P1_GROUPPERM;
11593 }
11594 if (val != 0)
11595 printf (" %lx", val);
11596 puts ("");
11597 }
11598 }
11599 break;
11600
11601 case DT_FLAGS_1:
11602 if (do_dynamic)
11603 {
11604 printf (_("Flags:"));
11605 if (entry->d_un.d_val == 0)
11606 printf (_(" None\n"));
11607 else
11608 {
11609 unsigned long int val = entry->d_un.d_val;
86f55779 11610
252b5132
RH
11611 if (val & DF_1_NOW)
11612 {
11613 printf (" NOW");
11614 val ^= DF_1_NOW;
11615 }
11616 if (val & DF_1_GLOBAL)
11617 {
11618 printf (" GLOBAL");
11619 val ^= DF_1_GLOBAL;
11620 }
11621 if (val & DF_1_GROUP)
11622 {
11623 printf (" GROUP");
11624 val ^= DF_1_GROUP;
11625 }
11626 if (val & DF_1_NODELETE)
11627 {
11628 printf (" NODELETE");
11629 val ^= DF_1_NODELETE;
11630 }
11631 if (val & DF_1_LOADFLTR)
11632 {
11633 printf (" LOADFLTR");
11634 val ^= DF_1_LOADFLTR;
11635 }
11636 if (val & DF_1_INITFIRST)
11637 {
11638 printf (" INITFIRST");
11639 val ^= DF_1_INITFIRST;
11640 }
11641 if (val & DF_1_NOOPEN)
11642 {
11643 printf (" NOOPEN");
11644 val ^= DF_1_NOOPEN;
11645 }
11646 if (val & DF_1_ORIGIN)
11647 {
11648 printf (" ORIGIN");
11649 val ^= DF_1_ORIGIN;
11650 }
11651 if (val & DF_1_DIRECT)
11652 {
11653 printf (" DIRECT");
11654 val ^= DF_1_DIRECT;
11655 }
11656 if (val & DF_1_TRANS)
11657 {
11658 printf (" TRANS");
11659 val ^= DF_1_TRANS;
11660 }
11661 if (val & DF_1_INTERPOSE)
11662 {
11663 printf (" INTERPOSE");
11664 val ^= DF_1_INTERPOSE;
11665 }
f7db6139 11666 if (val & DF_1_NODEFLIB)
dcefbbbd 11667 {
f7db6139
L
11668 printf (" NODEFLIB");
11669 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11670 }
11671 if (val & DF_1_NODUMP)
11672 {
11673 printf (" NODUMP");
11674 val ^= DF_1_NODUMP;
11675 }
34b60028 11676 if (val & DF_1_CONFALT)
dcefbbbd 11677 {
34b60028
L
11678 printf (" CONFALT");
11679 val ^= DF_1_CONFALT;
11680 }
11681 if (val & DF_1_ENDFILTEE)
11682 {
11683 printf (" ENDFILTEE");
11684 val ^= DF_1_ENDFILTEE;
11685 }
11686 if (val & DF_1_DISPRELDNE)
11687 {
11688 printf (" DISPRELDNE");
11689 val ^= DF_1_DISPRELDNE;
11690 }
11691 if (val & DF_1_DISPRELPND)
11692 {
11693 printf (" DISPRELPND");
11694 val ^= DF_1_DISPRELPND;
11695 }
11696 if (val & DF_1_NODIRECT)
11697 {
11698 printf (" NODIRECT");
11699 val ^= DF_1_NODIRECT;
11700 }
11701 if (val & DF_1_IGNMULDEF)
11702 {
11703 printf (" IGNMULDEF");
11704 val ^= DF_1_IGNMULDEF;
11705 }
11706 if (val & DF_1_NOKSYMS)
11707 {
11708 printf (" NOKSYMS");
11709 val ^= DF_1_NOKSYMS;
11710 }
11711 if (val & DF_1_NOHDR)
11712 {
11713 printf (" NOHDR");
11714 val ^= DF_1_NOHDR;
11715 }
11716 if (val & DF_1_EDITED)
11717 {
11718 printf (" EDITED");
11719 val ^= DF_1_EDITED;
11720 }
11721 if (val & DF_1_NORELOC)
11722 {
11723 printf (" NORELOC");
11724 val ^= DF_1_NORELOC;
11725 }
11726 if (val & DF_1_SYMINTPOSE)
11727 {
11728 printf (" SYMINTPOSE");
11729 val ^= DF_1_SYMINTPOSE;
11730 }
11731 if (val & DF_1_GLOBAUDIT)
11732 {
11733 printf (" GLOBAUDIT");
11734 val ^= DF_1_GLOBAUDIT;
11735 }
11736 if (val & DF_1_SINGLETON)
11737 {
11738 printf (" SINGLETON");
11739 val ^= DF_1_SINGLETON;
dcefbbbd 11740 }
5c383f02
RO
11741 if (val & DF_1_STUB)
11742 {
11743 printf (" STUB");
11744 val ^= DF_1_STUB;
11745 }
11746 if (val & DF_1_PIE)
11747 {
11748 printf (" PIE");
11749 val ^= DF_1_PIE;
11750 }
b1202ffa
L
11751 if (val & DF_1_KMOD)
11752 {
11753 printf (" KMOD");
11754 val ^= DF_1_KMOD;
11755 }
11756 if (val & DF_1_WEAKFILTER)
11757 {
11758 printf (" WEAKFILTER");
11759 val ^= DF_1_WEAKFILTER;
11760 }
11761 if (val & DF_1_NOCOMMON)
11762 {
11763 printf (" NOCOMMON");
11764 val ^= DF_1_NOCOMMON;
11765 }
252b5132
RH
11766 if (val != 0)
11767 printf (" %lx", val);
11768 puts ("");
11769 }
11770 }
11771 break;
11772
11773 case DT_PLTREL:
978c4450 11774 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11775 if (do_dynamic)
dda8d76d 11776 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11777 break;
11778
11779 case DT_NULL :
11780 case DT_NEEDED :
11781 case DT_PLTGOT :
11782 case DT_HASH :
11783 case DT_STRTAB :
11784 case DT_SYMTAB :
11785 case DT_RELA :
11786 case DT_INIT :
11787 case DT_FINI :
11788 case DT_SONAME :
11789 case DT_RPATH :
11790 case DT_SYMBOLIC:
11791 case DT_REL :
a7fd1186 11792 case DT_RELR :
252b5132
RH
11793 case DT_DEBUG :
11794 case DT_TEXTREL :
11795 case DT_JMPREL :
019148e4 11796 case DT_RUNPATH :
978c4450 11797 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11798
11799 if (do_dynamic)
11800 {
84714f86 11801 const char *name;
252b5132 11802
84714f86
AM
11803 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11804 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11805 else
d79b3d50 11806 name = NULL;
252b5132
RH
11807
11808 if (name)
11809 {
11810 switch (entry->d_tag)
11811 {
11812 case DT_NEEDED:
11813 printf (_("Shared library: [%s]"), name);
11814
13acb58d
AM
11815 if (filedata->program_interpreter
11816 && streq (name, filedata->program_interpreter))
f7a99963 11817 printf (_(" program interpreter"));
252b5132
RH
11818 break;
11819
11820 case DT_SONAME:
f7a99963 11821 printf (_("Library soname: [%s]"), name);
252b5132
RH
11822 break;
11823
11824 case DT_RPATH:
f7a99963 11825 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11826 break;
11827
019148e4
L
11828 case DT_RUNPATH:
11829 printf (_("Library runpath: [%s]"), name);
11830 break;
11831
252b5132 11832 default:
f7a99963
NC
11833 print_vma (entry->d_un.d_val, PREFIX_HEX);
11834 break;
252b5132
RH
11835 }
11836 }
11837 else
f7a99963
NC
11838 print_vma (entry->d_un.d_val, PREFIX_HEX);
11839
11840 putchar ('\n');
252b5132
RH
11841 }
11842 break;
11843
11844 case DT_PLTRELSZ:
11845 case DT_RELASZ :
11846 case DT_STRSZ :
11847 case DT_RELSZ :
11848 case DT_RELAENT :
a7fd1186
FS
11849 case DT_RELRENT :
11850 case DT_RELRSZ :
252b5132
RH
11851 case DT_SYMENT :
11852 case DT_RELENT :
978c4450 11853 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11854 /* Fall through. */
252b5132
RH
11855 case DT_PLTPADSZ:
11856 case DT_MOVEENT :
11857 case DT_MOVESZ :
04d8355a 11858 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11859 case DT_INIT_ARRAYSZ:
11860 case DT_FINI_ARRAYSZ:
047b2264
JJ
11861 case DT_GNU_CONFLICTSZ:
11862 case DT_GNU_LIBLISTSZ:
252b5132 11863 if (do_dynamic)
f7a99963
NC
11864 {
11865 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11866 printf (_(" (bytes)\n"));
f7a99963 11867 }
252b5132
RH
11868 break;
11869
11870 case DT_VERDEFNUM:
11871 case DT_VERNEEDNUM:
11872 case DT_RELACOUNT:
11873 case DT_RELCOUNT:
11874 if (do_dynamic)
f7a99963
NC
11875 {
11876 print_vma (entry->d_un.d_val, UNSIGNED);
11877 putchar ('\n');
11878 }
252b5132
RH
11879 break;
11880
11881 case DT_SYMINSZ:
11882 case DT_SYMINENT:
11883 case DT_SYMINFO:
11884 case DT_USED:
11885 case DT_INIT_ARRAY:
11886 case DT_FINI_ARRAY:
11887 if (do_dynamic)
11888 {
d79b3d50 11889 if (entry->d_tag == DT_USED
84714f86 11890 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11891 {
84714f86
AM
11892 const char *name
11893 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11894
b34976b6 11895 if (*name)
252b5132
RH
11896 {
11897 printf (_("Not needed object: [%s]\n"), name);
11898 break;
11899 }
11900 }
103f02d3 11901
f7a99963
NC
11902 print_vma (entry->d_un.d_val, PREFIX_HEX);
11903 putchar ('\n');
252b5132
RH
11904 }
11905 break;
11906
11907 case DT_BIND_NOW:
11908 /* The value of this entry is ignored. */
35b1837e
AM
11909 if (do_dynamic)
11910 putchar ('\n');
252b5132 11911 break;
103f02d3 11912
047b2264
JJ
11913 case DT_GNU_PRELINKED:
11914 if (do_dynamic)
11915 {
2cf0635d 11916 struct tm * tmp;
91d6fa6a 11917 time_t atime = entry->d_un.d_val;
047b2264 11918
91d6fa6a 11919 tmp = gmtime (&atime);
071436c6
NC
11920 /* PR 17533 file: 041-1244816-0.004. */
11921 if (tmp == NULL)
5a2cbcf4
L
11922 printf (_("<corrupt time val: %lx"),
11923 (unsigned long) atime);
071436c6
NC
11924 else
11925 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11926 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11927 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11928
11929 }
11930 break;
11931
fdc90cb4 11932 case DT_GNU_HASH:
978c4450 11933 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11934 if (do_dynamic)
11935 {
11936 print_vma (entry->d_un.d_val, PREFIX_HEX);
11937 putchar ('\n');
11938 }
11939 break;
11940
a5da3dee
VDM
11941 case DT_GNU_FLAGS_1:
11942 if (do_dynamic)
11943 {
11944 printf (_("Flags:"));
11945 if (entry->d_un.d_val == 0)
11946 printf (_(" None\n"));
11947 else
11948 {
11949 unsigned long int val = entry->d_un.d_val;
11950
11951 if (val & DF_GNU_1_UNIQUE)
11952 {
11953 printf (" UNIQUE");
11954 val ^= DF_GNU_1_UNIQUE;
11955 }
11956 if (val != 0)
11957 printf (" %lx", val);
11958 puts ("");
11959 }
11960 }
11961 break;
11962
252b5132
RH
11963 default:
11964 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11965 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11966 = entry->d_un.d_val;
252b5132
RH
11967
11968 if (do_dynamic)
11969 {
dda8d76d 11970 switch (filedata->file_header.e_machine)
252b5132 11971 {
37c18eed
SD
11972 case EM_AARCH64:
11973 dynamic_section_aarch64_val (entry);
11974 break;
252b5132 11975 case EM_MIPS:
4fe85591 11976 case EM_MIPS_RS3_LE:
978c4450 11977 dynamic_section_mips_val (filedata, entry);
252b5132 11978 break;
103f02d3 11979 case EM_PARISC:
b2d38a17 11980 dynamic_section_parisc_val (entry);
103f02d3 11981 break;
ecc51f48 11982 case EM_IA_64:
b2d38a17 11983 dynamic_section_ia64_val (entry);
ecc51f48 11984 break;
252b5132 11985 default:
f7a99963
NC
11986 print_vma (entry->d_un.d_val, PREFIX_HEX);
11987 putchar ('\n');
252b5132
RH
11988 }
11989 }
11990 break;
11991 }
11992 }
11993
015dc7e1 11994 return true;
252b5132
RH
11995}
11996
11997static char *
d3ba0551 11998get_ver_flags (unsigned int flags)
252b5132 11999{
6d4f21f6 12000 static char buff[128];
252b5132
RH
12001
12002 buff[0] = 0;
12003
12004 if (flags == 0)
12005 return _("none");
12006
12007 if (flags & VER_FLG_BASE)
7bb1ad17 12008 strcat (buff, "BASE");
252b5132
RH
12009
12010 if (flags & VER_FLG_WEAK)
12011 {
12012 if (flags & VER_FLG_BASE)
7bb1ad17 12013 strcat (buff, " | ");
252b5132 12014
7bb1ad17 12015 strcat (buff, "WEAK");
252b5132
RH
12016 }
12017
44ec90b9
RO
12018 if (flags & VER_FLG_INFO)
12019 {
12020 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12021 strcat (buff, " | ");
44ec90b9 12022
7bb1ad17 12023 strcat (buff, "INFO");
44ec90b9
RO
12024 }
12025
12026 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12027 {
12028 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12029 strcat (buff, " | ");
12030
12031 strcat (buff, _("<unknown>"));
12032 }
252b5132
RH
12033
12034 return buff;
12035}
12036
12037/* Display the contents of the version sections. */
98fb390a 12038
015dc7e1 12039static bool
dda8d76d 12040process_version_sections (Filedata * filedata)
252b5132 12041{
2cf0635d 12042 Elf_Internal_Shdr * section;
b34976b6 12043 unsigned i;
015dc7e1 12044 bool found = false;
252b5132
RH
12045
12046 if (! do_version)
015dc7e1 12047 return true;
252b5132 12048
dda8d76d
NC
12049 for (i = 0, section = filedata->section_headers;
12050 i < filedata->file_header.e_shnum;
b34976b6 12051 i++, section++)
252b5132
RH
12052 {
12053 switch (section->sh_type)
12054 {
12055 case SHT_GNU_verdef:
12056 {
2cf0635d 12057 Elf_External_Verdef * edefs;
452bf675
AM
12058 unsigned long idx;
12059 unsigned long cnt;
2cf0635d 12060 char * endbuf;
252b5132 12061
015dc7e1 12062 found = true;
252b5132 12063
ca0e11aa
NC
12064 if (filedata->is_separate)
12065 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12066 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12067 section->sh_info),
12068 filedata->file_name,
12069 printable_section_name (filedata, section),
12070 section->sh_info);
12071 else
12072 printf (ngettext ("\nVersion definition section '%s' "
12073 "contains %u entry:\n",
12074 "\nVersion definition section '%s' "
12075 "contains %u entries:\n",
12076 section->sh_info),
12077 printable_section_name (filedata, section),
12078 section->sh_info);
047c3dbf 12079
625d49fc 12080 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
233f82cf 12081 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12082 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12083 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12084
3f5e193b 12085 edefs = (Elf_External_Verdef *)
dda8d76d 12086 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12087 _("version definition section"));
a6e9f9df
AM
12088 if (!edefs)
12089 break;
59245841 12090 endbuf = (char *) edefs + section->sh_size;
252b5132 12091
1445030f 12092 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12093 {
2cf0635d
NC
12094 char * vstart;
12095 Elf_External_Verdef * edef;
b34976b6 12096 Elf_Internal_Verdef ent;
2cf0635d 12097 Elf_External_Verdaux * eaux;
b34976b6 12098 Elf_Internal_Verdaux aux;
452bf675 12099 unsigned long isum;
b34976b6 12100 int j;
103f02d3 12101
252b5132 12102 vstart = ((char *) edefs) + idx;
54806181
AM
12103 if (vstart + sizeof (*edef) > endbuf)
12104 break;
252b5132
RH
12105
12106 edef = (Elf_External_Verdef *) vstart;
12107
12108 ent.vd_version = BYTE_GET (edef->vd_version);
12109 ent.vd_flags = BYTE_GET (edef->vd_flags);
12110 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12111 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12112 ent.vd_hash = BYTE_GET (edef->vd_hash);
12113 ent.vd_aux = BYTE_GET (edef->vd_aux);
12114 ent.vd_next = BYTE_GET (edef->vd_next);
12115
452bf675 12116 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12117 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12118
12119 printf (_(" Index: %d Cnt: %d "),
12120 ent.vd_ndx, ent.vd_cnt);
12121
452bf675 12122 /* Check for overflow. */
1445030f 12123 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12124 break;
12125
252b5132
RH
12126 vstart += ent.vd_aux;
12127
1445030f
AM
12128 if (vstart + sizeof (*eaux) > endbuf)
12129 break;
252b5132
RH
12130 eaux = (Elf_External_Verdaux *) vstart;
12131
12132 aux.vda_name = BYTE_GET (eaux->vda_name);
12133 aux.vda_next = BYTE_GET (eaux->vda_next);
12134
84714f86 12135 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12136 printf (_("Name: %s\n"),
84714f86 12137 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12138 else
12139 printf (_("Name index: %ld\n"), aux.vda_name);
12140
12141 isum = idx + ent.vd_aux;
12142
b34976b6 12143 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12144 {
1445030f
AM
12145 if (aux.vda_next < sizeof (*eaux)
12146 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12147 {
12148 warn (_("Invalid vda_next field of %lx\n"),
12149 aux.vda_next);
12150 j = ent.vd_cnt;
12151 break;
12152 }
dd24e3da 12153 /* Check for overflow. */
7e26601c 12154 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12155 break;
12156
252b5132
RH
12157 isum += aux.vda_next;
12158 vstart += aux.vda_next;
12159
54806181
AM
12160 if (vstart + sizeof (*eaux) > endbuf)
12161 break;
1445030f 12162 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12163
12164 aux.vda_name = BYTE_GET (eaux->vda_name);
12165 aux.vda_next = BYTE_GET (eaux->vda_next);
12166
84714f86 12167 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12168 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12169 isum, j,
84714f86 12170 get_dynamic_name (filedata, aux.vda_name));
252b5132 12171 else
452bf675 12172 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12173 isum, j, aux.vda_name);
12174 }
dd24e3da 12175
54806181
AM
12176 if (j < ent.vd_cnt)
12177 printf (_(" Version def aux past end of section\n"));
252b5132 12178
c9f02c3e
MR
12179 /* PR 17531:
12180 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12181 if (ent.vd_next < sizeof (*edef)
12182 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12183 {
12184 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12185 cnt = section->sh_info;
12186 break;
12187 }
452bf675 12188 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12189 break;
12190
252b5132
RH
12191 idx += ent.vd_next;
12192 }
dd24e3da 12193
54806181
AM
12194 if (cnt < section->sh_info)
12195 printf (_(" Version definition past end of section\n"));
252b5132
RH
12196
12197 free (edefs);
12198 }
12199 break;
103f02d3 12200
252b5132
RH
12201 case SHT_GNU_verneed:
12202 {
2cf0635d 12203 Elf_External_Verneed * eneed;
452bf675
AM
12204 unsigned long idx;
12205 unsigned long cnt;
2cf0635d 12206 char * endbuf;
252b5132 12207
015dc7e1 12208 found = true;
252b5132 12209
ca0e11aa
NC
12210 if (filedata->is_separate)
12211 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12212 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12213 section->sh_info),
12214 filedata->file_name,
12215 printable_section_name (filedata, section),
12216 section->sh_info);
12217 else
12218 printf (ngettext ("\nVersion needs section '%s' "
12219 "contains %u entry:\n",
12220 "\nVersion needs section '%s' "
12221 "contains %u entries:\n",
12222 section->sh_info),
12223 printable_section_name (filedata, section),
12224 section->sh_info);
047c3dbf 12225
625d49fc 12226 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12227 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12228 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12229 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12230
dda8d76d 12231 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12232 section->sh_offset, 1,
12233 section->sh_size,
9cf03b7e 12234 _("Version Needs section"));
a6e9f9df
AM
12235 if (!eneed)
12236 break;
59245841 12237 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12238
12239 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12240 {
2cf0635d 12241 Elf_External_Verneed * entry;
b34976b6 12242 Elf_Internal_Verneed ent;
452bf675 12243 unsigned long isum;
b34976b6 12244 int j;
2cf0635d 12245 char * vstart;
252b5132
RH
12246
12247 vstart = ((char *) eneed) + idx;
54806181
AM
12248 if (vstart + sizeof (*entry) > endbuf)
12249 break;
252b5132
RH
12250
12251 entry = (Elf_External_Verneed *) vstart;
12252
12253 ent.vn_version = BYTE_GET (entry->vn_version);
12254 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12255 ent.vn_file = BYTE_GET (entry->vn_file);
12256 ent.vn_aux = BYTE_GET (entry->vn_aux);
12257 ent.vn_next = BYTE_GET (entry->vn_next);
12258
452bf675 12259 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12260
84714f86 12261 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12262 printf (_(" File: %s"),
84714f86 12263 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12264 else
12265 printf (_(" File: %lx"), ent.vn_file);
12266
12267 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12268
dd24e3da 12269 /* Check for overflow. */
7e26601c 12270 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12271 break;
252b5132
RH
12272 vstart += ent.vn_aux;
12273
12274 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12275 {
2cf0635d 12276 Elf_External_Vernaux * eaux;
b34976b6 12277 Elf_Internal_Vernaux aux;
252b5132 12278
54806181
AM
12279 if (vstart + sizeof (*eaux) > endbuf)
12280 break;
252b5132
RH
12281 eaux = (Elf_External_Vernaux *) vstart;
12282
12283 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12284 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12285 aux.vna_other = BYTE_GET (eaux->vna_other);
12286 aux.vna_name = BYTE_GET (eaux->vna_name);
12287 aux.vna_next = BYTE_GET (eaux->vna_next);
12288
84714f86 12289 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12290 printf (_(" %#06lx: Name: %s"),
84714f86 12291 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12292 else
452bf675 12293 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12294 isum, aux.vna_name);
12295
12296 printf (_(" Flags: %s Version: %d\n"),
12297 get_ver_flags (aux.vna_flags), aux.vna_other);
12298
1445030f
AM
12299 if (aux.vna_next < sizeof (*eaux)
12300 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12301 {
12302 warn (_("Invalid vna_next field of %lx\n"),
12303 aux.vna_next);
12304 j = ent.vn_cnt;
12305 break;
12306 }
1445030f
AM
12307 /* Check for overflow. */
12308 if (aux.vna_next > (size_t) (endbuf - vstart))
12309 break;
252b5132
RH
12310 isum += aux.vna_next;
12311 vstart += aux.vna_next;
12312 }
9cf03b7e 12313
54806181 12314 if (j < ent.vn_cnt)
f9a6a8f0 12315 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12316
1445030f
AM
12317 if (ent.vn_next < sizeof (*entry)
12318 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12319 {
452bf675 12320 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12321 cnt = section->sh_info;
12322 break;
12323 }
1445030f
AM
12324 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12325 break;
252b5132
RH
12326 idx += ent.vn_next;
12327 }
9cf03b7e 12328
54806181 12329 if (cnt < section->sh_info)
9cf03b7e 12330 warn (_("Missing Version Needs information\n"));
103f02d3 12331
252b5132
RH
12332 free (eneed);
12333 }
12334 break;
12335
12336 case SHT_GNU_versym:
12337 {
2cf0635d 12338 Elf_Internal_Shdr * link_section;
8b73c356
NC
12339 size_t total;
12340 unsigned int cnt;
2cf0635d
NC
12341 unsigned char * edata;
12342 unsigned short * data;
12343 char * strtab;
12344 Elf_Internal_Sym * symbols;
12345 Elf_Internal_Shdr * string_sec;
ba5cdace 12346 unsigned long num_syms;
d3ba0551 12347 long off;
252b5132 12348
dda8d76d 12349 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12350 break;
12351
dda8d76d 12352 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12353 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12354
dda8d76d 12355 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12356 break;
12357
015dc7e1 12358 found = true;
252b5132 12359
4de91c10 12360 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12361 if (symbols == NULL)
12362 break;
252b5132 12363
dda8d76d 12364 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12365
dda8d76d 12366 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12367 string_sec->sh_size,
12368 _("version string table"));
a6e9f9df 12369 if (!strtab)
0429c154
MS
12370 {
12371 free (symbols);
12372 break;
12373 }
252b5132 12374
ca0e11aa
NC
12375 if (filedata->is_separate)
12376 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12377 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12378 total),
12379 filedata->file_name,
12380 printable_section_name (filedata, section),
12381 (unsigned long) total);
12382 else
12383 printf (ngettext ("\nVersion symbols section '%s' "
12384 "contains %lu entry:\n",
12385 "\nVersion symbols section '%s' "
12386 "contains %lu entries:\n",
12387 total),
12388 printable_section_name (filedata, section),
12389 (unsigned long) total);
252b5132 12390
625d49fc 12391 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12392 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12393 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12394 printable_section_name (filedata, link_section));
252b5132 12395
dda8d76d 12396 off = offset_from_vma (filedata,
978c4450 12397 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12398 total * sizeof (short));
95099889
AM
12399 edata = (unsigned char *) get_data (NULL, filedata, off,
12400 sizeof (short), total,
12401 _("version symbol data"));
a6e9f9df
AM
12402 if (!edata)
12403 {
12404 free (strtab);
0429c154 12405 free (symbols);
a6e9f9df
AM
12406 break;
12407 }
252b5132 12408
3f5e193b 12409 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12410
12411 for (cnt = total; cnt --;)
b34976b6
AM
12412 data[cnt] = byte_get (edata + cnt * sizeof (short),
12413 sizeof (short));
252b5132
RH
12414
12415 free (edata);
12416
12417 for (cnt = 0; cnt < total; cnt += 4)
12418 {
12419 int j, nn;
ab273396
AM
12420 char *name;
12421 char *invalid = _("*invalid*");
252b5132
RH
12422
12423 printf (" %03x:", cnt);
12424
12425 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12426 switch (data[cnt + j])
252b5132
RH
12427 {
12428 case 0:
12429 fputs (_(" 0 (*local*) "), stdout);
12430 break;
12431
12432 case 1:
12433 fputs (_(" 1 (*global*) "), stdout);
12434 break;
12435
12436 default:
c244d050
NC
12437 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12438 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12439
dd24e3da 12440 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12441 array, break to avoid an out-of-bounds read. */
12442 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12443 {
12444 warn (_("invalid index into symbol array\n"));
12445 break;
12446 }
12447
ab273396 12448 name = NULL;
978c4450 12449 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12450 {
b34976b6
AM
12451 Elf_Internal_Verneed ivn;
12452 unsigned long offset;
252b5132 12453
d93f0186 12454 offset = offset_from_vma
978c4450
AM
12455 (filedata,
12456 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12457 sizeof (Elf_External_Verneed));
252b5132 12458
b34976b6 12459 do
252b5132 12460 {
b34976b6
AM
12461 Elf_Internal_Vernaux ivna;
12462 Elf_External_Verneed evn;
12463 Elf_External_Vernaux evna;
12464 unsigned long a_off;
252b5132 12465
dda8d76d 12466 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12467 _("version need")) == NULL)
12468 break;
0b4362b0 12469
252b5132
RH
12470 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12471 ivn.vn_next = BYTE_GET (evn.vn_next);
12472
12473 a_off = offset + ivn.vn_aux;
12474
12475 do
12476 {
dda8d76d 12477 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12478 1, _("version need aux (2)")) == NULL)
12479 {
12480 ivna.vna_next = 0;
12481 ivna.vna_other = 0;
12482 }
12483 else
12484 {
12485 ivna.vna_next = BYTE_GET (evna.vna_next);
12486 ivna.vna_other = BYTE_GET (evna.vna_other);
12487 }
252b5132
RH
12488
12489 a_off += ivna.vna_next;
12490 }
b34976b6 12491 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12492 && ivna.vna_next != 0);
12493
b34976b6 12494 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12495 {
12496 ivna.vna_name = BYTE_GET (evna.vna_name);
12497
54806181 12498 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12499 name = invalid;
54806181
AM
12500 else
12501 name = strtab + ivna.vna_name;
252b5132
RH
12502 break;
12503 }
12504
12505 offset += ivn.vn_next;
12506 }
12507 while (ivn.vn_next);
12508 }
00d93f34 12509
ab273396 12510 if (data[cnt + j] != 0x8001
978c4450 12511 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12512 {
b34976b6
AM
12513 Elf_Internal_Verdef ivd;
12514 Elf_External_Verdef evd;
12515 unsigned long offset;
252b5132 12516
d93f0186 12517 offset = offset_from_vma
978c4450
AM
12518 (filedata,
12519 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12520 sizeof evd);
252b5132
RH
12521
12522 do
12523 {
dda8d76d 12524 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12525 _("version def")) == NULL)
12526 {
12527 ivd.vd_next = 0;
948f632f 12528 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12529 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12530 break;
59245841
NC
12531 }
12532 else
12533 {
12534 ivd.vd_next = BYTE_GET (evd.vd_next);
12535 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12536 }
252b5132
RH
12537
12538 offset += ivd.vd_next;
12539 }
c244d050 12540 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12541 && ivd.vd_next != 0);
12542
c244d050 12543 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12544 {
b34976b6
AM
12545 Elf_External_Verdaux evda;
12546 Elf_Internal_Verdaux ivda;
252b5132
RH
12547
12548 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12549
dda8d76d 12550 if (get_data (&evda, filedata,
59245841
NC
12551 offset - ivd.vd_next + ivd.vd_aux,
12552 sizeof (evda), 1,
12553 _("version def aux")) == NULL)
12554 break;
252b5132
RH
12555
12556 ivda.vda_name = BYTE_GET (evda.vda_name);
12557
54806181 12558 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12559 name = invalid;
12560 else if (name != NULL && name != invalid)
12561 name = _("*both*");
54806181
AM
12562 else
12563 name = strtab + ivda.vda_name;
252b5132
RH
12564 }
12565 }
ab273396
AM
12566 if (name != NULL)
12567 nn += printf ("(%s%-*s",
12568 name,
12569 12 - (int) strlen (name),
12570 ")");
252b5132
RH
12571
12572 if (nn < 18)
12573 printf ("%*c", 18 - nn, ' ');
12574 }
12575
12576 putchar ('\n');
12577 }
12578
12579 free (data);
12580 free (strtab);
12581 free (symbols);
12582 }
12583 break;
103f02d3 12584
252b5132
RH
12585 default:
12586 break;
12587 }
12588 }
12589
12590 if (! found)
ca0e11aa
NC
12591 {
12592 if (filedata->is_separate)
12593 printf (_("\nNo version information found in linked file '%s'.\n"),
12594 filedata->file_name);
12595 else
12596 printf (_("\nNo version information found in this file.\n"));
12597 }
252b5132 12598
015dc7e1 12599 return true;
252b5132
RH
12600}
12601
d1133906 12602static const char *
dda8d76d 12603get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12604{
89246a0e 12605 static char buff[64];
252b5132
RH
12606
12607 switch (binding)
12608 {
b34976b6
AM
12609 case STB_LOCAL: return "LOCAL";
12610 case STB_GLOBAL: return "GLOBAL";
12611 case STB_WEAK: return "WEAK";
252b5132
RH
12612 default:
12613 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12614 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12615 binding);
252b5132 12616 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12617 {
12618 if (binding == STB_GNU_UNIQUE
df3a023b 12619 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12620 return "UNIQUE";
12621 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12622 }
252b5132 12623 else
e9e44622 12624 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12625 return buff;
12626 }
12627}
12628
d1133906 12629static const char *
dda8d76d 12630get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12631{
89246a0e 12632 static char buff[64];
252b5132
RH
12633
12634 switch (type)
12635 {
b34976b6
AM
12636 case STT_NOTYPE: return "NOTYPE";
12637 case STT_OBJECT: return "OBJECT";
12638 case STT_FUNC: return "FUNC";
12639 case STT_SECTION: return "SECTION";
12640 case STT_FILE: return "FILE";
12641 case STT_COMMON: return "COMMON";
12642 case STT_TLS: return "TLS";
15ab5209
DB
12643 case STT_RELC: return "RELC";
12644 case STT_SRELC: return "SRELC";
252b5132
RH
12645 default:
12646 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12647 {
dda8d76d 12648 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12649 return "THUMB_FUNC";
103f02d3 12650
dda8d76d 12651 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12652 return "REGISTER";
12653
dda8d76d 12654 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12655 return "PARISC_MILLI";
12656
e9e44622 12657 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12658 }
252b5132 12659 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12660 {
dda8d76d 12661 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12662 {
12663 if (type == STT_HP_OPAQUE)
12664 return "HP_OPAQUE";
12665 if (type == STT_HP_STUB)
12666 return "HP_STUB";
12667 }
12668
d8045f23 12669 if (type == STT_GNU_IFUNC
dda8d76d 12670 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12671 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12672 return "IFUNC";
12673
e9e44622 12674 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12675 }
252b5132 12676 else
e9e44622 12677 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12678 return buff;
12679 }
12680}
12681
d1133906 12682static const char *
d3ba0551 12683get_symbol_visibility (unsigned int visibility)
d1133906
NC
12684{
12685 switch (visibility)
12686 {
b34976b6
AM
12687 case STV_DEFAULT: return "DEFAULT";
12688 case STV_INTERNAL: return "INTERNAL";
12689 case STV_HIDDEN: return "HIDDEN";
d1133906 12690 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12691 default:
27a45f42 12692 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12693 return _("<unknown>");
d1133906
NC
12694 }
12695}
12696
2057d69d
CZ
12697static const char *
12698get_alpha_symbol_other (unsigned int other)
9abca702 12699{
2057d69d
CZ
12700 switch (other)
12701 {
12702 case STO_ALPHA_NOPV: return "NOPV";
12703 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12704 default:
27a45f42 12705 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12706 return _("<unknown>");
9abca702 12707 }
2057d69d
CZ
12708}
12709
fd85a6a1
NC
12710static const char *
12711get_solaris_symbol_visibility (unsigned int visibility)
12712{
12713 switch (visibility)
12714 {
12715 case 4: return "EXPORTED";
12716 case 5: return "SINGLETON";
12717 case 6: return "ELIMINATE";
12718 default: return get_symbol_visibility (visibility);
12719 }
12720}
12721
2301ed1c
SN
12722static const char *
12723get_aarch64_symbol_other (unsigned int other)
12724{
12725 static char buf[32];
12726
12727 if (other & STO_AARCH64_VARIANT_PCS)
12728 {
12729 other &= ~STO_AARCH64_VARIANT_PCS;
12730 if (other == 0)
12731 return "VARIANT_PCS";
12732 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12733 return buf;
12734 }
12735 return NULL;
12736}
12737
5e2b0d47
NC
12738static const char *
12739get_mips_symbol_other (unsigned int other)
12740{
12741 switch (other)
12742 {
32ec8896
NC
12743 case STO_OPTIONAL: return "OPTIONAL";
12744 case STO_MIPS_PLT: return "MIPS PLT";
12745 case STO_MIPS_PIC: return "MIPS PIC";
12746 case STO_MICROMIPS: return "MICROMIPS";
12747 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12748 case STO_MIPS16: return "MIPS16";
12749 default: return NULL;
5e2b0d47
NC
12750 }
12751}
12752
28f997cf 12753static const char *
dda8d76d 12754get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12755{
dda8d76d 12756 if (is_ia64_vms (filedata))
28f997cf
TG
12757 {
12758 static char res[32];
12759
12760 res[0] = 0;
12761
12762 /* Function types is for images and .STB files only. */
dda8d76d 12763 switch (filedata->file_header.e_type)
28f997cf
TG
12764 {
12765 case ET_DYN:
12766 case ET_EXEC:
12767 switch (VMS_ST_FUNC_TYPE (other))
12768 {
12769 case VMS_SFT_CODE_ADDR:
12770 strcat (res, " CA");
12771 break;
12772 case VMS_SFT_SYMV_IDX:
12773 strcat (res, " VEC");
12774 break;
12775 case VMS_SFT_FD:
12776 strcat (res, " FD");
12777 break;
12778 case VMS_SFT_RESERVE:
12779 strcat (res, " RSV");
12780 break;
12781 default:
bee0ee85
NC
12782 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12783 VMS_ST_FUNC_TYPE (other));
12784 strcat (res, " <unknown>");
12785 break;
28f997cf
TG
12786 }
12787 break;
12788 default:
12789 break;
12790 }
12791 switch (VMS_ST_LINKAGE (other))
12792 {
12793 case VMS_STL_IGNORE:
12794 strcat (res, " IGN");
12795 break;
12796 case VMS_STL_RESERVE:
12797 strcat (res, " RSV");
12798 break;
12799 case VMS_STL_STD:
12800 strcat (res, " STD");
12801 break;
12802 case VMS_STL_LNK:
12803 strcat (res, " LNK");
12804 break;
12805 default:
bee0ee85
NC
12806 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12807 VMS_ST_LINKAGE (other));
12808 strcat (res, " <unknown>");
12809 break;
28f997cf
TG
12810 }
12811
12812 if (res[0] != 0)
12813 return res + 1;
12814 else
12815 return res;
12816 }
12817 return NULL;
12818}
12819
6911b7dc
AM
12820static const char *
12821get_ppc64_symbol_other (unsigned int other)
12822{
14732552
AM
12823 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12824 return NULL;
12825
12826 other >>= STO_PPC64_LOCAL_BIT;
12827 if (other <= 6)
6911b7dc 12828 {
89246a0e 12829 static char buf[64];
14732552
AM
12830 if (other >= 2)
12831 other = ppc64_decode_local_entry (other);
12832 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12833 return buf;
12834 }
12835 return NULL;
12836}
12837
8155b853
NC
12838static const char *
12839get_riscv_symbol_other (unsigned int other)
12840{
12841 static char buf[32];
12842 buf[0] = 0;
12843
12844 if (other & STO_RISCV_VARIANT_CC)
12845 {
12846 strcat (buf, _(" VARIANT_CC"));
12847 other &= ~STO_RISCV_VARIANT_CC;
12848 }
12849
12850 if (other != 0)
12851 snprintf (buf, sizeof buf, " %x", other);
12852
12853
12854 if (buf[0] != 0)
12855 return buf + 1;
12856 else
12857 return buf;
12858}
12859
5e2b0d47 12860static const char *
dda8d76d 12861get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12862{
12863 const char * result = NULL;
89246a0e 12864 static char buff [64];
5e2b0d47
NC
12865
12866 if (other == 0)
12867 return "";
12868
dda8d76d 12869 switch (filedata->file_header.e_machine)
5e2b0d47 12870 {
2057d69d
CZ
12871 case EM_ALPHA:
12872 result = get_alpha_symbol_other (other);
12873 break;
2301ed1c
SN
12874 case EM_AARCH64:
12875 result = get_aarch64_symbol_other (other);
12876 break;
5e2b0d47
NC
12877 case EM_MIPS:
12878 result = get_mips_symbol_other (other);
28f997cf
TG
12879 break;
12880 case EM_IA_64:
dda8d76d 12881 result = get_ia64_symbol_other (filedata, other);
28f997cf 12882 break;
6911b7dc
AM
12883 case EM_PPC64:
12884 result = get_ppc64_symbol_other (other);
12885 break;
8155b853
NC
12886 case EM_RISCV:
12887 result = get_riscv_symbol_other (other);
12888 break;
5e2b0d47 12889 default:
fd85a6a1 12890 result = NULL;
5e2b0d47
NC
12891 break;
12892 }
12893
12894 if (result)
12895 return result;
12896
12897 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12898 return buff;
12899}
12900
d1133906 12901static const char *
dda8d76d 12902get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12903{
b34976b6 12904 static char buff[32];
5cf1065c 12905
252b5132
RH
12906 switch (type)
12907 {
b34976b6
AM
12908 case SHN_UNDEF: return "UND";
12909 case SHN_ABS: return "ABS";
12910 case SHN_COMMON: return "COM";
252b5132 12911 default:
9ce701e2 12912 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12913 && filedata->file_header.e_machine == EM_IA_64
12914 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12915 return "ANSI_COM";
12916 else if ((filedata->file_header.e_machine == EM_X86_64
12917 || filedata->file_header.e_machine == EM_L1OM
12918 || filedata->file_header.e_machine == EM_K1OM)
12919 && type == SHN_X86_64_LCOMMON)
12920 return "LARGE_COM";
12921 else if ((type == SHN_MIPS_SCOMMON
12922 && filedata->file_header.e_machine == EM_MIPS)
12923 || (type == SHN_TIC6X_SCOMMON
12924 && filedata->file_header.e_machine == EM_TI_C6000))
12925 return "SCOM";
12926 else if (type == SHN_MIPS_SUNDEFINED
12927 && filedata->file_header.e_machine == EM_MIPS)
12928 return "SUND";
12929 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12930 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12931 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12932 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12933 else if (type >= SHN_LORESERVE)
12934 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12935 else if (filedata->file_header.e_shnum != 0
12936 && type >= filedata->file_header.e_shnum)
12937 sprintf (buff, _("bad section index[%3d]"), type);
12938 else
12939 sprintf (buff, "%3d", type);
12940 break;
fd85a6a1
NC
12941 }
12942
10ca4b04 12943 return buff;
6bd1a22c
L
12944}
12945
bb4d2ac2 12946static const char *
dda8d76d 12947get_symbol_version_string (Filedata * filedata,
015dc7e1 12948 bool is_dynsym,
1449284b
NC
12949 const char * strtab,
12950 unsigned long int strtab_size,
12951 unsigned int si,
12952 Elf_Internal_Sym * psym,
12953 enum versioned_symbol_info * sym_info,
12954 unsigned short * vna_other)
bb4d2ac2 12955{
ab273396
AM
12956 unsigned char data[2];
12957 unsigned short vers_data;
12958 unsigned long offset;
7a815dd5 12959 unsigned short max_vd_ndx;
bb4d2ac2 12960
ab273396 12961 if (!is_dynsym
978c4450 12962 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12963 return NULL;
bb4d2ac2 12964
978c4450
AM
12965 offset = offset_from_vma (filedata,
12966 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12967 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12968
dda8d76d 12969 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12970 sizeof (data), 1, _("version data")) == NULL)
12971 return NULL;
12972
12973 vers_data = byte_get (data, 2);
bb4d2ac2 12974
1f6f5dba 12975 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12976 return NULL;
bb4d2ac2 12977
0b8b7609 12978 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12979 max_vd_ndx = 0;
12980
ab273396
AM
12981 /* Usually we'd only see verdef for defined symbols, and verneed for
12982 undefined symbols. However, symbols defined by the linker in
12983 .dynbss for variables copied from a shared library in order to
12984 avoid text relocations are defined yet have verneed. We could
12985 use a heuristic to detect the special case, for example, check
12986 for verneed first on symbols defined in SHT_NOBITS sections, but
12987 it is simpler and more reliable to just look for both verdef and
12988 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12989
ab273396
AM
12990 if (psym->st_shndx != SHN_UNDEF
12991 && vers_data != 0x8001
978c4450 12992 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12993 {
12994 Elf_Internal_Verdef ivd;
12995 Elf_Internal_Verdaux ivda;
12996 Elf_External_Verdaux evda;
12997 unsigned long off;
bb4d2ac2 12998
dda8d76d 12999 off = offset_from_vma (filedata,
978c4450 13000 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13001 sizeof (Elf_External_Verdef));
13002
13003 do
bb4d2ac2 13004 {
ab273396
AM
13005 Elf_External_Verdef evd;
13006
dda8d76d 13007 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13008 _("version def")) == NULL)
13009 {
13010 ivd.vd_ndx = 0;
13011 ivd.vd_aux = 0;
13012 ivd.vd_next = 0;
1f6f5dba 13013 ivd.vd_flags = 0;
ab273396
AM
13014 }
13015 else
bb4d2ac2 13016 {
ab273396
AM
13017 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13018 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13019 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13020 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13021 }
bb4d2ac2 13022
7a815dd5
L
13023 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13024 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13025
ab273396
AM
13026 off += ivd.vd_next;
13027 }
13028 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13029
ab273396
AM
13030 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13031 {
9abca702 13032 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13033 return NULL;
13034
ab273396
AM
13035 off -= ivd.vd_next;
13036 off += ivd.vd_aux;
bb4d2ac2 13037
dda8d76d 13038 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13039 _("version def aux")) != NULL)
13040 {
13041 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13042
ab273396 13043 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13044 return (ivda.vda_name < strtab_size
13045 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13046 }
13047 }
13048 }
bb4d2ac2 13049
978c4450 13050 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13051 {
13052 Elf_External_Verneed evn;
13053 Elf_Internal_Verneed ivn;
13054 Elf_Internal_Vernaux ivna;
bb4d2ac2 13055
dda8d76d 13056 offset = offset_from_vma (filedata,
978c4450 13057 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13058 sizeof evn);
13059 do
13060 {
13061 unsigned long vna_off;
bb4d2ac2 13062
dda8d76d 13063 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13064 _("version need")) == NULL)
13065 {
13066 ivna.vna_next = 0;
13067 ivna.vna_other = 0;
13068 ivna.vna_name = 0;
13069 break;
13070 }
bb4d2ac2 13071
ab273396
AM
13072 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13073 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13074
ab273396 13075 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13076
ab273396
AM
13077 do
13078 {
13079 Elf_External_Vernaux evna;
bb4d2ac2 13080
dda8d76d 13081 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13082 _("version need aux (3)")) == NULL)
bb4d2ac2 13083 {
ab273396
AM
13084 ivna.vna_next = 0;
13085 ivna.vna_other = 0;
13086 ivna.vna_name = 0;
bb4d2ac2 13087 }
bb4d2ac2 13088 else
bb4d2ac2 13089 {
ab273396
AM
13090 ivna.vna_other = BYTE_GET (evna.vna_other);
13091 ivna.vna_next = BYTE_GET (evna.vna_next);
13092 ivna.vna_name = BYTE_GET (evna.vna_name);
13093 }
bb4d2ac2 13094
ab273396
AM
13095 vna_off += ivna.vna_next;
13096 }
13097 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13098
ab273396
AM
13099 if (ivna.vna_other == vers_data)
13100 break;
bb4d2ac2 13101
ab273396
AM
13102 offset += ivn.vn_next;
13103 }
13104 while (ivn.vn_next != 0);
bb4d2ac2 13105
ab273396
AM
13106 if (ivna.vna_other == vers_data)
13107 {
13108 *sym_info = symbol_undefined;
13109 *vna_other = ivna.vna_other;
13110 return (ivna.vna_name < strtab_size
13111 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13112 }
7a815dd5
L
13113 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13114 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13115 return _("<corrupt>");
bb4d2ac2 13116 }
ab273396 13117 return NULL;
bb4d2ac2
L
13118}
13119
047c3dbf
NL
13120/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13121
13122static unsigned int
625d49fc 13123print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13124{
13125 switch (base)
13126 {
13127 case 8:
13128 return print_vma (vma, OCTAL_5);
13129
13130 case 10:
13131 return print_vma (vma, UNSIGNED_5);
13132
13133 case 16:
13134 return print_vma (vma, PREFIX_HEX_5);
13135
13136 case 0:
13137 default:
13138 return print_vma (vma, DEC_5);
13139 }
13140}
13141
10ca4b04
L
13142static void
13143print_dynamic_symbol (Filedata *filedata, unsigned long si,
13144 Elf_Internal_Sym *symtab,
13145 Elf_Internal_Shdr *section,
13146 char *strtab, size_t strtab_size)
252b5132 13147{
10ca4b04
L
13148 const char *version_string;
13149 enum versioned_symbol_info sym_info;
13150 unsigned short vna_other;
23356397
NC
13151 bool is_valid;
13152 const char * sstr;
10ca4b04 13153 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13154
10ca4b04
L
13155 printf ("%6ld: ", si);
13156 print_vma (psym->st_value, LONG_HEX);
13157 putchar (' ');
047c3dbf 13158 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13159 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13160 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13161 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13162 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13163 else
252b5132 13164 {
10ca4b04 13165 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13166
10ca4b04
L
13167 printf (" %-7s", get_symbol_visibility (vis));
13168 /* Check to see if any other bits in the st_other field are set.
13169 Note - displaying this information disrupts the layout of the
13170 table being generated, but for the moment this case is very rare. */
13171 if (psym->st_other ^ vis)
13172 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13173 }
10ca4b04 13174 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13175
23356397
NC
13176 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13177 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13178 && filedata->section_headers != NULL
23356397
NC
13179 && psym->st_name == 0)
13180 {
84714f86
AM
13181 is_valid
13182 = section_name_valid (filedata,
13183 filedata->section_headers + psym->st_shndx);
23356397 13184 sstr = is_valid ?
84714f86
AM
13185 section_name_print (filedata,
13186 filedata->section_headers + psym->st_shndx)
23356397
NC
13187 : _("<corrupt>");
13188 }
13189 else
13190 {
84714f86 13191 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13192 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13193 }
10ca4b04
L
13194
13195 version_string
13196 = get_symbol_version_string (filedata,
13197 (section == NULL
13198 || section->sh_type == SHT_DYNSYM),
13199 strtab, strtab_size, si,
13200 psym, &sym_info, &vna_other);
b9e920ec 13201
0942c7ab
NC
13202 int len_avail = 21;
13203 if (! do_wide && version_string != NULL)
13204 {
ddb43bab 13205 char buffer[16];
0942c7ab 13206
ddb43bab 13207 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13208
13209 if (sym_info == symbol_undefined)
13210 len_avail -= sprintf (buffer," (%d)", vna_other);
13211 else if (sym_info != symbol_hidden)
13212 len_avail -= 1;
13213 }
13214
13215 print_symbol (len_avail, sstr);
b9e920ec 13216
10ca4b04
L
13217 if (version_string)
13218 {
13219 if (sym_info == symbol_undefined)
13220 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13221 else
10ca4b04
L
13222 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13223 version_string);
13224 }
6bd1a22c 13225
10ca4b04 13226 putchar ('\n');
6bd1a22c 13227
10ca4b04
L
13228 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13229 && section != NULL
13230 && si >= section->sh_info
13231 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13232 && filedata->file_header.e_machine != EM_MIPS
13233 /* Solaris binaries have been found to violate this requirement as
13234 well. Not sure if this is a bug or an ABI requirement. */
13235 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13236 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13237 si, printable_section_name (filedata, section), section->sh_info);
13238}
f16a9783 13239
0f03783c
NC
13240static const char *
13241get_lto_kind (unsigned int kind)
13242{
13243 switch (kind)
13244 {
13245 case 0: return "DEF";
13246 case 1: return "WEAKDEF";
13247 case 2: return "UNDEF";
13248 case 3: return "WEAKUNDEF";
13249 case 4: return "COMMON";
13250 default:
13251 break;
13252 }
13253
13254 static char buffer[30];
13255 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13256 sprintf (buffer, "<unknown: %u>", kind);
13257 return buffer;
13258}
13259
13260static const char *
13261get_lto_visibility (unsigned int visibility)
13262{
13263 switch (visibility)
13264 {
13265 case 0: return "DEFAULT";
13266 case 1: return "PROTECTED";
13267 case 2: return "INTERNAL";
13268 case 3: return "HIDDEN";
13269 default:
13270 break;
13271 }
13272
13273 static char buffer[30];
13274 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13275 sprintf (buffer, "<unknown: %u>", visibility);
13276 return buffer;
13277}
13278
13279static const char *
13280get_lto_sym_type (unsigned int sym_type)
13281{
13282 switch (sym_type)
13283 {
13284 case 0: return "UNKNOWN";
13285 case 1: return "FUNCTION";
13286 case 2: return "VARIABLE";
13287 default:
13288 break;
13289 }
13290
13291 static char buffer[30];
13292 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13293 sprintf (buffer, "<unknown: %u>", sym_type);
13294 return buffer;
13295}
13296
13297/* Display an LTO format symbol table.
13298 FIXME: The format of LTO symbol tables is not formalized.
13299 So this code could need changing in the future. */
13300
015dc7e1 13301static bool
0f03783c
NC
13302display_lto_symtab (Filedata * filedata,
13303 Elf_Internal_Shdr * section)
13304{
13305 if (section->sh_size == 0)
13306 {
ca0e11aa
NC
13307 if (filedata->is_separate)
13308 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13309 printable_section_name (filedata, section),
13310 filedata->file_name);
13311 else
13312 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13313 printable_section_name (filedata, section));
047c3dbf 13314
015dc7e1 13315 return true;
0f03783c
NC
13316 }
13317
13318 if (section->sh_size > filedata->file_size)
13319 {
13320 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13321 printable_section_name (filedata, section),
13322 (unsigned long) section->sh_size);
015dc7e1 13323 return false;
0f03783c
NC
13324 }
13325
13326 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13327 section->sh_size, 1, _("LTO symbols"));
13328 if (alloced_data == NULL)
015dc7e1 13329 return false;
0f03783c
NC
13330
13331 /* Look for extended data for the symbol table. */
13332 Elf_Internal_Shdr * ext;
13333 void * ext_data_orig = NULL;
13334 char * ext_data = NULL;
13335 char * ext_data_end = NULL;
13336 char * ext_name = NULL;
13337
13338 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13339 (section_name (filedata, section)
13340 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13341 && ext_name != NULL /* Paranoia. */
13342 && (ext = find_section (filedata, ext_name)) != NULL)
13343 {
13344 if (ext->sh_size < 3)
13345 error (_("LTO Symbol extension table '%s' is empty!\n"),
13346 printable_section_name (filedata, ext));
13347 else
13348 {
13349 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13350 ext->sh_size, 1,
13351 _("LTO ext symbol data"));
13352 if (ext_data != NULL)
13353 {
13354 ext_data_end = ext_data + ext->sh_size;
13355 if (* ext_data++ != 1)
13356 error (_("Unexpected version number in symbol extension table\n"));
13357 }
13358 }
13359 }
b9e920ec 13360
0f03783c
NC
13361 const unsigned char * data = (const unsigned char *) alloced_data;
13362 const unsigned char * end = data + section->sh_size;
13363
ca0e11aa
NC
13364 if (filedata->is_separate)
13365 printf (_("\nIn linked file '%s': "), filedata->file_name);
13366 else
13367 printf ("\n");
13368
0f03783c
NC
13369 if (ext_data_orig != NULL)
13370 {
13371 if (do_wide)
ca0e11aa 13372 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13373 printable_section_name (filedata, section),
13374 printable_section_name (filedata, ext));
13375 else
13376 {
ca0e11aa 13377 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13378 printable_section_name (filedata, section));
13379 printf (_(" and extension table '%s' contain:\n"),
13380 printable_section_name (filedata, ext));
13381 }
13382 }
13383 else
ca0e11aa 13384 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13385 printable_section_name (filedata, section));
b9e920ec 13386
0f03783c 13387 /* FIXME: Add a wide version. */
b9e920ec 13388 if (ext_data_orig != NULL)
0f03783c
NC
13389 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13390 else
13391 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13392
13393 /* FIXME: We do not handle style prefixes. */
13394
13395 while (data < end)
13396 {
13397 const unsigned char * sym_name = data;
13398 data += strnlen ((const char *) sym_name, end - data) + 1;
13399 if (data >= end)
13400 goto fail;
13401
13402 const unsigned char * comdat_key = data;
13403 data += strnlen ((const char *) comdat_key, end - data) + 1;
13404 if (data >= end)
13405 goto fail;
13406
13407 if (data + 2 + 8 + 4 > end)
13408 goto fail;
13409
13410 unsigned int kind = *data++;
13411 unsigned int visibility = *data++;
13412
928c411d 13413 uint64_t size = byte_get (data, 8);
0f03783c
NC
13414 data += 8;
13415
928c411d 13416 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13417 data += 4;
13418
13419 if (ext_data != NULL)
13420 {
13421 if (ext_data < (ext_data_end - 1))
13422 {
13423 unsigned int sym_type = * ext_data ++;
13424 unsigned int sec_kind = * ext_data ++;
13425
31e5a3a3 13426 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13427 * comdat_key == 0 ? "-" : (char *) comdat_key,
13428 get_lto_kind (kind),
13429 get_lto_visibility (visibility),
31e5a3a3
AM
13430 size,
13431 slot,
0f03783c 13432 get_lto_sym_type (sym_type),
31e5a3a3 13433 sec_kind);
0f03783c
NC
13434 print_symbol (6, (const char *) sym_name);
13435 }
13436 else
13437 {
13438 error (_("Ran out of LTO symbol extension data\n"));
13439 ext_data = NULL;
13440 /* FIXME: return FAIL result ? */
13441 }
13442 }
13443 else
13444 {
31e5a3a3 13445 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13446 * comdat_key == 0 ? "-" : (char *) comdat_key,
13447 get_lto_kind (kind),
13448 get_lto_visibility (visibility),
31e5a3a3
AM
13449 size,
13450 slot);
0f03783c
NC
13451 print_symbol (21, (const char *) sym_name);
13452 }
13453 putchar ('\n');
13454 }
13455
13456 if (ext_data != NULL && ext_data < ext_data_end)
13457 {
13458 error (_("Data remains in the LTO symbol extension table\n"));
13459 goto fail;
13460 }
13461
13462 free (alloced_data);
13463 free (ext_data_orig);
13464 free (ext_name);
015dc7e1 13465 return true;
b9e920ec 13466
0f03783c
NC
13467 fail:
13468 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13469 free (alloced_data);
13470 free (ext_data_orig);
13471 free (ext_name);
015dc7e1 13472 return false;
0f03783c
NC
13473}
13474
13475/* Display LTO symbol tables. */
13476
015dc7e1 13477static bool
0f03783c
NC
13478process_lto_symbol_tables (Filedata * filedata)
13479{
13480 Elf_Internal_Shdr * section;
13481 unsigned int i;
015dc7e1 13482 bool res = true;
0f03783c
NC
13483
13484 if (!do_lto_syms)
015dc7e1 13485 return true;
0f03783c
NC
13486
13487 if (filedata->section_headers == NULL)
015dc7e1 13488 return true;
0f03783c
NC
13489
13490 for (i = 0, section = filedata->section_headers;
13491 i < filedata->file_header.e_shnum;
13492 i++, section++)
84714f86
AM
13493 if (section_name_valid (filedata, section)
13494 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13495 res &= display_lto_symtab (filedata, section);
13496
b9e920ec 13497 return res;
0f03783c
NC
13498}
13499
10ca4b04 13500/* Dump the symbol table. */
0f03783c 13501
015dc7e1 13502static bool
10ca4b04
L
13503process_symbol_table (Filedata * filedata)
13504{
13505 Elf_Internal_Shdr * section;
f16a9783 13506
10ca4b04 13507 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13508 return true;
6bd1a22c 13509
978c4450 13510 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13511 && do_syms
13512 && do_using_dynamic
978c4450
AM
13513 && filedata->dynamic_strings != NULL
13514 && filedata->dynamic_symbols != NULL)
6bd1a22c 13515 {
10ca4b04 13516 unsigned long si;
6bd1a22c 13517
ca0e11aa
NC
13518 if (filedata->is_separate)
13519 {
13520 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13521 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13522 filedata->num_dynamic_syms),
13523 filedata->file_name,
13524 filedata->num_dynamic_syms);
13525 }
13526 else
13527 {
13528 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13529 "\nSymbol table for image contains %lu entries:\n",
13530 filedata->num_dynamic_syms),
13531 filedata->num_dynamic_syms);
13532 }
10ca4b04
L
13533 if (is_32bit_elf)
13534 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13535 else
13536 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13537
978c4450
AM
13538 for (si = 0; si < filedata->num_dynamic_syms; si++)
13539 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13540 filedata->dynamic_strings,
13541 filedata->dynamic_strings_length);
252b5132 13542 }
8b73c356 13543 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13544 && filedata->section_headers != NULL)
252b5132 13545 {
b34976b6 13546 unsigned int i;
252b5132 13547
dda8d76d
NC
13548 for (i = 0, section = filedata->section_headers;
13549 i < filedata->file_header.e_shnum;
252b5132
RH
13550 i++, section++)
13551 {
2cf0635d 13552 char * strtab = NULL;
c256ffe7 13553 unsigned long int strtab_size = 0;
2cf0635d 13554 Elf_Internal_Sym * symtab;
ef3df110 13555 unsigned long si, num_syms;
252b5132 13556
2c610e4b
L
13557 if ((section->sh_type != SHT_SYMTAB
13558 && section->sh_type != SHT_DYNSYM)
13559 || (!do_syms
13560 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13561 continue;
13562
dd24e3da
NC
13563 if (section->sh_entsize == 0)
13564 {
13565 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13566 printable_section_name (filedata, section));
dd24e3da
NC
13567 continue;
13568 }
13569
d3a49aa8 13570 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13571
13572 if (filedata->is_separate)
13573 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13574 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13575 num_syms),
13576 filedata->file_name,
13577 printable_section_name (filedata, section),
13578 num_syms);
13579 else
13580 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13581 "\nSymbol table '%s' contains %lu entries:\n",
13582 num_syms),
13583 printable_section_name (filedata, section),
13584 num_syms);
dd24e3da 13585
f7a99963 13586 if (is_32bit_elf)
ca47b30c 13587 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13588 else
ca47b30c 13589 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13590
4de91c10 13591 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13592 if (symtab == NULL)
13593 continue;
13594
dda8d76d 13595 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13596 {
dda8d76d
NC
13597 strtab = filedata->string_table;
13598 strtab_size = filedata->string_table_length;
c256ffe7 13599 }
dda8d76d 13600 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13601 {
2cf0635d 13602 Elf_Internal_Shdr * string_sec;
252b5132 13603
dda8d76d 13604 string_sec = filedata->section_headers + section->sh_link;
252b5132 13605
dda8d76d 13606 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13607 1, string_sec->sh_size,
13608 _("string table"));
c256ffe7 13609 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13610 }
13611
10ca4b04
L
13612 for (si = 0; si < num_syms; si++)
13613 print_dynamic_symbol (filedata, si, symtab, section,
13614 strtab, strtab_size);
252b5132
RH
13615
13616 free (symtab);
dda8d76d 13617 if (strtab != filedata->string_table)
252b5132
RH
13618 free (strtab);
13619 }
13620 }
13621 else if (do_syms)
13622 printf
13623 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13624
978c4450 13625 if (do_histogram && filedata->buckets != NULL)
252b5132 13626 {
2cf0635d
NC
13627 unsigned long * lengths;
13628 unsigned long * counts;
66543521 13629 unsigned long hn;
625d49fc 13630 uint64_t si;
66543521
AM
13631 unsigned long maxlength = 0;
13632 unsigned long nzero_counts = 0;
13633 unsigned long nsyms = 0;
6bd6a03d 13634 char *visited;
252b5132 13635
d3a49aa8
AM
13636 printf (ngettext ("\nHistogram for bucket list length "
13637 "(total of %lu bucket):\n",
13638 "\nHistogram for bucket list length "
13639 "(total of %lu buckets):\n",
978c4450
AM
13640 (unsigned long) filedata->nbuckets),
13641 (unsigned long) filedata->nbuckets);
252b5132 13642
978c4450
AM
13643 lengths = (unsigned long *) calloc (filedata->nbuckets,
13644 sizeof (*lengths));
252b5132
RH
13645 if (lengths == NULL)
13646 {
8b73c356 13647 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13648 goto err_out;
252b5132 13649 }
978c4450
AM
13650 visited = xcmalloc (filedata->nchains, 1);
13651 memset (visited, 0, filedata->nchains);
8b73c356
NC
13652
13653 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13654 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13655 {
978c4450 13656 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13657 {
b34976b6 13658 ++nsyms;
252b5132 13659 if (maxlength < ++lengths[hn])
b34976b6 13660 ++maxlength;
978c4450 13661 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13662 {
13663 error (_("histogram chain is corrupt\n"));
13664 break;
13665 }
13666 visited[si] = 1;
252b5132
RH
13667 }
13668 }
6bd6a03d 13669 free (visited);
252b5132 13670
3f5e193b 13671 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13672 if (counts == NULL)
13673 {
b2e951ec 13674 free (lengths);
8b73c356 13675 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13676 goto err_out;
252b5132
RH
13677 }
13678
978c4450 13679 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13680 ++counts[lengths[hn]];
252b5132 13681
978c4450 13682 if (filedata->nbuckets > 0)
252b5132 13683 {
66543521
AM
13684 unsigned long i;
13685 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13686 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13687 for (i = 1; i <= maxlength; ++i)
103f02d3 13688 {
66543521
AM
13689 nzero_counts += counts[i] * i;
13690 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13691 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13692 (nzero_counts * 100.0) / nsyms);
13693 }
252b5132
RH
13694 }
13695
13696 free (counts);
13697 free (lengths);
13698 }
13699
978c4450
AM
13700 free (filedata->buckets);
13701 filedata->buckets = NULL;
13702 filedata->nbuckets = 0;
13703 free (filedata->chains);
13704 filedata->chains = NULL;
252b5132 13705
978c4450 13706 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13707 {
2cf0635d
NC
13708 unsigned long * lengths;
13709 unsigned long * counts;
fdc90cb4
JJ
13710 unsigned long hn;
13711 unsigned long maxlength = 0;
13712 unsigned long nzero_counts = 0;
13713 unsigned long nsyms = 0;
fdc90cb4 13714
f16a9783 13715 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13716 "(total of %lu bucket):\n",
f16a9783 13717 "\nHistogram for `%s' bucket list length "
d3a49aa8 13718 "(total of %lu buckets):\n",
978c4450
AM
13719 (unsigned long) filedata->ngnubuckets),
13720 GNU_HASH_SECTION_NAME (filedata),
13721 (unsigned long) filedata->ngnubuckets);
8b73c356 13722
978c4450
AM
13723 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13724 sizeof (*lengths));
fdc90cb4
JJ
13725 if (lengths == NULL)
13726 {
8b73c356 13727 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13728 goto err_out;
fdc90cb4
JJ
13729 }
13730
fdc90cb4
JJ
13731 printf (_(" Length Number %% of total Coverage\n"));
13732
978c4450
AM
13733 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13734 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13735 {
625d49fc 13736 uint64_t off, length = 1;
fdc90cb4 13737
978c4450 13738 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13739 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13740 off < filedata->ngnuchains
13741 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13742 ++off)
fdc90cb4
JJ
13743 ++length;
13744 lengths[hn] = length;
13745 if (length > maxlength)
13746 maxlength = length;
13747 nsyms += length;
13748 }
13749
3f5e193b 13750 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13751 if (counts == NULL)
13752 {
b2e951ec 13753 free (lengths);
8b73c356 13754 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13755 goto err_out;
fdc90cb4
JJ
13756 }
13757
978c4450 13758 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13759 ++counts[lengths[hn]];
13760
978c4450 13761 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13762 {
13763 unsigned long j;
13764 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13765 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13766 for (j = 1; j <= maxlength; ++j)
13767 {
13768 nzero_counts += counts[j] * j;
13769 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13770 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13771 (nzero_counts * 100.0) / nsyms);
13772 }
13773 }
13774
13775 free (counts);
13776 free (lengths);
fdc90cb4 13777 }
978c4450
AM
13778 free (filedata->gnubuckets);
13779 filedata->gnubuckets = NULL;
13780 filedata->ngnubuckets = 0;
13781 free (filedata->gnuchains);
13782 filedata->gnuchains = NULL;
13783 filedata->ngnuchains = 0;
13784 free (filedata->mipsxlat);
13785 filedata->mipsxlat = NULL;
015dc7e1 13786 return true;
fd486f32
AM
13787
13788 err_out:
978c4450
AM
13789 free (filedata->gnubuckets);
13790 filedata->gnubuckets = NULL;
13791 filedata->ngnubuckets = 0;
13792 free (filedata->gnuchains);
13793 filedata->gnuchains = NULL;
13794 filedata->ngnuchains = 0;
13795 free (filedata->mipsxlat);
13796 filedata->mipsxlat = NULL;
13797 free (filedata->buckets);
13798 filedata->buckets = NULL;
13799 filedata->nbuckets = 0;
13800 free (filedata->chains);
13801 filedata->chains = NULL;
015dc7e1 13802 return false;
252b5132
RH
13803}
13804
015dc7e1 13805static bool
ca0e11aa 13806process_syminfo (Filedata * filedata)
252b5132 13807{
b4c96d0d 13808 unsigned int i;
252b5132 13809
978c4450 13810 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13811 || !do_dynamic)
13812 /* No syminfo, this is ok. */
015dc7e1 13813 return true;
252b5132
RH
13814
13815 /* There better should be a dynamic symbol section. */
978c4450 13816 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13817 return false;
252b5132 13818
ca0e11aa
NC
13819 if (filedata->is_separate)
13820 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13821 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13822 filedata->dynamic_syminfo_nent),
13823 filedata->file_name,
13824 filedata->dynamic_syminfo_offset,
13825 filedata->dynamic_syminfo_nent);
13826 else
d3a49aa8
AM
13827 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13828 "contains %d entry:\n",
13829 "\nDynamic info segment at offset 0x%lx "
13830 "contains %d entries:\n",
978c4450 13831 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13832 filedata->dynamic_syminfo_offset,
13833 filedata->dynamic_syminfo_nent);
252b5132
RH
13834
13835 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13836 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13837 {
978c4450 13838 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13839
31104126 13840 printf ("%4d: ", i);
978c4450 13841 if (i >= filedata->num_dynamic_syms)
4082ef84 13842 printf (_("<corrupt index>"));
84714f86
AM
13843 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13844 print_symbol (30, get_dynamic_name (filedata,
978c4450 13845 filedata->dynamic_symbols[i].st_name));
d79b3d50 13846 else
978c4450 13847 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13848 putchar (' ');
252b5132 13849
978c4450 13850 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13851 {
13852 case SYMINFO_BT_SELF:
13853 fputs ("SELF ", stdout);
13854 break;
13855 case SYMINFO_BT_PARENT:
13856 fputs ("PARENT ", stdout);
13857 break;
13858 default:
978c4450
AM
13859 if (filedata->dynamic_syminfo[i].si_boundto > 0
13860 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13861 && valid_dynamic_name (filedata,
978c4450 13862 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13863 {
84714f86 13864 print_symbol (10, get_dynamic_name (filedata,
978c4450 13865 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13866 putchar (' ' );
13867 }
252b5132 13868 else
978c4450 13869 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13870 break;
13871 }
13872
13873 if (flags & SYMINFO_FLG_DIRECT)
13874 printf (" DIRECT");
13875 if (flags & SYMINFO_FLG_PASSTHRU)
13876 printf (" PASSTHRU");
13877 if (flags & SYMINFO_FLG_COPY)
13878 printf (" COPY");
13879 if (flags & SYMINFO_FLG_LAZYLOAD)
13880 printf (" LAZYLOAD");
13881
13882 puts ("");
13883 }
13884
015dc7e1 13885 return true;
252b5132
RH
13886}
13887
75802ccb
CE
13888/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13889 is contained by the region START .. END. The types of ADDR, START
13890 and END should all be the same. Note both ADDR + NELEM and END
13891 point to just beyond the end of the regions that are being tested. */
13892#define IN_RANGE(START,END,ADDR,NELEM) \
13893 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13894
cf13d699
NC
13895/* Check to see if the given reloc needs to be handled in a target specific
13896 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13897 FALSE.
13898
13899 If called with reloc == NULL, then this is a signal that reloc processing
13900 for the current section has finished, and any saved state should be
13901 discarded. */
09c11c86 13902
015dc7e1 13903static bool
dda8d76d
NC
13904target_specific_reloc_handling (Filedata * filedata,
13905 Elf_Internal_Rela * reloc,
13906 unsigned char * start,
13907 unsigned char * end,
13908 Elf_Internal_Sym * symtab,
13909 unsigned long num_syms)
252b5132 13910{
f84ce13b
NC
13911 unsigned int reloc_type = 0;
13912 unsigned long sym_index = 0;
13913
13914 if (reloc)
13915 {
dda8d76d 13916 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13917 sym_index = get_reloc_symindex (reloc->r_info);
13918 }
252b5132 13919
dda8d76d 13920 switch (filedata->file_header.e_machine)
252b5132 13921 {
13761a11
NC
13922 case EM_MSP430:
13923 case EM_MSP430_OLD:
13924 {
13925 static Elf_Internal_Sym * saved_sym = NULL;
13926
f84ce13b
NC
13927 if (reloc == NULL)
13928 {
13929 saved_sym = NULL;
015dc7e1 13930 return true;
f84ce13b
NC
13931 }
13932
13761a11
NC
13933 switch (reloc_type)
13934 {
13935 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13936 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13937 if (uses_msp430x_relocs (filedata))
13761a11 13938 break;
1a0670f3 13939 /* Fall through. */
13761a11 13940 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13941 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13942 /* PR 21139. */
13943 if (sym_index >= num_syms)
13944 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13945 sym_index);
13946 else
13947 saved_sym = symtab + sym_index;
015dc7e1 13948 return true;
13761a11
NC
13949
13950 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13951 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13952 goto handle_sym_diff;
0b4362b0 13953
13761a11
NC
13954 case 5: /* R_MSP430_16_BYTE */
13955 case 9: /* R_MSP430_8 */
7d81bc93 13956 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13957 if (uses_msp430x_relocs (filedata))
13761a11
NC
13958 break;
13959 goto handle_sym_diff;
13960
13961 case 2: /* R_MSP430_ABS16 */
13962 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13963 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13964 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13965 break;
13966 goto handle_sym_diff;
0b4362b0 13967
13761a11
NC
13968 handle_sym_diff:
13969 if (saved_sym != NULL)
13970 {
625d49fc 13971 uint64_t value;
5a805384 13972 unsigned int reloc_size = 0;
7d81bc93
JL
13973 int leb_ret = 0;
13974 switch (reloc_type)
13975 {
13976 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13977 reloc_size = 4;
13978 break;
13979 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13980 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13981 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13982 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13983 &reloc_size, &leb_ret);
7d81bc93
JL
13984 break;
13985 default:
13986 reloc_size = 2;
13987 break;
13988 }
13761a11 13989
5a805384 13990 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13991 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13992 "ULEB128 value\n"),
13993 (long) reloc->r_offset);
13994 else if (sym_index >= num_syms)
f84ce13b
NC
13995 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13996 sym_index);
03f7786e 13997 else
f84ce13b
NC
13998 {
13999 value = reloc->r_addend + (symtab[sym_index].st_value
14000 - saved_sym->st_value);
14001
b32e566b 14002 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14003 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14004 else
14005 /* PR 21137 */
14006 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
14007 (long) reloc->r_offset);
f84ce13b 14008 }
13761a11
NC
14009
14010 saved_sym = NULL;
015dc7e1 14011 return true;
13761a11
NC
14012 }
14013 break;
14014
14015 default:
14016 if (saved_sym != NULL)
071436c6 14017 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14018 break;
14019 }
14020 break;
14021 }
14022
cf13d699
NC
14023 case EM_MN10300:
14024 case EM_CYGNUS_MN10300:
14025 {
14026 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14027
f84ce13b
NC
14028 if (reloc == NULL)
14029 {
14030 saved_sym = NULL;
015dc7e1 14031 return true;
f84ce13b
NC
14032 }
14033
cf13d699
NC
14034 switch (reloc_type)
14035 {
14036 case 34: /* R_MN10300_ALIGN */
015dc7e1 14037 return true;
cf13d699 14038 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
14039 if (sym_index >= num_syms)
14040 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
14041 sym_index);
14042 else
14043 saved_sym = symtab + sym_index;
015dc7e1 14044 return true;
f84ce13b 14045
cf13d699
NC
14046 case 1: /* R_MN10300_32 */
14047 case 2: /* R_MN10300_16 */
14048 if (saved_sym != NULL)
14049 {
03f7786e 14050 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14051 uint64_t value;
252b5132 14052
f84ce13b
NC
14053 if (sym_index >= num_syms)
14054 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14055 sym_index);
03f7786e 14056 else
f84ce13b
NC
14057 {
14058 value = reloc->r_addend + (symtab[sym_index].st_value
14059 - saved_sym->st_value);
14060
b32e566b 14061 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14062 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14063 else
14064 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14065 (long) reloc->r_offset);
f84ce13b 14066 }
252b5132 14067
cf13d699 14068 saved_sym = NULL;
015dc7e1 14069 return true;
cf13d699
NC
14070 }
14071 break;
14072 default:
14073 if (saved_sym != NULL)
071436c6 14074 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14075 break;
14076 }
14077 break;
14078 }
6ff71e76
NC
14079
14080 case EM_RL78:
14081 {
625d49fc
AM
14082 static uint64_t saved_sym1 = 0;
14083 static uint64_t saved_sym2 = 0;
14084 static uint64_t value;
6ff71e76 14085
f84ce13b
NC
14086 if (reloc == NULL)
14087 {
14088 saved_sym1 = saved_sym2 = 0;
015dc7e1 14089 return true;
f84ce13b
NC
14090 }
14091
6ff71e76
NC
14092 switch (reloc_type)
14093 {
14094 case 0x80: /* R_RL78_SYM. */
14095 saved_sym1 = saved_sym2;
f84ce13b
NC
14096 if (sym_index >= num_syms)
14097 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14098 sym_index);
14099 else
14100 {
14101 saved_sym2 = symtab[sym_index].st_value;
14102 saved_sym2 += reloc->r_addend;
14103 }
015dc7e1 14104 return true;
6ff71e76
NC
14105
14106 case 0x83: /* R_RL78_OPsub. */
14107 value = saved_sym1 - saved_sym2;
14108 saved_sym2 = saved_sym1 = 0;
015dc7e1 14109 return true;
6ff71e76
NC
14110 break;
14111
14112 case 0x41: /* R_RL78_ABS32. */
b32e566b 14113 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14114 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14115 else
14116 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14117 (long) reloc->r_offset);
6ff71e76 14118 value = 0;
015dc7e1 14119 return true;
6ff71e76
NC
14120
14121 case 0x43: /* R_RL78_ABS16. */
b32e566b 14122 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14123 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14124 else
14125 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14126 (long) reloc->r_offset);
6ff71e76 14127 value = 0;
015dc7e1 14128 return true;
6ff71e76
NC
14129
14130 default:
14131 break;
14132 }
14133 break;
14134 }
252b5132
RH
14135 }
14136
015dc7e1 14137 return false;
252b5132
RH
14138}
14139
aca88567
NC
14140/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14141 DWARF debug sections. This is a target specific test. Note - we do not
14142 go through the whole including-target-headers-multiple-times route, (as
14143 we have already done with <elf/h8.h>) because this would become very
14144 messy and even then this function would have to contain target specific
14145 information (the names of the relocs instead of their numeric values).
14146 FIXME: This is not the correct way to solve this problem. The proper way
14147 is to have target specific reloc sizing and typing functions created by
14148 the reloc-macros.h header, in the same way that it already creates the
14149 reloc naming functions. */
14150
015dc7e1 14151static bool
dda8d76d 14152is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14153{
d347c9df 14154 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14155 switch (filedata->file_header.e_machine)
aca88567 14156 {
41e92641 14157 case EM_386:
22abe556 14158 case EM_IAMCU:
41e92641 14159 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14160 case EM_68K:
14161 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14162 case EM_860:
14163 return reloc_type == 1; /* R_860_32. */
14164 case EM_960:
14165 return reloc_type == 2; /* R_960_32. */
a06ea964 14166 case EM_AARCH64:
9282b95a
JW
14167 return (reloc_type == 258
14168 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14169 case EM_BPF:
14170 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14171 case EM_ADAPTEVA_EPIPHANY:
14172 return reloc_type == 3;
aca88567 14173 case EM_ALPHA:
137b6b5f 14174 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14175 case EM_ARC:
14176 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14177 case EM_ARC_COMPACT:
14178 case EM_ARC_COMPACT2:
14179 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14180 case EM_ARM:
14181 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14182 case EM_AVR_OLD:
aca88567
NC
14183 case EM_AVR:
14184 return reloc_type == 1;
14185 case EM_BLACKFIN:
14186 return reloc_type == 0x12; /* R_byte4_data. */
14187 case EM_CRIS:
14188 return reloc_type == 3; /* R_CRIS_32. */
14189 case EM_CR16:
14190 return reloc_type == 3; /* R_CR16_NUM32. */
14191 case EM_CRX:
14192 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14193 case EM_CSKY:
14194 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14195 case EM_CYGNUS_FRV:
14196 return reloc_type == 1;
41e92641
NC
14197 case EM_CYGNUS_D10V:
14198 case EM_D10V:
14199 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14200 case EM_CYGNUS_D30V:
14201 case EM_D30V:
14202 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14203 case EM_DLX:
14204 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14205 case EM_CYGNUS_FR30:
14206 case EM_FR30:
14207 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14208 case EM_FT32:
14209 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14210 case EM_H8S:
14211 case EM_H8_300:
14212 case EM_H8_300H:
14213 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14214 case EM_IA_64:
262cdac7
AM
14215 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14216 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14217 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14218 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14219 case EM_IP2K_OLD:
14220 case EM_IP2K:
14221 return reloc_type == 2; /* R_IP2K_32. */
14222 case EM_IQ2000:
14223 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14224 case EM_LATTICEMICO32:
14225 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14226 case EM_LOONGARCH:
14227 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14228 case EM_M32C_OLD:
aca88567
NC
14229 case EM_M32C:
14230 return reloc_type == 3; /* R_M32C_32. */
14231 case EM_M32R:
14232 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14233 case EM_68HC11:
14234 case EM_68HC12:
14235 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14236 case EM_S12Z:
2849d19f
JD
14237 return reloc_type == 7 || /* R_S12Z_EXT32 */
14238 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14239 case EM_MCORE:
14240 return reloc_type == 1; /* R_MCORE_ADDR32. */
14241 case EM_CYGNUS_MEP:
14242 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14243 case EM_METAG:
14244 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14245 case EM_MICROBLAZE:
14246 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14247 case EM_MIPS:
14248 return reloc_type == 2; /* R_MIPS_32. */
14249 case EM_MMIX:
14250 return reloc_type == 4; /* R_MMIX_32. */
14251 case EM_CYGNUS_MN10200:
14252 case EM_MN10200:
14253 return reloc_type == 1; /* R_MN10200_32. */
14254 case EM_CYGNUS_MN10300:
14255 case EM_MN10300:
14256 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14257 case EM_MOXIE:
14258 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14259 case EM_MSP430_OLD:
14260 case EM_MSP430:
13761a11 14261 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14262 case EM_MT:
14263 return reloc_type == 2; /* R_MT_32. */
35c08157 14264 case EM_NDS32:
81c5e376 14265 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14266 case EM_ALTERA_NIOS2:
36591ba1 14267 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14268 case EM_NIOS32:
14269 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14270 case EM_OR1K:
14271 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14272 case EM_PARISC:
9abca702 14273 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14274 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14275 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14276 case EM_PJ:
14277 case EM_PJ_OLD:
14278 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14279 case EM_PPC64:
14280 return reloc_type == 1; /* R_PPC64_ADDR32. */
14281 case EM_PPC:
14282 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14283 case EM_TI_PRU:
14284 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14285 case EM_RISCV:
14286 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14287 case EM_RL78:
14288 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14289 case EM_RX:
14290 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14291 case EM_S370:
14292 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14293 case EM_S390_OLD:
14294 case EM_S390:
14295 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14296 case EM_SCORE:
14297 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14298 case EM_SH:
14299 return reloc_type == 1; /* R_SH_DIR32. */
14300 case EM_SPARC32PLUS:
14301 case EM_SPARCV9:
14302 case EM_SPARC:
14303 return reloc_type == 3 /* R_SPARC_32. */
14304 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14305 case EM_SPU:
14306 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14307 case EM_TI_C6000:
14308 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14309 case EM_TILEGX:
14310 return reloc_type == 2; /* R_TILEGX_32. */
14311 case EM_TILEPRO:
14312 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14313 case EM_CYGNUS_V850:
14314 case EM_V850:
14315 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14316 case EM_V800:
14317 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14318 case EM_VAX:
14319 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14320 case EM_VISIUM:
14321 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14322 case EM_WEBASSEMBLY:
14323 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14324 case EM_X86_64:
8a9036a4 14325 case EM_L1OM:
7a9068fe 14326 case EM_K1OM:
aca88567 14327 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14328 case EM_XGATE:
14329 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14330 case EM_XSTORMY16:
14331 return reloc_type == 1; /* R_XSTROMY16_32. */
14332 case EM_XTENSA_OLD:
14333 case EM_XTENSA:
14334 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14335 case EM_Z80:
14336 return reloc_type == 6; /* R_Z80_32. */
aca88567 14337 default:
bee0ee85
NC
14338 {
14339 static unsigned int prev_warn = 0;
14340
14341 /* Avoid repeating the same warning multiple times. */
dda8d76d 14342 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14343 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14344 filedata->file_header.e_machine);
14345 prev_warn = filedata->file_header.e_machine;
015dc7e1 14346 return false;
bee0ee85 14347 }
aca88567
NC
14348 }
14349}
14350
14351/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14352 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14353
015dc7e1 14354static bool
dda8d76d 14355is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14356{
dda8d76d 14357 switch (filedata->file_header.e_machine)
d347c9df 14358 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14359 {
41e92641 14360 case EM_386:
22abe556 14361 case EM_IAMCU:
3e0873ac 14362 return reloc_type == 2; /* R_386_PC32. */
aca88567 14363 case EM_68K:
3e0873ac 14364 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14365 case EM_AARCH64:
14366 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14367 case EM_ADAPTEVA_EPIPHANY:
14368 return reloc_type == 6;
aca88567
NC
14369 case EM_ALPHA:
14370 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14371 case EM_ARC_COMPACT:
14372 case EM_ARC_COMPACT2:
14373 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14374 case EM_ARM:
3e0873ac 14375 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14376 case EM_AVR_OLD:
14377 case EM_AVR:
14378 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14379 case EM_LOONGARCH:
14380 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14381 case EM_MICROBLAZE:
14382 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14383 case EM_OR1K:
14384 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14385 case EM_PARISC:
85acf597 14386 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14387 case EM_PPC:
14388 return reloc_type == 26; /* R_PPC_REL32. */
14389 case EM_PPC64:
3e0873ac 14390 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14391 case EM_RISCV:
14392 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14393 case EM_S390_OLD:
14394 case EM_S390:
3e0873ac 14395 return reloc_type == 5; /* R_390_PC32. */
aca88567 14396 case EM_SH:
3e0873ac 14397 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14398 case EM_SPARC32PLUS:
14399 case EM_SPARCV9:
14400 case EM_SPARC:
3e0873ac 14401 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14402 case EM_SPU:
14403 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14404 case EM_TILEGX:
14405 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14406 case EM_TILEPRO:
14407 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14408 case EM_VISIUM:
14409 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14410 case EM_X86_64:
8a9036a4 14411 case EM_L1OM:
7a9068fe 14412 case EM_K1OM:
3e0873ac 14413 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14414 case EM_VAX:
14415 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14416 case EM_XTENSA_OLD:
14417 case EM_XTENSA:
14418 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14419 default:
14420 /* Do not abort or issue an error message here. Not all targets use
14421 pc-relative 32-bit relocs in their DWARF debug information and we
14422 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14423 more helpful warning message will be generated by apply_relocations
14424 anyway, so just return. */
015dc7e1 14425 return false;
aca88567
NC
14426 }
14427}
14428
14429/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14430 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14431
015dc7e1 14432static bool
dda8d76d 14433is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14434{
dda8d76d 14435 switch (filedata->file_header.e_machine)
aca88567 14436 {
a06ea964
NC
14437 case EM_AARCH64:
14438 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14439 case EM_ALPHA:
14440 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14441 case EM_IA_64:
262cdac7
AM
14442 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14443 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14444 case EM_LOONGARCH:
14445 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14446 case EM_PARISC:
14447 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14448 case EM_PPC64:
14449 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14450 case EM_RISCV:
14451 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14452 case EM_SPARC32PLUS:
14453 case EM_SPARCV9:
14454 case EM_SPARC:
714da62f
NC
14455 return reloc_type == 32 /* R_SPARC_64. */
14456 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14457 case EM_X86_64:
8a9036a4 14458 case EM_L1OM:
7a9068fe 14459 case EM_K1OM:
aca88567 14460 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14461 case EM_S390_OLD:
14462 case EM_S390:
aa137e4d
NC
14463 return reloc_type == 22; /* R_S390_64. */
14464 case EM_TILEGX:
14465 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14466 case EM_MIPS:
aa137e4d 14467 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14468 default:
015dc7e1 14469 return false;
aca88567
NC
14470 }
14471}
14472
85acf597
RH
14473/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14474 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14475
015dc7e1 14476static bool
dda8d76d 14477is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14478{
dda8d76d 14479 switch (filedata->file_header.e_machine)
85acf597 14480 {
a06ea964
NC
14481 case EM_AARCH64:
14482 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14483 case EM_ALPHA:
aa137e4d 14484 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14485 case EM_IA_64:
262cdac7
AM
14486 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14487 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14488 case EM_PARISC:
aa137e4d 14489 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14490 case EM_PPC64:
aa137e4d 14491 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14492 case EM_SPARC32PLUS:
14493 case EM_SPARCV9:
14494 case EM_SPARC:
aa137e4d 14495 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14496 case EM_X86_64:
8a9036a4 14497 case EM_L1OM:
7a9068fe 14498 case EM_K1OM:
aa137e4d 14499 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14500 case EM_S390_OLD:
14501 case EM_S390:
aa137e4d
NC
14502 return reloc_type == 23; /* R_S390_PC64. */
14503 case EM_TILEGX:
14504 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14505 default:
015dc7e1 14506 return false;
85acf597
RH
14507 }
14508}
14509
4dc3c23d
AM
14510/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14511 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14512
015dc7e1 14513static bool
dda8d76d 14514is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14515{
dda8d76d 14516 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14517 {
14518 case EM_CYGNUS_MN10200:
14519 case EM_MN10200:
14520 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14521 case EM_FT32:
14522 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14523 case EM_Z80:
14524 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14525 default:
015dc7e1 14526 return false;
4dc3c23d
AM
14527 }
14528}
14529
aca88567
NC
14530/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14531 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14532
015dc7e1 14533static bool
dda8d76d 14534is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14535{
d347c9df 14536 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14537 switch (filedata->file_header.e_machine)
4b78141a 14538 {
886a2506
NC
14539 case EM_ARC:
14540 case EM_ARC_COMPACT:
14541 case EM_ARC_COMPACT2:
14542 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14543 case EM_ADAPTEVA_EPIPHANY:
14544 return reloc_type == 5;
aca88567
NC
14545 case EM_AVR_OLD:
14546 case EM_AVR:
14547 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14548 case EM_CYGNUS_D10V:
14549 case EM_D10V:
14550 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14551 case EM_FT32:
14552 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14553 case EM_H8S:
14554 case EM_H8_300:
14555 case EM_H8_300H:
aca88567
NC
14556 return reloc_type == R_H8_DIR16;
14557 case EM_IP2K_OLD:
14558 case EM_IP2K:
14559 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14560 case EM_M32C_OLD:
f4236fe4
DD
14561 case EM_M32C:
14562 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14563 case EM_CYGNUS_MN10200:
14564 case EM_MN10200:
14565 return reloc_type == 2; /* R_MN10200_16. */
14566 case EM_CYGNUS_MN10300:
14567 case EM_MN10300:
14568 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14569 case EM_MSP430:
dda8d76d 14570 if (uses_msp430x_relocs (filedata))
13761a11 14571 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14572 /* Fall through. */
78c8d46c 14573 case EM_MSP430_OLD:
aca88567 14574 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14575 case EM_NDS32:
81c5e376 14576 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14577 case EM_ALTERA_NIOS2:
36591ba1 14578 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14579 case EM_NIOS32:
14580 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14581 case EM_OR1K:
14582 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14583 case EM_RISCV:
14584 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14585 case EM_TI_PRU:
14586 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14587 case EM_TI_C6000:
14588 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14589 case EM_VISIUM:
14590 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14591 case EM_XGATE:
14592 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14593 case EM_Z80:
14594 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14595 default:
015dc7e1 14596 return false;
4b78141a
NC
14597 }
14598}
14599
39e07931
AS
14600/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14601 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14602
015dc7e1 14603static bool
39e07931
AS
14604is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14605{
14606 switch (filedata->file_header.e_machine)
14607 {
14608 case EM_RISCV:
14609 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14610 case EM_Z80:
14611 return reloc_type == 1; /* R_Z80_8. */
39e07931 14612 default:
015dc7e1 14613 return false;
39e07931
AS
14614 }
14615}
14616
14617/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14618 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14619
015dc7e1 14620static bool
39e07931
AS
14621is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14622{
14623 switch (filedata->file_header.e_machine)
14624 {
14625 case EM_RISCV:
14626 return reloc_type == 53; /* R_RISCV_SET6. */
14627 default:
015dc7e1 14628 return false;
39e07931
AS
14629 }
14630}
14631
03336641
JW
14632/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14633 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14634
015dc7e1 14635static bool
03336641
JW
14636is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14637{
14638 /* Please keep this table alpha-sorted for ease of visual lookup. */
14639 switch (filedata->file_header.e_machine)
14640 {
14641 case EM_RISCV:
14642 return reloc_type == 35; /* R_RISCV_ADD32. */
14643 default:
015dc7e1 14644 return false;
03336641
JW
14645 }
14646}
14647
14648/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14649 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14650
015dc7e1 14651static bool
03336641
JW
14652is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14653{
14654 /* Please keep this table alpha-sorted for ease of visual lookup. */
14655 switch (filedata->file_header.e_machine)
14656 {
14657 case EM_RISCV:
14658 return reloc_type == 39; /* R_RISCV_SUB32. */
14659 default:
015dc7e1 14660 return false;
03336641
JW
14661 }
14662}
14663
14664/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14665 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14666
015dc7e1 14667static bool
03336641
JW
14668is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14669{
14670 /* Please keep this table alpha-sorted for ease of visual lookup. */
14671 switch (filedata->file_header.e_machine)
14672 {
14673 case EM_RISCV:
14674 return reloc_type == 36; /* R_RISCV_ADD64. */
14675 default:
015dc7e1 14676 return false;
03336641
JW
14677 }
14678}
14679
14680/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14681 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14682
015dc7e1 14683static bool
03336641
JW
14684is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14685{
14686 /* Please keep this table alpha-sorted for ease of visual lookup. */
14687 switch (filedata->file_header.e_machine)
14688 {
14689 case EM_RISCV:
14690 return reloc_type == 40; /* R_RISCV_SUB64. */
14691 default:
015dc7e1 14692 return false;
03336641
JW
14693 }
14694}
14695
14696/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14697 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14698
015dc7e1 14699static bool
03336641
JW
14700is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14701{
14702 /* Please keep this table alpha-sorted for ease of visual lookup. */
14703 switch (filedata->file_header.e_machine)
14704 {
14705 case EM_RISCV:
14706 return reloc_type == 34; /* R_RISCV_ADD16. */
14707 default:
015dc7e1 14708 return false;
03336641
JW
14709 }
14710}
14711
14712/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14713 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14714
015dc7e1 14715static bool
03336641
JW
14716is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14717{
14718 /* Please keep this table alpha-sorted for ease of visual lookup. */
14719 switch (filedata->file_header.e_machine)
14720 {
14721 case EM_RISCV:
14722 return reloc_type == 38; /* R_RISCV_SUB16. */
14723 default:
015dc7e1 14724 return false;
03336641
JW
14725 }
14726}
14727
14728/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14729 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14730
015dc7e1 14731static bool
03336641
JW
14732is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14733{
14734 /* Please keep this table alpha-sorted for ease of visual lookup. */
14735 switch (filedata->file_header.e_machine)
14736 {
14737 case EM_RISCV:
14738 return reloc_type == 33; /* R_RISCV_ADD8. */
14739 default:
015dc7e1 14740 return false;
03336641
JW
14741 }
14742}
14743
14744/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14745 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14746
015dc7e1 14747static bool
03336641
JW
14748is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14749{
14750 /* Please keep this table alpha-sorted for ease of visual lookup. */
14751 switch (filedata->file_header.e_machine)
14752 {
14753 case EM_RISCV:
14754 return reloc_type == 37; /* R_RISCV_SUB8. */
14755 default:
015dc7e1 14756 return false;
03336641
JW
14757 }
14758}
14759
39e07931
AS
14760/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14761 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14762
015dc7e1 14763static bool
39e07931
AS
14764is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14765{
14766 switch (filedata->file_header.e_machine)
14767 {
14768 case EM_RISCV:
14769 return reloc_type == 52; /* R_RISCV_SUB6. */
14770 default:
015dc7e1 14771 return false;
39e07931
AS
14772 }
14773}
14774
2a7b2e88
JK
14775/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14776 relocation entries (possibly formerly used for SHT_GROUP sections). */
14777
015dc7e1 14778static bool
dda8d76d 14779is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14780{
dda8d76d 14781 switch (filedata->file_header.e_machine)
2a7b2e88 14782 {
cb8f3167 14783 case EM_386: /* R_386_NONE. */
d347c9df 14784 case EM_68K: /* R_68K_NONE. */
cfb8c092 14785 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14786 case EM_ALPHA: /* R_ALPHA_NONE. */
14787 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14788 case EM_ARC: /* R_ARC_NONE. */
886a2506 14789 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14790 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14791 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14792 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14793 case EM_FT32: /* R_FT32_NONE. */
14794 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14795 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14796 case EM_L1OM: /* R_X86_64_NONE. */
14797 case EM_M32R: /* R_M32R_NONE. */
14798 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14799 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14800 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14801 case EM_NIOS32: /* R_NIOS_NONE. */
14802 case EM_OR1K: /* R_OR1K_NONE. */
14803 case EM_PARISC: /* R_PARISC_NONE. */
14804 case EM_PPC64: /* R_PPC64_NONE. */
14805 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14806 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14807 case EM_S390: /* R_390_NONE. */
14808 case EM_S390_OLD:
14809 case EM_SH: /* R_SH_NONE. */
14810 case EM_SPARC32PLUS:
14811 case EM_SPARC: /* R_SPARC_NONE. */
14812 case EM_SPARCV9:
aa137e4d
NC
14813 case EM_TILEGX: /* R_TILEGX_NONE. */
14814 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14815 case EM_TI_C6000:/* R_C6000_NONE. */
14816 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14817 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14818 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14819 return reloc_type == 0;
d347c9df 14820
a06ea964
NC
14821 case EM_AARCH64:
14822 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14823 case EM_AVR_OLD:
14824 case EM_AVR:
14825 return (reloc_type == 0 /* R_AVR_NONE. */
14826 || reloc_type == 30 /* R_AVR_DIFF8. */
14827 || reloc_type == 31 /* R_AVR_DIFF16. */
14828 || reloc_type == 32 /* R_AVR_DIFF32. */);
14829 case EM_METAG:
14830 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14831 case EM_NDS32:
81c5e376
AM
14832 return (reloc_type == 0 /* R_NDS32_NONE. */
14833 || reloc_type == 205 /* R_NDS32_DIFF8. */
14834 || reloc_type == 206 /* R_NDS32_DIFF16. */
14835 || reloc_type == 207 /* R_NDS32_DIFF32. */
14836 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14837 case EM_TI_PRU:
14838 return (reloc_type == 0 /* R_PRU_NONE. */
14839 || reloc_type == 65 /* R_PRU_DIFF8. */
14840 || reloc_type == 66 /* R_PRU_DIFF16. */
14841 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14842 case EM_XTENSA_OLD:
14843 case EM_XTENSA:
4dc3c23d
AM
14844 return (reloc_type == 0 /* R_XTENSA_NONE. */
14845 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14846 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14847 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14848 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14849 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14850 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14851 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14852 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14853 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14854 }
015dc7e1 14855 return false;
2a7b2e88
JK
14856}
14857
d1c4b12b
NC
14858/* Returns TRUE if there is a relocation against
14859 section NAME at OFFSET bytes. */
14860
015dc7e1 14861bool
31e5a3a3 14862reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
14863{
14864 Elf_Internal_Rela * relocs;
14865 Elf_Internal_Rela * rp;
14866
14867 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14868 return false;
d1c4b12b
NC
14869
14870 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14871
14872 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14873 if (rp->r_offset == offset)
015dc7e1 14874 return true;
d1c4b12b 14875
015dc7e1 14876 return false;
d1c4b12b
NC
14877}
14878
cf13d699 14879/* Apply relocations to a section.
32ec8896
NC
14880 Returns TRUE upon success, FALSE otherwise.
14881 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14882 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14883 will be set to the number of relocs loaded.
14884
cf13d699 14885 Note: So far support has been added only for those relocations
32ec8896
NC
14886 which can be found in debug sections. FIXME: Add support for
14887 more relocations ? */
1b315056 14888
015dc7e1 14889static bool
be7d229a
AM
14890apply_relocations (Filedata *filedata,
14891 const Elf_Internal_Shdr *section,
14892 unsigned char *start,
14893 size_t size,
14894 void **relocs_return,
14895 unsigned long *num_relocs_return)
1b315056 14896{
cf13d699 14897 Elf_Internal_Shdr * relsec;
0d2a7a93 14898 unsigned char * end = start + size;
cb8f3167 14899
d1c4b12b
NC
14900 if (relocs_return != NULL)
14901 {
14902 * (Elf_Internal_Rela **) relocs_return = NULL;
14903 * num_relocs_return = 0;
14904 }
14905
dda8d76d 14906 if (filedata->file_header.e_type != ET_REL)
32ec8896 14907 /* No relocs to apply. */
015dc7e1 14908 return true;
1b315056 14909
cf13d699 14910 /* Find the reloc section associated with the section. */
dda8d76d
NC
14911 for (relsec = filedata->section_headers;
14912 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14913 ++relsec)
252b5132 14914 {
015dc7e1 14915 bool is_rela;
41e92641 14916 unsigned long num_relocs;
2cf0635d
NC
14917 Elf_Internal_Rela * relocs;
14918 Elf_Internal_Rela * rp;
14919 Elf_Internal_Shdr * symsec;
14920 Elf_Internal_Sym * symtab;
ba5cdace 14921 unsigned long num_syms;
2cf0635d 14922 Elf_Internal_Sym * sym;
252b5132 14923
41e92641 14924 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14925 || relsec->sh_info >= filedata->file_header.e_shnum
14926 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14927 || relsec->sh_size == 0
dda8d76d 14928 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14929 continue;
428409d5 14930
a788aedd
AM
14931 symsec = filedata->section_headers + relsec->sh_link;
14932 if (symsec->sh_type != SHT_SYMTAB
14933 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14934 return false;
a788aedd 14935
41e92641
NC
14936 is_rela = relsec->sh_type == SHT_RELA;
14937
14938 if (is_rela)
14939 {
dda8d76d 14940 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14941 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14942 return false;
41e92641
NC
14943 }
14944 else
14945 {
dda8d76d 14946 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14947 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14948 return false;
41e92641
NC
14949 }
14950
14951 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14952 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14953 is_rela = false;
428409d5 14954
4de91c10 14955 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14956
41e92641 14957 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14958 {
625d49fc 14959 uint64_t addend;
015dc7e1
AM
14960 unsigned int reloc_type;
14961 unsigned int reloc_size;
14962 bool reloc_inplace = false;
14963 bool reloc_subtract = false;
14964 unsigned char *rloc;
14965 unsigned long sym_index;
4b78141a 14966
dda8d76d 14967 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14968
dda8d76d 14969 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14970 continue;
dda8d76d 14971 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14972 continue;
dda8d76d
NC
14973 else if (is_32bit_abs_reloc (filedata, reloc_type)
14974 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14975 reloc_size = 4;
dda8d76d
NC
14976 else if (is_64bit_abs_reloc (filedata, reloc_type)
14977 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14978 reloc_size = 8;
dda8d76d 14979 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14980 reloc_size = 3;
dda8d76d 14981 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14982 reloc_size = 2;
39e07931
AS
14983 else if (is_8bit_abs_reloc (filedata, reloc_type)
14984 || is_6bit_abs_reloc (filedata, reloc_type))
14985 reloc_size = 1;
03336641
JW
14986 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14987 reloc_type))
14988 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14989 {
14990 reloc_size = 4;
015dc7e1 14991 reloc_inplace = true;
03336641
JW
14992 }
14993 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14994 reloc_type))
14995 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14996 {
14997 reloc_size = 8;
015dc7e1 14998 reloc_inplace = true;
03336641
JW
14999 }
15000 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15001 reloc_type))
15002 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15003 {
15004 reloc_size = 2;
015dc7e1 15005 reloc_inplace = true;
03336641
JW
15006 }
15007 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15008 reloc_type))
15009 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15010 {
15011 reloc_size = 1;
015dc7e1 15012 reloc_inplace = true;
03336641 15013 }
39e07931
AS
15014 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15015 reloc_type)))
15016 {
15017 reloc_size = 1;
015dc7e1 15018 reloc_inplace = true;
39e07931 15019 }
aca88567 15020 else
4b78141a 15021 {
bee0ee85 15022 static unsigned int prev_reloc = 0;
dda8d76d 15023
bee0ee85
NC
15024 if (reloc_type != prev_reloc)
15025 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15026 reloc_type, printable_section_name (filedata, section));
bee0ee85 15027 prev_reloc = reloc_type;
4b78141a
NC
15028 continue;
15029 }
103f02d3 15030
91d6fa6a 15031 rloc = start + rp->r_offset;
75802ccb 15032 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
15033 {
15034 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
15035 (unsigned long) rp->r_offset,
dda8d76d 15036 printable_section_name (filedata, section));
700dd8b7
L
15037 continue;
15038 }
103f02d3 15039
ba5cdace
NC
15040 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
15041 if (sym_index >= num_syms)
15042 {
15043 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 15044 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15045 continue;
15046 }
15047 sym = symtab + sym_index;
41e92641
NC
15048
15049 /* If the reloc has a symbol associated with it,
55f25fc3
L
15050 make sure that it is of an appropriate type.
15051
15052 Relocations against symbols without type can happen.
15053 Gcc -feliminate-dwarf2-dups may generate symbols
15054 without type for debug info.
15055
15056 Icc generates relocations against function symbols
15057 instead of local labels.
15058
15059 Relocations against object symbols can happen, eg when
15060 referencing a global array. For an example of this see
15061 the _clz.o binary in libgcc.a. */
aca88567 15062 if (sym != symtab
b8871f35 15063 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15064 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15065 {
d3a49aa8 15066 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15067 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15068 printable_section_name (filedata, relsec),
d3a49aa8 15069 (long int)(rp - relocs));
aca88567 15070 continue;
5b18a4bc 15071 }
252b5132 15072
4dc3c23d
AM
15073 addend = 0;
15074 if (is_rela)
15075 addend += rp->r_addend;
c47320c3
AM
15076 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15077 partial_inplace. */
4dc3c23d 15078 if (!is_rela
dda8d76d 15079 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15080 && reloc_type == 1)
dda8d76d
NC
15081 || ((filedata->file_header.e_machine == EM_PJ
15082 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15083 && reloc_type == 1)
dda8d76d
NC
15084 || ((filedata->file_header.e_machine == EM_D30V
15085 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15086 && reloc_type == 12)
15087 || reloc_inplace)
39e07931
AS
15088 {
15089 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15090 addend += byte_get (rloc, reloc_size) & 0x3f;
15091 else
15092 addend += byte_get (rloc, reloc_size);
15093 }
cb8f3167 15094
dda8d76d
NC
15095 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15096 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15097 {
15098 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15099 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15100 addend -= 8;
91d6fa6a 15101 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15102 reloc_size);
15103 }
39e07931
AS
15104 else if (is_6bit_abs_reloc (filedata, reloc_type)
15105 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15106 {
15107 if (reloc_subtract)
15108 addend -= sym->st_value;
15109 else
15110 addend += sym->st_value;
15111 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15112 byte_put (rloc, addend, reloc_size);
15113 }
03336641
JW
15114 else if (reloc_subtract)
15115 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15116 else
91d6fa6a 15117 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15118 }
252b5132 15119
5b18a4bc 15120 free (symtab);
f84ce13b
NC
15121 /* Let the target specific reloc processing code know that
15122 we have finished with these relocs. */
dda8d76d 15123 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15124
15125 if (relocs_return)
15126 {
15127 * (Elf_Internal_Rela **) relocs_return = relocs;
15128 * num_relocs_return = num_relocs;
15129 }
15130 else
15131 free (relocs);
15132
5b18a4bc
NC
15133 break;
15134 }
32ec8896 15135
015dc7e1 15136 return true;
5b18a4bc 15137}
103f02d3 15138
cf13d699 15139#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15140static bool
dda8d76d 15141disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15142{
dda8d76d 15143 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15144
74e1a04b 15145 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15146
015dc7e1 15147 return true;
cf13d699
NC
15148}
15149#endif
15150
15151/* Reads in the contents of SECTION from FILE, returning a pointer
15152 to a malloc'ed buffer or NULL if something went wrong. */
15153
15154static char *
dda8d76d 15155get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15156{
be7d229a 15157 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15158
15159 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15160 {
c6b78c96 15161 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15162 printable_section_name (filedata, section));
cf13d699
NC
15163 return NULL;
15164 }
15165
dda8d76d 15166 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15167 _("section contents"));
cf13d699
NC
15168}
15169
0e602686
NC
15170/* Uncompresses a section that was compressed using zlib, in place. */
15171
015dc7e1 15172static bool
31e5a3a3
AM
15173uncompress_section_contents (unsigned char **buffer,
15174 uint64_t uncompressed_size,
15175 uint64_t *size)
0e602686 15176{
31e5a3a3
AM
15177 uint64_t compressed_size = *size;
15178 unsigned char *compressed_buffer = *buffer;
15179 unsigned char *uncompressed_buffer;
0e602686
NC
15180 z_stream strm;
15181 int rc;
15182
15183 /* It is possible the section consists of several compressed
15184 buffers concatenated together, so we uncompress in a loop. */
15185 /* PR 18313: The state field in the z_stream structure is supposed
15186 to be invisible to the user (ie us), but some compilers will
15187 still complain about it being used without initialisation. So
15188 we first zero the entire z_stream structure and then set the fields
15189 that we need. */
15190 memset (& strm, 0, sizeof strm);
15191 strm.avail_in = compressed_size;
15192 strm.next_in = (Bytef *) compressed_buffer;
15193 strm.avail_out = uncompressed_size;
15194 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15195
15196 rc = inflateInit (& strm);
15197 while (strm.avail_in > 0)
15198 {
15199 if (rc != Z_OK)
3624a6c1 15200 break;
0e602686
NC
15201 strm.next_out = ((Bytef *) uncompressed_buffer
15202 + (uncompressed_size - strm.avail_out));
15203 rc = inflate (&strm, Z_FINISH);
15204 if (rc != Z_STREAM_END)
3624a6c1 15205 break;
0e602686
NC
15206 rc = inflateReset (& strm);
15207 }
ad92f33d
AM
15208 if (inflateEnd (& strm) != Z_OK
15209 || rc != Z_OK
0e602686
NC
15210 || strm.avail_out != 0)
15211 goto fail;
15212
15213 *buffer = uncompressed_buffer;
15214 *size = uncompressed_size;
015dc7e1 15215 return true;
0e602686
NC
15216
15217 fail:
15218 free (uncompressed_buffer);
15219 /* Indicate decompression failure. */
15220 *buffer = NULL;
015dc7e1 15221 return false;
0e602686 15222}
dd24e3da 15223
015dc7e1 15224static bool
dda8d76d 15225dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15226{
015dc7e1 15227 Elf_Internal_Shdr *relsec;
be7d229a 15228 uint64_t num_bytes;
015dc7e1
AM
15229 unsigned char *data;
15230 unsigned char *end;
15231 unsigned char *real_start;
15232 unsigned char *start;
15233 bool some_strings_shown;
cf13d699 15234
dda8d76d 15235 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15236 if (start == NULL)
c6b78c96 15237 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15238 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15239
0e602686 15240 num_bytes = section->sh_size;
cf13d699 15241
835f2fae
NC
15242 if (filedata->is_separate)
15243 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15244 printable_section_name (filedata, section),
15245 filedata->file_name);
15246 else
15247 printf (_("\nString dump of section '%s':\n"),
15248 printable_section_name (filedata, section));
cf13d699 15249
0e602686
NC
15250 if (decompress_dumps)
15251 {
31e5a3a3
AM
15252 uint64_t new_size = num_bytes;
15253 uint64_t uncompressed_size = 0;
0e602686
NC
15254
15255 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15256 {
15257 Elf_Internal_Chdr chdr;
15258 unsigned int compression_header_size
ebdf1ebf
NC
15259 = get_compression_header (& chdr, (unsigned char *) start,
15260 num_bytes);
5844b465
NC
15261 if (compression_header_size == 0)
15262 /* An error message will have already been generated
15263 by get_compression_header. */
15264 goto error_out;
0e602686 15265
813dabb9 15266 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15267 {
813dabb9 15268 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15269 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15270 goto error_out;
813dabb9 15271 }
813dabb9
L
15272 uncompressed_size = chdr.ch_size;
15273 start += compression_header_size;
15274 new_size -= compression_header_size;
0e602686
NC
15275 }
15276 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15277 {
15278 /* Read the zlib header. In this case, it should be "ZLIB"
15279 followed by the uncompressed section size, 8 bytes in
15280 big-endian order. */
15281 uncompressed_size = start[4]; uncompressed_size <<= 8;
15282 uncompressed_size += start[5]; uncompressed_size <<= 8;
15283 uncompressed_size += start[6]; uncompressed_size <<= 8;
15284 uncompressed_size += start[7]; uncompressed_size <<= 8;
15285 uncompressed_size += start[8]; uncompressed_size <<= 8;
15286 uncompressed_size += start[9]; uncompressed_size <<= 8;
15287 uncompressed_size += start[10]; uncompressed_size <<= 8;
15288 uncompressed_size += start[11];
15289 start += 12;
15290 new_size -= 12;
15291 }
15292
1835f746
NC
15293 if (uncompressed_size)
15294 {
15295 if (uncompress_section_contents (& start,
15296 uncompressed_size, & new_size))
15297 num_bytes = new_size;
15298 else
15299 {
15300 error (_("Unable to decompress section %s\n"),
dda8d76d 15301 printable_section_name (filedata, section));
f761cb13 15302 goto error_out;
1835f746
NC
15303 }
15304 }
bc303e5d
NC
15305 else
15306 start = real_start;
0e602686 15307 }
fd8008d8 15308
cf13d699
NC
15309 /* If the section being dumped has relocations against it the user might
15310 be expecting these relocations to have been applied. Check for this
15311 case and issue a warning message in order to avoid confusion.
15312 FIXME: Maybe we ought to have an option that dumps a section with
15313 relocs applied ? */
dda8d76d
NC
15314 for (relsec = filedata->section_headers;
15315 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15316 ++relsec)
15317 {
15318 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15319 || relsec->sh_info >= filedata->file_header.e_shnum
15320 || filedata->section_headers + relsec->sh_info != section
cf13d699 15321 || relsec->sh_size == 0
dda8d76d 15322 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15323 continue;
15324
15325 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15326 break;
15327 }
15328
cf13d699
NC
15329 data = start;
15330 end = start + num_bytes;
015dc7e1 15331 some_strings_shown = false;
cf13d699 15332
ba3265d0
NC
15333#ifdef HAVE_MBSTATE_T
15334 mbstate_t state;
15335 /* Initialise the multibyte conversion state. */
15336 memset (& state, 0, sizeof (state));
15337#endif
15338
015dc7e1 15339 bool continuing = false;
ba3265d0 15340
cf13d699
NC
15341 while (data < end)
15342 {
15343 while (!ISPRINT (* data))
15344 if (++ data >= end)
15345 break;
15346
15347 if (data < end)
15348 {
071436c6
NC
15349 size_t maxlen = end - data;
15350
ba3265d0
NC
15351 if (continuing)
15352 {
15353 printf (" ");
015dc7e1 15354 continuing = false;
ba3265d0
NC
15355 }
15356 else
15357 {
d1ce973e 15358 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15359 }
15360
4082ef84
NC
15361 if (maxlen > 0)
15362 {
f3da8a96 15363 char c = 0;
ba3265d0
NC
15364
15365 while (maxlen)
15366 {
15367 c = *data++;
15368
15369 if (c == 0)
15370 break;
15371
15372 /* PR 25543: Treat new-lines as string-ending characters. */
15373 if (c == '\n')
15374 {
15375 printf ("\\n\n");
15376 if (*data != 0)
015dc7e1 15377 continuing = true;
ba3265d0
NC
15378 break;
15379 }
15380
15381 /* Do not print control characters directly as they can affect terminal
15382 settings. Such characters usually appear in the names generated
15383 by the assembler for local labels. */
15384 if (ISCNTRL (c))
15385 {
15386 printf ("^%c", c + 0x40);
15387 }
15388 else if (ISPRINT (c))
15389 {
15390 putchar (c);
15391 }
15392 else
15393 {
15394 size_t n;
15395#ifdef HAVE_MBSTATE_T
15396 wchar_t w;
15397#endif
15398 /* Let printf do the hard work of displaying multibyte characters. */
15399 printf ("%.1s", data - 1);
15400#ifdef HAVE_MBSTATE_T
15401 /* Try to find out how many bytes made up the character that was
15402 just printed. Advance the symbol pointer past the bytes that
15403 were displayed. */
15404 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15405#else
15406 n = 1;
15407#endif
15408 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15409 data += (n - 1);
15410 }
15411 }
15412
15413 if (c != '\n')
15414 putchar ('\n');
4082ef84
NC
15415 }
15416 else
15417 {
15418 printf (_("<corrupt>\n"));
15419 data = end;
15420 }
015dc7e1 15421 some_strings_shown = true;
cf13d699
NC
15422 }
15423 }
15424
15425 if (! some_strings_shown)
15426 printf (_(" No strings found in this section."));
15427
0e602686 15428 free (real_start);
cf13d699
NC
15429
15430 putchar ('\n');
015dc7e1 15431 return true;
f761cb13
AM
15432
15433error_out:
15434 free (real_start);
015dc7e1 15435 return false;
cf13d699
NC
15436}
15437
015dc7e1
AM
15438static bool
15439dump_section_as_bytes (Elf_Internal_Shdr *section,
15440 Filedata *filedata,
15441 bool relocate)
cf13d699 15442{
be7d229a
AM
15443 Elf_Internal_Shdr *relsec;
15444 size_t bytes;
15445 uint64_t section_size;
625d49fc 15446 uint64_t addr;
be7d229a
AM
15447 unsigned char *data;
15448 unsigned char *real_start;
15449 unsigned char *start;
0e602686 15450
dda8d76d 15451 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15452 if (start == NULL)
c6b78c96 15453 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15454 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15455
0e602686 15456 section_size = section->sh_size;
cf13d699 15457
835f2fae
NC
15458 if (filedata->is_separate)
15459 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15460 printable_section_name (filedata, section),
15461 filedata->file_name);
15462 else
15463 printf (_("\nHex dump of section '%s':\n"),
15464 printable_section_name (filedata, section));
cf13d699 15465
0e602686
NC
15466 if (decompress_dumps)
15467 {
31e5a3a3
AM
15468 uint64_t new_size = section_size;
15469 uint64_t uncompressed_size = 0;
0e602686
NC
15470
15471 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15472 {
15473 Elf_Internal_Chdr chdr;
15474 unsigned int compression_header_size
ebdf1ebf 15475 = get_compression_header (& chdr, start, section_size);
0e602686 15476
5844b465
NC
15477 if (compression_header_size == 0)
15478 /* An error message will have already been generated
15479 by get_compression_header. */
15480 goto error_out;
15481
813dabb9 15482 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15483 {
813dabb9 15484 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15485 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15486 goto error_out;
0e602686 15487 }
813dabb9
L
15488 uncompressed_size = chdr.ch_size;
15489 start += compression_header_size;
15490 new_size -= compression_header_size;
0e602686
NC
15491 }
15492 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15493 {
15494 /* Read the zlib header. In this case, it should be "ZLIB"
15495 followed by the uncompressed section size, 8 bytes in
15496 big-endian order. */
15497 uncompressed_size = start[4]; uncompressed_size <<= 8;
15498 uncompressed_size += start[5]; uncompressed_size <<= 8;
15499 uncompressed_size += start[6]; uncompressed_size <<= 8;
15500 uncompressed_size += start[7]; uncompressed_size <<= 8;
15501 uncompressed_size += start[8]; uncompressed_size <<= 8;
15502 uncompressed_size += start[9]; uncompressed_size <<= 8;
15503 uncompressed_size += start[10]; uncompressed_size <<= 8;
15504 uncompressed_size += start[11];
15505 start += 12;
15506 new_size -= 12;
15507 }
15508
f055032e
NC
15509 if (uncompressed_size)
15510 {
15511 if (uncompress_section_contents (& start, uncompressed_size,
15512 & new_size))
bc303e5d
NC
15513 {
15514 section_size = new_size;
15515 }
f055032e
NC
15516 else
15517 {
15518 error (_("Unable to decompress section %s\n"),
dda8d76d 15519 printable_section_name (filedata, section));
bc303e5d 15520 /* FIXME: Print the section anyway ? */
f761cb13 15521 goto error_out;
f055032e
NC
15522 }
15523 }
bc303e5d
NC
15524 else
15525 start = real_start;
0e602686 15526 }
14ae95f2 15527
cf13d699
NC
15528 if (relocate)
15529 {
dda8d76d 15530 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15531 goto error_out;
cf13d699
NC
15532 }
15533 else
15534 {
15535 /* If the section being dumped has relocations against it the user might
15536 be expecting these relocations to have been applied. Check for this
15537 case and issue a warning message in order to avoid confusion.
15538 FIXME: Maybe we ought to have an option that dumps a section with
15539 relocs applied ? */
dda8d76d
NC
15540 for (relsec = filedata->section_headers;
15541 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15542 ++relsec)
15543 {
15544 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15545 || relsec->sh_info >= filedata->file_header.e_shnum
15546 || filedata->section_headers + relsec->sh_info != section
cf13d699 15547 || relsec->sh_size == 0
dda8d76d 15548 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15549 continue;
15550
15551 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15552 break;
15553 }
15554 }
15555
15556 addr = section->sh_addr;
0e602686 15557 bytes = section_size;
cf13d699
NC
15558 data = start;
15559
15560 while (bytes)
15561 {
15562 int j;
15563 int k;
15564 int lbytes;
15565
15566 lbytes = (bytes > 16 ? 16 : bytes);
15567
15568 printf (" 0x%8.8lx ", (unsigned long) addr);
15569
15570 for (j = 0; j < 16; j++)
15571 {
15572 if (j < lbytes)
15573 printf ("%2.2x", data[j]);
15574 else
15575 printf (" ");
15576
15577 if ((j & 3) == 3)
15578 printf (" ");
15579 }
15580
15581 for (j = 0; j < lbytes; j++)
15582 {
15583 k = data[j];
15584 if (k >= ' ' && k < 0x7f)
15585 printf ("%c", k);
15586 else
15587 printf (".");
15588 }
15589
15590 putchar ('\n');
15591
15592 data += lbytes;
15593 addr += lbytes;
15594 bytes -= lbytes;
15595 }
15596
0e602686 15597 free (real_start);
cf13d699
NC
15598
15599 putchar ('\n');
015dc7e1 15600 return true;
f761cb13
AM
15601
15602 error_out:
15603 free (real_start);
015dc7e1 15604 return false;
cf13d699
NC
15605}
15606
094e34f2 15607#ifdef ENABLE_LIBCTF
7d9813f1
NA
15608static ctf_sect_t *
15609shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15610{
84714f86 15611 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15612 buf->cts_size = shdr->sh_size;
15613 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15614
15615 return buf;
15616}
15617
15618/* Formatting callback function passed to ctf_dump. Returns either the pointer
15619 it is passed, or a pointer to newly-allocated storage, in which case
15620 dump_ctf() will free it when it no longer needs it. */
15621
2f6ecaed
NA
15622static char *
15623dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15624 char *s, void *arg)
7d9813f1 15625{
3e50a591 15626 const char *blanks = arg;
7d9813f1
NA
15627 char *new_s;
15628
3e50a591 15629 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15630 return s;
15631 return new_s;
15632}
15633
926c9e76
NA
15634/* Dump CTF errors/warnings. */
15635static void
139633c3 15636dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15637{
15638 ctf_next_t *it = NULL;
15639 char *errtext;
15640 int is_warning;
15641 int err;
15642
15643 /* Dump accumulated errors and warnings. */
15644 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15645 {
5e9b84f7 15646 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15647 errtext);
15648 free (errtext);
15649 }
15650 if (err != ECTF_NEXT_END)
15651 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15652}
15653
2f6ecaed
NA
15654/* Dump one CTF archive member. */
15655
80b56fad
NA
15656static void
15657dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15658 size_t member)
2f6ecaed 15659{
2f6ecaed
NA
15660 const char *things[] = {"Header", "Labels", "Data objects",
15661 "Function objects", "Variables", "Types", "Strings",
15662 ""};
15663 const char **thing;
15664 size_t i;
15665
80b56fad
NA
15666 /* Don't print out the name of the default-named archive member if it appears
15667 first in the list. The name .ctf appears everywhere, even for things that
15668 aren't really archives, so printing it out is liable to be confusing; also,
15669 the common case by far is for only one archive member to exist, and hiding
15670 it in that case seems worthwhile. */
2f6ecaed 15671
80b56fad
NA
15672 if (strcmp (name, ".ctf") != 0 || member != 0)
15673 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15674
80b56fad
NA
15675 if (ctf_parent_name (ctf) != NULL)
15676 ctf_import (ctf, parent);
2f6ecaed
NA
15677
15678 for (i = 0, thing = things; *thing[0]; thing++, i++)
15679 {
15680 ctf_dump_state_t *s = NULL;
15681 char *item;
15682
15683 printf ("\n %s:\n", *thing);
15684 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15685 (void *) " ")) != NULL)
15686 {
15687 printf ("%s\n", item);
15688 free (item);
15689 }
15690
15691 if (ctf_errno (ctf))
15692 {
15693 error (_("Iteration failed: %s, %s\n"), *thing,
15694 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15695 break;
2f6ecaed
NA
15696 }
15697 }
8b37e7b6 15698
926c9e76 15699 dump_ctf_errs (ctf);
2f6ecaed
NA
15700}
15701
015dc7e1 15702static bool
7d9813f1
NA
15703dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15704{
7d9813f1
NA
15705 Elf_Internal_Shdr * symtab_sec = NULL;
15706 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15707 void * data = NULL;
15708 void * symdata = NULL;
15709 void * strdata = NULL;
80b56fad 15710 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15711 ctf_sect_t * symsectp = NULL;
15712 ctf_sect_t * strsectp = NULL;
2f6ecaed 15713 ctf_archive_t * ctfa = NULL;
139633c3 15714 ctf_dict_t * parent = NULL;
80b56fad 15715 ctf_dict_t * fp;
7d9813f1 15716
80b56fad
NA
15717 ctf_next_t *i = NULL;
15718 const char *name;
15719 size_t member = 0;
7d9813f1 15720 int err;
015dc7e1 15721 bool ret = false;
7d9813f1
NA
15722
15723 shdr_to_ctf_sect (&ctfsect, section, filedata);
15724 data = get_section_contents (section, filedata);
15725 ctfsect.cts_data = data;
15726
616febde 15727 if (!dump_ctf_symtab_name)
3d16b64e 15728 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15729
15730 if (!dump_ctf_strtab_name)
3d16b64e 15731 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15732
15733 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15734 {
15735 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15736 {
15737 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15738 goto fail;
15739 }
15740 if ((symdata = (void *) get_data (NULL, filedata,
15741 symtab_sec->sh_offset, 1,
15742 symtab_sec->sh_size,
15743 _("symbols"))) == NULL)
15744 goto fail;
15745 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15746 symsect.cts_data = symdata;
15747 }
835f2fae 15748
df16e041 15749 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15750 {
15751 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15752 {
15753 error (_("No string table section named %s\n"),
15754 dump_ctf_strtab_name);
15755 goto fail;
15756 }
15757 if ((strdata = (void *) get_data (NULL, filedata,
15758 strtab_sec->sh_offset, 1,
15759 strtab_sec->sh_size,
15760 _("strings"))) == NULL)
15761 goto fail;
15762 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15763 strsect.cts_data = strdata;
15764 }
835f2fae 15765
2f6ecaed
NA
15766 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15767 libctf papers over the difference, so we can pretend it is always an
80b56fad 15768 archive. */
7d9813f1 15769
2f6ecaed 15770 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15771 {
926c9e76 15772 dump_ctf_errs (NULL);
7d9813f1
NA
15773 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15774 goto fail;
15775 }
15776
96c61be5
NA
15777 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15778 != ELFDATA2MSB);
15779
80b56fad
NA
15780 /* Preload the parent dict, since it will need to be imported into every
15781 child in turn. */
15782 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15783 {
926c9e76 15784 dump_ctf_errs (NULL);
2f6ecaed
NA
15785 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15786 goto fail;
7d9813f1
NA
15787 }
15788
015dc7e1 15789 ret = true;
7d9813f1 15790
835f2fae
NC
15791 if (filedata->is_separate)
15792 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15793 printable_section_name (filedata, section),
15794 filedata->file_name);
15795 else
15796 printf (_("\nDump of CTF section '%s':\n"),
15797 printable_section_name (filedata, section));
7d9813f1 15798
80b56fad
NA
15799 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15800 dump_ctf_archive_member (fp, name, parent, member++);
15801 if (err != ECTF_NEXT_END)
15802 {
15803 dump_ctf_errs (NULL);
15804 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15805 ret = false;
15806 }
7d9813f1
NA
15807
15808 fail:
139633c3 15809 ctf_dict_close (parent);
2f6ecaed 15810 ctf_close (ctfa);
7d9813f1
NA
15811 free (data);
15812 free (symdata);
15813 free (strdata);
15814 return ret;
15815}
094e34f2 15816#endif
7d9813f1 15817
015dc7e1 15818static bool
dda8d76d
NC
15819load_specific_debug_section (enum dwarf_section_display_enum debug,
15820 const Elf_Internal_Shdr * sec,
15821 void * data)
1007acb3 15822{
2cf0635d 15823 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15824 char buf [64];
dda8d76d 15825 Filedata * filedata = (Filedata *) data;
9abca702 15826
19e6b90e 15827 if (section->start != NULL)
dda8d76d
NC
15828 {
15829 /* If it is already loaded, do nothing. */
15830 if (streq (section->filename, filedata->file_name))
015dc7e1 15831 return true;
dda8d76d
NC
15832 free (section->start);
15833 }
1007acb3 15834
19e6b90e
L
15835 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15836 section->address = sec->sh_addr;
dda8d76d
NC
15837 section->filename = filedata->file_name;
15838 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15839 sec->sh_offset, 1,
15840 sec->sh_size, buf);
59245841
NC
15841 if (section->start == NULL)
15842 section->size = 0;
15843 else
15844 {
77115a4a 15845 unsigned char *start = section->start;
31e5a3a3
AM
15846 uint64_t size = sec->sh_size;
15847 uint64_t uncompressed_size = 0;
77115a4a
L
15848
15849 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15850 {
15851 Elf_Internal_Chdr chdr;
d8024a91
NC
15852 unsigned int compression_header_size;
15853
f53be977
L
15854 if (size < (is_32bit_elf
15855 ? sizeof (Elf32_External_Chdr)
15856 : sizeof (Elf64_External_Chdr)))
d8024a91 15857 {
55be8fd0 15858 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15859 section->name);
015dc7e1 15860 return false;
d8024a91
NC
15861 }
15862
ebdf1ebf 15863 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15864 if (compression_header_size == 0)
15865 /* An error message will have already been generated
15866 by get_compression_header. */
015dc7e1 15867 return false;
d8024a91 15868
813dabb9
L
15869 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15870 {
15871 warn (_("section '%s' has unsupported compress type: %d\n"),
15872 section->name, chdr.ch_type);
015dc7e1 15873 return false;
813dabb9 15874 }
dab394de 15875 uncompressed_size = chdr.ch_size;
77115a4a
L
15876 start += compression_header_size;
15877 size -= compression_header_size;
15878 }
dab394de
L
15879 else if (size > 12 && streq ((char *) start, "ZLIB"))
15880 {
15881 /* Read the zlib header. In this case, it should be "ZLIB"
15882 followed by the uncompressed section size, 8 bytes in
15883 big-endian order. */
15884 uncompressed_size = start[4]; uncompressed_size <<= 8;
15885 uncompressed_size += start[5]; uncompressed_size <<= 8;
15886 uncompressed_size += start[6]; uncompressed_size <<= 8;
15887 uncompressed_size += start[7]; uncompressed_size <<= 8;
15888 uncompressed_size += start[8]; uncompressed_size <<= 8;
15889 uncompressed_size += start[9]; uncompressed_size <<= 8;
15890 uncompressed_size += start[10]; uncompressed_size <<= 8;
15891 uncompressed_size += start[11];
15892 start += 12;
15893 size -= 12;
15894 }
15895
1835f746 15896 if (uncompressed_size)
77115a4a 15897 {
1835f746
NC
15898 if (uncompress_section_contents (&start, uncompressed_size,
15899 &size))
15900 {
15901 /* Free the compressed buffer, update the section buffer
15902 and the section size if uncompress is successful. */
15903 free (section->start);
15904 section->start = start;
15905 }
15906 else
15907 {
15908 error (_("Unable to decompress section %s\n"),
dda8d76d 15909 printable_section_name (filedata, sec));
015dc7e1 15910 return false;
1835f746 15911 }
77115a4a 15912 }
bc303e5d 15913
77115a4a 15914 section->size = size;
59245841 15915 }
4a114e3e 15916
1b315056 15917 if (section->start == NULL)
015dc7e1 15918 return false;
1b315056 15919
19e6b90e 15920 if (debug_displays [debug].relocate)
32ec8896 15921 {
dda8d76d 15922 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15923 & section->reloc_info, & section->num_relocs))
015dc7e1 15924 return false;
32ec8896 15925 }
d1c4b12b
NC
15926 else
15927 {
15928 section->reloc_info = NULL;
15929 section->num_relocs = 0;
15930 }
1007acb3 15931
015dc7e1 15932 return true;
1007acb3
L
15933}
15934
301a9420
AM
15935#if HAVE_LIBDEBUGINFOD
15936/* Return a hex string representation of the build-id. */
15937unsigned char *
15938get_build_id (void * data)
15939{
ca0e11aa 15940 Filedata * filedata = (Filedata *) data;
301a9420
AM
15941 Elf_Internal_Shdr * shdr;
15942 unsigned long i;
15943
55be8fd0
NC
15944 /* Iterate through notes to find note.gnu.build-id.
15945 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15946 for (i = 0, shdr = filedata->section_headers;
15947 i < filedata->file_header.e_shnum && shdr != NULL;
15948 i++, shdr++)
15949 {
15950 if (shdr->sh_type != SHT_NOTE)
15951 continue;
15952
15953 char * next;
15954 char * end;
15955 size_t data_remaining;
15956 size_t min_notesz;
15957 Elf_External_Note * enote;
15958 Elf_Internal_Note inote;
15959
625d49fc
AM
15960 uint64_t offset = shdr->sh_offset;
15961 uint64_t align = shdr->sh_addralign;
15962 uint64_t length = shdr->sh_size;
301a9420
AM
15963
15964 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15965 if (enote == NULL)
15966 continue;
15967
15968 if (align < 4)
15969 align = 4;
15970 else if (align != 4 && align != 8)
f761cb13
AM
15971 {
15972 free (enote);
15973 continue;
15974 }
301a9420
AM
15975
15976 end = (char *) enote + length;
15977 data_remaining = end - (char *) enote;
15978
15979 if (!is_ia64_vms (filedata))
15980 {
15981 min_notesz = offsetof (Elf_External_Note, name);
15982 if (data_remaining < min_notesz)
15983 {
55be8fd0
NC
15984 warn (_("\
15985malformed note encountered in section %s whilst scanning for build-id note\n"),
15986 printable_section_name (filedata, shdr));
f761cb13 15987 free (enote);
55be8fd0 15988 continue;
301a9420
AM
15989 }
15990 data_remaining -= min_notesz;
15991
15992 inote.type = BYTE_GET (enote->type);
15993 inote.namesz = BYTE_GET (enote->namesz);
15994 inote.namedata = enote->name;
15995 inote.descsz = BYTE_GET (enote->descsz);
15996 inote.descdata = ((char *) enote
15997 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15998 inote.descpos = offset + (inote.descdata - (char *) enote);
15999 next = ((char *) enote
16000 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16001 }
16002 else
16003 {
16004 Elf64_External_VMS_Note *vms_enote;
16005
16006 /* PR binutils/15191
16007 Make sure that there is enough data to read. */
16008 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16009 if (data_remaining < min_notesz)
16010 {
55be8fd0
NC
16011 warn (_("\
16012malformed note encountered in section %s whilst scanning for build-id note\n"),
16013 printable_section_name (filedata, shdr));
f761cb13 16014 free (enote);
55be8fd0 16015 continue;
301a9420
AM
16016 }
16017 data_remaining -= min_notesz;
16018
16019 vms_enote = (Elf64_External_VMS_Note *) enote;
16020 inote.type = BYTE_GET (vms_enote->type);
16021 inote.namesz = BYTE_GET (vms_enote->namesz);
16022 inote.namedata = vms_enote->name;
16023 inote.descsz = BYTE_GET (vms_enote->descsz);
16024 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16025 inote.descpos = offset + (inote.descdata - (char *) enote);
16026 next = inote.descdata + align_power (inote.descsz, 3);
16027 }
16028
16029 /* Skip malformed notes. */
16030 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16031 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16032 || (size_t) (next - inote.descdata) < inote.descsz
16033 || ((size_t) (next - inote.descdata)
16034 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16035 {
55be8fd0
NC
16036 warn (_("\
16037malformed note encountered in section %s whilst scanning for build-id note\n"),
16038 printable_section_name (filedata, shdr));
f761cb13 16039 free (enote);
301a9420
AM
16040 continue;
16041 }
16042
16043 /* Check if this is the build-id note. If so then convert the build-id
16044 bytes to a hex string. */
16045 if (inote.namesz > 0
24d127aa 16046 && startswith (inote.namedata, "GNU")
301a9420
AM
16047 && inote.type == NT_GNU_BUILD_ID)
16048 {
16049 unsigned long j;
16050 char * build_id;
16051
16052 build_id = malloc (inote.descsz * 2 + 1);
16053 if (build_id == NULL)
f761cb13
AM
16054 {
16055 free (enote);
16056 return NULL;
16057 }
301a9420
AM
16058
16059 for (j = 0; j < inote.descsz; ++j)
16060 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16061 build_id[inote.descsz * 2] = '\0';
f761cb13 16062 free (enote);
301a9420 16063
55be8fd0 16064 return (unsigned char *) build_id;
301a9420 16065 }
f761cb13 16066 free (enote);
301a9420
AM
16067 }
16068
16069 return NULL;
16070}
16071#endif /* HAVE_LIBDEBUGINFOD */
16072
657d0d47
CC
16073/* If this is not NULL, load_debug_section will only look for sections
16074 within the list of sections given here. */
32ec8896 16075static unsigned int * section_subset = NULL;
657d0d47 16076
015dc7e1 16077bool
dda8d76d 16078load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16079{
2cf0635d
NC
16080 struct dwarf_section * section = &debug_displays [debug].section;
16081 Elf_Internal_Shdr * sec;
dda8d76d
NC
16082 Filedata * filedata = (Filedata *) data;
16083
e1dbfc17
L
16084 if (!dump_any_debugging)
16085 return false;
16086
f425ec66
NC
16087 /* Without section headers we cannot find any sections. */
16088 if (filedata->section_headers == NULL)
015dc7e1 16089 return false;
f425ec66 16090
9c1ce108
AM
16091 if (filedata->string_table == NULL
16092 && filedata->file_header.e_shstrndx != SHN_UNDEF
16093 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16094 {
16095 Elf_Internal_Shdr * strs;
16096
16097 /* Read in the string table, so that we have section names to scan. */
16098 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16099
4dff97b2 16100 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16101 {
9c1ce108
AM
16102 filedata->string_table
16103 = (char *) get_data (NULL, filedata, strs->sh_offset,
16104 1, strs->sh_size, _("string table"));
dda8d76d 16105
9c1ce108
AM
16106 filedata->string_table_length
16107 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16108 }
16109 }
d966045b
DJ
16110
16111 /* Locate the debug section. */
dda8d76d 16112 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16113 if (sec != NULL)
16114 section->name = section->uncompressed_name;
16115 else
16116 {
dda8d76d 16117 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16118 if (sec != NULL)
16119 section->name = section->compressed_name;
16120 }
16121 if (sec == NULL)
015dc7e1 16122 return false;
d966045b 16123
657d0d47
CC
16124 /* If we're loading from a subset of sections, and we've loaded
16125 a section matching this name before, it's likely that it's a
16126 different one. */
16127 if (section_subset != NULL)
16128 free_debug_section (debug);
16129
dda8d76d 16130 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16131}
16132
19e6b90e
L
16133void
16134free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16135{
2cf0635d 16136 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16137
19e6b90e
L
16138 if (section->start == NULL)
16139 return;
1007acb3 16140
19e6b90e
L
16141 free ((char *) section->start);
16142 section->start = NULL;
16143 section->address = 0;
16144 section->size = 0;
a788aedd 16145
9db70fc3
AM
16146 free (section->reloc_info);
16147 section->reloc_info = NULL;
16148 section->num_relocs = 0;
1007acb3
L
16149}
16150
015dc7e1 16151static bool
dda8d76d 16152display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16153{
84714f86
AM
16154 const char *name = (section_name_valid (filedata, section)
16155 ? section_name (filedata, section) : "");
16156 const char *print_name = printable_section_name (filedata, section);
be7d229a 16157 uint64_t length;
015dc7e1 16158 bool result = true;
3f5e193b 16159 int i;
1007acb3 16160
19e6b90e
L
16161 length = section->sh_size;
16162 if (length == 0)
1007acb3 16163 {
74e1a04b 16164 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16165 return true;
1007acb3 16166 }
5dff79d8
NC
16167 if (section->sh_type == SHT_NOBITS)
16168 {
16169 /* There is no point in dumping the contents of a debugging section
16170 which has the NOBITS type - the bits in the file will be random.
16171 This can happen when a file containing a .eh_frame section is
16172 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16173 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16174 print_name);
015dc7e1 16175 return false;
5dff79d8 16176 }
1007acb3 16177
24d127aa 16178 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16179 name = ".debug_info";
1007acb3 16180
19e6b90e
L
16181 /* See if we know how to display the contents of this section. */
16182 for (i = 0; i < max; i++)
d85bf2ba
NC
16183 {
16184 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16185 struct dwarf_section_display * display = debug_displays + i;
16186 struct dwarf_section * sec = & display->section;
d966045b 16187
d85bf2ba 16188 if (streq (sec->uncompressed_name, name)
24d127aa 16189 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16190 || streq (sec->compressed_name, name))
16191 {
015dc7e1 16192 bool secondary = (section != find_section (filedata, name));
1007acb3 16193
d85bf2ba
NC
16194 if (secondary)
16195 free_debug_section (id);
dda8d76d 16196
24d127aa 16197 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16198 sec->name = name;
16199 else if (streq (sec->uncompressed_name, name))
16200 sec->name = sec->uncompressed_name;
16201 else
16202 sec->name = sec->compressed_name;
657d0d47 16203
d85bf2ba
NC
16204 if (load_specific_debug_section (id, section, filedata))
16205 {
16206 /* If this debug section is part of a CU/TU set in a .dwp file,
16207 restrict load_debug_section to the sections in that set. */
16208 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16209
d85bf2ba 16210 result &= display->display (sec, filedata);
657d0d47 16211
d85bf2ba 16212 section_subset = NULL;
1007acb3 16213
44266f36 16214 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16215 free_debug_section (id);
16216 }
16217 break;
16218 }
16219 }
1007acb3 16220
19e6b90e 16221 if (i == max)
1007acb3 16222 {
74e1a04b 16223 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16224 result = false;
1007acb3
L
16225 }
16226
19e6b90e 16227 return result;
5b18a4bc 16228}
103f02d3 16229
aef1f6d0
DJ
16230/* Set DUMP_SECTS for all sections where dumps were requested
16231 based on section name. */
16232
16233static void
dda8d76d 16234initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16235{
2cf0635d 16236 struct dump_list_entry * cur;
aef1f6d0
DJ
16237
16238 for (cur = dump_sects_byname; cur; cur = cur->next)
16239 {
16240 unsigned int i;
015dc7e1 16241 bool any = false;
aef1f6d0 16242
dda8d76d 16243 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16244 if (section_name_valid (filedata, filedata->section_headers + i)
16245 && streq (section_name (filedata, filedata->section_headers + i),
16246 cur->name))
aef1f6d0 16247 {
6431e409 16248 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16249 any = true;
aef1f6d0
DJ
16250 }
16251
835f2fae
NC
16252 if (!any && !filedata->is_separate)
16253 warn (_("Section '%s' was not dumped because it does not exist\n"),
16254 cur->name);
aef1f6d0
DJ
16255 }
16256}
16257
015dc7e1 16258static bool
dda8d76d 16259process_section_contents (Filedata * filedata)
5b18a4bc 16260{
2cf0635d 16261 Elf_Internal_Shdr * section;
19e6b90e 16262 unsigned int i;
015dc7e1 16263 bool res = true;
103f02d3 16264
19e6b90e 16265 if (! do_dump)
015dc7e1 16266 return true;
103f02d3 16267
dda8d76d 16268 initialise_dumps_byname (filedata);
aef1f6d0 16269
dda8d76d 16270 for (i = 0, section = filedata->section_headers;
6431e409 16271 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16272 i++, section++)
16273 {
6431e409 16274 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16275
d6bfbc39
NC
16276 if (filedata->is_separate && ! process_links)
16277 dump &= DEBUG_DUMP;
047c3dbf 16278
19e6b90e 16279#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16280 if (dump & DISASS_DUMP)
16281 {
16282 if (! disassemble_section (section, filedata))
015dc7e1 16283 res = false;
dda8d76d 16284 }
19e6b90e 16285#endif
dda8d76d 16286 if (dump & HEX_DUMP)
32ec8896 16287 {
015dc7e1
AM
16288 if (! dump_section_as_bytes (section, filedata, false))
16289 res = false;
32ec8896 16290 }
103f02d3 16291
dda8d76d 16292 if (dump & RELOC_DUMP)
32ec8896 16293 {
015dc7e1
AM
16294 if (! dump_section_as_bytes (section, filedata, true))
16295 res = false;
32ec8896 16296 }
09c11c86 16297
dda8d76d 16298 if (dump & STRING_DUMP)
32ec8896 16299 {
dda8d76d 16300 if (! dump_section_as_strings (section, filedata))
015dc7e1 16301 res = false;
32ec8896 16302 }
cf13d699 16303
dda8d76d 16304 if (dump & DEBUG_DUMP)
32ec8896 16305 {
dda8d76d 16306 if (! display_debug_section (i, section, filedata))
015dc7e1 16307 res = false;
32ec8896 16308 }
7d9813f1 16309
094e34f2 16310#ifdef ENABLE_LIBCTF
7d9813f1
NA
16311 if (dump & CTF_DUMP)
16312 {
16313 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16314 res = false;
7d9813f1 16315 }
094e34f2 16316#endif
5b18a4bc 16317 }
103f02d3 16318
835f2fae 16319 if (! filedata->is_separate)
0ee3043f 16320 {
835f2fae
NC
16321 /* Check to see if the user requested a
16322 dump of a section that does not exist. */
16323 for (; i < filedata->dump.num_dump_sects; i++)
16324 if (filedata->dump.dump_sects[i])
16325 {
ca0e11aa 16326 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16327 res = false;
835f2fae 16328 }
0ee3043f 16329 }
32ec8896
NC
16330
16331 return res;
5b18a4bc 16332}
103f02d3 16333
5b18a4bc 16334static void
19e6b90e 16335process_mips_fpe_exception (int mask)
5b18a4bc 16336{
19e6b90e
L
16337 if (mask)
16338 {
015dc7e1 16339 bool first = true;
32ec8896 16340
19e6b90e 16341 if (mask & OEX_FPU_INEX)
015dc7e1 16342 fputs ("INEX", stdout), first = false;
19e6b90e 16343 if (mask & OEX_FPU_UFLO)
015dc7e1 16344 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16345 if (mask & OEX_FPU_OFLO)
015dc7e1 16346 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16347 if (mask & OEX_FPU_DIV0)
015dc7e1 16348 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16349 if (mask & OEX_FPU_INVAL)
16350 printf ("%sINVAL", first ? "" : "|");
16351 }
5b18a4bc 16352 else
19e6b90e 16353 fputs ("0", stdout);
5b18a4bc 16354}
103f02d3 16355
f6f0e17b
NC
16356/* Display's the value of TAG at location P. If TAG is
16357 greater than 0 it is assumed to be an unknown tag, and
16358 a message is printed to this effect. Otherwise it is
16359 assumed that a message has already been printed.
16360
16361 If the bottom bit of TAG is set it assumed to have a
16362 string value, otherwise it is assumed to have an integer
16363 value.
16364
16365 Returns an updated P pointing to the first unread byte
16366 beyond the end of TAG's value.
16367
16368 Reads at or beyond END will not be made. */
16369
16370static unsigned char *
60abdbed 16371display_tag_value (signed int tag,
f6f0e17b
NC
16372 unsigned char * p,
16373 const unsigned char * const end)
16374{
16375 unsigned long val;
16376
16377 if (tag > 0)
16378 printf (" Tag_unknown_%d: ", tag);
16379
16380 if (p >= end)
16381 {
4082ef84 16382 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16383 }
16384 else if (tag & 1)
16385 {
071436c6
NC
16386 /* PR 17531 file: 027-19978-0.004. */
16387 size_t maxlen = (end - p) - 1;
16388
16389 putchar ('"');
4082ef84
NC
16390 if (maxlen > 0)
16391 {
16392 print_symbol ((int) maxlen, (const char *) p);
16393 p += strnlen ((char *) p, maxlen) + 1;
16394 }
16395 else
16396 {
16397 printf (_("<corrupt string tag>"));
16398 p = (unsigned char *) end;
16399 }
071436c6 16400 printf ("\"\n");
f6f0e17b
NC
16401 }
16402 else
16403 {
cd30bcef 16404 READ_ULEB (val, p, end);
f6f0e17b
NC
16405 printf ("%ld (0x%lx)\n", val, val);
16406 }
16407
4082ef84 16408 assert (p <= end);
f6f0e17b
NC
16409 return p;
16410}
16411
53a346d8
CZ
16412/* ARC ABI attributes section. */
16413
16414static unsigned char *
16415display_arc_attribute (unsigned char * p,
16416 const unsigned char * const end)
16417{
16418 unsigned int tag;
53a346d8
CZ
16419 unsigned int val;
16420
cd30bcef 16421 READ_ULEB (tag, p, end);
53a346d8
CZ
16422
16423 switch (tag)
16424 {
16425 case Tag_ARC_PCS_config:
cd30bcef 16426 READ_ULEB (val, p, end);
53a346d8
CZ
16427 printf (" Tag_ARC_PCS_config: ");
16428 switch (val)
16429 {
16430 case 0:
16431 printf (_("Absent/Non standard\n"));
16432 break;
16433 case 1:
16434 printf (_("Bare metal/mwdt\n"));
16435 break;
16436 case 2:
16437 printf (_("Bare metal/newlib\n"));
16438 break;
16439 case 3:
16440 printf (_("Linux/uclibc\n"));
16441 break;
16442 case 4:
16443 printf (_("Linux/glibc\n"));
16444 break;
16445 default:
16446 printf (_("Unknown\n"));
16447 break;
16448 }
16449 break;
16450
16451 case Tag_ARC_CPU_base:
cd30bcef 16452 READ_ULEB (val, p, end);
53a346d8
CZ
16453 printf (" Tag_ARC_CPU_base: ");
16454 switch (val)
16455 {
16456 default:
16457 case TAG_CPU_NONE:
16458 printf (_("Absent\n"));
16459 break;
16460 case TAG_CPU_ARC6xx:
16461 printf ("ARC6xx\n");
16462 break;
16463 case TAG_CPU_ARC7xx:
16464 printf ("ARC7xx\n");
16465 break;
16466 case TAG_CPU_ARCEM:
16467 printf ("ARCEM\n");
16468 break;
16469 case TAG_CPU_ARCHS:
16470 printf ("ARCHS\n");
16471 break;
16472 }
16473 break;
16474
16475 case Tag_ARC_CPU_variation:
cd30bcef 16476 READ_ULEB (val, p, end);
53a346d8
CZ
16477 printf (" Tag_ARC_CPU_variation: ");
16478 switch (val)
16479 {
16480 default:
16481 if (val > 0 && val < 16)
53a346d8 16482 printf ("Core%d\n", val);
d8cbc93b
JL
16483 else
16484 printf ("Unknown\n");
16485 break;
16486
53a346d8
CZ
16487 case 0:
16488 printf (_("Absent\n"));
16489 break;
16490 }
16491 break;
16492
16493 case Tag_ARC_CPU_name:
16494 printf (" Tag_ARC_CPU_name: ");
16495 p = display_tag_value (-1, p, end);
16496 break;
16497
16498 case Tag_ARC_ABI_rf16:
cd30bcef 16499 READ_ULEB (val, p, end);
53a346d8
CZ
16500 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16501 break;
16502
16503 case Tag_ARC_ABI_osver:
cd30bcef 16504 READ_ULEB (val, p, end);
53a346d8
CZ
16505 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16506 break;
16507
16508 case Tag_ARC_ABI_pic:
16509 case Tag_ARC_ABI_sda:
cd30bcef 16510 READ_ULEB (val, p, end);
53a346d8
CZ
16511 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16512 : " Tag_ARC_ABI_pic: ");
16513 switch (val)
16514 {
16515 case 0:
16516 printf (_("Absent\n"));
16517 break;
16518 case 1:
16519 printf ("MWDT\n");
16520 break;
16521 case 2:
16522 printf ("GNU\n");
16523 break;
16524 default:
16525 printf (_("Unknown\n"));
16526 break;
16527 }
16528 break;
16529
16530 case Tag_ARC_ABI_tls:
cd30bcef 16531 READ_ULEB (val, p, end);
53a346d8
CZ
16532 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16533 break;
16534
16535 case Tag_ARC_ABI_enumsize:
cd30bcef 16536 READ_ULEB (val, p, end);
53a346d8
CZ
16537 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16538 _("smallest"));
16539 break;
16540
16541 case Tag_ARC_ABI_exceptions:
cd30bcef 16542 READ_ULEB (val, p, end);
53a346d8
CZ
16543 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16544 : _("default"));
16545 break;
16546
16547 case Tag_ARC_ABI_double_size:
cd30bcef 16548 READ_ULEB (val, p, end);
53a346d8
CZ
16549 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16550 break;
16551
16552 case Tag_ARC_ISA_config:
16553 printf (" Tag_ARC_ISA_config: ");
16554 p = display_tag_value (-1, p, end);
16555 break;
16556
16557 case Tag_ARC_ISA_apex:
16558 printf (" Tag_ARC_ISA_apex: ");
16559 p = display_tag_value (-1, p, end);
16560 break;
16561
16562 case Tag_ARC_ISA_mpy_option:
cd30bcef 16563 READ_ULEB (val, p, end);
53a346d8
CZ
16564 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16565 break;
16566
db1e1b45 16567 case Tag_ARC_ATR_version:
cd30bcef 16568 READ_ULEB (val, p, end);
db1e1b45 16569 printf (" Tag_ARC_ATR_version: %d\n", val);
16570 break;
16571
53a346d8
CZ
16572 default:
16573 return display_tag_value (tag & 1, p, end);
16574 }
16575
16576 return p;
16577}
16578
11c1ff18
PB
16579/* ARM EABI attributes section. */
16580typedef struct
16581{
70e99720 16582 unsigned int tag;
2cf0635d 16583 const char * name;
11c1ff18 16584 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16585 unsigned int type;
288f0ba2 16586 const char *const *table;
11c1ff18
PB
16587} arm_attr_public_tag;
16588
288f0ba2 16589static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16590 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16591 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16592 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16593 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16594static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16595static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16596 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16597static const char *const arm_attr_tag_FP_arch[] =
bca38921 16598 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16599 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16600static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16601static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16602 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16603 "NEON for ARMv8.1"};
288f0ba2 16604static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16605 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16606 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16607static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16608 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16609static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16610 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16611static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16612 {"Absolute", "PC-relative", "None"};
288f0ba2 16613static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16614 {"None", "direct", "GOT-indirect"};
288f0ba2 16615static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16616 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16617static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16618static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16619 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16620static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16621static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16622static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16623 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16624static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16625 {"Unused", "small", "int", "forced to int"};
288f0ba2 16626static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16627 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16628static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16629 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16630static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16631 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16632static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16633 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16634 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16635static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16636 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16637 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16638static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16639static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16640 {"Not Allowed", "Allowed"};
288f0ba2 16641static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16642 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16643static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16644 {"Follow architecture", "Allowed"};
288f0ba2 16645static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16646 {"Not Allowed", "Allowed"};
288f0ba2 16647static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16648 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16649 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16650static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16651static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16652 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16653 "TrustZone and Virtualization Extensions"};
288f0ba2 16654static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16655 {"Not Allowed", "Allowed"};
11c1ff18 16656
288f0ba2 16657static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16658 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16659
99db83d0
AC
16660static const char * arm_attr_tag_PAC_extension[] =
16661 {"No PAC/AUT instructions",
16662 "PAC/AUT instructions permitted in the NOP space",
16663 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16664
4b535030
AC
16665static const char * arm_attr_tag_BTI_extension[] =
16666 {"BTI instructions not permitted",
16667 "BTI instructions permitted in the NOP space",
16668 "BTI instructions permitted in the NOP and in the non-NOP space"};
16669
b81ee92f
AC
16670static const char * arm_attr_tag_BTI_use[] =
16671 {"Compiled without branch target enforcement",
16672 "Compiled with branch target enforcement"};
16673
c9fed665
AC
16674static const char * arm_attr_tag_PACRET_use[] =
16675 {"Compiled without return address signing and authentication",
16676 "Compiled with return address signing and authentication"};
16677
11c1ff18
PB
16678#define LOOKUP(id, name) \
16679 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16680static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16681{
16682 {4, "CPU_raw_name", 1, NULL},
16683 {5, "CPU_name", 1, NULL},
16684 LOOKUP(6, CPU_arch),
16685 {7, "CPU_arch_profile", 0, NULL},
16686 LOOKUP(8, ARM_ISA_use),
16687 LOOKUP(9, THUMB_ISA_use),
75375b3e 16688 LOOKUP(10, FP_arch),
11c1ff18 16689 LOOKUP(11, WMMX_arch),
f5f53991
AS
16690 LOOKUP(12, Advanced_SIMD_arch),
16691 LOOKUP(13, PCS_config),
11c1ff18
PB
16692 LOOKUP(14, ABI_PCS_R9_use),
16693 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16694 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16695 LOOKUP(17, ABI_PCS_GOT_use),
16696 LOOKUP(18, ABI_PCS_wchar_t),
16697 LOOKUP(19, ABI_FP_rounding),
16698 LOOKUP(20, ABI_FP_denormal),
16699 LOOKUP(21, ABI_FP_exceptions),
16700 LOOKUP(22, ABI_FP_user_exceptions),
16701 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16702 {24, "ABI_align_needed", 0, NULL},
16703 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16704 LOOKUP(26, ABI_enum_size),
16705 LOOKUP(27, ABI_HardFP_use),
16706 LOOKUP(28, ABI_VFP_args),
16707 LOOKUP(29, ABI_WMMX_args),
16708 LOOKUP(30, ABI_optimization_goals),
16709 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16710 {32, "compatibility", 0, NULL},
f5f53991 16711 LOOKUP(34, CPU_unaligned_access),
75375b3e 16712 LOOKUP(36, FP_HP_extension),
8e79c3df 16713 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16714 LOOKUP(42, MPextension_use),
16715 LOOKUP(44, DIV_use),
15afaa63 16716 LOOKUP(46, DSP_extension),
a7ad558c 16717 LOOKUP(48, MVE_arch),
99db83d0 16718 LOOKUP(50, PAC_extension),
4b535030 16719 LOOKUP(52, BTI_extension),
b81ee92f 16720 LOOKUP(74, BTI_use),
c9fed665 16721 LOOKUP(76, PACRET_use),
f5f53991
AS
16722 {64, "nodefaults", 0, NULL},
16723 {65, "also_compatible_with", 0, NULL},
16724 LOOKUP(66, T2EE_use),
16725 {67, "conformance", 1, NULL},
16726 LOOKUP(68, Virtualization_use),
cd21e546 16727 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16728};
16729#undef LOOKUP
16730
11c1ff18 16731static unsigned char *
f6f0e17b
NC
16732display_arm_attribute (unsigned char * p,
16733 const unsigned char * const end)
11c1ff18 16734{
70e99720 16735 unsigned int tag;
70e99720 16736 unsigned int val;
2cf0635d 16737 arm_attr_public_tag * attr;
11c1ff18 16738 unsigned i;
70e99720 16739 unsigned int type;
11c1ff18 16740
cd30bcef 16741 READ_ULEB (tag, p, end);
11c1ff18 16742 attr = NULL;
2cf0635d 16743 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16744 {
16745 if (arm_attr_public_tags[i].tag == tag)
16746 {
16747 attr = &arm_attr_public_tags[i];
16748 break;
16749 }
16750 }
16751
16752 if (attr)
16753 {
16754 printf (" Tag_%s: ", attr->name);
16755 switch (attr->type)
16756 {
16757 case 0:
16758 switch (tag)
16759 {
16760 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16761 READ_ULEB (val, p, end);
11c1ff18
PB
16762 switch (val)
16763 {
2b692964
NC
16764 case 0: printf (_("None\n")); break;
16765 case 'A': printf (_("Application\n")); break;
16766 case 'R': printf (_("Realtime\n")); break;
16767 case 'M': printf (_("Microcontroller\n")); break;
16768 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16769 default: printf ("??? (%d)\n", val); break;
16770 }
16771 break;
16772
75375b3e 16773 case 24: /* Tag_align_needed. */
cd30bcef 16774 READ_ULEB (val, p, end);
75375b3e
MGD
16775 switch (val)
16776 {
2b692964
NC
16777 case 0: printf (_("None\n")); break;
16778 case 1: printf (_("8-byte\n")); break;
16779 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16780 case 3: printf ("??? 3\n"); break;
16781 default:
16782 if (val <= 12)
dd24e3da 16783 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16784 1 << val);
16785 else
16786 printf ("??? (%d)\n", val);
16787 break;
16788 }
16789 break;
16790
16791 case 25: /* Tag_align_preserved. */
cd30bcef 16792 READ_ULEB (val, p, end);
75375b3e
MGD
16793 switch (val)
16794 {
2b692964
NC
16795 case 0: printf (_("None\n")); break;
16796 case 1: printf (_("8-byte, except leaf SP\n")); break;
16797 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16798 case 3: printf ("??? 3\n"); break;
16799 default:
16800 if (val <= 12)
dd24e3da 16801 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16802 1 << val);
16803 else
16804 printf ("??? (%d)\n", val);
16805 break;
16806 }
16807 break;
16808
11c1ff18 16809 case 32: /* Tag_compatibility. */
071436c6 16810 {
cd30bcef 16811 READ_ULEB (val, p, end);
071436c6 16812 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16813 if (p < end - 1)
16814 {
16815 size_t maxlen = (end - p) - 1;
16816
16817 print_symbol ((int) maxlen, (const char *) p);
16818 p += strnlen ((char *) p, maxlen) + 1;
16819 }
16820 else
16821 {
16822 printf (_("<corrupt>"));
16823 p = (unsigned char *) end;
16824 }
071436c6 16825 putchar ('\n');
071436c6 16826 }
11c1ff18
PB
16827 break;
16828
f5f53991 16829 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16830 /* PR 17531: file: 001-505008-0.01. */
16831 if (p < end)
16832 p++;
2b692964 16833 printf (_("True\n"));
f5f53991
AS
16834 break;
16835
16836 case 65: /* Tag_also_compatible_with. */
cd30bcef 16837 READ_ULEB (val, p, end);
f5f53991
AS
16838 if (val == 6 /* Tag_CPU_arch. */)
16839 {
cd30bcef 16840 READ_ULEB (val, p, end);
071436c6 16841 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16842 printf ("??? (%d)\n", val);
16843 else
16844 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16845 }
16846 else
16847 printf ("???\n");
071436c6
NC
16848 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16849 ;
f5f53991
AS
16850 break;
16851
11c1ff18 16852 default:
bee0ee85
NC
16853 printf (_("<unknown: %d>\n"), tag);
16854 break;
11c1ff18
PB
16855 }
16856 return p;
16857
16858 case 1:
f6f0e17b 16859 return display_tag_value (-1, p, end);
11c1ff18 16860 case 2:
f6f0e17b 16861 return display_tag_value (0, p, end);
11c1ff18
PB
16862
16863 default:
16864 assert (attr->type & 0x80);
cd30bcef 16865 READ_ULEB (val, p, end);
11c1ff18
PB
16866 type = attr->type & 0x7f;
16867 if (val >= type)
16868 printf ("??? (%d)\n", val);
16869 else
16870 printf ("%s\n", attr->table[val]);
16871 return p;
16872 }
16873 }
11c1ff18 16874
f6f0e17b 16875 return display_tag_value (tag, p, end);
11c1ff18
PB
16876}
16877
104d59d1 16878static unsigned char *
60bca95a 16879display_gnu_attribute (unsigned char * p,
60abdbed 16880 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16881 const unsigned char * const end)
104d59d1 16882{
cd30bcef 16883 unsigned int tag;
60abdbed 16884 unsigned int val;
104d59d1 16885
cd30bcef 16886 READ_ULEB (tag, p, end);
104d59d1
JM
16887
16888 /* Tag_compatibility is the only generic GNU attribute defined at
16889 present. */
16890 if (tag == 32)
16891 {
cd30bcef 16892 READ_ULEB (val, p, end);
071436c6
NC
16893
16894 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16895 if (p == end)
16896 {
071436c6 16897 printf (_("<corrupt>\n"));
f6f0e17b
NC
16898 warn (_("corrupt vendor attribute\n"));
16899 }
16900 else
16901 {
4082ef84
NC
16902 if (p < end - 1)
16903 {
16904 size_t maxlen = (end - p) - 1;
071436c6 16905
4082ef84
NC
16906 print_symbol ((int) maxlen, (const char *) p);
16907 p += strnlen ((char *) p, maxlen) + 1;
16908 }
16909 else
16910 {
16911 printf (_("<corrupt>"));
16912 p = (unsigned char *) end;
16913 }
071436c6 16914 putchar ('\n');
f6f0e17b 16915 }
104d59d1
JM
16916 return p;
16917 }
16918
16919 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16920 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16921
f6f0e17b 16922 return display_tag_value (tag, p, end);
104d59d1
JM
16923}
16924
85f7484a
PB
16925static unsigned char *
16926display_m68k_gnu_attribute (unsigned char * p,
16927 unsigned int tag,
16928 const unsigned char * const end)
16929{
16930 unsigned int val;
16931
16932 if (tag == Tag_GNU_M68K_ABI_FP)
16933 {
16934 printf (" Tag_GNU_M68K_ABI_FP: ");
16935 if (p == end)
16936 {
16937 printf (_("<corrupt>\n"));
16938 return p;
16939 }
16940 READ_ULEB (val, p, end);
16941
16942 if (val > 3)
16943 printf ("(%#x), ", val);
16944
16945 switch (val & 3)
16946 {
16947 case 0:
16948 printf (_("unspecified hard/soft float\n"));
16949 break;
16950 case 1:
16951 printf (_("hard float\n"));
16952 break;
16953 case 2:
16954 printf (_("soft float\n"));
16955 break;
16956 }
16957 return p;
16958 }
16959
16960 return display_tag_value (tag & 1, p, end);
16961}
16962
34c8bcba 16963static unsigned char *
f6f0e17b 16964display_power_gnu_attribute (unsigned char * p,
60abdbed 16965 unsigned int tag,
f6f0e17b 16966 const unsigned char * const end)
34c8bcba 16967{
005d79fd 16968 unsigned int val;
34c8bcba
JM
16969
16970 if (tag == Tag_GNU_Power_ABI_FP)
16971 {
34c8bcba 16972 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16973 if (p == end)
005d79fd
AM
16974 {
16975 printf (_("<corrupt>\n"));
16976 return p;
16977 }
cd30bcef 16978 READ_ULEB (val, p, end);
60bca95a 16979
005d79fd
AM
16980 if (val > 15)
16981 printf ("(%#x), ", val);
16982
16983 switch (val & 3)
34c8bcba
JM
16984 {
16985 case 0:
005d79fd 16986 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16987 break;
16988 case 1:
005d79fd 16989 printf (_("hard float, "));
34c8bcba
JM
16990 break;
16991 case 2:
005d79fd 16992 printf (_("soft float, "));
34c8bcba 16993 break;
3c7b9897 16994 case 3:
005d79fd 16995 printf (_("single-precision hard float, "));
3c7b9897 16996 break;
005d79fd
AM
16997 }
16998
16999 switch (val & 0xC)
17000 {
17001 case 0:
17002 printf (_("unspecified long double\n"));
17003 break;
17004 case 4:
17005 printf (_("128-bit IBM long double\n"));
17006 break;
17007 case 8:
17008 printf (_("64-bit long double\n"));
17009 break;
17010 case 12:
17011 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17012 break;
17013 }
17014 return p;
005d79fd 17015 }
34c8bcba 17016
c6e65352
DJ
17017 if (tag == Tag_GNU_Power_ABI_Vector)
17018 {
c6e65352 17019 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17020 if (p == end)
005d79fd
AM
17021 {
17022 printf (_("<corrupt>\n"));
17023 return p;
17024 }
cd30bcef 17025 READ_ULEB (val, p, end);
005d79fd
AM
17026
17027 if (val > 3)
17028 printf ("(%#x), ", val);
17029
17030 switch (val & 3)
c6e65352
DJ
17031 {
17032 case 0:
005d79fd 17033 printf (_("unspecified\n"));
c6e65352
DJ
17034 break;
17035 case 1:
005d79fd 17036 printf (_("generic\n"));
c6e65352
DJ
17037 break;
17038 case 2:
17039 printf ("AltiVec\n");
17040 break;
17041 case 3:
17042 printf ("SPE\n");
17043 break;
c6e65352
DJ
17044 }
17045 return p;
005d79fd 17046 }
c6e65352 17047
f82e0623
NF
17048 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17049 {
005d79fd 17050 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17051 if (p == end)
f6f0e17b 17052 {
005d79fd 17053 printf (_("<corrupt>\n"));
f6f0e17b
NC
17054 return p;
17055 }
cd30bcef 17056 READ_ULEB (val, p, end);
0b4362b0 17057
005d79fd
AM
17058 if (val > 2)
17059 printf ("(%#x), ", val);
17060
17061 switch (val & 3)
17062 {
17063 case 0:
17064 printf (_("unspecified\n"));
17065 break;
17066 case 1:
17067 printf ("r3/r4\n");
17068 break;
17069 case 2:
17070 printf (_("memory\n"));
17071 break;
17072 case 3:
17073 printf ("???\n");
17074 break;
17075 }
f82e0623
NF
17076 return p;
17077 }
17078
f6f0e17b 17079 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17080}
17081
643f7afb
AK
17082static unsigned char *
17083display_s390_gnu_attribute (unsigned char * p,
60abdbed 17084 unsigned int tag,
643f7afb
AK
17085 const unsigned char * const end)
17086{
cd30bcef 17087 unsigned int val;
643f7afb
AK
17088
17089 if (tag == Tag_GNU_S390_ABI_Vector)
17090 {
643f7afb 17091 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17092 READ_ULEB (val, p, end);
643f7afb
AK
17093
17094 switch (val)
17095 {
17096 case 0:
17097 printf (_("any\n"));
17098 break;
17099 case 1:
17100 printf (_("software\n"));
17101 break;
17102 case 2:
17103 printf (_("hardware\n"));
17104 break;
17105 default:
17106 printf ("??? (%d)\n", val);
17107 break;
17108 }
17109 return p;
17110 }
17111
17112 return display_tag_value (tag & 1, p, end);
17113}
17114
9e8c70f9 17115static void
60abdbed 17116display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17117{
17118 if (mask)
17119 {
015dc7e1 17120 bool first = true;
071436c6 17121
9e8c70f9 17122 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17123 fputs ("mul32", stdout), first = false;
9e8c70f9 17124 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17125 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17126 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17127 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17128 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17129 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17130 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17131 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17132 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17133 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17134 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17135 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17136 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17137 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17138 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17139 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17140 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17141 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17142 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17143 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17144 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17145 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17146 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17147 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17148 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17149 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17150 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17151 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17152 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17153 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17154 }
17155 else
071436c6
NC
17156 fputc ('0', stdout);
17157 fputc ('\n', stdout);
9e8c70f9
DM
17158}
17159
3d68f91c 17160static void
60abdbed 17161display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17162{
17163 if (mask)
17164 {
015dc7e1 17165 bool first = true;
071436c6 17166
3d68f91c 17167 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17168 fputs ("fjathplus", stdout), first = false;
3d68f91c 17169 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17170 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17171 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17172 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17173 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17174 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17175 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17176 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17177 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17178 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17179 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17180 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17181 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17182 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17183 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17184 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17185 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17186 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17187 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17188 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17189 }
17190 else
071436c6
NC
17191 fputc ('0', stdout);
17192 fputc ('\n', stdout);
3d68f91c
JM
17193}
17194
9e8c70f9 17195static unsigned char *
f6f0e17b 17196display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17197 unsigned int tag,
f6f0e17b 17198 const unsigned char * const end)
9e8c70f9 17199{
cd30bcef 17200 unsigned int val;
3d68f91c 17201
9e8c70f9
DM
17202 if (tag == Tag_GNU_Sparc_HWCAPS)
17203 {
cd30bcef 17204 READ_ULEB (val, p, end);
9e8c70f9 17205 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17206 display_sparc_hwcaps (val);
17207 return p;
3d68f91c
JM
17208 }
17209 if (tag == Tag_GNU_Sparc_HWCAPS2)
17210 {
cd30bcef 17211 READ_ULEB (val, p, end);
3d68f91c
JM
17212 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17213 display_sparc_hwcaps2 (val);
17214 return p;
17215 }
9e8c70f9 17216
f6f0e17b 17217 return display_tag_value (tag, p, end);
9e8c70f9
DM
17218}
17219
351cdf24 17220static void
32ec8896 17221print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17222{
17223 switch (val)
17224 {
17225 case Val_GNU_MIPS_ABI_FP_ANY:
17226 printf (_("Hard or soft float\n"));
17227 break;
17228 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17229 printf (_("Hard float (double precision)\n"));
17230 break;
17231 case Val_GNU_MIPS_ABI_FP_SINGLE:
17232 printf (_("Hard float (single precision)\n"));
17233 break;
17234 case Val_GNU_MIPS_ABI_FP_SOFT:
17235 printf (_("Soft float\n"));
17236 break;
17237 case Val_GNU_MIPS_ABI_FP_OLD_64:
17238 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17239 break;
17240 case Val_GNU_MIPS_ABI_FP_XX:
17241 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17242 break;
17243 case Val_GNU_MIPS_ABI_FP_64:
17244 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17245 break;
17246 case Val_GNU_MIPS_ABI_FP_64A:
17247 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17248 break;
3350cc01
CM
17249 case Val_GNU_MIPS_ABI_FP_NAN2008:
17250 printf (_("NaN 2008 compatibility\n"));
17251 break;
351cdf24
MF
17252 default:
17253 printf ("??? (%d)\n", val);
17254 break;
17255 }
17256}
17257
2cf19d5c 17258static unsigned char *
f6f0e17b 17259display_mips_gnu_attribute (unsigned char * p,
60abdbed 17260 unsigned int tag,
f6f0e17b 17261 const unsigned char * const end)
2cf19d5c 17262{
2cf19d5c
JM
17263 if (tag == Tag_GNU_MIPS_ABI_FP)
17264 {
32ec8896 17265 unsigned int val;
f6f0e17b 17266
2cf19d5c 17267 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17268 READ_ULEB (val, p, end);
351cdf24 17269 print_mips_fp_abi_value (val);
2cf19d5c
JM
17270 return p;
17271 }
17272
a9f58168
CF
17273 if (tag == Tag_GNU_MIPS_ABI_MSA)
17274 {
32ec8896 17275 unsigned int val;
a9f58168 17276
a9f58168 17277 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17278 READ_ULEB (val, p, end);
a9f58168
CF
17279
17280 switch (val)
17281 {
17282 case Val_GNU_MIPS_ABI_MSA_ANY:
17283 printf (_("Any MSA or not\n"));
17284 break;
17285 case Val_GNU_MIPS_ABI_MSA_128:
17286 printf (_("128-bit MSA\n"));
17287 break;
17288 default:
17289 printf ("??? (%d)\n", val);
17290 break;
17291 }
17292 return p;
17293 }
17294
f6f0e17b 17295 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17296}
17297
59e6276b 17298static unsigned char *
f6f0e17b
NC
17299display_tic6x_attribute (unsigned char * p,
17300 const unsigned char * const end)
59e6276b 17301{
60abdbed 17302 unsigned int tag;
cd30bcef 17303 unsigned int val;
59e6276b 17304
cd30bcef 17305 READ_ULEB (tag, p, end);
59e6276b
JM
17306
17307 switch (tag)
17308 {
75fa6dc1 17309 case Tag_ISA:
75fa6dc1 17310 printf (" Tag_ISA: ");
cd30bcef 17311 READ_ULEB (val, p, end);
59e6276b
JM
17312
17313 switch (val)
17314 {
75fa6dc1 17315 case C6XABI_Tag_ISA_none:
59e6276b
JM
17316 printf (_("None\n"));
17317 break;
75fa6dc1 17318 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17319 printf ("C62x\n");
17320 break;
75fa6dc1 17321 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17322 printf ("C67x\n");
17323 break;
75fa6dc1 17324 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17325 printf ("C67x+\n");
17326 break;
75fa6dc1 17327 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17328 printf ("C64x\n");
17329 break;
75fa6dc1 17330 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17331 printf ("C64x+\n");
17332 break;
75fa6dc1 17333 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17334 printf ("C674x\n");
17335 break;
17336 default:
17337 printf ("??? (%d)\n", val);
17338 break;
17339 }
17340 return p;
17341
87779176 17342 case Tag_ABI_wchar_t:
87779176 17343 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17344 READ_ULEB (val, p, end);
87779176
JM
17345 switch (val)
17346 {
17347 case 0:
17348 printf (_("Not used\n"));
17349 break;
17350 case 1:
17351 printf (_("2 bytes\n"));
17352 break;
17353 case 2:
17354 printf (_("4 bytes\n"));
17355 break;
17356 default:
17357 printf ("??? (%d)\n", val);
17358 break;
17359 }
17360 return p;
17361
17362 case Tag_ABI_stack_align_needed:
87779176 17363 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17364 READ_ULEB (val, p, end);
87779176
JM
17365 switch (val)
17366 {
17367 case 0:
17368 printf (_("8-byte\n"));
17369 break;
17370 case 1:
17371 printf (_("16-byte\n"));
17372 break;
17373 default:
17374 printf ("??? (%d)\n", val);
17375 break;
17376 }
17377 return p;
17378
17379 case Tag_ABI_stack_align_preserved:
cd30bcef 17380 READ_ULEB (val, p, end);
87779176
JM
17381 printf (" Tag_ABI_stack_align_preserved: ");
17382 switch (val)
17383 {
17384 case 0:
17385 printf (_("8-byte\n"));
17386 break;
17387 case 1:
17388 printf (_("16-byte\n"));
17389 break;
17390 default:
17391 printf ("??? (%d)\n", val);
17392 break;
17393 }
17394 return p;
17395
b5593623 17396 case Tag_ABI_DSBT:
cd30bcef 17397 READ_ULEB (val, p, end);
b5593623
JM
17398 printf (" Tag_ABI_DSBT: ");
17399 switch (val)
17400 {
17401 case 0:
17402 printf (_("DSBT addressing not used\n"));
17403 break;
17404 case 1:
17405 printf (_("DSBT addressing used\n"));
17406 break;
17407 default:
17408 printf ("??? (%d)\n", val);
17409 break;
17410 }
17411 return p;
17412
87779176 17413 case Tag_ABI_PID:
cd30bcef 17414 READ_ULEB (val, p, end);
87779176
JM
17415 printf (" Tag_ABI_PID: ");
17416 switch (val)
17417 {
17418 case 0:
17419 printf (_("Data addressing position-dependent\n"));
17420 break;
17421 case 1:
17422 printf (_("Data addressing position-independent, GOT near DP\n"));
17423 break;
17424 case 2:
17425 printf (_("Data addressing position-independent, GOT far from DP\n"));
17426 break;
17427 default:
17428 printf ("??? (%d)\n", val);
17429 break;
17430 }
17431 return p;
17432
17433 case Tag_ABI_PIC:
cd30bcef 17434 READ_ULEB (val, p, end);
87779176
JM
17435 printf (" Tag_ABI_PIC: ");
17436 switch (val)
17437 {
17438 case 0:
17439 printf (_("Code addressing position-dependent\n"));
17440 break;
17441 case 1:
17442 printf (_("Code addressing position-independent\n"));
17443 break;
17444 default:
17445 printf ("??? (%d)\n", val);
17446 break;
17447 }
17448 return p;
17449
17450 case Tag_ABI_array_object_alignment:
cd30bcef 17451 READ_ULEB (val, p, end);
87779176
JM
17452 printf (" Tag_ABI_array_object_alignment: ");
17453 switch (val)
17454 {
17455 case 0:
17456 printf (_("8-byte\n"));
17457 break;
17458 case 1:
17459 printf (_("4-byte\n"));
17460 break;
17461 case 2:
17462 printf (_("16-byte\n"));
17463 break;
17464 default:
17465 printf ("??? (%d)\n", val);
17466 break;
17467 }
17468 return p;
17469
17470 case Tag_ABI_array_object_align_expected:
cd30bcef 17471 READ_ULEB (val, p, end);
87779176
JM
17472 printf (" Tag_ABI_array_object_align_expected: ");
17473 switch (val)
17474 {
17475 case 0:
17476 printf (_("8-byte\n"));
17477 break;
17478 case 1:
17479 printf (_("4-byte\n"));
17480 break;
17481 case 2:
17482 printf (_("16-byte\n"));
17483 break;
17484 default:
17485 printf ("??? (%d)\n", val);
17486 break;
17487 }
17488 return p;
17489
3cbd1c06 17490 case Tag_ABI_compatibility:
071436c6 17491 {
cd30bcef 17492 READ_ULEB (val, p, end);
071436c6 17493 printf (" Tag_ABI_compatibility: ");
071436c6 17494 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17495 if (p < end - 1)
17496 {
17497 size_t maxlen = (end - p) - 1;
17498
17499 print_symbol ((int) maxlen, (const char *) p);
17500 p += strnlen ((char *) p, maxlen) + 1;
17501 }
17502 else
17503 {
17504 printf (_("<corrupt>"));
17505 p = (unsigned char *) end;
17506 }
071436c6 17507 putchar ('\n');
071436c6
NC
17508 return p;
17509 }
87779176
JM
17510
17511 case Tag_ABI_conformance:
071436c6 17512 {
4082ef84
NC
17513 printf (" Tag_ABI_conformance: \"");
17514 if (p < end - 1)
17515 {
17516 size_t maxlen = (end - p) - 1;
071436c6 17517
4082ef84
NC
17518 print_symbol ((int) maxlen, (const char *) p);
17519 p += strnlen ((char *) p, maxlen) + 1;
17520 }
17521 else
17522 {
17523 printf (_("<corrupt>"));
17524 p = (unsigned char *) end;
17525 }
071436c6 17526 printf ("\"\n");
071436c6
NC
17527 return p;
17528 }
59e6276b
JM
17529 }
17530
f6f0e17b
NC
17531 return display_tag_value (tag, p, end);
17532}
59e6276b 17533
f6f0e17b 17534static void
60abdbed 17535display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17536{
17537 unsigned long addr = 0;
17538 size_t bytes = end - p;
17539
feceaa59 17540 assert (end >= p);
f6f0e17b 17541 while (bytes)
87779176 17542 {
f6f0e17b
NC
17543 int j;
17544 int k;
17545 int lbytes = (bytes > 16 ? 16 : bytes);
17546
17547 printf (" 0x%8.8lx ", addr);
17548
17549 for (j = 0; j < 16; j++)
17550 {
17551 if (j < lbytes)
17552 printf ("%2.2x", p[j]);
17553 else
17554 printf (" ");
17555
17556 if ((j & 3) == 3)
17557 printf (" ");
17558 }
17559
17560 for (j = 0; j < lbytes; j++)
17561 {
17562 k = p[j];
17563 if (k >= ' ' && k < 0x7f)
17564 printf ("%c", k);
17565 else
17566 printf (".");
17567 }
17568
17569 putchar ('\n');
17570
17571 p += lbytes;
17572 bytes -= lbytes;
17573 addr += lbytes;
87779176 17574 }
59e6276b 17575
f6f0e17b 17576 putchar ('\n');
59e6276b
JM
17577}
17578
13761a11 17579static unsigned char *
b0191216 17580display_msp430_attribute (unsigned char * p,
13761a11
NC
17581 const unsigned char * const end)
17582{
60abdbed
NC
17583 unsigned int val;
17584 unsigned int tag;
13761a11 17585
cd30bcef 17586 READ_ULEB (tag, p, end);
0b4362b0 17587
13761a11
NC
17588 switch (tag)
17589 {
17590 case OFBA_MSPABI_Tag_ISA:
13761a11 17591 printf (" Tag_ISA: ");
cd30bcef 17592 READ_ULEB (val, p, end);
13761a11
NC
17593 switch (val)
17594 {
17595 case 0: printf (_("None\n")); break;
17596 case 1: printf (_("MSP430\n")); break;
17597 case 2: printf (_("MSP430X\n")); break;
17598 default: printf ("??? (%d)\n", val); break;
17599 }
17600 break;
17601
17602 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17603 printf (" Tag_Code_Model: ");
cd30bcef 17604 READ_ULEB (val, p, end);
13761a11
NC
17605 switch (val)
17606 {
17607 case 0: printf (_("None\n")); break;
17608 case 1: printf (_("Small\n")); break;
17609 case 2: printf (_("Large\n")); break;
17610 default: printf ("??? (%d)\n", val); break;
17611 }
17612 break;
17613
17614 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17615 printf (" Tag_Data_Model: ");
cd30bcef 17616 READ_ULEB (val, p, end);
13761a11
NC
17617 switch (val)
17618 {
17619 case 0: printf (_("None\n")); break;
17620 case 1: printf (_("Small\n")); break;
17621 case 2: printf (_("Large\n")); break;
17622 case 3: printf (_("Restricted Large\n")); break;
17623 default: printf ("??? (%d)\n", val); break;
17624 }
17625 break;
17626
17627 default:
17628 printf (_(" <unknown tag %d>: "), tag);
17629
17630 if (tag & 1)
17631 {
071436c6 17632 putchar ('"');
4082ef84
NC
17633 if (p < end - 1)
17634 {
17635 size_t maxlen = (end - p) - 1;
17636
17637 print_symbol ((int) maxlen, (const char *) p);
17638 p += strnlen ((char *) p, maxlen) + 1;
17639 }
17640 else
17641 {
17642 printf (_("<corrupt>"));
17643 p = (unsigned char *) end;
17644 }
071436c6 17645 printf ("\"\n");
13761a11
NC
17646 }
17647 else
17648 {
cd30bcef 17649 READ_ULEB (val, p, end);
13761a11
NC
17650 printf ("%d (0x%x)\n", val, val);
17651 }
17652 break;
17653 }
17654
4082ef84 17655 assert (p <= end);
13761a11
NC
17656 return p;
17657}
17658
c0ea7c52
JL
17659static unsigned char *
17660display_msp430_gnu_attribute (unsigned char * p,
17661 unsigned int tag,
17662 const unsigned char * const end)
17663{
17664 if (tag == Tag_GNU_MSP430_Data_Region)
17665 {
cd30bcef 17666 unsigned int val;
c0ea7c52 17667
c0ea7c52 17668 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17669 READ_ULEB (val, p, end);
c0ea7c52
JL
17670
17671 switch (val)
17672 {
17673 case Val_GNU_MSP430_Data_Region_Any:
17674 printf (_("Any Region\n"));
17675 break;
17676 case Val_GNU_MSP430_Data_Region_Lower:
17677 printf (_("Lower Region Only\n"));
17678 break;
17679 default:
cd30bcef 17680 printf ("??? (%u)\n", val);
c0ea7c52
JL
17681 }
17682 return p;
17683 }
17684 return display_tag_value (tag & 1, p, end);
17685}
17686
2dc8dd17
JW
17687struct riscv_attr_tag_t {
17688 const char *name;
cd30bcef 17689 unsigned int tag;
2dc8dd17
JW
17690};
17691
17692static struct riscv_attr_tag_t riscv_attr_tag[] =
17693{
17694#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17695 T(arch),
17696 T(priv_spec),
17697 T(priv_spec_minor),
17698 T(priv_spec_revision),
17699 T(unaligned_access),
17700 T(stack_align),
17701#undef T
17702};
17703
17704static unsigned char *
17705display_riscv_attribute (unsigned char *p,
17706 const unsigned char * const end)
17707{
cd30bcef
AM
17708 unsigned int val;
17709 unsigned int tag;
2dc8dd17
JW
17710 struct riscv_attr_tag_t *attr = NULL;
17711 unsigned i;
17712
cd30bcef 17713 READ_ULEB (tag, p, end);
2dc8dd17
JW
17714
17715 /* Find the name of attribute. */
17716 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17717 {
17718 if (riscv_attr_tag[i].tag == tag)
17719 {
17720 attr = &riscv_attr_tag[i];
17721 break;
17722 }
17723 }
17724
17725 if (attr)
17726 printf (" %s: ", attr->name);
17727 else
17728 return display_tag_value (tag, p, end);
17729
17730 switch (tag)
17731 {
17732 case Tag_RISCV_priv_spec:
17733 case Tag_RISCV_priv_spec_minor:
17734 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17735 READ_ULEB (val, p, end);
17736 printf (_("%u\n"), val);
2dc8dd17
JW
17737 break;
17738 case Tag_RISCV_unaligned_access:
cd30bcef 17739 READ_ULEB (val, p, end);
2dc8dd17
JW
17740 switch (val)
17741 {
17742 case 0:
17743 printf (_("No unaligned access\n"));
17744 break;
17745 case 1:
17746 printf (_("Unaligned access\n"));
17747 break;
17748 }
17749 break;
17750 case Tag_RISCV_stack_align:
cd30bcef
AM
17751 READ_ULEB (val, p, end);
17752 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17753 break;
17754 case Tag_RISCV_arch:
17755 p = display_tag_value (-1, p, end);
17756 break;
17757 default:
17758 return display_tag_value (tag, p, end);
17759 }
17760
17761 return p;
17762}
17763
0861f561
CQ
17764static unsigned char *
17765display_csky_attribute (unsigned char * p,
17766 const unsigned char * const end)
17767{
17768 unsigned int tag;
17769 unsigned int val;
17770 READ_ULEB (tag, p, end);
17771
17772 if (tag >= Tag_CSKY_MAX)
17773 {
17774 return display_tag_value (-1, p, end);
17775 }
17776
17777 switch (tag)
17778 {
17779 case Tag_CSKY_ARCH_NAME:
17780 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17781 return display_tag_value (-1, p, end);
17782 case Tag_CSKY_CPU_NAME:
17783 printf (" Tag_CSKY_CPU_NAME:\t\t");
17784 return display_tag_value (-1, p, end);
17785
17786 case Tag_CSKY_ISA_FLAGS:
17787 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17788 return display_tag_value (0, p, end);
17789 case Tag_CSKY_ISA_EXT_FLAGS:
17790 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17791 return display_tag_value (0, p, end);
17792
17793 case Tag_CSKY_DSP_VERSION:
17794 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17795 READ_ULEB (val, p, end);
17796 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17797 printf ("DSP Extension\n");
17798 else if (val == VAL_CSKY_DSP_VERSION_2)
17799 printf ("DSP 2.0\n");
17800 break;
17801
17802 case Tag_CSKY_VDSP_VERSION:
17803 printf (" Tag_CSKY_VDSP_VERSION:\t");
17804 READ_ULEB (val, p, end);
17805 printf ("VDSP Version %d\n", val);
17806 break;
17807
17808 case Tag_CSKY_FPU_VERSION:
17809 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17810 READ_ULEB (val, p, end);
17811 if (val == VAL_CSKY_FPU_VERSION_1)
17812 printf ("ABIV1 FPU Version 1\n");
17813 else if (val == VAL_CSKY_FPU_VERSION_2)
17814 printf ("FPU Version 2\n");
17815 break;
17816
17817 case Tag_CSKY_FPU_ABI:
17818 printf (" Tag_CSKY_FPU_ABI:\t\t");
17819 READ_ULEB (val, p, end);
17820 if (val == VAL_CSKY_FPU_ABI_HARD)
17821 printf ("Hard\n");
17822 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17823 printf ("SoftFP\n");
17824 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17825 printf ("Soft\n");
17826 break;
17827 case Tag_CSKY_FPU_ROUNDING:
17828 READ_ULEB (val, p, end);
f253158f
NC
17829 if (val == 1)
17830 {
17831 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17832 printf ("Needed\n");
17833 }
0861f561
CQ
17834 break;
17835 case Tag_CSKY_FPU_DENORMAL:
17836 READ_ULEB (val, p, end);
f253158f
NC
17837 if (val == 1)
17838 {
17839 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17840 printf ("Needed\n");
17841 }
0861f561
CQ
17842 break;
17843 case Tag_CSKY_FPU_Exception:
17844 READ_ULEB (val, p, end);
f253158f
NC
17845 if (val == 1)
17846 {
17847 printf (" Tag_CSKY_FPU_Exception:\t");
17848 printf ("Needed\n");
17849 }
0861f561
CQ
17850 break;
17851 case Tag_CSKY_FPU_NUMBER_MODULE:
17852 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17853 return display_tag_value (-1, p, end);
17854 case Tag_CSKY_FPU_HARDFP:
17855 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17856 READ_ULEB (val, p, end);
17857 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17858 printf (" Half");
17859 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17860 printf (" Single");
17861 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17862 printf (" Double");
17863 printf ("\n");
17864 break;
17865 default:
17866 return display_tag_value (tag, p, end);
17867 }
17868 return p;
17869}
17870
015dc7e1 17871static bool
dda8d76d 17872process_attributes (Filedata * filedata,
60bca95a 17873 const char * public_name,
104d59d1 17874 unsigned int proc_type,
f6f0e17b 17875 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17876 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17877{
2cf0635d 17878 Elf_Internal_Shdr * sect;
11c1ff18 17879 unsigned i;
015dc7e1 17880 bool res = true;
11c1ff18
PB
17881
17882 /* Find the section header so that we get the size. */
dda8d76d
NC
17883 for (i = 0, sect = filedata->section_headers;
17884 i < filedata->file_header.e_shnum;
11c1ff18
PB
17885 i++, sect++)
17886 {
071436c6
NC
17887 unsigned char * contents;
17888 unsigned char * p;
17889
104d59d1 17890 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17891 continue;
17892
dda8d76d 17893 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17894 sect->sh_size, _("attributes"));
60bca95a 17895 if (contents == NULL)
32ec8896 17896 {
015dc7e1 17897 res = false;
32ec8896
NC
17898 continue;
17899 }
60bca95a 17900
11c1ff18 17901 p = contents;
60abdbed
NC
17902 /* The first character is the version of the attributes.
17903 Currently only version 1, (aka 'A') is recognised here. */
17904 if (*p != 'A')
32ec8896
NC
17905 {
17906 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17907 res = false;
32ec8896 17908 }
60abdbed 17909 else
11c1ff18 17910 {
625d49fc 17911 uint64_t section_len;
071436c6
NC
17912
17913 section_len = sect->sh_size - 1;
11c1ff18 17914 p++;
60bca95a 17915
071436c6 17916 while (section_len > 0)
11c1ff18 17917 {
625d49fc 17918 uint64_t attr_len;
e9847026 17919 unsigned int namelen;
015dc7e1
AM
17920 bool public_section;
17921 bool gnu_section;
11c1ff18 17922
071436c6 17923 if (section_len <= 4)
e0a31db1
NC
17924 {
17925 error (_("Tag section ends prematurely\n"));
015dc7e1 17926 res = false;
e0a31db1
NC
17927 break;
17928 }
071436c6 17929 attr_len = byte_get (p, 4);
11c1ff18 17930 p += 4;
60bca95a 17931
071436c6 17932 if (attr_len > section_len)
11c1ff18 17933 {
071436c6
NC
17934 error (_("Bad attribute length (%u > %u)\n"),
17935 (unsigned) attr_len, (unsigned) section_len);
17936 attr_len = section_len;
015dc7e1 17937 res = false;
11c1ff18 17938 }
74e1a04b 17939 /* PR 17531: file: 001-101425-0.004 */
071436c6 17940 else if (attr_len < 5)
74e1a04b 17941 {
071436c6 17942 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17943 res = false;
74e1a04b
NC
17944 break;
17945 }
e9847026 17946
071436c6
NC
17947 section_len -= attr_len;
17948 attr_len -= 4;
17949
17950 namelen = strnlen ((char *) p, attr_len) + 1;
17951 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17952 {
17953 error (_("Corrupt attribute section name\n"));
015dc7e1 17954 res = false;
e9847026
NC
17955 break;
17956 }
17957
071436c6
NC
17958 printf (_("Attribute Section: "));
17959 print_symbol (INT_MAX, (const char *) p);
17960 putchar ('\n');
60bca95a
NC
17961
17962 if (public_name && streq ((char *) p, public_name))
015dc7e1 17963 public_section = true;
11c1ff18 17964 else
015dc7e1 17965 public_section = false;
60bca95a
NC
17966
17967 if (streq ((char *) p, "gnu"))
015dc7e1 17968 gnu_section = true;
104d59d1 17969 else
015dc7e1 17970 gnu_section = false;
60bca95a 17971
11c1ff18 17972 p += namelen;
071436c6 17973 attr_len -= namelen;
e0a31db1 17974
071436c6 17975 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17976 {
e0a31db1 17977 int tag;
cd30bcef 17978 unsigned int val;
625d49fc 17979 uint64_t size;
071436c6 17980 unsigned char * end;
60bca95a 17981
e0a31db1 17982 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17983 if (attr_len < 6)
e0a31db1
NC
17984 {
17985 error (_("Unused bytes at end of section\n"));
015dc7e1 17986 res = false;
e0a31db1
NC
17987 section_len = 0;
17988 break;
17989 }
17990
17991 tag = *(p++);
11c1ff18 17992 size = byte_get (p, 4);
071436c6 17993 if (size > attr_len)
11c1ff18 17994 {
e9847026 17995 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17996 (unsigned) size, (unsigned) attr_len);
015dc7e1 17997 res = false;
071436c6 17998 size = attr_len;
11c1ff18 17999 }
e0a31db1
NC
18000 /* PR binutils/17531: Safe handling of corrupt files. */
18001 if (size < 6)
18002 {
18003 error (_("Bad subsection length (%u < 6)\n"),
18004 (unsigned) size);
015dc7e1 18005 res = false;
e0a31db1
NC
18006 section_len = 0;
18007 break;
18008 }
60bca95a 18009
071436c6 18010 attr_len -= size;
11c1ff18 18011 end = p + size - 1;
071436c6 18012 assert (end <= contents + sect->sh_size);
11c1ff18 18013 p += 4;
60bca95a 18014
11c1ff18
PB
18015 switch (tag)
18016 {
18017 case 1:
2b692964 18018 printf (_("File Attributes\n"));
11c1ff18
PB
18019 break;
18020 case 2:
2b692964 18021 printf (_("Section Attributes:"));
11c1ff18
PB
18022 goto do_numlist;
18023 case 3:
2b692964 18024 printf (_("Symbol Attributes:"));
1a0670f3 18025 /* Fall through. */
11c1ff18
PB
18026 do_numlist:
18027 for (;;)
18028 {
cd30bcef 18029 READ_ULEB (val, p, end);
11c1ff18
PB
18030 if (val == 0)
18031 break;
18032 printf (" %d", val);
18033 }
18034 printf ("\n");
18035 break;
18036 default:
2b692964 18037 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18038 public_section = false;
11c1ff18
PB
18039 break;
18040 }
60bca95a 18041
071436c6 18042 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18043 {
18044 while (p < end)
f6f0e17b 18045 p = display_pub_attribute (p, end);
60abdbed 18046 assert (p == end);
104d59d1 18047 }
071436c6 18048 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18049 {
18050 while (p < end)
18051 p = display_gnu_attribute (p,
f6f0e17b
NC
18052 display_proc_gnu_attribute,
18053 end);
60abdbed 18054 assert (p == end);
11c1ff18 18055 }
071436c6 18056 else if (p < end)
11c1ff18 18057 {
071436c6 18058 printf (_(" Unknown attribute:\n"));
f6f0e17b 18059 display_raw_attribute (p, end);
11c1ff18
PB
18060 p = end;
18061 }
071436c6
NC
18062 else
18063 attr_len = 0;
11c1ff18
PB
18064 }
18065 }
18066 }
d70c5fc7 18067
60bca95a 18068 free (contents);
11c1ff18 18069 }
32ec8896
NC
18070
18071 return res;
11c1ff18
PB
18072}
18073
ccb4c951
RS
18074/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18075 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18076 and return the VMA of the next entry, or -1 if there was a problem.
18077 Does not read from DATA_END or beyond. */
ccb4c951 18078
625d49fc
AM
18079static uint64_t
18080print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18081 unsigned char * data_end)
ccb4c951
RS
18082{
18083 printf (" ");
18084 print_vma (addr, LONG_HEX);
18085 printf (" ");
18086 if (addr < pltgot + 0xfff0)
18087 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18088 else
18089 printf ("%10s", "");
18090 printf (" ");
18091 if (data == NULL)
2b692964 18092 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18093 else
18094 {
625d49fc 18095 uint64_t entry;
82b1b41b 18096 unsigned char * from = data + addr - pltgot;
ccb4c951 18097
82b1b41b
NC
18098 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18099 {
18100 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18101 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18102 return (uint64_t) -1;
82b1b41b
NC
18103 }
18104 else
18105 {
18106 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18107 print_vma (entry, LONG_HEX);
18108 }
ccb4c951
RS
18109 }
18110 return addr + (is_32bit_elf ? 4 : 8);
18111}
18112
861fb55a
DJ
18113/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18114 PLTGOT. Print the Address and Initial fields of an entry at VMA
18115 ADDR and return the VMA of the next entry. */
18116
625d49fc
AM
18117static uint64_t
18118print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18119{
18120 printf (" ");
18121 print_vma (addr, LONG_HEX);
18122 printf (" ");
18123 if (data == NULL)
2b692964 18124 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18125 else
18126 {
625d49fc 18127 uint64_t entry;
861fb55a
DJ
18128
18129 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18130 print_vma (entry, LONG_HEX);
18131 }
18132 return addr + (is_32bit_elf ? 4 : 8);
18133}
18134
351cdf24
MF
18135static void
18136print_mips_ases (unsigned int mask)
18137{
18138 if (mask & AFL_ASE_DSP)
18139 fputs ("\n\tDSP ASE", stdout);
18140 if (mask & AFL_ASE_DSPR2)
18141 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18142 if (mask & AFL_ASE_DSPR3)
18143 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18144 if (mask & AFL_ASE_EVA)
18145 fputs ("\n\tEnhanced VA Scheme", stdout);
18146 if (mask & AFL_ASE_MCU)
18147 fputs ("\n\tMCU (MicroController) ASE", stdout);
18148 if (mask & AFL_ASE_MDMX)
18149 fputs ("\n\tMDMX ASE", stdout);
18150 if (mask & AFL_ASE_MIPS3D)
18151 fputs ("\n\tMIPS-3D ASE", stdout);
18152 if (mask & AFL_ASE_MT)
18153 fputs ("\n\tMT ASE", stdout);
18154 if (mask & AFL_ASE_SMARTMIPS)
18155 fputs ("\n\tSmartMIPS ASE", stdout);
18156 if (mask & AFL_ASE_VIRT)
18157 fputs ("\n\tVZ ASE", stdout);
18158 if (mask & AFL_ASE_MSA)
18159 fputs ("\n\tMSA ASE", stdout);
18160 if (mask & AFL_ASE_MIPS16)
18161 fputs ("\n\tMIPS16 ASE", stdout);
18162 if (mask & AFL_ASE_MICROMIPS)
18163 fputs ("\n\tMICROMIPS ASE", stdout);
18164 if (mask & AFL_ASE_XPA)
18165 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18166 if (mask & AFL_ASE_MIPS16E2)
18167 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18168 if (mask & AFL_ASE_CRC)
18169 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18170 if (mask & AFL_ASE_GINV)
18171 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18172 if (mask & AFL_ASE_LOONGSON_MMI)
18173 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18174 if (mask & AFL_ASE_LOONGSON_CAM)
18175 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18176 if (mask & AFL_ASE_LOONGSON_EXT)
18177 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18178 if (mask & AFL_ASE_LOONGSON_EXT2)
18179 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18180 if (mask == 0)
18181 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18182 else if ((mask & ~AFL_ASE_MASK) != 0)
18183 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18184}
18185
18186static void
18187print_mips_isa_ext (unsigned int isa_ext)
18188{
18189 switch (isa_ext)
18190 {
18191 case 0:
18192 fputs (_("None"), stdout);
18193 break;
18194 case AFL_EXT_XLR:
18195 fputs ("RMI XLR", stdout);
18196 break;
2c629856
N
18197 case AFL_EXT_OCTEON3:
18198 fputs ("Cavium Networks Octeon3", stdout);
18199 break;
351cdf24
MF
18200 case AFL_EXT_OCTEON2:
18201 fputs ("Cavium Networks Octeon2", stdout);
18202 break;
18203 case AFL_EXT_OCTEONP:
18204 fputs ("Cavium Networks OcteonP", stdout);
18205 break;
351cdf24
MF
18206 case AFL_EXT_OCTEON:
18207 fputs ("Cavium Networks Octeon", stdout);
18208 break;
18209 case AFL_EXT_5900:
18210 fputs ("Toshiba R5900", stdout);
18211 break;
18212 case AFL_EXT_4650:
18213 fputs ("MIPS R4650", stdout);
18214 break;
18215 case AFL_EXT_4010:
18216 fputs ("LSI R4010", stdout);
18217 break;
18218 case AFL_EXT_4100:
18219 fputs ("NEC VR4100", stdout);
18220 break;
18221 case AFL_EXT_3900:
18222 fputs ("Toshiba R3900", stdout);
18223 break;
18224 case AFL_EXT_10000:
18225 fputs ("MIPS R10000", stdout);
18226 break;
18227 case AFL_EXT_SB1:
18228 fputs ("Broadcom SB-1", stdout);
18229 break;
18230 case AFL_EXT_4111:
18231 fputs ("NEC VR4111/VR4181", stdout);
18232 break;
18233 case AFL_EXT_4120:
18234 fputs ("NEC VR4120", stdout);
18235 break;
18236 case AFL_EXT_5400:
18237 fputs ("NEC VR5400", stdout);
18238 break;
18239 case AFL_EXT_5500:
18240 fputs ("NEC VR5500", stdout);
18241 break;
18242 case AFL_EXT_LOONGSON_2E:
18243 fputs ("ST Microelectronics Loongson 2E", stdout);
18244 break;
18245 case AFL_EXT_LOONGSON_2F:
18246 fputs ("ST Microelectronics Loongson 2F", stdout);
18247 break;
38bf472a
MR
18248 case AFL_EXT_INTERAPTIV_MR2:
18249 fputs ("Imagination interAptiv MR2", stdout);
18250 break;
351cdf24 18251 default:
00ac7aa0 18252 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18253 }
18254}
18255
32ec8896 18256static signed int
351cdf24
MF
18257get_mips_reg_size (int reg_size)
18258{
18259 return (reg_size == AFL_REG_NONE) ? 0
18260 : (reg_size == AFL_REG_32) ? 32
18261 : (reg_size == AFL_REG_64) ? 64
18262 : (reg_size == AFL_REG_128) ? 128
18263 : -1;
18264}
18265
015dc7e1 18266static bool
dda8d76d 18267process_mips_specific (Filedata * filedata)
5b18a4bc 18268{
2cf0635d 18269 Elf_Internal_Dyn * entry;
351cdf24 18270 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18271 size_t liblist_offset = 0;
18272 size_t liblistno = 0;
18273 size_t conflictsno = 0;
18274 size_t options_offset = 0;
18275 size_t conflicts_offset = 0;
861fb55a
DJ
18276 size_t pltrelsz = 0;
18277 size_t pltrel = 0;
625d49fc
AM
18278 uint64_t pltgot = 0;
18279 uint64_t mips_pltgot = 0;
18280 uint64_t jmprel = 0;
18281 uint64_t local_gotno = 0;
18282 uint64_t gotsym = 0;
18283 uint64_t symtabno = 0;
015dc7e1 18284 bool res = true;
103f02d3 18285
dda8d76d 18286 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18287 display_mips_gnu_attribute))
015dc7e1 18288 res = false;
2cf19d5c 18289
dda8d76d 18290 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18291
18292 if (sect != NULL)
18293 {
18294 Elf_External_ABIFlags_v0 *abiflags_ext;
18295 Elf_Internal_ABIFlags_v0 abiflags_in;
18296
18297 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18298 {
18299 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18300 res = false;
32ec8896 18301 }
351cdf24
MF
18302 else
18303 {
dda8d76d 18304 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18305 sect->sh_size, _("MIPS ABI Flags section"));
18306 if (abiflags_ext)
18307 {
18308 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18309 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18310 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18311 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18312 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18313 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18314 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18315 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18316 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18317 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18318 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18319
18320 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18321 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18322 if (abiflags_in.isa_rev > 1)
18323 printf ("r%d", abiflags_in.isa_rev);
18324 printf ("\nGPR size: %d",
18325 get_mips_reg_size (abiflags_in.gpr_size));
18326 printf ("\nCPR1 size: %d",
18327 get_mips_reg_size (abiflags_in.cpr1_size));
18328 printf ("\nCPR2 size: %d",
18329 get_mips_reg_size (abiflags_in.cpr2_size));
18330 fputs ("\nFP ABI: ", stdout);
18331 print_mips_fp_abi_value (abiflags_in.fp_abi);
18332 fputs ("ISA Extension: ", stdout);
18333 print_mips_isa_ext (abiflags_in.isa_ext);
18334 fputs ("\nASEs:", stdout);
18335 print_mips_ases (abiflags_in.ases);
18336 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18337 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18338 fputc ('\n', stdout);
18339 free (abiflags_ext);
18340 }
18341 }
18342 }
18343
19e6b90e 18344 /* We have a lot of special sections. Thanks SGI! */
978c4450 18345 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18346 {
18347 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18348 sect = find_section (filedata, ".got");
bbdd9a68
MR
18349 if (sect != NULL)
18350 {
18351 unsigned char *data_end;
18352 unsigned char *data;
625d49fc 18353 uint64_t ent, end;
bbdd9a68
MR
18354 int addr_size;
18355
18356 pltgot = sect->sh_addr;
18357
18358 ent = pltgot;
18359 addr_size = (is_32bit_elf ? 4 : 8);
18360 end = pltgot + sect->sh_size;
18361
dda8d76d 18362 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18363 end - pltgot, 1,
18364 _("Global Offset Table data"));
18365 /* PR 12855: Null data is handled gracefully throughout. */
18366 data_end = data + (end - pltgot);
18367
18368 printf (_("\nStatic GOT:\n"));
18369 printf (_(" Canonical gp value: "));
18370 print_vma (ent + 0x7ff0, LONG_HEX);
18371 printf ("\n\n");
18372
18373 /* In a dynamic binary GOT[0] is reserved for the dynamic
18374 loader to store the lazy resolver pointer, however in
18375 a static binary it may well have been omitted and GOT
18376 reduced to a table of addresses.
18377 PR 21344: Check for the entry being fully available
18378 before fetching it. */
18379 if (data
18380 && data + ent - pltgot + addr_size <= data_end
18381 && byte_get (data + ent - pltgot, addr_size) == 0)
18382 {
18383 printf (_(" Reserved entries:\n"));
18384 printf (_(" %*s %10s %*s\n"),
18385 addr_size * 2, _("Address"), _("Access"),
18386 addr_size * 2, _("Value"));
18387 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18388 printf ("\n");
625d49fc 18389 if (ent == (uint64_t) -1)
bbdd9a68
MR
18390 goto sgot_print_fail;
18391
18392 /* Check for the MSB of GOT[1] being set, identifying a
18393 GNU object. This entry will be used by some runtime
18394 loaders, to store the module pointer. Otherwise this
18395 is an ordinary local entry.
18396 PR 21344: Check for the entry being fully available
18397 before fetching it. */
18398 if (data
18399 && data + ent - pltgot + addr_size <= data_end
18400 && (byte_get (data + ent - pltgot, addr_size)
18401 >> (addr_size * 8 - 1)) != 0)
18402 {
18403 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18404 printf ("\n");
625d49fc 18405 if (ent == (uint64_t) -1)
bbdd9a68
MR
18406 goto sgot_print_fail;
18407 }
18408 printf ("\n");
18409 }
18410
f17e9d8a 18411 if (data != NULL && ent < end)
bbdd9a68
MR
18412 {
18413 printf (_(" Local entries:\n"));
18414 printf (" %*s %10s %*s\n",
18415 addr_size * 2, _("Address"), _("Access"),
18416 addr_size * 2, _("Value"));
18417 while (ent < end)
18418 {
18419 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18420 printf ("\n");
625d49fc 18421 if (ent == (uint64_t) -1)
bbdd9a68
MR
18422 goto sgot_print_fail;
18423 }
18424 printf ("\n");
18425 }
18426
18427 sgot_print_fail:
9db70fc3 18428 free (data);
bbdd9a68
MR
18429 }
18430 return res;
18431 }
252b5132 18432
978c4450 18433 for (entry = filedata->dynamic_section;
071436c6 18434 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18435 (entry < filedata->dynamic_section + filedata->dynamic_nent
18436 && entry->d_tag != DT_NULL);
071436c6 18437 ++entry)
252b5132
RH
18438 switch (entry->d_tag)
18439 {
18440 case DT_MIPS_LIBLIST:
d93f0186 18441 liblist_offset
dda8d76d 18442 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18443 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18444 break;
18445 case DT_MIPS_LIBLISTNO:
18446 liblistno = entry->d_un.d_val;
18447 break;
18448 case DT_MIPS_OPTIONS:
dda8d76d 18449 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18450 break;
18451 case DT_MIPS_CONFLICT:
d93f0186 18452 conflicts_offset
dda8d76d 18453 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18454 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18455 break;
18456 case DT_MIPS_CONFLICTNO:
18457 conflictsno = entry->d_un.d_val;
18458 break;
ccb4c951 18459 case DT_PLTGOT:
861fb55a
DJ
18460 pltgot = entry->d_un.d_ptr;
18461 break;
ccb4c951
RS
18462 case DT_MIPS_LOCAL_GOTNO:
18463 local_gotno = entry->d_un.d_val;
18464 break;
18465 case DT_MIPS_GOTSYM:
18466 gotsym = entry->d_un.d_val;
18467 break;
18468 case DT_MIPS_SYMTABNO:
18469 symtabno = entry->d_un.d_val;
18470 break;
861fb55a
DJ
18471 case DT_MIPS_PLTGOT:
18472 mips_pltgot = entry->d_un.d_ptr;
18473 break;
18474 case DT_PLTREL:
18475 pltrel = entry->d_un.d_val;
18476 break;
18477 case DT_PLTRELSZ:
18478 pltrelsz = entry->d_un.d_val;
18479 break;
18480 case DT_JMPREL:
18481 jmprel = entry->d_un.d_ptr;
18482 break;
252b5132
RH
18483 default:
18484 break;
18485 }
18486
18487 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18488 {
2cf0635d 18489 Elf32_External_Lib * elib;
252b5132
RH
18490 size_t cnt;
18491
dda8d76d 18492 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18493 sizeof (Elf32_External_Lib),
18494 liblistno,
18495 _("liblist section data"));
a6e9f9df 18496 if (elib)
252b5132 18497 {
d3a49aa8
AM
18498 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18499 "\nSection '.liblist' contains %lu entries:\n",
18500 (unsigned long) liblistno),
a6e9f9df 18501 (unsigned long) liblistno);
2b692964 18502 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18503 stdout);
18504
18505 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18506 {
a6e9f9df 18507 Elf32_Lib liblist;
91d6fa6a 18508 time_t atime;
d5b07ef4 18509 char timebuf[128];
2cf0635d 18510 struct tm * tmp;
a6e9f9df
AM
18511
18512 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18513 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18514 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18515 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18516 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18517
91d6fa6a 18518 tmp = gmtime (&atime);
e9e44622
JJ
18519 snprintf (timebuf, sizeof (timebuf),
18520 "%04u-%02u-%02uT%02u:%02u:%02u",
18521 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18522 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18523
31104126 18524 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18525 if (valid_dynamic_name (filedata, liblist.l_name))
18526 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18527 else
2b692964 18528 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18529 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18530 liblist.l_version);
a6e9f9df
AM
18531
18532 if (liblist.l_flags == 0)
2b692964 18533 puts (_(" NONE"));
a6e9f9df
AM
18534 else
18535 {
18536 static const struct
252b5132 18537 {
2cf0635d 18538 const char * name;
a6e9f9df 18539 int bit;
252b5132 18540 }
a6e9f9df
AM
18541 l_flags_vals[] =
18542 {
18543 { " EXACT_MATCH", LL_EXACT_MATCH },
18544 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18545 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18546 { " EXPORTS", LL_EXPORTS },
18547 { " DELAY_LOAD", LL_DELAY_LOAD },
18548 { " DELTA", LL_DELTA }
18549 };
18550 int flags = liblist.l_flags;
18551 size_t fcnt;
18552
60bca95a 18553 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18554 if ((flags & l_flags_vals[fcnt].bit) != 0)
18555 {
18556 fputs (l_flags_vals[fcnt].name, stdout);
18557 flags ^= l_flags_vals[fcnt].bit;
18558 }
18559 if (flags != 0)
18560 printf (" %#x", (unsigned int) flags);
252b5132 18561
a6e9f9df
AM
18562 puts ("");
18563 }
252b5132 18564 }
252b5132 18565
a6e9f9df
AM
18566 free (elib);
18567 }
32ec8896 18568 else
015dc7e1 18569 res = false;
252b5132
RH
18570 }
18571
18572 if (options_offset != 0)
18573 {
2cf0635d 18574 Elf_External_Options * eopt;
252b5132
RH
18575 size_t offset;
18576 int cnt;
18577
18578 /* Find the section header so that we get the size. */
dda8d76d 18579 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18580 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18581 if (sect == NULL)
18582 {
18583 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18584 return false;
071436c6 18585 }
7fc0c668
NC
18586 /* PR 24243 */
18587 if (sect->sh_size < sizeof (* eopt))
18588 {
18589 error (_("The MIPS options section is too small.\n"));
015dc7e1 18590 return false;
7fc0c668 18591 }
252b5132 18592
dda8d76d 18593 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18594 sect->sh_size, _("options"));
a6e9f9df 18595 if (eopt)
252b5132 18596 {
fd17d1e6 18597 Elf_Internal_Options option;
76da6bbe 18598
a6e9f9df 18599 offset = cnt = 0;
82b1b41b 18600 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18601 {
2cf0635d 18602 Elf_External_Options * eoption;
fd17d1e6 18603 unsigned int optsize;
252b5132 18604
a6e9f9df 18605 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18606
fd17d1e6 18607 optsize = BYTE_GET (eoption->size);
76da6bbe 18608
82b1b41b 18609 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18610 if (optsize < sizeof (* eopt)
18611 || optsize > sect->sh_size - offset)
82b1b41b 18612 {
645f43a8 18613 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18614 optsize);
645f43a8 18615 free (eopt);
015dc7e1 18616 return false;
82b1b41b 18617 }
fd17d1e6 18618 offset += optsize;
a6e9f9df
AM
18619 ++cnt;
18620 }
252b5132 18621
d3a49aa8
AM
18622 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18623 "\nSection '%s' contains %d entries:\n",
18624 cnt),
dda8d76d 18625 printable_section_name (filedata, sect), cnt);
76da6bbe 18626
82b1b41b 18627 offset = 0;
a6e9f9df 18628 while (cnt-- > 0)
252b5132 18629 {
a6e9f9df 18630 size_t len;
fd17d1e6
AM
18631 Elf_External_Options * eoption;
18632
18633 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18634
18635 option.kind = BYTE_GET (eoption->kind);
18636 option.size = BYTE_GET (eoption->size);
18637 option.section = BYTE_GET (eoption->section);
18638 option.info = BYTE_GET (eoption->info);
a6e9f9df 18639
fd17d1e6 18640 switch (option.kind)
252b5132 18641 {
a6e9f9df
AM
18642 case ODK_NULL:
18643 /* This shouldn't happen. */
d0c4e780 18644 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18645 option.section, option.info);
a6e9f9df 18646 break;
2e6be59c 18647
a6e9f9df
AM
18648 case ODK_REGINFO:
18649 printf (" REGINFO ");
dda8d76d 18650 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18651 {
2cf0635d 18652 Elf32_External_RegInfo * ereg;
b34976b6 18653 Elf32_RegInfo reginfo;
a6e9f9df 18654
2e6be59c 18655 /* 32bit form. */
fd17d1e6
AM
18656 if (option.size < (sizeof (Elf_External_Options)
18657 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18658 {
18659 printf (_("<corrupt>\n"));
18660 error (_("Truncated MIPS REGINFO option\n"));
18661 cnt = 0;
18662 break;
18663 }
18664
fd17d1e6 18665 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18666
a6e9f9df
AM
18667 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18668 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18669 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18670 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18671 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18672 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18673
d0c4e780
AM
18674 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18675 reginfo.ri_gprmask, reginfo.ri_gp_value);
18676 printf (" "
18677 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18678 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18679 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18680 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18681 }
18682 else
18683 {
18684 /* 64 bit form. */
2cf0635d 18685 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18686 Elf64_Internal_RegInfo reginfo;
18687
fd17d1e6
AM
18688 if (option.size < (sizeof (Elf_External_Options)
18689 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18690 {
18691 printf (_("<corrupt>\n"));
18692 error (_("Truncated MIPS REGINFO option\n"));
18693 cnt = 0;
18694 break;
18695 }
18696
fd17d1e6 18697 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18698 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18699 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18700 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18701 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18702 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18703 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18704
d0c4e780
AM
18705 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18706 reginfo.ri_gprmask, reginfo.ri_gp_value);
18707 printf (" "
18708 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18709 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18710 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18711 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18712 }
fd17d1e6 18713 offset += option.size;
a6e9f9df 18714 continue;
2e6be59c 18715
a6e9f9df
AM
18716 case ODK_EXCEPTIONS:
18717 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18718 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18719 fputs (") fpe_max(", stdout);
fd17d1e6 18720 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18721 fputs (")", stdout);
18722
fd17d1e6 18723 if (option.info & OEX_PAGE0)
a6e9f9df 18724 fputs (" PAGE0", stdout);
fd17d1e6 18725 if (option.info & OEX_SMM)
a6e9f9df 18726 fputs (" SMM", stdout);
fd17d1e6 18727 if (option.info & OEX_FPDBUG)
a6e9f9df 18728 fputs (" FPDBUG", stdout);
fd17d1e6 18729 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18730 fputs (" DISMISS", stdout);
18731 break;
2e6be59c 18732
a6e9f9df
AM
18733 case ODK_PAD:
18734 fputs (" PAD ", stdout);
fd17d1e6 18735 if (option.info & OPAD_PREFIX)
a6e9f9df 18736 fputs (" PREFIX", stdout);
fd17d1e6 18737 if (option.info & OPAD_POSTFIX)
a6e9f9df 18738 fputs (" POSTFIX", stdout);
fd17d1e6 18739 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18740 fputs (" SYMBOL", stdout);
18741 break;
2e6be59c 18742
a6e9f9df
AM
18743 case ODK_HWPATCH:
18744 fputs (" HWPATCH ", stdout);
fd17d1e6 18745 if (option.info & OHW_R4KEOP)
a6e9f9df 18746 fputs (" R4KEOP", stdout);
fd17d1e6 18747 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18748 fputs (" R8KPFETCH", stdout);
fd17d1e6 18749 if (option.info & OHW_R5KEOP)
a6e9f9df 18750 fputs (" R5KEOP", stdout);
fd17d1e6 18751 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18752 fputs (" R5KCVTL", stdout);
18753 break;
2e6be59c 18754
a6e9f9df
AM
18755 case ODK_FILL:
18756 fputs (" FILL ", stdout);
18757 /* XXX Print content of info word? */
18758 break;
2e6be59c 18759
a6e9f9df
AM
18760 case ODK_TAGS:
18761 fputs (" TAGS ", stdout);
18762 /* XXX Print content of info word? */
18763 break;
2e6be59c 18764
a6e9f9df
AM
18765 case ODK_HWAND:
18766 fputs (" HWAND ", stdout);
fd17d1e6 18767 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18768 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18769 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18770 fputs (" R4KEOP_CLEAN", stdout);
18771 break;
2e6be59c 18772
a6e9f9df
AM
18773 case ODK_HWOR:
18774 fputs (" HWOR ", stdout);
fd17d1e6 18775 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18776 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18777 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18778 fputs (" R4KEOP_CLEAN", stdout);
18779 break;
2e6be59c 18780
a6e9f9df 18781 case ODK_GP_GROUP:
d0c4e780 18782 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18783 option.info & OGP_GROUP,
18784 (option.info & OGP_SELF) >> 16);
a6e9f9df 18785 break;
2e6be59c 18786
a6e9f9df 18787 case ODK_IDENT:
d0c4e780 18788 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18789 option.info & OGP_GROUP,
18790 (option.info & OGP_SELF) >> 16);
a6e9f9df 18791 break;
2e6be59c 18792
a6e9f9df
AM
18793 default:
18794 /* This shouldn't happen. */
d0c4e780 18795 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18796 option.kind, option.section, option.info);
a6e9f9df 18797 break;
252b5132 18798 }
a6e9f9df 18799
2cf0635d 18800 len = sizeof (* eopt);
fd17d1e6 18801 while (len < option.size)
82b1b41b 18802 {
fd17d1e6 18803 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18804
82b1b41b
NC
18805 if (ISPRINT (datum))
18806 printf ("%c", datum);
18807 else
18808 printf ("\\%03o", datum);
18809 len ++;
18810 }
a6e9f9df 18811 fputs ("\n", stdout);
82b1b41b 18812
fd17d1e6 18813 offset += option.size;
252b5132 18814 }
a6e9f9df 18815 free (eopt);
252b5132 18816 }
32ec8896 18817 else
015dc7e1 18818 res = false;
252b5132
RH
18819 }
18820
18821 if (conflicts_offset != 0 && conflictsno != 0)
18822 {
2cf0635d 18823 Elf32_Conflict * iconf;
252b5132
RH
18824 size_t cnt;
18825
978c4450 18826 if (filedata->dynamic_symbols == NULL)
252b5132 18827 {
591a748a 18828 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18829 return false;
252b5132
RH
18830 }
18831
7296a62a
NC
18832 /* PR 21345 - print a slightly more helpful error message
18833 if we are sure that the cmalloc will fail. */
645f43a8 18834 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18835 {
18836 error (_("Overlarge number of conflicts detected: %lx\n"),
18837 (long) conflictsno);
015dc7e1 18838 return false;
7296a62a
NC
18839 }
18840
3f5e193b 18841 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18842 if (iconf == NULL)
18843 {
8b73c356 18844 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18845 return false;
252b5132
RH
18846 }
18847
9ea033b2 18848 if (is_32bit_elf)
252b5132 18849 {
2cf0635d 18850 Elf32_External_Conflict * econf32;
a6e9f9df 18851
3f5e193b 18852 econf32 = (Elf32_External_Conflict *)
95099889
AM
18853 get_data (NULL, filedata, conflicts_offset,
18854 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18855 if (!econf32)
5a814d6d
AM
18856 {
18857 free (iconf);
015dc7e1 18858 return false;
5a814d6d 18859 }
252b5132
RH
18860
18861 for (cnt = 0; cnt < conflictsno; ++cnt)
18862 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18863
18864 free (econf32);
252b5132
RH
18865 }
18866 else
18867 {
2cf0635d 18868 Elf64_External_Conflict * econf64;
a6e9f9df 18869
3f5e193b 18870 econf64 = (Elf64_External_Conflict *)
95099889
AM
18871 get_data (NULL, filedata, conflicts_offset,
18872 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18873 if (!econf64)
5a814d6d
AM
18874 {
18875 free (iconf);
015dc7e1 18876 return false;
5a814d6d 18877 }
252b5132
RH
18878
18879 for (cnt = 0; cnt < conflictsno; ++cnt)
18880 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18881
18882 free (econf64);
252b5132
RH
18883 }
18884
d3a49aa8
AM
18885 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18886 "\nSection '.conflict' contains %lu entries:\n",
18887 (unsigned long) conflictsno),
c7e7ca54 18888 (unsigned long) conflictsno);
252b5132
RH
18889 puts (_(" Num: Index Value Name"));
18890
18891 for (cnt = 0; cnt < conflictsno; ++cnt)
18892 {
b34976b6 18893 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18894
978c4450 18895 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18896 printf (_("<corrupt symbol index>"));
d79b3d50 18897 else
e0a31db1
NC
18898 {
18899 Elf_Internal_Sym * psym;
18900
978c4450 18901 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18902 print_vma (psym->st_value, FULL_HEX);
18903 putchar (' ');
84714f86
AM
18904 if (valid_dynamic_name (filedata, psym->st_name))
18905 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18906 else
18907 printf (_("<corrupt: %14ld>"), psym->st_name);
18908 }
31104126 18909 putchar ('\n');
252b5132
RH
18910 }
18911
252b5132
RH
18912 free (iconf);
18913 }
18914
ccb4c951
RS
18915 if (pltgot != 0 && local_gotno != 0)
18916 {
625d49fc 18917 uint64_t ent, local_end, global_end;
bbeee7ea 18918 size_t i, offset;
2cf0635d 18919 unsigned char * data;
82b1b41b 18920 unsigned char * data_end;
bbeee7ea 18921 int addr_size;
ccb4c951 18922
91d6fa6a 18923 ent = pltgot;
ccb4c951
RS
18924 addr_size = (is_32bit_elf ? 4 : 8);
18925 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18926
74e1a04b
NC
18927 /* PR binutils/17533 file: 012-111227-0.004 */
18928 if (symtabno < gotsym)
18929 {
18930 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18931 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18932 return false;
74e1a04b 18933 }
82b1b41b 18934
74e1a04b 18935 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18936 /* PR 17531: file: 54c91a34. */
18937 if (global_end < local_end)
18938 {
18939 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18940 return false;
82b1b41b 18941 }
948f632f 18942
dda8d76d
NC
18943 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18944 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18945 global_end - pltgot, 1,
18946 _("Global Offset Table data"));
919383ac 18947 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18948 data_end = data + (global_end - pltgot);
59245841 18949
ccb4c951
RS
18950 printf (_("\nPrimary GOT:\n"));
18951 printf (_(" Canonical gp value: "));
18952 print_vma (pltgot + 0x7ff0, LONG_HEX);
18953 printf ("\n\n");
18954
18955 printf (_(" Reserved entries:\n"));
18956 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18957 addr_size * 2, _("Address"), _("Access"),
18958 addr_size * 2, _("Initial"));
82b1b41b 18959 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18960 printf (_(" Lazy resolver\n"));
625d49fc 18961 if (ent == (uint64_t) -1)
82b1b41b 18962 goto got_print_fail;
75ec1fdb 18963
c4ab9505
MR
18964 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18965 This entry will be used by some runtime loaders, to store the
18966 module pointer. Otherwise this is an ordinary local entry.
18967 PR 21344: Check for the entry being fully available before
18968 fetching it. */
18969 if (data
18970 && data + ent - pltgot + addr_size <= data_end
18971 && (byte_get (data + ent - pltgot, addr_size)
18972 >> (addr_size * 8 - 1)) != 0)
18973 {
18974 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18975 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 18976 if (ent == (uint64_t) -1)
c4ab9505 18977 goto got_print_fail;
ccb4c951
RS
18978 }
18979 printf ("\n");
18980
f17e9d8a 18981 if (data != NULL && ent < local_end)
ccb4c951
RS
18982 {
18983 printf (_(" Local entries:\n"));
cc5914eb 18984 printf (" %*s %10s %*s\n",
2b692964
NC
18985 addr_size * 2, _("Address"), _("Access"),
18986 addr_size * 2, _("Initial"));
91d6fa6a 18987 while (ent < local_end)
ccb4c951 18988 {
82b1b41b 18989 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18990 printf ("\n");
625d49fc 18991 if (ent == (uint64_t) -1)
82b1b41b 18992 goto got_print_fail;
ccb4c951
RS
18993 }
18994 printf ("\n");
18995 }
18996
f17e9d8a 18997 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18998 {
18999 int sym_width;
19000
19001 printf (_(" Global entries:\n"));
cc5914eb 19002 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19003 addr_size * 2, _("Address"),
19004 _("Access"),
2b692964 19005 addr_size * 2, _("Initial"),
9cf03b7e
NC
19006 addr_size * 2, _("Sym.Val."),
19007 _("Type"),
19008 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19009 _("Ndx"), _("Name"));
0b4362b0 19010
ccb4c951 19011 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19012
ccb4c951
RS
19013 for (i = gotsym; i < symtabno; i++)
19014 {
82b1b41b 19015 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19016 printf (" ");
e0a31db1 19017
978c4450 19018 if (filedata->dynamic_symbols == NULL)
e0a31db1 19019 printf (_("<no dynamic symbols>"));
978c4450 19020 else if (i < filedata->num_dynamic_syms)
e0a31db1 19021 {
978c4450 19022 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19023
19024 print_vma (psym->st_value, LONG_HEX);
19025 printf (" %-7s %3s ",
dda8d76d
NC
19026 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19027 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 19028
84714f86 19029 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19030 print_symbol (sym_width,
84714f86 19031 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19032 else
19033 printf (_("<corrupt: %14ld>"), psym->st_name);
19034 }
ccb4c951 19035 else
7fc5ac57
JBG
19036 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
19037 (unsigned long) i);
e0a31db1 19038
ccb4c951 19039 printf ("\n");
625d49fc 19040 if (ent == (uint64_t) -1)
82b1b41b 19041 break;
ccb4c951
RS
19042 }
19043 printf ("\n");
19044 }
19045
82b1b41b 19046 got_print_fail:
9db70fc3 19047 free (data);
ccb4c951
RS
19048 }
19049
861fb55a
DJ
19050 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19051 {
625d49fc 19052 uint64_t ent, end;
861fb55a
DJ
19053 size_t offset, rel_offset;
19054 unsigned long count, i;
2cf0635d 19055 unsigned char * data;
861fb55a 19056 int addr_size, sym_width;
2cf0635d 19057 Elf_Internal_Rela * rels;
861fb55a 19058
dda8d76d 19059 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19060 if (pltrel == DT_RELA)
19061 {
dda8d76d 19062 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19063 return false;
861fb55a
DJ
19064 }
19065 else
19066 {
dda8d76d 19067 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19068 return false;
861fb55a
DJ
19069 }
19070
91d6fa6a 19071 ent = mips_pltgot;
861fb55a
DJ
19072 addr_size = (is_32bit_elf ? 4 : 8);
19073 end = mips_pltgot + (2 + count) * addr_size;
19074
dda8d76d
NC
19075 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19076 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19077 1, _("Procedure Linkage Table data"));
59245841 19078 if (data == NULL)
288f0ba2
AM
19079 {
19080 free (rels);
015dc7e1 19081 return false;
288f0ba2 19082 }
59245841 19083
9cf03b7e 19084 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19085 printf (_(" Reserved entries:\n"));
19086 printf (_(" %*s %*s Purpose\n"),
2b692964 19087 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19088 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19089 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19090 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19091 printf (_(" Module pointer\n"));
861fb55a
DJ
19092 printf ("\n");
19093
19094 printf (_(" Entries:\n"));
cc5914eb 19095 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19096 addr_size * 2, _("Address"),
19097 addr_size * 2, _("Initial"),
19098 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19099 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19100 for (i = 0; i < count; i++)
19101 {
df97ab2a 19102 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19103
91d6fa6a 19104 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19105 printf (" ");
e0a31db1 19106
978c4450 19107 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19108 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19109 else
e0a31db1 19110 {
978c4450 19111 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19112
19113 print_vma (psym->st_value, LONG_HEX);
19114 printf (" %-7s %3s ",
dda8d76d
NC
19115 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19116 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19117 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19118 print_symbol (sym_width,
84714f86 19119 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19120 else
19121 printf (_("<corrupt: %14ld>"), psym->st_name);
19122 }
861fb55a
DJ
19123 printf ("\n");
19124 }
19125 printf ("\n");
19126
9db70fc3 19127 free (data);
861fb55a
DJ
19128 free (rels);
19129 }
19130
32ec8896 19131 return res;
252b5132
RH
19132}
19133
015dc7e1 19134static bool
dda8d76d 19135process_nds32_specific (Filedata * filedata)
35c08157
KLC
19136{
19137 Elf_Internal_Shdr *sect = NULL;
19138
dda8d76d 19139 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19140 if (sect != NULL && sect->sh_size >= 4)
35c08157 19141 {
9c7b8e9b
AM
19142 unsigned char *buf;
19143 unsigned int flag;
35c08157
KLC
19144
19145 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19146 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19147 _("NDS32 elf flags section"));
35c08157 19148
9c7b8e9b 19149 if (buf == NULL)
015dc7e1 19150 return false;
32ec8896 19151
9c7b8e9b
AM
19152 flag = byte_get (buf, 4);
19153 free (buf);
19154 switch (flag & 0x3)
35c08157
KLC
19155 {
19156 case 0:
19157 printf ("(VEC_SIZE):\tNo entry.\n");
19158 break;
19159 case 1:
19160 printf ("(VEC_SIZE):\t4 bytes\n");
19161 break;
19162 case 2:
19163 printf ("(VEC_SIZE):\t16 bytes\n");
19164 break;
19165 case 3:
19166 printf ("(VEC_SIZE):\treserved\n");
19167 break;
19168 }
19169 }
19170
015dc7e1 19171 return true;
35c08157
KLC
19172}
19173
015dc7e1 19174static bool
dda8d76d 19175process_gnu_liblist (Filedata * filedata)
047b2264 19176{
2cf0635d
NC
19177 Elf_Internal_Shdr * section;
19178 Elf_Internal_Shdr * string_sec;
19179 Elf32_External_Lib * elib;
19180 char * strtab;
c256ffe7 19181 size_t strtab_size;
047b2264 19182 size_t cnt;
d3a49aa8 19183 unsigned long num_liblist;
047b2264 19184 unsigned i;
015dc7e1 19185 bool res = true;
047b2264
JJ
19186
19187 if (! do_arch)
015dc7e1 19188 return true;
047b2264 19189
dda8d76d
NC
19190 for (i = 0, section = filedata->section_headers;
19191 i < filedata->file_header.e_shnum;
b34976b6 19192 i++, section++)
047b2264
JJ
19193 {
19194 switch (section->sh_type)
19195 {
19196 case SHT_GNU_LIBLIST:
dda8d76d 19197 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19198 break;
19199
3f5e193b 19200 elib = (Elf32_External_Lib *)
dda8d76d 19201 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19202 _("liblist section data"));
047b2264
JJ
19203
19204 if (elib == NULL)
32ec8896 19205 {
015dc7e1 19206 res = false;
32ec8896
NC
19207 break;
19208 }
047b2264 19209
dda8d76d
NC
19210 string_sec = filedata->section_headers + section->sh_link;
19211 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19212 string_sec->sh_size,
19213 _("liblist string table"));
047b2264
JJ
19214 if (strtab == NULL
19215 || section->sh_entsize != sizeof (Elf32_External_Lib))
19216 {
19217 free (elib);
2842702f 19218 free (strtab);
015dc7e1 19219 res = false;
047b2264
JJ
19220 break;
19221 }
59245841 19222 strtab_size = string_sec->sh_size;
047b2264 19223
d3a49aa8
AM
19224 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19225 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19226 "\nLibrary list section '%s' contains %lu entries:\n",
19227 num_liblist),
dda8d76d 19228 printable_section_name (filedata, section),
d3a49aa8 19229 num_liblist);
047b2264 19230
2b692964 19231 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19232
19233 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19234 ++cnt)
19235 {
19236 Elf32_Lib liblist;
91d6fa6a 19237 time_t atime;
d5b07ef4 19238 char timebuf[128];
2cf0635d 19239 struct tm * tmp;
047b2264
JJ
19240
19241 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19242 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19243 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19244 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19245 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19246
91d6fa6a 19247 tmp = gmtime (&atime);
e9e44622
JJ
19248 snprintf (timebuf, sizeof (timebuf),
19249 "%04u-%02u-%02uT%02u:%02u:%02u",
19250 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19251 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19252
19253 printf ("%3lu: ", (unsigned long) cnt);
19254 if (do_wide)
c256ffe7 19255 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19256 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19257 else
c256ffe7 19258 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19259 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19260 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19261 liblist.l_version, liblist.l_flags);
19262 }
19263
19264 free (elib);
2842702f 19265 free (strtab);
047b2264
JJ
19266 }
19267 }
19268
32ec8896 19269 return res;
047b2264
JJ
19270}
19271
9437c45b 19272static const char *
dda8d76d 19273get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19274{
19275 static char buff[64];
103f02d3 19276
dda8d76d 19277 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19278 switch (e_type)
19279 {
57346661 19280 case NT_AUXV:
1ec5cd37 19281 return _("NT_AUXV (auxiliary vector)");
57346661 19282 case NT_PRSTATUS:
1ec5cd37 19283 return _("NT_PRSTATUS (prstatus structure)");
57346661 19284 case NT_FPREGSET:
1ec5cd37 19285 return _("NT_FPREGSET (floating point registers)");
57346661 19286 case NT_PRPSINFO:
1ec5cd37 19287 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19288 case NT_TASKSTRUCT:
1ec5cd37 19289 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19290 case NT_GDB_TDESC:
19291 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19292 case NT_PRXFPREG:
1ec5cd37 19293 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19294 case NT_PPC_VMX:
19295 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19296 case NT_PPC_VSX:
19297 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19298 case NT_PPC_TAR:
19299 return _("NT_PPC_TAR (ppc TAR register)");
19300 case NT_PPC_PPR:
19301 return _("NT_PPC_PPR (ppc PPR register)");
19302 case NT_PPC_DSCR:
19303 return _("NT_PPC_DSCR (ppc DSCR register)");
19304 case NT_PPC_EBB:
19305 return _("NT_PPC_EBB (ppc EBB registers)");
19306 case NT_PPC_PMU:
19307 return _("NT_PPC_PMU (ppc PMU registers)");
19308 case NT_PPC_TM_CGPR:
19309 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19310 case NT_PPC_TM_CFPR:
19311 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19312 case NT_PPC_TM_CVMX:
19313 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19314 case NT_PPC_TM_CVSX:
3fd21718 19315 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19316 case NT_PPC_TM_SPR:
19317 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19318 case NT_PPC_TM_CTAR:
19319 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19320 case NT_PPC_TM_CPPR:
19321 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19322 case NT_PPC_TM_CDSCR:
19323 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19324 case NT_386_TLS:
19325 return _("NT_386_TLS (x86 TLS information)");
19326 case NT_386_IOPERM:
19327 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19328 case NT_X86_XSTATE:
19329 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19330 case NT_X86_CET:
19331 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19332 case NT_S390_HIGH_GPRS:
19333 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19334 case NT_S390_TIMER:
19335 return _("NT_S390_TIMER (s390 timer register)");
19336 case NT_S390_TODCMP:
19337 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19338 case NT_S390_TODPREG:
19339 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19340 case NT_S390_CTRS:
19341 return _("NT_S390_CTRS (s390 control registers)");
19342 case NT_S390_PREFIX:
19343 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19344 case NT_S390_LAST_BREAK:
19345 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19346 case NT_S390_SYSTEM_CALL:
19347 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19348 case NT_S390_TDB:
19349 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19350 case NT_S390_VXRS_LOW:
19351 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19352 case NT_S390_VXRS_HIGH:
19353 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19354 case NT_S390_GS_CB:
19355 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19356 case NT_S390_GS_BC:
19357 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19358 case NT_ARM_VFP:
19359 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19360 case NT_ARM_TLS:
19361 return _("NT_ARM_TLS (AArch TLS registers)");
19362 case NT_ARM_HW_BREAK:
19363 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19364 case NT_ARM_HW_WATCH:
19365 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19366 case NT_ARM_SYSTEM_CALL:
19367 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19368 case NT_ARM_SVE:
19369 return _("NT_ARM_SVE (AArch SVE registers)");
19370 case NT_ARM_PAC_MASK:
19371 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19372 case NT_ARM_PACA_KEYS:
19373 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19374 case NT_ARM_PACG_KEYS:
19375 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19376 case NT_ARM_TAGGED_ADDR_CTRL:
19377 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19378 case NT_ARM_PAC_ENABLED_KEYS:
19379 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19380 case NT_ARC_V2:
19381 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19382 case NT_RISCV_CSR:
19383 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19384 case NT_PSTATUS:
1ec5cd37 19385 return _("NT_PSTATUS (pstatus structure)");
57346661 19386 case NT_FPREGS:
1ec5cd37 19387 return _("NT_FPREGS (floating point registers)");
57346661 19388 case NT_PSINFO:
1ec5cd37 19389 return _("NT_PSINFO (psinfo structure)");
57346661 19390 case NT_LWPSTATUS:
1ec5cd37 19391 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19392 case NT_LWPSINFO:
1ec5cd37 19393 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19394 case NT_WIN32PSTATUS:
1ec5cd37 19395 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19396 case NT_SIGINFO:
19397 return _("NT_SIGINFO (siginfo_t data)");
19398 case NT_FILE:
19399 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19400 default:
19401 break;
19402 }
19403 else
19404 switch (e_type)
19405 {
19406 case NT_VERSION:
19407 return _("NT_VERSION (version)");
19408 case NT_ARCH:
19409 return _("NT_ARCH (architecture)");
9ef920e9 19410 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19411 return _("OPEN");
9ef920e9 19412 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19413 return _("func");
c8795e1f
NC
19414 case NT_GO_BUILDID:
19415 return _("GO BUILDID");
3ac925fc
LB
19416 case FDO_PACKAGING_METADATA:
19417 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19418 default:
19419 break;
19420 }
19421
e9e44622 19422 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19423 return buff;
779fe533
NC
19424}
19425
015dc7e1 19426static bool
9ece1fa9
TT
19427print_core_note (Elf_Internal_Note *pnote)
19428{
19429 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19430 uint64_t count, page_size;
9ece1fa9
TT
19431 unsigned char *descdata, *filenames, *descend;
19432
19433 if (pnote->type != NT_FILE)
04ac15ab
AS
19434 {
19435 if (do_wide)
19436 printf ("\n");
015dc7e1 19437 return true;
04ac15ab 19438 }
9ece1fa9 19439
9ece1fa9
TT
19440 if (!is_32bit_elf)
19441 {
19442 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19443 /* Still "successful". */
015dc7e1 19444 return true;
9ece1fa9 19445 }
9ece1fa9
TT
19446
19447 if (pnote->descsz < 2 * addr_size)
19448 {
32ec8896 19449 error (_(" Malformed note - too short for header\n"));
015dc7e1 19450 return false;
9ece1fa9
TT
19451 }
19452
19453 descdata = (unsigned char *) pnote->descdata;
19454 descend = descdata + pnote->descsz;
19455
19456 if (descdata[pnote->descsz - 1] != '\0')
19457 {
32ec8896 19458 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19459 return false;
9ece1fa9
TT
19460 }
19461
19462 count = byte_get (descdata, addr_size);
19463 descdata += addr_size;
19464
19465 page_size = byte_get (descdata, addr_size);
19466 descdata += addr_size;
19467
625d49fc 19468 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19469 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19470 {
32ec8896 19471 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19472 return false;
9ece1fa9
TT
19473 }
19474
19475 printf (_(" Page size: "));
19476 print_vma (page_size, DEC);
19477 printf ("\n");
19478
19479 printf (_(" %*s%*s%*s\n"),
19480 (int) (2 + 2 * addr_size), _("Start"),
19481 (int) (4 + 2 * addr_size), _("End"),
19482 (int) (4 + 2 * addr_size), _("Page Offset"));
19483 filenames = descdata + count * 3 * addr_size;
595712bb 19484 while (count-- > 0)
9ece1fa9 19485 {
625d49fc 19486 uint64_t start, end, file_ofs;
9ece1fa9
TT
19487
19488 if (filenames == descend)
19489 {
32ec8896 19490 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19491 return false;
9ece1fa9
TT
19492 }
19493
19494 start = byte_get (descdata, addr_size);
19495 descdata += addr_size;
19496 end = byte_get (descdata, addr_size);
19497 descdata += addr_size;
19498 file_ofs = byte_get (descdata, addr_size);
19499 descdata += addr_size;
19500
19501 printf (" ");
19502 print_vma (start, FULL_HEX);
19503 printf (" ");
19504 print_vma (end, FULL_HEX);
19505 printf (" ");
19506 print_vma (file_ofs, FULL_HEX);
19507 printf ("\n %s\n", filenames);
19508
19509 filenames += 1 + strlen ((char *) filenames);
19510 }
19511
015dc7e1 19512 return true;
9ece1fa9
TT
19513}
19514
1118d252
RM
19515static const char *
19516get_gnu_elf_note_type (unsigned e_type)
19517{
1449284b 19518 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19519 switch (e_type)
19520 {
19521 case NT_GNU_ABI_TAG:
19522 return _("NT_GNU_ABI_TAG (ABI version tag)");
19523 case NT_GNU_HWCAP:
19524 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19525 case NT_GNU_BUILD_ID:
19526 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19527 case NT_GNU_GOLD_VERSION:
19528 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19529 case NT_GNU_PROPERTY_TYPE_0:
19530 return _("NT_GNU_PROPERTY_TYPE_0");
19531 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19532 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19533 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19534 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19535 default:
1449284b
NC
19536 {
19537 static char buff[64];
1118d252 19538
1449284b
NC
19539 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19540 return buff;
19541 }
19542 }
1118d252
RM
19543}
19544
a9eafb08
L
19545static void
19546decode_x86_compat_isa (unsigned int bitmask)
19547{
19548 while (bitmask)
19549 {
19550 unsigned int bit = bitmask & (- bitmask);
19551
19552 bitmask &= ~ bit;
19553 switch (bit)
19554 {
19555 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19556 printf ("i486");
19557 break;
19558 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19559 printf ("586");
19560 break;
19561 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19562 printf ("686");
19563 break;
19564 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19565 printf ("SSE");
19566 break;
19567 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19568 printf ("SSE2");
19569 break;
19570 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19571 printf ("SSE3");
19572 break;
19573 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19574 printf ("SSSE3");
19575 break;
19576 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19577 printf ("SSE4_1");
19578 break;
19579 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19580 printf ("SSE4_2");
19581 break;
19582 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19583 printf ("AVX");
19584 break;
19585 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19586 printf ("AVX2");
19587 break;
19588 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19589 printf ("AVX512F");
19590 break;
19591 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19592 printf ("AVX512CD");
19593 break;
19594 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19595 printf ("AVX512ER");
19596 break;
19597 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19598 printf ("AVX512PF");
19599 break;
19600 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19601 printf ("AVX512VL");
19602 break;
19603 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19604 printf ("AVX512DQ");
19605 break;
19606 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19607 printf ("AVX512BW");
19608 break;
65b3d26e
L
19609 default:
19610 printf (_("<unknown: %x>"), bit);
19611 break;
a9eafb08
L
19612 }
19613 if (bitmask)
19614 printf (", ");
19615 }
19616}
19617
9ef920e9 19618static void
32930e4e 19619decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19620{
0a59decb 19621 if (!bitmask)
90c745dc
L
19622 {
19623 printf (_("<None>"));
19624 return;
19625 }
90c745dc 19626
9ef920e9
NC
19627 while (bitmask)
19628 {
1fc87489 19629 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19630
19631 bitmask &= ~ bit;
19632 switch (bit)
19633 {
32930e4e 19634 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19635 printf ("CMOV");
19636 break;
32930e4e 19637 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19638 printf ("SSE");
19639 break;
32930e4e 19640 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19641 printf ("SSE2");
19642 break;
32930e4e 19643 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19644 printf ("SSE3");
19645 break;
32930e4e 19646 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19647 printf ("SSSE3");
19648 break;
32930e4e 19649 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19650 printf ("SSE4_1");
19651 break;
32930e4e 19652 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19653 printf ("SSE4_2");
19654 break;
32930e4e 19655 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19656 printf ("AVX");
19657 break;
32930e4e 19658 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19659 printf ("AVX2");
19660 break;
32930e4e 19661 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19662 printf ("FMA");
19663 break;
32930e4e 19664 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19665 printf ("AVX512F");
19666 break;
32930e4e 19667 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19668 printf ("AVX512CD");
19669 break;
32930e4e 19670 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19671 printf ("AVX512ER");
19672 break;
32930e4e 19673 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19674 printf ("AVX512PF");
19675 break;
32930e4e 19676 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19677 printf ("AVX512VL");
19678 break;
32930e4e 19679 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19680 printf ("AVX512DQ");
19681 break;
32930e4e 19682 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19683 printf ("AVX512BW");
19684 break;
32930e4e 19685 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19686 printf ("AVX512_4FMAPS");
19687 break;
32930e4e 19688 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19689 printf ("AVX512_4VNNIW");
19690 break;
32930e4e 19691 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19692 printf ("AVX512_BITALG");
19693 break;
32930e4e 19694 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19695 printf ("AVX512_IFMA");
19696 break;
32930e4e 19697 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19698 printf ("AVX512_VBMI");
19699 break;
32930e4e 19700 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19701 printf ("AVX512_VBMI2");
19702 break;
32930e4e 19703 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19704 printf ("AVX512_VNNI");
19705 break;
32930e4e 19706 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19707 printf ("AVX512_BF16");
19708 break;
65b3d26e
L
19709 default:
19710 printf (_("<unknown: %x>"), bit);
19711 break;
9ef920e9
NC
19712 }
19713 if (bitmask)
19714 printf (", ");
19715 }
19716}
19717
28cdbb18
SM
19718static const char *
19719get_amdgpu_elf_note_type (unsigned int e_type)
19720{
19721 switch (e_type)
19722 {
19723 case NT_AMDGPU_METADATA:
19724 return _("NT_AMDGPU_METADATA (code object metadata)");
19725 default:
19726 {
19727 static char buf[64];
19728 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19729 return buf;
19730 }
19731 }
19732}
19733
32930e4e
L
19734static void
19735decode_x86_isa (unsigned int bitmask)
19736{
32930e4e
L
19737 while (bitmask)
19738 {
19739 unsigned int bit = bitmask & (- bitmask);
19740
19741 bitmask &= ~ bit;
19742 switch (bit)
19743 {
b0ab0693
L
19744 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19745 printf ("x86-64-baseline");
19746 break;
32930e4e
L
19747 case GNU_PROPERTY_X86_ISA_1_V2:
19748 printf ("x86-64-v2");
19749 break;
19750 case GNU_PROPERTY_X86_ISA_1_V3:
19751 printf ("x86-64-v3");
19752 break;
19753 case GNU_PROPERTY_X86_ISA_1_V4:
19754 printf ("x86-64-v4");
19755 break;
19756 default:
19757 printf (_("<unknown: %x>"), bit);
19758 break;
19759 }
19760 if (bitmask)
19761 printf (", ");
19762 }
19763}
19764
ee2fdd6f 19765static void
a9eafb08 19766decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19767{
0a59decb 19768 if (!bitmask)
90c745dc
L
19769 {
19770 printf (_("<None>"));
19771 return;
19772 }
90c745dc 19773
ee2fdd6f
L
19774 while (bitmask)
19775 {
19776 unsigned int bit = bitmask & (- bitmask);
19777
19778 bitmask &= ~ bit;
19779 switch (bit)
19780 {
19781 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19782 printf ("IBT");
ee2fdd6f 19783 break;
48580982 19784 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19785 printf ("SHSTK");
48580982 19786 break;
279d901e
L
19787 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19788 printf ("LAM_U48");
19789 break;
19790 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19791 printf ("LAM_U57");
19792 break;
ee2fdd6f
L
19793 default:
19794 printf (_("<unknown: %x>"), bit);
19795 break;
19796 }
19797 if (bitmask)
19798 printf (", ");
19799 }
19800}
19801
a9eafb08
L
19802static void
19803decode_x86_feature_2 (unsigned int bitmask)
19804{
0a59decb 19805 if (!bitmask)
90c745dc
L
19806 {
19807 printf (_("<None>"));
19808 return;
19809 }
90c745dc 19810
a9eafb08
L
19811 while (bitmask)
19812 {
19813 unsigned int bit = bitmask & (- bitmask);
19814
19815 bitmask &= ~ bit;
19816 switch (bit)
19817 {
19818 case GNU_PROPERTY_X86_FEATURE_2_X86:
19819 printf ("x86");
19820 break;
19821 case GNU_PROPERTY_X86_FEATURE_2_X87:
19822 printf ("x87");
19823 break;
19824 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19825 printf ("MMX");
19826 break;
19827 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19828 printf ("XMM");
19829 break;
19830 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19831 printf ("YMM");
19832 break;
19833 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19834 printf ("ZMM");
19835 break;
a308b89d
L
19836 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19837 printf ("TMM");
19838 break;
32930e4e
L
19839 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19840 printf ("MASK");
19841 break;
a9eafb08
L
19842 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19843 printf ("FXSR");
19844 break;
19845 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19846 printf ("XSAVE");
19847 break;
19848 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19849 printf ("XSAVEOPT");
19850 break;
19851 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19852 printf ("XSAVEC");
19853 break;
65b3d26e
L
19854 default:
19855 printf (_("<unknown: %x>"), bit);
19856 break;
a9eafb08
L
19857 }
19858 if (bitmask)
19859 printf (", ");
19860 }
19861}
19862
cd702818
SD
19863static void
19864decode_aarch64_feature_1_and (unsigned int bitmask)
19865{
19866 while (bitmask)
19867 {
19868 unsigned int bit = bitmask & (- bitmask);
19869
19870 bitmask &= ~ bit;
19871 switch (bit)
19872 {
19873 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19874 printf ("BTI");
19875 break;
19876
19877 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19878 printf ("PAC");
19879 break;
19880
19881 default:
19882 printf (_("<unknown: %x>"), bit);
19883 break;
19884 }
19885 if (bitmask)
19886 printf (", ");
19887 }
19888}
19889
6320fd00
L
19890static void
19891decode_1_needed (unsigned int bitmask)
19892{
19893 while (bitmask)
19894 {
19895 unsigned int bit = bitmask & (- bitmask);
19896
19897 bitmask &= ~ bit;
19898 switch (bit)
19899 {
19900 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19901 printf ("indirect external access");
19902 break;
19903 default:
19904 printf (_("<unknown: %x>"), bit);
19905 break;
19906 }
19907 if (bitmask)
19908 printf (", ");
19909 }
19910}
19911
9ef920e9 19912static void
dda8d76d 19913print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19914{
19915 unsigned char * ptr = (unsigned char *) pnote->descdata;
19916 unsigned char * ptr_end = ptr + pnote->descsz;
19917 unsigned int size = is_32bit_elf ? 4 : 8;
19918
19919 printf (_(" Properties: "));
19920
1fc87489 19921 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19922 {
19923 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19924 return;
19925 }
19926
6ab2c4ed 19927 while (ptr < ptr_end)
9ef920e9 19928 {
1fc87489 19929 unsigned int j;
6ab2c4ed
MC
19930 unsigned int type;
19931 unsigned int datasz;
19932
19933 if ((size_t) (ptr_end - ptr) < 8)
19934 {
19935 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19936 break;
19937 }
19938
19939 type = byte_get (ptr, 4);
19940 datasz = byte_get (ptr + 4, 4);
9ef920e9 19941
1fc87489 19942 ptr += 8;
9ef920e9 19943
6ab2c4ed 19944 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19945 {
1fc87489
L
19946 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19947 type, datasz);
9ef920e9 19948 break;
1fc87489 19949 }
9ef920e9 19950
1fc87489
L
19951 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19952 {
dda8d76d
NC
19953 if (filedata->file_header.e_machine == EM_X86_64
19954 || filedata->file_header.e_machine == EM_IAMCU
19955 || filedata->file_header.e_machine == EM_386)
1fc87489 19956 {
aa7bca9b
L
19957 unsigned int bitmask;
19958
19959 if (datasz == 4)
0a59decb 19960 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19961 else
19962 bitmask = 0;
19963
1fc87489
L
19964 switch (type)
19965 {
19966 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19967 if (datasz != 4)
aa7bca9b
L
19968 printf (_("x86 ISA used: <corrupt length: %#x> "),
19969 datasz);
1fc87489 19970 else
aa7bca9b
L
19971 {
19972 printf ("x86 ISA used: ");
19973 decode_x86_isa (bitmask);
19974 }
1fc87489 19975 goto next;
9ef920e9 19976
1fc87489 19977 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19978 if (datasz != 4)
aa7bca9b
L
19979 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19980 datasz);
1fc87489 19981 else
aa7bca9b
L
19982 {
19983 printf ("x86 ISA needed: ");
19984 decode_x86_isa (bitmask);
19985 }
1fc87489 19986 goto next;
9ef920e9 19987
ee2fdd6f 19988 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19989 if (datasz != 4)
aa7bca9b
L
19990 printf (_("x86 feature: <corrupt length: %#x> "),
19991 datasz);
ee2fdd6f 19992 else
aa7bca9b
L
19993 {
19994 printf ("x86 feature: ");
a9eafb08
L
19995 decode_x86_feature_1 (bitmask);
19996 }
19997 goto next;
19998
19999 case GNU_PROPERTY_X86_FEATURE_2_USED:
20000 if (datasz != 4)
20001 printf (_("x86 feature used: <corrupt length: %#x> "),
20002 datasz);
20003 else
20004 {
20005 printf ("x86 feature used: ");
20006 decode_x86_feature_2 (bitmask);
20007 }
20008 goto next;
20009
20010 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20011 if (datasz != 4)
20012 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20013 else
20014 {
20015 printf ("x86 feature needed: ");
20016 decode_x86_feature_2 (bitmask);
20017 }
20018 goto next;
20019
20020 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20021 if (datasz != 4)
20022 printf (_("x86 ISA used: <corrupt length: %#x> "),
20023 datasz);
20024 else
20025 {
20026 printf ("x86 ISA used: ");
20027 decode_x86_compat_isa (bitmask);
20028 }
20029 goto next;
20030
20031 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20032 if (datasz != 4)
20033 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20034 datasz);
20035 else
20036 {
20037 printf ("x86 ISA needed: ");
20038 decode_x86_compat_isa (bitmask);
aa7bca9b 20039 }
ee2fdd6f
L
20040 goto next;
20041
32930e4e
L
20042 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20043 if (datasz != 4)
20044 printf (_("x86 ISA used: <corrupt length: %#x> "),
20045 datasz);
20046 else
20047 {
20048 printf ("x86 ISA used: ");
20049 decode_x86_compat_2_isa (bitmask);
20050 }
20051 goto next;
20052
20053 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20054 if (datasz != 4)
20055 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20056 datasz);
20057 else
20058 {
20059 printf ("x86 ISA needed: ");
20060 decode_x86_compat_2_isa (bitmask);
20061 }
20062 goto next;
20063
1fc87489
L
20064 default:
20065 break;
20066 }
20067 }
cd702818
SD
20068 else if (filedata->file_header.e_machine == EM_AARCH64)
20069 {
20070 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20071 {
20072 printf ("AArch64 feature: ");
20073 if (datasz != 4)
20074 printf (_("<corrupt length: %#x> "), datasz);
20075 else
20076 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20077 goto next;
20078 }
20079 }
1fc87489
L
20080 }
20081 else
20082 {
20083 switch (type)
9ef920e9 20084 {
1fc87489
L
20085 case GNU_PROPERTY_STACK_SIZE:
20086 printf (_("stack size: "));
20087 if (datasz != size)
20088 printf (_("<corrupt length: %#x> "), datasz);
20089 else
20090 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20091 goto next;
20092
20093 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20094 printf ("no copy on protected ");
20095 if (datasz)
20096 printf (_("<corrupt length: %#x> "), datasz);
20097 goto next;
20098
20099 default:
5a767724
L
20100 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20101 && type <= GNU_PROPERTY_UINT32_AND_HI)
20102 || (type >= GNU_PROPERTY_UINT32_OR_LO
20103 && type <= GNU_PROPERTY_UINT32_OR_HI))
20104 {
6320fd00
L
20105 switch (type)
20106 {
20107 case GNU_PROPERTY_1_NEEDED:
20108 if (datasz != 4)
20109 printf (_("1_needed: <corrupt length: %#x> "),
20110 datasz);
20111 else
20112 {
20113 unsigned int bitmask = byte_get (ptr, 4);
20114 printf ("1_needed: ");
20115 decode_1_needed (bitmask);
20116 }
20117 goto next;
20118
20119 default:
20120 break;
20121 }
5a767724
L
20122 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20123 printf (_("UINT32_AND (%#x): "), type);
20124 else
20125 printf (_("UINT32_OR (%#x): "), type);
20126 if (datasz != 4)
20127 printf (_("<corrupt length: %#x> "), datasz);
20128 else
20129 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20130 goto next;
20131 }
9ef920e9
NC
20132 break;
20133 }
9ef920e9
NC
20134 }
20135
1fc87489
L
20136 if (type < GNU_PROPERTY_LOPROC)
20137 printf (_("<unknown type %#x data: "), type);
20138 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20139 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20140 else
20141 printf (_("<application-specific type %#x data: "), type);
20142 for (j = 0; j < datasz; ++j)
20143 printf ("%02x ", ptr[j] & 0xff);
20144 printf (">");
20145
dc1e8a47 20146 next:
9ef920e9 20147 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20148 if (ptr == ptr_end)
20149 break;
1fc87489 20150
6ab2c4ed
MC
20151 if (do_wide)
20152 printf (", ");
20153 else
20154 printf ("\n\t");
9ef920e9
NC
20155 }
20156
20157 printf ("\n");
20158}
20159
015dc7e1 20160static bool
dda8d76d 20161print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20162{
1449284b 20163 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20164 switch (pnote->type)
20165 {
20166 case NT_GNU_BUILD_ID:
20167 {
20168 unsigned long i;
20169
20170 printf (_(" Build ID: "));
20171 for (i = 0; i < pnote->descsz; ++i)
20172 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20173 printf ("\n");
664f90a3
TT
20174 }
20175 break;
20176
20177 case NT_GNU_ABI_TAG:
20178 {
20179 unsigned long os, major, minor, subminor;
20180 const char *osname;
20181
3102e897
NC
20182 /* PR 17531: file: 030-599401-0.004. */
20183 if (pnote->descsz < 16)
20184 {
20185 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20186 break;
20187 }
20188
664f90a3
TT
20189 os = byte_get ((unsigned char *) pnote->descdata, 4);
20190 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20191 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20192 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20193
20194 switch (os)
20195 {
20196 case GNU_ABI_TAG_LINUX:
20197 osname = "Linux";
20198 break;
20199 case GNU_ABI_TAG_HURD:
20200 osname = "Hurd";
20201 break;
20202 case GNU_ABI_TAG_SOLARIS:
20203 osname = "Solaris";
20204 break;
20205 case GNU_ABI_TAG_FREEBSD:
20206 osname = "FreeBSD";
20207 break;
20208 case GNU_ABI_TAG_NETBSD:
20209 osname = "NetBSD";
20210 break;
14ae95f2
RM
20211 case GNU_ABI_TAG_SYLLABLE:
20212 osname = "Syllable";
20213 break;
20214 case GNU_ABI_TAG_NACL:
20215 osname = "NaCl";
20216 break;
664f90a3
TT
20217 default:
20218 osname = "Unknown";
20219 break;
20220 }
20221
20222 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20223 major, minor, subminor);
20224 }
20225 break;
926c5385
CC
20226
20227 case NT_GNU_GOLD_VERSION:
20228 {
20229 unsigned long i;
20230
20231 printf (_(" Version: "));
20232 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20233 printf ("%c", pnote->descdata[i]);
20234 printf ("\n");
20235 }
20236 break;
1449284b
NC
20237
20238 case NT_GNU_HWCAP:
20239 {
20240 unsigned long num_entries, mask;
20241
20242 /* Hardware capabilities information. Word 0 is the number of entries.
20243 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20244 is a series of entries, where each entry is a single byte followed
20245 by a nul terminated string. The byte gives the bit number to test
20246 if enabled in the bitmask. */
20247 printf (_(" Hardware Capabilities: "));
20248 if (pnote->descsz < 8)
20249 {
32ec8896 20250 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20251 return false;
1449284b
NC
20252 }
20253 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20254 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20255 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20256 /* FIXME: Add code to display the entries... */
20257 }
20258 break;
20259
9ef920e9 20260 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20261 print_gnu_property_note (filedata, pnote);
9ef920e9 20262 break;
9abca702 20263
1449284b
NC
20264 default:
20265 /* Handle unrecognised types. An error message should have already been
20266 created by get_gnu_elf_note_type(), so all that we need to do is to
20267 display the data. */
20268 {
20269 unsigned long i;
20270
20271 printf (_(" Description data: "));
20272 for (i = 0; i < pnote->descsz; ++i)
20273 printf ("%02x ", pnote->descdata[i] & 0xff);
20274 printf ("\n");
20275 }
20276 break;
664f90a3
TT
20277 }
20278
015dc7e1 20279 return true;
664f90a3
TT
20280}
20281
685080f2
NC
20282static const char *
20283get_v850_elf_note_type (enum v850_notes n_type)
20284{
20285 static char buff[64];
20286
20287 switch (n_type)
20288 {
20289 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20290 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20291 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20292 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20293 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20294 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20295 default:
20296 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20297 return buff;
20298 }
20299}
20300
015dc7e1 20301static bool
685080f2
NC
20302print_v850_note (Elf_Internal_Note * pnote)
20303{
20304 unsigned int val;
20305
20306 if (pnote->descsz != 4)
015dc7e1 20307 return false;
32ec8896 20308
685080f2
NC
20309 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20310
20311 if (val == 0)
20312 {
20313 printf (_("not set\n"));
015dc7e1 20314 return true;
685080f2
NC
20315 }
20316
20317 switch (pnote->type)
20318 {
20319 case V850_NOTE_ALIGNMENT:
20320 switch (val)
20321 {
015dc7e1
AM
20322 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20323 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20324 }
20325 break;
14ae95f2 20326
685080f2
NC
20327 case V850_NOTE_DATA_SIZE:
20328 switch (val)
20329 {
015dc7e1
AM
20330 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20331 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20332 }
20333 break;
14ae95f2 20334
685080f2
NC
20335 case V850_NOTE_FPU_INFO:
20336 switch (val)
20337 {
015dc7e1
AM
20338 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20339 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20340 }
20341 break;
14ae95f2 20342
685080f2
NC
20343 case V850_NOTE_MMU_INFO:
20344 case V850_NOTE_CACHE_INFO:
20345 case V850_NOTE_SIMD_INFO:
20346 if (val == EF_RH850_SIMD)
20347 {
20348 printf (_("yes\n"));
015dc7e1 20349 return true;
685080f2
NC
20350 }
20351 break;
20352
20353 default:
20354 /* An 'unknown note type' message will already have been displayed. */
20355 break;
20356 }
20357
20358 printf (_("unknown value: %x\n"), val);
015dc7e1 20359 return false;
685080f2
NC
20360}
20361
015dc7e1 20362static bool
c6056a74
SF
20363process_netbsd_elf_note (Elf_Internal_Note * pnote)
20364{
20365 unsigned int version;
20366
20367 switch (pnote->type)
20368 {
20369 case NT_NETBSD_IDENT:
b966f55f
AM
20370 if (pnote->descsz < 1)
20371 break;
c6056a74
SF
20372 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20373 if ((version / 10000) % 100)
b966f55f 20374 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20375 version, version / 100000000, (version / 1000000) % 100,
20376 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20377 'A' + (version / 10000) % 26);
c6056a74
SF
20378 else
20379 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20380 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20381 (version / 100) % 100);
015dc7e1 20382 return true;
c6056a74
SF
20383
20384 case NT_NETBSD_MARCH:
9abca702 20385 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20386 pnote->descdata);
015dc7e1 20387 return true;
c6056a74 20388
9abca702 20389 case NT_NETBSD_PAX:
b966f55f
AM
20390 if (pnote->descsz < 1)
20391 break;
9abca702
CZ
20392 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20393 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20394 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20395 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20396 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20397 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20398 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20399 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20400 return true;
c6056a74 20401 }
b966f55f
AM
20402
20403 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20404 pnote->descsz, pnote->type);
015dc7e1 20405 return false;
c6056a74
SF
20406}
20407
f4ddf30f 20408static const char *
dda8d76d 20409get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20410{
f4ddf30f
JB
20411 switch (e_type)
20412 {
20413 case NT_FREEBSD_THRMISC:
20414 return _("NT_THRMISC (thrmisc structure)");
20415 case NT_FREEBSD_PROCSTAT_PROC:
20416 return _("NT_PROCSTAT_PROC (proc data)");
20417 case NT_FREEBSD_PROCSTAT_FILES:
20418 return _("NT_PROCSTAT_FILES (files data)");
20419 case NT_FREEBSD_PROCSTAT_VMMAP:
20420 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20421 case NT_FREEBSD_PROCSTAT_GROUPS:
20422 return _("NT_PROCSTAT_GROUPS (groups data)");
20423 case NT_FREEBSD_PROCSTAT_UMASK:
20424 return _("NT_PROCSTAT_UMASK (umask data)");
20425 case NT_FREEBSD_PROCSTAT_RLIMIT:
20426 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20427 case NT_FREEBSD_PROCSTAT_OSREL:
20428 return _("NT_PROCSTAT_OSREL (osreldate data)");
20429 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20430 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20431 case NT_FREEBSD_PROCSTAT_AUXV:
20432 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20433 case NT_FREEBSD_PTLWPINFO:
20434 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20435 case NT_FREEBSD_X86_SEGBASES:
20436 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20437 }
dda8d76d 20438 return get_note_type (filedata, e_type);
f4ddf30f
JB
20439}
20440
9437c45b 20441static const char *
dda8d76d 20442get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20443{
20444 static char buff[64];
20445
540e6170
CZ
20446 switch (e_type)
20447 {
20448 case NT_NETBSDCORE_PROCINFO:
20449 /* NetBSD core "procinfo" structure. */
20450 return _("NetBSD procinfo structure");
9437c45b 20451
540e6170
CZ
20452 case NT_NETBSDCORE_AUXV:
20453 return _("NetBSD ELF auxiliary vector data");
9437c45b 20454
06d949ec
KR
20455 case NT_NETBSDCORE_LWPSTATUS:
20456 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20457
540e6170 20458 default:
06d949ec 20459 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20460 defined for NetBSD core files. If the note type is less
20461 than the start of the machine-dependent note types, we don't
20462 understand it. */
20463
20464 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20465 {
20466 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20467 return buff;
20468 }
20469 break;
9437c45b
JT
20470 }
20471
dda8d76d 20472 switch (filedata->file_header.e_machine)
9437c45b
JT
20473 {
20474 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20475 and PT_GETFPREGS == mach+2. */
20476
20477 case EM_OLD_ALPHA:
20478 case EM_ALPHA:
20479 case EM_SPARC:
20480 case EM_SPARC32PLUS:
20481 case EM_SPARCV9:
20482 switch (e_type)
20483 {
2b692964 20484 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20485 return _("PT_GETREGS (reg structure)");
2b692964 20486 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20487 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20488 default:
20489 break;
20490 }
20491 break;
20492
c0d38b0e
CZ
20493 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20494 There's also old PT___GETREGS40 == mach + 1 for old reg
20495 structure which lacks GBR. */
20496 case EM_SH:
20497 switch (e_type)
20498 {
20499 case NT_NETBSDCORE_FIRSTMACH + 1:
20500 return _("PT___GETREGS40 (old reg structure)");
20501 case NT_NETBSDCORE_FIRSTMACH + 3:
20502 return _("PT_GETREGS (reg structure)");
20503 case NT_NETBSDCORE_FIRSTMACH + 5:
20504 return _("PT_GETFPREGS (fpreg structure)");
20505 default:
20506 break;
20507 }
20508 break;
20509
9437c45b
JT
20510 /* On all other arch's, PT_GETREGS == mach+1 and
20511 PT_GETFPREGS == mach+3. */
20512 default:
20513 switch (e_type)
20514 {
2b692964 20515 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20516 return _("PT_GETREGS (reg structure)");
2b692964 20517 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20518 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20519 default:
20520 break;
20521 }
20522 }
20523
9cf03b7e 20524 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20525 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20526 return buff;
20527}
20528
98ca73af
FC
20529static const char *
20530get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20531{
20532 switch (e_type)
20533 {
20534 case NT_OPENBSD_PROCINFO:
20535 return _("OpenBSD procinfo structure");
20536 case NT_OPENBSD_AUXV:
20537 return _("OpenBSD ELF auxiliary vector data");
20538 case NT_OPENBSD_REGS:
20539 return _("OpenBSD regular registers");
20540 case NT_OPENBSD_FPREGS:
20541 return _("OpenBSD floating point registers");
20542 case NT_OPENBSD_WCOOKIE:
20543 return _("OpenBSD window cookie");
20544 }
20545
20546 return get_note_type (filedata, e_type);
20547}
20548
70616151
TT
20549static const char *
20550get_stapsdt_note_type (unsigned e_type)
20551{
20552 static char buff[64];
20553
20554 switch (e_type)
20555 {
20556 case NT_STAPSDT:
20557 return _("NT_STAPSDT (SystemTap probe descriptors)");
20558
20559 default:
20560 break;
20561 }
20562
20563 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20564 return buff;
20565}
20566
015dc7e1 20567static bool
c6a9fc58
TT
20568print_stapsdt_note (Elf_Internal_Note *pnote)
20569{
3ca60c57
NC
20570 size_t len, maxlen;
20571 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20572 char *data = pnote->descdata;
20573 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20574 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20575 char *provider, *probe, *arg_fmt;
20576
3ca60c57
NC
20577 if (pnote->descsz < (addr_size * 3))
20578 goto stapdt_note_too_small;
20579
c6a9fc58
TT
20580 pc = byte_get ((unsigned char *) data, addr_size);
20581 data += addr_size;
3ca60c57 20582
c6a9fc58
TT
20583 base_addr = byte_get ((unsigned char *) data, addr_size);
20584 data += addr_size;
3ca60c57 20585
c6a9fc58
TT
20586 semaphore = byte_get ((unsigned char *) data, addr_size);
20587 data += addr_size;
20588
3ca60c57
NC
20589 if (data >= data_end)
20590 goto stapdt_note_too_small;
20591 maxlen = data_end - data;
20592 len = strnlen (data, maxlen);
20593 if (len < maxlen)
20594 {
20595 provider = data;
20596 data += len + 1;
20597 }
20598 else
20599 goto stapdt_note_too_small;
20600
20601 if (data >= data_end)
20602 goto stapdt_note_too_small;
20603 maxlen = data_end - data;
20604 len = strnlen (data, maxlen);
20605 if (len < maxlen)
20606 {
20607 probe = data;
20608 data += len + 1;
20609 }
20610 else
20611 goto stapdt_note_too_small;
9abca702 20612
3ca60c57
NC
20613 if (data >= data_end)
20614 goto stapdt_note_too_small;
20615 maxlen = data_end - data;
20616 len = strnlen (data, maxlen);
20617 if (len < maxlen)
20618 {
20619 arg_fmt = data;
20620 data += len + 1;
20621 }
20622 else
20623 goto stapdt_note_too_small;
c6a9fc58
TT
20624
20625 printf (_(" Provider: %s\n"), provider);
20626 printf (_(" Name: %s\n"), probe);
20627 printf (_(" Location: "));
20628 print_vma (pc, FULL_HEX);
20629 printf (_(", Base: "));
20630 print_vma (base_addr, FULL_HEX);
20631 printf (_(", Semaphore: "));
20632 print_vma (semaphore, FULL_HEX);
9cf03b7e 20633 printf ("\n");
c6a9fc58
TT
20634 printf (_(" Arguments: %s\n"), arg_fmt);
20635
20636 return data == data_end;
3ca60c57
NC
20637
20638 stapdt_note_too_small:
20639 printf (_(" <corrupt - note is too small>\n"));
20640 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20641 return false;
c6a9fc58
TT
20642}
20643
e5382207
LB
20644static bool
20645print_fdo_note (Elf_Internal_Note * pnote)
20646{
20647 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20648 {
20649 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20650 return true;
20651 }
20652 return false;
20653}
20654
00e98fc7
TG
20655static const char *
20656get_ia64_vms_note_type (unsigned e_type)
20657{
20658 static char buff[64];
20659
20660 switch (e_type)
20661 {
20662 case NT_VMS_MHD:
20663 return _("NT_VMS_MHD (module header)");
20664 case NT_VMS_LNM:
20665 return _("NT_VMS_LNM (language name)");
20666 case NT_VMS_SRC:
20667 return _("NT_VMS_SRC (source files)");
20668 case NT_VMS_TITLE:
9cf03b7e 20669 return "NT_VMS_TITLE";
00e98fc7
TG
20670 case NT_VMS_EIDC:
20671 return _("NT_VMS_EIDC (consistency check)");
20672 case NT_VMS_FPMODE:
20673 return _("NT_VMS_FPMODE (FP mode)");
20674 case NT_VMS_LINKTIME:
9cf03b7e 20675 return "NT_VMS_LINKTIME";
00e98fc7
TG
20676 case NT_VMS_IMGNAM:
20677 return _("NT_VMS_IMGNAM (image name)");
20678 case NT_VMS_IMGID:
20679 return _("NT_VMS_IMGID (image id)");
20680 case NT_VMS_LINKID:
20681 return _("NT_VMS_LINKID (link id)");
20682 case NT_VMS_IMGBID:
20683 return _("NT_VMS_IMGBID (build id)");
20684 case NT_VMS_GSTNAM:
20685 return _("NT_VMS_GSTNAM (sym table name)");
20686 case NT_VMS_ORIG_DYN:
9cf03b7e 20687 return "NT_VMS_ORIG_DYN";
00e98fc7 20688 case NT_VMS_PATCHTIME:
9cf03b7e 20689 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20690 default:
20691 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20692 return buff;
20693 }
20694}
20695
015dc7e1 20696static bool
00e98fc7
TG
20697print_ia64_vms_note (Elf_Internal_Note * pnote)
20698{
8d18bf79
NC
20699 int maxlen = pnote->descsz;
20700
20701 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20702 goto desc_size_fail;
20703
00e98fc7
TG
20704 switch (pnote->type)
20705 {
20706 case NT_VMS_MHD:
8d18bf79
NC
20707 if (maxlen <= 36)
20708 goto desc_size_fail;
20709
20710 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20711
20712 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20713 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20714 if (l + 34 < maxlen)
20715 {
20716 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20717 if (l + 35 < maxlen)
20718 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20719 else
20720 printf (_(" Module version : <missing>\n"));
20721 }
00e98fc7 20722 else
8d18bf79
NC
20723 {
20724 printf (_(" Module name : <missing>\n"));
20725 printf (_(" Module version : <missing>\n"));
20726 }
00e98fc7 20727 break;
8d18bf79 20728
00e98fc7 20729 case NT_VMS_LNM:
8d18bf79 20730 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20731 break;
8d18bf79 20732
00e98fc7 20733 case NT_VMS_FPMODE:
9cf03b7e 20734 printf (_(" Floating Point mode: "));
8d18bf79
NC
20735 if (maxlen < 8)
20736 goto desc_size_fail;
20737 /* FIXME: Generate an error if descsz > 8 ? */
20738
b8281767 20739 printf ("0x%016" PRIx64 "\n",
625d49fc 20740 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20741 break;
8d18bf79 20742
00e98fc7
TG
20743 case NT_VMS_LINKTIME:
20744 printf (_(" Link time: "));
8d18bf79
NC
20745 if (maxlen < 8)
20746 goto desc_size_fail;
20747 /* FIXME: Generate an error if descsz > 8 ? */
20748
0e3c1eeb 20749 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20750 printf ("\n");
20751 break;
8d18bf79 20752
00e98fc7
TG
20753 case NT_VMS_PATCHTIME:
20754 printf (_(" Patch time: "));
8d18bf79
NC
20755 if (maxlen < 8)
20756 goto desc_size_fail;
20757 /* FIXME: Generate an error if descsz > 8 ? */
20758
0e3c1eeb 20759 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20760 printf ("\n");
20761 break;
8d18bf79 20762
00e98fc7 20763 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20764 if (maxlen < 34)
20765 goto desc_size_fail;
20766
00e98fc7 20767 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20768 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20769 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20770 printf (_(" Last modified : "));
0e3c1eeb 20771 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20772 printf (_("\n Link flags : "));
b8281767 20773 printf ("0x%016" PRIx64 "\n",
625d49fc 20774 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20775 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20776 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20777 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20778 break;
8d18bf79 20779
00e98fc7 20780 case NT_VMS_IMGNAM:
8d18bf79 20781 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20782 break;
8d18bf79 20783
00e98fc7 20784 case NT_VMS_GSTNAM:
8d18bf79 20785 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20786 break;
8d18bf79 20787
00e98fc7 20788 case NT_VMS_IMGID:
8d18bf79 20789 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20790 break;
8d18bf79 20791
00e98fc7 20792 case NT_VMS_LINKID:
8d18bf79 20793 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20794 break;
8d18bf79 20795
00e98fc7 20796 default:
015dc7e1 20797 return false;
00e98fc7 20798 }
8d18bf79 20799
015dc7e1 20800 return true;
8d18bf79
NC
20801
20802 desc_size_fail:
20803 printf (_(" <corrupt - data size is too small>\n"));
20804 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20805 return false;
00e98fc7
TG
20806}
20807
fd486f32
AM
20808struct build_attr_cache {
20809 Filedata *filedata;
20810 char *strtab;
20811 unsigned long strtablen;
20812 Elf_Internal_Sym *symtab;
20813 unsigned long nsyms;
20814} ba_cache;
20815
6f156d7a
NC
20816/* Find the symbol associated with a build attribute that is attached
20817 to address OFFSET. If PNAME is non-NULL then store the name of
20818 the symbol (if found) in the provided pointer, Returns NULL if a
20819 symbol could not be found. */
c799a79d 20820
6f156d7a 20821static Elf_Internal_Sym *
015dc7e1
AM
20822get_symbol_for_build_attribute (Filedata *filedata,
20823 unsigned long offset,
20824 bool is_open_attr,
20825 const char **pname)
9ef920e9 20826{
fd486f32
AM
20827 Elf_Internal_Sym *saved_sym = NULL;
20828 Elf_Internal_Sym *sym;
9ef920e9 20829
dda8d76d 20830 if (filedata->section_headers != NULL
fd486f32 20831 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20832 {
c799a79d 20833 Elf_Internal_Shdr * symsec;
9ef920e9 20834
fd486f32
AM
20835 free (ba_cache.strtab);
20836 ba_cache.strtab = NULL;
20837 free (ba_cache.symtab);
20838 ba_cache.symtab = NULL;
20839
c799a79d 20840 /* Load the symbol and string sections. */
dda8d76d
NC
20841 for (symsec = filedata->section_headers;
20842 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20843 symsec ++)
9ef920e9 20844 {
28d13567
AM
20845 if (symsec->sh_type == SHT_SYMTAB
20846 && get_symtab (filedata, symsec,
20847 &ba_cache.symtab, &ba_cache.nsyms,
20848 &ba_cache.strtab, &ba_cache.strtablen))
20849 break;
9ef920e9 20850 }
fd486f32 20851 ba_cache.filedata = filedata;
9ef920e9
NC
20852 }
20853
fd486f32 20854 if (ba_cache.symtab == NULL)
6f156d7a 20855 return NULL;
9ef920e9 20856
c799a79d 20857 /* Find a symbol whose value matches offset. */
fd486f32 20858 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20859 if (sym->st_value == offset)
20860 {
fd486f32 20861 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20862 /* Huh ? This should not happen. */
20863 continue;
9ef920e9 20864
fd486f32 20865 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20866 continue;
9ef920e9 20867
9b9b1092 20868 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20869 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20870 if (ba_cache.strtab[sym->st_name] == '$'
20871 && ba_cache.strtab[sym->st_name + 1] != 0
20872 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20873 continue;
20874
c799a79d
NC
20875 if (is_open_attr)
20876 {
20877 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20878 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20879 FUNC symbols entirely. */
20880 switch (ELF_ST_TYPE (sym->st_info))
20881 {
c799a79d 20882 case STT_OBJECT:
6f156d7a 20883 case STT_FILE:
c799a79d 20884 saved_sym = sym;
6f156d7a
NC
20885 if (sym->st_size)
20886 {
20887 /* If the symbol has a size associated
20888 with it then we can stop searching. */
fd486f32 20889 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20890 }
c799a79d 20891 continue;
9ef920e9 20892
c799a79d
NC
20893 case STT_FUNC:
20894 /* Ignore function symbols. */
20895 continue;
20896
20897 default:
20898 break;
20899 }
20900
20901 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20902 {
c799a79d
NC
20903 case STB_GLOBAL:
20904 if (saved_sym == NULL
20905 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20906 saved_sym = sym;
20907 break;
c871dade 20908
c799a79d
NC
20909 case STB_LOCAL:
20910 if (saved_sym == NULL)
20911 saved_sym = sym;
20912 break;
20913
20914 default:
9ef920e9
NC
20915 break;
20916 }
20917 }
c799a79d
NC
20918 else
20919 {
20920 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20921 continue;
20922
20923 saved_sym = sym;
20924 break;
20925 }
20926 }
20927
6f156d7a 20928 if (saved_sym && pname)
fd486f32 20929 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20930
20931 return saved_sym;
c799a79d
NC
20932}
20933
d20e98ab
NC
20934/* Returns true iff addr1 and addr2 are in the same section. */
20935
015dc7e1 20936static bool
d20e98ab
NC
20937same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20938{
20939 Elf_Internal_Shdr * a1;
20940 Elf_Internal_Shdr * a2;
20941
20942 a1 = find_section_by_address (filedata, addr1);
20943 a2 = find_section_by_address (filedata, addr2);
9abca702 20944
d20e98ab
NC
20945 return a1 == a2 && a1 != NULL;
20946}
20947
015dc7e1 20948static bool
dda8d76d
NC
20949print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20950 Filedata * filedata)
c799a79d 20951{
015dc7e1
AM
20952 static unsigned long global_offset = 0;
20953 static unsigned long global_end = 0;
20954 static unsigned long func_offset = 0;
20955 static unsigned long func_end = 0;
c871dade 20956
015dc7e1
AM
20957 Elf_Internal_Sym *sym;
20958 const char *name;
20959 unsigned long start;
20960 unsigned long end;
20961 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20962
20963 switch (pnote->descsz)
c799a79d 20964 {
6f156d7a
NC
20965 case 0:
20966 /* A zero-length description means that the range of
20967 the previous note of the same type should be used. */
c799a79d 20968 if (is_open_attr)
c871dade 20969 {
6f156d7a
NC
20970 if (global_end > global_offset)
20971 printf (_(" Applies to region from %#lx to %#lx\n"),
20972 global_offset, global_end);
20973 else
20974 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20975 }
20976 else
20977 {
6f156d7a
NC
20978 if (func_end > func_offset)
20979 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20980 else
20981 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20982 }
015dc7e1 20983 return true;
9ef920e9 20984
6f156d7a
NC
20985 case 4:
20986 start = byte_get ((unsigned char *) pnote->descdata, 4);
20987 end = 0;
20988 break;
20989
20990 case 8:
c74147bb
NC
20991 start = byte_get ((unsigned char *) pnote->descdata, 4);
20992 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20993 break;
20994
20995 case 16:
20996 start = byte_get ((unsigned char *) pnote->descdata, 8);
20997 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20998 break;
9abca702 20999
6f156d7a 21000 default:
c799a79d
NC
21001 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21002 printf (_(" <invalid descsz>"));
015dc7e1 21003 return false;
c799a79d
NC
21004 }
21005
6f156d7a
NC
21006 name = NULL;
21007 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21008 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21009 in order to avoid them being confused with the start address of the
21010 first function in the file... */
21011 if (sym == NULL && is_open_attr)
21012 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21013 & name);
6f156d7a
NC
21014
21015 if (end == 0 && sym != NULL && sym->st_size > 0)
21016 end = start + sym->st_size;
c799a79d
NC
21017
21018 if (is_open_attr)
21019 {
d20e98ab
NC
21020 /* FIXME: Need to properly allow for section alignment.
21021 16 is just the alignment used on x86_64. */
21022 if (global_end > 0
21023 && start > BFD_ALIGN (global_end, 16)
21024 /* Build notes are not guaranteed to be organised in order of
21025 increasing address, but we should find the all of the notes
21026 for one section in the same place. */
21027 && same_section (filedata, start, global_end))
6f156d7a
NC
21028 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
21029 global_end + 1, start - 1);
21030
21031 printf (_(" Applies to region from %#lx"), start);
21032 global_offset = start;
21033
21034 if (end)
21035 {
21036 printf (_(" to %#lx"), end);
21037 global_end = end;
21038 }
c799a79d
NC
21039 }
21040 else
21041 {
6f156d7a
NC
21042 printf (_(" Applies to region from %#lx"), start);
21043 func_offset = start;
21044
21045 if (end)
21046 {
21047 printf (_(" to %#lx"), end);
21048 func_end = end;
21049 }
c799a79d
NC
21050 }
21051
6f156d7a
NC
21052 if (sym && name)
21053 printf (_(" (%s)"), name);
21054
21055 printf ("\n");
015dc7e1 21056 return true;
9ef920e9
NC
21057}
21058
015dc7e1 21059static bool
9ef920e9
NC
21060print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21061{
1d15e434
NC
21062 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21063 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21064 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21065 char name_type;
21066 char name_attribute;
1d15e434 21067 const char * expected_types;
9ef920e9
NC
21068 const char * name = pnote->namedata;
21069 const char * text;
88305e1b 21070 signed int left;
9ef920e9
NC
21071
21072 if (name == NULL || pnote->namesz < 2)
21073 {
21074 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21075 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21076 return false;
9ef920e9
NC
21077 }
21078
6f156d7a
NC
21079 if (do_wide)
21080 left = 28;
21081 else
21082 left = 20;
88305e1b
NC
21083
21084 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21085 if (name[0] == 'G' && name[1] == 'A')
21086 {
6f156d7a
NC
21087 if (pnote->namesz < 4)
21088 {
21089 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21090 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21091 return false;
6f156d7a
NC
21092 }
21093
88305e1b
NC
21094 printf ("GA");
21095 name += 2;
21096 left -= 2;
21097 }
21098
9ef920e9
NC
21099 switch ((name_type = * name))
21100 {
21101 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21102 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21103 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21104 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21105 printf ("%c", * name);
88305e1b 21106 left --;
9ef920e9
NC
21107 break;
21108 default:
21109 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21110 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21111 return false;
9ef920e9
NC
21112 }
21113
9ef920e9
NC
21114 ++ name;
21115 text = NULL;
21116
21117 switch ((name_attribute = * name))
21118 {
21119 case GNU_BUILD_ATTRIBUTE_VERSION:
21120 text = _("<version>");
1d15e434 21121 expected_types = string_expected;
9ef920e9
NC
21122 ++ name;
21123 break;
21124 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21125 text = _("<stack prot>");
75d7d298 21126 expected_types = "!+*";
9ef920e9
NC
21127 ++ name;
21128 break;
21129 case GNU_BUILD_ATTRIBUTE_RELRO:
21130 text = _("<relro>");
1d15e434 21131 expected_types = bool_expected;
9ef920e9
NC
21132 ++ name;
21133 break;
21134 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21135 text = _("<stack size>");
1d15e434 21136 expected_types = number_expected;
9ef920e9
NC
21137 ++ name;
21138 break;
21139 case GNU_BUILD_ATTRIBUTE_TOOL:
21140 text = _("<tool>");
1d15e434 21141 expected_types = string_expected;
9ef920e9
NC
21142 ++ name;
21143 break;
21144 case GNU_BUILD_ATTRIBUTE_ABI:
21145 text = _("<ABI>");
21146 expected_types = "$*";
21147 ++ name;
21148 break;
21149 case GNU_BUILD_ATTRIBUTE_PIC:
21150 text = _("<PIC>");
1d15e434 21151 expected_types = number_expected;
9ef920e9
NC
21152 ++ name;
21153 break;
a8be5506
NC
21154 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21155 text = _("<short enum>");
1d15e434 21156 expected_types = bool_expected;
a8be5506
NC
21157 ++ name;
21158 break;
9ef920e9
NC
21159 default:
21160 if (ISPRINT (* name))
21161 {
21162 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21163
21164 if (len > left && ! do_wide)
21165 len = left;
75d7d298 21166 printf ("%.*s:", len, name);
9ef920e9 21167 left -= len;
0dd6ae21 21168 name += len;
9ef920e9
NC
21169 }
21170 else
21171 {
3e6b6445 21172 static char tmpbuf [128];
88305e1b 21173
3e6b6445
NC
21174 error (_("unrecognised byte in name field: %d\n"), * name);
21175 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21176 text = tmpbuf;
21177 name ++;
9ef920e9
NC
21178 }
21179 expected_types = "*$!+";
21180 break;
21181 }
21182
21183 if (text)
88305e1b 21184 left -= printf ("%s", text);
9ef920e9
NC
21185
21186 if (strchr (expected_types, name_type) == NULL)
75d7d298 21187 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21188
21189 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21190 {
21191 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21192 (unsigned long) pnote->namesz,
21193 (long) (name - pnote->namedata));
015dc7e1 21194 return false;
9ef920e9
NC
21195 }
21196
21197 if (left < 1 && ! do_wide)
015dc7e1 21198 return true;
9ef920e9
NC
21199
21200 switch (name_type)
21201 {
21202 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21203 {
b06b2c92 21204 unsigned int bytes;
ddef72cd
NC
21205 unsigned long long val = 0;
21206 unsigned int shift = 0;
21207 char * decoded = NULL;
21208
b06b2c92
NC
21209 bytes = pnote->namesz - (name - pnote->namedata);
21210 if (bytes > 0)
21211 /* The -1 is because the name field is always 0 terminated, and we
21212 want to be able to ensure that the shift in the while loop below
21213 will not overflow. */
21214 -- bytes;
21215
ddef72cd
NC
21216 if (bytes > sizeof (val))
21217 {
3e6b6445
NC
21218 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21219 bytes);
21220 bytes = sizeof (val);
ddef72cd 21221 }
3e6b6445
NC
21222 /* We do not bother to warn if bytes == 0 as this can
21223 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21224
21225 while (bytes --)
21226 {
54b8331d 21227 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21228
21229 val |= byte << shift;
9ef920e9
NC
21230 shift += 8;
21231 }
21232
75d7d298 21233 switch (name_attribute)
9ef920e9 21234 {
75d7d298 21235 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21236 switch (val)
21237 {
75d7d298
NC
21238 case 0: decoded = "static"; break;
21239 case 1: decoded = "pic"; break;
21240 case 2: decoded = "PIC"; break;
21241 case 3: decoded = "pie"; break;
21242 case 4: decoded = "PIE"; break;
21243 default: break;
9ef920e9 21244 }
75d7d298
NC
21245 break;
21246 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21247 switch (val)
9ef920e9 21248 {
75d7d298
NC
21249 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21250 case 0: decoded = "off"; break;
21251 case 1: decoded = "on"; break;
21252 case 2: decoded = "all"; break;
21253 case 3: decoded = "strong"; break;
21254 case 4: decoded = "explicit"; break;
21255 default: break;
9ef920e9 21256 }
75d7d298
NC
21257 break;
21258 default:
21259 break;
9ef920e9
NC
21260 }
21261
75d7d298 21262 if (decoded != NULL)
3e6b6445
NC
21263 {
21264 print_symbol (-left, decoded);
21265 left = 0;
21266 }
21267 else if (val == 0)
21268 {
21269 printf ("0x0");
21270 left -= 3;
21271 }
9ef920e9 21272 else
75d7d298
NC
21273 {
21274 if (do_wide)
ddef72cd 21275 left -= printf ("0x%llx", val);
75d7d298 21276 else
ddef72cd 21277 left -= printf ("0x%-.*llx", left, val);
75d7d298 21278 }
9ef920e9
NC
21279 }
21280 break;
21281 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21282 left -= print_symbol (- left, name);
21283 break;
21284 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21285 left -= print_symbol (- left, "true");
21286 break;
21287 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21288 left -= print_symbol (- left, "false");
21289 break;
21290 }
21291
21292 if (do_wide && left > 0)
21293 printf ("%-*s", left, " ");
9abca702 21294
015dc7e1 21295 return true;
9ef920e9
NC
21296}
21297
2952f10c
SM
21298/* Print the contents of PNOTE as hex. */
21299
21300static void
21301print_note_contents_hex (Elf_Internal_Note *pnote)
21302{
21303 if (pnote->descsz)
21304 {
21305 unsigned long i;
21306
21307 printf (_(" description data: "));
21308 for (i = 0; i < pnote->descsz; i++)
21309 printf ("%02x ", pnote->descdata[i] & 0xff);
21310 if (!do_wide)
21311 printf ("\n");
21312 }
21313
21314 if (do_wide)
21315 printf ("\n");
21316}
21317
21318#if defined HAVE_MSGPACK
21319
21320static void
21321print_indents (int n)
21322{
21323 printf (" ");
21324
21325 for (int i = 0; i < n; i++)
21326 printf (" ");
21327}
21328
21329/* Print OBJ in human-readable form. */
21330
21331static void
21332dump_msgpack_obj (const msgpack_object *obj, int indent)
21333{
21334 switch (obj->type)
21335 {
21336 case MSGPACK_OBJECT_NIL:
21337 printf ("(nil)");
21338 break;
21339
21340 case MSGPACK_OBJECT_BOOLEAN:
21341 printf ("%s", obj->via.boolean ? "true" : "false");
21342 break;
21343
21344 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21345 printf ("%" PRIu64, obj->via.u64);
21346 break;
21347
21348 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21349 printf ("%" PRIi64, obj->via.i64);
21350 break;
21351
21352 case MSGPACK_OBJECT_FLOAT32:
21353 case MSGPACK_OBJECT_FLOAT64:
21354 printf ("%f", obj->via.f64);
21355 break;
21356
21357 case MSGPACK_OBJECT_STR:
21358 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21359 break;
21360
21361 case MSGPACK_OBJECT_ARRAY:
21362 {
21363 const msgpack_object_array *array = &obj->via.array;
21364
21365 printf ("[\n");
21366 ++indent;
21367
21368 for (uint32_t i = 0; i < array->size; ++i)
21369 {
21370 const msgpack_object *item = &array->ptr[i];
21371
21372 print_indents (indent);
21373 dump_msgpack_obj (item, indent);
21374 printf (",\n");
21375 }
21376
21377 --indent;
21378 print_indents (indent);
21379 printf ("]");
21380 break;
21381 }
21382 break;
21383
21384 case MSGPACK_OBJECT_MAP:
21385 {
21386 const msgpack_object_map *map = &obj->via.map;
21387
21388 printf ("{\n");
21389 ++indent;
21390
21391 for (uint32_t i = 0; i < map->size; ++i)
21392 {
21393 const msgpack_object_kv *kv = &map->ptr[i];
21394 const msgpack_object *key = &kv->key;
21395 const msgpack_object *val = &kv->val;
21396
21397 print_indents (indent);
21398 dump_msgpack_obj (key, indent);
21399 printf (": ");
21400 dump_msgpack_obj (val, indent);
21401
21402 printf (",\n");
21403 }
21404
21405 --indent;
21406 print_indents (indent);
21407 printf ("}");
21408
21409 break;
21410 }
21411
21412 case MSGPACK_OBJECT_BIN:
21413 printf ("(bin)");
21414 break;
21415
21416 case MSGPACK_OBJECT_EXT:
21417 printf ("(ext)");
21418 break;
21419 }
21420}
21421
21422static void
21423dump_msgpack (const msgpack_unpacked *msg)
21424{
21425 print_indents (0);
21426 dump_msgpack_obj (&msg->data, 0);
21427 printf ("\n");
21428}
21429
21430#endif /* defined HAVE_MSGPACK */
21431
21432static bool
21433print_amdgpu_note (Elf_Internal_Note *pnote)
21434{
21435#if defined HAVE_MSGPACK
21436 /* If msgpack is available, decode and dump the note's content. */
21437 bool ret;
21438 msgpack_unpacked msg;
21439 msgpack_unpack_return msgpack_ret;
21440
21441 assert (pnote->type == NT_AMDGPU_METADATA);
21442
21443 msgpack_unpacked_init (&msg);
21444 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21445 NULL);
21446
21447 switch (msgpack_ret)
21448 {
21449 case MSGPACK_UNPACK_SUCCESS:
21450 dump_msgpack (&msg);
21451 ret = true;
21452 break;
21453
21454 default:
21455 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21456 ret = false;
21457 break;
21458 }
21459
21460 msgpack_unpacked_destroy (&msg);
21461 return ret;
21462#else
21463 /* msgpack is not available, dump contents as hex. */
21464 print_note_contents_hex (pnote);
21465 return true;
21466#endif
21467}
21468
6d118b09
NC
21469/* Note that by the ELF standard, the name field is already null byte
21470 terminated, and namesz includes the terminating null byte.
21471 I.E. the value of namesz for the name "FSF" is 4.
21472
e3c8793a 21473 If the value of namesz is zero, there is no name present. */
9ef920e9 21474
015dc7e1 21475static bool
9ef920e9 21476process_note (Elf_Internal_Note * pnote,
dda8d76d 21477 Filedata * filedata)
779fe533 21478{
2cf0635d
NC
21479 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21480 const char * nt;
9437c45b
JT
21481
21482 if (pnote->namesz == 0)
1ec5cd37
NC
21483 /* If there is no note name, then use the default set of
21484 note type strings. */
dda8d76d 21485 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21486
24d127aa 21487 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21488 /* GNU-specific object file notes. */
21489 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21490
28cdbb18
SM
21491 else if (startswith (pnote->namedata, "AMDGPU"))
21492 /* AMDGPU-specific object file notes. */
21493 nt = get_amdgpu_elf_note_type (pnote->type);
21494
24d127aa 21495 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21496 /* FreeBSD-specific core file notes. */
dda8d76d 21497 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21498
24d127aa 21499 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21500 /* NetBSD-specific core file notes. */
dda8d76d 21501 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21502
24d127aa 21503 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21504 /* NetBSD-specific core file notes. */
21505 return process_netbsd_elf_note (pnote);
21506
24d127aa 21507 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21508 /* NetBSD-specific core file notes. */
21509 return process_netbsd_elf_note (pnote);
21510
98ca73af
FC
21511 else if (startswith (pnote->namedata, "OpenBSD"))
21512 /* OpenBSD-specific core file notes. */
21513 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21514
e9b095a5 21515 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21516 {
21517 /* SPU-specific core file notes. */
21518 nt = pnote->namedata + 4;
21519 name = "SPU";
21520 }
21521
24d127aa 21522 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21523 /* VMS/ia64-specific file notes. */
21524 nt = get_ia64_vms_note_type (pnote->type);
21525
24d127aa 21526 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21527 nt = get_stapsdt_note_type (pnote->type);
21528
9437c45b 21529 else
1ec5cd37
NC
21530 /* Don't recognize this note name; just use the default set of
21531 note type strings. */
dda8d76d 21532 nt = get_note_type (filedata, pnote->type);
9437c45b 21533
1449284b 21534 printf (" ");
9ef920e9 21535
24d127aa 21536 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21537 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21538 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21539 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21540 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21541 print_gnu_build_attribute_name (pnote);
21542 else
21543 print_symbol (-20, name);
21544
21545 if (do_wide)
21546 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21547 else
21548 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21549
24d127aa 21550 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21551 return print_ia64_vms_note (pnote);
24d127aa 21552 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21553 return print_gnu_note (filedata, pnote);
24d127aa 21554 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21555 return print_stapsdt_note (pnote);
24d127aa 21556 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21557 return print_core_note (pnote);
e5382207
LB
21558 else if (startswith (pnote->namedata, "FDO"))
21559 return print_fdo_note (pnote);
24d127aa 21560 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21561 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21562 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21563 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21564 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21565 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21566 else if (startswith (pnote->namedata, "AMDGPU")
21567 && pnote->type == NT_AMDGPU_METADATA)
21568 return print_amdgpu_note (pnote);
779fe533 21569
2952f10c 21570 print_note_contents_hex (pnote);
015dc7e1 21571 return true;
1449284b 21572}
6d118b09 21573
015dc7e1 21574static bool
dda8d76d
NC
21575process_notes_at (Filedata * filedata,
21576 Elf_Internal_Shdr * section,
625d49fc
AM
21577 uint64_t offset,
21578 uint64_t length,
21579 uint64_t align)
779fe533 21580{
015dc7e1
AM
21581 Elf_External_Note *pnotes;
21582 Elf_External_Note *external;
21583 char *end;
21584 bool res = true;
103f02d3 21585
779fe533 21586 if (length <= 0)
015dc7e1 21587 return false;
103f02d3 21588
1449284b
NC
21589 if (section)
21590 {
dda8d76d 21591 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21592 if (pnotes)
32ec8896 21593 {
dda8d76d 21594 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21595 {
21596 free (pnotes);
015dc7e1 21597 return false;
f761cb13 21598 }
32ec8896 21599 }
1449284b
NC
21600 }
21601 else
82ed9683 21602 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21603 _("notes"));
4dff97b2 21604
dd24e3da 21605 if (pnotes == NULL)
015dc7e1 21606 return false;
779fe533 21607
103f02d3 21608 external = pnotes;
103f02d3 21609
ca0e11aa
NC
21610 if (filedata->is_separate)
21611 printf (_("In linked file '%s': "), filedata->file_name);
21612 else
21613 printf ("\n");
1449284b 21614 if (section)
ca0e11aa 21615 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21616 else
ca0e11aa 21617 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21618 (unsigned long) offset, (unsigned long) length);
21619
82ed9683
L
21620 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21621 specifies that notes should be aligned to 4 bytes in 32-bit
21622 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21623 we also support 4 byte alignment in 64-bit objects. If section
21624 alignment is less than 4, we treate alignment as 4 bytes. */
21625 if (align < 4)
21626 align = 4;
21627 else if (align != 4 && align != 8)
21628 {
21629 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21630 (long) align);
a788aedd 21631 free (pnotes);
015dc7e1 21632 return false;
82ed9683
L
21633 }
21634
dbe15e4e 21635 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21636
c8071705
NC
21637 end = (char *) pnotes + length;
21638 while ((char *) external < end)
779fe533 21639 {
b34976b6 21640 Elf_Internal_Note inote;
15b42fb0 21641 size_t min_notesz;
4dff97b2 21642 char * next;
2cf0635d 21643 char * temp = NULL;
c8071705 21644 size_t data_remaining = end - (char *) external;
6d118b09 21645
dda8d76d 21646 if (!is_ia64_vms (filedata))
15b42fb0 21647 {
9dd3a467
NC
21648 /* PR binutils/15191
21649 Make sure that there is enough data to read. */
15b42fb0
AM
21650 min_notesz = offsetof (Elf_External_Note, name);
21651 if (data_remaining < min_notesz)
9dd3a467 21652 {
d3a49aa8
AM
21653 warn (ngettext ("Corrupt note: only %ld byte remains, "
21654 "not enough for a full note\n",
21655 "Corrupt note: only %ld bytes remain, "
21656 "not enough for a full note\n",
21657 data_remaining),
21658 (long) data_remaining);
9dd3a467
NC
21659 break;
21660 }
5396a86e
AM
21661 data_remaining -= min_notesz;
21662
15b42fb0
AM
21663 inote.type = BYTE_GET (external->type);
21664 inote.namesz = BYTE_GET (external->namesz);
21665 inote.namedata = external->name;
21666 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21667 inote.descdata = ((char *) external
4dff97b2 21668 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21669 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21670 next = ((char *) external
4dff97b2 21671 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21672 }
00e98fc7 21673 else
15b42fb0
AM
21674 {
21675 Elf64_External_VMS_Note *vms_external;
00e98fc7 21676
9dd3a467
NC
21677 /* PR binutils/15191
21678 Make sure that there is enough data to read. */
15b42fb0
AM
21679 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21680 if (data_remaining < min_notesz)
9dd3a467 21681 {
d3a49aa8
AM
21682 warn (ngettext ("Corrupt note: only %ld byte remains, "
21683 "not enough for a full note\n",
21684 "Corrupt note: only %ld bytes remain, "
21685 "not enough for a full note\n",
21686 data_remaining),
21687 (long) data_remaining);
9dd3a467
NC
21688 break;
21689 }
5396a86e 21690 data_remaining -= min_notesz;
3e55a963 21691
15b42fb0
AM
21692 vms_external = (Elf64_External_VMS_Note *) external;
21693 inote.type = BYTE_GET (vms_external->type);
21694 inote.namesz = BYTE_GET (vms_external->namesz);
21695 inote.namedata = vms_external->name;
21696 inote.descsz = BYTE_GET (vms_external->descsz);
21697 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21698 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21699 next = inote.descdata + align_power (inote.descsz, 3);
21700 }
21701
5396a86e
AM
21702 /* PR 17531: file: 3443835e. */
21703 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21704 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21705 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21706 || (size_t) (next - inote.descdata) < inote.descsz
21707 || ((size_t) (next - inote.descdata)
21708 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21709 {
15b42fb0 21710 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21711 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21712 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21713 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21714 break;
21715 }
21716
15b42fb0 21717 external = (Elf_External_Note *) next;
dd24e3da 21718
6d118b09
NC
21719 /* Verify that name is null terminated. It appears that at least
21720 one version of Linux (RedHat 6.0) generates corefiles that don't
21721 comply with the ELF spec by failing to include the null byte in
21722 namesz. */
18344509 21723 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21724 {
5396a86e 21725 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21726 {
5396a86e
AM
21727 temp = (char *) malloc (inote.namesz + 1);
21728 if (temp == NULL)
21729 {
21730 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21731 res = false;
5396a86e
AM
21732 break;
21733 }
76da6bbe 21734
5396a86e
AM
21735 memcpy (temp, inote.namedata, inote.namesz);
21736 inote.namedata = temp;
21737 }
21738 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21739 }
21740
dda8d76d 21741 if (! process_note (& inote, filedata))
015dc7e1 21742 res = false;
103f02d3 21743
9db70fc3
AM
21744 free (temp);
21745 temp = NULL;
779fe533
NC
21746 }
21747
21748 free (pnotes);
103f02d3 21749
779fe533
NC
21750 return res;
21751}
21752
015dc7e1 21753static bool
dda8d76d 21754process_corefile_note_segments (Filedata * filedata)
779fe533 21755{
015dc7e1 21756 Elf_Internal_Phdr *segment;
b34976b6 21757 unsigned int i;
015dc7e1 21758 bool res = true;
103f02d3 21759
dda8d76d 21760 if (! get_program_headers (filedata))
015dc7e1 21761 return true;
103f02d3 21762
dda8d76d
NC
21763 for (i = 0, segment = filedata->program_headers;
21764 i < filedata->file_header.e_phnum;
b34976b6 21765 i++, segment++)
779fe533
NC
21766 {
21767 if (segment->p_type == PT_NOTE)
625d49fc
AM
21768 if (! process_notes_at (filedata, NULL, segment->p_offset,
21769 segment->p_filesz, segment->p_align))
015dc7e1 21770 res = false;
779fe533 21771 }
103f02d3 21772
779fe533
NC
21773 return res;
21774}
21775
015dc7e1 21776static bool
625d49fc 21777process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21778{
21779 Elf_External_Note * pnotes;
21780 Elf_External_Note * external;
c8071705 21781 char * end;
015dc7e1 21782 bool res = true;
685080f2
NC
21783
21784 if (length <= 0)
015dc7e1 21785 return false;
685080f2 21786
dda8d76d 21787 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21788 _("v850 notes"));
21789 if (pnotes == NULL)
015dc7e1 21790 return false;
685080f2
NC
21791
21792 external = pnotes;
c8071705 21793 end = (char*) pnotes + length;
685080f2
NC
21794
21795 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21796 (unsigned long) offset, (unsigned long) length);
21797
c8071705 21798 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21799 {
21800 Elf_External_Note * next;
21801 Elf_Internal_Note inote;
21802
21803 inote.type = BYTE_GET (external->type);
21804 inote.namesz = BYTE_GET (external->namesz);
21805 inote.namedata = external->name;
21806 inote.descsz = BYTE_GET (external->descsz);
21807 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21808 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21809
c8071705
NC
21810 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21811 {
21812 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21813 inote.descdata = inote.namedata;
21814 inote.namesz = 0;
21815 }
21816
685080f2
NC
21817 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21818
c8071705 21819 if ( ((char *) next > end)
685080f2
NC
21820 || ((char *) next < (char *) pnotes))
21821 {
21822 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21823 (unsigned long) ((char *) external - (char *) pnotes));
21824 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21825 inote.type, inote.namesz, inote.descsz);
21826 break;
21827 }
21828
21829 external = next;
21830
21831 /* Prevent out-of-bounds indexing. */
c8071705 21832 if ( inote.namedata + inote.namesz > end
685080f2
NC
21833 || inote.namedata + inote.namesz < inote.namedata)
21834 {
21835 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21836 (unsigned long) ((char *) external - (char *) pnotes));
21837 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21838 inote.type, inote.namesz, inote.descsz);
21839 break;
21840 }
21841
21842 printf (" %s: ", get_v850_elf_note_type (inote.type));
21843
21844 if (! print_v850_note (& inote))
21845 {
015dc7e1 21846 res = false;
685080f2
NC
21847 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21848 inote.namesz, inote.descsz);
21849 }
21850 }
21851
21852 free (pnotes);
21853
21854 return res;
21855}
21856
015dc7e1 21857static bool
dda8d76d 21858process_note_sections (Filedata * filedata)
1ec5cd37 21859{
015dc7e1 21860 Elf_Internal_Shdr *section;
1ec5cd37 21861 unsigned long i;
32ec8896 21862 unsigned int n = 0;
015dc7e1 21863 bool res = true;
1ec5cd37 21864
dda8d76d
NC
21865 for (i = 0, section = filedata->section_headers;
21866 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21867 i++, section++)
685080f2
NC
21868 {
21869 if (section->sh_type == SHT_NOTE)
21870 {
625d49fc
AM
21871 if (! process_notes_at (filedata, section, section->sh_offset,
21872 section->sh_size, section->sh_addralign))
015dc7e1 21873 res = false;
685080f2
NC
21874 n++;
21875 }
21876
dda8d76d
NC
21877 if (( filedata->file_header.e_machine == EM_V800
21878 || filedata->file_header.e_machine == EM_V850
21879 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21880 && section->sh_type == SHT_RENESAS_INFO)
21881 {
625d49fc
AM
21882 if (! process_v850_notes (filedata, section->sh_offset,
21883 section->sh_size))
015dc7e1 21884 res = false;
685080f2
NC
21885 n++;
21886 }
21887 }
df565f32
NC
21888
21889 if (n == 0)
21890 /* Try processing NOTE segments instead. */
dda8d76d 21891 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21892
21893 return res;
21894}
21895
015dc7e1 21896static bool
dda8d76d 21897process_notes (Filedata * filedata)
779fe533
NC
21898{
21899 /* If we have not been asked to display the notes then do nothing. */
21900 if (! do_notes)
015dc7e1 21901 return true;
103f02d3 21902
dda8d76d
NC
21903 if (filedata->file_header.e_type != ET_CORE)
21904 return process_note_sections (filedata);
103f02d3 21905
779fe533 21906 /* No program headers means no NOTE segment. */
dda8d76d
NC
21907 if (filedata->file_header.e_phnum > 0)
21908 return process_corefile_note_segments (filedata);
779fe533 21909
ca0e11aa
NC
21910 if (filedata->is_separate)
21911 printf (_("No notes found in linked file '%s'.\n"),
21912 filedata->file_name);
21913 else
21914 printf (_("No notes found file.\n"));
21915
015dc7e1 21916 return true;
779fe533
NC
21917}
21918
60abdbed
NC
21919static unsigned char *
21920display_public_gnu_attributes (unsigned char * start,
21921 const unsigned char * const end)
21922{
21923 printf (_(" Unknown GNU attribute: %s\n"), start);
21924
21925 start += strnlen ((char *) start, end - start);
21926 display_raw_attribute (start, end);
21927
21928 return (unsigned char *) end;
21929}
21930
21931static unsigned char *
21932display_generic_attribute (unsigned char * start,
21933 unsigned int tag,
21934 const unsigned char * const end)
21935{
21936 if (tag == 0)
21937 return (unsigned char *) end;
21938
21939 return display_tag_value (tag, start, end);
21940}
21941
015dc7e1 21942static bool
dda8d76d 21943process_arch_specific (Filedata * filedata)
252b5132 21944{
a952a375 21945 if (! do_arch)
015dc7e1 21946 return true;
a952a375 21947
dda8d76d 21948 switch (filedata->file_header.e_machine)
252b5132 21949 {
53a346d8
CZ
21950 case EM_ARC:
21951 case EM_ARC_COMPACT:
21952 case EM_ARC_COMPACT2:
dda8d76d 21953 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21954 display_arc_attribute,
21955 display_generic_attribute);
11c1ff18 21956 case EM_ARM:
dda8d76d 21957 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21958 display_arm_attribute,
21959 display_generic_attribute);
21960
252b5132 21961 case EM_MIPS:
4fe85591 21962 case EM_MIPS_RS3_LE:
dda8d76d 21963 return process_mips_specific (filedata);
60abdbed
NC
21964
21965 case EM_MSP430:
dda8d76d 21966 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21967 display_msp430_attribute,
c0ea7c52 21968 display_msp430_gnu_attribute);
60abdbed 21969
2dc8dd17
JW
21970 case EM_RISCV:
21971 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21972 display_riscv_attribute,
21973 display_generic_attribute);
21974
35c08157 21975 case EM_NDS32:
dda8d76d 21976 return process_nds32_specific (filedata);
60abdbed 21977
85f7484a
PB
21978 case EM_68K:
21979 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21980 display_m68k_gnu_attribute);
21981
34c8bcba 21982 case EM_PPC:
b82317dd 21983 case EM_PPC64:
dda8d76d 21984 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21985 display_power_gnu_attribute);
21986
643f7afb
AK
21987 case EM_S390:
21988 case EM_S390_OLD:
dda8d76d 21989 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21990 display_s390_gnu_attribute);
21991
9e8c70f9
DM
21992 case EM_SPARC:
21993 case EM_SPARC32PLUS:
21994 case EM_SPARCV9:
dda8d76d 21995 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21996 display_sparc_gnu_attribute);
21997
59e6276b 21998 case EM_TI_C6000:
dda8d76d 21999 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22000 display_tic6x_attribute,
22001 display_generic_attribute);
22002
0861f561
CQ
22003 case EM_CSKY:
22004 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22005 display_csky_attribute, NULL);
22006
252b5132 22007 default:
dda8d76d 22008 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22009 display_public_gnu_attributes,
22010 display_generic_attribute);
252b5132 22011 }
252b5132
RH
22012}
22013
015dc7e1 22014static bool
dda8d76d 22015get_file_header (Filedata * filedata)
252b5132 22016{
9ea033b2 22017 /* Read in the identity array. */
dda8d76d 22018 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22019 return false;
252b5132 22020
9ea033b2 22021 /* Determine how to read the rest of the header. */
dda8d76d 22022 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22023 {
1a0670f3
AM
22024 default:
22025 case ELFDATANONE:
adab8cdc
AO
22026 case ELFDATA2LSB:
22027 byte_get = byte_get_little_endian;
22028 byte_put = byte_put_little_endian;
22029 break;
22030 case ELFDATA2MSB:
22031 byte_get = byte_get_big_endian;
22032 byte_put = byte_put_big_endian;
22033 break;
9ea033b2
NC
22034 }
22035
22036 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22037 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22038
22039 /* Read in the rest of the header. */
22040 if (is_32bit_elf)
22041 {
22042 Elf32_External_Ehdr ehdr32;
252b5132 22043
dda8d76d 22044 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22045 return false;
103f02d3 22046
dda8d76d
NC
22047 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22048 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22049 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22050 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22051 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22052 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22053 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22054 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22055 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22056 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22057 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22058 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22059 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22060 }
252b5132 22061 else
9ea033b2
NC
22062 {
22063 Elf64_External_Ehdr ehdr64;
a952a375 22064
dda8d76d 22065 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22066 return false;
103f02d3 22067
dda8d76d
NC
22068 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22069 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22070 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22071 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22072 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22073 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22074 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22075 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22076 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22077 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22078 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22079 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22080 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22081 }
252b5132 22082
015dc7e1 22083 return true;
252b5132
RH
22084}
22085
13acb58d
AM
22086static void
22087free_filedata (Filedata *filedata)
22088{
22089 free (filedata->program_interpreter);
13acb58d 22090 free (filedata->program_headers);
13acb58d 22091 free (filedata->section_headers);
13acb58d 22092 free (filedata->string_table);
13acb58d 22093 free (filedata->dump.dump_sects);
13acb58d 22094 free (filedata->dynamic_strings);
13acb58d 22095 free (filedata->dynamic_symbols);
13acb58d 22096 free (filedata->dynamic_syminfo);
13acb58d 22097 free (filedata->dynamic_section);
13acb58d
AM
22098
22099 while (filedata->symtab_shndx_list != NULL)
22100 {
22101 elf_section_list *next = filedata->symtab_shndx_list->next;
22102 free (filedata->symtab_shndx_list);
22103 filedata->symtab_shndx_list = next;
22104 }
22105
22106 free (filedata->section_headers_groups);
13acb58d
AM
22107
22108 if (filedata->section_groups)
22109 {
22110 size_t i;
22111 struct group_list * g;
22112 struct group_list * next;
22113
22114 for (i = 0; i < filedata->group_count; i++)
22115 {
22116 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22117 {
22118 next = g->next;
22119 free (g);
22120 }
22121 }
22122
22123 free (filedata->section_groups);
13acb58d 22124 }
066f8fbe
AM
22125 memset (&filedata->section_headers, 0,
22126 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22127}
22128
dda8d76d
NC
22129static void
22130close_file (Filedata * filedata)
22131{
22132 if (filedata)
22133 {
22134 if (filedata->handle)
22135 fclose (filedata->handle);
22136 free (filedata);
22137 }
22138}
22139
22140void
22141close_debug_file (void * data)
22142{
13acb58d 22143 free_filedata ((Filedata *) data);
dda8d76d
NC
22144 close_file ((Filedata *) data);
22145}
22146
22147static Filedata *
015dc7e1 22148open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22149{
22150 struct stat statbuf;
22151 Filedata * filedata = NULL;
22152
22153 if (stat (pathname, & statbuf) < 0
22154 || ! S_ISREG (statbuf.st_mode))
22155 goto fail;
22156
22157 filedata = calloc (1, sizeof * filedata);
22158 if (filedata == NULL)
22159 goto fail;
22160
22161 filedata->handle = fopen (pathname, "rb");
22162 if (filedata->handle == NULL)
22163 goto fail;
22164
be7d229a 22165 filedata->file_size = statbuf.st_size;
dda8d76d 22166 filedata->file_name = pathname;
ca0e11aa 22167 filedata->is_separate = is_separate;
dda8d76d
NC
22168
22169 if (! get_file_header (filedata))
22170 goto fail;
22171
4de91c10
AM
22172 if (!get_section_headers (filedata, false))
22173 goto fail;
dda8d76d
NC
22174
22175 return filedata;
22176
22177 fail:
22178 if (filedata)
22179 {
22180 if (filedata->handle)
22181 fclose (filedata->handle);
22182 free (filedata);
22183 }
22184 return NULL;
22185}
22186
22187void *
22188open_debug_file (const char * pathname)
22189{
015dc7e1 22190 return open_file (pathname, true);
dda8d76d
NC
22191}
22192
835f2fae
NC
22193static void
22194initialise_dump_sects (Filedata * filedata)
22195{
22196 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22197 Note we do this even if cmdline_dump_sects is empty because we
22198 must make sure that the dump_sets array is zeroed out before each
22199 object file is processed. */
22200 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22201 memset (filedata->dump.dump_sects, 0,
22202 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22203
22204 if (cmdline.num_dump_sects > 0)
22205 {
22206 if (filedata->dump.num_dump_sects == 0)
22207 /* A sneaky way of allocating the dump_sects array. */
22208 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22209
22210 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22211 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22212 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22213 }
22214}
22215
94585d6d
NC
22216static bool
22217might_need_separate_debug_info (Filedata * filedata)
22218{
22219 /* Debuginfo files do not need further separate file loading. */
22220 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22221 return false;
22222
22223 /* Since do_follow_links might be enabled by default, only treat it as an
22224 indication that separate files should be loaded if setting it was a
22225 deliberate user action. */
22226 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22227 return true;
22228
22229 if (process_links || do_syms || do_unwind
22230 || dump_any_debugging || do_dump || do_debugging)
22231 return true;
22232
22233 return false;
22234}
22235
fb52b2f4
NC
22236/* Process one ELF object file according to the command line options.
22237 This file may actually be stored in an archive. The file is
32ec8896
NC
22238 positioned at the start of the ELF object. Returns TRUE if no
22239 problems were encountered, FALSE otherwise. */
fb52b2f4 22240
015dc7e1 22241static bool
dda8d76d 22242process_object (Filedata * filedata)
252b5132 22243{
015dc7e1 22244 bool have_separate_files;
252b5132 22245 unsigned int i;
015dc7e1 22246 bool res;
252b5132 22247
dda8d76d 22248 if (! get_file_header (filedata))
252b5132 22249 {
dda8d76d 22250 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22251 return false;
252b5132
RH
22252 }
22253
22254 /* Initialise per file variables. */
978c4450
AM
22255 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22256 filedata->version_info[i] = 0;
252b5132 22257
978c4450
AM
22258 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22259 filedata->dynamic_info[i] = 0;
22260 filedata->dynamic_info_DT_GNU_HASH = 0;
22261 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22262
22263 /* Process the file. */
22264 if (show_name)
dda8d76d 22265 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22266
835f2fae 22267 initialise_dump_sects (filedata);
d70c5fc7 22268
4de91c10
AM
22269 /* There may be some extensions in the first section header. Don't
22270 bomb if we can't read it. */
22271 get_section_headers (filedata, true);
22272
dda8d76d 22273 if (! process_file_header (filedata))
4de91c10
AM
22274 {
22275 res = false;
22276 goto out;
22277 }
252b5132 22278
e331b18d
AM
22279 /* Throw away the single section header read above, so that we
22280 re-read the entire set. */
22281 free (filedata->section_headers);
22282 filedata->section_headers = NULL;
22283
dda8d76d 22284 if (! process_section_headers (filedata))
2f62977e 22285 {
32ec8896 22286 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22287 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22288
2f62977e 22289 if (! do_using_dynamic)
015dc7e1 22290 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22291 }
252b5132 22292
dda8d76d 22293 if (! process_section_groups (filedata))
32ec8896 22294 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22295 do_unwind = false;
d1f5c6e3 22296
93df3340
AM
22297 process_program_headers (filedata);
22298
22299 res = process_dynamic_section (filedata);
252b5132 22300
dda8d76d 22301 if (! process_relocs (filedata))
015dc7e1 22302 res = false;
252b5132 22303
dda8d76d 22304 if (! process_unwind (filedata))
015dc7e1 22305 res = false;
4d6ed7c8 22306
dda8d76d 22307 if (! process_symbol_table (filedata))
015dc7e1 22308 res = false;
252b5132 22309
0f03783c 22310 if (! process_lto_symbol_tables (filedata))
015dc7e1 22311 res = false;
b9e920ec 22312
dda8d76d 22313 if (! process_syminfo (filedata))
015dc7e1 22314 res = false;
252b5132 22315
dda8d76d 22316 if (! process_version_sections (filedata))
015dc7e1 22317 res = false;
252b5132 22318
94585d6d 22319 if (might_need_separate_debug_info (filedata))
24841daa 22320 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22321 else
015dc7e1 22322 have_separate_files = false;
dda8d76d
NC
22323
22324 if (! process_section_contents (filedata))
015dc7e1 22325 res = false;
f5842774 22326
24841daa 22327 if (have_separate_files)
dda8d76d 22328 {
24841daa
NC
22329 separate_info * d;
22330
22331 for (d = first_separate_info; d != NULL; d = d->next)
22332 {
835f2fae
NC
22333 initialise_dump_sects (d->handle);
22334
ca0e11aa 22335 if (process_links && ! process_file_header (d->handle))
015dc7e1 22336 res = false;
ca0e11aa 22337 else if (! process_section_headers (d->handle))
015dc7e1 22338 res = false;
d6bfbc39 22339 else if (! process_section_contents (d->handle))
015dc7e1 22340 res = false;
ca0e11aa
NC
22341 else if (process_links)
22342 {
ca0e11aa 22343 if (! process_section_groups (d->handle))
015dc7e1 22344 res = false;
93df3340 22345 process_program_headers (d->handle);
ca0e11aa 22346 if (! process_dynamic_section (d->handle))
015dc7e1 22347 res = false;
ca0e11aa 22348 if (! process_relocs (d->handle))
015dc7e1 22349 res = false;
ca0e11aa 22350 if (! process_unwind (d->handle))
015dc7e1 22351 res = false;
ca0e11aa 22352 if (! process_symbol_table (d->handle))
015dc7e1 22353 res = false;
ca0e11aa 22354 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22355 res = false;
ca0e11aa 22356 if (! process_syminfo (d->handle))
015dc7e1 22357 res = false;
ca0e11aa 22358 if (! process_version_sections (d->handle))
015dc7e1 22359 res = false;
ca0e11aa 22360 if (! process_notes (d->handle))
015dc7e1 22361 res = false;
ca0e11aa 22362 }
24841daa
NC
22363 }
22364
22365 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22366 }
22367
22368 if (! process_notes (filedata))
015dc7e1 22369 res = false;
103f02d3 22370
dda8d76d 22371 if (! process_gnu_liblist (filedata))
015dc7e1 22372 res = false;
047b2264 22373
dda8d76d 22374 if (! process_arch_specific (filedata))
015dc7e1 22375 res = false;
252b5132 22376
4de91c10 22377 out:
13acb58d 22378 free_filedata (filedata);
e4b17d5c 22379
19e6b90e 22380 free_debug_memory ();
18bd398b 22381
32ec8896 22382 return res;
252b5132
RH
22383}
22384
2cf0635d 22385/* Process an ELF archive.
32ec8896
NC
22386 On entry the file is positioned just after the ARMAG string.
22387 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22388
015dc7e1
AM
22389static bool
22390process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22391{
22392 struct archive_info arch;
22393 struct archive_info nested_arch;
22394 size_t got;
015dc7e1 22395 bool ret = true;
2cf0635d 22396
015dc7e1 22397 show_name = true;
2cf0635d
NC
22398
22399 /* The ARCH structure is used to hold information about this archive. */
22400 arch.file_name = NULL;
22401 arch.file = NULL;
22402 arch.index_array = NULL;
22403 arch.sym_table = NULL;
22404 arch.longnames = NULL;
22405
22406 /* The NESTED_ARCH structure is used as a single-item cache of information
22407 about a nested archive (when members of a thin archive reside within
22408 another regular archive file). */
22409 nested_arch.file_name = NULL;
22410 nested_arch.file = NULL;
22411 nested_arch.index_array = NULL;
22412 nested_arch.sym_table = NULL;
22413 nested_arch.longnames = NULL;
22414
dda8d76d 22415 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22416 filedata->file_size, is_thin_archive,
22417 do_archive_index) != 0)
2cf0635d 22418 {
015dc7e1 22419 ret = false;
2cf0635d 22420 goto out;
4145f1d5 22421 }
fb52b2f4 22422
4145f1d5
NC
22423 if (do_archive_index)
22424 {
2cf0635d 22425 if (arch.sym_table == NULL)
1cb7d8b1
AM
22426 error (_("%s: unable to dump the index as none was found\n"),
22427 filedata->file_name);
4145f1d5
NC
22428 else
22429 {
591f7597 22430 unsigned long i, l;
4145f1d5
NC
22431 unsigned long current_pos;
22432
1cb7d8b1
AM
22433 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22434 "in the symbol table)\n"),
22435 filedata->file_name, (unsigned long) arch.index_num,
22436 arch.sym_size);
dda8d76d
NC
22437
22438 current_pos = ftell (filedata->handle);
4145f1d5 22439
2cf0635d 22440 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22441 {
1cb7d8b1
AM
22442 if (i == 0
22443 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22444 {
22445 char * member_name
22446 = get_archive_member_name_at (&arch, arch.index_array[i],
22447 &nested_arch);
2cf0635d 22448
1cb7d8b1
AM
22449 if (member_name != NULL)
22450 {
22451 char * qualified_name
22452 = make_qualified_name (&arch, &nested_arch,
22453 member_name);
2cf0635d 22454
1cb7d8b1
AM
22455 if (qualified_name != NULL)
22456 {
22457 printf (_("Contents of binary %s at offset "),
22458 qualified_name);
c2a7d3f5
NC
22459 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22460 putchar ('\n');
1cb7d8b1
AM
22461 free (qualified_name);
22462 }
fd486f32 22463 free (member_name);
4145f1d5
NC
22464 }
22465 }
2cf0635d
NC
22466
22467 if (l >= arch.sym_size)
4145f1d5 22468 {
1cb7d8b1
AM
22469 error (_("%s: end of the symbol table reached "
22470 "before the end of the index\n"),
dda8d76d 22471 filedata->file_name);
015dc7e1 22472 ret = false;
cb8f3167 22473 break;
4145f1d5 22474 }
591f7597 22475 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22476 printf ("\t%.*s\n",
22477 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22478 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22479 }
22480
67ce483b 22481 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22482 l = (l + 7) & ~ 7;
22483 else
22484 l += l & 1;
22485
2cf0635d 22486 if (l < arch.sym_size)
32ec8896 22487 {
d3a49aa8
AM
22488 error (ngettext ("%s: %ld byte remains in the symbol table, "
22489 "but without corresponding entries in "
22490 "the index table\n",
22491 "%s: %ld bytes remain in the symbol table, "
22492 "but without corresponding entries in "
22493 "the index table\n",
22494 arch.sym_size - l),
dda8d76d 22495 filedata->file_name, arch.sym_size - l);
015dc7e1 22496 ret = false;
32ec8896 22497 }
4145f1d5 22498
dda8d76d 22499 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22500 {
1cb7d8b1
AM
22501 error (_("%s: failed to seek back to start of object files "
22502 "in the archive\n"),
dda8d76d 22503 filedata->file_name);
015dc7e1 22504 ret = false;
2cf0635d 22505 goto out;
4145f1d5 22506 }
fb52b2f4 22507 }
4145f1d5
NC
22508
22509 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22510 && !do_segments && !do_header && !do_dump && !do_version
22511 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22512 && !do_section_groups && !do_dyn_syms)
2cf0635d 22513 {
015dc7e1 22514 ret = true; /* Archive index only. */
2cf0635d
NC
22515 goto out;
22516 }
fb52b2f4
NC
22517 }
22518
fb52b2f4
NC
22519 while (1)
22520 {
2cf0635d
NC
22521 char * name;
22522 size_t namelen;
22523 char * qualified_name;
22524
22525 /* Read the next archive header. */
dda8d76d 22526 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22527 {
22528 error (_("%s: failed to seek to next archive header\n"),
22529 arch.file_name);
015dc7e1 22530 ret = false;
1cb7d8b1
AM
22531 break;
22532 }
dda8d76d 22533 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22534 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22535 {
22536 if (got == 0)
2cf0635d 22537 break;
28e817cc
NC
22538 /* PR 24049 - we cannot use filedata->file_name as this will
22539 have already been freed. */
22540 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22541
015dc7e1 22542 ret = false;
1cb7d8b1
AM
22543 break;
22544 }
2cf0635d 22545 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22546 {
22547 error (_("%s: did not find a valid archive header\n"),
22548 arch.file_name);
015dc7e1 22549 ret = false;
1cb7d8b1
AM
22550 break;
22551 }
2cf0635d
NC
22552
22553 arch.next_arhdr_offset += sizeof arch.arhdr;
22554
978c4450 22555 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22556
22557 name = get_archive_member_name (&arch, &nested_arch);
22558 if (name == NULL)
fb52b2f4 22559 {
28e817cc 22560 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22561 ret = false;
d989285c 22562 break;
fb52b2f4 22563 }
2cf0635d 22564 namelen = strlen (name);
fb52b2f4 22565
2cf0635d
NC
22566 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22567 if (qualified_name == NULL)
fb52b2f4 22568 {
28e817cc 22569 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22570 free (name);
015dc7e1 22571 ret = false;
d989285c 22572 break;
fb52b2f4
NC
22573 }
22574
2cf0635d 22575 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22576 {
22577 /* This is a proxy for an external member of a thin archive. */
22578 Filedata * member_filedata;
22579 char * member_file_name = adjust_relative_path
dda8d76d 22580 (filedata->file_name, name, namelen);
32ec8896 22581
fd486f32 22582 free (name);
1cb7d8b1
AM
22583 if (member_file_name == NULL)
22584 {
fd486f32 22585 free (qualified_name);
015dc7e1 22586 ret = false;
1cb7d8b1
AM
22587 break;
22588 }
2cf0635d 22589
015dc7e1 22590 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22591 if (member_filedata == NULL)
22592 {
22593 error (_("Input file '%s' is not readable.\n"), member_file_name);
22594 free (member_file_name);
fd486f32 22595 free (qualified_name);
015dc7e1 22596 ret = false;
1cb7d8b1
AM
22597 break;
22598 }
2cf0635d 22599
978c4450 22600 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22601 member_filedata->file_name = qualified_name;
2cf0635d 22602
75a2da57
AH
22603 /* The call to process_object() expects the file to be at the beginning. */
22604 rewind (member_filedata->handle);
22605
1cb7d8b1 22606 if (! process_object (member_filedata))
015dc7e1 22607 ret = false;
2cf0635d 22608
1cb7d8b1
AM
22609 close_file (member_filedata);
22610 free (member_file_name);
1cb7d8b1 22611 }
2cf0635d 22612 else if (is_thin_archive)
1cb7d8b1
AM
22613 {
22614 Filedata thin_filedata;
eb02c04d 22615
1cb7d8b1 22616 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22617
a043396b
NC
22618 /* PR 15140: Allow for corrupt thin archives. */
22619 if (nested_arch.file == NULL)
22620 {
22621 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22622 qualified_name, name);
fd486f32
AM
22623 free (qualified_name);
22624 free (name);
015dc7e1 22625 ret = false;
a043396b
NC
22626 break;
22627 }
fd486f32 22628 free (name);
a043396b 22629
1cb7d8b1 22630 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22631 filedata->archive_file_offset
22632 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22633
1cb7d8b1
AM
22634 /* The nested archive file will have been opened and setup by
22635 get_archive_member_name. */
978c4450
AM
22636 if (fseek (nested_arch.file, filedata->archive_file_offset,
22637 SEEK_SET) != 0)
1cb7d8b1
AM
22638 {
22639 error (_("%s: failed to seek to archive member.\n"),
22640 nested_arch.file_name);
fd486f32 22641 free (qualified_name);
015dc7e1 22642 ret = false;
1cb7d8b1
AM
22643 break;
22644 }
2cf0635d 22645
dda8d76d
NC
22646 thin_filedata.handle = nested_arch.file;
22647 thin_filedata.file_name = qualified_name;
9abca702 22648
1cb7d8b1 22649 if (! process_object (& thin_filedata))
015dc7e1 22650 ret = false;
1cb7d8b1 22651 }
2cf0635d 22652 else
1cb7d8b1 22653 {
fd486f32 22654 free (name);
978c4450 22655 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22656 filedata->file_name = qualified_name;
1cb7d8b1 22657 if (! process_object (filedata))
015dc7e1 22658 ret = false;
237877b8 22659 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22660 /* Stop looping with "negative" archive_file_size. */
978c4450 22661 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22662 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22663 }
fb52b2f4 22664
2cf0635d 22665 free (qualified_name);
fb52b2f4
NC
22666 }
22667
4145f1d5 22668 out:
2cf0635d
NC
22669 if (nested_arch.file != NULL)
22670 fclose (nested_arch.file);
22671 release_archive (&nested_arch);
22672 release_archive (&arch);
fb52b2f4 22673
d989285c 22674 return ret;
fb52b2f4
NC
22675}
22676
015dc7e1 22677static bool
2cf0635d 22678process_file (char * file_name)
fb52b2f4 22679{
dda8d76d 22680 Filedata * filedata = NULL;
fb52b2f4
NC
22681 struct stat statbuf;
22682 char armag[SARMAG];
015dc7e1 22683 bool ret = true;
fb52b2f4
NC
22684
22685 if (stat (file_name, &statbuf) < 0)
22686 {
f24ddbdd
NC
22687 if (errno == ENOENT)
22688 error (_("'%s': No such file\n"), file_name);
22689 else
22690 error (_("Could not locate '%s'. System error message: %s\n"),
22691 file_name, strerror (errno));
015dc7e1 22692 return false;
f24ddbdd
NC
22693 }
22694
22695 if (! S_ISREG (statbuf.st_mode))
22696 {
22697 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22698 return false;
fb52b2f4
NC
22699 }
22700
dda8d76d
NC
22701 filedata = calloc (1, sizeof * filedata);
22702 if (filedata == NULL)
22703 {
22704 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22705 return false;
dda8d76d
NC
22706 }
22707
22708 filedata->file_name = file_name;
22709 filedata->handle = fopen (file_name, "rb");
22710 if (filedata->handle == NULL)
fb52b2f4 22711 {
f24ddbdd 22712 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22713 free (filedata);
015dc7e1 22714 return false;
fb52b2f4
NC
22715 }
22716
dda8d76d 22717 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22718 {
4145f1d5 22719 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22720 fclose (filedata->handle);
22721 free (filedata);
015dc7e1 22722 return false;
fb52b2f4
NC
22723 }
22724
be7d229a 22725 filedata->file_size = statbuf.st_size;
015dc7e1 22726 filedata->is_separate = false;
f54498b4 22727
fb52b2f4 22728 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22729 {
015dc7e1
AM
22730 if (! process_archive (filedata, false))
22731 ret = false;
32ec8896 22732 }
2cf0635d 22733 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22734 {
015dc7e1
AM
22735 if ( ! process_archive (filedata, true))
22736 ret = false;
32ec8896 22737 }
fb52b2f4
NC
22738 else
22739 {
1b513401 22740 if (do_archive_index && !check_all)
4145f1d5
NC
22741 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22742 file_name);
22743
dda8d76d 22744 rewind (filedata->handle);
978c4450 22745 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22746
dda8d76d 22747 if (! process_object (filedata))
015dc7e1 22748 ret = false;
fb52b2f4
NC
22749 }
22750
dda8d76d 22751 fclose (filedata->handle);
8fb879cd
AM
22752 free (filedata->section_headers);
22753 free (filedata->program_headers);
22754 free (filedata->string_table);
6431e409 22755 free (filedata->dump.dump_sects);
dda8d76d 22756 free (filedata);
32ec8896 22757
fd486f32 22758 free (ba_cache.strtab);
1bd6175a 22759 ba_cache.strtab = NULL;
fd486f32 22760 free (ba_cache.symtab);
1bd6175a 22761 ba_cache.symtab = NULL;
fd486f32
AM
22762 ba_cache.filedata = NULL;
22763
fb52b2f4
NC
22764 return ret;
22765}
22766
252b5132
RH
22767#ifdef SUPPORT_DISASSEMBLY
22768/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22769 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22770 symbols. */
252b5132
RH
22771
22772void
2cf0635d 22773print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22774{
22775 fprintf (outfile,"0x%8.8x", addr);
22776}
22777
e3c8793a 22778/* Needed by the i386 disassembler. */
dda8d76d 22779
252b5132
RH
22780void
22781db_task_printsym (unsigned int addr)
22782{
22783 print_address (addr, stderr);
22784}
22785#endif
22786
22787int
2cf0635d 22788main (int argc, char ** argv)
252b5132 22789{
ff78d6d6
L
22790 int err;
22791
87b9f255 22792#ifdef HAVE_LC_MESSAGES
252b5132 22793 setlocale (LC_MESSAGES, "");
3882b010 22794#endif
3882b010 22795 setlocale (LC_CTYPE, "");
252b5132
RH
22796 bindtextdomain (PACKAGE, LOCALEDIR);
22797 textdomain (PACKAGE);
22798
869b9d07
MM
22799 expandargv (&argc, &argv);
22800
dda8d76d 22801 parse_args (& cmdline, argc, argv);
59f14fc0 22802
18bd398b 22803 if (optind < (argc - 1))
1b513401
NC
22804 /* When displaying information for more than one file,
22805 prefix the information with the file name. */
015dc7e1 22806 show_name = true;
5656ba2c
L
22807 else if (optind >= argc)
22808 {
1b513401 22809 /* Ensure that the warning is always displayed. */
015dc7e1 22810 do_checks = true;
1b513401 22811
5656ba2c
L
22812 warn (_("Nothing to do.\n"));
22813 usage (stderr);
22814 }
18bd398b 22815
015dc7e1 22816 err = false;
252b5132 22817 while (optind < argc)
32ec8896 22818 if (! process_file (argv[optind++]))
015dc7e1 22819 err = true;
252b5132 22820
9db70fc3 22821 free (cmdline.dump_sects);
252b5132 22822
7d9813f1
NA
22823 free (dump_ctf_symtab_name);
22824 free (dump_ctf_strtab_name);
22825 free (dump_ctf_parent_name);
22826
32ec8896 22827 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22828}